mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +00:00
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:
parent
6b5e924027
commit
785f03a599
2 changed files with 13 additions and 5 deletions
|
|
@ -6226,10 +6226,13 @@ void GameHandler::performGameObjectInteractionNow(uint64_t guid) {
|
|||
lastInteractedGoGuid_ = guid;
|
||||
|
||||
if (chestLike) {
|
||||
// Chest-like GOs also need a CMSG_LOOT to open the loot window.
|
||||
// Sent in the same frame: USE transitions the GO to lootable state,
|
||||
// then LOOT requests the contents.
|
||||
lootTarget(guid);
|
||||
// Don't send CMSG_LOOT immediately — the server may start a timed cast
|
||||
// (e.g., "Opening") and the GO isn't lootable until the cast finishes.
|
||||
// Sending LOOT prematurely gets an empty response or is silently dropped,
|
||||
// which can interfere with the server's loot state machine.
|
||||
// Instead, handleSpellGo will send LOOT after the cast completes
|
||||
// (using lastInteractedGoGuid_ set above). For instant-open chests
|
||||
// (no cast), the server sends SMSG_LOOT_RESPONSE directly after USE.
|
||||
} else if (isMailbox) {
|
||||
LOG_INFO("Mailbox interaction: opening mail UI and requesting mail list");
|
||||
mailboxGuid_ = guid;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue