From e56d3ca7deed4cb74d151e9dd0170df22f53ba31 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 9 Mar 2026 19:36:58 -0700 Subject: [PATCH] Add spell impact sounds for player-targeted spells and improve achievement messages - Play SpellSoundManager::playImpact() with correct school when the player is hit by another unit's spell (SMSG_SPELL_GO hitTargets check) - Show achievement name in SMSG_SERVER_FIRST_ACHIEVEMENT notifications using the already-loaded achievementNameCache_ - playImpact was fully implemented but never called; now wired up --- src/game/game_handler.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index e97ff85b..3c4d3bf9 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -4545,10 +4545,18 @@ void GameHandler::handlePacket(network::Packet& packet) { if (packet.getSize() - packet.getReadPos() >= 12) { /*uint64_t guid =*/ packet.readUInt64(); uint32_t achievementId = packet.readUInt32(); - char buf[192]; - std::snprintf(buf, sizeof(buf), - "%s is the first on the realm to earn achievement #%u!", - charName.c_str(), achievementId); + loadAchievementNameCache(); + auto nit = achievementNameCache_.find(achievementId); + char buf[256]; + if (nit != achievementNameCache_.end() && !nit->second.empty()) { + std::snprintf(buf, sizeof(buf), + "%s is the first on the realm to earn: %s!", + charName.c_str(), nit->second.c_str()); + } else { + std::snprintf(buf, sizeof(buf), + "%s is the first on the realm to earn achievement #%u!", + charName.c_str(), achievementId); + } addSystemChatMessage(buf); } } @@ -12169,6 +12177,24 @@ void GameHandler::handleSpellGo(network::Packet& packet) { currentCastSpellId = 0; castTimeRemaining = 0.0f; } + + // Play impact sound when player is hit by any spell (from self or others) + bool playerIsHit = false; + for (const auto& tgt : data.hitTargets) { + if (tgt == playerGuid) { playerIsHit = true; break; } + } + if (playerIsHit && data.casterUnit != playerGuid) { + if (auto* renderer = core::Application::getInstance().getRenderer()) { + if (auto* ssm = renderer->getSpellSoundManager()) { + loadSpellNameCache(); + auto it = spellNameCache_.find(data.spellId); + auto school = (it != spellNameCache_.end() && it->second.schoolMask) + ? schoolMaskToMagicSchool(it->second.schoolMask) + : audio::SpellSoundManager::MagicSchool::ARCANE; + ssm->playImpact(school, audio::SpellSoundManager::SpellPower::MEDIUM); + } + } + } } void GameHandler::handleSpellCooldown(network::Packet& packet) {