//Spawns a nightmare public static void SpawnNightmare(NightmareType nt, EntityAlive target = null) { NightmareInstance ni = new NightmareInstance(); ni.InstanceType = nt; try { API.Log("Spawning instance " + ni.InstanceType.ClassName); using (Dictionary <int, EntityClass> .KeyCollection.Enumerator enumerator3 = EntityClass.list.Keys.GetEnumerator()) { while (enumerator3.MoveNext()) { //Find entity class int current3 = enumerator3.Current; //API.Log("Iterating enum, on " + current3+ " ("+EntityClass.list[current3].entityClassName+")"); if (!EntityClass.list[current3].entityClassName.Equals(ni.InstanceType.ClassName)) { continue; } //API.Log("Found entity " + current3 + " to be classname " + ni.InstanceType.ClassName); //Find a place to spawn it int x = 0, y = 0, z = 0; if (target == null) { API.Log("Finding target"); ni.PickRandomTarget(); } else { ni.TargetEntity = target; } if (ni.TargetEntity == null) { API.Log("Failed to find a target entity"); return; } API.Log("Finding location to spawn"); bool isSpawnLocFound = false; for (int i = 0; i < 10; i++) { if (GameManager.Instance.World.FindRandomSpawnPointNearPlayer(ni.TargetEntity, 30, out x, out y, out z, 200)) { isSpawnLocFound = true; break; } } if (!isSpawnLocFound) { API.Log("Failed to find spawn location near player" + ni.TargetEntity); return; } UnityEngine.Vector3 pos = new UnityEngine.Vector3(x, y, z); API.Log("Creating entity.." + current3); //This is found in AIDirectoryBloodMoonParty ni.Instance = (EntityEnemy)EntityFactory.CreateEntity(current3, pos); ni.Instance.isFeral = true; //ni.Instance.lootContainer.AddItem(new ItemStack(new ItemValue(114), 1)); //string loot = "Loot: "; //foreach (var item in ni.Instance.equipment.GetItems()) //{ // loot += string.Format("{0} [{1}] x{2}", item.ItemClass, item.Quality); //} //API.Log(string.Format("Loot: {0}", loot)); GameManager.Instance.World.SpawnEntityInWorld(ni.Instance); //ni.Instance.SetEntityName("A nightmare"); //ni.Instance.SetSpawnerSource(EnumSpawnerSource.Dynamic); NightmareInstances.Add(ni); ni.Instance.SetAttackTarget(ni.TargetEntity, 1200); API.Log("Added instance " + ni.InstanceType.ClassName + " at " + x + ", " + y + ", " + z); WhisperMessage(ConnectionManager.Instance.GetClientInfoForPlayerId(ni.TargetEntity.belongsPlayerId.ToString()), ni.InstanceType.Message); return; } } API.Log("Failed to find class type of nightmare: " + ni.InstanceType.ClassName); } catch (Exception e) { API.Log("Failed to spawn nightmare: " + e.Message); return; } }
private static void MainLoop() { //Lasttime only triggers when server is offline, and saves effort. ulong lastTime = 0; ulong currentTime = 0; while (true) { try { Thread.Sleep(6000); currentTime = GameManager.Instance.World.GetWorldTime(); if (NextNightmareReseed <= currentTime) { SeedNightmares(); } if (currentTime == lastTime) { continue; } lastTime = currentTime; string strNextNightmare = ""; if (NextNightmare < currentTime) { strNextNightmare = "None"; } if (NextNightmare >= currentTime) { strNextNightmare = string.Format("{1} ({2:0}s)", NextNightmare, ((NextNightmare - currentTime) / 5.8f)); } API.Log(string.Format("Time: {0}, NextNightmare: {1} ({2:0}s), NextReseed: {3} ({4:0}s [{5} Nightmares Currently Spawned])", currentTime, strNextNightmare, NextNightmareReseed, ((NextNightmareReseed - currentTime) / 5.8f), NightmareInstances.Count)); if (ConnectionManager.Instance.ClientCount() < 1 || GameManager.Instance.World.GetPlayers().Count < 1) { continue; } //AI LOGIC/CLEANUP for (int i = NightmareInstances.Count - 1; i > -1; i--) { int index = i; NightmareInstance ni = NightmareInstances[index]; //Remove dead/null instances if (ni == null || ni.Instance == null || ni.Instance.IsDead()) { NightmareInstances.RemoveAt(index); API.Log(string.Format("Removed nightmare instance {0}, {1} nightmares remain", index, NightmareInstances.Count)); continue; } //Ensure entity is behaving like a nightmare if (ni.Instance.GetAttackTarget() == null && ni.TargetEntity != null && !ni.TargetEntity.IsDead() && ni.TargetEntity.IsSpawned()) { API.Log(string.Format("{0} {1} was evaded by target player {2}, re-engaging (it's a nightmare afterall)...", ni.InstanceType.ClassName, index, ni.TargetEntity.belongsPlayerId)); ni.Instance.SetAttackTarget(ni.TargetEntity, 1200); continue; } //Ensure target is still legit if (ni.TargetEntity == null || (ni.TargetEntity.IsDead() && ni.TargetEntity.IsSpawned())) { API.Log(string.Format("{0} {1} thinks target is dead/disconnected, picking new target...", ni.InstanceType.ClassName, index)); ni.PickRandomTarget(); if (ni.TargetEntity == null) { NightmareInstances.RemoveAt(index); API.Log("Removed nightmare instance " + index + " due to no target found, " + NightmareInstances.Count + " left"); continue; } //engage target ni.Instance.SetAttackTarget(ni.TargetEntity, 1200); } } if (NightmareSeeds.Count > 0 && NextNightmare <= GameManager.Instance.World.GetWorldTime()) { foreach (NightmareType nt in NightmareSeeds[0].NightmareTypes) { SpawnNightmare(nt); } NightmareSeeds.RemoveAt(0); NextNightmare = 0; if (NightmareSeeds.Count > 0) { NextNightmare = NightmareSeeds[0].SeedTime; } } } catch (Exception e) { API.Log("Exception during MainLoop: " + e.Message); } } }