1589 lines
42 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|