aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-02-13 22:08:49 +0100
committerShauren <shauren.trinity@gmail.com>2021-06-20 21:49:11 +0200
commitbccd81e12ac418d2ba76c1cd6470c813a4d19229 (patch)
tree44cbd40476319ae3faf1107814af028e9f4e7e4f
parentbd158f6c29581e08633c3971a130b0720f90b630 (diff)
Entities/GO: GameObjects now support (delayed) despawning in a reasonable manner. Closes #21406.
(cherry picked from commit f071fa9e931533c28e6b9d8b0e38ed8878ce2b45)
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp26
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
3 files changed, 28 insertions, 2 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 1dd8649b6f8..976491c65be 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1058,7 +1058,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
creature->DespawnOrUnsummon(respawnDelay);
}
else if (GameObject* goTarget = target->ToGameObject())
- goTarget->SetRespawnTime(respawnDelay);
+ goTarget->DespawnOrUnsummon(Milliseconds(respawnDelay));
}
break;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index b6e621c13b4..0dfb70f1a9c 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -117,6 +117,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_respawnTime = 0;
m_respawnDelayTime = 300;
+ m_despawnDelay = 0;
m_lootState = GO_NOT_READY;
m_spawnedByDefault = true;
m_usetimes = 0;
@@ -518,6 +519,14 @@ void GameObject::Update(uint32 diff)
else if (!AIM_Initialize())
TC_LOG_ERROR("misc", "Could not initialize GameObjectAI");
+ if (m_despawnDelay)
+ {
+ if (m_despawnDelay > diff)
+ m_despawnDelay -= diff;
+ else
+ DespawnOrUnsummon();
+ }
+
switch (m_lootState)
{
case GO_NOT_READY:
@@ -945,6 +954,21 @@ void GameObject::AddUniqueUse(Player* player)
m_unique_users.insert(player->GetGUID());
}
+void GameObject::DespawnOrUnsummon(Milliseconds const& delay)
+{
+ if (delay > Milliseconds::zero())
+ {
+ if (!m_despawnDelay || m_despawnDelay > delay.count())
+ m_despawnDelay = delay.count();
+ }
+ else
+ {
+ if (m_goData && m_respawnDelayTime)
+ SaveRespawnTime(m_respawnDelayTime);
+ Delete();
+ }
+}
+
void GameObject::Delete()
{
SetLootState(GO_NOT_READY);
@@ -1266,7 +1290,7 @@ Unit* GameObject::GetOwner() const
void GameObject::SaveRespawnTime(uint32 forceDelay, bool savetodb)
{
- if (m_goData && m_respawnTime > GameTime::GetGameTime() && m_spawnedByDefault)
+ if (m_goData && (forceDelay || m_respawnTime > GameTime::GetGameTime()) && m_spawnedByDefault)
{
if (m_respawnCompatibilityMode)
{
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index ea4d55f963d..0a59323fe5c 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -164,6 +164,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void SetSpawnedByDefault(bool b) { m_spawnedByDefault = b; }
uint32 GetRespawnDelay() const { return m_respawnDelayTime; }
void Refresh();
+ void DespawnOrUnsummon(Milliseconds const& delay = 0ms);
void Delete();
void SendGameObjectDespawn();
void getFishLoot(Loot* loot, Player* loot_owner);
@@ -316,6 +317,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
uint32 m_spellId;
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer
+ uint32 m_despawnDelay;
LootState m_lootState;
ObjectGuid m_lootStateUnitGUID; // GUID of the unit passed with SetLootState(LootState, Unit*)
bool m_spawnedByDefault;