aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-12-30 21:08:22 +0100
committerGitHub <noreply@github.com>2020-12-30 21:08:22 +0100
commitf8afcec9f3efc58ce8a38a6c63e2ebfc24d2e01d (patch)
tree725a62d14988ec5c99d93769510ff92ef5d36c8c /src
parent0ad1854d1c6a3b6ff93e71272c919f1f5f11d5ed (diff)
Core/Maps: move pooling hand-off outside of Map::CheckRespawn (PR#25785)
fixes #25777
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Maps/Map.cpp109
-rw-r--r--src/server/game/Pools/PoolMgr.cpp15
-rw-r--r--src/server/game/Pools/PoolMgr.h1
3 files changed, 69 insertions, 56 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 1908f2efe2a..912a68e5d31 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3036,47 +3036,42 @@ bool Map::CheckRespawn(RespawnInfo* info)
return false;
}
- uint32 poolId = info->spawnId ? sPoolMgr->IsPartOfAPool(info->type, info->spawnId) : 0;
// Next, check if there's already an instance of this object that would block the respawn
- // Only do this for unpooled spawns
- if (!poolId)
+ bool alreadyExists = false;
+ switch (info->type)
{
- bool doDelete = false;
- switch (info->type)
+ case SPAWN_TYPE_CREATURE:
{
- case SPAWN_TYPE_CREATURE:
- {
- // escort check for creatures only (if the world config boolean is set)
- bool const isEscort = (sWorld->getBoolConfig(CONFIG_RESPAWN_DYNAMIC_ESCORTNPC) && data->spawnGroupData->flags & SPAWNGROUP_FLAG_ESCORTQUESTNPC);
+ // escort check for creatures only (if the world config boolean is set)
+ bool const isEscort = (sWorld->getBoolConfig(CONFIG_RESPAWN_DYNAMIC_ESCORTNPC) && data->spawnGroupData->flags & SPAWNGROUP_FLAG_ESCORTQUESTNPC);
- auto range = _creatureBySpawnIdStore.equal_range(info->spawnId);
- for (auto it = range.first; it != range.second; ++it)
- {
- Creature* creature = it->second;
- if (!creature->IsAlive())
- continue;
- // escort NPCs are allowed to respawn as long as all other instances are already escorting
- if (isEscort && creature->IsEscorted())
- continue;
- doDelete = true;
- break;
- }
+ auto range = _creatureBySpawnIdStore.equal_range(info->spawnId);
+ for (auto it = range.first; it != range.second; ++it)
+ {
+ Creature* creature = it->second;
+ if (!creature->IsAlive())
+ continue;
+ // escort NPCs are allowed to respawn as long as all other instances are already escorting
+ if (isEscort && creature->IsEscorted())
+ continue;
+ alreadyExists = true;
break;
}
- case SPAWN_TYPE_GAMEOBJECT:
- // gameobject check is simpler - they cannot be dead or escorting
- if (_gameobjectBySpawnIdStore.find(info->spawnId) != _gameobjectBySpawnIdStore.end())
- doDelete = true;
- break;
- default:
- ABORT_MSG("Invalid spawn type %u with spawnId %u on map %u", uint32(info->type), info->spawnId, GetId());
- return true;
- }
- if (doDelete)
- {
- info->respawnTime = 0;
- return false;
+ break;
}
+ case SPAWN_TYPE_GAMEOBJECT:
+ // gameobject check is simpler - they cannot be dead or escorting
+ if (_gameobjectBySpawnIdStore.find(info->spawnId) != _gameobjectBySpawnIdStore.end())
+ alreadyExists = true;
+ break;
+ default:
+ ABORT_MSG("Invalid spawn type %u with spawnId %u on map %u", uint32(info->type), info->spawnId, GetId());
+ return true;
+ }
+ if (alreadyExists)
+ {
+ info->respawnTime = 0;
+ return false;
}
// next, check linked respawn time
@@ -3094,21 +3089,6 @@ bool Map::CheckRespawn(RespawnInfo* info)
info->respawnTime = respawnTime;
return false;
}
-
- // now, check if we're part of a pool
- if (poolId)
- {
- // ok, part of a pool - hand off to pool logic to handle this, we're just going to remove the respawn and call it a day
- if (info->type == SPAWN_TYPE_GAMEOBJECT)
- sPoolMgr->UpdatePool<GameObject>(poolId, info->spawnId);
- else if (info->type == SPAWN_TYPE_CREATURE)
- sPoolMgr->UpdatePool<Creature>(poolId, info->spawnId);
- else
- ABORT_MSG("Invalid spawn type %u (spawnid %u) on map %u", uint32(info->type), info->spawnId, GetId());
- info->respawnTime = 0;
- return false;
- }
-
// everything ok, let's spawn
return true;
}
@@ -3275,22 +3255,39 @@ void Map::ProcessRespawns()
RespawnInfo* next = _respawnTimes.top();
if (now < next->respawnTime) // done for this tick
break;
- if (CheckRespawn(next)) // see if we're allowed to respawn
- {
- // ok, respawn
+
+ if (uint32 poolId = sPoolMgr->IsPartOfAPool(next->type, next->spawnId)) // is this part of a pool?
+ { // if yes, respawn will be handled by (external) pooling logic, just delete the respawn time
+ // step 1: remove entry from maps to avoid it being reachable by outside logic
_respawnTimes.pop();
GetRespawnMapForType(next->type).erase(next->spawnId);
+
+ // step 2: tell pooling logic to do its thing
+ sPoolMgr->UpdatePool(poolId, next->type, next->spawnId);
+
+ // step 3: get rid of the actual entry
+ delete next;
+ }
+ else if (CheckRespawn(next)) // see if we're allowed to respawn
+ { // ok, respawn
+ // step 1: remove entry from maps to avoid it being reachable by outside logic
+ _respawnTimes.pop();
+ GetRespawnMapForType(next->type).erase(next->spawnId);
+
+ // step 2: do the respawn, which involves external logic
DoRespawn(next->type, next->spawnId, next->gridId);
+
+ // step 3: get rid of the actual entry
delete next;
}
- else if (!next->respawnTime) // just remove respawn entry without rescheduling
- {
+ else if (!next->respawnTime)
+ { // just remove this respawn entry without rescheduling
_respawnTimes.pop();
GetRespawnMapForType(next->type).erase(next->spawnId);
delete next;
}
- else // value changed, update heap position
- {
+ else
+ { // new respawn time, update heap position
ASSERT(now < next->respawnTime); // infinite loop guard
_respawnTimes.decrease(next->handle);
SaveRespawnInfoDB(*next);
diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp
index 3f427526dcf..e685c1f1b15 100644
--- a/src/server/game/Pools/PoolMgr.cpp
+++ b/src/server/game/Pools/PoolMgr.cpp
@@ -845,3 +845,18 @@ void PoolMgr::UpdatePool(uint32 pool_id, uint32 db_guid_or_pool_id)
template void PoolMgr::UpdatePool<Pool>(uint32 pool_id, uint32 db_guid_or_pool_id);
template void PoolMgr::UpdatePool<GameObject>(uint32 pool_id, uint32 db_guid_or_pool_id);
template void PoolMgr::UpdatePool<Creature>(uint32 pool_id, uint32 db_guid_or_pool_id);
+
+void PoolMgr::UpdatePool(uint32 pool_id, SpawnObjectType type, uint32 spawnId)
+{
+ switch (type)
+ {
+ case SPAWN_TYPE_CREATURE:
+ UpdatePool<Creature>(pool_id, spawnId);
+ break;
+ case SPAWN_TYPE_GAMEOBJECT:
+ UpdatePool<GameObject>(pool_id, spawnId);
+ break;
+ default:
+ ABORT_MSG("Invalid spawn type %u passed to PoolMgr::IsPartOfPool (with spawnId %u)", uint32(type), spawnId);
+ }
+}
diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h
index 7ee026998b3..d60fad2e3d0 100644
--- a/src/server/game/Pools/PoolMgr.h
+++ b/src/server/game/Pools/PoolMgr.h
@@ -120,6 +120,7 @@ class TC_GAME_API PoolMgr
template<typename T>
void UpdatePool(uint32 pool_id, uint32 db_guid_or_pool_id);
+ void UpdatePool(uint32 pool_id, SpawnObjectType type, ObjectGuid::LowType spawnId);
private:
template<typename T>