Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusAlterAddon : BaseAddon
|
||||
{
|
||||
[Constructable]
|
||||
public ExodusAlterAddon()
|
||||
{
|
||||
this.AddComponent(0x3F9, 0, 1, 5);
|
||||
this.AddComponent(0x3FA, 1, 0, 5);
|
||||
this.AddComponent(0x3F7, 0, 0, 5);
|
||||
this.AddComponent(0x3F8, 1, 1, 5);
|
||||
}
|
||||
|
||||
public void AddComponent(int id, int x, int y, int z)
|
||||
{
|
||||
AddonComponent ac = new AddonComponent(id);
|
||||
|
||||
ac.Hue = 2702;
|
||||
this.AddComponent(ac, x, y, z);
|
||||
}
|
||||
|
||||
public ExodusAlterAddon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0); // Version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusChest : DecorativeBox, IRevealableItem
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
TileData.ItemTable[0x2DF3].Flags = TileFlag.None;
|
||||
}
|
||||
|
||||
public override int DefaultGumpID { get { return 0x10C; } }
|
||||
|
||||
public bool CheckWhenHidden { get { return true; } }
|
||||
|
||||
public static Type[] RituelItem { get { return m_RituelItem; } }
|
||||
|
||||
private static Type[] m_RituelItem = new Type[]
|
||||
{
|
||||
typeof(ExodusSummoningRite), typeof(ExodusSacrificalDagger), typeof(RobeofRite), typeof(ExodusSummoningAlter)
|
||||
};
|
||||
|
||||
private Timer m_Timer;
|
||||
private ExodusChestRegion m_Region;
|
||||
|
||||
public override bool IsDecoContainer { get { return false; } }
|
||||
|
||||
[Constructable]
|
||||
public ExodusChest()
|
||||
: base()
|
||||
{
|
||||
Visible = false;
|
||||
Locked = true;
|
||||
LockLevel = 90;
|
||||
RequiredSkill = 90;
|
||||
MaxLockLevel = 100;
|
||||
Weight = 0.0;
|
||||
Hue = 2700;
|
||||
Movable = false;
|
||||
|
||||
TrapType = TrapType.PoisonTrap;
|
||||
TrapPower = 100;
|
||||
GenerateTreasure();
|
||||
}
|
||||
|
||||
public ExodusChest(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CheckReveal(Mobile m)
|
||||
{
|
||||
if (!m.InRange(Location, 3))
|
||||
return false;
|
||||
|
||||
return m.Skills[SkillName.DetectHidden].Value >= 98.0;
|
||||
}
|
||||
|
||||
public virtual void OnRevealed(Mobile m)
|
||||
{
|
||||
Visible = true;
|
||||
StartDeleteTimer();
|
||||
}
|
||||
|
||||
public virtual bool CheckPassiveDetect(Mobile m)
|
||||
{
|
||||
if (m.InRange(this.Location, 4))
|
||||
{
|
||||
int skill = (int)m.Skills[SkillName.DetectHidden].Value;
|
||||
|
||||
if (skill >= 80 && Utility.Random(300) < skill)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void StartDeleteTimer()
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.2)
|
||||
{
|
||||
Item item = Activator.CreateInstance(m_RituelItem[Utility.Random(m_RituelItem.Length)]) as Item;
|
||||
DropItem(item);
|
||||
}
|
||||
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromMinutes(5), new TimerCallback(Delete));
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLoc)
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
UpdateRegion();
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (Deleted)
|
||||
return;
|
||||
|
||||
UpdateRegion();
|
||||
}
|
||||
|
||||
public void UpdateRegion()
|
||||
{
|
||||
if (m_Region != null)
|
||||
m_Region.Unregister();
|
||||
|
||||
if (!Deleted && Map != Map.Internal)
|
||||
{
|
||||
m_Region = new ExodusChestRegion(this);
|
||||
m_Region.Register();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
|
||||
base.OnAfterDelete();
|
||||
|
||||
UpdateRegion();
|
||||
}
|
||||
|
||||
protected virtual void GenerateTreasure()
|
||||
{
|
||||
DropItem(new Gold(1500, 3000));
|
||||
|
||||
Item item = null;
|
||||
|
||||
for (int i = 0 ; i < Loot.GemTypes.Length; i++)
|
||||
{
|
||||
item = Activator.CreateInstance(Loot.GemTypes[i]) as Item;
|
||||
item.Amount = Utility.Random(1, 6);
|
||||
DropItem(item);
|
||||
}
|
||||
|
||||
if (0.25 > Utility.RandomDouble())
|
||||
{
|
||||
item = new SmokeBomb(Utility.Random(3, 6));
|
||||
DropItem(item);
|
||||
}
|
||||
|
||||
if (0.25 > Utility.RandomDouble())
|
||||
{
|
||||
switch (Utility.Random(2))
|
||||
{
|
||||
case 0:
|
||||
item = new ParasiticPotion(Utility.Random(1, 3)); break;
|
||||
case 1:
|
||||
item = new InvisibilityPotion(Utility.Random(1, 3)); break;
|
||||
}
|
||||
|
||||
DropItem(item);
|
||||
}
|
||||
|
||||
if (0.2 > Utility.RandomDouble())
|
||||
{
|
||||
item = Loot.RandomEssence();
|
||||
item.Amount = Utility.Random(3, 6);
|
||||
DropItem(item);
|
||||
}
|
||||
|
||||
if (0.1 > Utility.RandomDouble())
|
||||
{
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0: DropItem(new Taint()); break;
|
||||
case 1: DropItem(new Corruption()); break;
|
||||
case 2: DropItem(new Blight()); break;
|
||||
case 3: DropItem(new LuminescentFungi()); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void GiveRituelItem(Mobile m)
|
||||
{
|
||||
Item item = Activator.CreateInstance(m_RituelItem[Utility.Random(m_RituelItem.Length)]) as Item;
|
||||
m.PlaySound(0x5B4);
|
||||
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
m.AddToBackpack(item);
|
||||
m.SendLocalizedMessage(1072223); // An item has been placed in your backpack.
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (!Locked)
|
||||
Delete();
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(UpdateRegion));
|
||||
}
|
||||
}
|
||||
|
||||
public class ExodusChestRegion : BaseRegion
|
||||
{
|
||||
private readonly ExodusChest m_Chest;
|
||||
|
||||
public ExodusChest ExodusChest { get { return m_Chest; } }
|
||||
|
||||
public ExodusChestRegion(ExodusChest chest)
|
||||
: base(null, chest.Map, Region.Find(chest.Location, chest.Map), new Rectangle2D(chest.Location.X - 2, chest.Location.Y - 2 , 5, 5) )
|
||||
{
|
||||
m_Chest = chest;
|
||||
}
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
if (!m_Chest.Visible && m is PlayerMobile && m.Skills[SkillName.DetectHidden].Value >= 98.0)
|
||||
{
|
||||
m.SendLocalizedMessage(1153493); // Your keen senses detect something hidden in the area...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,538 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusNexus : NexusAddon
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("GenExodusNexus", AccessLevel.Administrator, Generate_ExodusNexus);
|
||||
}
|
||||
|
||||
public static void Generate_ExodusNexus(CommandEventArgs e)
|
||||
{
|
||||
Decorate.Generate("exodus", "Data/Decoration/Exodus", Map.Ilshenar);
|
||||
}
|
||||
|
||||
private static readonly TimeSpan m_UseTimeout = TimeSpan.FromMinutes(2.0);
|
||||
private Dictionary<Mobile, DamageTimer> DamageTable = new Dictionary<Mobile, DamageTimer>();
|
||||
private int m_SideLength;
|
||||
private Node[] m_Path;
|
||||
private Mobile User { get; set; }
|
||||
private DateTime LastUse { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active { get { return this.Hue == 0; } }
|
||||
|
||||
[Constructable]
|
||||
public ExodusNexus()
|
||||
: this(Utility.RandomMinMax(3, 6))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ExodusNexus(int sideLength)
|
||||
{
|
||||
this.Hue = 1987;
|
||||
this.SideLength = sideLength;
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int SideLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_SideLength;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 3)
|
||||
value = 3;
|
||||
else if (value > 6)
|
||||
value = 6;
|
||||
|
||||
if (this.m_SideLength != value)
|
||||
{
|
||||
this.m_SideLength = value;
|
||||
this.ExodusInitPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Node[] Path { get { return this.m_Path; } }
|
||||
|
||||
public struct Node
|
||||
{
|
||||
private int m_X;
|
||||
private int m_Y;
|
||||
|
||||
public Node(int x, int y)
|
||||
{
|
||||
this.m_X = x;
|
||||
this.m_Y = y;
|
||||
}
|
||||
|
||||
public int X
|
||||
{
|
||||
get { return this.m_X; }
|
||||
set { this.m_X = value; }
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get { return this.m_Y; }
|
||||
set { this.m_Y = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public enum PathDirection
|
||||
{
|
||||
Left,
|
||||
Up,
|
||||
Right,
|
||||
Down
|
||||
}
|
||||
|
||||
public void ExodusInitPath()
|
||||
{
|
||||
// Depth-First Search algorithm
|
||||
int totalNodes = this.SideLength * this.SideLength;
|
||||
|
||||
Node[] stack = new Node[totalNodes];
|
||||
Node current = stack[0] = new Node(0, 0);
|
||||
int stackSize = 1;
|
||||
|
||||
bool[,] visited = new bool[this.SideLength, this.SideLength];
|
||||
visited[0, 0] = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
PathDirection[] choices = new PathDirection[4];
|
||||
int count = 0;
|
||||
|
||||
if (current.X > 0 && !visited[current.X - 1, current.Y])
|
||||
choices[count++] = PathDirection.Left;
|
||||
|
||||
if (current.Y > 0 && !visited[current.X, current.Y - 1])
|
||||
choices[count++] = PathDirection.Up;
|
||||
|
||||
if (current.X < this.SideLength - 1 && !visited[current.X + 1, current.Y])
|
||||
choices[count++] = PathDirection.Right;
|
||||
|
||||
if (current.Y < this.SideLength - 1 && !visited[current.X, current.Y + 1])
|
||||
choices[count++] = PathDirection.Down;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
PathDirection dir = choices[Utility.Random(count)];
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case PathDirection.Left:
|
||||
current = new Node(current.X - 1, current.Y);
|
||||
break;
|
||||
case PathDirection.Up:
|
||||
current = new Node(current.X, current.Y - 1);
|
||||
break;
|
||||
case PathDirection.Right:
|
||||
current = new Node(current.X + 1, current.Y);
|
||||
break;
|
||||
default:
|
||||
current = new Node(current.X, current.Y + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
stack[stackSize++] = current;
|
||||
|
||||
if (current.X == this.SideLength - 1 && current.Y == this.SideLength - 1)
|
||||
break;
|
||||
|
||||
visited[current.X, current.Y] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = stack[--stackSize - 1];
|
||||
}
|
||||
}
|
||||
|
||||
this.m_Path = new Node[stackSize];
|
||||
|
||||
for (int i = 0; i < stackSize; i++)
|
||||
{
|
||||
this.m_Path[i] = stack[i];
|
||||
}
|
||||
|
||||
if (this.User != null)
|
||||
{
|
||||
this.User.CloseGump(typeof(NexusGameGump));
|
||||
this.User = null;
|
||||
}
|
||||
}
|
||||
|
||||
public ExodusNexus(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public void OpenGump(Mobile from)
|
||||
{
|
||||
if (!from.InRange(this, 3))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.User != null)
|
||||
{
|
||||
if (this.User == from)
|
||||
return;
|
||||
|
||||
if (this.User.Deleted || this.User.Map != this.Map || !this.User.InRange(this, 3) ||
|
||||
this.User.NetState == null || DateTime.UtcNow - this.LastUse >= m_UseTimeout)
|
||||
{
|
||||
this.User.CloseGump(typeof(NexusGameGump));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1152379); // Someone is currently working at the Nexus.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.User = from;
|
||||
this.LastUse = DateTime.UtcNow;
|
||||
|
||||
from.SendGump(new NexusGameGump(this, from, 0, false));
|
||||
}
|
||||
|
||||
public void DoDamage(Mobile to)
|
||||
{
|
||||
to.SendLocalizedMessage(1152372); // The Nexus shoots an arc of energy at you!
|
||||
to.BoltEffect(0);
|
||||
to.LocalOverheadMessage(Server.Network.MessageType.Regular, 0x21, 1114443); // * Your body convulses from electric shock *
|
||||
to.NonlocalOverheadMessage(Server.Network.MessageType.Regular, 0x21, 1114443, to.Name); // * ~1_NAME~ spasms from electric shock *
|
||||
|
||||
AOS.Damage(to, to, 60, 0, 0, 0, 0, 100);
|
||||
|
||||
if (!to.Alive)
|
||||
return;
|
||||
|
||||
if (!DamageTable.ContainsKey(to))
|
||||
{
|
||||
DamageTimer timer = new DamageTimer(this, to);
|
||||
|
||||
to.Frozen = true;
|
||||
DamageTable[to] = timer;
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void Solve(Mobile from)
|
||||
{
|
||||
Effects.PlaySound(this.Location, this.Map, 0x211);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x1F3);
|
||||
|
||||
Effects.SendLocationEffect(this.Location, this.Map, 0x36B0, 4, 4);
|
||||
Effects.SendLocationEffect(new Point3D(this.X - 1, this.Y - 1, this.Z + 2), this.Map, 0x36B0, 4, 4);
|
||||
Effects.SendLocationEffect(new Point3D(this.X - 2, this.Y - 1, this.Z + 2), this.Map, 0x36B0, 4, 4);
|
||||
|
||||
from.SendLocalizedMessage(1152371); // You repair the mysterious Nexus! As it whirs to life it spits out a punch card!
|
||||
from.AddToBackpack(new PunchCard());
|
||||
|
||||
this.Hue = 0;
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(10), new TimerCallback(delegate { this.Hue = 1987; }));
|
||||
}
|
||||
|
||||
public class DamageTimer : Timer
|
||||
{
|
||||
private readonly ExodusNexus m_Nexus;
|
||||
private readonly Mobile m_To;
|
||||
private int m_Step;
|
||||
|
||||
public DamageTimer(ExodusNexus nexus, Mobile to)
|
||||
: base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0))
|
||||
{
|
||||
this.m_Nexus = nexus;
|
||||
this.m_To = to;
|
||||
this.m_Step = 0;
|
||||
|
||||
this.Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (this.m_Nexus.Deleted || this.m_To.Deleted || !this.m_To.Alive)
|
||||
{
|
||||
this.End();
|
||||
return;
|
||||
}
|
||||
|
||||
this.m_To.PlaySound(0x28);
|
||||
|
||||
this.m_To.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *");
|
||||
this.m_To.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true, string.Format("* {0} spasms from electric shock *", this.m_To.Name));
|
||||
|
||||
AOS.Damage(this.m_To, this.m_To, 20, 0, 0, 0, 0, 100);
|
||||
|
||||
if (++this.m_Step >= 3 || !this.m_To.Alive)
|
||||
{
|
||||
this.End();
|
||||
}
|
||||
}
|
||||
|
||||
private void End()
|
||||
{
|
||||
m_Nexus.DamageTable.Remove(m_To);
|
||||
this.m_To.Frozen = false;
|
||||
|
||||
this.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0); // Version
|
||||
|
||||
writer.Write((int)this.m_SideLength);
|
||||
writer.Write((int)this.m_Path.Length);
|
||||
|
||||
for (int i = 0; i < this.m_Path.Length; i++)
|
||||
{
|
||||
Node cur = this.m_Path[i];
|
||||
|
||||
writer.Write(cur.X);
|
||||
writer.Write(cur.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_SideLength = reader.ReadInt();
|
||||
this.m_Path = new Node[reader.ReadInt()];
|
||||
|
||||
for (int i = 0; i < this.m_Path.Length; i++)
|
||||
{
|
||||
this.m_Path[i] = new Node(reader.ReadInt(), reader.ReadInt());
|
||||
}
|
||||
|
||||
if (this.Hue == 0)
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(10), new TimerCallback(delegate { this.Hue = 1987; }));
|
||||
}
|
||||
|
||||
public class NexusGameGump : Gump
|
||||
{
|
||||
private readonly ExodusNexus m_Nexus;
|
||||
private readonly Mobile m_From;
|
||||
private readonly int m_Step;
|
||||
public NexusGameGump(ExodusNexus nexus, Mobile from, int step, bool hint)
|
||||
: base(5, 30)
|
||||
{
|
||||
this.m_Nexus = nexus;
|
||||
this.m_From = from;
|
||||
this.m_Step = step;
|
||||
|
||||
int sideLength = nexus.SideLength;
|
||||
|
||||
this.AddBackground(50, 0, 530, 410, 0xA28);
|
||||
|
||||
this.AddImage(0, 0, 0x28C8);
|
||||
this.AddImage(547, 0, 0x28C9);
|
||||
|
||||
this.AddBackground(95, 20, 442, 90, 0xA28);
|
||||
|
||||
this.AddHtmlLocalized(165, 35, 300, 45, 1153747, false, false); // <center>GENERATOR CONTROL nexus</center>
|
||||
this.AddHtmlLocalized(165, 60, 300, 70, 1153748, false, false); // <center>Use the Directional Controls to</center>
|
||||
this.AddHtmlLocalized(165, 75, 300, 85, 1153749, false, false); // <center>Close the Grid Circuit</center>
|
||||
|
||||
this.AddImage(140, 40, 0x28D3);
|
||||
this.AddImage(420, 40, 0x28D3);
|
||||
|
||||
this.AddBackground(365, 120, 178, 210, 0x1400);
|
||||
|
||||
this.AddImage(365, 115, 0x28D4);
|
||||
this.AddImage(365, 288, 0x28D4);
|
||||
|
||||
this.AddImage(414, 189, 0x589);
|
||||
this.AddImage(435, 210, 0xA52);
|
||||
|
||||
this.AddButton(408, 222, 0x29EA, 0x29EC, 1, GumpButtonType.Reply, 0); // Left
|
||||
this.AddButton(448, 185, 0x29CC, 0x29CE, 2, GumpButtonType.Reply, 0); // Up
|
||||
this.AddButton(473, 222, 0x29D6, 0x29D8, 3, GumpButtonType.Reply, 0); // Right
|
||||
this.AddButton(448, 243, 0x29E0, 0x29E2, 4, GumpButtonType.Reply, 0); // Down
|
||||
|
||||
this.AddBackground(90, 115, 30 + 40 * sideLength, 30 + 40 * sideLength, 0xA28);
|
||||
this.AddBackground(100, 125, 10 + 40 * sideLength, 10 + 40 * sideLength, 0x1400);
|
||||
|
||||
for (int i = 0; i < sideLength; i++)
|
||||
{
|
||||
for (int j = 0; j < sideLength - 1; j++)
|
||||
{
|
||||
this.AddImage(120 + 40 * i, 162 + 40 * j, 0x13F9);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < sideLength - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < sideLength; j++)
|
||||
{
|
||||
this.AddImage(138 + 40 * i, 147 + 40 * j, 0x13FD);
|
||||
}
|
||||
}
|
||||
|
||||
Node[] path = nexus.Path;
|
||||
|
||||
NodeHue[,] hues = new NodeHue[sideLength, sideLength];
|
||||
|
||||
for (int i = 0; i <= step; i++)
|
||||
{
|
||||
Node n = path[i];
|
||||
hues[n.X, n.Y] = NodeHue.Blue;
|
||||
}
|
||||
|
||||
Node lastNode = path[path.Length - 1];
|
||||
hues[lastNode.X, lastNode.Y] = NodeHue.Red;
|
||||
|
||||
for (int i = 0; i < sideLength; i++)
|
||||
{
|
||||
for (int j = 0; j < sideLength; j++)
|
||||
{
|
||||
this.AddNode(110 + 40 * i, 135 + 40 * j, hues[i, j]);
|
||||
}
|
||||
}
|
||||
|
||||
Node curNode = path[step];
|
||||
this.AddImage(118 + 40 * curNode.X, 143 + 40 * curNode.Y, 0x13A8);
|
||||
|
||||
if (hint)
|
||||
{
|
||||
Node nextNode = path[step + 1];
|
||||
this.AddImage(119 + 40 * nextNode.X, 143 + 40 * nextNode.Y, 0x939);
|
||||
}
|
||||
|
||||
if (from.Skills.Lockpicking.Value >= 65.0)
|
||||
{
|
||||
this.AddButton(365, 350, 0xFA6, 0xFA7, 5, GumpButtonType.Reply, 0);
|
||||
this.AddHtmlLocalized(405, 345, 140, 40, 1153750, false, false); // Attempt to Decipher the Circuit Path
|
||||
}
|
||||
}
|
||||
|
||||
private enum NodeHue
|
||||
{
|
||||
Gray,
|
||||
Blue,
|
||||
Red
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (this.m_Nexus.Deleted || info.ButtonID == 0 || !this.m_From.CheckAlive())
|
||||
{
|
||||
this.m_Nexus.User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.m_From.Map != this.m_Nexus.Map || !this.m_From.InRange(this.m_Nexus, 3))
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(500446); // That is too far away.
|
||||
this.m_Nexus.User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Node nextNode = this.m_Nexus.Path[this.m_Step + 1];
|
||||
|
||||
if (info.ButtonID == 5) // Attempt to Decipher
|
||||
{
|
||||
double lockpicking = this.m_From.Skills.Lockpicking.Value;
|
||||
|
||||
if (lockpicking < 65.0)
|
||||
return;
|
||||
|
||||
this.m_From.PlaySound(0x241);
|
||||
|
||||
if (40.0 + Utility.RandomDouble() * 80.0 < lockpicking)
|
||||
{
|
||||
this.m_From.SendGump(new NexusGameGump(this.m_Nexus, this.m_From, this.m_Step, true));
|
||||
this.m_Nexus.LastUse = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Nexus.DoDamage(this.m_From);
|
||||
this.m_Nexus.User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node curNode = this.m_Nexus.Path[this.m_Step];
|
||||
|
||||
int newX, newY;
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1: // Left
|
||||
newX = curNode.X - 1;
|
||||
newY = curNode.Y;
|
||||
break;
|
||||
case 2: // Up
|
||||
newX = curNode.X;
|
||||
newY = curNode.Y - 1;
|
||||
break;
|
||||
case 3: // Right
|
||||
newX = curNode.X + 1;
|
||||
newY = curNode.Y;
|
||||
break;
|
||||
case 4: // Down
|
||||
newX = curNode.X;
|
||||
newY = curNode.Y + 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextNode.X == newX && nextNode.Y == newY)
|
||||
{
|
||||
if (this.m_Step + 1 == this.m_Nexus.Path.Length - 1)
|
||||
{
|
||||
this.m_Nexus.Solve(this.m_From);
|
||||
this.m_Nexus.User = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_From.PlaySound(0x1F4);
|
||||
this.m_From.SendGump(new NexusGameGump(this.m_Nexus, this.m_From, this.m_Step + 1, false));
|
||||
this.m_Nexus.LastUse = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Nexus.DoDamage(this.m_From);
|
||||
this.m_Nexus.User = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNode(int x, int y, NodeHue hue)
|
||||
{
|
||||
int id;
|
||||
switch (hue)
|
||||
{
|
||||
case NodeHue.Gray:
|
||||
id = 0x25F8;
|
||||
break;
|
||||
case NodeHue.Blue:
|
||||
id = 0x868;
|
||||
break;
|
||||
default:
|
||||
id = 0x9A8;
|
||||
break;
|
||||
}
|
||||
|
||||
this.AddImage(x, y, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
using System;
|
||||
using Server.Targeting;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Alterable(typeof(DefBlacksmithy), typeof(ExodusSacrificalGargishDagger))]
|
||||
[FlipableAttribute(0x2D21, 0x2D2D)]
|
||||
public class ExodusSacrificalDagger : BaseKnife
|
||||
{
|
||||
public override int LabelNumber { get { return 1153500; } } // exodus sacrificial dagger
|
||||
private int m_Lifespan;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public ExodusSacrificalDagger() : base(0x2D2D)
|
||||
{
|
||||
Weight = 4.0;
|
||||
Layer = Layer.OneHanded;
|
||||
Hue = 2500;
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
m_Lifespan = Lifespan;
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 60; } }
|
||||
public override int InitMaxHits { get { return 60; } }
|
||||
public override int AosStrengthReq { get { return 15; } }
|
||||
public override SkillName DefSkill { get { return SkillName.Fencing; } }
|
||||
public override float MlSpeed { get { return 2.00f; } }
|
||||
public override int AosMinDamage { get { return 10; } }
|
||||
public override int AosMaxDamage { get { return 12; } }
|
||||
public override int PhysicalResistance { get { return 12; } }
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
RobeofRite robe = from.FindItemOnLayer(Layer.OuterTorso) as RobeofRite;
|
||||
ExodusSacrificalDagger dagger = from.FindItemOnLayer(Layer.OneHanded) as ExodusSacrificalDagger;
|
||||
|
||||
if (Party.Get(from) == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153596); // You must join a party with the players you wish to perform the ritual with.
|
||||
}
|
||||
else if (robe == null || dagger == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153591); // Thou art not properly attired to perform such a ritual.
|
||||
}
|
||||
else if (!((PlayerMobile)from).UseSummoningRite)
|
||||
{
|
||||
from.SendLocalizedMessage(1153603); // You must first use the Summoning Rite on a Summoning Tome.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153604); // Target the summoning tome or yourself to declare your intentions for performing this ritual...
|
||||
from.Target = new SacrificalTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class SacrificalTarget : Target
|
||||
{
|
||||
private Item m_Dagger;
|
||||
|
||||
public SacrificalTarget(Item dagger) : base(2, true, TargetFlags.None)
|
||||
{
|
||||
m_Dagger = dagger;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is ExodusTomeAltar)
|
||||
{
|
||||
ExodusTomeAltar altar = (ExodusTomeAltar)targeted;
|
||||
|
||||
if (altar.CheckParty(altar.Owner, from))
|
||||
{
|
||||
bool SacrificalRitual = altar.Rituals.Find(s => s.RitualMobile == from).Ritual2;
|
||||
|
||||
if (!SacrificalRitual)
|
||||
{
|
||||
((PlayerMobile)from).UseSummoningRite = false;
|
||||
from.Say(1153605); // *You thrust the dagger into your flesh as tribute to Exodus!*
|
||||
altar.Rituals.Find(s => s.RitualMobile == from).Ritual2 = true;
|
||||
m_Dagger.Delete();
|
||||
Misc.Titles.AwardKarma(from, 10000, true);
|
||||
Effects.SendLocationParticles(EffectItem.Create(altar.Location, altar.Map, TimeSpan.FromSeconds(2)), 0x373A, 10, 10, 2023);
|
||||
|
||||
from.SendLocalizedMessage(1153598, from.Name); // ~1_PLAYER~ has read the Summoning Rite!
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153599); // You've already used this item in another ritual.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153595); // You must first join the party of the person who built this altar.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153601); // That is not a Summoning Tome.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ExodusSacrificalDagger(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Lifespan { get { return 604800; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TimeLeft
|
||||
{
|
||||
get { return m_Lifespan; }
|
||||
set
|
||||
{
|
||||
m_Lifespan = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
TimeSpan t = TimeSpan.FromSeconds(m_Lifespan);
|
||||
|
||||
int weeks = (int)t.Days / 7;
|
||||
int days = t.Days;
|
||||
int hours = t.Hours;
|
||||
int minutes = t.Minutes;
|
||||
|
||||
if (weeks > 0)
|
||||
list.Add(string.Format("Lifespan: {0} {1}", weeks, weeks == 1 ? "week" : "weeks"));
|
||||
else if (days > 0)
|
||||
list.Add(string.Format("Lifespan: {0} {1}", days, days == 1 ? "day" : "days"));
|
||||
else if (hours > 0)
|
||||
list.Add(string.Format("Lifespan: {0} {1}", hours, hours == 1 ? "hour" : "hours"));
|
||||
else if (minutes > 0)
|
||||
list.Add(string.Format("Lifespan: {0} {1}", minutes, minutes == 1 ? "minute" : "minutes"));
|
||||
else
|
||||
list.Add(1072517, m_Lifespan.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
return;
|
||||
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), new TimerCallback(Slice));
|
||||
m_Timer.Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
public virtual void StopTimer()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
m_Timer.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
public virtual void Slice()
|
||||
{
|
||||
m_Lifespan -= 10;
|
||||
|
||||
InvalidateProperties();
|
||||
|
||||
if (m_Lifespan <= 0)
|
||||
Decay();
|
||||
}
|
||||
|
||||
public virtual void Decay()
|
||||
{
|
||||
if (RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)RootParent;
|
||||
|
||||
if (Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(Location, Map, 0x201);
|
||||
}
|
||||
|
||||
StopTimer();
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
writer.Write((int)m_Lifespan);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
m_Lifespan = reader.ReadInt();
|
||||
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
[FlipableAttribute(0x0902, 0x406A)]
|
||||
public class ExodusSacrificalGargishDagger : ExodusSacrificalDagger
|
||||
{
|
||||
[Constructable]
|
||||
public ExodusSacrificalGargishDagger()
|
||||
{
|
||||
ItemID = 0x406A;
|
||||
Weight = 4.0;
|
||||
}
|
||||
|
||||
public override Race RequiredRace { get { return Race.Gargoyle; } }
|
||||
public override bool CanBeWornByGargoyles { get { return true; } }
|
||||
|
||||
public ExodusSacrificalGargishDagger(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using Server.Targeting;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.PartySystem;
|
||||
using System.Linq;
|
||||
using Server.Engines.Exodus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusSummoningAlter : BaseDecayingItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1153502; } } // exodus summoning altar
|
||||
|
||||
[Constructable]
|
||||
public ExodusSummoningAlter() : base(0x14F0)
|
||||
{
|
||||
this.LootType = LootType.Regular;
|
||||
this.Weight = 1;
|
||||
}
|
||||
|
||||
public override int Lifespan { get { return 604800; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
|
||||
public ExodusSummoningAlter(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1054107); // This item must be in your backpack.
|
||||
}
|
||||
else if (Party.Get(from) == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153596); // You must join a party with the players you wish to perform the ritual with.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153675); // The Summoning Altar must be built upon a shrine, within Trammel or Felucca it matters not...
|
||||
from.Target = new SummoningTarget(from, this);
|
||||
}
|
||||
}
|
||||
|
||||
public class SummoningTarget : Target
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private Item m_Deed;
|
||||
|
||||
public SummoningTarget(Mobile from, Item deed) : base(2, true, TargetFlags.None)
|
||||
{
|
||||
m_Mobile = from;
|
||||
m_Deed = deed;
|
||||
}
|
||||
|
||||
public static bool IsValidTile(int itemID)
|
||||
{
|
||||
return (itemID >= 0x149F && itemID <= 0x14D6);
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is StaticTarget)
|
||||
{
|
||||
StaticTarget targ = (StaticTarget)targeted;
|
||||
|
||||
if (IsValidTile(targ.ItemID) && (from.Map == Map.Felucca || from.Map == Map.Trammel))
|
||||
{
|
||||
bool alter = from.Map.GetItemsInRange(targ.Location, 5).Where(x => x is ExodusTomeAltar).Any();
|
||||
|
||||
if (alter)
|
||||
{
|
||||
from.SendLocalizedMessage(1153590); // An altar has already been built here.
|
||||
}
|
||||
else if (ExodusTomeAltar.Altar == null && VerLorRegController.Active && VerLorRegController.Mobile != null && CheckExodus())
|
||||
{
|
||||
Point3D p = Point3D.Zero;
|
||||
|
||||
if (from.Region.IsPartOf("Shrine of Compassion"))
|
||||
{
|
||||
p = new Point3D(1858, 875, 12);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Honesty"))
|
||||
{
|
||||
p = new Point3D(4209, 564, 60);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Honor"))
|
||||
{
|
||||
p = new Point3D(1727, 3528, 15);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Humility"))
|
||||
{
|
||||
p = new Point3D(4274, 3697, 12);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Justice"))
|
||||
{
|
||||
p = new Point3D(1301, 634, 28);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Sacrifice"))
|
||||
{
|
||||
p = new Point3D(3355, 290, 16);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Spirituality"))
|
||||
{
|
||||
p = new Point3D(1606, 2490, 20);
|
||||
}
|
||||
else if (from.Region.IsPartOf("Shrine of Valor"))
|
||||
{
|
||||
p = new Point3D(2492, 3931, 17);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500269); // You cannot build that there.
|
||||
return;
|
||||
}
|
||||
|
||||
if (p != Point3D.Zero)
|
||||
{
|
||||
ExodusTomeAltar altar = new ExodusTomeAltar(from);
|
||||
altar.MoveToWorld(p, from.Map);
|
||||
altar.Owner = from;
|
||||
m_Deed.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1075213); // The master of this realm has already been summoned and is engaged in combat. Your opportunity will come after he has squashed the current batch of intruders!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500269); // You cannot build that there.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500269); // You cannot build that there.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckExodus() // Before ritual check
|
||||
{
|
||||
return ClockworkExodus.Instances.FirstOrDefault(m => m.Region.IsPartOf("Ver Lor Reg") && ((m.Hits >= m.HitsMax * 0.60 && m.MinHits >= m.HitsMax * 0.60) || (m.Hits >= m.HitsMax * 0.75))) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Targeting;
|
||||
using System.Linq;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusSummoningRite : BaseDecayingItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1153498; } } // exodus summoning rite
|
||||
|
||||
[Constructable]
|
||||
public ExodusSummoningRite() : base(0x2258)
|
||||
{
|
||||
Weight = 1;
|
||||
Hue = 1910;
|
||||
LootType = LootType.Regular;
|
||||
}
|
||||
|
||||
public override int Lifespan { get { return 604800; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
|
||||
public ExodusSummoningRite(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
RobeofRite robe = from.FindItemOnLayer(Layer.OuterTorso) as RobeofRite;
|
||||
ExodusSacrificalDagger dagger = from.FindItemOnLayer(Layer.OneHanded) as ExodusSacrificalDagger;
|
||||
|
||||
if (!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1054107); // This item must be in your backpack.
|
||||
}
|
||||
else if (Party.Get(from) == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153596); // You must join a party with the players you wish to perform the ritual with.
|
||||
}
|
||||
else if (robe == null || dagger == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153591); // Thou art not properly attired to perform such a ritual.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153600); // Which Summoning Tome do you wish to use this on?
|
||||
from.Target = new RiteTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class RiteTarget : Target
|
||||
{
|
||||
private Item m_Deed;
|
||||
|
||||
public RiteTarget(Item deed) : base(2, true, TargetFlags.None)
|
||||
{
|
||||
m_Deed = deed;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is ExodusTomeAltar)
|
||||
{
|
||||
ExodusTomeAltar altar = (ExodusTomeAltar)targeted;
|
||||
|
||||
if (altar.CheckParty(altar.Owner, from))
|
||||
{
|
||||
if (altar.Rituals.Count(s => s.RitualMobile == from) == 0)
|
||||
{
|
||||
altar.Rituals.Add(new RitualArray { RitualMobile = from, Ritual1 = false, Ritual2 = false });
|
||||
}
|
||||
|
||||
bool RiteRitual = altar.Rituals.Find(s => s.RitualMobile == from).Ritual1;
|
||||
|
||||
if (!RiteRitual)
|
||||
{
|
||||
((PlayerMobile)from).UseSummoningRite = true;
|
||||
from.Say(1153597); // You place the rite within the tome and begin to meditate...
|
||||
altar.Rituals.Find(s => s.RitualMobile == from).Ritual1 = true;
|
||||
m_Deed.Delete();
|
||||
from.SendLocalizedMessage(1153598, from.Name); // ~1_PLAYER~ has read the Summoning Rite!
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153599); // You've already used this item in another ritual.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153595); // You must first join the party of the person who built this altar.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153601); // That is not a Summoning Tome.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
using System;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Gumps;
|
||||
using Server.Commands;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Exodus;
|
||||
using Server.Mobiles;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExodusTomeAltar : BaseDecayingItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1153602; } } // Exodus Summoning Tome
|
||||
public static ExodusTomeAltar Altar { get; set; }
|
||||
public TimeSpan DelayExit { get { return TimeSpan.FromMinutes(10); } }
|
||||
private Point3D m_TeleportDest = new Point3D(764, 640, 0);
|
||||
public override int Lifespan { get { return 420; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
private List<RitualArray> m_Rituals;
|
||||
private Mobile m_Owner;
|
||||
private Item m_ExodusAlterAddon;
|
||||
|
||||
public List<RitualArray> Rituals { get { return m_Rituals; } }
|
||||
public Mobile Owner
|
||||
{
|
||||
get { return this.m_Owner; }
|
||||
set { this.m_Owner = value; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ExodusTomeAltar(Mobile from)
|
||||
: base(0x1C11)
|
||||
{
|
||||
this.Hue = 1943;
|
||||
this.Movable = false;
|
||||
this.LootType = LootType.Regular;
|
||||
this.Weight = 0.0;
|
||||
|
||||
this.m_Rituals = new List<RitualArray>();
|
||||
this.m_ExodusAlterAddon = new ExodusAlterAddon();
|
||||
this.m_ExodusAlterAddon.Movable = false;
|
||||
}
|
||||
|
||||
public ExodusTomeAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
private class BeginTheRitual : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private ExodusTomeAltar m_altar;
|
||||
|
||||
public BeginTheRitual(ExodusTomeAltar altar, Mobile from) : base(1153608, 2) // Begin the Ritual
|
||||
{
|
||||
m_Mobile = from;
|
||||
m_altar = altar;
|
||||
|
||||
if (altar.Owner != from)
|
||||
Flags |= CMEFlags.Disabled;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_altar.Owner == m_Mobile)
|
||||
{
|
||||
m_altar.SendConfirmationsExodus(m_Mobile);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1153610); // Only the altar owner can commence with the ritual.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
list.Add(new BeginTheRitual(this, from));
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.HasGump(typeof(AltarGump)))
|
||||
{
|
||||
from.SendGump(new AltarGump(from));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_ExodusAlterAddon != null)
|
||||
this.m_ExodusAlterAddon.Delete();
|
||||
|
||||
if (Altar != null)
|
||||
Altar = null;
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.Deleted)
|
||||
return;
|
||||
|
||||
if (this.m_ExodusAlterAddon != null)
|
||||
this.m_ExodusAlterAddon.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLoc)
|
||||
{
|
||||
if (this.Deleted)
|
||||
return;
|
||||
|
||||
if (this.m_ExodusAlterAddon != null)
|
||||
this.m_ExodusAlterAddon.Location = new Point3D(this.X - 1, this.Y - 1, this.Z - 18);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)m_ExodusAlterAddon);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_ExodusAlterAddon = reader.ReadItem();
|
||||
}
|
||||
|
||||
public bool CheckParty(Mobile from, Mobile m)
|
||||
{
|
||||
Party party = Party.Get(from);
|
||||
|
||||
if (party != null)
|
||||
{
|
||||
foreach (PartyMemberInfo info in party.Members)
|
||||
{
|
||||
if (info.Mobile == m)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void SendConfirmationsExodus(Mobile from)
|
||||
{
|
||||
Party party = Party.Get(from);
|
||||
|
||||
if (party != null)
|
||||
{
|
||||
int MemberRange = party.Members.Where(x => !from.InRange(x.Mobile, 5)).Count();
|
||||
|
||||
if (MemberRange != 0)
|
||||
{
|
||||
from.SendLocalizedMessage(1153611); // One or more members of your party are not close enough to you to perform the ritual.
|
||||
return;
|
||||
}
|
||||
|
||||
RobeofRite robe;
|
||||
|
||||
foreach (PartyMemberInfo info in party.Members)
|
||||
{
|
||||
robe = info.Mobile.FindItemOnLayer(Layer.OuterTorso) as RobeofRite;
|
||||
|
||||
if (!m_Rituals.Where(z => z.RitualMobile == info.Mobile && z.Ritual1 && z.Ritual2).Any() || robe == null)
|
||||
{
|
||||
from.SendLocalizedMessage(1153609, info.Mobile.Name); // ~1_PLAYER~ has not fulfilled all the requirements of the Ritual! You cannot commence until they do.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PartyMemberInfo info in party.Members)
|
||||
{
|
||||
this.SendBattleground(info.Mobile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1153596); // You must join a party with the players you wish to perform the ritual with.
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SendBattleground(Mobile from)
|
||||
{
|
||||
if (VerLorRegController.Active && VerLorRegController.Mobile != null && ExodusSummoningAlter.CheckExodus())
|
||||
{
|
||||
// teleport party member
|
||||
from.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
|
||||
from.PlaySound(0x1FE);
|
||||
from.MoveToWorld(this.m_TeleportDest, Map.Ilshenar);
|
||||
BaseCreature.TeleportPets(from, m_TeleportDest, Map.Ilshenar);
|
||||
|
||||
// Robe of Rite Delete
|
||||
RobeofRite robe = from.FindItemOnLayer(Layer.OuterTorso) as RobeofRite;
|
||||
|
||||
if (robe != null)
|
||||
{
|
||||
robe.Delete();
|
||||
}
|
||||
|
||||
// Altar Delete
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerCallback(Delete));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1075213); // The master of this realm has already been summoned and is engaged in combat. Your opportunity will come after he has squashed the current batch of intruders!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualArray
|
||||
{
|
||||
public Mobile RitualMobile { get; set; }
|
||||
public bool Ritual1 { get; set; }
|
||||
public bool Ritual2 { get; set; }
|
||||
}
|
||||
|
||||
public class AltarGump : Gump
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("TomeAltarGump", AccessLevel.Administrator, new CommandEventHandler(TomeAltarGump_OnCommand));
|
||||
}
|
||||
|
||||
[Usage("TomeAltarGump")]
|
||||
public static void TomeAltarGump_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (!from.HasGump(typeof(AltarGump)))
|
||||
{
|
||||
from.SendGump(new AltarGump(from));
|
||||
}
|
||||
}
|
||||
|
||||
public AltarGump(Mobile owner) : base(100, 100)
|
||||
{
|
||||
this.Closable = true;
|
||||
this.Disposable = true;
|
||||
this.Dragable = true;
|
||||
|
||||
AddPage(0);
|
||||
AddBackground(0, 0, 447, 195, 5120);
|
||||
AddHtmlLocalized(17, 14, 412, 161, 1153607, 0x7FFF, false, false); // Contained within this Tome is the ritual by which Lord Exodus may once again be called upon Britannia in his physical form, summoned from deep within the Void. Only when the Summoning Rite has been rejoined with the tome and only when the Robe of Rite covers the caster can the Sacrificial Dagger be used to seal thy fate. Stab into this book the dagger and declare thy quest for Valor as thou stand to defend Britannia from this evil, or sacrifice thy blood unto this altar to declare thy quest for greed and wealth...only thou can judge thyself...
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0: {
|
||||
//Cancel
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExoticToolkit : BaseDecayingItem
|
||||
{
|
||||
[Constructable]
|
||||
public ExoticToolkit()
|
||||
: base(0x1EB9)
|
||||
{
|
||||
this.Hue = 2500;
|
||||
this.Weight = 1;
|
||||
}
|
||||
|
||||
public override int Lifespan { get { return 604800; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153866; } } // Exotic Toolkit
|
||||
|
||||
public ExoticToolkit(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
from.SendLocalizedMessage(500325); // I am too far away to do that.
|
||||
else
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
from.SendLocalizedMessage(1152378); // Use this on a broken Nexus.
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalTarget : Target
|
||||
{
|
||||
public ExoticToolkit m_Toolkit;
|
||||
public InternalTarget(ExoticToolkit toolkit) : base(-1, true, TargetFlags.None)
|
||||
{
|
||||
m_Toolkit = toolkit;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is NexusComponent)
|
||||
{
|
||||
NexusComponent addon = ((NexusComponent)targeted) as NexusComponent;
|
||||
|
||||
if (addon.Addon is ExodusNexus)
|
||||
{
|
||||
if (!((ExodusNexus)addon.Addon).Active)
|
||||
{
|
||||
((ExodusNexus)addon.Addon).OpenGump(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class KeypunchReader : OrnateWoodenChest
|
||||
{
|
||||
public override int LabelNumber { get { return 1153868; } } // Keypunch Reader
|
||||
|
||||
[Constructable]
|
||||
public KeypunchReader()
|
||||
: base()
|
||||
{
|
||||
this.Weight = 0.0;
|
||||
this.Hue = 2500;
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public KeypunchReader(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!base.OnDragDrop(from, dropped))
|
||||
return false;
|
||||
|
||||
if (this.TotalItems >= 50)
|
||||
{
|
||||
CheckItems(from);
|
||||
}
|
||||
|
||||
if (dropped is PunchCard)
|
||||
{
|
||||
from.SendLocalizedMessage(1152375); // You feed the punch card into the machine but nothing happens.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
|
||||
{
|
||||
if (!base.OnDragDropInto(from, item, p))
|
||||
return false;
|
||||
|
||||
if (this.TotalItems >= 50)
|
||||
{
|
||||
CheckItems(from);
|
||||
}
|
||||
|
||||
if (item is PunchCard)
|
||||
{
|
||||
from.SendLocalizedMessage(1152375); // You feed the punch card into the machine but nothing happens.
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CheckItems(Mobile m)
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
|
||||
var punch = items.Where(x => x is PunchCard);
|
||||
var kit = items.Where(x => x is ExoticToolkit);
|
||||
|
||||
if (punch.Count() >= 50 && kit.Count() >= 1)
|
||||
{
|
||||
punch.ToList().ForEach(f => f.Delete());
|
||||
|
||||
this.DropItem(new NexusAddonDeed());
|
||||
m.SendLocalizedMessage(1152376); // As you feed the punch card into the machine it turns on!
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MechanicalComponent : BaseDecayingItem
|
||||
{
|
||||
[Constructable]
|
||||
public MechanicalComponent()
|
||||
: base(0x2DD7)
|
||||
{
|
||||
this.Hue = 2500;
|
||||
this.Weight = 1;
|
||||
}
|
||||
|
||||
public override int Lifespan { get { return 259200; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153865; } } // Mechanical Component
|
||||
|
||||
public MechanicalComponent(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.Skills[SkillName.Tinkering].Value >= 80.0)
|
||||
{
|
||||
from.AddToBackpack(new ExoticToolkit());
|
||||
this.Delete();
|
||||
from.SendLocalizedMessage(1152369); // You successfully convert the component into an exotic tool kit.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1152370); // Only an Adept Tinker would know what to do with this.
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PunchCard : BaseDecayingItem
|
||||
{
|
||||
[Constructable]
|
||||
public PunchCard()
|
||||
: base(0x0FF4)
|
||||
{
|
||||
this.LootType = LootType.Regular;
|
||||
this.Hue = Utility.RandomNondyedHue();
|
||||
this.Weight = 2;
|
||||
}
|
||||
|
||||
public override int Lifespan { get { return 21600; } }
|
||||
public override bool UseSeconds { get { return false; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153867; } } // Punch Card
|
||||
|
||||
public PunchCard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class RobeofRite : Robe
|
||||
{
|
||||
public override int LabelNumber { get { return 1153510; } } // robe of rite
|
||||
|
||||
private int m_Lifespan;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public RobeofRite() : base(0x1F03)
|
||||
{
|
||||
this.Weight = 3;
|
||||
this.Hue = 2702;
|
||||
this.StrRequirement = 10;
|
||||
|
||||
if (this.Lifespan > 0)
|
||||
{
|
||||
this.m_Lifespan = this.Lifespan;
|
||||
this.StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public RobeofRite(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Lifespan { get { return 604800; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TimeLeft
|
||||
{
|
||||
get { return this.m_Lifespan; }
|
||||
set
|
||||
{
|
||||
this.m_Lifespan = value;
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (this.Lifespan > 0)
|
||||
{
|
||||
TimeSpan t = TimeSpan.FromSeconds(this.m_Lifespan);
|
||||
|
||||
int weeks = (int)t.Days / 7;
|
||||
int days = t.Days;
|
||||
int hours = t.Hours;
|
||||
int minutes = t.Minutes;
|
||||
|
||||
if (weeks > 1)
|
||||
list.Add(1153092, weeks.ToString()); // Lifespan: ~1_val~ weeks
|
||||
else if (days > 1)
|
||||
list.Add(1153091, days.ToString()); // Lifespan: ~1_val~ days
|
||||
else if (hours > 1)
|
||||
list.Add(1153090, hours.ToString()); // Lifespan: ~1_val~ hours
|
||||
else if (minutes > 1)
|
||||
list.Add(1153089, minutes.ToString()); // Lifespan: ~1_val~ minutes
|
||||
else
|
||||
list.Add(1072517, this.m_Lifespan.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
return;
|
||||
|
||||
this.m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), new TimerCallback(Slice));
|
||||
this.m_Timer.Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
public virtual void StopTimer()
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
this.m_Timer.Stop();
|
||||
|
||||
this.m_Timer = null;
|
||||
}
|
||||
|
||||
public virtual void Slice()
|
||||
{
|
||||
this.m_Lifespan -= 10;
|
||||
|
||||
this.InvalidateProperties();
|
||||
|
||||
if (this.m_Lifespan <= 0)
|
||||
this.Decay();
|
||||
}
|
||||
|
||||
public virtual void Decay()
|
||||
{
|
||||
if (this.RootParent is Mobile)
|
||||
{
|
||||
Mobile parent = (Mobile)this.RootParent;
|
||||
|
||||
if (this.Name == null)
|
||||
parent.SendLocalizedMessage(1072515, "#" + this.LabelNumber); // The ~1_name~ expired...
|
||||
else
|
||||
parent.SendLocalizedMessage(1072515, this.Name); // The ~1_name~ expired...
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(parent.Location, parent.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(parent.Location, parent.Map, 0x201);
|
||||
}
|
||||
else
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
this.StopTimer();
|
||||
this.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
writer.Write((int)this.m_Lifespan);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
this.m_Lifespan = reader.ReadInt();
|
||||
|
||||
this.StartTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Asclepius : GnarledStaff
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Asclepius()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public Asclepius(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153526; } } // Asclepius [Replica]
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
list.Add(1153525); // 15% Bandage Healing Bonus
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BracersofAlchemicalDevastation : BoneArms
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
public override int LabelNumber { get { return 1153523; } }//Bracers of Alchemical Devastation [Replica]
|
||||
|
||||
[Constructable]
|
||||
public BracersofAlchemicalDevastation()
|
||||
{
|
||||
Attributes.RegenMana = 4;
|
||||
Attributes.CastRecovery = 3;
|
||||
ArmorAttributes.MageArmor = 1;
|
||||
WeaponAttributes.HitLightning = 35;
|
||||
}
|
||||
|
||||
public BracersofAlchemicalDevastation(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int BasePhysicalResistance { get { return 10; } }
|
||||
public override int BaseFireResistance { get { return 8; } }
|
||||
public override int BaseColdResistance { get { return 8; } }
|
||||
public override int BasePoisonResistance { get { return 8; } }
|
||||
public override int BaseEnergyResistance { get { return 8; } }
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ClockworkLeggings : PlateLegs
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public ClockworkLeggings()
|
||||
{
|
||||
Hue = 0xA91;
|
||||
Attributes.RegenStam = 5;
|
||||
Attributes.DefendChance = 25;
|
||||
Attributes.BonusDex = 5;
|
||||
}
|
||||
|
||||
public ClockworkLeggings(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber { get { return 1153536; } }
|
||||
|
||||
public override int BasePhysicalResistance { get { return 8; } }
|
||||
public override int BaseFireResistance { get { return 6; } }
|
||||
public override int BaseColdResistance { get { return 5; } }
|
||||
public override int BasePoisonResistance { get { return 6; } }
|
||||
public override int BaseEnergyResistance { get { return 5; } }
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DupresSword : VikingSword
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public DupresSword()
|
||||
{
|
||||
Hue = 0xA91;
|
||||
Attributes.BonusStr = 10;
|
||||
Attributes.AttackChance = 25;
|
||||
Attributes.WeaponSpeed = 35;
|
||||
Attributes.WeaponDamage = 100;
|
||||
WeaponAttributes.HitManaDrain = 50;
|
||||
}
|
||||
|
||||
public DupresSword(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153551; } }
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GargishAsclepius : GargishGnarledStaff
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishAsclepius()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public GargishAsclepius(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153526; } } // GargishAsclepius [Replica]
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
list.Add(1153525); // 15% Bandage Healing Bonus
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GargishBracersofAlchemicalDevastation : GargishLeatherArms
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishBracersofAlchemicalDevastation()
|
||||
{
|
||||
Attributes.RegenMana = 4;
|
||||
Attributes.CastRecovery = 3;
|
||||
ArmorAttributes.MageArmor = 1;
|
||||
WeaponAttributes.HitLightning = 35;
|
||||
}
|
||||
|
||||
public GargishBracersofAlchemicalDevastation(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1153523;
|
||||
}
|
||||
}//Bracers of Alchemical Devastation [Replica]
|
||||
|
||||
public override int BasePhysicalResistance { get { return 10; } }
|
||||
public override int BaseFireResistance { get { return 8; } }
|
||||
public override int BaseColdResistance { get { return 8; } }
|
||||
public override int BasePoisonResistance { get { return 8; } }
|
||||
public override int BaseEnergyResistance { get { return 8; } }
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GargishClockworkLeggings : GargishPlateLegs
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishClockworkLeggings()
|
||||
{
|
||||
Hue = 0xA91;
|
||||
Attributes.RegenStam = 5;
|
||||
Attributes.DefendChance = 25;
|
||||
Attributes.BonusDex = 5;
|
||||
StrRequirement = 90;
|
||||
}
|
||||
|
||||
public GargishClockworkLeggings(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber { get { return 1153536; } }
|
||||
|
||||
public override int BasePhysicalResistance { get { return 8; } }
|
||||
public override int BaseFireResistance { get { return 6; } }
|
||||
public override int BaseColdResistance { get { return 5; } }
|
||||
public override int BasePoisonResistance { get { return 6; } }
|
||||
public override int BaseEnergyResistance { get { return 5; } }
|
||||
public override int InitMinHits { get { return 255; } }
|
||||
public override int InitMaxHits { get { return 255; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GargishDupresSword : StoneWarSword
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GargishDupresSword()
|
||||
{
|
||||
Hue = 0xA91;
|
||||
|
||||
Attributes.BonusStr = 10;
|
||||
Attributes.AttackChance = 25;
|
||||
Attributes.WeaponSpeed = 35;
|
||||
Attributes.WeaponDamage = 100;
|
||||
WeaponAttributes.HitManaDrain = 50;
|
||||
}
|
||||
|
||||
public GargishDupresSword(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153551; } }
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class HygieiasAmulet : GoldNecklace
|
||||
{
|
||||
public override bool IsArtifact { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public HygieiasAmulet()
|
||||
{
|
||||
SkillBonuses.SetValues(0, SkillName.Alchemy, 10);
|
||||
}
|
||||
|
||||
public HygieiasAmulet(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanFortify { get { return false; } }
|
||||
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1153524;
|
||||
}
|
||||
} // Hygieia's Amulet [Replica]
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ScrollofValiantCommendation : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Owner { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ScrollofValiantCommendation() : base(0x46AE)
|
||||
{
|
||||
Weight = 1;
|
||||
}
|
||||
|
||||
public ScrollofValiantCommendation(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1153521;
|
||||
}
|
||||
}// Scroll of Valiant Commendation [Replica]
|
||||
|
||||
public override void AddNameProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
|
||||
if (String.IsNullOrEmpty(Owner))
|
||||
{
|
||||
list.Add(1152708); // Double click to permanently gain +5 to your maximum stats
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(1152706, Owner); // Rewarded to ~1_name~
|
||||
list.Add(1152707); // Presented for Exceptional Bravery During the Siege of Exodus City.
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if (!IsChildOf(from.Backpack))
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
else
|
||||
{
|
||||
if (from is PlayerMobile && ((PlayerMobile)from).HasValiantStatReward)
|
||||
{
|
||||
from.SendLocalizedMessage(1049510); // Your stats are too high for this power scroll.
|
||||
}
|
||||
else if (String.IsNullOrEmpty(Owner))
|
||||
{
|
||||
from.SendLocalizedMessage(1049512); // You feel a surge of magic as the scroll enhances your powers!
|
||||
|
||||
((PlayerMobile)from).HasValiantStatReward = true;
|
||||
from.StatCap += 5;
|
||||
Owner = from.Name;
|
||||
InvalidateProperties();
|
||||
|
||||
Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0, 0, 0, 0, 0, 5060, 0);
|
||||
Effects.PlaySound(from.Location, from.Map, 0x243);
|
||||
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
|
||||
|
||||
Effects.SendTargetParticles(from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write(Owner);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Owner = reader.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a vile corpse")]
|
||||
public class ClockworkExodus : BaseCreature
|
||||
{
|
||||
public static int m_MinHits;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MinHits
|
||||
{
|
||||
get { return m_MinHits; }
|
||||
set { m_MinHits = value; }
|
||||
}
|
||||
|
||||
public static List<ClockworkExodus> Instances { get; set; }
|
||||
|
||||
private static readonly Type[] m_Artifact = new Type[]
|
||||
{
|
||||
typeof(ScrollofValiantCommendation),
|
||||
typeof(BracersofAlchemicalDevastation),
|
||||
typeof(HygieiasAmulet),
|
||||
typeof(Asclepius),
|
||||
typeof(ClockworkLeggings),
|
||||
typeof(DupresSword),
|
||||
typeof(GargishDupresSword),
|
||||
typeof(GargishClockworkLeggings),
|
||||
typeof(GargishBracersofAlchemicalDevastation),
|
||||
typeof(GargishAsclepius)
|
||||
};
|
||||
|
||||
private Point3D m_LastTarget;
|
||||
|
||||
[Constructable]
|
||||
public ClockworkExodus() : base(AIType.AI_Mystic, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "Clockwork Exodus";
|
||||
Body = 1248;
|
||||
BaseSoundID = 639;
|
||||
Hue = 2500;
|
||||
Female = true;
|
||||
|
||||
SetStr(851, 950);
|
||||
SetDex(581, 683);
|
||||
SetInt(601, 750);
|
||||
|
||||
SetHits(50000);
|
||||
SetStam(507, 669);
|
||||
|
||||
SetDamage(20, 30);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 75);
|
||||
SetDamageType(ResistanceType.Fire, 25);
|
||||
SetDamageType(ResistanceType.Energy, 50);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 75, 90);
|
||||
SetResistance(ResistanceType.Fire, 50, 65);
|
||||
SetResistance(ResistanceType.Cold, 45, 60);
|
||||
SetResistance(ResistanceType.Poison, 45, 60);
|
||||
SetResistance(ResistanceType.Energy, 45, 60);
|
||||
|
||||
SetSkill(SkillName.EvalInt, 130.0);
|
||||
SetSkill(SkillName.Mysticism, 120);
|
||||
SetSkill(SkillName.MagicResist, 140.0);
|
||||
SetSkill(SkillName.Tactics, 90.1, 105.0);
|
||||
SetSkill(SkillName.Wrestling, 90.1, 105.0);
|
||||
SetSkill(SkillName.SpiritSpeak, 120.0);
|
||||
SetSkill(SkillName.Necromancy, 120.0);
|
||||
SetSkill(SkillName.Poisoning, 120.0);
|
||||
SetSkill(SkillName.Meditation, 120.0);
|
||||
SetSkill(SkillName.Anatomy, 120.0);
|
||||
SetSkill(SkillName.Healing, 120.0);
|
||||
|
||||
Fame = 24000;
|
||||
Karma = -24000;
|
||||
|
||||
VirtualArmor = 20;
|
||||
|
||||
m_MinHits = Hits;
|
||||
|
||||
if (Instances == null)
|
||||
Instances = new List<ClockworkExodus>();
|
||||
|
||||
Instances.Add(this);
|
||||
|
||||
SetWeaponAbility(WeaponAbility.BleedAttack);
|
||||
SetAreaEffect(AreaEffect.AuraOfEnergy);
|
||||
}
|
||||
|
||||
public static void DistributeRandomArtifact(BaseCreature bc, Type[] typelist)
|
||||
{
|
||||
int random = Utility.Random(typelist.Length);
|
||||
Item item = Loot.Construct(typelist[random]);
|
||||
DistributeArtifact(DemonKnight.FindRandomPlayer(bc), item);
|
||||
}
|
||||
|
||||
public static void DistributeArtifact(Mobile to, Item artifact)
|
||||
{
|
||||
if (to == null || artifact == null)
|
||||
return;
|
||||
|
||||
Container pack = to.Backpack;
|
||||
|
||||
if (pack == null || !pack.TryDropItem(to, artifact, false))
|
||||
to.BankBox.DropItem(artifact);
|
||||
|
||||
to.SendLocalizedMessage(502088); // A special gift has been placed in your backpack.
|
||||
}
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.2)
|
||||
DistributeRandomArtifact(this, m_Artifact);
|
||||
|
||||
Map map = Map;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
for (int x = -8; x <= 8; ++x)
|
||||
{
|
||||
for (int y = -8; y <= 8; ++y)
|
||||
{
|
||||
double dist = Math.Sqrt(x * x + y * y);
|
||||
|
||||
if (dist <= 8)
|
||||
new GoldTimer(map, X + x, Y + y).Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Instances != null && Instances.Contains(this))
|
||||
Instances.Remove(this);
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
public override bool CanBeParagon { get { return false; } }
|
||||
public override bool Unprovokable { get { return true; } }
|
||||
public virtual double ChangeCombatant { get { return 0.3; } }
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Greater; } }
|
||||
public override int TreasureMapLevel { get { return 5; } }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.AosSuperBoss, 2);
|
||||
}
|
||||
|
||||
public void SpawnVortices(Mobile target)
|
||||
{
|
||||
Map map = Map;
|
||||
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
MovingParticles(target, 0x1AF6, 5, 0, false, false, 0x816, 0, 3006, 0, 0, 0);
|
||||
|
||||
DeathVortexTrap dv;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
dv = new DeathVortexTrap();
|
||||
dv.MoveToWorld(GetSpawnPosition(target.Location, map, 3), map);
|
||||
}
|
||||
|
||||
target.SendLocalizedMessage(1152693); // The power of the Void surges around you!
|
||||
|
||||
m_LastTarget = target.Location;
|
||||
}
|
||||
|
||||
public void DoSpecialAbility(Mobile target)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
if (m_LastTarget != target.Location)
|
||||
{
|
||||
target.SendLocalizedMessage(1152692, Name); // ~1_CREATURE~ casts a deadly vortex at you!
|
||||
SpawnVortices(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile attacker)
|
||||
{
|
||||
base.OnDamagedBySpell(attacker);
|
||||
|
||||
DoSpecialAbility(attacker);
|
||||
}
|
||||
|
||||
public override void OnGaveMeleeAttack(Mobile defender)
|
||||
{
|
||||
base.OnGaveMeleeAttack(defender); //if it hits you it spawns vortices
|
||||
|
||||
DoSpecialAbility(defender);
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker); //if you hit creature it spawns vortices
|
||||
|
||||
DoSpecialAbility(attacker);
|
||||
}
|
||||
|
||||
public override void OnDamage(int amount, Mobile from, bool willKill)
|
||||
{
|
||||
base.OnDamage(amount, from, willKill);
|
||||
|
||||
if (Hits < m_MinHits && Hits < HitsMax * 0.60)
|
||||
m_MinHits = Hits;
|
||||
|
||||
if (Hits >= HitsMax * 0.75)
|
||||
m_MinHits = HitsMax;
|
||||
}
|
||||
|
||||
public ClockworkExodus(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
writer.Write((int)m_MinHits);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_MinHits = reader.ReadInt();
|
||||
|
||||
if (Instances == null)
|
||||
Instances = new List<ClockworkExodus>();
|
||||
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
private class GoldTimer : Timer
|
||||
{
|
||||
private Map m_Map;
|
||||
private int m_X, m_Y;
|
||||
|
||||
public GoldTimer(Map map, int x, int y) : base(TimeSpan.FromSeconds(Utility.RandomDouble() * 10.0))
|
||||
{
|
||||
m_Map = map;
|
||||
m_X = x;
|
||||
m_Y = y;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
int z = m_Map.GetAverageZ(m_X, m_Y);
|
||||
bool canFit = m_Map.CanFit(m_X, m_Y, z, 6, false, false);
|
||||
|
||||
for (int i = -3; !canFit && i <= 3; ++i)
|
||||
{
|
||||
canFit = m_Map.CanFit(m_X, m_Y, z + i, 6, false, false);
|
||||
|
||||
if (canFit)
|
||||
z += i;
|
||||
}
|
||||
|
||||
if (!canFit)
|
||||
return;
|
||||
|
||||
Gold g = new Gold(500, 1000);
|
||||
g.MoveToWorld(new Point3D(m_X, m_Y, z), m_Map);
|
||||
|
||||
if (0.3 >= Utility.RandomDouble())
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
|
||||
Effects.PlaySound(g, g.Map, 0x208);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DeathVortexTrap : BaseTrap
|
||||
{
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public DeathVortexTrap()
|
||||
: base(0x3789)
|
||||
{
|
||||
this.Hue = 2070;
|
||||
this.Movable = false;
|
||||
|
||||
m_Timer = new InternalTimer(this);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public DeathVortexTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
m_Timer.Stop();
|
||||
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public override bool PassivelyTriggered { get { return true; } }
|
||||
public override TimeSpan PassiveTriggerDelay { get { return TimeSpan.FromSeconds(2.0); } }
|
||||
public override int PassiveTriggerRange { get { return 3; } }
|
||||
public override TimeSpan ResetDelay { get { return TimeSpan.FromSeconds(0.2); } }
|
||||
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (from.IsStaff())
|
||||
return;
|
||||
|
||||
if (from.Alive && this.CheckRange(from.Location, 1) && !(from is ClockworkExodus))
|
||||
StamManaDrain(from);
|
||||
}
|
||||
|
||||
public void StamManaDrain(Mobile defender)
|
||||
{
|
||||
switch (Utility.Random(2)) // 50%/50% for stamina leech or mana leech
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (defender.Alive)
|
||||
{
|
||||
int manaToLeech = (int)(defender.Mana * 0.6); // defender loses 1/2 of their mana
|
||||
defender.Mana -= manaToLeech;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (defender.Alive)
|
||||
{
|
||||
int stamToLeech = (int)(defender.Stam * 0.7); // defender loses 9/10 of their stamina
|
||||
defender.Stam -= stamToLeech;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
defender.SendLocalizedMessage(1152694, "", 0x22); // Your life force is drained by the death vortex!
|
||||
}
|
||||
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private DeathVortexTrap m_Item;
|
||||
|
||||
public InternalTimer(DeathVortexTrap item) : base(TimeSpan.FromSeconds(15.0))
|
||||
{
|
||||
m_Item = item;
|
||||
|
||||
Priority = TimerPriority.OneMinute;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Delete();
|
||||
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Timer = new InternalTimer(this);
|
||||
m_Timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a human corpse" )]
|
||||
public class DupresChampion : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public DupresChampion() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
Name = NameList.RandomName("male");
|
||||
Title = "The Champion";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Female = false;
|
||||
|
||||
SetStr( 190, 200 );
|
||||
SetDex( 50, 75 );
|
||||
SetInt( 150, 250 );
|
||||
SetHits( 3900, 4100 );
|
||||
SetDamage( 22, 28 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 50, 70 );
|
||||
SetResistance( ResistanceType.Fire, 50, 70 );
|
||||
SetResistance( ResistanceType.Cold, 50, 70 );
|
||||
SetResistance( ResistanceType.Poison, 50, 70 );
|
||||
SetResistance( ResistanceType.Energy, 50, 70 );
|
||||
|
||||
SetSkill( SkillName.EvalInt, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Magery, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Meditation, 195.0, 200.0 );
|
||||
SetSkill( SkillName.MagicResist, 100.0, 120.0 );
|
||||
SetSkill( SkillName.Tactics, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Wrestling, 195.0, 220.0 );
|
||||
|
||||
VirtualArmor = 70;
|
||||
|
||||
Item cutlass = new Cutlass();
|
||||
cutlass.LootType = LootType.Blessed;
|
||||
SetWearable(cutlass);
|
||||
|
||||
Item ph = new PlateHelm();
|
||||
ph.LootType = LootType.Blessed;
|
||||
ph.Hue = 0x8A5; // gold
|
||||
SetWearable(ph);
|
||||
|
||||
Item pa = new PlateArms();
|
||||
pa.LootType = LootType.Blessed;
|
||||
pa.Hue = 0x8A5; // gold
|
||||
SetWearable(pa);
|
||||
|
||||
Item pg = new PlateGorget();
|
||||
pg.LootType = LootType.Blessed;
|
||||
pg.Hue = 0x8A5; // gold
|
||||
SetWearable(pg);
|
||||
|
||||
Item pgl = new PlateGloves();
|
||||
pgl.LootType = LootType.Blessed;
|
||||
pgl.Hue = 0x8A5; // gold
|
||||
SetWearable(pgl);
|
||||
|
||||
Item pl = new PlateLegs();
|
||||
pl.LootType = LootType.Blessed;
|
||||
pl.Hue = 0x8A5; // gold
|
||||
SetWearable(pl);
|
||||
|
||||
Item pc = new PlateChest();
|
||||
pc.LootType = LootType.Blessed;
|
||||
pc.Hue = 0x8A5; // gold
|
||||
SetWearable(pc);
|
||||
|
||||
Item mks = new MetalKiteShield();
|
||||
mks.LootType = LootType.Blessed;
|
||||
mks.Hue = 0x776;
|
||||
SetWearable(mks);
|
||||
|
||||
Item bs = new BodySash(0x486); // dark purple
|
||||
bs.LootType = LootType.Blessed;
|
||||
SetWearable(bs);
|
||||
|
||||
Item cloak = new Cloak(0x486); // dark purple
|
||||
cloak.LootType = LootType.Blessed;
|
||||
SetWearable(cloak);
|
||||
|
||||
PackGold( 400, 600 );
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0:
|
||||
PackItem(new ExodusSummoningRite());
|
||||
break;
|
||||
case 1:
|
||||
PackItem(new ExodusSacrificalDagger());
|
||||
break;
|
||||
case 2:
|
||||
PackItem(new RobeofRite());
|
||||
break;
|
||||
case 3:
|
||||
PackItem(new ExodusSummoningAlter());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanBeParagon { get { return false; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override int TreasureMapLevel{ get{ return 5; } }
|
||||
|
||||
public DupresChampion(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a human corpse" )]
|
||||
public class DupresKnight : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public DupresKnight() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
Name = NameList.RandomName("male");
|
||||
Title = "The Knight";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Female = false;
|
||||
|
||||
SetStr( 190, 200 );
|
||||
SetDex( 50, 75 );
|
||||
SetInt( 150, 250 );
|
||||
SetHits( 3900, 4100 );
|
||||
SetDamage( 22, 28 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 50, 70 );
|
||||
SetResistance( ResistanceType.Fire, 50, 70 );
|
||||
SetResistance( ResistanceType.Cold, 50, 70 );
|
||||
SetResistance( ResistanceType.Poison, 50, 70 );
|
||||
SetResistance( ResistanceType.Energy, 50, 70 );
|
||||
|
||||
SetSkill( SkillName.EvalInt, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Magery, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Meditation, 195.0, 200.0 );
|
||||
SetSkill( SkillName.MagicResist, 100.0, 120.0 );
|
||||
SetSkill( SkillName.Tactics, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Wrestling, 195.0, 220.0 );
|
||||
|
||||
VirtualArmor = 70;
|
||||
|
||||
Item longsword = new Longsword();
|
||||
longsword.LootType = LootType.Blessed;
|
||||
SetWearable(longsword);
|
||||
|
||||
Item ph = new PlateHelm();
|
||||
ph.LootType = LootType.Blessed;
|
||||
SetWearable(ph);
|
||||
|
||||
Item pa = new PlateArms();
|
||||
pa.LootType = LootType.Blessed;
|
||||
SetWearable(pa);
|
||||
|
||||
Item pg = new PlateGorget();
|
||||
pg.LootType = LootType.Blessed;
|
||||
SetWearable(pg);
|
||||
|
||||
Item pgl = new PlateGloves();
|
||||
pgl.LootType = LootType.Blessed;
|
||||
SetWearable(pgl);
|
||||
|
||||
Item pl = new PlateLegs();
|
||||
pl.LootType = LootType.Blessed;
|
||||
SetWearable(pl);
|
||||
|
||||
Item pc = new PlateChest();
|
||||
pc.LootType = LootType.Blessed;
|
||||
SetWearable(pc);
|
||||
|
||||
Item mks = new MetalKiteShield();
|
||||
mks.LootType = LootType.Blessed;
|
||||
mks.Hue = 0x794;
|
||||
SetWearable(mks);
|
||||
|
||||
Item bs = new BodySash(0x794); // dark purple
|
||||
bs.LootType = LootType.Blessed;
|
||||
SetWearable(bs);
|
||||
|
||||
PackGold( 400, 600 );
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanBeParagon { get { return false; } }
|
||||
public override bool InitialInnocent { get { return true; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override int TreasureMapLevel{ get{ return 5; } }
|
||||
|
||||
public DupresKnight(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName( "a human corpse" )]
|
||||
public class DupresSquire : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public DupresSquire() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
Name = NameList.RandomName("male");
|
||||
Title = "The Squire";
|
||||
Body = 0x190;
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Female = false;
|
||||
|
||||
SetStr( 190, 200 );
|
||||
SetDex( 50, 75 );
|
||||
SetInt( 150, 250 );
|
||||
SetHits( 3900, 4100 );
|
||||
SetDamage( 22, 28 );
|
||||
|
||||
SetDamageType( ResistanceType.Physical, 100 );
|
||||
|
||||
SetResistance( ResistanceType.Physical, 50, 70 );
|
||||
SetResistance( ResistanceType.Fire, 50, 70 );
|
||||
SetResistance( ResistanceType.Cold, 50, 70 );
|
||||
SetResistance( ResistanceType.Poison, 50, 70 );
|
||||
SetResistance( ResistanceType.Energy, 50, 70 );
|
||||
|
||||
SetSkill( SkillName.EvalInt, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Magery, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Meditation, 195.0, 200.0 );
|
||||
SetSkill( SkillName.MagicResist, 100.0, 120.0 );
|
||||
SetSkill( SkillName.Tactics, 195.0, 220.0 );
|
||||
SetSkill( SkillName.Wrestling, 195.0, 220.0 );
|
||||
|
||||
VirtualArmor = 70;
|
||||
|
||||
Item vikingsword = new VikingSword();
|
||||
vikingsword.LootType = LootType.Blessed;
|
||||
SetWearable(vikingsword);
|
||||
|
||||
Item cc = new ChainChest();
|
||||
cc.LootType = LootType.Blessed;
|
||||
SetWearable(cc);
|
||||
|
||||
Item cl = new ChainLegs();
|
||||
cl.LootType = LootType.Blessed;
|
||||
SetWearable(cl);
|
||||
|
||||
Item ch = new CloseHelm();
|
||||
ch.LootType = LootType.Blessed;
|
||||
SetWearable(ch);
|
||||
|
||||
Item boots = new Boots(1);
|
||||
boots.LootType = LootType.Blessed;
|
||||
SetWearable(boots);
|
||||
|
||||
Item pgl = new PlateGloves();
|
||||
pgl.LootType = LootType.Blessed;
|
||||
SetWearable(pgl);
|
||||
|
||||
Item mks = new MetalKiteShield();
|
||||
mks.LootType = LootType.Blessed;
|
||||
mks.Hue = 0x776;
|
||||
SetWearable(mks);
|
||||
|
||||
Item bs = new BodySash(0x794); // dark purple
|
||||
bs.LootType = LootType.Blessed;
|
||||
SetWearable(bs);
|
||||
|
||||
PackGold( 400, 600 );
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanBeParagon { get { return false; } }
|
||||
public override bool InitialInnocent { get { return true; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
public override int TreasureMapLevel{ get{ return 5; } }
|
||||
|
||||
public DupresSquire(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
#region Header
|
||||
//Exodus Encounter by Redmoon
|
||||
#endregion Header
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.ContextMenus;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class ExodusArchZealot : Mobile
|
||||
{
|
||||
public virtual bool IsInvulnerable { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public ExodusArchZealot()
|
||||
{
|
||||
Name = "Hunter";
|
||||
Title = "the Arch Zealot";
|
||||
Body = 0x190;
|
||||
CantWalk = true;
|
||||
Hue = 0;
|
||||
Blessed = true;
|
||||
|
||||
AddItem(new HoodedShroudOfShadows(0xA91));
|
||||
AddItem(new ThighBoots());
|
||||
|
||||
Item beard = new Item(0x2040);
|
||||
beard.Hue = 902;
|
||||
beard.Layer = Layer.FacialHair;
|
||||
beard.Movable = false;
|
||||
|
||||
AddItem(beard);
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (from.InRange(Location, 2))
|
||||
{
|
||||
if (from.Race == Race.Gargoyle && dropped.GetType() == typeof(ExodusSacrificalDagger))
|
||||
{
|
||||
dropped.Delete();
|
||||
from.AddToBackpack(new ExodusSacrificalGargishDagger());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
|
||||
public ExodusArchZealot(Serial serial): base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
list.Add(new ExodusArchZealotGumpEntry(from, this));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public class ExodusArchZealotGumpEntry : ContextMenuEntry
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private Mobile m_Giver;
|
||||
|
||||
public ExodusArchZealotGumpEntry(Mobile from, Mobile giver) : base(6146, 3)
|
||||
{
|
||||
m_Mobile = from;
|
||||
m_Giver = giver;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if( !( m_Mobile is PlayerMobile ) )
|
||||
return;
|
||||
|
||||
PlayerMobile mobile = (PlayerMobile) m_Mobile;
|
||||
{
|
||||
if (!mobile.HasGump(typeof(ExodusArchZealotGump)))
|
||||
{
|
||||
mobile.SendGump(new ExodusArchZealotGump(mobile));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ExodusArchZealotGump : Gump
|
||||
{
|
||||
public const int White = 0x7FFF;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("ExodusArchZealotGump", AccessLevel.GameMaster, new CommandEventHandler(ExodusArchZealotGump_OnCommand));
|
||||
}
|
||||
|
||||
private static void ExodusArchZealotGump_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendGump(new ExodusArchZealotGump(e.Mobile));
|
||||
}
|
||||
|
||||
public ExodusArchZealotGump(Mobile owner) : base(50, 50)
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
AddPage(0);
|
||||
AddImageTiled(54, 33, 369, 400, 2624);
|
||||
AddAlphaRegion(54, 33, 369, 400);
|
||||
|
||||
AddImageTiled(416, 39, 44, 389, 203);
|
||||
//--------------------------------------Window size bar--------------------------------------------
|
||||
|
||||
AddImage(97, 49, 9005);
|
||||
AddImageTiled(58, 39, 29, 390, 10460);
|
||||
AddImageTiled(412, 37, 31, 389, 10460);
|
||||
AddHtmlLocalized(140, 60, 250, 24, 1153670, White, false, false); // Exodus Arch Zealot
|
||||
AddImage(430, 9, 10441);
|
||||
AddImageTiled(40, 38, 17, 391, 9263);
|
||||
AddImage(6, 25, 10421);
|
||||
AddImage(34, 12, 10420);
|
||||
AddImageTiled(94, 25, 342, 15, 10304);
|
||||
AddImageTiled(40, 427, 415, 16, 10304);
|
||||
AddImage(-10, 314, 10402);
|
||||
AddImage(56, 150, 10411);
|
||||
AddImage(136, 84, 96);
|
||||
|
||||
AddPage(1);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153671, White, false, true); // Greetings Traveler *sly grin* Can you feel it? Can you feel the awesome power that emanates from this place...surely Lord Exodus will join us again soon, why <20> that<61>s why you<6F>re here isn<73>t it? To perform the Ritual?
|
||||
|
||||
AddHtmlLocalized(155, 260, 250, 24, 1153672, White, false, false);
|
||||
AddButton(125, 260, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 2);//Ritual?
|
||||
|
||||
AddHtmlLocalized(155, 280, 250, 24, 1153674, White, false, false);
|
||||
AddButton(125, 280, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 3);//Summoning Altar?
|
||||
|
||||
AddHtmlLocalized(155, 300, 250, 24, 1153676, White, false, false);
|
||||
AddButton(125, 300, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 4);//Robe of Rite?
|
||||
|
||||
AddHtmlLocalized(155, 320, 250, 24, 1153678, White, false, false);
|
||||
AddButton(125, 320, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 5);//Summoning Rite?
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153680, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 6);//Sacrifical Dagger?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
|
||||
//// START PAGE 2 Ritual
|
||||
AddPage(2);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153673, White, false, true); // The Ritual can only be performed by the most devoted of followers...and even then, only when the Summoning Altar has been built can the Robe of Rite be worn, the Summoning Rite be read and the Sacrificial dagger used to declare thy intention...only then can the great Lord Exodus be summoned to this plane...for these are the Keys to his return *laughs manically*
|
||||
|
||||
AddHtmlLocalized(155, 280, 250, 24, 1153674, White, false, false);
|
||||
AddButton(125, 280, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 3);//Summoning Altar?
|
||||
|
||||
AddHtmlLocalized(155, 300, 250, 24, 1153676, White, false, false);
|
||||
AddButton(125, 300, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 4);//Robe of Rite?
|
||||
|
||||
AddHtmlLocalized(155, 320, 250, 24, 1153678, White, false, false);
|
||||
AddButton(125, 320, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 5);//Summoning Rite?
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153680, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 6);//Sacrifical Dagger?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
///// END PAGE 2 Ritual
|
||||
|
||||
|
||||
//// START PAGE 3 Summoning Alter
|
||||
AddPage(3);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153675, White, false, true); // The Summoning Altar must be built upon a shrine, within Trammel or Felucca it matters not...
|
||||
|
||||
AddHtmlLocalized(155, 300, 250, 24, 1153676, White, false, false);
|
||||
AddButton(125, 300, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 4);//Robe of Rite?
|
||||
|
||||
AddHtmlLocalized(155, 320, 250, 24, 1153678, White, false, false);
|
||||
AddButton(125, 320, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 5);//Summoning Rite?
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153680, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 6);//Sacrifical Dagger?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
///// END PAGE 3 Summoning Alter
|
||||
|
||||
|
||||
//// START PAGE 4 Robe of Rite
|
||||
|
||||
AddPage(4);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153677, White, false, true); // These vestments must be worn as a sign of devotion to the ritual, for without them thou art not true to Lord Exodus.
|
||||
|
||||
AddHtmlLocalized(155, 320, 250, 24, 1153678, White, false, false);
|
||||
AddButton(125, 320, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 5);//Summoning Rite?
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153680, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 6);//Sacrifical Dagger?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
///// END PAGE 4 Robe of Rite
|
||||
|
||||
|
||||
//// START PAGE 5 Summoning Rite
|
||||
AddPage(5);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153679, White, false, true); // From the tongue of the summoner these words must flow, for without them thou art not true!
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153680, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 6);//Sacrifical Dagger?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
///// END PAGE 5 Summoning Rite
|
||||
|
||||
|
||||
//// START PAGE 6 Sacrifical Dagger
|
||||
AddPage(6);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153681, White, false, true); // This dagger, infused with black rock, is the instrument by which thou shall prove thy intention before the altar. If you wish a dagger to fit the talons of a gargoyle, simply hand to me the human tool and I shall alter it for you.
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153682, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 7);//The Keys?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
///// END PAGE 6 Sacrifical Dagger
|
||||
|
||||
|
||||
//// START PAGE 7 Keys
|
||||
AddPage(7);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153683, White, false, true); // Without the Keys the ritual cannot be performed. To obtain these Keys you may follow the path of the Warrior, the Rogue, or the Craftsman.
|
||||
|
||||
AddHtmlLocalized(155, 320, 250, 24, 1153684, White, false, false);
|
||||
AddButton(125, 320, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 8);//The Warrior?
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153686, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 9);//The Rogue?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153688, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 10);//The Craftsman?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
////END PAGE 7 Keys
|
||||
|
||||
|
||||
//// START PAGE 8 WARRIOR
|
||||
AddPage(8);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153685, White, false, true); // Deep within Exodus Dungeon, minions of Lord Exodus battle fiercely against Lord Dupre<72>s men...slay either one to collect the Keys.
|
||||
|
||||
AddHtmlLocalized(155, 340, 250, 24, 1153686, White, false, false);
|
||||
AddButton(125, 340, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 9);//The Rogue?
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153688, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 10);//The Craftsman?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
////END PAGE 8 WARRIOR
|
||||
|
||||
|
||||
////START PAGE 9 ROGUE
|
||||
AddPage(9);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153687, White, false, true); // Hidden deep inside the dungeon are supply caches...within them the intrepid rogue can find the Keys to the ritual. Look keenly and be deft with thy touch...as these caches are likely to be trapped. For the light of touch the Keys may be stolen from Zealots within the depths of the Dungeon...
|
||||
|
||||
AddHtmlLocalized(155, 360, 250, 24, 1153688, White, false, false);
|
||||
AddButton(125, 360, 0x26B0, 0x26B1, 0, GumpButtonType.Page, 10);//The Craftsman?
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
////END PAGE 9 ROGUE
|
||||
|
||||
////START PAGE 10 CRAFTSMAN
|
||||
AddPage(10);
|
||||
AddHtmlLocalized(107, 110, 300, 230, 1153689, White, false, true); // From the hands of the skilled artisan all of these Keys may be built by means of Tailoring, Alchemy, Carpentry, and Smithy.
|
||||
|
||||
AddButton(325, 390, 0xF7, 0xF8, 0, GumpButtonType.Reply, 0);//OK
|
||||
////END PAGE 10 CRAFTSMAN
|
||||
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info) //Function for GumpButtonType.Reply Buttons
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
//Cancel
|
||||
from.SendMessage("Good Luck!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a drone's corpse")]
|
||||
public class ExodusDrone : BaseCreature
|
||||
{
|
||||
private bool m_FieldActive;
|
||||
|
||||
[Constructable]
|
||||
public ExodusDrone() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
this.Name = "Exodus Drone";
|
||||
this.Body = 0x2F4;
|
||||
this.Hue = 0xA92;
|
||||
this.SetStr(554, 650);
|
||||
this.SetDex(77, 85);
|
||||
this.SetInt(64, 85);
|
||||
|
||||
this.SetHits(332, 389);
|
||||
this.SetDamage(13, 19);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 50);
|
||||
this.SetDamageType(ResistanceType.Energy, 50);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 45, 55);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 60);
|
||||
this.SetResistance(ResistanceType.Cold, 25, 35);
|
||||
this.SetResistance(ResistanceType.Poison, 25, 34);
|
||||
this.SetResistance(ResistanceType.Energy, 25, 35);
|
||||
|
||||
this.SetSkill(SkillName.MagicResist, 83.8, 95.4);
|
||||
this.SetSkill(SkillName.Tactics, 82.9, 94.9);
|
||||
this.SetSkill(SkillName.Wrestling, 84.7, 95.9);
|
||||
|
||||
this.Fame = 18000;
|
||||
this.Karma = -18000;
|
||||
this.VirtualArmor = 65;
|
||||
|
||||
this.PackItem(new PowerCrystal());
|
||||
this.PackItem(new ArcaneGem());
|
||||
this.PackItem(new ClockworkAssembly());
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
this.AddLoot(LootPack.Average);
|
||||
}
|
||||
|
||||
public ExodusDrone(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public bool FieldActive { get { return this.m_FieldActive; } }
|
||||
public bool CanUseField { get { return this.Hits >= this.HitsMax * 9 / 10; } } // TODO: an OSI bug prevents to verify this
|
||||
public override bool IsScaredOfScaryThings { get { return false; } }
|
||||
public override bool IsScaryToPets { get { return true; } }
|
||||
public override bool BardImmune { get { return !Core.AOS; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
|
||||
public override int GetIdleSound() { return 0x218; }
|
||||
public override int GetAngerSound() { return 0x26C; }
|
||||
public override int GetDeathSound() { return 0x211; }
|
||||
public override int GetAttackSound() { return 0x232; }
|
||||
public override int GetHurtSound() { return 0x140; }
|
||||
|
||||
public override void AlterMeleeDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (this.m_FieldActive)
|
||||
damage = 0; // no melee damage when the field is up
|
||||
}
|
||||
|
||||
public override void AlterSpellDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (!this.m_FieldActive)
|
||||
damage = 0; // no spell damage when the field is down
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile from)
|
||||
{
|
||||
if (from != null && from.Alive && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(from);
|
||||
}
|
||||
|
||||
if (!this.m_FieldActive)
|
||||
{
|
||||
// should there be an effect when spells nullifying is on?
|
||||
this.FixedParticles(0, 10, 0, 0x2522, EffectLayer.Waist);
|
||||
}
|
||||
else if (this.m_FieldActive && !this.CanUseField)
|
||||
{
|
||||
this.m_FieldActive = false;
|
||||
|
||||
// TODO: message and effect when field turns down; cannot be verified on OSI due to a bug
|
||||
this.FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker);
|
||||
|
||||
if (this.m_FieldActive)
|
||||
{
|
||||
this.FixedParticles(0x376A, 20, 10, 0x2530, EffectLayer.Waist);
|
||||
|
||||
this.PlaySound(0x2F4);
|
||||
|
||||
attacker.SendAsciiMessage("Your weapon cannot penetrate the creature's magical barrier");
|
||||
}
|
||||
|
||||
if (attacker != null && attacker.Alive && attacker.Weapon is BaseRanged && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
// TODO: an OSI bug prevents to verify if the field can regenerate or not
|
||||
if (!this.m_FieldActive && !this.IsHurt())
|
||||
this.m_FieldActive = true;
|
||||
}
|
||||
|
||||
public override bool Move(Direction d)
|
||||
{
|
||||
bool move = base.Move(d);
|
||||
|
||||
if (move && this.m_FieldActive && this.Combatant != null)
|
||||
this.FixedParticles(0, 10, 0, 0x2530, EffectLayer.Waist);
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public void SendEBolt(Mobile to)
|
||||
{
|
||||
this.MovingParticles(to, 0x379F, 7, 0, false, true, 0xBE3, 0xFCB, 0x211);
|
||||
to.PlaySound(0x229);
|
||||
this.DoHarmful(to);
|
||||
AOS.Damage(to, this, 50, 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a juggernaut's corpse")]
|
||||
public class ExodusJuggernaut : BaseCreature
|
||||
{
|
||||
private bool m_FieldActive;
|
||||
|
||||
[Constructable]
|
||||
public ExodusJuggernaut() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
this.Name = "Exodus Juggernaut";
|
||||
this.Body = 0x2F0;
|
||||
this.Hue = 2702;
|
||||
this.SetStr(1506, 1565);
|
||||
this.SetDex(92, 99);
|
||||
this.SetInt(101, 126);
|
||||
|
||||
this.SetHits(1012, 1069);
|
||||
this.SetDamage(19, 25);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 60);
|
||||
this.SetDamageType(ResistanceType.Energy, 40);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 60, 80);
|
||||
this.SetResistance(ResistanceType.Fire, 60, 80);
|
||||
this.SetResistance(ResistanceType.Cold, 20, 30);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 40);
|
||||
this.SetResistance(ResistanceType.Energy, 40, 50);
|
||||
|
||||
this.SetSkill(SkillName.MagicResist, 99.1, 100.0);
|
||||
this.SetSkill(SkillName.Tactics, 99.1, 100.0);
|
||||
this.SetSkill(SkillName.Wrestling, 99.1, 100.0);
|
||||
|
||||
this.Fame = 18000;
|
||||
this.Karma = -18000;
|
||||
this.VirtualArmor = 65;
|
||||
|
||||
this.PackItem(new PowerCrystal());
|
||||
this.PackItem(new ArcaneGem());
|
||||
this.PackItem(new ClockworkAssembly());
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
this.AddLoot(LootPack.Rich);
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public ExodusJuggernaut(Serial serial): base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public bool FieldActive { get { return this.m_FieldActive; } }
|
||||
public bool CanUseField { get { return this.Hits >= this.HitsMax * 9 / 10; } } // TODO: an OSI bug prevents to verify this
|
||||
public override bool IsScaredOfScaryThings { get { return false; } }
|
||||
public override bool IsScaryToPets { get { return true; } }
|
||||
public override bool BardImmune { get { return !Core.AOS; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
|
||||
public override int GetIdleSound() { return 0x218; }
|
||||
public override int GetAngerSound() { return 0x26C; }
|
||||
public override int GetDeathSound() { return 0x211; }
|
||||
public override int GetAttackSound() { return 0x232; }
|
||||
public override int GetHurtSound() { return 0x140; }
|
||||
|
||||
public override void AlterMeleeDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (this.m_FieldActive)
|
||||
damage = 0; // no melee damage when the field is up
|
||||
}
|
||||
|
||||
public override void AlterSpellDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (!this.m_FieldActive)
|
||||
damage = 0; // no spell damage when the field is down
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile from)
|
||||
{
|
||||
if (from != null && from.Alive && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(from);
|
||||
}
|
||||
|
||||
if (!this.m_FieldActive)
|
||||
{
|
||||
// should there be an effect when spells nullifying is on?
|
||||
this.FixedParticles(0, 10, 0, 0x2522, EffectLayer.Waist);
|
||||
}
|
||||
else if (this.m_FieldActive && !this.CanUseField)
|
||||
{
|
||||
this.m_FieldActive = false;
|
||||
|
||||
// TODO: message and effect when field turns down; cannot be verified on OSI due to a bug
|
||||
this.FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker);
|
||||
|
||||
if (this.m_FieldActive)
|
||||
{
|
||||
this.FixedParticles(0x376A, 20, 10, 0x2530, EffectLayer.Waist);
|
||||
|
||||
this.PlaySound(0x2F4);
|
||||
|
||||
attacker.SendAsciiMessage("Your weapon cannot penetrate the creature's magical barrier");
|
||||
}
|
||||
|
||||
if (attacker != null && attacker.Alive && attacker.Weapon is BaseRanged && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
// TODO: an OSI bug prevents to verify if the field can regenerate or not
|
||||
if (!this.m_FieldActive && !this.IsHurt())
|
||||
this.m_FieldActive = true;
|
||||
}
|
||||
|
||||
public override bool Move(Direction d)
|
||||
{
|
||||
bool move = base.Move(d);
|
||||
|
||||
if (move && this.m_FieldActive && this.Combatant != null)
|
||||
this.FixedParticles(0, 10, 0, 0x2530, EffectLayer.Waist);
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public void SendEBolt(Mobile to)
|
||||
{
|
||||
this.MovingParticles(to, 0x379F, 7, 0, false, true, 0xBE3, 0xFCB, 0x211);
|
||||
to.PlaySound(0x229);
|
||||
this.DoHarmful(to);
|
||||
AOS.Damage(to, this, 50, 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a exodus minion lord's corpse")]
|
||||
public class ExodusMinionLord : BaseCreature
|
||||
{
|
||||
private bool m_FieldActive;
|
||||
|
||||
[Constructable]
|
||||
public ExodusMinionLord() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Name = "Exodus Minion Lord";
|
||||
Body = 0x2FB;
|
||||
Hue = 0xA92;
|
||||
SetStr(1501, 1571);
|
||||
SetDex(74, 78);
|
||||
SetInt(66, 89);
|
||||
|
||||
SetHits(903, 957);
|
||||
|
||||
SetDamage(19, 25);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 65, 80);
|
||||
SetResistance(ResistanceType.Fire, 65, 80);
|
||||
SetResistance(ResistanceType.Cold, 20, 30);
|
||||
SetResistance(ResistanceType.Poison, 30, 40);
|
||||
SetResistance(ResistanceType.Energy, 40, 50);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 99.3, 99.8);
|
||||
SetSkill(SkillName.Tactics, 99.4, 100.0);
|
||||
SetSkill(SkillName.Wrestling, 99.2, 99.7);
|
||||
|
||||
Fame = 18000;
|
||||
Karma = -18000;
|
||||
VirtualArmor = 65;
|
||||
|
||||
PackItem(new PowerCrystal());
|
||||
PackItem(new ArcaneGem());
|
||||
PackItem(new ClockworkAssembly());
|
||||
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.Average);
|
||||
AddLoot(LootPack.Rich);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0:
|
||||
PackItem(new ExodusSummoningRite());
|
||||
break;
|
||||
case 1:
|
||||
PackItem(new ExodusSacrificalDagger());
|
||||
break;
|
||||
case 2:
|
||||
PackItem(new RobeofRite());
|
||||
break;
|
||||
case 3:
|
||||
PackItem(new ExodusSummoningAlter());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_FieldActive = CanUseField;
|
||||
}
|
||||
|
||||
public ExodusMinionLord(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public bool FieldActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_FieldActive;
|
||||
}
|
||||
}
|
||||
public bool CanUseField
|
||||
{
|
||||
get
|
||||
{
|
||||
return Hits >= HitsMax * 9 / 10;
|
||||
}
|
||||
}// TODO: an OSI bug prevents to verify this
|
||||
public override bool IsScaredOfScaryThings
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override bool IsScaryToPets
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override bool AutoDispel
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override bool BardImmune
|
||||
{
|
||||
get
|
||||
{
|
||||
return !Core.AOS;
|
||||
}
|
||||
}
|
||||
public override Poison PoisonImmune
|
||||
{
|
||||
get
|
||||
{
|
||||
return Poison.Lethal;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetIdleSound()
|
||||
{
|
||||
return 0x218;
|
||||
}
|
||||
|
||||
public override int GetAngerSound()
|
||||
{
|
||||
return 0x26C;
|
||||
}
|
||||
|
||||
public override int GetDeathSound()
|
||||
{
|
||||
return 0x211;
|
||||
}
|
||||
|
||||
public override int GetAttackSound()
|
||||
{
|
||||
return 0x232;
|
||||
}
|
||||
|
||||
public override int GetHurtSound()
|
||||
{
|
||||
return 0x140;
|
||||
}
|
||||
|
||||
public override void AlterMeleeDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (m_FieldActive)
|
||||
damage = 0; // no melee damage when the field is up
|
||||
}
|
||||
|
||||
public override void AlterSpellDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (!m_FieldActive)
|
||||
damage = 0; // no spell damage when the field is down
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile from)
|
||||
{
|
||||
if (from != null && from.Alive && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
SendEBolt(from);
|
||||
}
|
||||
|
||||
if (!m_FieldActive)
|
||||
{
|
||||
// should there be an effect when spells nullifying is on?
|
||||
FixedParticles(0, 10, 0, 0x2522, EffectLayer.Waist);
|
||||
}
|
||||
else if (m_FieldActive && !CanUseField)
|
||||
{
|
||||
m_FieldActive = false;
|
||||
|
||||
// TODO: message and effect when field turns down; cannot be verified on OSI due to a bug
|
||||
FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker);
|
||||
|
||||
if (m_FieldActive)
|
||||
{
|
||||
FixedParticles(0x376A, 20, 10, 0x2530, EffectLayer.Waist);
|
||||
|
||||
PlaySound(0x2F4);
|
||||
|
||||
attacker.SendAsciiMessage("Your weapon cannot penetrate the creature's magical barrier");
|
||||
}
|
||||
|
||||
if (attacker != null && attacker.Alive && attacker.Weapon is BaseRanged && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
SendEBolt(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
// TODO: an OSI bug prevents to verify if the field can regenerate or not
|
||||
if (!m_FieldActive && !IsHurt())
|
||||
m_FieldActive = true;
|
||||
}
|
||||
|
||||
public override bool Move(Direction d)
|
||||
{
|
||||
bool move = base.Move(d);
|
||||
|
||||
if (move && m_FieldActive && Combatant != null)
|
||||
FixedParticles(0, 10, 0, 0x2530, EffectLayer.Waist);
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public void SendEBolt(Mobile to)
|
||||
{
|
||||
MovingParticles(to, 0x379F, 7, 0, false, true, 0xBE3, 0xFCB, 0x211);
|
||||
to.PlaySound(0x229);
|
||||
DoHarmful(to);
|
||||
AOS.Damage(to, this, 50, 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_FieldActive = CanUseField;
|
||||
|
||||
if (Name == "Exodus Minion Lord")
|
||||
Name = "exodus minion lord";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a sentinel's corpse")]
|
||||
public class ExodusSentinel : BaseCreature
|
||||
{
|
||||
private bool m_FieldActive;
|
||||
|
||||
[Constructable]
|
||||
public ExodusSentinel() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
this.Name = "Exodus Sentinel";
|
||||
this.Body = 0x2FB;
|
||||
this.Hue = 0xA92;
|
||||
this.SetStr(854, 934);
|
||||
this.SetDex(81, 90);
|
||||
this.SetInt(81, 105);
|
||||
|
||||
this.SetHits(516, 564);
|
||||
|
||||
this.SetDamage(16, 22);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 60);
|
||||
this.SetDamageType(ResistanceType.Energy, 40);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 60, 70);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 50);
|
||||
this.SetResistance(ResistanceType.Cold, 25, 35);
|
||||
this.SetResistance(ResistanceType.Poison, 25, 35);
|
||||
this.SetResistance(ResistanceType.Energy, 25, 35);
|
||||
|
||||
this.SetSkill(SkillName.MagicResist, 91.5, 99.6);
|
||||
this.SetSkill(SkillName.Tactics, 91.9, 99.4);
|
||||
this.SetSkill(SkillName.Wrestling, 90.1, 98.9);
|
||||
|
||||
this.Fame = 18000;
|
||||
this.Karma = -18000;
|
||||
this.VirtualArmor = 65;
|
||||
|
||||
this.PackItem(new PowerCrystal());
|
||||
this.PackItem(new ArcaneGem());
|
||||
this.PackItem(new ClockworkAssembly());
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
this.AddLoot(LootPack.Rich);
|
||||
}
|
||||
|
||||
public override void OnKilledBy(Mobile m)
|
||||
{
|
||||
base.OnKilledBy(m);
|
||||
|
||||
if (Utility.RandomDouble() < 0.1)
|
||||
{
|
||||
ExodusChest.GiveRituelItem(m);
|
||||
}
|
||||
}
|
||||
|
||||
public ExodusSentinel(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public bool FieldActive { get { return this.m_FieldActive; } }
|
||||
public bool CanUseField { get { return this.Hits >= this.HitsMax * 9 / 10; } }// TODO: an OSI bug prevents to verify this
|
||||
public override bool IsScaredOfScaryThings { get { return false; } }
|
||||
public override bool IsScaryToPets { get { return true; } }
|
||||
public override bool BardImmune { get { return !Core.AOS; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
|
||||
public override int GetIdleSound() { return 0x218; }
|
||||
public override int GetAngerSound() { return 0x26C; }
|
||||
public override int GetDeathSound() { return 0x211; }
|
||||
public override int GetAttackSound() { return 0x232; }
|
||||
public override int GetHurtSound() { return 0x140; }
|
||||
|
||||
public override void AlterMeleeDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (this.m_FieldActive)
|
||||
damage = 0; // no melee damage when the field is up
|
||||
}
|
||||
|
||||
public override void AlterSpellDamageFrom(Mobile from, ref int damage)
|
||||
{
|
||||
if (!this.m_FieldActive)
|
||||
damage = 0; // no spell damage when the field is down
|
||||
}
|
||||
|
||||
public override void OnDamagedBySpell(Mobile from)
|
||||
{
|
||||
if (from != null && from.Alive && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(from);
|
||||
}
|
||||
|
||||
if (!this.m_FieldActive)
|
||||
{
|
||||
// should there be an effect when spells nullifying is on?
|
||||
this.FixedParticles(0, 10, 0, 0x2522, EffectLayer.Waist);
|
||||
}
|
||||
else if (this.m_FieldActive && !this.CanUseField)
|
||||
{
|
||||
this.m_FieldActive = false;
|
||||
|
||||
// TODO: message and effect when field turns down; cannot be verified on OSI due to a bug
|
||||
this.FixedParticles(0x3735, 1, 30, 0x251F, EffectLayer.Waist);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker)
|
||||
{
|
||||
base.OnGotMeleeAttack(attacker);
|
||||
|
||||
if (this.m_FieldActive)
|
||||
{
|
||||
this.FixedParticles(0x376A, 20, 10, 0x2530, EffectLayer.Waist);
|
||||
|
||||
this.PlaySound(0x2F4);
|
||||
|
||||
attacker.SendAsciiMessage("Your weapon cannot penetrate the creature's magical barrier");
|
||||
}
|
||||
|
||||
if (attacker != null && attacker.Alive && attacker.Weapon is BaseRanged && 0.4 > Utility.RandomDouble())
|
||||
{
|
||||
this.SendEBolt(attacker);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
// TODO: an OSI bug prevents to verify if the field can regenerate or not
|
||||
if (!this.m_FieldActive && !this.IsHurt())
|
||||
this.m_FieldActive = true;
|
||||
}
|
||||
|
||||
public override bool Move(Direction d)
|
||||
{
|
||||
bool move = base.Move(d);
|
||||
|
||||
if (move && this.m_FieldActive && this.Combatant != null)
|
||||
this.FixedParticles(0, 10, 0, 0x2530, EffectLayer.Waist);
|
||||
|
||||
return move;
|
||||
}
|
||||
|
||||
public void SendEBolt(Mobile to)
|
||||
{
|
||||
this.MovingParticles(to, 0x379F, 7, 0, false, true, 0xBE3, 0xFCB, 0x211);
|
||||
to.PlaySound(0x229);
|
||||
this.DoHarmful(to);
|
||||
AOS.Damage(to, this, 50, 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_FieldActive = this.CanUseField;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[CorpseName("a human corpse")]
|
||||
public class ExodusZealot : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public ExodusZealot()
|
||||
: base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
this.Body = 401;
|
||||
this.Female = false;
|
||||
this.Hue = 33875;
|
||||
this.HairItemID = Race.Human.RandomHair(this);
|
||||
this.HairHue = Race.Human.RandomHairHue();
|
||||
|
||||
this.Name = NameList.RandomName("male");
|
||||
this.Title = "The Exodus Zealot";
|
||||
|
||||
this.SetStr(150, 210);
|
||||
this.SetDex(75, 90);
|
||||
this.SetInt(255, 310);
|
||||
|
||||
this.SetHits(325, 390);
|
||||
|
||||
this.SetDamage(6, 12);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 30, 40);
|
||||
this.SetResistance(ResistanceType.Fire, 20, 30);
|
||||
this.SetResistance(ResistanceType.Cold, 35, 40);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 40);
|
||||
this.SetResistance(ResistanceType.Energy, 30, 40);
|
||||
|
||||
this.SetSkill(SkillName.Wrestling, 70.0, 100.0);
|
||||
this.SetSkill(SkillName.Tactics, 80.0, 100.0);
|
||||
this.SetSkill(SkillName.MagicResist, 50.0, 70.0);
|
||||
this.SetSkill(SkillName.Anatomy, 70.0, 100.0);
|
||||
this.SetSkill(SkillName.Magery, 85.0, 100.0);
|
||||
this.SetSkill(SkillName.EvalInt, 80.0, 100.0);
|
||||
this.SetSkill(SkillName.Poisoning, 70.0, 100.0);
|
||||
|
||||
this.Fame = 10000;
|
||||
this.Karma = -10000;
|
||||
this.VirtualArmor = 30;
|
||||
|
||||
Item boots = new ThighBoots();
|
||||
boots.Movable = false;
|
||||
this.SetWearable(boots);
|
||||
|
||||
Item item = new HoodedShroudOfShadows(2702);
|
||||
item.LootType = LootType.Blessed;
|
||||
this.SetWearable(item);
|
||||
|
||||
item = new Spellbook();
|
||||
item.LootType = LootType.Blessed;
|
||||
this.SetWearable(item);
|
||||
}
|
||||
|
||||
public ExodusZealot(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
public override bool ShowFameTitle { get { return false; } }
|
||||
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
this.AddLoot(LootPack.FilthyRich);
|
||||
this.AddLoot(LootPack.MedScrolls);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Gumps;
|
||||
using System.Linq;
|
||||
using Server.Regions;
|
||||
using System.Xml;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.Exodus
|
||||
{
|
||||
public class VerLorRegCity : DungeonRegion
|
||||
{
|
||||
private static readonly Point3D[] Random_Locations =
|
||||
{
|
||||
new Point3D(1217, 469, -13),
|
||||
new Point3D(720, 1356, -60),
|
||||
new Point3D(748, 728, -29),
|
||||
new Point3D(287, 1016, 0),
|
||||
new Point3D(987, 1007, -35),
|
||||
new Point3D(1175, 1287, -30),
|
||||
new Point3D(1532, 1341, -3),
|
||||
new Point3D(527, 218, -44),
|
||||
};
|
||||
|
||||
public VerLorRegCity(XmlElement xml, Map map, Region parent)
|
||||
: base(xml, map, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public class ExitTimer : Timer
|
||||
{
|
||||
private static TimeSpan m_Delay = TimeSpan.FromMinutes(2);
|
||||
private static TimeSpan m_Warning = TimeSpan.FromMinutes(8);
|
||||
VerLorRegCity m_region;
|
||||
|
||||
public ExitTimer(VerLorRegCity region) : base(m_Warning)
|
||||
{
|
||||
m_region = region;
|
||||
}
|
||||
protected override void OnTick()
|
||||
{
|
||||
foreach (Mobile m in m_region.GetEnumeratedMobiles().Where(m => m is PlayerMobile && m.AccessLevel == AccessLevel.Player))
|
||||
{
|
||||
m.SendLocalizedMessage(1010589);
|
||||
}
|
||||
|
||||
Timer.DelayCall(m_Delay, new TimerCallback(m_region.MoveLocation));
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveLocation()
|
||||
{
|
||||
foreach (Mobile m in this.GetEnumeratedMobiles().Where(m => m is PlayerMobile && m.AccessLevel == AccessLevel.Player))
|
||||
{
|
||||
Point3D p = Random_Locations[Utility.Random(Random_Locations.Length)];
|
||||
|
||||
m.MoveToWorld(p, m.Map);
|
||||
BaseCreature.TeleportPets(m, p, m.Map);
|
||||
}
|
||||
|
||||
VerLorRegController.Start();
|
||||
}
|
||||
|
||||
public override bool CheckTravel(Mobile traveller, Point3D p, TravelCheckType type)
|
||||
{
|
||||
if (traveller.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
return type > TravelCheckType.Mark;
|
||||
}
|
||||
|
||||
public override void OnDeath(Mobile m)
|
||||
{
|
||||
if (VerLorRegController.Mobile != null && VerLorRegController.Mobile == m)
|
||||
{
|
||||
VerLorRegController.Stop();
|
||||
new ExitTimer(this).Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GoldDust : Item, ICommodity
|
||||
{
|
||||
[Constructable]
|
||||
public GoldDust() : this(1)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GoldDust(int amount) : base(0x4C09)
|
||||
{
|
||||
this.Stackable = true;
|
||||
this.Hue = 1177;
|
||||
this.Weight = 1.0;
|
||||
this.Amount = amount;
|
||||
}
|
||||
|
||||
public GoldDust(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
TextDefinition ICommodity.Description { get { return LabelNumber; } }
|
||||
bool ICommodity.IsDeedable { get { return true; } }
|
||||
|
||||
public override int LabelNumber { get { return 1153504; } } // gold dust
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class NexusCore : Item
|
||||
{
|
||||
[Constructable]
|
||||
public NexusCore() : base(0x4B82)
|
||||
{
|
||||
Stackable = false;
|
||||
}
|
||||
|
||||
public NexusCore(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override int LabelNumber { get { return 1153501; } } // nexus core
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version == 0)
|
||||
Stackable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SmallPieceofBlackrock : Item, ICommodity
|
||||
{
|
||||
[Constructable]
|
||||
public SmallPieceofBlackrock(): this(1)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SmallPieceofBlackrock(int amount) : base(0x0F28)
|
||||
{
|
||||
this.Hue = 1175;
|
||||
this.Stackable = true;
|
||||
this.Amount = amount;
|
||||
this.Weight = 1.0;
|
||||
}
|
||||
|
||||
public SmallPieceofBlackrock(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
TextDefinition ICommodity.Description { get { return LabelNumber; } }
|
||||
bool ICommodity.IsDeedable { get { return true; } }
|
||||
|
||||
public override int LabelNumber { get { return 1150016; } }
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.Exodus
|
||||
{
|
||||
public class VerLorRegController : Item
|
||||
{
|
||||
private static bool m_Active;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public static bool Active
|
||||
{
|
||||
get { return m_Active; }
|
||||
set { if (value) Start(); else Stop();}
|
||||
}
|
||||
|
||||
private static ClockworkExodus m_Mobile;
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public static ClockworkExodus Mobile
|
||||
{
|
||||
get { return m_Mobile; }
|
||||
set { m_Mobile = value; }
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Administrator)]
|
||||
public static VerLorRegController IlshenarInstance { get; set; }
|
||||
|
||||
public VerLorRegController(Map map) : base(7107)
|
||||
{
|
||||
this.Name = "Ver Lor Reg Controller";
|
||||
this.Visible = false;
|
||||
this.Movable = false;
|
||||
|
||||
Start();
|
||||
}
|
||||
|
||||
public VerLorRegController(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (IlshenarInstance == null)
|
||||
{
|
||||
IlshenarInstance = new VerLorRegController(Map.Ilshenar);
|
||||
IlshenarInstance.MoveToWorld(new Point3D(849, 648, -40), Map.Ilshenar);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
|
||||
writer.Write((bool)m_Active);
|
||||
writer.WriteMobile(m_Mobile);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Active = reader.ReadBool();
|
||||
m_Mobile = (ClockworkExodus)reader.ReadMobile();
|
||||
|
||||
if (Map == Map.Ilshenar)
|
||||
IlshenarInstance = this;
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
if (m_Active)
|
||||
return;
|
||||
|
||||
m_Active = true;
|
||||
|
||||
if (m_Mobile == null)
|
||||
{
|
||||
ClockworkExodus m = new ClockworkExodus();
|
||||
m.Home = new Point3D(854, 642, -40);
|
||||
m.RangeHome = 4;
|
||||
m.MoveToWorld(new Point3D(854, 642, -40), Map.Ilshenar);
|
||||
m_Mobile = m;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
if (!m_Active)
|
||||
return;
|
||||
|
||||
m_Active = false;
|
||||
m_Mobile.Delete();
|
||||
m_Mobile = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user