fix(Core/Pooling): Fixed less and less objects from pools being spawned the longer the server is running (#5572)

This commit is contained in:
UltraNix
2021-05-08 20:39:09 +02:00
committed by GitHub
parent 75c75a40d4
commit 44babc3c3a
26 changed files with 136 additions and 105 deletions

View File

@@ -261,7 +261,7 @@ public:
targetList.reverse();
if (targetType == SELECT_TARGET_RANDOM)
acore::Containers::RandomResizeList(targetList, maxTargets);
acore::Containers::RandomResize(targetList, maxTargets);
else
targetList.resize(maxTargets);
}

View File

@@ -107,7 +107,7 @@ public:
// We need to use a copy of SummonList here, otherwise original SummonList would be modified
StorageType listCopy = storage_;
acore::Containers::RandomResizeList<ObjectGuid, Predicate>(listCopy, predicate, max);
acore::Containers::RandomResize(listCopy, predicate, max);
for (StorageType::iterator i = listCopy.begin(); i != listCopy.end(); ++i)
{
Creature* summon = ObjectAccessor::GetCreature(*me, *i);

View File

@@ -734,7 +734,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
caster = unit->SummonTrigger(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation(), 5000);
if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit)
acore::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit);
acore::Containers::RandomResize(*targets, e.action.cast.targetsLimit);
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -793,7 +793,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit)
acore::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit);
acore::Containers::RandomResize(*targets, e.action.cast.targetsLimit);
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -3680,7 +3680,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
l->push_back(*itr);
if (e.target.playerRange.maxCount > 0)
acore::Containers::RandomResizeList(*l, e.target.playerRange.maxCount);
acore::Containers::RandomResize(*l, e.target.playerRange.maxCount);
}
delete units;
@@ -3800,7 +3800,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
l->push_back(*itr);
if (e.target.o > 0)
acore::Containers::RandomResizeList(*l, e.target.o);
acore::Containers::RandomResize(*l, e.target.o);
delete units;
break;
@@ -3842,7 +3842,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
}
if (e.target.roleSelection.resize > 0)
acore::Containers::RandomResizeList(*l, e.target.roleSelection.resize);
acore::Containers::RandomResize(*l, e.target.roleSelection.resize);
delete units;
break;

View File

@@ -141,34 +141,6 @@ bool PoolGroup<T>::CheckPool() const
return true;
}
template <class T>
PoolObject* PoolGroup<T>::RollOne(ActivePoolData& spawns, uint32 triggerFrom)
{
if (!ExplicitlyChanced.empty())
{
float roll = (float)rand_chance();
for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i)
{
roll -= ExplicitlyChanced[i].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 && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsActiveObject<T>(ExplicitlyChanced[i].guid)))
return &ExplicitlyChanced[i];
}
}
if (!EqualChanced.empty())
{
int32 index = irand(0, EqualChanced.size() - 1);
// 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 (EqualChanced[index].guid == triggerFrom || !spawns.IsActiveObject<T>(EqualChanced[index].guid))
return &EqualChanced[index];
}
return nullptr;
}
// Main method to despawn a creature or gameobject in a pool
// If no guid is passed, the pool is just removed (event end case)
// If guid is filled, cache will be used and no removal will occur, it just fill the cache
@@ -321,40 +293,70 @@ void PoolGroup<Pool>::RemoveOneRelation(uint32 child_pool_id)
template <class T>
void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 triggerFrom)
{
uint32 lastDespawned = 0;
int count = limit - spawns.GetActiveObjectCount(poolId);
// If triggered from some object respawn this object is still marked as spawned
// and also counted into m_SpawnedPoolAmount so we need increase count to be
// spawned by 1
if (triggerFrom)
++count;
// This will try to spawn the rest of pool, not guaranteed
for (int i = 0; i < count; ++i)
{
PoolObject* obj = RollOne(spawns, triggerFrom);
if (!obj)
continue;
if (obj->guid == lastDespawned)
continue;
++count;
}
if (obj->guid == triggerFrom)
{
ReSpawn1Object(obj);
triggerFrom = 0;
continue;
}
spawns.ActivateObject<T>(obj->guid, poolId);
Spawn1Object(obj);
if (count > 0)
{
PoolObjectList rolledObjects;
rolledObjects.reserve(count);
if (triggerFrom)
// roll objects to be spawned
if (!ExplicitlyChanced.empty())
{
// One spawn one despawn no count increase
DespawnObject(spawns, triggerFrom);
lastDespawned = triggerFrom;
triggerFrom = 0;
float roll = (float)rand_chance();
for (PoolObject& obj : ExplicitlyChanced)
{
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)))
{
rolledObjects.push_back(obj);
break;
}
}
}
if (!EqualChanced.empty() && rolledObjects.empty())
{
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);
});
acore::Containers::RandomResize(rolledObjects, count);
}
// try to spawn rolled objects
for (PoolObject& obj : rolledObjects)
{
if (obj.guid == triggerFrom)
{
ReSpawn1Object(&obj);
triggerFrom = 0;
}
else
{
spawns.ActivateObject<T>(obj.guid, poolId);
Spawn1Object(&obj);
}
}
}
// One spawn one despawn no count increase
if (triggerFrom)
{
DespawnObject(spawns, triggerFrom);
}
}

View File

@@ -64,7 +64,6 @@ public:
bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
void AddEntry(PoolObject& poolitem, uint32 maxentries);
bool CheckPool() const;
PoolObject* RollOne(ActivePoolData& spawns, uint32 triggerFrom);
void DespawnObject(ActivePoolData& spawns, ObjectGuid::LowType guid = 0);
void Despawn1Object(ObjectGuid::LowType guid);
void SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 triggerFrom);

View File

@@ -1197,7 +1197,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
if ((*j)->IsAffectedOnSpell(m_spellInfo))
maxTargets += (*j)->GetAmount();
acore::Containers::RandomResizeList(targets, maxTargets);
acore::Containers::RandomResize(targets, maxTargets);
}
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
@@ -1280,7 +1280,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
if ((*j)->IsAffectedOnSpell(m_spellInfo))
maxTargets += (*j)->GetAmount();
acore::Containers::RandomResizeList(targets, maxTargets);
acore::Containers::RandomResize(targets, maxTargets);
}
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)