using Server; using System; using System.Collections.Generic; using Server.Gumps; using Server.Mobiles; using Server.Commands; using System.Linq; namespace Server.Engines.MiniChamps { public class MiniChamp : Item { public static void Initialize() { CommandSystem.Register("GenMiniChamp", AccessLevel.Administrator, new CommandEventHandler(GenStoneRuins_OnCommand)); } private static List Controllers = new List(); [Usage("GenMiniChamp")] [Description("MiniChampion Generator")] public static void GenStoneRuins_OnCommand(CommandEventArgs e) { foreach (var controller in Controllers) { controller.Delete(); } Map map = Map.TerMur; MiniChamp MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.CrimsonVeins; MiniChamp.MoveToWorld(new Point3D(974, 161, -10), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.AbyssalLair; MiniChamp.MoveToWorld(new Point3D(987, 328, 11), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.DiscardedCavernClanRibbon; MiniChamp.MoveToWorld(new Point3D(915, 501, -11), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.DiscardedCavernClanScratch; MiniChamp.MoveToWorld(new Point3D(950, 552, -13), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.DiscardedCavernClanChitter; MiniChamp.MoveToWorld(new Point3D(980, 491, -11), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.EnslavedGoblins; MiniChamp.MoveToWorld(new Point3D(578, 799, -45), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.FairyDragonLair; MiniChamp.MoveToWorld(new Point3D(887, 273, 4), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.FireTemple; MiniChamp.MoveToWorld(new Point3D(546, 760, -91), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.LandsoftheLich; MiniChamp.MoveToWorld(new Point3D(530, 658, 9), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.LavaCaldera; MiniChamp.MoveToWorld(new Point3D(578, 900, -72), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.PassageofTears; MiniChamp.MoveToWorld(new Point3D(684, 579, -14), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.SecretGarden; MiniChamp.MoveToWorld(new Point3D(434, 701, 29), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.Type = MiniChampType.SkeletalDragon; MiniChamp.MoveToWorld(new Point3D(677, 824, -108), map); MiniChamp.Active = true; MiniChamp = new MiniChamp(); MiniChamp.BossSpawnPoint = new Point3D(384, 1931, 50); MiniChamp.Type = MiniChampType.MeraktusTheTormented; MiniChamp.MoveToWorld(new Point3D(395, 1913, 12), Map.Malas); MiniChamp.Active = true; e.Mobile.SendMessage("Created Mini Champion Spawns."); } private bool m_Active; private MiniChampType m_Type; private List Spawn; public List Despawns; private int m_Level; private int m_SpawnRange; private TimeSpan m_RestartDelay; private Timer m_Timer, m_RestartTimer; [CommandProperty(AccessLevel.GameMaster)] public Point3D BossSpawnPoint { get; set; } [Constructable] public MiniChamp() : base(0xBD2) { Movable = false; Visible = false; Name = "Mini Champion Controller"; Despawns = new List(); Spawn = new List(); m_RestartDelay = TimeSpan.FromMinutes(5.0); m_SpawnRange = 30; BossSpawnPoint = Point3D.Zero; Controllers.Add(this); } [CommandProperty(AccessLevel.GameMaster)] public int SpawnRange { get { return m_SpawnRange; } set { m_SpawnRange = value; InvalidateProperties(); } } [CommandProperty(AccessLevel.GameMaster)] public TimeSpan RestartDelay { get { return m_RestartDelay; } set { m_RestartDelay = value; } } [CommandProperty(AccessLevel.GameMaster)] public MiniChampType Type { get { return m_Type; } set { m_Type = value; InvalidateProperties(); } } [CommandProperty(AccessLevel.GameMaster)] public bool Active { get { return m_Active; } set { if (value) Start(); else Stop(); } } [CommandProperty(AccessLevel.GameMaster)] public int Level { get { return m_Level; } set { m_Level = value; InvalidateProperties(); } } public void Start() { if (m_Active || Deleted) return; m_Active = true; if (m_Timer != null) m_Timer.Stop(); m_Timer = new SliceTimer(this); m_Timer.Start(); if (m_RestartTimer != null) m_RestartTimer.Stop(); m_RestartTimer = null; AdvanceLevel(); InvalidateProperties(); } public void Stop() { if (!m_Active || Deleted) return; m_Active = false; m_Level = 0; ClearSpawn(); Despawn(); if (m_Timer != null) m_Timer.Stop(); m_Timer = null; if (m_RestartTimer != null) m_RestartTimer.Stop(); m_RestartTimer = null; InvalidateProperties(); } public void Despawn() { foreach (var toDespawn in Despawns) { toDespawn.Delete(); } Despawns.Clear(); } public void OnSlice() { if (!m_Active || Deleted) return; bool changed = false; bool done = true; foreach (var spawn in Spawn) { if (spawn.Slice() && !changed) { changed = true; } if (!spawn.Done && done) { done = false; } } if (done) { AdvanceLevel(); } if (m_Active) { foreach (var spawn in Spawn) { if (spawn.Respawn() && !changed) { changed = true; } } } if (done || changed) { InvalidateProperties(); } } public void ClearSpawn() { foreach (var spawn in Spawn) { foreach (var creature in spawn.Creatures) { Despawns.Add(creature); } } Spawn.Clear(); } public void AdvanceLevel() { Level++; MiniChampInfo info = MiniChampInfo.GetInfo(m_Type); MiniChampLevelInfo levelInfo = info.GetLevelInfo(Level); if (levelInfo != null && Level <= info.MaxLevel) { ClearSpawn(); if (m_Type == MiniChampType.MeraktusTheTormented) { MinotaurShouts(); } foreach(var type in levelInfo.Types) { Spawn.Add(new MiniChampSpawnInfo(this, type)); } } else // begin restart { Stop(); m_RestartTimer = Timer.DelayCall(m_RestartDelay, new TimerCallback(Start)); } } private void MinotaurShouts() { int cliloc = 0; switch (Level) { case 1: return; case 2: cliloc = 1073370; break; case 3: cliloc = 1073367; break; case 4: cliloc = 1073368; break; case 5: cliloc = 1073369; break; } IPooledEnumerable eable = GetMobilesInRange(m_SpawnRange); foreach(Mobile x in eable) { if (x is PlayerMobile) x.SendLocalizedMessage(cliloc); } eable.Free(); } public override void GetProperties(ObjectPropertyList list) { base.GetProperties(list); list.Add(1060658, "Type\t{0}", m_Type); // ~1_val~: ~2_val~ list.Add(1060661, "Spawn Range\t{0}", m_SpawnRange); // ~1_val~: ~2_val~ if (m_Active) { MiniChampInfo info = MiniChampInfo.GetInfo(m_Type); list.Add(1060742); // active list.Add("Level {0} / {1}", Level, info != null ? info.MaxLevel.ToString() : "???"); // ~1_val~: ~2_val~ for (int i = 0; i < Spawn.Count; i++) { Spawn[i].AddProperties(list, i + 1150301); } } else { list.Add(1060743); // inactive } } public override void OnDoubleClick(Mobile from) { from.SendGump(new PropertiesGump(from, this)); } public override void OnDelete() { Controllers.Remove(this); Stop(); base.OnDelete(); } public MiniChamp(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write((int)0); // version writer.Write(BossSpawnPoint); writer.Write((bool)m_Active); writer.Write((int)m_Type); writer.Write((int)m_Level); writer.Write((int)m_SpawnRange); writer.Write((TimeSpan)m_RestartDelay); writer.Write((int)Spawn.Count); for (int i = 0; i < Spawn.Count; i++) { Spawn[i].Serialize(writer); } writer.Write(Despawns, true); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); int version = reader.ReadInt(); switch (version) { case 0: { Spawn = new List(); BossSpawnPoint = reader.ReadPoint3D(); m_Active = reader.ReadBool(); m_Type = (MiniChampType)reader.ReadInt(); m_Level = reader.ReadInt(); m_SpawnRange = reader.ReadInt(); m_RestartDelay = reader.ReadTimeSpan(); int spawnCount = reader.ReadInt(); for (int i = 0; i < spawnCount; i++) { Spawn.Add(new MiniChampSpawnInfo(reader)); } Despawns = reader.ReadStrongMobileList(); if (m_Active) { m_Timer = new SliceTimer(this); m_Timer.Start(); } else { m_RestartTimer = Timer.DelayCall(m_RestartDelay, new TimerCallback(Start)); } break; } } Controllers.Add(this); } } public class SliceTimer : Timer { private MiniChamp m_Controller; public SliceTimer(MiniChamp controller) : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) { m_Controller = controller; } protected override void OnTick() { m_Controller.OnSlice(); } } }