game: fix SMSG_SPELL_GO miss-entry consumption in WotLK and TBC parsers

Both SpellGoParser::parse (WotLK) and TbcPacketParsers::parseSpellGo
(TBC) read missCount but did not consume the per-miss (guid + missType)
entries that follow, leaving unread bytes in the packet and silently
corrupting any subsequent parsing of cast-flags–gated spell data.

- Add SpellGoMissEntry{targetGuid, missType} and missTargets vector
  to SpellGoData
- WotLK parser now reads packed GUIDs + missType per miss entry
- TBC parser now reads full uint64 GUIDs + missType per miss entry
  (9 bytes per entry, bounds-checked)
- handleSpellGo now shows MISS/DODGE/PARRY/BLOCK combat text
  for each missed target when the local player cast the spell,
  complementing the existing SMSG_SPELLLOGMISS path
- Remove unused foliageLikeModel variable in m2_renderer pass-2 loop
  (fix unused-variable warning)
- Update smoke model comment in m2_renderer to reflect current state
This commit is contained in:
Kelsi 2026-03-09 23:00:21 -07:00
parent 06a628dae2
commit 6951b7803d
5 changed files with 42 additions and 4 deletions

View file

@ -12713,6 +12713,26 @@ void GameHandler::handleSpellGo(network::Packet& packet) {
castTimeRemaining = 0.0f;
}
// Show miss/dodge/parry/etc combat text when player's spells miss targets
if (data.casterUnit == playerGuid && !data.missTargets.empty()) {
static const CombatTextEntry::Type missTypes[] = {
CombatTextEntry::MISS, // 0=MISS
CombatTextEntry::DODGE, // 1=DODGE
CombatTextEntry::PARRY, // 2=PARRY
CombatTextEntry::BLOCK, // 3=BLOCK
CombatTextEntry::MISS, // 4=EVADE → show as MISS
CombatTextEntry::MISS, // 5=IMMUNE → show as MISS
CombatTextEntry::MISS, // 6=DEFLECT
CombatTextEntry::MISS, // 7=ABSORB
CombatTextEntry::MISS, // 8=RESIST
};
// Show text for each miss (usually just 1 target per spell go)
for (const auto& m : data.missTargets) {
CombatTextEntry::Type ct = (m.missType < 9) ? missTypes[m.missType] : CombatTextEntry::MISS;
addCombatText(ct, 0, 0, true);
}
}
// Play impact sound when player is hit by any spell (from self or others)
bool playerIsHit = false;
for (const auto& tgt : data.hitTargets) {