mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Pooling: Fixed less and less objects from pools being spawned the longer the server is running (#20949)
Closes #11141
(cherry picked from commit de80cd2e0d)
This commit is contained in:
@@ -159,34 +159,6 @@ bool PoolGroup<T>::CheckPool() const
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PoolObject* PoolGroup<T>::RollOne(ActivePoolData& spawns, uint64 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())
|
||||
{
|
||||
uint32 index = urand(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
|
||||
@@ -346,7 +318,6 @@ void PoolGroup<Pool>::RemoveOneRelation(uint32 child_pool_id)
|
||||
template <class T>
|
||||
void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint64 triggerFrom)
|
||||
{
|
||||
uint32 lastDespawned = 0;
|
||||
int count = limit - spawns.GetActiveObjectCount(poolId);
|
||||
|
||||
// If triggered from some object respawn this object is still marked as spawned
|
||||
@@ -355,32 +326,70 @@ void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint64 trig
|
||||
if (triggerFrom)
|
||||
++count;
|
||||
|
||||
// This will try to spawn the rest of pool, not guaranteed
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (count > 0)
|
||||
{
|
||||
PoolObject* obj = RollOne(spawns, triggerFrom);
|
||||
if (!obj)
|
||||
continue;
|
||||
if (obj->guid == lastDespawned)
|
||||
continue;
|
||||
PoolObjectList rolledObjects;
|
||||
rolledObjects.reserve(count);
|
||||
|
||||
if (obj->guid == triggerFrom)
|
||||
// roll objects to be spawned
|
||||
if (!ExplicitlyChanced.empty())
|
||||
{
|
||||
ReSpawn1Object(obj);
|
||||
triggerFrom = 0;
|
||||
continue;
|
||||
while (count && ExplicitlyChanced.size() > rolledObjects.size())
|
||||
{
|
||||
--count;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
spawns.ActivateObject<T>(obj->guid, poolId);
|
||||
Spawn1Object(obj);
|
||||
|
||||
if (triggerFrom)
|
||||
else if (!EqualChanced.empty())
|
||||
{
|
||||
// One spawn one despawn no count increase
|
||||
DespawnObject(spawns, triggerFrom);
|
||||
lastDespawned = triggerFrom;
|
||||
triggerFrom = 0;
|
||||
rolledObjects = EqualChanced;
|
||||
|
||||
for (auto itr = rolledObjects.begin(); itr != rolledObjects.end();)
|
||||
{
|
||||
// remove most of the active objects so there is higher chance inactive ones are spawned
|
||||
if (spawns.IsActiveObject<T>(itr->guid) && urand(1, 4) != 1)
|
||||
itr = rolledObjects.erase(itr);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
Trinity::Containers::RandomResize(rolledObjects, count);
|
||||
}
|
||||
|
||||
// try to spawn rolled objects
|
||||
for (PoolObject& obj : rolledObjects)
|
||||
{
|
||||
if (spawns.IsActiveObject<T>(obj.guid))
|
||||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Method that is actualy doing the spawn job on 1 creature
|
||||
|
||||
Reference in New Issue
Block a user