fix: stale GO interaction guard broke future casts; premature LOOT interfered

Two remaining GO interaction bugs:

1. pendingGameObjectInteractGuid_ was never cleared after SMSG_SPELL_GO
   or SMSG_CAST_FAILED, leaving it stale. This suppressed CMSG_CANCEL_CAST
   for ALL subsequent spell casts (not just GO casts), causing the server
   to think the player was still casting when they weren't.

2. For chest-like GOs, CMSG_LOOT was sent simultaneously with
   CMSG_GAMEOBJ_USE. If the server starts a timed cast ("Opening"),
   the GO isn't lootable until the cast completes — the premature LOOT
   gets an empty response or is dropped, potentially corrupting the
   server's loot state. Now defers LOOT to handleSpellGo which sends it
   after the cast completes (via lastInteractedGoGuid_).
This commit is contained in:
Kelsi 2026-03-29 22:36:30 -07:00
parent 6b5e924027
commit 785f03a599
2 changed files with 13 additions and 5 deletions

View file

@ -794,6 +794,7 @@ void SpellHandler::handleCastFailed(network::Packet& packet) {
currentCastSpellId_ = 0;
castTimeRemaining_ = 0.0f;
owner_.lastInteractedGoGuid_ = 0;
owner_.pendingGameObjectInteractGuid_ = 0;
craftQueueSpellId_ = 0;
craftQueueRemaining_ = 0;
queuedSpellId_ = 0;
@ -952,11 +953,15 @@ void SpellHandler::handleSpellGo(network::Packet& packet) {
currentCastSpellId_ = 0;
castTimeRemaining_ = 0.0f;
// Gather node looting
// Gather node looting: re-send CMSG_LOOT now that the cast completed.
if (wasInTimedCast && owner_.lastInteractedGoGuid_ != 0) {
owner_.lootTarget(owner_.lastInteractedGoGuid_);
owner_.lastInteractedGoGuid_ = 0;
}
// Clear the GO interaction guard so future cancelCast() calls work
// normally. Without this, pendingGameObjectInteractGuid_ stays stale
// and suppresses CMSG_CANCEL_CAST for ALL subsequent spell casts.
owner_.pendingGameObjectInteractGuid_ = 0;
if (owner_.spellCastAnimCallback_) {
owner_.spellCastAnimCallback_(owner_.playerGuid, false, false);