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

326 lines
8.7 KiB
C#

using System;
using Server;
using Server.Mobiles;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Items;
namespace Server.Engines.TreasuresOfKotlCity
{
public class KotlBattleSimulator : Item, ISpawner
{
public static KotlBattleSimulator Instance { get; set; }
public static int Levels = 7;
public static Rectangle2D SpawnBounds = new Rectangle2D(500, 2272, 87, 71);
public static Type[] SpawnTypes = new Type[] { typeof(SpectralKotlWarrior), typeof(SpectralMyrmidexWarrior) };
public static TimeSpan BattleDuration = TimeSpan.FromMinutes(60);
public static TimeSpan NextSpawnDuration { get { return TimeSpan.FromSeconds(Utility.RandomMinMax(2, 25)); } }
private bool _Active;
[CommandProperty(AccessLevel.GameMaster)]
public bool Active
{
get { return _Active; }
set
{
bool active = _Active;
_Active = value;
if (!active && _Active)
{
StartSpawn();
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int SpawnCount { get { return Spawn != null ? Spawn.Count : 0; } }
[CommandProperty(AccessLevel.GameMaster)]
public int Level { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int Kills { get; set; }
public List<ISpawnable> Spawn { get; set; }
public bool UnlinkOnTaming { get { return true; } }
public Point3D HomeLocation { get { return new Point3D(544, 2303, 0); } }
public int HomeRange { get { return 30; } }
public int SpawnPerWave { get { return 10 + (Level * 2); } }
public int KillsPerWave { get { return 20 + (Level * 2); } }
public Timer Timer { get; set; }
public KotlBattleSimulator()
: base(40147)
{
Visible = false;
Movable = false;
Instance = this;
}
private void StartSpawn()
{
Kills = 0;
Level = 0;
StartTimer();
for (int i = 0; i < SpawnPerWave; i++)
{
Timer.DelayCall(NextSpawnDuration, DoSpawn);
}
}
public void StartTimer()
{
EndTimer();
Timer = Timer.DelayCall(BattleDuration, EndSimulation);
Timer.Start();
}
public void EndTimer()
{
if (Timer != null)
{
Timer.Stop();
Timer = null;
}
}
public virtual void GetSpawnProperties(ISpawnable spawn, ObjectPropertyList list)
{ }
public virtual void GetSpawnContextEntries(ISpawnable spawn, Mobile user, List<ContextMenuEntry> list)
{ }
public void Remove(ISpawnable spawn)
{
if (Spawn != null && Spawn.Contains(spawn))
{
Kills++;
Spawn.Remove(spawn);
if (Kills >= KillsPerWave)
{
if (Level >= Levels)
{
EndSimulation();
return;
}
else
{
IncreaseLevel();
}
}
Timer.DelayCall(NextSpawnDuration, DoSpawn);
}
}
private void IncreaseLevel()
{
int oldMaxCount = SpawnPerWave;
Level++;
Kills = 0;
int inc = SpawnPerWave - oldMaxCount;
if (inc > 0)
{
for (int i = 0; i < inc; i++)
{
Timer.DelayCall(NextSpawnDuration, DoSpawn);
}
}
}
public void EndSimulation()
{
EndTimer();
if (WheelsOfTime.Instance != null && (WheelsOfTime.Instance.RockBarrier == null || WheelsOfTime.Instance.RockBarrier.Deleted))
{
WheelsOfTime.Instance.RockBarrier = new KotlWallAddon();
}
WheelsOfTime.Instance.RockBarrier.MoveToWorld(WheelsOfTime.RockBarrierLocation, Map.TerMur);
if (WheelsOfTime.Instance != null)
{
WheelsOfTime.Instance.TimeWarpEnds = DateTime.UtcNow + TimeSpan.FromSeconds(10);
}
PowerCoreDockingStation.Stations.ForEach(station =>
{
station.Deactivate();
});
Active = false;
Level = 0;
Kills = 0;
// What about spawn?
ColUtility.Free(Spawn);
}
private void DoSpawn()
{
if (!_Active)
return;
Point3D loc;
do
{
loc = Map.TerMur.GetRandomSpawnPoint(SpawnBounds);
}
while (!Map.TerMur.CanSpawnMobile(loc));
bool strong = Map.Tiles.GetStaticTiles(loc.X, loc.Y, true).Length > 0;
BaseCreature bc;
switch (Utility.Random(2))
{
default:
case 0: bc = new SpectralKotlWarrior(strong); break;
case 1: bc = new SpectralMyrmidexWarrior(strong); break;
}
if (bc != null)
{
bc.Spawner = this;
bc.Home = HomeLocation;
bc.RangeHome = HomeRange;
bc.OnBeforeSpawn(loc, Map.TerMur);
bc.MoveToWorld(loc, Map.TerMur);
bc.OnAfterSpawn();
if (Spawn == null)
Spawn = new List<ISpawnable>();
Spawn.Add(bc);
}
}
public KotlBattleSimulator(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // Version
writer.Write(_Active);
writer.Write(Level);
writer.Write(Kills);
if (Spawn != null)
{
writer.Write(Spawn.Count);
Spawn.ForEach(sp => writer.Write(sp as Mobile));
}
else
{
writer.Write(0);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Instance = this;
_Active = reader.ReadBool();
Level = reader.ReadInt();
Kills = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
BaseCreature bc = reader.ReadMobile() as BaseCreature;
if (bc != null)
{
bc.Spawner = this;
bc.Home = HomeLocation;
bc.RangeHome = HomeRange;
if (Spawn == null)
Spawn = new List<ISpawnable>();
Spawn.Add(bc);
}
}
if (_Active)
{
StartTimer();
if (Spawn == null || Spawn.Count == 0)
{
if (Spawn == null)
Spawn = new List<ISpawnable>();
if (Level >= Levels)
{
EndSimulation();
return;
}
else
{
IncreaseLevel();
}
}
else
{
int toSpawn = Math.Max(0, SpawnPerWave - (Spawn.Count + Kills));
if (toSpawn > 0)
{
for (int i = 0; i < toSpawn; i++)
{
Timer.DelayCall(NextSpawnDuration, DoSpawn);
}
}
}
}
// Teleporter Fix
if (version == 0)
{
Timer.DelayCall(TimeSpan.FromSeconds(20), () =>
{
if (Map != null)
{
IPooledEnumerable eable = Map.GetItemsInRange(new Point3D(644, 2308, 0), 0);
foreach (Item i in eable)
{
if (i is Teleporter)
{
((Teleporter)i).PointDest = new Point3D(543, 2479, 2);
}
}
}
});
}
}
}
}