#pragma once #include #include #include #include #include namespace wowee { namespace pipeline { class AssetManager; } namespace audio { class AmbientSoundManager { public: AmbientSoundManager() = default; ~AmbientSoundManager() = default; // Initialization bool initialize(pipeline::AssetManager* assets); void shutdown(); // Main update loop - called from renderer void update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming = false, bool isBlacksmith = false); // Weather control enum class WeatherType { NONE, RAIN_LIGHT, RAIN_MEDIUM, RAIN_HEAVY, SNOW_LIGHT, SNOW_MEDIUM, SNOW_HEAVY }; void setWeather(WeatherType type); WeatherType getCurrentWeather() const { return currentWeather_; } // Zone ambience control enum class ZoneType { NONE, FOREST_NORMAL, FOREST_SNOW, BEACH, GRASSLANDS, JUNGLE, MARSH, DESERT_CANYON, DESERT_PLAINS }; void setZoneType(ZoneType type); ZoneType getCurrentZone() const { return currentZone_; } // Convenience: derive ZoneType and CityType from a WoW zone ID void setZoneId(uint32_t zoneId); // City ambience control enum class CityType { NONE, STORMWIND, IRONFORGE, DARNASSUS, ORGRIMMAR, UNDERCITY, THUNDERBLUFF }; void setCityType(CityType type); CityType getCurrentCity() const { return currentCity_; } // Emitter management enum class AmbientType { FIREPLACE_SMALL, FIREPLACE_LARGE, TORCH, FOUNTAIN, WATER_SURFACE, RIVER, WATERFALL, WIND, BIRD_DAY, CRICKET_NIGHT, OWL_NIGHT }; uint64_t addEmitter(const glm::vec3& position, AmbientType type); void removeEmitter(uint64_t id); void clearEmitters(); // Time of day control (0-24 hours) void setGameTime(float hours); // Volume control void setVolumeScale(float scale); float getVolumeScale() const { return volumeScale_; } private: struct AmbientEmitter { uint64_t id; AmbientType type; glm::vec3 position; bool active; float lastPlayTime; float loopInterval; // For periodic/looping sounds }; struct AmbientSample { std::string path; std::vector data; bool loaded; }; // Sound libraries std::vector fireSoundsSmall_; std::vector fireSoundsLarge_; std::vector torchSounds_; std::vector waterSounds_; std::vector riverSounds_; std::vector waterfallSounds_; std::vector fountainSounds_; std::vector windSounds_; std::vector tavernSounds_; std::vector blacksmithSounds_; // Weather sound libraries std::vector rainLightSounds_; std::vector rainMediumSounds_; std::vector rainHeavySounds_; std::vector snowLightSounds_; std::vector snowMediumSounds_; std::vector snowHeavySounds_; // Water ambience libraries std::vector oceanSounds_; std::vector underwaterSounds_; // Zone ambience libraries (day and night versions) std::vector forestNormalDaySounds_; std::vector forestNormalNightSounds_; std::vector forestSnowDaySounds_; std::vector forestSnowNightSounds_; std::vector beachDaySounds_; std::vector beachNightSounds_; std::vector grasslandsDaySounds_; std::vector grasslandsNightSounds_; std::vector jungleDaySounds_; std::vector jungleNightSounds_; std::vector marshDaySounds_; std::vector marshNightSounds_; std::vector desertCanyonDaySounds_; std::vector desertCanyonNightSounds_; std::vector desertPlainsDaySounds_; std::vector desertPlainsNightSounds_; // City ambience libraries (day and night versions) std::vector stormwindDaySounds_; std::vector stormwindNightSounds_; std::vector ironforgeSounds_; // No separate day/night std::vector darnassusDaySounds_; std::vector darnassusNightSounds_; std::vector orgrimmarDaySounds_; std::vector orgrimmarNightSounds_; std::vector undercitySounds_; // No separate day/night (underground) std::vector thunderbluffDaySounds_; std::vector thunderbluffNightSounds_; // City bell sounds std::vector bellAllianceSounds_; std::vector bellHordeSounds_; std::vector bellNightElfSounds_; std::vector bellTribalSounds_; // Active emitters std::vector emitters_; uint64_t nextEmitterId_ = 1; // State tracking float gameTimeHours_ = 12.0f; // Default noon float volumeScale_ = 1.0f; float birdTimer_ = 0.0f; float cricketTimer_ = 0.0f; float windLoopTime_ = 0.0f; float blacksmithLoopTime_ = 0.0f; float weatherLoopTime_ = 0.0f; float oceanLoopTime_ = 0.0f; float zoneLoopTime_ = 0.0f; float cityLoopTime_ = 0.0f; float bellTollDelay_ = 0.0f; // Delay between individual bell tolls int lastHourTolled_ = -1; // Track last hour we tolled for int remainingTolls_ = 0; // Number of tolls left to play bool wasIndoor_ = false; bool wasBlacksmith_ = false; bool wasSwimming_ = false; bool initialized_ = false; WeatherType currentWeather_ = WeatherType::NONE; ZoneType currentZone_ = ZoneType::NONE; CityType currentCity_ = CityType::NONE; // Active audio tracking struct ActiveSound { uint64_t emitterId; float startTime; }; std::vector activeSounds_; // Helper methods void updatePositionalEmitters(float deltaTime, const glm::vec3& cameraPos); void updatePeriodicSounds(float deltaTime, bool isIndoor, bool isSwimming); void updateWindAmbience(float deltaTime, bool isIndoor); void updateBlacksmithAmbience(float deltaTime); void updateWeatherAmbience(float deltaTime, bool isIndoor); void updateWaterAmbience(float deltaTime, bool isSwimming); void updateZoneAmbience(float deltaTime, bool isIndoor); void updateCityAmbience(float deltaTime); void updateBellTolls(float deltaTime); bool loadSound(const std::string& path, AmbientSample& sample, pipeline::AssetManager* assets); // Time of day helpers bool isDaytime() const { return gameTimeHours_ >= 6.0f && gameTimeHours_ < 20.0f; } bool isNighttime() const { return !isDaytime(); } }; } // namespace audio } // namespace wowee