void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 triggerFrom) { sLog->outDebug(LOG_FILTER_POOLSYS, "PoolGroup<Quest>: Spawning pool %u", poolId); // load state from db if (!triggerFrom) { QueryResult result = CharacterDatabase.PQuery("SELECT quest_id FROM pool_quest_save WHERE pool_id = %u", poolId); if (result) { do { uint32 questId = result->Fetch()[0].GetUInt32(); spawns.ActivateObject<Quest>(questId, poolId); PoolObject tempObj(questId, 0.0f); Spawn1Object(&tempObj); --limit; } while (result->NextRow() && limit); return; } } ActivePoolObjects currentQuests = spawns.GetActiveQuests(); ActivePoolObjects newQuests; // always try to select different quests for (PoolObjectList::iterator itr = EqualChanced.begin(); itr != EqualChanced.end(); ++itr) { if (spawns.IsActiveObject<Quest>(itr->guid)) continue; newQuests.insert(itr->guid); } // clear the pool DespawnObject(spawns); // recycle minimal amount of quests if possible count is lower than limit if (limit > newQuests.size() && !currentQuests.empty()) { do { uint32 questId = SelectRandomContainerElement(currentQuests); newQuests.insert(questId); currentQuests.erase(questId); } while (newQuests.size() < limit && !currentQuests.empty()); // failsafe } if (newQuests.empty()) return; // activate <limit> random quests do { uint32 questId = SelectRandomContainerElement(newQuests); spawns.ActivateObject<Quest>(questId, poolId); PoolObject tempObj(questId, 0.0f); Spawn1Object(&tempObj); newQuests.erase(questId); --limit; } while (limit && !newQuests.empty()); // if we are here it means the pool is initialized at startup and did not have previous saved state if (!triggerFrom) sPoolMgr->SaveQuestsToDB(); }