Implement MusicManager fade-out in stopMusic() — was a stub

stopMusic(fadeMs) previously had (void)fadeMs with no fade logic.
Added fadingOut/fadeOutTimer/fadeOutDuration/fadeOutStartVolume state
and wired update() to interpolate volume to zero then stop playback.
Also clean up DuelProposedPacket comment (removed misleading TODO label).
This commit is contained in:
Kelsi 2026-03-09 16:30:42 -07:00
parent f2eabc87ef
commit 13e3e5ea35
3 changed files with 40 additions and 11 deletions

View file

@ -52,6 +52,11 @@ private:
float fadeInTimer = 0.0f;
float fadeInDuration = 0.0f;
float fadeInTargetVolume = 0.0f;
// Fade-out state (for stopMusic with fadeMs > 0)
bool fadingOut = false;
float fadeOutTimer = 0.0f;
float fadeOutDuration = 0.0f;
float fadeOutStartVolume = 0.0f;
std::unordered_map<std::string, std::vector<uint8_t>> musicDataCache_;
};

View file

@ -144,15 +144,24 @@ void MusicManager::playFilePath(const std::string& filePath, bool loop, float fa
}
void MusicManager::stopMusic(float fadeMs) {
(void)fadeMs; // Fade not implemented yet
AudioEngine::instance().stopMusic();
playing = false;
if (!playing) return;
fadingIn = false;
fadeInTimer = 0.0f;
fadeInDuration = 0.0f;
fadeInTargetVolume = 0.0f;
currentTrack.clear();
currentTrackIsFile = false;
crossfading = false;
if (fadeMs > 0.0f) {
// Begin fade-out; actual stop happens once volume reaches zero in update()
fadingOut = true;
fadeOutTimer = 0.0f;
fadeOutDuration = fadeMs / 1000.0f;
fadeOutStartVolume = effectiveMusicVolume();
} else {
AudioEngine::instance().stopMusic();
playing = false;
fadingOut = false;
currentTrack.clear();
currentTrackIsFile = false;
}
}
void MusicManager::setVolume(int volume) {
@ -224,6 +233,22 @@ void MusicManager::update(float deltaTime) {
playing = false;
}
if (fadingOut) {
fadeOutTimer += deltaTime;
float t = std::clamp(1.0f - fadeOutTimer / std::max(fadeOutDuration, 0.001f), 0.0f, 1.0f);
AudioEngine::instance().setMusicVolume(fadeOutStartVolume * t);
if (t <= 0.0f) {
// Fade complete — stop playback and restore volume for next track
fadingOut = false;
AudioEngine::instance().stopMusic();
AudioEngine::instance().setMusicVolume(effectiveMusicVolume());
playing = false;
currentTrack.clear();
currentTrackIsFile = false;
}
return; // Don't process other fade logic while fading out
}
if (fadingIn) {
fadeInTimer += deltaTime;
float t = std::clamp(fadeInTimer / std::max(fadeInDuration, 0.001f), 0.0f, 1.0f);

View file

@ -2131,9 +2131,8 @@ network::Packet RequestRaidInfoPacket::build() {
// ============================================================
network::Packet DuelProposedPacket::build(uint64_t targetGuid) {
// TODO: Duels are initiated via CMSG_CAST_SPELL with spell 7266,
// not a dedicated CMSG_DUEL_PROPOSED opcode (which doesn't exist in WoW).
// For now, build a cast spell packet targeting the opponent.
// Duels are initiated via CMSG_CAST_SPELL with spell 7266 (Duel) targeted at the opponent.
// There is no separate CMSG_DUEL_PROPOSED opcode in WoW.
auto packet = CastSpellPacket::build(7266, targetGuid, 0);
LOG_DEBUG("Built duel request (spell 7266) for target: 0x", std::hex, targetGuid, std::dec);
return packet;