feat: show spell failure reason in chat from SMSG_SPELL_FAILURE

SMSG_SPELL_FAILURE carries a failReason byte (same enum as SMSG_CAST_RESULT)
that was previously ignored. Now parse castCount+spellId+failReason and
display the localized reason string for the player's interrupted casts
(e.g. 'Interrupted', 'Stunned', 'Can\'t do that while moving').
This commit is contained in:
Kelsi 2026-03-11 03:42:41 -07:00
parent 1446d4fddd
commit 144c87a72f

View file

@ -2752,6 +2752,27 @@ void GameHandler::handlePacket(network::Packet& packet) {
uint64_t failGuid = tbcOrClassic
? (packet.getSize() - packet.getReadPos() >= 8 ? packet.readUInt64() : 0)
: UpdateObjectParser::readPackedGuid(packet);
// Read castCount + spellId + failReason
if (packet.getSize() - packet.getReadPos() >= 6) {
/*uint8_t castCount =*/ packet.readUInt8();
/*uint32_t spellId =*/ packet.readUInt32();
uint8_t failReason = packet.readUInt8();
if (failGuid == playerGuid && failReason != 0) {
// Show interruption/failure reason in chat for player
int pt = -1;
if (auto pe = entityManager.getEntity(playerGuid))
if (auto pu = std::dynamic_pointer_cast<Unit>(pe))
pt = static_cast<int>(pu->getPowerType());
const char* reason = getSpellCastResultString(failReason, pt);
if (reason) {
MessageChatData emsg;
emsg.type = ChatType::SYSTEM;
emsg.language = ChatLanguage::UNIVERSAL;
emsg.message = reason;
addLocalChatMessage(emsg);
}
}
}
if (failGuid == playerGuid || failGuid == 0) {
// Player's own cast failed
casting = false;