Core/Pools: Fix pools with 1 member never spawning anything anymore (#26620)

* Core/Pools: Fix pools with 1 member never spawning anything anymore

Attempts to fix a 6 years old bug and never fixed by the original author.

* Remove respawn times from db once a respawn has been handled

* Allow to specify if Despawn1Object() should save or not the respawn time. We don't need to do that when respawning an object.

* Apply the same fix to GameObjects too
This commit is contained in:
Giacomo Pozzoni
2021-06-26 14:21:18 +02:00
committed by GitHub
parent 6c5b641dd4
commit c8ca48823d
4 changed files with 23 additions and 15 deletions

View File

@@ -1665,9 +1665,12 @@ bool Creature::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap,
return false;
}
}
else
{
// compatibility mode creatures will be respawned in ::Update()
m_deathState = DEAD;
}
// compatibility mode creatures will be respawned in ::Update()
m_deathState = DEAD;
if (CanFly())
{
float tz = map->GetHeight(GetPhaseMask(), data->spawnPoint, true, MAX_FALL_DISTANCE);

View File

@@ -3267,6 +3267,7 @@ void Map::ProcessRespawns()
sPoolMgr->UpdatePool(poolId, next->type, next->spawnId);
// step 3: get rid of the actual entry
RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
delete next;
}
else if (CheckRespawn(next)) // see if we're allowed to respawn
@@ -3279,12 +3280,14 @@ void Map::ProcessRespawns()
DoRespawn(next->type, next->spawnId, next->gridId);
// step 3: get rid of the actual entry
RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
delete next;
}
else if (!next->respawnTime)
{ // just remove this respawn entry without rescheduling
_respawnTimes.pop();
GetRespawnMapForType(next->type).erase(next->spawnId);
RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
delete next;
}
else

View File

@@ -168,7 +168,7 @@ void PoolGroup<T>::DespawnObject(ActivePoolData& spawns, ObjectGuid::LowType gui
// Method that is actualy doing the removal job on one creature
template<>
void PoolGroup<Creature>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime)
void PoolGroup<Creature>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime, bool saveRespawnTime)
{
if (CreatureData const* data = sObjectMgr->GetCreatureData(guid))
{
@@ -183,7 +183,7 @@ void PoolGroup<Creature>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDe
Creature* creature = itr->second;
++itr;
// For dynamic spawns, save respawn time here
if (!creature->GetRespawnCompatibilityMode())
if (saveRespawnTime && !creature->GetRespawnCompatibilityMode())
creature->SaveRespawnTime();
creature->AddObjectToRemoveList();
}
@@ -196,7 +196,7 @@ void PoolGroup<Creature>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDe
// Same on one gameobject
template<>
void PoolGroup<GameObject>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime)
void PoolGroup<GameObject>::Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime, bool saveRespawnTime)
{
if (GameObjectData const* data = sObjectMgr->GetGameObjectData(guid))
{
@@ -212,7 +212,7 @@ void PoolGroup<GameObject>::Despawn1Object(ObjectGuid::LowType guid, bool always
++itr;
// For dynamic spawns, save respawn time here
if (!go->GetRespawnCompatibilityMode())
if (saveRespawnTime && !go->GetRespawnCompatibilityMode())
go->SaveRespawnTime();
go->AddObjectToRemoveList();
}
@@ -225,7 +225,7 @@ void PoolGroup<GameObject>::Despawn1Object(ObjectGuid::LowType guid, bool always
// Same on one pool
template<>
void PoolGroup<Pool>::Despawn1Object(uint32 child_pool_id, bool alwaysDeleteRespawnTime)
void PoolGroup<Pool>::Despawn1Object(uint32 child_pool_id, bool alwaysDeleteRespawnTime, bool /*saveRespawnTime*/)
{
sPoolMgr->DespawnPool(child_pool_id, alwaysDeleteRespawnTime);
}
@@ -278,7 +278,7 @@ void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 trig
roll -= obj.chance;
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
// so this need explicit check for this case
if (roll < 0 && (/*obj.guid == triggerFrom ||*/ !spawns.IsActiveObject<T>(obj.guid)))
if (roll < 0 && (obj.guid == triggerFrom || !spawns.IsActiveObject<T>(obj.guid)))
{
rolledObjects.push_back(obj);
break;
@@ -288,9 +288,9 @@ void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 trig
if (!EqualChanced.empty() && rolledObjects.empty())
{
std::copy_if(EqualChanced.begin(), EqualChanced.end(), std::back_inserter(rolledObjects), [/*triggerFrom, */&spawns](PoolObject const& object)
std::copy_if(EqualChanced.begin(), EqualChanced.end(), std::back_inserter(rolledObjects), [triggerFrom, &spawns](PoolObject const& object)
{
return /*object.guid == triggerFrom ||*/ !spawns.IsActiveObject<T>(object.guid);
return object.guid == triggerFrom || !spawns.IsActiveObject<T>(object.guid);
});
Trinity::Containers::RandomResize(rolledObjects, count);
@@ -379,16 +379,18 @@ void PoolGroup<Pool>::Spawn1Object(PoolObject* obj)
// Method that does the respawn job on the specified creature
template <>
void PoolGroup<Creature>::ReSpawn1Object(PoolObject* /*obj*/)
void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj)
{
// Creature is still on map, nothing to do
Despawn1Object(obj->guid, false, false);
Spawn1Object(obj);
}
// Method that does the respawn job on the specified gameobject
template <>
void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* /*obj*/)
void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj)
{
// GameObject is still on map, nothing to do
Despawn1Object(obj->guid, false, false);
Spawn1Object(obj);
}
// Nothing to do for a child Pool

View File

@@ -73,7 +73,7 @@ class TC_GAME_API PoolGroup
void AddEntry(PoolObject& poolitem, uint32 maxentries);
bool CheckPool() const;
void DespawnObject(ActivePoolData& spawns, ObjectGuid::LowType guid=0, bool alwaysDeleteRespawnTime = false);
void Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime = false);
void Despawn1Object(ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime = false, bool saveRespawnTime = true);
void SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 triggerFrom);
void RemoveRespawnTimeFromDB(ObjectGuid::LowType guid);