Files
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

367 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Commands;
using Server.Gumps;
namespace Server.Engines.SorcerersDungeon
{
public class TOSDSpawner
{
public static void Initialize()
{
CommandSystem.Register("TOSDSpawner", AccessLevel.Administrator, e =>
{
if (e.Mobile is PlayerMobile)
{
if (Instance != null)
{
BaseGump.SendGump(new TOSDSpawnerGump((PlayerMobile)e.Mobile));
}
else
{
e.Mobile.SendMessage("This spawner is not set up at this time. Enabled Treasures of Sorcerer's Dungeon to enable the spawner.");
}
}
});
if (Instance != null)
{
Instance.BeginTimer();
}
}
public static TOSDSpawner Instance { get; set; }
public BaseCreature Boss { get; set; }
public int Index { get; set; }
public int KillCount { get; set; }
public List<BaseCreature> Spawn { get; set; }
public bool Spawning { get; set; }
public Timer Timer { get; set; }
public List<TOSDSpawnEntry> Entries { get; set; }
public TOSDSpawner()
{
Instance = this;
Entries = new List<TOSDSpawnEntry>();
Spawn = new List<BaseCreature>();
BuildEntries();
Activate();
}
private void Activate()
{
foreach (var rec in Entries.Select(e => e.SpawnArea))
{
IPooledEnumerable eable = Map.Ilshenar.GetItemsInBounds(rec);
foreach (Item item in eable)
{
if (item is XmlSpawner)
{
((XmlSpawner)item).DoReset = true;
}
}
}
}
public void Deactivate()
{
foreach (var rec in Entries.Select(e => e.SpawnArea))
{
IPooledEnumerable eable = Map.Ilshenar.GetItemsInBounds(rec);
foreach (Item item in eable)
{
if (item is XmlSpawner)
{
((XmlSpawner)item).DoRespawn = true;
}
}
}
EndTimer();
foreach (var bc in Spawn)
{
bc.Delete();
}
Instance = null;
}
public void BeginTimer()
{
EndTimer();
Timer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), OnTick);
Timer.Start();
}
public void EndTimer()
{
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
}
private void OnTick()
{
if (Spawning)
{
return;
}
if (Boss != null && Boss.Deleted)
{
if (Index == Entries.Count - 1)
{
Index = 0;
}
else
{
Index++;
}
Reset();
}
else if (Boss == null && KillCount >= Entries[Index].ToKill)
{
DoSpawn(Entries[Index].Boss, true);
}
else if (Spawn.Count < Entries[Index].MaxSpawn && (Boss == null || Entries[Index].SpawnArea.Contains(Boss)))
{
Spawning = true;
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(3, 8)), () =>
{
DoSpawn(Entries[Index].Spawn[Utility.Random(Entries[Index].Spawn.Length)], false);
Spawning = false;
});
}
}
public void DoSpawn(Type t, bool boss)
{
var spawn = Activator.CreateInstance(t) as BaseCreature;
for (int i = 0; i < 20; i++)
{
var p = Map.Ilshenar.GetRandomSpawnPoint(Entries[Index].SpawnArea);
if (Map.Ilshenar.CanSpawnMobile(p))
{
spawn.MoveToWorld(p, Map.Ilshenar);
if (boss)
{
Boss = spawn;
}
else
{
AddSpawn(spawn);
}
return;
}
}
spawn.Delete();
}
public void AddSpawn(BaseCreature bc)
{
Spawn.Add(bc);
}
public void OnCreatureDeath(BaseCreature bc)
{
if (Spawn.Contains(bc))
{
Spawn.Remove(bc);
KillCount++;
}
}
public void Reset()
{
ColUtility.Free(Spawn);
Boss = null;
Spawning = false;
KillCount = 0;
EndTimer();
Timer.DelayCall(TimeSpan.FromMinutes(Utility.RandomMinMax(1, 3)), () =>
{
BeginTimer();
});
}
public void Serialize(GenericWriter writer)
{
writer.Write(0);
writer.Write(Boss);
writer.Write(KillCount);
writer.Write(Index);
writer.Write(Spawn.Count);
foreach (var bc in Spawn)
{
writer.Write(bc);
}
}
public void Deserialize(GenericReader reader)
{
reader.ReadInt(); // version
Boss = reader.ReadMobile() as BaseCreature;
KillCount = reader.ReadInt();
Index = reader.ReadInt();
int count = reader.ReadInt();
for(int i = 0; i < count; i++)
{
var bc = reader.ReadMobile() as BaseCreature;
if(bc != null)
{
AddSpawn(bc);
}
}
}
public void BuildEntries()
{
Entries.Add(new TOSDSpawnEntry(typeof(NightmareFairy), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(327, 26, 29, 32), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(JackInTheBox), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(296, 10, 17, 26), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(HeadlessElf), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(271, 4, 20, 33), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(AbominableSnowman), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(227, 39, 21, 19), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(TwistedHolidayTree), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(251, 68, 25, 32), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(RabidReindeer), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(144, 5, 23, 19), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(GarishGingerman), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(60, 53, 13, 34), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(StockingSerpent), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(152, 48, 16, 23), 80, 15));
Entries.Add(new TOSDSpawnEntry(typeof(JackThePumpkinKing), new Type[] { typeof(Zombie), typeof(Skeleton), typeof(Gargoyle), typeof(Lich), typeof(LichLord) }, new Rectangle2D(291, 73, 37, 36), 80, 15));
}
}
public class TOSDSpawnEntry
{
public Type Boss { get; set; }
public Type[] Spawn { get; set; }
public Rectangle2D SpawnArea { get; set; }
public int ToKill { get; set; }
public int MaxSpawn { get; set; }
public TOSDSpawnEntry(Type boss, Type[] spawn, Rectangle2D area, int toKill, int maxSpawn)
{
Boss = boss;
Spawn = spawn;
SpawnArea = area;
ToKill = toKill;
MaxSpawn = maxSpawn;
}
}
public class TOSDSpawnerGump : BaseGump
{
public TOSDSpawnerGump(PlayerMobile pm)
: base(pm, 50, 50)
{
}
public override void AddGumpLayout()
{
AddBackground(0, 0, 500, 300, 9300);
AddHtml(0, 10, 500, 20, Center("Treasures of Sorcerer's Dungeon Spawner"), false, false);
var spawner = TOSDSpawner.Instance;
if (spawner == null)
{
AddHtml(10, 40, 150, 20, "Spawner Disabled", false, false);
}
else
{
int y = 60;
AddLabel(10, 40, 0, "Go");
AddLabel(40, 40, 0, "Boss");
AddLabel(240, 40, 0, "Current");
AddLabel(320, 40, 0, "Max");
AddLabel(400, 40, 0, "Killed");
for (int i = 0; i < spawner.Entries.Count; i++)
{
var entry = spawner.Entries[i];
var hue = i == spawner.Index ? "green" : "red";
AddButton(7, y, 1531, 1532, i + 100, GumpButtonType.Reply, 0);
AddHtml(40, y, 200, 20, Color(hue, entry.Boss.Name), false, false);
AddHtml(320, y, 80, 20, Color(hue, entry.MaxSpawn.ToString()), false, false);
if (hue == "green")
{
AddHtml(240, y, 80, 20, Color(hue, spawner.Spawn.Count.ToString()), false, false);
AddHtml(400, y, 80, 20, Color(hue, spawner.KillCount.ToString()), false, false);
}
else
{
AddHtml(240, y, 80, 20, Color(hue, "0"), false, false);
AddHtml(400, y, 80, 20, Color(hue, "0"), false, false);
}
y += 22;
}
}
}
public override void OnResponse(RelayInfo info)
{
if (info.ButtonID > 0)
{
int id = info.ButtonID - 100;
var spawner = TOSDSpawner.Instance;
if (spawner != null && id >= 0 && id < spawner.Entries.Count)
{
var entry = spawner.Entries[id];
do
{
var p = Map.Ilshenar.GetRandomSpawnPoint(entry.SpawnArea);
if (Map.Ilshenar.CanSpawnMobile(p))
{
User.MoveToWorld(p, Map.Ilshenar);
Refresh();
break;
}
}
while (true);
}
}
}
}
}