mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Add major city ambient audio with day/night variations
Implemented city-specific ambient soundscapes for all six major cities: Alliance cities: - Stormwind: day/night crowd and marketplace sounds - Ironforge: underground forge ambience (no day/night) - Darnassus: day/night elven city sounds Horde cities: - Orgrimmar: day/night orcish city atmosphere - Undercity: underground undead ambience (no day/night) - Thunder Bluff: day/night tauren plateau sounds Technical details: - Added CityType enum (NONE, STORMWIND, IRONFORGE, DARNASSUS, ORGRIMMAR, UNDERCITY, THUNDERBLUFF) - Loads 12 city sound files from Sound\Ambience\WMOAmbience - Underground cities (Ironforge, Undercity) use single sound without day/night variants - 20s loop interval for city ambience (more frequent than zone ambience) - Volume at 0.4 for noticeable but not overwhelming urban atmosphere - Cities take priority over zone ambience to prevent mixing - updateZoneAmbience() now checks for active city and skips if in city - State change logging for debugging city transitions
This commit is contained in:
parent
d6f0c2ec46
commit
77a9b3192d
2 changed files with 121 additions and 3 deletions
|
|
@ -45,6 +45,19 @@ public:
|
|||
void setZoneType(ZoneType type);
|
||||
ZoneType getCurrentZone() const { return currentZone_; }
|
||||
|
||||
// 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,
|
||||
|
|
@ -127,6 +140,18 @@ private:
|
|||
std::vector<AmbientSample> desertPlainsDaySounds_;
|
||||
std::vector<AmbientSample> desertPlainsNightSounds_;
|
||||
|
||||
// City ambience libraries (day and night versions)
|
||||
std::vector<AmbientSample> stormwindDaySounds_;
|
||||
std::vector<AmbientSample> stormwindNightSounds_;
|
||||
std::vector<AmbientSample> ironforgeSounds_; // No separate day/night
|
||||
std::vector<AmbientSample> darnassusDaySounds_;
|
||||
std::vector<AmbientSample> darnassusNightSounds_;
|
||||
std::vector<AmbientSample> orgrimmarDaySounds_;
|
||||
std::vector<AmbientSample> orgrimmarNightSounds_;
|
||||
std::vector<AmbientSample> undercitySounds_; // No separate day/night (underground)
|
||||
std::vector<AmbientSample> thunderbluffDaySounds_;
|
||||
std::vector<AmbientSample> thunderbluffNightSounds_;
|
||||
|
||||
// Active emitters
|
||||
std::vector<AmbientEmitter> emitters_;
|
||||
uint64_t nextEmitterId_ = 1;
|
||||
|
|
@ -141,12 +166,14 @@ private:
|
|||
float weatherLoopTime_ = 0.0f;
|
||||
float oceanLoopTime_ = 0.0f;
|
||||
float zoneLoopTime_ = 0.0f;
|
||||
float cityLoopTime_ = 0.0f;
|
||||
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 {
|
||||
|
|
@ -163,6 +190,7 @@ private:
|
|||
void updateWeatherAmbience(float deltaTime, bool isIndoor);
|
||||
void updateWaterAmbience(float deltaTime, bool isSwimming);
|
||||
void updateZoneAmbience(float deltaTime, bool isIndoor);
|
||||
void updateCityAmbience(float deltaTime);
|
||||
bool loadSound(const std::string& path, AmbientSample& sample, pipeline::AssetManager* assets);
|
||||
|
||||
// Time of day helpers
|
||||
|
|
|
|||
|
|
@ -152,6 +152,37 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
desertPlainsNightSounds_.resize(1);
|
||||
bool desertPlainsNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\PlainsDesertNight.wav", desertPlainsNightSounds_[0], assets);
|
||||
|
||||
// Load city ambience sounds (day and night where available)
|
||||
stormwindDaySounds_.resize(1);
|
||||
bool stormwindDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\StormwindDay.wav", stormwindDaySounds_[0], assets);
|
||||
|
||||
stormwindNightSounds_.resize(1);
|
||||
bool stormwindNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\StormwindNight.wav", stormwindNightSounds_[0], assets);
|
||||
|
||||
ironforgeSounds_.resize(1);
|
||||
bool ironforgeLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\Ironforge.wav", ironforgeSounds_[0], assets);
|
||||
|
||||
darnassusDaySounds_.resize(1);
|
||||
bool darnassusDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusDay.wav", darnassusDaySounds_[0], assets);
|
||||
|
||||
darnassusNightSounds_.resize(1);
|
||||
bool darnassusNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusNight.wav", darnassusNightSounds_[0], assets);
|
||||
|
||||
orgrimmarDaySounds_.resize(1);
|
||||
bool orgrimmarDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\OrgrimmarDay.wav", orgrimmarDaySounds_[0], assets);
|
||||
|
||||
orgrimmarNightSounds_.resize(1);
|
||||
bool orgrimmarNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\OrgrimmarNight.wav", orgrimmarNightSounds_[0], assets);
|
||||
|
||||
undercitySounds_.resize(1);
|
||||
bool undercityLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\Undercity.wav", undercitySounds_[0], assets);
|
||||
|
||||
thunderbluffDaySounds_.resize(1);
|
||||
bool thunderbluffDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffDay.wav", thunderbluffDaySounds_[0], assets);
|
||||
|
||||
thunderbluffNightSounds_.resize(1);
|
||||
bool thunderbluffNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffNight.wav", thunderbluffNightSounds_[0], assets);
|
||||
|
||||
LOG_INFO("AmbientSoundManager: Wind loaded: ", windLoaded ? "YES" : "NO",
|
||||
", Tavern loaded: ", tavernLoaded ? "YES" : "NO",
|
||||
", Blacksmith loaded: ", blacksmithLoaded ? "YES" : "NO");
|
||||
|
|
@ -162,6 +193,9 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
LOG_INFO("AmbientSoundManager: Zone sounds - Forest: ", (forestDayLoaded && forestNightLoaded) ? "YES" : "NO",
|
||||
", Beach: ", (beachDayLoaded && beachNightLoaded) ? "YES" : "NO",
|
||||
", Desert: ", (desertCanyonDayLoaded && desertPlainsDayLoaded) ? "YES" : "NO");
|
||||
LOG_INFO("AmbientSoundManager: City sounds - Stormwind: ", (stormwindDayLoaded && stormwindNightLoaded) ? "YES" : "NO",
|
||||
", Ironforge: ", ironforgeLoaded ? "YES" : "NO",
|
||||
", Orgrimmar: ", (orgrimmarDayLoaded && orgrimmarNightLoaded) ? "YES" : "NO");
|
||||
|
||||
// Initialize timers with random offsets
|
||||
birdTimer_ = randomFloat(0.0f, 5.0f);
|
||||
|
|
@ -219,10 +253,11 @@ void AmbientSoundManager::update(float deltaTime, const glm::vec3& cameraPos, bo
|
|||
updateWindAmbience(deltaTime, isIndoor);
|
||||
}
|
||||
|
||||
// Update weather, water, and zone ambience
|
||||
// Update weather, water, zone, and city ambience
|
||||
updateWeatherAmbience(deltaTime, isIndoor);
|
||||
updateWaterAmbience(deltaTime, isSwimming);
|
||||
updateZoneAmbience(deltaTime, isIndoor);
|
||||
updateCityAmbience(deltaTime);
|
||||
|
||||
// Track indoor state changes
|
||||
wasIndoor_ = isIndoor;
|
||||
|
|
@ -481,6 +516,15 @@ void AmbientSoundManager::setZoneType(ZoneType type) {
|
|||
}
|
||||
}
|
||||
|
||||
void AmbientSoundManager::setCityType(CityType type) {
|
||||
if (currentCity_ != type) {
|
||||
LOG_INFO("AmbientSoundManager: City changed from ", static_cast<int>(currentCity_),
|
||||
" to ", static_cast<int>(type));
|
||||
currentCity_ = type;
|
||||
cityLoopTime_ = 12.0f; // Play city ambience soon after entering
|
||||
}
|
||||
}
|
||||
|
||||
void AmbientSoundManager::updateWeatherAmbience(float deltaTime, bool isIndoor) {
|
||||
// Don't play weather sounds when indoors
|
||||
if (isIndoor || currentWeather_ == WeatherType::NONE) return;
|
||||
|
|
@ -559,8 +603,8 @@ void AmbientSoundManager::updateWaterAmbience(float deltaTime, bool isSwimming)
|
|||
}
|
||||
|
||||
void AmbientSoundManager::updateZoneAmbience(float deltaTime, bool isIndoor) {
|
||||
// Don't play zone ambience when indoors
|
||||
if (isIndoor || currentZone_ == ZoneType::NONE) return;
|
||||
// Don't play zone ambience when indoors or in cities
|
||||
if (isIndoor || currentZone_ == ZoneType::NONE || currentCity_ != CityType::NONE) return;
|
||||
|
||||
zoneLoopTime_ += deltaTime;
|
||||
|
||||
|
|
@ -610,5 +654,51 @@ void AmbientSoundManager::updateZoneAmbience(float deltaTime, bool isIndoor) {
|
|||
}
|
||||
}
|
||||
|
||||
void AmbientSoundManager::updateCityAmbience(float deltaTime) {
|
||||
// Only play city ambience when actually in a city
|
||||
if (currentCity_ == CityType::NONE) return;
|
||||
|
||||
cityLoopTime_ += deltaTime;
|
||||
|
||||
// Select appropriate sound library based on city type and time of day
|
||||
const std::vector<AmbientSample>* cityLibrary = nullptr;
|
||||
bool isDay = isDaytime();
|
||||
|
||||
switch (currentCity_) {
|
||||
case CityType::STORMWIND:
|
||||
cityLibrary = isDay ? &stormwindDaySounds_ : &stormwindNightSounds_;
|
||||
break;
|
||||
case CityType::IRONFORGE:
|
||||
cityLibrary = &ironforgeSounds_; // No day/night (underground)
|
||||
break;
|
||||
case CityType::DARNASSUS:
|
||||
cityLibrary = isDay ? &darnassusDaySounds_ : &darnassusNightSounds_;
|
||||
break;
|
||||
case CityType::ORGRIMMAR:
|
||||
cityLibrary = isDay ? &orgrimmarDaySounds_ : &orgrimmarNightSounds_;
|
||||
break;
|
||||
case CityType::UNDERCITY:
|
||||
cityLibrary = &undercitySounds_; // No day/night (underground)
|
||||
break;
|
||||
case CityType::THUNDERBLUFF:
|
||||
cityLibrary = isDay ? &thunderbluffDaySounds_ : &thunderbluffNightSounds_;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Play city ambience sound if library is loaded and timer expired
|
||||
if (cityLibrary && !cityLibrary->empty() && (*cityLibrary)[0].loaded) {
|
||||
// Play every 20 seconds for city ambience (moderate intervals for urban atmosphere)
|
||||
if (cityLoopTime_ >= 20.0f) {
|
||||
float volume = 0.4f * volumeScale_; // City ambience at moderate volume
|
||||
AudioEngine::instance().playSound2D((*cityLibrary)[0].data, volume, 1.0f);
|
||||
LOG_INFO("Playing city ambience: type ", static_cast<int>(currentCity_),
|
||||
" (", isDay ? "day" : "night", ")");
|
||||
cityLoopTime_ = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace audio
|
||||
} // namespace wowee
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue