fix(Core/SAI): Update SMART_ACTION_FORCE_DESPAWN to allow temporarily despawning gameobjects (#8340)

* fix(Core/SAI): Update SMART_ACTION_FORCE_DESPAWN to allow temporarily despawning gameobjects

* brackets

* Some improvements

* restore the virtual
This commit is contained in:
Skjalf
2021-10-14 08:23:59 -03:00
committed by GitHub
parent a8643f27b2
commit 3894dfc897
3 changed files with 93 additions and 13 deletions

View File

@@ -53,6 +53,8 @@ GameObject::GameObject() : WorldObject(false), MovableMapObject(),
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
m_respawnDelayTime = 300;
m_despawnDelay = 0;
m_despawnRespawnTime = 0s;
m_lootState = GO_NOT_READY;
m_spawnedByDefault = true;
m_allowModifyDestructibleBuilding = true;
@@ -399,6 +401,19 @@ void GameObject::Update(uint32 diff)
else if (!AIM_Initialize())
LOG_ERROR("entities.gameobject", "Could not initialize GameObjectAI");
if (m_despawnDelay)
{
if (m_despawnDelay > diff)
{
m_despawnDelay -= diff;
}
else
{
m_despawnDelay = 0;
DespawnOrUnsummon(0ms, m_despawnRespawnTime);
}
}
switch (m_lootState)
{
case GO_NOT_READY:
@@ -811,6 +826,47 @@ void GameObject::AddUniqueUse(Player* player)
m_unique_users.insert(player->GetGUID());
}
void GameObject::DespawnOrUnsummon(Milliseconds delay, Seconds forceRespawnTime)
{
if (delay > 0ms)
{
if (!m_despawnDelay || m_despawnDelay > delay.count())
{
m_despawnDelay = delay.count();
m_despawnRespawnTime = forceRespawnTime;
}
}
else
{
if (m_goData)
{
int32 const respawnDelay = (forceRespawnTime > 0s) ? forceRespawnTime.count() : m_goData->spawntimesecs;
SetRespawnTime(respawnDelay);
}
// Respawn is handled by the gameobject itself.
// If we delete it from world, it simply never respawns...
// Uncomment this and remove the following lines if dynamic spawn is implemented.
// Delete();
{
SetLootState(GO_JUST_DEACTIVATED);
SendObjectDeSpawnAnim(GetGUID());
SetGoState(GO_STATE_READY);
if (GameObjectTemplateAddon const* addon = GetTemplateAddon())
{
SetUInt32Value(GAMEOBJECT_FLAGS, addon->flags);
}
uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool<GameObject>(m_spawnId) : 0;
if (poolid)
{
sPoolMgr->UpdatePool<GameObject>(poolid, m_spawnId);
}
}
}
}
void GameObject::Delete()
{
SetLootState(GO_NOT_READY);
@@ -1075,10 +1131,13 @@ Unit* GameObject::GetOwner() const
return ObjectAccessor::GetUnit(*this, GetOwnerGUID());
}
void GameObject::SaveRespawnTime()
void GameObject::SaveRespawnTime(uint32 forceDelay)
{
if (m_goData && m_goData->dbData && m_respawnTime > time(nullptr) && m_spawnedByDefault)
GetMap()->SaveGORespawnTime(m_spawnId, m_respawnTime);
if (m_goData && m_goData->dbData && (forceDelay || m_respawnTime > time(nullptr)) && m_spawnedByDefault)
{
time_t respawnTime = forceDelay ? time(nullptr) + forceDelay : m_respawnTime;
GetMap()->SaveGORespawnTime(m_spawnId, respawnTime);
}
}
bool GameObject::IsNeverVisible() const
@@ -1132,6 +1191,16 @@ bool GameObject::IsInvisibleDueToDespawn() const
return false;
}
void GameObject::SetRespawnTime(int32 respawn)
{
m_respawnTime = respawn > 0 ? time(nullptr) + respawn : 0;
m_respawnDelayTime = respawn > 0 ? respawn : 0;
if (respawn && !m_spawnedByDefault)
{
UpdateObjectVisibility(true);
}
}
void GameObject::Respawn()
{
if (m_spawnedByDefault && m_respawnTime > 0)