fix: client timer fallback re-sent CMSG_GAMEOBJ_USE and cleared loot guid

When the client-side cast timer expired slightly before SMSG_SPELL_GO
arrived, the fallback at update():1367 called performGameObjectInteraction
Now which sent a DUPLICATE CMSG_GAMEOBJ_USE to the server (confusing its
GO state machine), then resetCastState() cleared lastInteractedGoGuid_.
When SMSG_SPELL_GO finally arrived, the guid was gone so CMSG_LOOT was
never sent — quest chests produced no loot window.

Fix: the fallback no longer re-sends USE (server drives the interaction
via SMSG_SPELL_GO). resetCastState() no longer clears
lastInteractedGoGuid_ so the SMSG_SPELL_GO handler can still send LOOT.
This commit is contained in:
Kelsi 2026-03-29 22:45:17 -07:00
parent 785f03a599
commit cfbae93ce3
2 changed files with 11 additions and 5 deletions

View file

@ -1362,13 +1362,15 @@ void GameHandler::update(float deltaTime) {
addSystemChatMessage("Interrupted.");
}
// Check if client-side cast timer expired (tick-down is in SpellHandler::updateTimers).
// SMSG_SPELL_GO normally clears casting, but GO interaction casts are client-timed
// and need this fallback to trigger the loot/use action.
// For GO interaction casts, do NOT re-send CMSG_GAMEOBJ_USE — the server
// drives the interaction and sends SMSG_SPELL_GO + SMSG_LOOT_RESPONSE when
// the cast completes. Re-sending USE here sent a duplicate packet that
// confused the server's GO state machine, and resetCastState() then cleared
// lastInteractedGoGuid_ so the subsequent SMSG_SPELL_GO couldn't trigger loot.
if (spellHandler_ && spellHandler_->casting_ && spellHandler_->castTimeRemaining_ <= 0.0f) {
if (pendingGameObjectInteractGuid_ != 0) {
uint64_t interactGuid = pendingGameObjectInteractGuid_;
// Let the server finish — just clear the pending flag.
pendingGameObjectInteractGuid_ = 0;
performGameObjectInteractionNow(interactGuid);
}
spellHandler_->resetCastState();
}