audio: stop precast sound on spell completion, failure, or interrupt

Add AudioEngine::playSound2DStoppable() + stopSound() so callers can
hold a handle and cancel playback early. SpellSoundManager::playPrecast()
now stores the handle in activePrecastId_; stopPrecast() cuts the sound.

playCast() calls stopPrecast() before playing the release sound, so the
channeling audio never bleeds past cast time. SMSG_SPELL_FAILURE and
SMSG_CAST_FAILED both call stopPrecast() so interrupted casts silence
immediately.
This commit is contained in:
Kelsi 2026-03-09 21:04:24 -07:00
parent e0d47040d3
commit 9d1616a11b
5 changed files with 100 additions and 3 deletions

View file

@ -2516,6 +2516,11 @@ void GameHandler::handlePacket(network::Packet& packet) {
// Spell failed mid-cast
casting = false;
currentCastSpellId = 0;
if (auto* renderer = core::Application::getInstance().getRenderer()) {
if (auto* ssm = renderer->getSpellSoundManager()) {
ssm->stopPrecast();
}
}
break;
case Opcode::SMSG_SPELL_COOLDOWN:
handleSpellCooldown(packet);
@ -12368,6 +12373,13 @@ void GameHandler::handleCastFailed(network::Packet& packet) {
currentCastSpellId = 0;
castTimeRemaining = 0.0f;
// Stop precast sound — spell failed before completing
if (auto* renderer = core::Application::getInstance().getRenderer()) {
if (auto* ssm = renderer->getSpellSoundManager()) {
ssm->stopPrecast();
}
}
// Add system message about failed cast with readable reason
int powerType = -1;
auto playerEntity = entityManager.getEntity(playerGuid);