@@ -130,40 +130,27 @@ bool PoolGroup<T>::CheckPool() const
130
130
}
131
131
132
132
// Main method to despawn a creature or gameobject in a pool
133
- // If no guid is passed, the pool is just removed (event end case)
134
- // If guid is filled, cache will be used and no removal will occur, it just fill the cache
135
133
template <class T >
136
134
void PoolGroup<T>::DespawnObject(ActivePoolData& spawns, ObjectGuid::LowType guid, bool alwaysDeleteRespawnTime)
137
135
{
138
- for (size_t i=0 ; i < EqualChanced.size (); ++i)
136
+ // if spawned
137
+ if (spawns.IsActiveObject <T>(guid))
139
138
{
140
- // if spawned
141
- if (spawns.IsActiveObject <T>(EqualChanced[i].guid ))
142
- {
143
- if (!guid || EqualChanced[i].guid == guid)
144
- {
145
- Despawn1Object (EqualChanced[i].guid , alwaysDeleteRespawnTime);
146
- spawns.RemoveObject <T>(EqualChanced[i].guid , poolId);
147
- }
148
- }
149
- else if (alwaysDeleteRespawnTime)
150
- RemoveRespawnTimeFromDB (EqualChanced[i].guid );
139
+ Despawn1Object (guid, alwaysDeleteRespawnTime);
140
+ spawns.RemoveObject <T>(guid, poolId);
151
141
}
142
+ else if (alwaysDeleteRespawnTime)
143
+ RemoveRespawnTimeFromDB (guid);
144
+ }
152
145
153
- for (size_t i = 0 ; i < ExplicitlyChanced.size (); ++i)
154
- {
155
- // spawned
156
- if (spawns.IsActiveObject <T>(ExplicitlyChanced[i].guid ))
157
- {
158
- if (!guid || ExplicitlyChanced[i].guid == guid)
159
- {
160
- Despawn1Object (ExplicitlyChanced[i].guid , alwaysDeleteRespawnTime);
161
- spawns.RemoveObject <T>(ExplicitlyChanced[i].guid , poolId);
162
- }
163
- }
164
- else if (alwaysDeleteRespawnTime)
165
- RemoveRespawnTimeFromDB (ExplicitlyChanced[i].guid );
166
- }
146
+ template <class T >
147
+ void PoolGroup<T>::DespawnAllObjects(ActivePoolData& spawns, bool alwaysDeleteRespawnTime)
148
+ {
149
+ for (PoolObject& pooledObject : EqualChanced)
150
+ DespawnObject (spawns, pooledObject.guid , alwaysDeleteRespawnTime);
151
+
152
+ for (PoolObject& pooledObject : ExplicitlyChanced)
153
+ DespawnObject (spawns, pooledObject.guid , alwaysDeleteRespawnTime);
167
154
}
168
155
169
156
// Method that is actualy doing the removal job on one creature
@@ -255,66 +242,69 @@ void PoolGroup<Pool>::RemoveOneRelation(uint32 child_pool_id)
255
242
template <class T >
256
243
void PoolGroup<T>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 triggerFrom)
257
244
{
258
- int count = limit - spawns.GetActiveObjectCount (poolId);
259
-
260
- // If triggered from some object respawn this object is still marked as spawned
261
- // and also counted into m_SpawnedPoolAmount so we need increase count to be
262
- // spawned by 1
245
+ // First clear the object that triggered the respawn, if any.
246
+ // DespawnObject is responsible for decrementing the active object counter.
263
247
if (triggerFrom)
264
- ++count ;
248
+ DespawnObject (spawns, triggerFrom) ;
265
249
266
- if (count > 0 )
267
- {
268
- PoolObjectList rolledObjects;
269
- rolledObjects.reserve (count);
250
+ int32 count = limit - spawns.GetActiveObjectCount (poolId);
251
+ if (count <= 0 )
252
+ return ;
270
253
271
- // roll objects to be spawned
272
- if (!ExplicitlyChanced.empty ())
273
- {
274
- float roll = (float )rand_chance ();
254
+ PoolObjectList candidates;
255
+ candidates.reserve (EqualChanced.size () + ExplicitlyChanced.size ());
275
256
276
- for (PoolObject& obj : ExplicitlyChanced)
277
- {
278
- roll -= obj.chance ;
279
- // Triggering object is marked as spawned at this time and can be also rolled (respawn case)
280
- // so this need explicit check for this case
281
- if (roll < 0 && (obj.guid == triggerFrom || !spawns.IsActiveObject <T>(obj.guid )))
282
- {
283
- rolledObjects.push_back (obj);
284
- break ;
285
- }
286
- }
287
- }
257
+ // Add all not already active candidates.
258
+ for (PoolObject& obj : EqualChanced)
259
+ if (!spawns.IsActiveObject <T>(obj.guid ))
260
+ candidates.push_back (obj);
288
261
289
- if (!EqualChanced.empty () && rolledObjects.empty ())
290
- {
291
- std::copy_if (EqualChanced.begin (), EqualChanced.end (), std::back_inserter (rolledObjects), [triggerFrom, &spawns](PoolObject const & object)
292
- {
293
- return object.guid == triggerFrom || !spawns.IsActiveObject <T>(object.guid );
294
- });
262
+ for (PoolObject& obj : ExplicitlyChanced)
263
+ if (!spawns.IsActiveObject <T>(obj.guid ))
264
+ candidates.push_back (obj);
295
265
296
- Trinity::Containers::RandomResize (rolledObjects, count);
297
- }
266
+ if (candidates.empty ())
267
+ return ;
268
+
269
+ PoolObjectList rolledObjects;
270
+ rolledObjects.reserve (count);
298
271
299
- // try to spawn rolled objects
300
- for (PoolObject& obj : rolledObjects)
272
+ // Attempt to select one object based on explicit chance.
273
+ if (!ExplicitlyChanced.empty ())
274
+ {
275
+ float roll = (float )rand_chance ();
276
+ for (PoolObject& candidate : candidates)
301
277
{
302
- if (obj. guid == triggerFrom )
278
+ if (candidate. chance > 0 )
303
279
{
304
- ReSpawn1Object (&obj);
305
- triggerFrom = 0 ;
306
- }
307
- else
308
- {
309
- spawns.ActivateObject <T>(obj.guid , poolId);
310
- Spawn1Object (&obj);
280
+ roll -= candidate.chance ;
281
+ if (roll < 0 )
282
+ {
283
+ rolledObjects.push_back (candidate);
284
+ std::swap (candidate, candidates.back ());
285
+ candidates.pop_back ();
286
+ break ; // We only roll for one chanced object.
287
+ }
311
288
}
312
289
}
313
290
}
314
291
315
- // One spawn one despawn no count increase
316
- if (triggerFrom)
317
- DespawnObject (spawns, triggerFrom);
292
+ // Fill the remaining slots with random selections from the rest of the candidates.
293
+ uint32 remainingCount = count - rolledObjects.size ();
294
+ if (remainingCount > 0 && !candidates.empty ())
295
+ {
296
+ if (candidates.size () > remainingCount)
297
+ Trinity::Containers::RandomResize (candidates, remainingCount);
298
+
299
+ rolledObjects.insert (rolledObjects.end (), candidates.begin (), candidates.end ());
300
+ }
301
+
302
+ // Spawn all the objects we've selected.
303
+ for (PoolObject& objToSpawn : rolledObjects)
304
+ {
305
+ spawns.ActivateObject <T>(objToSpawn.guid , poolId);
306
+ Spawn1Object (&objToSpawn);
307
+ }
318
308
}
319
309
320
310
// Method that is actualy doing the spawn job on 1 creature
@@ -377,14 +367,6 @@ void PoolGroup<Pool>::Spawn1Object(PoolObject* obj)
377
367
sPoolMgr ->SpawnPool (obj->guid );
378
368
}
379
369
380
- // Method that does the respawn job on the specified object
381
- template <typename T>
382
- void PoolGroup<T>::ReSpawn1Object(PoolObject* obj)
383
- {
384
- Despawn1Object (obj->guid , false , false );
385
- Spawn1Object (obj);
386
- }
387
-
388
370
template <>
389
371
void PoolGroup<Creature>::RemoveRespawnTimeFromDB(ObjectGuid::LowType guid)
390
372
{
@@ -771,17 +753,17 @@ void PoolMgr::DespawnPool(uint32 pool_id, bool alwaysDeleteRespawnTime)
771
753
{
772
754
auto it = mPoolCreatureGroups .find (pool_id);
773
755
if (it != mPoolCreatureGroups .end () && !it->second .isEmpty ())
774
- it->second .DespawnObject (mSpawnedData , 0 , alwaysDeleteRespawnTime);
756
+ it->second .DespawnAllObjects (mSpawnedData , alwaysDeleteRespawnTime);
775
757
}
776
758
{
777
759
auto it = mPoolGameobjectGroups .find (pool_id);
778
760
if (it != mPoolGameobjectGroups .end () && !it->second .isEmpty ())
779
- it->second .DespawnObject (mSpawnedData , 0 , alwaysDeleteRespawnTime);
761
+ it->second .DespawnAllObjects (mSpawnedData , alwaysDeleteRespawnTime);
780
762
}
781
763
{
782
764
auto it = mPoolPoolGroups .find (pool_id);
783
765
if (it != mPoolPoolGroups .end () && !it->second .isEmpty ())
784
- it->second .DespawnObject (mSpawnedData , 0 , alwaysDeleteRespawnTime);
766
+ it->second .DespawnAllObjects (mSpawnedData , alwaysDeleteRespawnTime);
785
767
}
786
768
}
787
769
0 commit comments