diff options
-rw-r--r-- | src/server/game/Pools/PoolMgr.cpp | 103 | ||||
-rw-r--r-- | src/server/game/Pools/PoolMgr.h | 1 |
2 files changed, 56 insertions, 48 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 diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h index 4961164536b..9628d206cb5 100644 --- a/src/server/game/Pools/PoolMgr.h +++ b/src/server/game/Pools/PoolMgr.h @@ -81,7 +81,6 @@ class TC_GAME_API PoolGroup bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); } void AddEntry(PoolObject& poolitem, uint32 maxentries); bool CheckPool() const; - PoolObject* RollOne(ActivePoolData& spawns, uint64 triggerFrom); void DespawnObject(ActivePoolData& spawns, uint64 guid=0); void Despawn1Object(uint64 guid); void SpawnObject(ActivePoolData& spawns, uint32 limit, uint64 triggerFrom); |