aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Pools/PoolMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Pools/PoolMgr.cpp')
-rw-r--r--src/server/game/Pools/PoolMgr.cpp103
1 files changed, 56 insertions, 47 deletions
diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp
index 44a1ef3ee82..37fac27db46 100644
--- a/src/server/game/Pools/PoolMgr.cpp
+++ b/src/server/game/Pools/PoolMgr.cpp
@@ -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);
+ else if (!EqualChanced.empty())
+ {
+ rolledObjects = EqualChanced;
- if (triggerFrom)
+ 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)
{
- // One spawn one despawn no count increase
- DespawnObject(spawns, triggerFrom);
- lastDespawned = triggerFrom;
- triggerFrom = 0;
+ 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