From 072cc4d0431ef9e8f5e3672b5e5dcbc7082d8064 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 5 Aug 2018 21:28:10 +0200 Subject: [PATCH] Core/SAI: added missing changes for SMART_ACTION_FORCE_DESPAWN that was causing broken despawn actions --- .../game/AI/SmartScripts/SmartScript.cpp | 20 ++++++++----------- .../game/AI/SmartScripts/SmartScriptMgr.h | 1 + .../game/Entities/GameObject/GameObject.cpp | 10 ++++------ .../game/Entities/GameObject/GameObject.h | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 66e1129d2ab..f3a7f295be0 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1046,22 +1046,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_FORCE_DESPAWN: { // there should be at least a world update tick before despawn, to avoid breaking linked actions - int32 const respawnDelay = std::max(e.action.forceDespawn.delay, 1); + Milliseconds despawnDelay(e.action.forceDespawn.delay); + if (despawnDelay <= 0ms) + despawnDelay = 1ms; + + Seconds forceRespawnTimer(e.action.forceDespawn.forceRespawnTimer); for (WorldObject* target : targets) { - if (Creature* creatureTarget = target->ToCreature()) - { - if (SmartAI* smartAI = CAST_AI(SmartAI, creatureTarget->AI())) - { - smartAI->SetDespawnTime(respawnDelay); - smartAI->StartDespawn(); - } - else - creatureTarget->DespawnOrUnsummon(respawnDelay); - } + if (Creature* creature = target->ToCreature()) + creature->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); else if (GameObject* goTarget = target->ToGameObject()) - goTarget->DespawnOrUnsummon(Milliseconds(respawnDelay)); + goTarget->DespawnOrUnsummon(despawnDelay, forceRespawnTimer); } break; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 3305ce683d1..fd96ceee0a1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -784,6 +784,7 @@ struct SmartAction struct { uint32 delay; + uint32 forceRespawnTimer; } forceDespawn; struct diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 9c31b0924cf..f2d0a503e4f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -389,7 +389,7 @@ void GameObject::Update(uint32 diff) else { m_despawnDelay = 0; - DespawnOrUnsummon(0ms, m_despawnRespawnTime);; + DespawnOrUnsummon(0ms, m_despawnRespawnTime); } } @@ -809,7 +809,7 @@ void GameObject::AddUniqueUse(Player* player) m_unique_users.insert(player->GetGUID()); } -void GameObject::DespawnOrUnsummon(Milliseconds delay, Seconds forceRespawnTime) +void GameObject::DespawnOrUnsummon(Milliseconds const& delay, Seconds const& forceRespawnTime) { if (delay > 0ms) { @@ -821,11 +821,9 @@ void GameObject::DespawnOrUnsummon(Milliseconds delay, Seconds forceRespawnTime) } else { - if (m_goData) - { - uint32 const respawnDelay = (forceRespawnTime > 0s) ? forceRespawnTime.count() : m_goData->spawntimesecs; + uint32 const respawnDelay = (forceRespawnTime > 0s) ? forceRespawnTime.count() : m_respawnDelayTime; + if (m_goData && respawnDelay) SaveRespawnTime(respawnDelay); - } Delete(); } } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index be9a54036d2..ffe8a94fd44 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -153,7 +153,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject void SetSpawnedByDefault(bool b) { m_spawnedByDefault = b; } uint32 GetRespawnDelay() const { return m_respawnDelayTime; } void Refresh(); - void DespawnOrUnsummon(Milliseconds delay = 0ms, Seconds forceRespawnTime = 0s); + void DespawnOrUnsummon(Milliseconds const& delay = 0ms, Seconds const& forceRespawnTime = 0s); void Delete(); void SendGameObjectDespawn(); void getFishLoot(Loot* loot, Player* loot_owner);