From 982be6de008181d7deb75cd8060c13e165a0a4e6 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sat, 19 Feb 2022 22:26:26 +0100 Subject: [PATCH] fix(Core/GameObjects): move activation code of traps to GO_ACTIVATED (#10537) - Original author: @Gacko --- .../game/Entities/Creature/Creature.cpp | 5 +- .../game/Entities/GameObject/GameObject.cpp | 68 ++++++++++++------- .../game/Entities/GameObject/GameObject.h | 2 + 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 1b9ff285e..fdbe3a40e 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -651,7 +651,10 @@ void Creature::Update(uint32 diff) m_groupLootTimer = 0; lootingGroupLowGUID = 0; } - else m_groupLootTimer -= diff; + else + { + m_groupLootTimer -= diff; + } } else if (m_corpseRemoveTime <= GameTime::GetGameTime().count()) { diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 834f1da52..25cd488c3 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -651,15 +651,10 @@ void GameObject::Update(uint32 diff) // Type 2 - Bomb (will go away after casting it's spell) if (goInfo->trap.type == 2) { - if (goInfo->trap.spellId) - CastSpell(nullptr, goInfo->trap.spellId); // FIXME: null target won't work for target type 1 - SetLootState(GO_JUST_DEACTIVATED); + SetLootState(GO_ACTIVATED); break; } - // Type 0 despawns after being triggered, type 1 does not. - bool isBattlegroundTrap = false; - /// @todo This is activation radius. Casting radius must be selected from spell data. /// @todo Move activated state code to GO_ACTIVATED, in this place just check for activation and set state. float radius = float(goInfo->trap.diameter) * 0.5f; @@ -667,10 +662,10 @@ void GameObject::Update(uint32 diff) { // Cast in other case (at some triggering/linked go/etc explicit call) if (goInfo->trap.cooldown != 3 || m_respawnTime > 0) + { break; + } - // Battleground gameobjects have data2 == 0 && data5 == 3 - isBattlegroundTrap = true; radius = 3.f; } @@ -699,22 +694,7 @@ void GameObject::Update(uint32 diff) if (target) { - // some traps do not have spell but should be triggered - if (goInfo->trap.spellId) - CastSpell(target, goInfo->trap.spellId); - - m_cooldownTime = GameTime::GetGameTimeMS().count() + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)) * IN_MILLISECONDS; // template or 4 seconds - - if (goInfo->trap.type == 1) - SetLootState(GO_JUST_DEACTIVATED); - - if (isBattlegroundTrap && target->GetTypeId() == TYPEID_PLAYER) - { - // battleground gameobjects case - if (target->ToPlayer()->InBattleground()) - if (Battleground* bg = target->ToPlayer()->GetBattleground()) - bg->HandleTriggerBuff(this); - } + SetLootState(GO_ACTIVATED, target); } } else if (uint32 max_charges = goInfo->GetCharges()) @@ -757,8 +737,41 @@ void GameObject::Update(uint32 diff) m_groupLootTimer = 0; lootingGroupLowGUID = 0; } - else m_groupLootTimer -= diff; + else + { + m_groupLootTimer -= diff; + } } + break; + case GAMEOBJECT_TYPE_TRAP: + { + GameObjectTemplate const* goInfo = GetGOInfo(); + if (goInfo->trap.type == 2) + { + if (goInfo->trap.spellId) + CastSpell(nullptr, goInfo->trap.spellId); // FIXME: null target won't work for target type 1 + SetLootState(GO_JUST_DEACTIVATED); + } + else if (Unit* target = ObjectAccessor::GetUnit(*this, _lootStateUnitGUID)) + { + if (goInfo->trap.spellId) + CastSpell(target, goInfo->trap.spellId); + + m_cooldownTime = GameTime::GetGameTimeMS().count() + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)) * IN_MILLISECONDS; // template or 4 seconds + + if (goInfo->trap.type == 1) + SetLootState(GO_JUST_DEACTIVATED); + else if (!goInfo->trap.type) + SetLootState(GO_READY); + + // Battleground gameobjects have data2 == 0 && data5 == 3 + if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) + if (Player* player = target->ToPlayer()) + if (Battleground* bg = player->GetBattleground()) + bg->HandleTriggerBuff(this); + } + break; + } default: break; } @@ -2366,6 +2379,11 @@ void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; + if (unit) + _lootStateUnitGUID = unit->GetGUID(); + else + _lootStateUnitGUID.Clear(); + AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); // pussywizard: lootState has nothing to do with collision, it depends entirely on GOState. Loot state is for timed close/open door and respawning, which then sets GOState diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 4bd2aca7b..a9337760e 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -1021,6 +1021,8 @@ protected: ObjectGuid m_linkedTrap; + ObjectGuid _lootStateUnitGUID; + private: void CheckRitualList(); void ClearRitualList();