Core/Maps: move pooling hand-off outside of Map::CheckRespawn

Port From (https://github.com/TrinityCore/TrinityCore/commit/a8d00ddd69f3ff0f197b31d407e8c5112f229b4b)
This commit is contained in:
hondacrx
2022-05-24 14:27:27 -04:00
parent 3e7425030b
commit 271c3fd945
2 changed files with 65 additions and 54 deletions
+52 -54
View File
@@ -2374,48 +2374,45 @@ namespace Game.Maps
return false;
}
uint poolId = info.spawnId != 0 ? Global.PoolMgr.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 == 0)
bool alreadyExists = false;
switch (info.type)
{
bool doDelete = false;
switch (info.type)
case SpawnObjectType.Creature:
{
case SpawnObjectType.Creature:
// escort check for creatures only (if the world config boolean is set)
bool isEscort = WorldConfig.GetBoolValue(WorldCfg.RespawnDynamicEscortNpc) && data.spawnGroupData.flags.HasFlag(SpawnGroupFlags.EscortQuestNpc);
var range = _creatureBySpawnIdStore.LookupByKey(info.spawnId);
foreach (var creature in range)
{
// escort check for creatures only (if the world config boolean is set)
bool isEscort = WorldConfig.GetBoolValue(WorldCfg.RespawnDynamicEscortNpc) && data.spawnGroupData.flags.HasFlag(SpawnGroupFlags.EscortQuestNpc);
if (!creature.IsAlive())
continue;
var range = _creatureBySpawnIdStore.LookupByKey(info.spawnId);
foreach (var creature in range)
{
if (!creature.IsAlive())
continue;
// escort NPCs are allowed to respawn as long as all other instances are already escorting
if (isEscort && creature.IsEscorted())
continue;
// escort NPCs are allowed to respawn as long as all other instances are already escorting
if (isEscort && creature.IsEscorted())
continue;
doDelete = true;
break;
}
alreadyExists = true;
break;
}
case SpawnObjectType.GameObject:
// gameobject check is simpler - they cannot be dead or escorting
if (_gameobjectBySpawnIdStore.ContainsKey(info.spawnId))
doDelete = true;
break;
default:
Cypher.Assert(false, $"Invalid spawn type {info.type} with spawnId {info.spawnId} on map {GetId()}");
return true;
}
if (doDelete)
{
info.respawnTime = 0;
return false;
break;
}
case SpawnObjectType.GameObject:
// gameobject check is simpler - they cannot be dead or escorting
if (_gameobjectBySpawnIdStore.ContainsKey(info.spawnId))
alreadyExists = true;
break;
default:
Cypher.Assert(false, $"Invalid spawn type {info.type} with spawnId {info.spawnId} on map {GetId()}");
return true;
}
if (alreadyExists)
{
info.respawnTime = 0;
return false;
}
// next, check linked respawn time
@@ -2435,20 +2432,6 @@ namespace Game.Maps
return false;
}
// now, check if we're part of a pool
if (poolId != 0)
{
// 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 == SpawnObjectType.GameObject)
Global.PoolMgr.UpdatePool<GameObject>(poolId, info.spawnId);
else if (info.type == SpawnObjectType.Creature)
Global.PoolMgr.UpdatePool<Creature>(poolId, info.spawnId);
else
Cypher.Assert(false, $"Invalid spawn type {info.type} (spawnid {info.spawnId}) on map {GetId()}");
info.respawnTime = 0;
return false;
}
// everything ok, let's spawn
return true;
}
@@ -2650,22 +2633,37 @@ namespace Game.Maps
if (now < next.respawnTime) // done for this tick
break;
if (CheckRespawn(next)) // see if we're allowed to respawn
{
// ok, respawn
uint poolId = Global.PoolMgr.IsPartOfAPool(next.type, next.spawnId);
if (poolId != 0) // 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.Remove(next);
// step 2: tell pooling logic to do its thing
Global.PoolMgr.UpdatePool(poolId, next.type, next.spawnId);
// step 3: get rid of the actual entry
GetRespawnMapForType(next.type).Remove(next.spawnId);
}
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.Remove(next);
// step 2: do the respawn, which involves external logic
DoRespawn(next.type, next.spawnId, next.gridId);
// step 3: get rid of the actual entry
GetRespawnMapForType(next.type).Remove(next.spawnId);
}
else if (next.respawnTime == 0) // just remove respawn entry without rescheduling
{
else if (next.respawnTime == 0)
{ // just remove this respawn entry without rescheduling
_respawnTimes.Remove(next);
GetRespawnMapForType(next.type).Remove(next.spawnId);
}
else // value changed, update heap position
{
else
{ // new respawn time, update heap position
Cypher.Assert(now < next.respawnTime); // infinite loop guard
//_respawnTimes.decrease(next.handle);
SaveRespawnInfoDB(next);
}
}
+13
View File
@@ -360,6 +360,19 @@ namespace Game
SpawnPool<T>(pool_id, db_guid_or_pool_id);
}
public void UpdatePool(uint pool_id, SpawnObjectType type, ulong spawnId)
{
switch (type)
{
case SpawnObjectType.Creature:
UpdatePool<Creature>(pool_id, spawnId);
break;
case SpawnObjectType.GameObject:
UpdatePool<GameObject>(pool_id, spawnId);
break;
}
}
public uint IsPartOfAPool<T>(ulong db_guid)
{
switch (typeof(T).Name)