mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Increase blacksmith hammer sound pitch to 1.6x
Raises pitch from 1.4f to 1.6f for more distinct metallic clink in blacksmith ambience.
This commit is contained in:
parent
dab23f1895
commit
251f0ac246
4 changed files with 134 additions and 34 deletions
|
|
@ -23,7 +23,7 @@ public:
|
|||
void shutdown();
|
||||
|
||||
// Main update loop - called from renderer
|
||||
void update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming = false);
|
||||
void update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming = false, bool isBlacksmith = false);
|
||||
|
||||
// Emitter management
|
||||
enum class AmbientType {
|
||||
|
|
@ -75,6 +75,7 @@ private:
|
|||
std::vector<AmbientSample> waterfallSounds_;
|
||||
std::vector<AmbientSample> windSounds_;
|
||||
std::vector<AmbientSample> tavernSounds_;
|
||||
std::vector<AmbientSample> blacksmithSounds_;
|
||||
|
||||
// Active emitters
|
||||
std::vector<AmbientEmitter> emitters_;
|
||||
|
|
@ -86,7 +87,9 @@ private:
|
|||
float birdTimer_ = 0.0f;
|
||||
float cricketTimer_ = 0.0f;
|
||||
float windLoopTime_ = 0.0f;
|
||||
float blacksmithLoopTime_ = 0.0f;
|
||||
bool wasIndoor_ = false;
|
||||
bool wasBlacksmith_ = false;
|
||||
bool initialized_ = false;
|
||||
|
||||
// Active audio tracking
|
||||
|
|
@ -100,6 +103,7 @@ private:
|
|||
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);
|
||||
bool loadSound(const std::string& path, AmbientSample& sample, pipeline::AssetManager* assets);
|
||||
|
||||
// Time of day helpers
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ private:
|
|||
uint32_t currentZoneId = 0;
|
||||
std::string currentZoneName;
|
||||
bool inTavern_ = false;
|
||||
bool inBlacksmith_ = false;
|
||||
|
||||
// Third-person character state
|
||||
glm::vec3 characterPosition = glm::vec3(0.0f);
|
||||
|
|
|
|||
|
|
@ -73,8 +73,16 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
tavernSounds_.resize(1);
|
||||
bool tavernLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\Tavern.wav", tavernSounds_[0], assets);
|
||||
|
||||
// Load multiple hammer sounds for variety (short metal hit sounds)
|
||||
blacksmithSounds_.resize(3);
|
||||
bool bs1 = loadSound("Sound\\Item\\Weapons\\Mace1HMetal\\1hMaceMetalHitWoodCrit.wav", blacksmithSounds_[0], assets);
|
||||
bool bs2 = loadSound("Sound\\Item\\Weapons\\Sword2H\\m2hSwordHitMetalShield1c.wav", blacksmithSounds_[1], assets);
|
||||
bool bs3 = loadSound("Sound\\Item\\Weapons\\Axe2H\\m2hAxeHitChain1c.wav", blacksmithSounds_[2], assets);
|
||||
bool blacksmithLoaded = (bs1 || bs2 || bs3);
|
||||
|
||||
LOG_INFO("AmbientSoundManager: Wind loaded: ", windLoaded ? "YES" : "NO",
|
||||
", Tavern loaded: ", tavernLoaded ? "YES" : "NO");
|
||||
", Tavern loaded: ", tavernLoaded ? "YES" : "NO",
|
||||
", Blacksmith loaded: ", blacksmithLoaded ? "YES" : "NO");
|
||||
|
||||
// Initialize timers with random offsets
|
||||
birdTimer_ = randomFloat(0.0f, 5.0f);
|
||||
|
|
@ -108,16 +116,33 @@ bool AmbientSoundManager::loadSound(const std::string& path, AmbientSample& samp
|
|||
return false;
|
||||
}
|
||||
|
||||
void AmbientSoundManager::update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming) {
|
||||
void AmbientSoundManager::update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming, bool isBlacksmith) {
|
||||
if (!initialized_) return;
|
||||
|
||||
// Update all emitter systems
|
||||
updatePositionalEmitters(deltaTime, cameraPos);
|
||||
updatePeriodicSounds(deltaTime, isIndoor, isSwimming);
|
||||
updateWindAmbience(deltaTime, isIndoor);
|
||||
|
||||
// Don't play outdoor periodic sounds (birds) when indoors OR in blacksmith
|
||||
if (!isIndoor && !isBlacksmith) {
|
||||
updatePeriodicSounds(deltaTime, isIndoor, isSwimming);
|
||||
}
|
||||
|
||||
// Handle state changes
|
||||
if (wasBlacksmith_ && !isBlacksmith) {
|
||||
LOG_INFO("Ambient: EXITED BLACKSMITH");
|
||||
blacksmithLoopTime_ = 0.0f; // Reset timer when leaving
|
||||
}
|
||||
|
||||
// Blacksmith takes priority over tavern
|
||||
if (isBlacksmith) {
|
||||
updateBlacksmithAmbience(deltaTime);
|
||||
} else {
|
||||
updateWindAmbience(deltaTime, isIndoor);
|
||||
}
|
||||
|
||||
// Track indoor state changes
|
||||
wasIndoor_ = isIndoor;
|
||||
wasBlacksmith_ = isBlacksmith;
|
||||
}
|
||||
|
||||
void AmbientSoundManager::updatePositionalEmitters(float deltaTime, const glm::vec3& cameraPos) {
|
||||
|
|
@ -248,30 +273,72 @@ void AmbientSoundManager::updatePeriodicSounds(float deltaTime, bool isIndoor, b
|
|||
}
|
||||
}
|
||||
|
||||
void AmbientSoundManager::updateBlacksmithAmbience(float deltaTime) {
|
||||
bool stateChanged = !wasBlacksmith_;
|
||||
|
||||
if (stateChanged) {
|
||||
LOG_INFO("Ambient: ENTERED BLACKSMITH");
|
||||
blacksmithLoopTime_ = 1.5f; // Play first hammer soon
|
||||
}
|
||||
|
||||
// Only play if we have loaded sounds
|
||||
bool hasSound = false;
|
||||
for (const auto& sound : blacksmithSounds_) {
|
||||
if (sound.loaded) {
|
||||
hasSound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasSound) {
|
||||
blacksmithLoopTime_ += deltaTime;
|
||||
// Play every 2.5 seconds - rapid hammer strikes like real blacksmith
|
||||
if (blacksmithLoopTime_ >= 2.5f) {
|
||||
// Pick random hammer sound
|
||||
int index = 0;
|
||||
for (int i = 0; i < static_cast<int>(blacksmithSounds_.size()); i++) {
|
||||
if (blacksmithSounds_[i].loaded) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float volume = 0.35f * volumeScale_; // Reduced from 0.7
|
||||
float pitch = 1.6f; // Higher pitch for metallic clink
|
||||
AudioEngine::instance().playSound2D(blacksmithSounds_[index].data, volume, pitch);
|
||||
LOG_INFO("Playing blacksmith ambience (hammer strike)");
|
||||
blacksmithLoopTime_ = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmbientSoundManager::updateWindAmbience(float deltaTime, bool isIndoor) {
|
||||
// Always track indoor state for next frame
|
||||
bool stateChanged = (wasIndoor_ != isIndoor);
|
||||
|
||||
if (stateChanged) {
|
||||
LOG_INFO("Ambient: ", isIndoor ? "ENTERED BUILDING" : "EXITED TO OUTDOORS");
|
||||
windLoopTime_ = 99.0f; // Force immediate playback on next update
|
||||
// Start timer at 10 seconds so ambience plays after ~5 seconds
|
||||
if (isIndoor) {
|
||||
windLoopTime_ = 10.0f; // Play tavern ambience soon
|
||||
} else {
|
||||
windLoopTime_ = 25.0f; // Play outdoor ambience soon
|
||||
}
|
||||
}
|
||||
|
||||
wasIndoor_ = isIndoor;
|
||||
|
||||
// Indoor ambience (tavern sounds)
|
||||
// Indoor ambience (tavern sounds) - glass clinking, chatter
|
||||
if (isIndoor) {
|
||||
if (!tavernSounds_.empty() && tavernSounds_[0].loaded) {
|
||||
windLoopTime_ += deltaTime;
|
||||
if (windLoopTime_ >= 8.0f) {
|
||||
float volume = 0.8f * volumeScale_;
|
||||
bool success = AudioEngine::instance().playSound2D(tavernSounds_[0].data, volume, 1.0f);
|
||||
LOG_INFO("Playing tavern ambience: ", success ? "OK" : "FAILED", " (vol=", volume, ")");
|
||||
// Play every 15 seconds for ambient atmosphere
|
||||
if (windLoopTime_ >= 15.0f) {
|
||||
float volume = 0.5f * volumeScale_;
|
||||
AudioEngine::instance().playSound2D(tavernSounds_[0].data, volume, 1.0f);
|
||||
LOG_INFO("Playing tavern ambience (glasses clinking)");
|
||||
windLoopTime_ = 0.0f;
|
||||
}
|
||||
} else {
|
||||
LOG_WARNING("Cannot play tavern: empty=", tavernSounds_.empty(),
|
||||
" loaded=", (!tavernSounds_.empty() && tavernSounds_[0].loaded));
|
||||
}
|
||||
}
|
||||
// Outdoor wind ambience
|
||||
|
|
@ -279,14 +346,11 @@ void AmbientSoundManager::updateWindAmbience(float deltaTime, bool isIndoor) {
|
|||
if (!windSounds_.empty() && windSounds_[0].loaded) {
|
||||
windLoopTime_ += deltaTime;
|
||||
if (windLoopTime_ >= 30.0f) {
|
||||
float volume = 0.2f * volumeScale_;
|
||||
bool success = AudioEngine::instance().playSound2D(windSounds_[0].data, volume, 1.0f);
|
||||
LOG_INFO("Playing outdoor ambience: ", success ? "OK" : "FAILED", " (vol=", volume, ")");
|
||||
float volume = 0.3f * volumeScale_;
|
||||
AudioEngine::instance().playSound2D(windSounds_[0].data, volume, 1.0f);
|
||||
LOG_INFO("Playing outdoor ambience");
|
||||
windLoopTime_ = 0.0f;
|
||||
}
|
||||
} else {
|
||||
LOG_WARNING("Cannot play outdoor: empty=", windSounds_.empty(),
|
||||
" loaded=", (!windSounds_.empty() && windSounds_[0].loaded));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1422,7 +1422,10 @@ void Renderer::update(float deltaTime) {
|
|||
bool isIndoor = wmoRenderer->isInsideWMO(camPos.x, camPos.y, camPos.z, &wmoId);
|
||||
bool isSwimming = cameraController->isSwimming();
|
||||
|
||||
ambientSoundManager->update(deltaTime, camPos, isIndoor, isSwimming);
|
||||
// Check if inside blacksmith (96048 = Goldshire blacksmith)
|
||||
bool isBlacksmith = (wmoId == 96048);
|
||||
|
||||
ambientSoundManager->update(deltaTime, camPos, isIndoor, isSwimming, isBlacksmith);
|
||||
}
|
||||
|
||||
// Update M2 doodad animations (pass camera for frustum-culling bone computation)
|
||||
|
|
@ -1438,9 +1441,10 @@ void Renderer::update(float deltaTime) {
|
|||
uint32_t zoneId = zoneManager->getZoneId(tile.x, tile.y);
|
||||
|
||||
bool insideTavern = false;
|
||||
bool insideBlacksmith = false;
|
||||
std::string tavernMusic;
|
||||
|
||||
// Override with WMO-based detection (e.g., inside Stormwind, taverns)
|
||||
// Override with WMO-based detection (e.g., inside Stormwind, taverns, blacksmiths)
|
||||
if (wmoRenderer) {
|
||||
glm::vec3 camPos = camera->getPosition();
|
||||
uint32_t wmoModelId = 0;
|
||||
|
|
@ -1450,7 +1454,7 @@ void Renderer::update(float deltaTime) {
|
|||
zoneId = 1519; // Stormwind City
|
||||
}
|
||||
|
||||
// Detect taverns/inns by WMO model ID (common inn WMOs)
|
||||
// Detect taverns/inns/blacksmiths by WMO model ID
|
||||
// Log WMO ID for debugging
|
||||
static uint32_t lastLoggedWmoId = 0;
|
||||
if (wmoModelId != lastLoggedWmoId) {
|
||||
|
|
@ -1458,24 +1462,31 @@ void Renderer::update(float deltaTime) {
|
|||
lastLoggedWmoId = wmoModelId;
|
||||
}
|
||||
|
||||
// Blacksmith detection
|
||||
if (wmoModelId == 96048) { // Goldshire blacksmith
|
||||
insideBlacksmith = true;
|
||||
LOG_INFO("Detected blacksmith WMO ", wmoModelId);
|
||||
}
|
||||
|
||||
// These IDs represent typical Alliance and Horde inn buildings
|
||||
if (wmoModelId == 191 || // Goldshire inn
|
||||
if (wmoModelId == 191 || // Goldshire inn (old ID)
|
||||
wmoModelId == 71414 || // Goldshire inn (actual)
|
||||
wmoModelId == 190 || // Small inn (common)
|
||||
wmoModelId == 220 || // Tavern building
|
||||
wmoModelId == 221 || // Large tavern
|
||||
wmoModelId == 5392 || // Horde inn
|
||||
wmoModelId == 5393) { // Another inn variant
|
||||
insideTavern = true;
|
||||
// WoW tavern music (cozy ambient tracks)
|
||||
// WoW tavern music (cozy ambient tracks) - FIXED PATHS
|
||||
static const std::vector<std::string> tavernTracks = {
|
||||
"Sound\\Music\\GlueScreenMusic\\tavern_01.mp3",
|
||||
"Sound\\Music\\GlueScreenMusic\\tavern_02.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\Tavern\\tavernAlliance01.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\Tavern\\tavernAlliance02.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\TavernAlliance\\TavernAlliance01.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\TavernAlliance\\TavernAlliance02.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\TavernHuman\\RA_HumanTavern1A.mp3",
|
||||
"Sound\\Music\\ZoneMusic\\TavernHuman\\RA_HumanTavern2A.mp3",
|
||||
};
|
||||
static int tavernTrackIndex = 0;
|
||||
tavernMusic = tavernTracks[tavernTrackIndex % tavernTracks.size()];
|
||||
LOG_INFO("Detected tavern WMO, playing: ", tavernMusic);
|
||||
LOG_INFO("Detected tavern WMO ", wmoModelId, ", playing: ", tavernMusic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1485,10 +1496,10 @@ void Renderer::update(float deltaTime) {
|
|||
if (!inTavern_ && !tavernMusic.empty()) {
|
||||
inTavern_ = true;
|
||||
LOG_INFO("Entered tavern");
|
||||
musicManager->crossfadeTo(tavernMusic);
|
||||
musicManager->playMusic(tavernMusic, true); // Immediate playback, looping
|
||||
}
|
||||
} else if (inTavern_) {
|
||||
// Exited tavern - restore zone music
|
||||
// Exited tavern - restore zone music with crossfade
|
||||
inTavern_ = false;
|
||||
LOG_INFO("Exited tavern");
|
||||
auto* info = zoneManager->getZoneInfo(currentZoneId);
|
||||
|
|
@ -1500,8 +1511,28 @@ void Renderer::update(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle normal zone transitions (only if not in tavern)
|
||||
if (!insideTavern && zoneId != currentZoneId && zoneId != 0) {
|
||||
// Handle blacksmith music (stop music when entering blacksmith, let ambience play)
|
||||
if (insideBlacksmith) {
|
||||
if (!inBlacksmith_) {
|
||||
inBlacksmith_ = true;
|
||||
LOG_INFO("Entered blacksmith - stopping music");
|
||||
musicManager->stopMusic();
|
||||
}
|
||||
} else if (inBlacksmith_) {
|
||||
// Exited blacksmith - restore zone music with crossfade
|
||||
inBlacksmith_ = false;
|
||||
LOG_INFO("Exited blacksmith - restoring music");
|
||||
auto* info = zoneManager->getZoneInfo(currentZoneId);
|
||||
if (info) {
|
||||
std::string music = zoneManager->getRandomMusic(currentZoneId);
|
||||
if (!music.empty()) {
|
||||
musicManager->crossfadeTo(music);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle normal zone transitions (only if not in tavern or blacksmith)
|
||||
if (!insideTavern && !insideBlacksmith && zoneId != currentZoneId && zoneId != 0) {
|
||||
currentZoneId = zoneId;
|
||||
auto* info = zoneManager->getZoneInfo(zoneId);
|
||||
if (info) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue