PoolObject RollOne(ActivePoolData spawns, ulong triggerFrom) { if (!ExplicitlyChanced.Empty()) { float roll = (float)RandomHelper.randChance(); for (int i = 0; i < ExplicitlyChanced.Count; ++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()) { int index = RandomHelper.IRand(0, EqualChanced.Count - 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(null); }
public void DespawnObject(ActivePoolData spawns, ulong guid = 0) { for (int i = 0; i < EqualChanced.Count; ++i) { // if spawned if (spawns.IsActiveObject <T>(EqualChanced[i].guid)) { if (guid == 0 || EqualChanced[i].guid == guid) { Despawn1Object(EqualChanced[i].guid); spawns.RemoveObject <T>(EqualChanced[i].guid, poolId); } } } for (int i = 0; i < ExplicitlyChanced.Count; ++i) { // spawned if (spawns.IsActiveObject <T>(ExplicitlyChanced[i].guid)) { if (guid == 0 || ExplicitlyChanced[i].guid == guid) { Despawn1Object(ExplicitlyChanced[i].guid); spawns.RemoveObject <T>(ExplicitlyChanced[i].guid, poolId); } } } }
public void SpawnObject(ActivePoolData spawns, uint limit, ulong triggerFrom) { if (typeof(T).Name == "Quest") { SpawnQuestObject(spawns, limit, triggerFrom); return; } ulong lastDespawned = 0; int count = (int)(limit - spawns.GetActiveObjectCount(poolId)); // If triggered from some object respawn this object is still marked as spawned // and also counted into m_SpawnedPoolAmount so we need increase count to be // spawned by 1 if (triggerFrom != 0) { ++count; } // This will try to spawn the rest of pool, not guaranteed for (int i = 0; i < count; ++i) { PoolObject obj = RollOne(spawns, triggerFrom); if (obj == null) { continue; } if (obj.guid == lastDespawned) { continue; } if (obj.guid == triggerFrom) { ReSpawn1Object(obj); triggerFrom = 0; continue; } spawns.ActivateObject <T>(obj.guid, poolId); Spawn1Object(obj); if (triggerFrom != 0) { // One spawn one despawn no count increase DespawnObject(spawns, triggerFrom); lastDespawned = triggerFrom; triggerFrom = 0; } } }
void SpawnQuestObject(ActivePoolData spawns, uint limit, ulong triggerFrom) { Log.outDebug(LogFilter.Pool, "PoolGroup<Quest>: Spawning pool {0}", poolId); // load state from db if (triggerFrom == 0) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_POOL_QUEST_SAVE); stmt.AddValue(0, poolId); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) { do { uint questId = result.Read <uint>(0); spawns.ActivateObject <Quest>(questId, poolId); PoolObject tempObj = new PoolObject(questId, 0.0f); Spawn1Object(tempObj); --limit; } while (result.NextRow() && limit != 0); return; } } List <ulong> currentQuests = spawns.GetActiveQuests(); List <ulong> newQuests = new List <ulong>(); // always try to select different quests foreach (var poolObject in EqualChanced) { if (spawns.IsActiveObject <Quest>(poolObject.guid)) { continue; } newQuests.Add(poolObject.guid); } // clear the pool DespawnObject(spawns); // recycle minimal amount of quests if possible count is lower than limit if (limit > newQuests.Count && !currentQuests.Empty()) { do { ulong questId = currentQuests.SelectRandom(); newQuests.Add(questId); currentQuests.Remove(questId); } while (newQuests.Count < limit && !currentQuests.Empty()); // failsafe } if (newQuests.Empty()) { return; } // activate <limit> random quests do { ulong questId = newQuests.SelectRandom(); spawns.ActivateObject <Quest>(questId, poolId); PoolObject tempObj = new PoolObject(questId, 0.0f); Spawn1Object(tempObj); newQuests.Remove(questId); --limit; } while (limit != 0 && !newQuests.Empty()); // if we are here it means the pool is initialized at startup and did not have previous saved state if (triggerFrom == 0) { Global.PoolMgr.SaveQuestsToDB(); } }
public void SpawnObject(ActivePoolData spawns, uint limit, ulong triggerFrom) { if (typeof(T).Name == "Quest") { SpawnQuestObject(spawns, limit, triggerFrom); return; } int count = (int)(limit - spawns.GetActiveObjectCount(poolId)); // If triggered from some object respawn this object is still marked as spawned // and also counted into m_SpawnedPoolAmount so we need increase count to be // spawned by 1 if (triggerFrom != 0) { ++count; } // This will try to spawn the rest of pool, not guaranteed if (count > 0) { List <PoolObject> rolledObjects = new List <PoolObject>(); // roll objects to be spawned if (!ExplicitlyChanced.Empty()) { while (count != 0 && ExplicitlyChanced.Count > rolledObjects.Count) { --count; float roll = (float)RandomHelper.randChance(); foreach (PoolObject obj in 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.Add(obj); break; } } } } else if (!EqualChanced.Empty()) { rolledObjects = EqualChanced; for (var i = 0; i < rolledObjects.Count; ++i) { var obj = rolledObjects[i]; // remove most of the active objects so there is higher chance inactive ones are spawned if (spawns.IsActiveObject <T>(obj.guid) && RandomHelper.URand(1, 4) != 1) { rolledObjects.Remove(obj); } } rolledObjects.RandomResize((uint)count); } // try to spawn rolled objects foreach (PoolObject obj in 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 != 0) { DespawnObject(spawns, triggerFrom); } }