Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarAmbient.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarAmbient.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarAmbient.cpp')
-rw-r--r--source/game/StarAmbient.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/source/game/StarAmbient.cpp b/source/game/StarAmbient.cpp
new file mode 100644
index 0000000..6cb912d
--- /dev/null
+++ b/source/game/StarAmbient.cpp
@@ -0,0 +1,175 @@
+#include "StarAmbient.hpp"
+#include "StarJsonExtra.hpp"
+#include "StarTime.hpp"
+#include "StarMixer.hpp"
+#include "StarRoot.hpp"
+#include "StarAssets.hpp"
+#include "StarRandom.hpp"
+#include "StarGameTypes.hpp"
+
+namespace Star {
+
+AmbientTrackGroup::AmbientTrackGroup() {
+ tracks = {};
+}
+
+AmbientTrackGroup::AmbientTrackGroup(StringList tracks) : tracks(move(tracks)) {}
+
+AmbientTrackGroup::AmbientTrackGroup(Json const& config, String const& directory) {
+ for (auto track : jsonToStringList(config.get("tracks", JsonArray())))
+ tracks.append(AssetPath::relativeTo(directory, track));
+}
+
+Json AmbientTrackGroup::toJson() const {
+ return JsonObject{{"tracks", jsonFromStringList(tracks)}};
+}
+
+AmbientNoisesDescription::AmbientNoisesDescription() {}
+
+AmbientNoisesDescription::AmbientNoisesDescription(AmbientTrackGroup day, AmbientTrackGroup night)
+ : daySounds(move(day)), nightSounds(move(night)) {}
+
+AmbientNoisesDescription::AmbientNoisesDescription(Json const& config, String const& directory) {
+ if (auto day = config.opt("day"))
+ daySounds = AmbientTrackGroup(*day, directory);
+ if (auto night = config.opt("night"))
+ nightSounds = AmbientTrackGroup(*night, directory);
+}
+
+Json AmbientNoisesDescription::toJson() const {
+ return JsonObject{{"day", daySounds.toJson()}, {"night", nightSounds.toJson()}};
+}
+
+AmbientManager::~AmbientManager() {
+ cancelAll();
+}
+
+void AmbientManager::setTrackSwitchGrace(float grace) {
+ m_trackSwitchGrace = grace;
+}
+
+void AmbientManager::setTrackFadeInTime(float fadeInTime) {
+ m_trackFadeInTime = fadeInTime;
+}
+
+AudioInstancePtr AmbientManager::updateAmbient(AmbientNoisesDescriptionPtr current, bool dayTime) {
+ auto assets = Root::singleton().assets();
+
+ if (m_currentTrack) {
+ if (m_currentTrack->finished())
+ m_currentTrack = {};
+ }
+ StringList tracks;
+ if (current) {
+ if (dayTime)
+ tracks = current->daySounds.tracks;
+ else
+ tracks = current->nightSounds.tracks;
+ }
+ if (m_currentTrack) {
+ if (!tracks.contains(m_currentTrackName)) {
+ if (m_trackSwitchGrace <= Time::monotonicTime() - m_trackGraceTimestamp) {
+ m_currentTrack->stop(m_trackFadeInTime);
+ m_currentTrack = {};
+ }
+ } else {
+ m_trackGraceTimestamp = Time::monotonicTime();
+ }
+ }
+ if (!m_currentTrack) {
+ m_currentTrackName = "";
+ if (tracks.size() > 0) {
+ while ((m_recentTracks.size() / 2) >= tracks.size())
+ m_recentTracks.removeFirst();
+ while (true) {
+ m_currentTrackName = Random::randValueFrom(tracks);
+ if (m_currentTrackName.empty() || !m_recentTracks.contains(m_currentTrackName))
+ break;
+ m_recentTracks.removeFirst(); // reduce chance of collisions on collision
+ }
+ }
+ if (!m_currentTrackName.empty()) {
+ if (auto audio = assets->tryAudio(m_currentTrackName)) {
+ m_recentTracks.append(m_currentTrackName);
+ m_currentTrack = make_shared<AudioInstance>(*audio);
+ m_currentTrack->setLoops(-1);
+ // Slowly fade the music track in
+ m_currentTrack->setVolume(0.0f);
+ m_currentTrack->setVolume(m_volume, m_trackFadeInTime);
+ m_delay = 0;
+ m_duration = 0;
+ m_volumeChanged = false;
+ return m_currentTrack;
+ }
+ }
+ }
+ if (m_volumeChanged) {
+ if (m_delay > 0)
+ m_delay -= WorldTimestep;
+ else {
+ m_volumeChanged = false;
+ if (m_currentTrack) {
+ m_currentTrack->setVolume(m_volume, m_duration);
+ }
+ }
+ }
+
+ return {};
+}
+
+AudioInstancePtr AmbientManager::updateWeather(WeatherNoisesDescriptionPtr current) {
+ auto assets = Root::singleton().assets();
+
+ if (m_weatherTrack) {
+ if (m_weatherTrack->finished())
+ m_weatherTrack = {};
+ }
+
+ StringList tracks;
+ if (current)
+ tracks = current->tracks;
+
+ if (m_weatherTrack) {
+ if (!tracks.contains(m_weatherTrackName)) {
+ m_weatherTrack->stop(10.0f);
+ m_weatherTrack = {};
+ }
+ }
+
+ if (!m_weatherTrack) {
+ m_weatherTrackName = Random::randValueFrom(tracks);
+ if (!m_weatherTrackName.empty()) {
+ if (auto audio = assets->tryAudio(m_weatherTrackName)) {
+ m_weatherTrack = make_shared<AudioInstance>(*audio);
+ m_weatherTrack->setLoops(-1);
+ m_weatherTrack->setVolume(0.0f);
+ m_weatherTrack->setVolume(1, m_trackFadeInTime);
+ return m_weatherTrack;
+ }
+ }
+ }
+
+ return {};
+}
+
+void AmbientManager::cancelAll() {
+ if (m_weatherTrack) {
+ m_weatherTrack->stop();
+ m_weatherTrack = {};
+ }
+ if (m_currentTrack) {
+ m_currentTrack->stop();
+ m_currentTrack = {};
+ }
+}
+
+void AmbientManager::setVolume(float volume, float delay, float duration) {
+ if (m_volume == volume)
+ return;
+ m_volume = volume;
+ m_delay = delay;
+ m_duration = duration;
+ m_volumeChanged = true;
+}
+
+}