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

1589 lines
42 KiB
C#

using System;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Items;
using Server.Gumps;
using Server.Engines.PartySystem;
using System.Linq;
namespace Server.Engines.Shadowguard
{
public class BarEncounter : ShadowguardEncounter
{
public const int LiquorCount = 10;
public override Type AddonType { get { return typeof(BarAddon); } }
public List<Mobile> Pirates { get; set; }
public int Wave { get; set; }
public List<ShadowguardBottleOfLiquor> Bottles { get; set; }
public BarEncounter()
: base(EncounterType.Bar)
{
}
public BarEncounter(ShadowguardInstance instance)
: base(EncounterType.Bar, instance)
{
}
public override void Setup()
{
Pirates = new List<Mobile>();
Bottles = new List<ShadowguardBottleOfLiquor>();
Wave = 0;
int toSpawn = Math.Max(3, PartySize() * 3);
for (int i = 0; i < toSpawn; i++)
SpawnRandomPirate();
for (int i = 0; i < LiquorCount; i++)
SpawnRandomLiquor();
}
public override void CheckEncounter()
{
if(Completed || Bottles == null)
return;
int liquorCount = Bottles.Where(b => b != null && !b.Deleted).Count();
if(liquorCount < LiquorCount)
{
SpawnRandomLiquor();
}
}
private void SpawnRandomLiquor()
{
int row = Utility.Random(4);
Rectangle2D rec = SpawnRecs[Utility.Random(SpawnRecs.Length)];
ConvertOffset(ref rec);
int x = Utility.RandomMinMax(rec.X, rec.X + rec.Width);
int y = Utility.RandomMinMax(rec.Y, rec.Y + rec.Height);
int z = -14;
x = x + (9 * row);
ShadowguardBottleOfLiquor bottle = new ShadowguardBottleOfLiquor(this);
bottle.MoveToWorld(new Point3D(x, y, z), Map.TerMur);
Bottles.Add(bottle);
}
private void SpawnRandomPirate()
{
if (Pirates == null)
return;
int row = Utility.Random(8);
Point3D ranPnt = SpawnPoints[Utility.Random(SpawnPoints.Length)];
ConvertOffset(ref ranPnt);
int a = row % 2 == 0 ? 0 : 3;
int startX = ranPnt.X + a;
int x = startX + ((row / 2) * 9);
ShadowguardPirate pirate = new ShadowguardPirate();
pirate.MoveToWorld(new Point3D(x, ranPnt.Y, ranPnt.Z), Map.TerMur);
Pirates.Add(pirate);
}
public override void OnCreatureKilled(BaseCreature bc)
{
if (!(bc is ShadowguardPirate) || Pirates == null)
return;
if(Pirates.Contains(bc))
Pirates.Remove(bc);
if(Pirates.Count <= 0)
{
Wave++;
Pirates.Clear();
int toSpawn = Math.Max(3, PartySize() * 3);
if(Wave < 4)
{
for (int i = 0; i < toSpawn; i++)
{
SpawnRandomPirate();
}
}
else if (Wave == 4)
{
var pirate = new ShantyThePirate();
Point3D p = SpawnPoints[Utility.Random(SpawnPoints.Length)];
ConvertOffset(ref p);
pirate.MoveToWorld(p, Map.TerMur);
Pirates.Add(pirate);
}
else
CompleteEncounter();
}
}
public override void ClearItems()
{
if (Bottles != null)
{
List<ShadowguardBottleOfLiquor> list = new List<ShadowguardBottleOfLiquor>(Bottles.Where(b => b != null && !b.Deleted));
foreach (var bottle in list)
bottle.Delete();
ColUtility.Free(list);
ColUtility.Free(Bottles);
Bottles = null;
}
if (Pirates != null)
{
ColUtility.Free(Pirates);
Pirates = null;
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Wave);
writer.Write(Pirates == null ? 0 : Pirates.Count);
if (Pirates != null) Pirates.ForEach(p => writer.Write(p));
writer.Write(Bottles == null ? 0 : Bottles.Count);
if (Bottles != null) Bottles.ForEach(b => writer.Write(b));
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Pirates = new List<Mobile>();
Bottles = new List<ShadowguardBottleOfLiquor>();
Wave = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Mobile p = reader.ReadMobile();
if (p != null)
Pirates.Add(p);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
ShadowguardBottleOfLiquor b = reader.ReadItem() as ShadowguardBottleOfLiquor;
if (b != null)
Bottles.Add(b);
}
if (Pirates == null || Pirates.Count < 6)
{
int toSpawn = Pirates == null ? 6 : 6 - Pirates.Count;
for (int i = 0; i < toSpawn; i++)
{
SpawnRandomPirate();
}
}
}
}
public class OrchardEncounter : ShadowguardEncounter
{
public List<ShadowguardCypress> Trees { get; set; }
public List<BaseCreature> Spawn { get; set; }
public Item Bones { get; set; }
public ShadowguardApple Apple { get; set; }
public override Type AddonType { get { return typeof(OrchardAddon); } }
public OrchardEncounter()
: base(EncounterType.Orchard)
{
}
public OrchardEncounter(ShadowguardInstance instance)
: base(EncounterType.Orchard, instance)
{
}
public override void Setup()
{
Trees = new List<ShadowguardCypress>();
Spawn = new List<BaseCreature>();
List<Point3D> points = new List<Point3D>();
for(int i = 0; i < SpawnPoints.Length; i++)
{
Point3D p = SpawnPoints[i];
ConvertOffset(ref p);
points.Add(p);
}
foreach(int i in Enum.GetValues(typeof(VirtueType)))
{
if(i > 7)
break;
ShadowguardCypress tree = new ShadowguardCypress(this, (VirtueType)i);
Point3D p = points[Utility.Random(points.Count)];
tree.MoveToWorld(p, Map.TerMur);
points.Remove(p);
Trees.Add(tree);
tree = new ShadowguardCypress(this, (VirtueType)i + 8);
p = points[Utility.Random(points.Count)];
tree.MoveToWorld(p, Map.TerMur);
points.Remove(p);
Trees.Add(tree);
}
Item bones = new WitheringBones();
Point3D pnt = new Point3D(-15, -11, 0);
ConvertOffset(ref pnt);
bones.MoveToWorld(pnt, Map.TerMur);
Bones = bones;
ColUtility.Free(points);
}
public override void CheckEncounter()
{
if (Trees == null)
return;
int treeCount = Trees.Count;
foreach(ShadowguardCypress tree in Trees)
{
if(tree == null || tree.Deleted)
treeCount--;
}
if(treeCount <= 0)
CompleteEncounter();
}
public override void CompleteEncounter()
{
base.CompleteEncounter();
ClearSpawn();
}
private void ClearSpawn()
{
if (Spawn != null)
{
List<BaseCreature> list = new List<BaseCreature>(Spawn.Where(e => e != null && e.Alive));
foreach (var spawn in list)
spawn.Delete();
ColUtility.Free(list);
ColUtility.Free(Spawn);
Spawn = null;
}
}
public void AddSpawn(BaseCreature bc)
{
if(Spawn != null)
Spawn.Add(bc);
}
public override void ClearItems()
{
ClearSpawn();
if (Apple != null)
{
Apple.Delete();
}
if (Trees != null)
{
List<ShadowguardCypress> list = new List<ShadowguardCypress>(Trees.Where(t => t != null && !t.Deleted));
foreach (var tree in list)
tree.Delete();
ColUtility.Free(list);
ColUtility.Free(Trees);
Trees = null;
}
if (Bones != null)
{
Bones.Delete();
Bones = null;
}
}
public void OnApplePicked()
{
if (Trees == null)
return;
foreach (var tree in Trees.Where(t => t != null && !t.Deleted))
{
if (tree.Foilage != null)
{
tree.Foilage.ItemID--;
}
}
}
public void OnAppleDeleted()
{
if (Trees == null)
return;
foreach (var tree in Trees.Where(t => t != null && !t.Deleted))
{
if (tree.Foilage != null)
{
tree.Foilage.ItemID++;
}
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Trees == null ? 0 : Trees.Count);
if (Trees != null) Trees.ForEach(t => writer.Write(t));
writer.Write(Spawn == null ? 0 : Spawn.Count);
if (Spawn != null) Spawn.ForEach(s => writer.Write(s));
writer.Write(Bones);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Trees = new List<ShadowguardCypress>();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
ShadowguardCypress tree = reader.ReadItem() as ShadowguardCypress;
if (tree != null)
Trees.Add(tree);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (Spawn == null)
Spawn = new List<BaseCreature>();
BaseCreature bc = reader.ReadMobile() as BaseCreature;
if (bc != null)
Spawn.Add(bc);
}
Bones = reader.ReadItem();
}
}
public class ArmoryEncounter : ShadowguardEncounter
{
public List<Item> Armor { get; set; }
public List<Item> DestroyedArmor { get; set; }
public List<Item> Items { get; set; }
public List<BaseCreature> Spawn { get; set; }
public override Type AddonType { get { return typeof(ArmoryAddon); } }
public ArmoryEncounter()
: base(EncounterType.Armory)
{
}
public ArmoryEncounter(ShadowguardInstance instance)
: base(EncounterType.Armory, instance)
{
}
public override void Setup()
{
Armor = new List<Item>();
DestroyedArmor = new List<Item>();
Spawn = new List<BaseCreature>();
Items = new List<Item>();
int toSpawn = 1 + (PartySize() * 2);
ColUtility.For(SpawnPoints, (i, p) =>
{
ConvertOffset(ref p);
var armor = new CursedSuitOfArmor(this);
armor.MoveToWorld(p, Map.TerMur);
Armor.Add(armor);
if(i > 13)
armor.ItemID = 0x1512;
});
for(int i = 0; i < toSpawn; i++)
{
SpawnRandom();
}
Item item = new Static(3633);
Point3D pnt = new Point3D(-4, 2, 0);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
item = new Static(3633);
pnt = new Point3D(-4, -4, 0);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
item = new Static(3633);
pnt = new Point3D(2, -4, 0);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
item = new PurifyingFlames();
pnt = new Point3D(-4, 2, 8);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
item = new PurifyingFlames();
pnt = new Point3D(-4, -4, 8);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
item = new PurifyingFlames();
pnt = new Point3D(2, -4, 8);
ConvertOffset(ref pnt);
item.MoveToWorld(pnt, Map.TerMur);
Items.Add(item);
}
public override void CheckEncounter()
{
if (Completed || Armor == null)
return;
if (Armor.Where(a => a != null && !a.Deleted).Count() == 0)
CompleteEncounter();
}
public override void OnCreatureKilled(BaseCreature bc)
{
if (Spawn != null && Spawn.Contains(bc))
{
Spawn.Remove(bc);
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(5, 15)), SpawnRandom);
}
}
public void AddDestroyedArmor(Item item)
{
if(DestroyedArmor != null)
DestroyedArmor.Add(item);
}
public override void CompleteEncounter()
{
base.CompleteEncounter();
ClearSpawn();
}
private void ClearSpawn()
{
if (Spawn != null)
{
List<BaseCreature> list = new List<BaseCreature>(Spawn.Where(s => s != null && !s.Deleted));
foreach (BaseCreature spawn in list)
spawn.Delete();
ColUtility.Free(list);
ColUtility.Free(Spawn);
Spawn = null;
}
}
public override void ClearItems()
{
if (Armor != null)
{
List<Item> list = new List<Item>(Armor.Where(i => i != null && !i.Deleted));
foreach (Item armor in list)
armor.Delete();
ColUtility.Free(list);
ColUtility.Free(Armor);
Armor = null;
}
if (DestroyedArmor != null)
{
List<Item> list = new List<Item>(DestroyedArmor.Where(i => i != null && !i.Deleted));
foreach (Item dest in list)
dest.Delete();
ColUtility.Free(list);
ColUtility.Free(DestroyedArmor);
DestroyedArmor = null;
}
if (Items != null)
{
List<Item> list = new List<Item>(Items.Where(i => i != null && !i.Deleted));
foreach (Item item in list)
item.Delete();
ColUtility.Free(list);
ColUtility.Free(Items);
Items = null;
}
}
private void SpawnRandom()
{
if (Spawn == null)
return;
Rectangle2D rec = SpawnRecs[Utility.Random(SpawnRecs.Length)];
ConvertOffset(ref rec);
while(true)
{
int x = Utility.RandomMinMax(rec.X, rec.X + rec.Width);
int y = Utility.RandomMinMax(rec.Y, rec.Y + rec.Height);
int z = Map.TerMur.GetAverageZ(x, y);
if(Map.TerMur.CanSpawnMobile(x, y, z))
{
var armor = new EnsorcelledArmor(this);
armor.MoveToWorld(new Point3D(x, y, z), Map.TerMur);
Spawn.Add(armor);
break;
}
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Armor == null ? 0 : Armor.Count);
if (Armor != null) Armor.ForEach(a => writer.Write(a));
writer.Write(DestroyedArmor == null ? 0 : DestroyedArmor.Count);
if (DestroyedArmor != null) DestroyedArmor.ForEach(a => writer.Write(a));
writer.Write(Spawn == null ? 0 : Spawn.Count);
if (Spawn != null) Spawn.ForEach(a => writer.Write(a));
writer.Write(Items == null ? 0 : Items.Count);
if (Items != null) Items.ForEach(i => writer.Write(i));
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Armor = new List<Item>();
DestroyedArmor = new List<Item>();
Items = new List<Item>();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Item it = reader.ReadItem();
if (it != null)
{
if(it is CursedSuitOfArmor)
((CursedSuitOfArmor)it).Encounter = this;
Armor.Add(it);
}
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Item it = reader.ReadItem();
if (it != null)
DestroyedArmor.Add(it);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (Spawn == null)
Spawn = new List<BaseCreature>();
BaseCreature bc = reader.ReadMobile() as BaseCreature;
if (bc != null)
{
if (bc is EnsorcelledArmor)
((EnsorcelledArmor)bc).Encounter = this;
Spawn.Add(bc);
}
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (Items == null)
Items = new List<Item>();
Item item = reader.ReadItem();
if (item != null)
{
Items.Add(item);
}
}
if (Spawn == null || Spawn.Count < 4)
{
int toSpawn = Spawn == null ? 4 : 4 - Spawn.Count;
for (int i = 0; i < toSpawn; i++)
{
if(Spawn == null)
Spawn = new List<BaseCreature>();
SpawnRandom();
}
}
}
}
public class FountainEncounter : ShadowguardEncounter
{
public static readonly int MaxElementals = 30;
public List<BaseCreature> Elementals { get; set; }
public List<Item> ShadowguardCanals { get; set; }
public List<FlowChecker> FlowCheckers { get; set; }
public DateTime _NextSpawn;
public override Type AddonType { get { return typeof(ShadowguardFountainAddon); } }
public FountainEncounter()
: base(EncounterType.Fountain)
{
}
public FountainEncounter(ShadowguardInstance instance)
: base(EncounterType.Fountain, instance)
{
}
public void UseSpigot(ShadowguardSpigot spigot, Mobile m)
{
if (FlowCheckers == null)
return;
foreach(FlowChecker checker in FlowCheckers)
{
if(checker.CheckUse(spigot, m))
return;
}
}
public override void CheckEncounter()
{
if (FlowCheckers != null && FlowCheckers.Where(c => c.Complete).Count() == 4)
CompleteEncounter();
}
public override void OnCreatureKilled(BaseCreature bc)
{
if (Elementals != null && Elementals.Contains(bc))
{
Elementals.Remove(bc);
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(1, 5)), SpawnRandomElemental);
}
}
public override void OnTick()
{
if (_NextSpawn < DateTime.UtcNow && (Elementals == null || Elementals.Count < MaxElementals))
{
SpawnRandomElemental();
_NextSpawn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(30, 45));
}
}
public override void Setup()
{
ShadowguardCanals = new List<Item>();
Elementals = new List<BaseCreature>();
FlowCheckers = new List<FlowChecker>();
int toSpawn = 3 + (PartySize() * 2);
Timer.DelayCall(ShadowguardController.ReadyDuration + TimeSpan.FromSeconds(30), () =>
{
for(int i = 0; i < toSpawn; i++)
SpawnRandomElemental();
});
for(int i = 0; i < 4; i++)
{
ShadowguardSpigot spigot = new ShadowguardSpigot(i < 2 ? 0x9BF2 : 0x9BE5);
Point3D p = SpawnPoints[i];
ConvertOffset(ref p);
spigot.MoveToWorld(p, Map.TerMur);
AddShadowguardCanal(spigot);
FlowCheckers.Add(new FlowChecker(spigot, this));
}
Rectangle2D rec1 = SpawnRecs[4];
Rectangle2D rec2 = SpawnRecs[5];
ConvertOffset(ref rec1);
ConvertOffset(ref rec2);
SpawnDrain(rec1);
SpawnDrain(rec2);
}
public override void CompleteEncounter()
{
base.CompleteEncounter();
ClearSpawn();
}
private void ClearSpawn()
{
if (Elementals != null)
{
List<BaseCreature> list = new List<BaseCreature>(Elementals.Where(t => t != null && !t.Deleted));
foreach (var elemental in list)
elemental.Delete();
ColUtility.Free(list);
ColUtility.Free(Elementals);
Elementals = null;
}
}
public override void ClearItems()
{
if (ShadowguardCanals != null)
{
List<Item> list = new List<Item>(ShadowguardCanals.Where(i => i != null && !i.Deleted));
foreach (var canal in list)
canal.Delete();
ColUtility.Free(list);
ColUtility.Free(ShadowguardCanals);
ShadowguardCanals = null;
}
ClearSpawn();
if (FlowCheckers != null)
{
ColUtility.ForEach(FlowCheckers.Where(f => f != null), f => f.EndEncounter());
}
}
private void SpawnRandomElemental()
{
if (Elementals == null)
return;
Rectangle2D rec = SpawnRecs[Utility.RandomMinMax(0, 3)];
ConvertOffset(ref rec);
while(true)
{
int x = Utility.RandomMinMax(rec.X, rec.X + rec.Width);
int y = Utility.RandomMinMax(rec.Y, rec.Y + rec.Height);
int z = Map.TerMur.GetAverageZ(x, y);
if(Map.TerMur.CanSpawnMobile(x, y, z))
{
BaseCreature elemental = new VileWaterElemental();
elemental.MoveToWorld(new Point3D(x, y, z), Map.TerMur);
Elementals.Add(elemental);
break;
}
}
}
private void SpawnDrain(Rectangle2D rec)
{
int x = Utility.RandomMinMax(rec.X, rec.X + rec.Width);
int y = Utility.RandomMinMax(rec.Y, rec.Y + rec.Height);
int z = Map.TerMur.GetAverageZ(x, y);
ShadowguardDrain drain = new ShadowguardDrain();
drain.MoveToWorld(new Point3D(x, y, z), Map.TerMur);
AddShadowguardCanal(drain);
}
public void SpawnBaddie(Mobile m)
{
if (Elementals == null)
return;
Point3D p = m.Location;
for (int i = 0; i < 10; i++)
{
int x = Utility.RandomMinMax(p.X - 1, p.X + 1);
int y = Utility.RandomMinMax(p.Y - 1, p.Y + 1);
if (Map.TerMur.CanSpawnMobile(x, y, -20))
{
p = new Point3D(x, y, -20);
break;
}
}
BaseCreature creature = new HurricaneElemental();
creature.MoveToWorld(p, Map.TerMur);
Elementals.Add(creature);
creature.Combatant = m;
}
public void AddShadowguardCanal(Item canal)
{
if(ShadowguardCanals != null && !ShadowguardCanals.Contains(canal))
ShadowguardCanals.Add(canal);
}
public class FlowChecker
{
private FountainEncounter _Encounter;
private List<ShadowguardCanal> _Checked;
private ShadowguardSpigot _Spigot;
private ShadowguardDrain _Drain;
public bool Complete { get { return _Spigot != null && _Drain != null; } }
public FlowChecker(ShadowguardSpigot start, FountainEncounter encounter)
{
_Spigot = start;
_Encounter = encounter;
}
public void EndEncounter()
{
if(_Spigot != null)
_Spigot.Delete();
if(_Checked != null)
{
ColUtility.Free(_Checked);
_Checked = null;
}
_Encounter = null;
}
public bool CheckUse(ShadowguardSpigot spigot, Mobile m)
{
if (spigot != _Spigot)
return false;
Check(m);
return true;
}
public void Check(Mobile m)
{
Point3D p;
Map map = Map.TerMur;
bool southFacing = _Spigot.ItemID == 39922;
if(_Checked != null)
_Checked.Clear();
if (southFacing)
p = new Point3D(_Spigot.X, _Spigot.Y + 1, -20);
else
p = new Point3D(_Spigot.X + 1, _Spigot.Y, -20);
Item item = FindItem(p);
if (item is ShadowguardCanal)
{
ShadowguardCanal canal = item as ShadowguardCanal;
if ((southFacing && (canal.Flow == Flow.NorthSouth || canal.Flow == Flow.SouthEastCorner || canal.Flow == Flow.SouthWestCorner)) ||
(!southFacing && (canal.Flow == Flow.EastWest || canal.Flow == Flow.SouthEastCorner || canal.Flow == Flow.NorthEastCorner)))
{
if (_Checked == null)
_Checked = new List<ShadowguardCanal>();
_Checked.Add(canal);
RecursiveCheck(item, null);
}
}
if(Complete)
{
Fill();
Timer.DelayCall(TimeSpan.FromSeconds(2), () => _Encounter.CheckEncounter());
}
else
_Encounter.SpawnBaddie(m);
}
public void RecursiveCheck(Item item, Item last)
{
Item next = null;
for(int i = 0; i < _Offsets.Length; i += 2)
{
Point3D p = new Point3D(item.X + _Offsets[i], item.Y + _Offsets[i+1], item.Z);
next = FindItem(p);
if(next != null && next != last)
{
if(Connects(item, next))
{
if(next is ShadowguardDrain)
{
_Drain = (ShadowguardDrain)next;
return;
}
else if (next is ShadowguardCanal)
{
if (_Checked == null)
_Checked = new List<ShadowguardCanal>();
_Checked.Add((ShadowguardCanal)next);
RecursiveCheck(next, item);
}
}
}
}
}
public bool Connects(Item one, Item two)
{
if(one is ShadowguardCanal && two is ShadowguardDrain)
{
Flow flow = ((ShadowguardCanal)one).Flow;
Direction d = Utility.GetDirection(one, two);
bool canConnect = false;
switch(d)
{
case Direction.North: canConnect = flow == Flow.NorthSouth || flow == Flow.SouthEastCorner || flow == Flow.SouthWestCorner; break;
case Direction.East: canConnect = flow == Flow.EastWest || flow == Flow.NorthWestCorner || flow == Flow.SouthWestCorner; break;
case Direction.South: canConnect = flow == Flow.NorthSouth || flow == Flow.NorthEastCorner || flow == Flow.NorthWestCorner; break;
case Direction.West: canConnect = flow == Flow.EastWest || flow == Flow.NorthEastCorner || flow == Flow.SouthEastCorner; break;
}
return canConnect;
}
else if (two is ShadowguardCanal)
{
return ((ShadowguardCanal)one).Connects((ShadowguardCanal)two);
}
return false;
}
public Item FindItem(Point3D p)
{
IPooledEnumerable eable = Map.TerMur.GetItemsInRange(p, 0);
foreach(Item i in eable)
{
if(i.Z == p.Z && (i is ShadowguardCanal || i is ShadowguardDrain))
{
eable.Free();
return i;
}
}
eable.Free();
return null;
}
private void Fill()
{
int time = 200;
if (_Spigot.ItemID == 39922)
_Spigot.ItemID = 17294;
else if (_Spigot.ItemID == 39909)
_Spigot.ItemID = 17278;
_Checked.ForEach(i => i.Movable = false);
ColUtility.For(_Checked, (i, item) =>
{
Timer.DelayCall(TimeSpan.FromMilliseconds(time), Fill, item);
time += 200;
});
}
private void Fill(object o)
{
if (o is ShadowguardCanal)
{
((ShadowguardCanal)o).Fill();
if (_Checked.IndexOf((ShadowguardCanal)o) == _Checked.Count - 1)
_Drain.Hue = 0;
}
}
private int[] _Offsets = new int[]
{
0, -1,
1, 0,
0, 1,
-1, 0
};
public FlowChecker(GenericReader reader, FountainEncounter encounter)
{
int version = reader.ReadInt();
_Encounter = encounter;
_Spigot = reader.ReadItem() as ShadowguardSpigot;
_Drain = reader.ReadItem() as ShadowguardDrain;
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (_Checked == null)
_Checked = new List<ShadowguardCanal>();
ShadowguardCanal c = reader.ReadItem() as ShadowguardCanal;
if (c != null)
_Checked.Add(c);
}
}
public void Serialize(GenericWriter writer)
{
writer.Write(0);
writer.Write(_Spigot);
writer.Write(_Drain);
writer.Write(_Checked == null ? 0 : _Checked.Count);
if (_Checked != null) _Checked.ForEach(c => writer.Write(c));
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Elementals == null ? 0 : Elementals.Count);
if (Elementals != null) Elementals.ForEach(e => writer.Write(e));
writer.Write(ShadowguardCanals == null ? 0 : ShadowguardCanals.Count);
if (ShadowguardCanals != null) ShadowguardCanals.ForEach(c => writer.Write(c));
writer.Write(FlowCheckers == null ? 0 : FlowCheckers.Count);
if (FlowCheckers != null) FlowCheckers.ForEach(f => f.Serialize(writer));
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Elementals = new List<BaseCreature>();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
BaseCreature bc = reader.ReadMobile() as BaseCreature;
if (bc != null)
Elementals.Add(bc);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (ShadowguardCanals == null)
ShadowguardCanals = new List<Item>();
Item canal = reader.ReadItem();
if (canal != null)
ShadowguardCanals.Add(canal);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
if (FlowCheckers == null)
FlowCheckers = new List<FlowChecker>();
FlowCheckers.Add(new FlowChecker(reader, this));
}
if (Elementals == null || Elementals.Count < 8)
{
int toSpawn = Elementals == null ? 8 : 8 - Elementals.Count;
for (int i = 0; i < toSpawn; i++)
{
SpawnRandomElemental();
}
}
}
}
public class BelfryEncounter : ShadowguardEncounter
{
public List<VileDrake> Drakes { get; set; }
public ShadowguardGreaterDragon Dragon { get; set; }
public List<Item> Bells { get; set; }
public override Type AddonType { get { return typeof(BelfryAddon); } }
public BelfryEncounter()
: base(EncounterType.Belfry)
{
}
public BelfryEncounter(ShadowguardInstance instance)
: base(EncounterType.Belfry, instance)
{
}
public override void Setup()
{
Drakes = new List<VileDrake>();
Bells = new List<Item>();
Point3D p = SpawnPoints[0];
ConvertOffset(ref p);
Dragon = new ShadowguardGreaterDragon();
Dragon.MoveToWorld(p, Map.TerMur);
FeedingBell bell = new FeedingBell();
p = new Point3D(16, 6, 0);
ConvertOffset(ref p);
bell.MoveToWorld(p, Map.TerMur);
Bells.Add(bell);
bell = new FeedingBell();
p = new Point3D(16, -7, 0);
ConvertOffset(ref p);
bell.MoveToWorld(p, Map.TerMur);
Bells.Add(bell);
bell = new FeedingBell();
p = new Point3D(-20, -7, 0);
ConvertOffset(ref p);
bell.MoveToWorld(p, Map.TerMur);
Bells.Add(bell);
bell = new FeedingBell();
p = new Point3D(-20, 6, 0);
ConvertOffset(ref p);
bell.MoveToWorld(p, Map.TerMur);
Bells.Add(bell);
}
public void SpawnDrake(Point3D p, Mobile from)
{
if (Drakes == null)
return;
Rectangle2D rec = SpawnRecs[0];
ConvertOffset(ref rec);
foreach (Rectangle2D r in SpawnRecs)
{
Rectangle2D copy = r;
ConvertOffset(ref copy);
if (copy.Contains(p))
{
rec = copy;
break;
}
}
while(true)
{
int x = Utility.RandomMinMax(rec.X, rec.X + rec.Width);
int y = Utility.RandomMinMax(rec.Y, rec.Y + rec.Height);
int z = Map.TerMur.GetAverageZ(x, y);
if(Map.TerMur.CanSpawnMobile(x, y, z))
{
var drake = new VileDrake();
drake.MoveToWorld(new Point3D(x, y, z), Map.TerMur);
Timer.DelayCall(TimeSpan.FromSeconds(.5), () => drake.Combatant = from);
Drakes.Add(drake);
break;
}
}
}
public override void CheckEncounter()
{
}
public override void OnCreatureKilled(BaseCreature bc)
{
if(bc is VileDrake && Drakes != null && Drakes.Contains((VileDrake)bc))
Drakes.Remove((VileDrake)bc);
if(bc == Dragon)
{
CompleteEncounter();
}
}
public override void ClearItems()
{
if (Drakes != null)
{
List<BaseCreature> list = new List<BaseCreature>(Drakes.Where(d => d != null && !d.Deleted));
foreach (var drake in list)
drake.Delete();
ColUtility.Free(list);
ColUtility.Free(Drakes);
Drakes = null;
}
if (Bells != null)
{
List<Item> list = new List<Item>(Bells.Where(b => b != null && !b.Deleted));
foreach (var bell in list)
bell.Delete();
ColUtility.Free(list);
ColUtility.Free(Bells);
Bells = null;
}
if(Dragon != null && Dragon.Alive)
Dragon.Delete();
Dragon = null;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(Dragon);
writer.Write(Drakes == null ? 0 : Drakes.Count);
if (Drakes != null) Drakes.ForEach(d => writer.Write(d));
writer.Write(Bells == null ? 0 : Bells.Count);
if (Bells != null) Bells.ForEach(b => writer.Write(b));
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Drakes = new List<VileDrake>();
Bells = new List<Item>();
Dragon = reader.ReadMobile() as ShadowguardGreaterDragon;
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
VileDrake d = reader.ReadMobile() as VileDrake;
if (d != null)
Drakes.Add(d);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
FeedingBell b = reader.ReadItem() as FeedingBell;
if (b != null)
Bells.Add(b);
}
if (Dragon == null || Dragon.Deleted)
Expire();
}
}
public class RoofEncounter : ShadowguardEncounter
{
[CommandProperty(AccessLevel.GameMaster)]
public ShadowguardBoss CurrentBoss { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public LadyMinax Minax { get; set; }
public List<Type> Bosses { get; set; }
private Type[] _Bosses = new Type[] { typeof(Anon), typeof(Virtuebane), typeof(Ozymandias), typeof(Juonar) };
public override TimeSpan EncounterDuration { get { return TimeSpan.MaxValue; } }
public override TimeSpan ResetDuration { get { return TimeSpan.FromMinutes(5); } }
public override Type AddonType { get { return null; } }
public override void Setup()
{
Bosses = new List<Type>(_Bosses);
for(int i = 0; i < 15; i++)
{
Type t = Bosses[Utility.Random(Bosses.Count)];
Bosses.Remove(t);
Bosses.Insert(0, t);
}
Point3D p = SpawnPoints[0];
ConvertOffset(ref p);
Minax = new LadyMinax();
Minax.MoveToWorld(p, Map.TerMur);
Minax.Home = p;
Minax.RangeHome = 5;
Timer.DelayCall(TimeSpan.FromSeconds(35), () =>
{
SendPartyMessage(1156255); // Minax Says: Well Well! You've managed to get through my fortress but alas you shall never foil my plans! Perhaps you need some friends to play with? Muwahhahah!
});
Timer.DelayCall(TimeSpan.FromSeconds(40), SpawnBoss);
}
public RoofEncounter()
: base(EncounterType.Roof)
{
}
public RoofEncounter(ShadowguardInstance instance)
: base(EncounterType.Roof, instance)
{
}
public override void CheckEncounter()
{
}
public override void CompleteEncounter()
{
base.CompleteEncounter();
foreach (var pm in Region.GetEnumeratedMobiles().OfType<PlayerMobile>())
{
Controller.CompleteRoof(pm);
}
}
public override void OnCreatureKilled(BaseCreature bc)
{
if(Bosses != null && bc is ShadowguardBoss && bc == CurrentBoss)
{
if (Bosses.Count > 0)
SpawnBoss();
else
{
if (Minax != null && Minax.Alive)
Minax.Say(1156257); // How...How could this happen! I shall nay be bested by mere mortals! We shall meet again vile heroes!
GiveRewardTitle();
CompleteEncounter();
}
}
}
private void GiveRewardTitle()
{
Mobile m = PartyLeader;
if (m == null)
return;
foreach (var pm in Region.GetEnumeratedMobiles().OfType<PlayerMobile>())
{
pm.AddRewardTitle(1156318); // Destroyer of the Time Rift
}
}
public override void ClearItems()
{
if (Minax != null)
Minax.Delete();
if (Bosses != null)
{
ColUtility.Free(Bosses);
Bosses = null;
}
if (CurrentBoss != null)
{
if(!CurrentBoss.Deleted)
CurrentBoss.Delete();
CurrentBoss = null;
}
}
private void SpawnBoss()
{
if (Bosses == null)
return;
Point3D p = SpawnPoints[0];
ConvertOffset(ref p);
CurrentBoss = Activator.CreateInstance(Bosses[0]) as ShadowguardBoss;
Bosses.Remove(Bosses[0]);
if(CurrentBoss != null)
{
CurrentBoss.MoveToWorld(p, Map.TerMur);
}
if (Bosses.Count == 0)
CurrentBoss.IsLastBoss = true;
if (Minax != null && Minax.Alive)
{
if (CurrentBoss is Juonar)
Minax.Say(1156258); // You shall burn as Trinsic burned at the hands of the Vile Lich Juo'nar!
else if (CurrentBoss is Anon)
Minax.Say(1156259); // Oh Anon my dear! Deal with these pesky intruders will you? Burn them to ASH!
else if (CurrentBoss is Virtuebane)
Minax.Say(1156260); // You didn't think that ridiculous pie trick would work twice in a row? Virtuebane I command thee destroy these vile creatures!
else
Minax.Say(1156261); // And now you shall bow to the King of Kings! Suffer at the hands of the Feudal Lord Ozymandias!
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(CurrentBoss);
writer.Write(Minax);
writer.Write(Bosses == null ? 0 : Bosses.Count);
if (Bosses != null) Bosses.ForEach(b => writer.Write(b.Name));
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
Bosses = new List<Type>();
CurrentBoss = reader.ReadMobile() as ShadowguardBoss;
Minax = reader.ReadMobile() as LadyMinax;
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Type boss = ScriptCompiler.FindTypeByName(reader.ReadString());
if (boss != null)
Bosses.Add(boss);
}
if (CurrentBoss == null && !Completed)
{
Completed = true;
}
}
}
}