Core/Maps: move pooling hand-off outside of Map::CheckRespawn
Port From (https://github.com/TrinityCore/TrinityCore/commit/a8d00ddd69f3ff0f197b31d407e8c5112f229b4b)
This commit is contained in:
+52
-54
@@ -2374,48 +2374,45 @@ namespace Game.Maps
|
|||||||
return false;
|
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
|
// Next, check if there's already an instance of this object that would block the respawn
|
||||||
// Only do this for unpooled spawns
|
// Only do this for unpooled spawns
|
||||||
if (poolId == 0)
|
bool alreadyExists = false;
|
||||||
|
switch (info.type)
|
||||||
{
|
{
|
||||||
bool doDelete = false;
|
case SpawnObjectType.Creature:
|
||||||
switch (info.type)
|
|
||||||
{
|
{
|
||||||
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)
|
if (!creature.IsAlive())
|
||||||
bool isEscort = WorldConfig.GetBoolValue(WorldCfg.RespawnDynamicEscortNpc) && data.spawnGroupData.flags.HasFlag(SpawnGroupFlags.EscortQuestNpc);
|
continue;
|
||||||
|
|
||||||
var range = _creatureBySpawnIdStore.LookupByKey(info.spawnId);
|
// escort NPCs are allowed to respawn as long as all other instances are already escorting
|
||||||
foreach (var creature in range)
|
if (isEscort && creature.IsEscorted())
|
||||||
{
|
continue;
|
||||||
if (!creature.IsAlive())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// escort NPCs are allowed to respawn as long as all other instances are already escorting
|
alreadyExists = true;
|
||||||
if (isEscort && creature.IsEscorted())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
doDelete = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SpawnObjectType.GameObject:
|
break;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
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
|
// next, check linked respawn time
|
||||||
@@ -2435,20 +2432,6 @@ namespace Game.Maps
|
|||||||
return false;
|
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
|
// everything ok, let's spawn
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2650,22 +2633,37 @@ namespace Game.Maps
|
|||||||
if (now < next.respawnTime) // done for this tick
|
if (now < next.respawnTime) // done for this tick
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (CheckRespawn(next)) // see if we're allowed to respawn
|
uint poolId = Global.PoolMgr.IsPartOfAPool(next.type, next.spawnId);
|
||||||
{
|
if (poolId != 0) // is this part of a pool?
|
||||||
// ok, respawn
|
{ // 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);
|
_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);
|
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);
|
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);
|
_respawnTimes.Remove(next);
|
||||||
GetRespawnMapForType(next.type).Remove(next.spawnId);
|
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
|
Cypher.Assert(now < next.respawnTime); // infinite loop guard
|
||||||
//_respawnTimes.decrease(next.handle);
|
|
||||||
SaveRespawnInfoDB(next);
|
SaveRespawnInfoDB(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,6 +360,19 @@ namespace Game
|
|||||||
SpawnPool<T>(pool_id, db_guid_or_pool_id);
|
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)
|
public uint IsPartOfAPool<T>(ulong db_guid)
|
||||||
{
|
{
|
||||||
switch (typeof(T).Name)
|
switch (typeof(T).Name)
|
||||||
|
|||||||
Reference in New Issue
Block a user