Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
53
Scripts/Items/Functional/AcidVine.cs
Normal file
53
Scripts/Items/Functional/AcidVine.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class AcidVine : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1111655; } } // magic vines
|
||||
public override bool ForceShowProperties { get { return ObjectPropertyList.Enabled; } }
|
||||
|
||||
[Constructable]
|
||||
public AcidVine()
|
||||
: base(3313)
|
||||
{
|
||||
Weight = 1.0;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public AcidVine(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.InRange(this.GetWorldLocation(), 1))
|
||||
{
|
||||
from.SendLocalizedMessage(1111658); // The vines tighten their grip, stopping you from opening the door.
|
||||
}
|
||||
else if (from.InRange(this.GetWorldLocation(), 4))
|
||||
{
|
||||
from.SendLocalizedMessage(1111665); // You notice something odd about the vines covering the wall.
|
||||
}
|
||||
else if (!from.InRange(this.GetWorldLocation(), 4))
|
||||
{
|
||||
from.SendLocalizedMessage(1019045); // I can't reach that.
|
||||
}
|
||||
|
||||
base.OnDoubleClick(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
536
Scripts/Items/Functional/Ankhs.cs
Normal file
536
Scripts/Items/Functional/Ankhs.cs
Normal file
@@ -0,0 +1,536 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Ankhs
|
||||
{
|
||||
public const int ResurrectRange = 2;
|
||||
public const int TitheRange = 2;
|
||||
public const int LockRange = 2;
|
||||
public static void GetContextMenuEntries(Mobile from, Item item, List<ContextMenuEntry> list)
|
||||
{
|
||||
if (from is PlayerMobile)
|
||||
list.Add(new LockKarmaEntry((PlayerMobile)from));
|
||||
|
||||
list.Add(new ResurrectEntry(from, item));
|
||||
|
||||
if (Core.AOS)
|
||||
list.Add(new TitheEntry(from));
|
||||
}
|
||||
|
||||
public static void Resurrect(Mobile m, Item item)
|
||||
{
|
||||
if (m.Alive)
|
||||
return;
|
||||
|
||||
if (!m.InRange(item.GetWorldLocation(), ResurrectRange))
|
||||
m.SendLocalizedMessage(500446); // That is too far away.
|
||||
else if (m.Map != null && m.Map.CanFit(m.Location, 16, false, false))
|
||||
{
|
||||
m.CloseGump(typeof(ResurrectGump));
|
||||
m.SendGump(new ResurrectGump(m, ResurrectMessage.VirtueShrine));
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
|
||||
}
|
||||
|
||||
private class ResurrectEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly Item m_Item;
|
||||
public ResurrectEntry(Mobile mobile, Item item)
|
||||
: base(6195, ResurrectRange)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
m_Item = item;
|
||||
|
||||
Enabled = !m_Mobile.Alive;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Resurrect(m_Mobile, m_Item);
|
||||
}
|
||||
}
|
||||
|
||||
private class LockKarmaEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly PlayerMobile m_Mobile;
|
||||
public LockKarmaEntry(PlayerMobile mobile)
|
||||
: base(mobile.KarmaLocked ? 6197 : 6196, LockRange)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Mobile.KarmaLocked = !m_Mobile.KarmaLocked;
|
||||
|
||||
if (m_Mobile.KarmaLocked)
|
||||
m_Mobile.SendLocalizedMessage(1060192); // Your karma has been locked. Your karma can no longer be raised.
|
||||
else
|
||||
m_Mobile.SendLocalizedMessage(1060191); // Your karma has been unlocked. Your karma can be raised again.
|
||||
}
|
||||
}
|
||||
|
||||
private class TitheEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
public TitheEntry(Mobile mobile)
|
||||
: base(6198, TitheRange)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
|
||||
Enabled = m_Mobile.Alive;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_Mobile.CheckAlive())
|
||||
m_Mobile.SendGump(new TithingGump(m_Mobile, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AnkhWest : Item
|
||||
{
|
||||
private InternalItem m_Item;
|
||||
[Constructable]
|
||||
public AnkhWest()
|
||||
: this(false)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public AnkhWest(bool bloodied)
|
||||
: base(bloodied ? 0x1D98 : 0x3)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Item = new InternalItem(bloodied, this);
|
||||
}
|
||||
|
||||
public AnkhWest(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}// Tell the core that we implement OnMovement
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Hue = value;
|
||||
if (m_Item.Hue != value)
|
||||
m_Item.Hue = value;
|
||||
}
|
||||
}
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Parent == null && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
Ankhs.GetContextMenuEntries(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile m)
|
||||
{
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Location = new Point3D(X, Y + 1, Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Map = Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (m_Item != null)
|
||||
m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Item = reader.ReadItem() as InternalItem;
|
||||
}
|
||||
|
||||
private class InternalItem : Item
|
||||
{
|
||||
private AnkhWest m_Item;
|
||||
public InternalItem(bool bloodied, AnkhWest item)
|
||||
: base(bloodied ? 0x1D97 : 0x2)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}// Tell the core that we implement OnMovement
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Hue = value;
|
||||
if (m_Item.Hue != value)
|
||||
m_Item.Hue = value;
|
||||
}
|
||||
}
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Location = new Point3D(X, Y - 1, Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Map = Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (m_Item != null)
|
||||
m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Parent == null && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
Ankhs.GetContextMenuEntries(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile m)
|
||||
{
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Item = reader.ReadItem() as AnkhWest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TypeAlias("Server.Items.AnkhEast")]
|
||||
public class AnkhNorth : Item
|
||||
{
|
||||
private InternalItem m_Item;
|
||||
[Constructable]
|
||||
public AnkhNorth()
|
||||
: this(false)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public AnkhNorth(bool bloodied)
|
||||
: base(bloodied ? 0x1E5D : 0x4)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Item = new InternalItem(bloodied, this);
|
||||
}
|
||||
|
||||
public AnkhNorth(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}// Tell the core that we implement OnMovement
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Hue = value;
|
||||
if (m_Item.Hue != value)
|
||||
m_Item.Hue = value;
|
||||
}
|
||||
}
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Parent == null && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
Ankhs.GetContextMenuEntries(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile m)
|
||||
{
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Location = new Point3D(X + 1, Y, Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Map = Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (m_Item != null)
|
||||
m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Item = reader.ReadItem() as InternalItem;
|
||||
}
|
||||
|
||||
[TypeAlias("Server.Items.AnkhEast+InternalItem")]
|
||||
private class InternalItem : Item
|
||||
{
|
||||
private AnkhNorth m_Item;
|
||||
public InternalItem(bool bloodied, AnkhNorth item)
|
||||
: base(bloodied ? 0x1E5C : 0x5)
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}// Tell the core that we implement OnMovement
|
||||
[Hue, CommandProperty(AccessLevel.GameMaster)]
|
||||
public override int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Hue;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Hue = value;
|
||||
if (m_Item.Hue != value)
|
||||
m_Item.Hue = value;
|
||||
}
|
||||
}
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Location = new Point3D(X - 1, Y, Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (m_Item != null)
|
||||
m_Item.Map = Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (m_Item != null)
|
||||
m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Parent == null && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
Ankhs.GetContextMenuEntries(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile m)
|
||||
{
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Item = reader.ReadItem() as AnkhNorth;
|
||||
}
|
||||
}
|
||||
|
||||
private class MemorialStone : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1071563; } } // Memorial Stone
|
||||
|
||||
[Constructable]
|
||||
public MemorialStone()
|
||||
: base(0x117F)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public MemorialStone(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (Parent == null && Utility.InRange(Location, m.Location, 1) && !Utility.InRange(Location, oldLocation, 1))
|
||||
Ankhs.Resurrect(m, this);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
Ankhs.GetContextMenuEntries(from, this, list);
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile m)
|
||||
{
|
||||
Ankhs.Resurrect(m, 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Scripts/Items/Functional/AnvilForge.cs
Normal file
65
Scripts/Items/Functional/AnvilForge.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0xFAF, 0xFB0)]
|
||||
[Server.Engines.Craft.Anvil]
|
||||
public class Anvil : Item
|
||||
{
|
||||
[Constructable]
|
||||
public Anvil()
|
||||
: base(0xFAF)
|
||||
{
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public Anvil(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();
|
||||
}
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
public class Forge : Item
|
||||
{
|
||||
[Constructable]
|
||||
public Forge()
|
||||
: base(0xFB1)
|
||||
{
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public Forge(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Scripts/Items/Functional/Automaton/AutomatonActuator.cs
Normal file
35
Scripts/Items/Functional/Automaton/AutomatonActuator.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class AutomatonActuator : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1156997; } } // Automaton Actuator
|
||||
|
||||
[Constructable]
|
||||
public AutomatonActuator()
|
||||
: base(0x9CE9)
|
||||
{
|
||||
}
|
||||
|
||||
public AutomatonActuator(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
106
Scripts/Items/Functional/Automaton/AutomatonStatue.cs
Normal file
106
Scripts/Items/Functional/Automaton/AutomatonStatue.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class AutomatonStatue : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KotlAutomaton Automaton { get; set; }
|
||||
|
||||
public override int LabelNumber { get { return 1124395; } } // Automaton
|
||||
public override bool HandlesOnMovement { get { return Automaton == null; } }
|
||||
|
||||
[Constructable]
|
||||
public AutomatonStatue()
|
||||
: base(Utility.RandomBool() ? 0x9DB3 : 0x9DB4)
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D lastLocation)
|
||||
{
|
||||
base.OnMovement(m, lastLocation);
|
||||
|
||||
if (m.Player && m.InRange(this.Location, 5) && m.AccessLevel == AccessLevel.Player && 0.5 > Utility.RandomDouble())
|
||||
{
|
||||
var automaton = new KotlAutomaton();
|
||||
automaton.MoveToWorld(Location, Map);
|
||||
|
||||
OnBirth(automaton, this);
|
||||
|
||||
Visible = false;
|
||||
Automaton = automaton;
|
||||
|
||||
Timer.DelayCall(() => automaton.Combatant = m);
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<KotlAutomaton, AutomatonStatue> Statues { get; set; }
|
||||
|
||||
public static void OnBirth(KotlAutomaton automaton, AutomatonStatue statue)
|
||||
{
|
||||
if (Statues == null)
|
||||
Statues = new Dictionary<KotlAutomaton, AutomatonStatue>();
|
||||
|
||||
if (!Statues.ContainsKey(automaton))
|
||||
Statues[automaton] = statue;
|
||||
|
||||
}
|
||||
|
||||
public static void OnDeath(KotlAutomaton automaton)
|
||||
{
|
||||
if (Statues == null)
|
||||
return;
|
||||
|
||||
if (Statues.ContainsKey(automaton) && Statues[automaton] != null && !Statues[automaton].Deleted)
|
||||
{
|
||||
Statues[automaton].Delete();
|
||||
Statues.Remove(automaton);
|
||||
|
||||
if (Statues.Count == 0)
|
||||
Statues = null;
|
||||
}
|
||||
}
|
||||
|
||||
public AutomatonStatue(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
if (Automaton != null)
|
||||
{
|
||||
writer.Write(0);
|
||||
writer.Write(Automaton);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(1);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (reader.ReadInt() == 0)
|
||||
{
|
||||
Automaton = reader.ReadMobile() as KotlAutomaton;
|
||||
|
||||
if (Automaton == null)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Scripts/Items/Functional/Automaton/BlackrockAutomaton.cs
Normal file
75
Scripts/Items/Functional/Automaton/BlackrockAutomaton.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BlackrockAutomaton : KotlAutomaton
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public override Type RepairResource
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(CrystallineBlackrock); // TODO: Needs to be regular blackrock. THis doesn't exist on ServUO
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public BlackrockAutomaton()
|
||||
{
|
||||
Name = "blackrock automaton";
|
||||
Body = 1406;
|
||||
BaseSoundID = 541;
|
||||
|
||||
Hue = 0x8497;
|
||||
|
||||
SetStr(800, 900);
|
||||
SetDex(67, 74);
|
||||
SetInt(255, 263);
|
||||
|
||||
SetHits(774, 876);
|
||||
|
||||
SetDamage(15, 20);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 55, 60);
|
||||
SetResistance(ResistanceType.Fire, 55, 60);
|
||||
SetResistance(ResistanceType.Cold, 50, 55);
|
||||
SetResistance(ResistanceType.Poison, 50, 55);
|
||||
SetResistance(ResistanceType.Energy, 45, 50);
|
||||
|
||||
SetSkill(SkillName.Anatomy, 90.3, 99.9);
|
||||
SetSkill(SkillName.MagicResist, 121.0, 126.7);
|
||||
SetSkill(SkillName.Tactics, 82.0, 94.8);
|
||||
SetSkill(SkillName.Wrestling, 94.4, 108.4);
|
||||
|
||||
SetWeaponAbility(WeaponAbility.ParalyzingBlow);
|
||||
SetWeaponAbility(WeaponAbility.Disarm);
|
||||
SetWeaponAbility(WeaponAbility.ArmorPierce);
|
||||
}
|
||||
|
||||
public override double WeaponAbilityChance { get { return 0.45; } }
|
||||
|
||||
public override void OnResourceChanged()
|
||||
{
|
||||
}
|
||||
|
||||
public BlackrockAutomaton(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Scripts/Items/Functional/Automaton/BlackrockAutomatonHead.cs
Normal file
46
Scripts/Items/Functional/Automaton/BlackrockAutomatonHead.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x9DB1, 0x9DB2)]
|
||||
public class BlackrockAutomatonHead : KotlAutomatonHead
|
||||
{
|
||||
public override int LabelNumber { get { return 1157220; } } // Blackrock Automaton Head
|
||||
|
||||
[Constructable]
|
||||
public BlackrockAutomatonHead()
|
||||
{
|
||||
Hue = 1175;
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1157022, "#1157178"); // Rebuilt ~1_MATTYPE~ Automaton Head
|
||||
}
|
||||
|
||||
public override KotlAutomaton GetAutomaton(Mobile master)
|
||||
{
|
||||
return new BlackrockAutomaton();
|
||||
}
|
||||
|
||||
public BlackrockAutomatonHead(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Scripts/Items/Functional/Automaton/BlackrockMoonstone.cs
Normal file
36
Scripts/Items/Functional/Automaton/BlackrockMoonstone.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BlackrockMoonstone : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1156993; } } // Black Moonstone
|
||||
|
||||
[Constructable]
|
||||
public BlackrockMoonstone()
|
||||
: base(0x9CAA)
|
||||
{
|
||||
Hue = 1175;
|
||||
}
|
||||
|
||||
public BlackrockMoonstone(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
149
Scripts/Items/Functional/Automaton/BrokenAutomatonHead.cs
Normal file
149
Scripts/Items/Functional/Automaton/BrokenAutomatonHead.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x9DB1, 0x9DB2)]
|
||||
public class BrokenAutomatonHead : Item
|
||||
{
|
||||
public static int RepairAmount = 75;
|
||||
|
||||
private KotlAutomaton _Automaton;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public KotlAutomaton Automaton { get { return _Automaton; } set { _Automaton = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual Type RepairResource
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_Automaton == null)
|
||||
return typeof(IronIngot);
|
||||
|
||||
return _Automaton.RepairResource;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Nontransferable { get { return true; } }
|
||||
|
||||
public BrokenAutomatonHead(KotlAutomaton automaton)
|
||||
: base(0x9DB1)
|
||||
{
|
||||
_Automaton = automaton;
|
||||
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
if (_Automaton != null)
|
||||
{
|
||||
if(_Automaton is BlackrockAutomaton)
|
||||
list.Add(1157046, String.Format("{0}\t#{1}", _Automaton.Name, "1157178")); // ~1_NAME~'s Broken ~2_TYPE~ Automaton Head
|
||||
else
|
||||
list.Add(1157046, String.Format("{0}\t#{1}", _Automaton.Name, CraftResources.GetLocalizationNumber(_Automaton.Resource).ToString())); // ~1_NAME~'s Broken ~2_TYPE~ Automaton Head
|
||||
}
|
||||
else
|
||||
{
|
||||
base.AddNameProperty(list);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool TryRepair(Mobile from)
|
||||
{
|
||||
if (from.Backpack != null && IsChildOf(from.Backpack))
|
||||
{
|
||||
Type res = RepairResource;
|
||||
|
||||
if (_Automaton == null || _Automaton.ControlMaster != from)
|
||||
{
|
||||
from.SendLocalizedMessage(1157051); // You must be the owner of that pet to have it repair.
|
||||
}
|
||||
else if (from.Backpack.GetAmount(res) < RepairAmount)
|
||||
{
|
||||
if (res == typeof(CrystallineBlackrock))
|
||||
from.SendLocalizedMessage(1157179, String.Format("\t{0}", _Automaton.Name));
|
||||
else
|
||||
from.SendLocalizedMessage(1157050, String.Format("#{0}\t{1}", CraftResources.GetLocalizationNumber(_Automaton.Resource).ToString(), _Automaton.Name)); // You need 75 ~1_MATERIAL~ ingots to repair the ~2_CREATURE~.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.Backpack.ConsumeTotal(res, RepairAmount);
|
||||
|
||||
return RetrieveAutomaton(from);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool RetrieveAutomaton(Mobile from)
|
||||
{
|
||||
KotlAutomaton automaton = _Automaton;
|
||||
|
||||
Delete();
|
||||
|
||||
if (automaton != null && !automaton.Deleted)
|
||||
{
|
||||
automaton.ResurrectPet();
|
||||
automaton.Hits = automaton.HitsMax;
|
||||
|
||||
automaton.MoveToWorld(from.Location, from.Map);
|
||||
from.PlaySound(0x23B);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("An error has occured, your automaton has been deleted!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool OnDroppedInto(Mobile from, Container target, Point3D p)
|
||||
{
|
||||
if (target is BankBox)
|
||||
return true;
|
||||
|
||||
return base.OnDroppedInto(from, target, p);
|
||||
}
|
||||
|
||||
public override bool DropToWorld(Mobile from, Point3D p)
|
||||
{
|
||||
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
|
||||
{
|
||||
from.SendLocalizedMessage(1076256); // That item cannot be traded.
|
||||
return false;
|
||||
}
|
||||
|
||||
public BrokenAutomatonHead(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(_Automaton);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
_Automaton = reader.ReadMobile() as KotlAutomaton;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x9DB1, 0x9DB2)]
|
||||
public class InoperativeAutomatonHead : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1157002; } } // Inoperative Automaton Head
|
||||
|
||||
[Constructable]
|
||||
public InoperativeAutomatonHead()
|
||||
: base(0x9DB1)
|
||||
{
|
||||
}
|
||||
|
||||
public InoperativeAutomatonHead(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
217
Scripts/Items/Functional/Automaton/KotlAutomaton.cs
Normal file
217
Scripts/Items/Functional/Automaton/KotlAutomaton.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class KotlAutomaton : BaseCreature, IRepairableMobile
|
||||
{
|
||||
private CraftResource _Resource;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource
|
||||
{
|
||||
get { return _Resource; }
|
||||
set
|
||||
{
|
||||
var old = _Resource;
|
||||
_Resource = value;
|
||||
|
||||
if (old != _Resource)
|
||||
OnResourceChanged();
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual Type RepairResource
|
||||
{
|
||||
get
|
||||
{
|
||||
CraftResourceInfo resInfo = CraftResources.GetInfo(_Resource);
|
||||
|
||||
if (resInfo == null || resInfo.ResourceTypes.Length == 0)
|
||||
return typeof(IronIngot);
|
||||
|
||||
return resInfo.ResourceTypes[0];
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public KotlAutomaton()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
_Resource = CraftResource.Iron;
|
||||
|
||||
Name = "kotl automaton";
|
||||
Body = 1406;
|
||||
BaseSoundID = 541;
|
||||
|
||||
SetStr(793, 875);
|
||||
SetDex(67, 74);
|
||||
SetInt(255, 263);
|
||||
|
||||
SetHits(774, 876);
|
||||
|
||||
SetDamage(15, 20);
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 45, 50);
|
||||
SetResistance(ResistanceType.Fire, 45, 50);
|
||||
SetResistance(ResistanceType.Cold, 45, 50);
|
||||
SetResistance(ResistanceType.Poison, 45, 50);
|
||||
SetResistance(ResistanceType.Energy, 45, 50);
|
||||
|
||||
SetSkill(SkillName.Anatomy, 90.3, 99.9);
|
||||
SetSkill(SkillName.MagicResist, 121.0, 126.7);
|
||||
SetSkill(SkillName.Tactics, 82.0, 94.8);
|
||||
SetSkill(SkillName.Wrestling, 94.4, 108.4);
|
||||
SetSkill(SkillName.DetectHidden, 40.0);
|
||||
SetSkill(SkillName.Parry, 70.0, 80.0);
|
||||
|
||||
Fame = 14000;
|
||||
Karma = -14000;
|
||||
|
||||
ControlSlots = 4;
|
||||
SetWeaponAbility(WeaponAbility.ParalyzingBlow);
|
||||
SetWeaponAbility(WeaponAbility.Disarm);
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
this.AddLoot(LootPack.Rich, 4);
|
||||
}
|
||||
|
||||
public virtual void OnResourceChanged()
|
||||
{
|
||||
Hue = 0x8000 | CraftResources.GetHue(_Resource);
|
||||
|
||||
CraftResourceInfo resInfo = CraftResources.GetInfo(_Resource);
|
||||
|
||||
if (resInfo == null)
|
||||
return;
|
||||
|
||||
CraftAttributeInfo attrs = resInfo.AttributeInfo;
|
||||
|
||||
if (attrs == null)
|
||||
return;
|
||||
|
||||
SetResistance(ResistanceType.Physical, Utility.RandomMinMax(45, 50) + attrs.ArmorPhysicalResist);
|
||||
SetResistance(ResistanceType.Fire, Utility.RandomMinMax(45, 50) + attrs.ArmorFireResist);
|
||||
SetResistance(ResistanceType.Cold, Utility.RandomMinMax(45, 50) + attrs.ArmorColdResist);
|
||||
SetResistance(ResistanceType.Poison, Utility.RandomMinMax(45, 50) + attrs.ArmorPoisonResist);
|
||||
SetResistance(ResistanceType.Energy, Utility.RandomMinMax(45, 50) + attrs.ArmorEnergyResist);
|
||||
|
||||
int fire = attrs.WeaponFireDamage;
|
||||
int cold = attrs.WeaponColdDamage;
|
||||
int poison = attrs.WeaponPoisonDamage;
|
||||
int energy = attrs.WeaponEnergyDamage;
|
||||
int physical = 100 - fire - cold - poison - energy;
|
||||
|
||||
SetDamageType(ResistanceType.Physical, physical);
|
||||
SetDamageType(ResistanceType.Fire, fire);
|
||||
SetDamageType(ResistanceType.Cold, cold);
|
||||
SetDamageType(ResistanceType.Poison, poison);
|
||||
SetDamageType(ResistanceType.Energy, energy);
|
||||
}
|
||||
|
||||
public override double GetControlChance(Mobile m, bool useBaseSkill)
|
||||
{
|
||||
if (m.Skills[SkillName.Tinkering].Base < 100.0)
|
||||
{
|
||||
m.SendLocalizedMessage(1157043); // You lack the skill to command this Automaton.
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
if (!Controlled)
|
||||
{
|
||||
if (Region.IsPartOf("KotlCity"))
|
||||
{
|
||||
AutomatonStatue.OnDeath(this);
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
Mobile master = GetMaster();
|
||||
|
||||
if (Controlled && master != null && master.Backpack != null)
|
||||
{
|
||||
BrokenAutomatonHead broke = new BrokenAutomatonHead(this);
|
||||
|
||||
ControlTarget = null;
|
||||
ControlOrder = OrderType.Stay;
|
||||
Internalize();
|
||||
|
||||
IsStabled = true;
|
||||
Loyalty = MaxLoyalty;
|
||||
|
||||
master.Backpack.DropItem(broke); // This needs to drop regardless of weight/item count, right?
|
||||
|
||||
master.SendLocalizedMessage(1157048); // A broken automaton head has been placed in your backpack.
|
||||
}
|
||||
|
||||
base.OnDeath(c);
|
||||
}
|
||||
|
||||
public KotlAutomaton(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
// Missing Wrestling Mastery Ability
|
||||
|
||||
public override double WeaponAbilityChance { get { return 0.33; } }
|
||||
|
||||
public override bool IsScaredOfScaryThings { get { return false; } }
|
||||
public override bool IsScaryToPets { get { return !Controlled; } }
|
||||
public override FoodType FavoriteFood { get { return FoodType.None; } }
|
||||
public override bool CanBeDistracted { get { return false; } }
|
||||
public override bool DeleteOnRelease { get { return true; } }
|
||||
public override bool AutoDispel { get { return !Controlled; } }
|
||||
public override bool BleedImmune { get { return true; } }
|
||||
public override bool BardImmune { get { return true; } }
|
||||
public override Poison PoisonImmune { get { return Poison.Lethal; } }
|
||||
|
||||
public override bool CanTransfer(Mobile m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanFriend(Mobile m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1);
|
||||
|
||||
writer.Write((int)_Resource);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
_Resource = (CraftResource)reader.ReadInt();
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
SetWeaponAbility(WeaponAbility.ParalyzingBlow);
|
||||
SetWeaponAbility(WeaponAbility.Disarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
Scripts/Items/Functional/Automaton/KotlAutomatonHead.cs
Normal file
108
Scripts/Items/Functional/Automaton/KotlAutomatonHead.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Craft;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x9DB1, 0x9DB2)]
|
||||
public class KotlAutomatonHead : Item, ICraftable
|
||||
{
|
||||
private bool _Activated;
|
||||
private CraftResource _Resource;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CraftResource Resource { get { return _Resource; } set { _Resource = value; Hue = CraftResources.GetHue(this._Resource); InvalidateProperties(); } }
|
||||
|
||||
[Constructable]
|
||||
public KotlAutomatonHead()
|
||||
: base(0x9DB1)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Resource = CraftResource.Iron;
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1157022, String.Format("#{0}", CraftResources.GetLocalizationNumber(_Resource))); // Rebuilt ~1_MATTYPE~ Automaton Head
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
int skill = (int)from.Skills[SkillName.Tinkering].Base;
|
||||
|
||||
if (skill < 100.0)
|
||||
{
|
||||
from.SendLocalizedMessage(1157006); // You must be a Grandmaster Tinker to activate an Automaton.
|
||||
}
|
||||
else if (_Activated)
|
||||
{
|
||||
from.SendLocalizedMessage(1157007); // The Automaton is already being activated.
|
||||
}
|
||||
else
|
||||
{
|
||||
_Activated = true;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(3), () =>
|
||||
{
|
||||
_Activated = false;
|
||||
|
||||
KotlAutomaton automaton = GetAutomaton(from);
|
||||
|
||||
if (automaton.SetControlMaster(from))
|
||||
{
|
||||
automaton.IsBonded = true;
|
||||
|
||||
Delete();
|
||||
|
||||
automaton.MoveToWorld(from.Location, from.Map);
|
||||
from.PlaySound(0x23B);
|
||||
}
|
||||
else
|
||||
{
|
||||
automaton.Delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public virtual KotlAutomaton GetAutomaton(Mobile master)
|
||||
{
|
||||
KotlAutomaton automaton = new KotlAutomaton();
|
||||
automaton.Resource = _Resource;
|
||||
|
||||
return automaton;
|
||||
}
|
||||
|
||||
#region ICraftable Members
|
||||
public int OnCraft(int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, ITool tool, CraftItem craftItem, int resHue)
|
||||
{
|
||||
if (typeRes == null)
|
||||
typeRes = craftItem.Resources.GetAt(0).ItemType;
|
||||
|
||||
Resource = CraftResources.GetFromType(typeRes);
|
||||
|
||||
return quality;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public KotlAutomatonHead(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Scripts/Items/Functional/BaseArtifactLight.cs
Normal file
40
Scripts/Items/Functional/BaseArtifactLight.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseArtifactLight : BaseLight, IArtifact
|
||||
{
|
||||
public abstract int ArtifactRarity { get; }
|
||||
public virtual bool ShowArtifactRarity { get { return true; } }
|
||||
|
||||
public BaseArtifactLight(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
}
|
||||
|
||||
public BaseArtifactLight(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (ShowArtifactRarity)
|
||||
list.Add(1061078, this.ArtifactRarity.ToString()); // artifact rarity ~1_val~
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Scripts/Items/Functional/BaseDecayingItem.cs
Normal file
142
Scripts/Items/Functional/BaseDecayingItem.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BaseDecayingItem : Item
|
||||
{
|
||||
private int m_Lifespan;
|
||||
private Timer m_Timer;
|
||||
|
||||
public virtual int Lifespan { get { return 0; } }
|
||||
public virtual bool UseSeconds { get { return true; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TimeLeft
|
||||
{
|
||||
get { return m_Lifespan; }
|
||||
set
|
||||
{
|
||||
m_Lifespan = value;
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public BaseDecayingItem(int itemID) : base(itemID)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
m_Lifespan = this.Lifespan;
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (Lifespan > 0)
|
||||
{
|
||||
if (UseSeconds)
|
||||
list.Add(1072517, m_Lifespan.ToString()); // Lifespan: ~1_val~ seconds
|
||||
else
|
||||
{
|
||||
TimeSpan t = TimeSpan.FromSeconds(TimeLeft);
|
||||
|
||||
int weeks = (int)t.Days / 7;
|
||||
int days = t.Days;
|
||||
int hours = t.Hours;
|
||||
int minutes = t.Minutes;
|
||||
|
||||
if (weeks > 1)
|
||||
list.Add(1153092, (t.Days / 7).ToString()); // Lifespan: ~1_val~ weeks
|
||||
else if (days > 1)
|
||||
list.Add(1153091, t.Days.ToString()); // Lifespan: ~1_val~ days
|
||||
else if (hours > 1)
|
||||
list.Add(1153090, t.Hours.ToString()); // Lifespan: ~1_val~ hours
|
||||
else if (minutes > 1)
|
||||
list.Add(1153089, t.Minutes.ToString()); // Lifespan: ~1_val~ minutes
|
||||
else
|
||||
list.Add(1072517, t.Seconds.ToString()); // Lifespan: ~1_val~ seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (m_Timer != null || Lifespan == 0)
|
||||
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(this.Location, this.Map, EffectItem.DefaultDuration), 0x3728, 8, 20, 5042);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x201);
|
||||
}
|
||||
|
||||
StopTimer();
|
||||
Delete();
|
||||
}
|
||||
|
||||
public BaseDecayingItem (Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if(Lifespan > 0)
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
604
Scripts/Items/Functional/BaseDoor.cs
Normal file
604
Scripts/Items/Functional/BaseDoor.cs
Normal file
@@ -0,0 +1,604 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseDoor : Item, ILockable, ITelekinesisable
|
||||
{
|
||||
private static readonly Point3D[] m_Offsets = new Point3D[]
|
||||
{
|
||||
new Point3D(-1, 1, 0),
|
||||
new Point3D(1, 1, 0),
|
||||
new Point3D(-1, 0, 0),
|
||||
new Point3D(1,-1, 0),
|
||||
new Point3D(1, 1, 0),
|
||||
new Point3D(1,-1, 0),
|
||||
new Point3D(0, 0, 0),
|
||||
new Point3D(0,-1, 0),
|
||||
new Point3D(0, 0, 0),
|
||||
new Point3D(0, 0, 0),
|
||||
new Point3D(0, 0, 0),
|
||||
new Point3D(0, 0, 0)
|
||||
};
|
||||
private bool m_Open, m_Locked;
|
||||
private int m_OpenedID, m_OpenedSound;
|
||||
private int m_ClosedID, m_ClosedSound;
|
||||
private Point3D m_Offset;
|
||||
private BaseDoor m_Link;
|
||||
private uint m_KeyValue;
|
||||
private Timer m_Timer;
|
||||
public BaseDoor(int closedID, int openedID, int openedSound, int closedSound, Point3D offset)
|
||||
: base(closedID)
|
||||
{
|
||||
m_OpenedID = openedID;
|
||||
m_ClosedID = closedID;
|
||||
m_OpenedSound = openedSound;
|
||||
m_ClosedSound = closedSound;
|
||||
m_Offset = offset;
|
||||
|
||||
m_Timer = new InternalTimer(this);
|
||||
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public BaseDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Locked
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Locked;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Locked = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public uint KeyValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_KeyValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_KeyValue = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Open
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Open;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_Open != value)
|
||||
{
|
||||
m_Open = value;
|
||||
|
||||
ItemID = m_Open ? m_OpenedID : m_ClosedID;
|
||||
|
||||
if (m_Open)
|
||||
Location = new Point3D(X + m_Offset.X, Y + m_Offset.Y, Z + m_Offset.Z);
|
||||
else
|
||||
Location = new Point3D(X - m_Offset.X, Y - m_Offset.Y, Z - m_Offset.Z);
|
||||
|
||||
Effects.PlaySound(this, Map, m_Open ? m_OpenedSound : m_ClosedSound);
|
||||
|
||||
if (m_Open)
|
||||
m_Timer.Start();
|
||||
else
|
||||
m_Timer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int OpenedID
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OpenedID;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_OpenedID = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ClosedID
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ClosedID;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_ClosedID = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int OpenedSound
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_OpenedSound;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_OpenedSound = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ClosedSound
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ClosedSound;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_ClosedSound = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D Offset
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Offset;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Offset = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BaseDoor Link
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Link != null && m_Link.Deleted)
|
||||
m_Link = null;
|
||||
|
||||
return m_Link;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Link = value;
|
||||
}
|
||||
}
|
||||
public virtual bool UseChainedFunctionality
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Called by RunUO
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.OpenDoorMacroUsed += new OpenDoorMacroEventHandler(EventSink_OpenDoorMacroUsed);
|
||||
|
||||
CommandSystem.Register("Link", AccessLevel.GameMaster, new CommandEventHandler(Link_OnCommand));
|
||||
CommandSystem.Register("ChainLink", AccessLevel.GameMaster, new CommandEventHandler(ChainLink_OnCommand));
|
||||
}
|
||||
|
||||
public static Point3D GetOffset(DoorFacing facing)
|
||||
{
|
||||
return m_Offsets[(int)facing];
|
||||
}
|
||||
|
||||
public bool CanClose()
|
||||
{
|
||||
if (!m_Open)
|
||||
return true;
|
||||
|
||||
Map map = Map;
|
||||
|
||||
if (map == null)
|
||||
return false;
|
||||
|
||||
Point3D p = new Point3D(X - m_Offset.X, Y - m_Offset.Y, Z - m_Offset.Z);
|
||||
|
||||
return CheckFit(map, p, 16);
|
||||
}
|
||||
|
||||
public List<BaseDoor> GetChain()
|
||||
{
|
||||
List<BaseDoor> list = new List<BaseDoor>();
|
||||
BaseDoor c = this;
|
||||
|
||||
do
|
||||
{
|
||||
list.Add(c);
|
||||
c = c.Link;
|
||||
}
|
||||
while (c != null && !list.Contains(c));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public bool IsFreeToClose()
|
||||
{
|
||||
if (!UseChainedFunctionality)
|
||||
return CanClose();
|
||||
|
||||
List<BaseDoor> list = GetChain();
|
||||
|
||||
bool freeToClose = true;
|
||||
|
||||
for (int i = 0; freeToClose && i < list.Count; ++i)
|
||||
freeToClose = list[i].CanClose();
|
||||
|
||||
return freeToClose;
|
||||
}
|
||||
|
||||
public virtual void OnTelekinesis(Mobile from)
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(Location, Map, EffectItem.DefaultDuration), 0x376A, 9, 32, 5022);
|
||||
Effects.PlaySound(Location, Map, 0x1F5);
|
||||
|
||||
Use(from);
|
||||
}
|
||||
|
||||
public virtual bool IsInside(Mobile from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool UseLocks()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Use(Mobile from)
|
||||
{
|
||||
if (m_Locked && !m_Open && UseLocks())
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502502); // That is locked, but you open it with your godly powers.
|
||||
//from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, 502502, "", "" ) ); // That is locked, but you open it with your godly powers.
|
||||
}
|
||||
else if (Key.ContainsKey(from.Backpack, KeyValue))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501282); // You quickly unlock, open, and relock the door
|
||||
}
|
||||
else if (IsInside(from))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 501280); // That is locked, but is usable from the inside.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Hue == 0x44E && Map == Map.Malas) // doom door into healer room in doom
|
||||
SendLocalizedMessageTo(from, 1060014); // Only the dead may pass.
|
||||
else
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502503); // That is locked.
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Open && !IsFreeToClose())
|
||||
return;
|
||||
|
||||
if (m_Open)
|
||||
OnClosed(from);
|
||||
else
|
||||
OnOpened(from);
|
||||
|
||||
if (UseChainedFunctionality)
|
||||
{
|
||||
bool open = !m_Open;
|
||||
|
||||
List<BaseDoor> list = GetChain();
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
list[i].Open = open;
|
||||
}
|
||||
else
|
||||
{
|
||||
Open = !m_Open;
|
||||
|
||||
BaseDoor link = Link;
|
||||
|
||||
if (m_Open && link != null && !link.Open)
|
||||
link.Open = true;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void OnOpened(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnClosed(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.IsPlayer() && (/*!from.InLOS( this ) || */!from.InRange(GetWorldLocation(), 2)))
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
else
|
||||
Use(from);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_KeyValue);
|
||||
|
||||
writer.Write(m_Open);
|
||||
writer.Write(m_Locked);
|
||||
writer.Write(m_OpenedID);
|
||||
writer.Write(m_ClosedID);
|
||||
writer.Write(m_OpenedSound);
|
||||
writer.Write(m_ClosedSound);
|
||||
writer.Write(m_Offset);
|
||||
writer.Write(m_Link);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_KeyValue = reader.ReadUInt();
|
||||
m_Open = reader.ReadBool();
|
||||
m_Locked = reader.ReadBool();
|
||||
m_OpenedID = reader.ReadInt();
|
||||
m_ClosedID = reader.ReadInt();
|
||||
m_OpenedSound = reader.ReadInt();
|
||||
m_ClosedSound = reader.ReadInt();
|
||||
m_Offset = reader.ReadPoint3D();
|
||||
m_Link = reader.ReadItem() as BaseDoor;
|
||||
|
||||
m_Timer = new InternalTimer(this);
|
||||
|
||||
if (m_Open)
|
||||
m_Timer.Start();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("Link")]
|
||||
[Description("Links two targeted doors together.")]
|
||||
private static void Link_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(Link_OnFirstTarget));
|
||||
e.Mobile.SendMessage("Target the first door to link.");
|
||||
}
|
||||
|
||||
private static void Link_OnFirstTarget(Mobile from, object targeted)
|
||||
{
|
||||
BaseDoor door = targeted as BaseDoor;
|
||||
|
||||
if (door == null)
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetCallback(Link_OnFirstTarget));
|
||||
from.SendMessage("That is not a door. Try again.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(Link_OnSecondTarget), door);
|
||||
from.SendMessage("Target the second door to link.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Link_OnSecondTarget(Mobile from, object targeted, object state)
|
||||
{
|
||||
BaseDoor first = (BaseDoor)state;
|
||||
BaseDoor second = targeted as BaseDoor;
|
||||
|
||||
if (second == null)
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(Link_OnSecondTarget), first);
|
||||
from.SendMessage("That is not a door. Try again.");
|
||||
}
|
||||
else
|
||||
{
|
||||
first.Link = second;
|
||||
second.Link = first;
|
||||
from.SendMessage("The doors have been linked.");
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("ChainLink")]
|
||||
[Description("Chain-links two or more targeted doors together.")]
|
||||
private static void ChainLink_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(ChainLink_OnTarget), new List<BaseDoor>());
|
||||
e.Mobile.SendMessage("Target the first of a sequence of doors to link.");
|
||||
}
|
||||
|
||||
private static void ChainLink_OnTarget(Mobile from, object targeted, object state)
|
||||
{
|
||||
BaseDoor door = targeted as BaseDoor;
|
||||
|
||||
if (door == null)
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(ChainLink_OnTarget), state);
|
||||
from.SendMessage("That is not a door. Try again.");
|
||||
}
|
||||
else
|
||||
{
|
||||
List<BaseDoor> list = (List<BaseDoor>)state;
|
||||
|
||||
if (list.Count > 0 && list[0] == door)
|
||||
{
|
||||
if (list.Count >= 2)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
list[i].Link = list[(i + 1) % list.Count];
|
||||
|
||||
from.SendMessage("The chain of doors have been linked.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(ChainLink_OnTarget), state);
|
||||
from.SendMessage("You have not yet targeted two unique doors. Target the second door to link.");
|
||||
}
|
||||
}
|
||||
else if (list.Contains(door))
|
||||
{
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(ChainLink_OnTarget), state);
|
||||
from.SendMessage("You have already targeted that door. Target another door, or retarget the first door to complete the chain.");
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(door);
|
||||
|
||||
from.BeginTarget(-1, false, TargetFlags.None, new TargetStateCallback(ChainLink_OnTarget), state);
|
||||
|
||||
if (list.Count == 1)
|
||||
from.SendMessage("Target the second door to link.");
|
||||
else
|
||||
from.SendMessage("Target another door to link. To complete the chain, retarget the first door.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EventSink_OpenDoorMacroUsed(OpenDoorMacroEventArgs args)
|
||||
{
|
||||
Mobile m = args.Mobile;
|
||||
|
||||
if (m.Map != null)
|
||||
{
|
||||
int x = m.X, y = m.Y;
|
||||
|
||||
switch ( m.Direction & Direction.Mask )
|
||||
{
|
||||
case Direction.North:
|
||||
--y;
|
||||
break;
|
||||
case Direction.Right:
|
||||
++x;
|
||||
--y;
|
||||
break;
|
||||
case Direction.East:
|
||||
++x;
|
||||
break;
|
||||
case Direction.Down:
|
||||
++x;
|
||||
++y;
|
||||
break;
|
||||
case Direction.South:
|
||||
++y;
|
||||
break;
|
||||
case Direction.Left:
|
||||
--x;
|
||||
++y;
|
||||
break;
|
||||
case Direction.West:
|
||||
--x;
|
||||
break;
|
||||
case Direction.Up:
|
||||
--x;
|
||||
--y;
|
||||
break;
|
||||
}
|
||||
|
||||
Sector sector = m.Map.GetSector(x, y);
|
||||
|
||||
foreach (Item item in sector.Items)
|
||||
{
|
||||
if (item.Location.X == x && item.Location.Y == y && (item.Z + item.ItemData.Height) > m.Z && (m.Z + 16) > item.Z && item is BaseDoor && m.CanSee(item) && m.InLOS(item))
|
||||
{
|
||||
if (m.CheckAlive())
|
||||
{
|
||||
m.SendLocalizedMessage(500024); // Opening door...
|
||||
item.OnDoubleClick(m);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckFit(Map map, Point3D p, int height)
|
||||
{
|
||||
if (map == Map.Internal)
|
||||
return false;
|
||||
|
||||
int x = p.X;
|
||||
int y = p.Y;
|
||||
int z = p.Z;
|
||||
|
||||
Sector sector = map.GetSector(x, y);
|
||||
List<Item> items = sector.Items;
|
||||
List<Mobile> mobs = sector.Mobiles;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item item = items[i];
|
||||
|
||||
if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y) && !(item is BaseDoor))
|
||||
{
|
||||
ItemData id = item.ItemData;
|
||||
bool surface = id.Surface;
|
||||
bool impassable = id.Impassable;
|
||||
|
||||
if ((surface || impassable) && (item.Z + id.CalcHeight) > z && (z + height) > item.Z)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mobs.Count; ++i)
|
||||
{
|
||||
Mobile m = mobs[i];
|
||||
|
||||
if (m.Location.X == x && m.Location.Y == y)
|
||||
{
|
||||
if (m.Hidden && m.IsPlayer())
|
||||
continue;
|
||||
|
||||
if (!m.Alive)
|
||||
continue;
|
||||
|
||||
if ((m.Z + 16) > z && (z + height) > m.Z)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private readonly BaseDoor m_Door;
|
||||
public InternalTimer(BaseDoor door)
|
||||
: base(TimeSpan.FromSeconds(20.0), TimeSpan.FromSeconds(10.0))
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
m_Door = door;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Door.Open && m_Door.IsFreeToClose())
|
||||
m_Door.Open = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
143
Scripts/Items/Functional/BaseSwitch.cs
Normal file
143
Scripts/Items/Functional/BaseSwitch.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BaseSwitch : Item
|
||||
{
|
||||
private int m_TurnOn;
|
||||
private int m_TurnOff;
|
||||
private int m_LocMessageA;
|
||||
private int m_LocMessageB;
|
||||
private bool m_Used;
|
||||
private bool m_Working;
|
||||
[Constructable]
|
||||
public BaseSwitch(int TurnOff, int TurnOn, int LocMessageA, int LocMessageB, bool Working)
|
||||
: base(TurnOff)
|
||||
{
|
||||
this.Movable = false;
|
||||
this.m_TurnOn = TurnOn;
|
||||
this.m_TurnOff = TurnOff;
|
||||
this.m_LocMessageA = LocMessageA;
|
||||
this.m_LocMessageB = LocMessageB;
|
||||
this.m_Used = false;
|
||||
this.m_Working = Working;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public BaseSwitch(int TurnOff, int TurnOn)
|
||||
: base(TurnOff)
|
||||
{
|
||||
this.Movable = false;
|
||||
this.m_TurnOn = TurnOn;
|
||||
this.m_TurnOff = TurnOff;
|
||||
this.m_LocMessageA = 0;
|
||||
this.m_LocMessageB = 0;
|
||||
this.m_Used = false;
|
||||
this.m_Working = false;
|
||||
}
|
||||
|
||||
public BaseSwitch(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (!m.InRange(this, 2))
|
||||
{
|
||||
m.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int MessageA = 0;
|
||||
|
||||
if (this.m_LocMessageA == 0)
|
||||
MessageA = 500357 + Utility.Random(5);
|
||||
else
|
||||
MessageA = this.m_LocMessageA;
|
||||
|
||||
int MessageB = 0;
|
||||
|
||||
if (this.m_LocMessageB == 0)
|
||||
MessageB = 500357 + Utility.Random(5);
|
||||
else
|
||||
MessageB = this.m_LocMessageB;
|
||||
|
||||
/*
|
||||
500357 - If this lever ever did anything, it doesn't do it anymore.
|
||||
500358 - The lever feels loose, and you realize it no longer controls anything.
|
||||
500359 - You flip the lever and think you hear something, but realize it was just your imagination.
|
||||
500360 - The lever flips without effort, doing nothing.
|
||||
*/
|
||||
|
||||
if (this.ItemID == this.m_TurnOff && this.m_Used == false)
|
||||
{
|
||||
this.ItemID = this.m_TurnOn;
|
||||
this.m_Used = true;
|
||||
Effects.PlaySound(this.Location, this.Map, 0x3E8);
|
||||
|
||||
m.LocalOverheadMessage(MessageType.Regular, 0, MessageA); //Message received when it is turned on by first time.
|
||||
|
||||
//This call to another method to do something special, so you don't need
|
||||
//to override OnDoubleClick and rewrite this section again.
|
||||
if (this.m_Working == true)
|
||||
{
|
||||
this.DoSomethingSpecial(m);
|
||||
}
|
||||
|
||||
//Refresh time of two minutes, equal to RunUO's RaiseSwith
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(2.0), delegate()
|
||||
{
|
||||
this.ItemID = this.m_TurnOff;
|
||||
this.m_Used = false;
|
||||
});
|
||||
}
|
||||
else if (this.ItemID == this.m_TurnOff && this.m_Used == true)
|
||||
{
|
||||
this.ItemID = this.m_TurnOn;
|
||||
Effects.PlaySound(this.Location, this.Map, 0x3E8);
|
||||
m.LocalOverheadMessage(MessageType.Regular, 0, MessageB); //Message received after click it again until the refresh.
|
||||
}
|
||||
else //TurnOn and m_Used true
|
||||
{
|
||||
this.ItemID = this.m_TurnOff;
|
||||
Effects.PlaySound(this.Location, this.Map, 0x3E8);
|
||||
m.LocalOverheadMessage(MessageType.Regular, 0, MessageB); //Message received after click it again until the refresh.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DoSomethingSpecial(Mobile from)
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0, 1116629); //It does Nothing!
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
writer.Write(this.m_TurnOn);
|
||||
writer.Write(this.m_TurnOff);
|
||||
writer.Write(this.m_LocMessageA);
|
||||
writer.Write(this.m_LocMessageB);
|
||||
writer.Write(this.m_Working);
|
||||
writer.Write(this.m_Used);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
this.m_TurnOn = reader.ReadInt();
|
||||
this.m_TurnOff = reader.ReadInt();
|
||||
this.m_LocMessageA = reader.ReadInt();
|
||||
this.m_LocMessageB = reader.ReadInt();
|
||||
this.m_Working = reader.ReadBool();
|
||||
this.m_Used = reader.ReadBool();
|
||||
this.m_Used = false;
|
||||
this.ItemID = this.m_TurnOff;
|
||||
}
|
||||
}
|
||||
}
|
||||
114
Scripts/Items/Functional/BaseTrap.cs
Normal file
114
Scripts/Items/Functional/BaseTrap.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class BaseTrap : Item
|
||||
{
|
||||
private DateTime m_NextPassiveTrigger, m_NextActiveTrigger;
|
||||
public BaseTrap(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public BaseTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public virtual TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public virtual int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
public virtual TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}// Tell the core that we implement OnMovement
|
||||
public virtual void OnTrigger(Mobile from)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int GetEffectHue()
|
||||
{
|
||||
int hue = this.Hue & 0x3FFF;
|
||||
|
||||
if (hue < 2)
|
||||
return 0;
|
||||
|
||||
return hue - 1;
|
||||
}
|
||||
|
||||
public bool CheckRange(Point3D loc, Point3D oldLoc, int range)
|
||||
{
|
||||
return this.CheckRange(loc, range) && !this.CheckRange(oldLoc, range);
|
||||
}
|
||||
|
||||
public bool CheckRange(Point3D loc, int range)
|
||||
{
|
||||
return ((this.Z + 8) >= loc.Z && (loc.Z + 16) > this.Z) &&
|
||||
Utility.InRange(this.GetWorldLocation(), loc, range);
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
base.OnMovement(m, oldLocation);
|
||||
|
||||
if (m.Location == oldLocation)
|
||||
return;
|
||||
|
||||
if (this.CheckRange(m.Location, oldLocation, 0) && DateTime.UtcNow >= this.m_NextActiveTrigger)
|
||||
{
|
||||
this.m_NextActiveTrigger = this.m_NextPassiveTrigger = DateTime.UtcNow + this.ResetDelay;
|
||||
|
||||
this.OnTrigger(m);
|
||||
}
|
||||
else if (this.PassivelyTriggered && this.CheckRange(m.Location, oldLocation, this.PassiveTriggerRange) && DateTime.UtcNow >= this.m_NextPassiveTrigger)
|
||||
{
|
||||
this.m_NextPassiveTrigger = DateTime.UtcNow + this.PassiveTriggerDelay;
|
||||
|
||||
this.OnTrigger(m);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Scripts/Items/Functional/BedlamAltar.cs
Normal file
55
Scripts/Items/Functional/BedlamAltar.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BedlamAltar : PeerlessAltar
|
||||
{
|
||||
public override int KeyCount{ get{ return 3; } }
|
||||
public override MasterKey MasterKey{ get{ return new BedlamKey(); } }
|
||||
|
||||
public override Type[] Keys{ get{ return new Type[]
|
||||
{
|
||||
typeof( LibrariansKey )
|
||||
}; }}
|
||||
|
||||
public override BasePeerless Boss{ get{ return new MonstrousInterredGrizzle(); } }
|
||||
|
||||
[Constructable]
|
||||
public BedlamAltar() : base( 0x207E )
|
||||
{
|
||||
BossLocation = new Point3D( 106, 1615, 90 );
|
||||
TeleportDest = new Point3D( 101, 1623, 50 );
|
||||
ExitDest = new Point3D( 2068, 1372, -75 );
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(99, 1609, 14, 18),
|
||||
};
|
||||
|
||||
public BedlamAltar( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Scripts/Items/Functional/BlightedGroveAltar.cs
Normal file
55
Scripts/Items/Functional/BlightedGroveAltar.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BlightedGroveAltar : PeerlessAltar
|
||||
{
|
||||
public override int KeyCount{ get{ return 3; } }
|
||||
public override MasterKey MasterKey{ get{ return new BlightedGroveKey(); } }
|
||||
|
||||
public override Type[] Keys{ get{ return new Type[]
|
||||
{
|
||||
typeof( DryadsBlessing )
|
||||
}; }}
|
||||
|
||||
public override BasePeerless Boss{ get{ return new LadyMelisande(); } }
|
||||
|
||||
[Constructable]
|
||||
public BlightedGroveAltar() : base( 0x207B )
|
||||
{
|
||||
BossLocation = new Point3D( 6483, 947, 23 );
|
||||
TeleportDest = new Point3D( 6518, 946, 36 );
|
||||
ExitDest = new Point3D( 587, 1641, -1 );
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6456, 922, 84, 47),
|
||||
};
|
||||
|
||||
public BlightedGroveAltar( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
716
Scripts/Items/Functional/BulletinBoards.cs
Normal file
716
Scripts/Items/Functional/BulletinBoards.cs
Normal file
@@ -0,0 +1,716 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public struct BulletinEquip
|
||||
{
|
||||
public int itemID;
|
||||
public int hue;
|
||||
public BulletinEquip(int itemID, int hue)
|
||||
{
|
||||
this.itemID = itemID;
|
||||
this.hue = hue;
|
||||
}
|
||||
}
|
||||
|
||||
[Flipable(0x1E5E, 0x1E5F)]
|
||||
public class BulletinBoard : BaseBulletinBoard
|
||||
{
|
||||
[Constructable]
|
||||
public BulletinBoard()
|
||||
: base(0x1E5E)
|
||||
{
|
||||
}
|
||||
|
||||
public BulletinBoard(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 abstract class BaseBulletinBoard : Item
|
||||
{
|
||||
// Threads will be removed six hours after the last post was made
|
||||
private static readonly TimeSpan ThreadDeletionTime = TimeSpan.FromHours(6.0);
|
||||
// A player may only create a thread once every two minutes
|
||||
private static readonly TimeSpan ThreadCreateTime = TimeSpan.FromMinutes(2.0);
|
||||
// A player may only reply once every thirty seconds
|
||||
private static readonly TimeSpan ThreadReplyTime = TimeSpan.FromSeconds(30.0);
|
||||
private string m_BoardName;
|
||||
public BaseBulletinBoard(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
this.m_BoardName = "bulletin board";
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public BaseBulletinBoard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string BoardName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_BoardName;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_BoardName = value;
|
||||
}
|
||||
}
|
||||
public static bool CheckTime(DateTime time, TimeSpan range)
|
||||
{
|
||||
return (time + range) < DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public static string FormatTS(TimeSpan ts)
|
||||
{
|
||||
int totalSeconds = (int)ts.TotalSeconds;
|
||||
int seconds = totalSeconds % 60;
|
||||
int minutes = totalSeconds / 60;
|
||||
|
||||
if (minutes != 0 && seconds != 0)
|
||||
return String.Format("{0} minute{1} and {2} second{3}", minutes, minutes == 1 ? "" : "s", seconds, seconds == 1 ? "" : "s");
|
||||
else if (minutes != 0)
|
||||
return String.Format("{0} minute{1}", minutes, minutes == 1 ? "" : "s");
|
||||
else
|
||||
return String.Format("{0} second{1}", seconds, seconds == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
PacketHandlers.Register(0x71, 0, true, new OnPacketReceive(BBClientRequest));
|
||||
}
|
||||
|
||||
public static void BBClientRequest(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
int packetID = pvSrc.ReadByte();
|
||||
BaseBulletinBoard board = World.FindItem(pvSrc.ReadInt32()) as BaseBulletinBoard;
|
||||
|
||||
if (board == null || !board.CheckRange(from))
|
||||
return;
|
||||
|
||||
switch ( packetID )
|
||||
{
|
||||
case 3:
|
||||
BBRequestContent(from, board, pvSrc);
|
||||
break;
|
||||
case 4:
|
||||
BBRequestHeader(from, board, pvSrc);
|
||||
break;
|
||||
case 5:
|
||||
BBPostMessage(from, board, pvSrc);
|
||||
break;
|
||||
case 6:
|
||||
BBRemoveMessage(from, board, pvSrc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void BBRequestContent(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
BulletinMessage msg = World.FindItem(pvSrc.ReadInt32()) as BulletinMessage;
|
||||
|
||||
if (msg == null || msg.Parent != board)
|
||||
return;
|
||||
|
||||
from.Send(new BBMessageContent(board, msg));
|
||||
}
|
||||
|
||||
public static void BBRequestHeader(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
BulletinMessage msg = World.FindItem(pvSrc.ReadInt32()) as BulletinMessage;
|
||||
|
||||
if (msg == null || msg.Parent != board)
|
||||
return;
|
||||
|
||||
from.Send(new BBMessageHeader(board, msg));
|
||||
}
|
||||
|
||||
public static void BBPostMessage(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
BulletinMessage thread = World.FindItem(pvSrc.ReadInt32()) as BulletinMessage;
|
||||
|
||||
if (thread != null && thread.Parent != board)
|
||||
thread = null;
|
||||
|
||||
int breakout = 0;
|
||||
|
||||
while (thread != null && thread.Thread != null && breakout++ < 10)
|
||||
thread = thread.Thread;
|
||||
|
||||
DateTime lastPostTime = DateTime.MinValue;
|
||||
|
||||
if (board.GetLastPostTime(from, (thread == null), ref lastPostTime))
|
||||
{
|
||||
if (!CheckTime(lastPostTime, (thread == null ? ThreadCreateTime : ThreadReplyTime)))
|
||||
{
|
||||
if (thread == null)
|
||||
from.SendMessage("You must wait {0} before creating a new thread.", FormatTS(ThreadCreateTime));
|
||||
else
|
||||
from.SendMessage("You must wait {0} before replying to another thread.", FormatTS(ThreadReplyTime));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string subject = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte());
|
||||
|
||||
if (subject.Length == 0)
|
||||
return;
|
||||
|
||||
string[] lines = new string[pvSrc.ReadByte()];
|
||||
|
||||
if (lines.Length == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < lines.Length; ++i)
|
||||
lines[i] = pvSrc.ReadUTF8StringSafe(pvSrc.ReadByte());
|
||||
|
||||
board.PostMessage(from, thread, subject, lines);
|
||||
}
|
||||
|
||||
public static void BBRemoveMessage(Mobile from, BaseBulletinBoard board, PacketReader pvSrc)
|
||||
{
|
||||
BulletinMessage msg = World.FindItem(pvSrc.ReadInt32()) as BulletinMessage;
|
||||
|
||||
if (msg == null || msg.Parent != board)
|
||||
return;
|
||||
|
||||
if (from.AccessLevel < AccessLevel.GameMaster && msg.Poster != from)
|
||||
return;
|
||||
|
||||
msg.Delete();
|
||||
}
|
||||
|
||||
public virtual void Cleanup()
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= items.Count)
|
||||
continue;
|
||||
|
||||
BulletinMessage msg = items[i] as BulletinMessage;
|
||||
|
||||
if (msg == null)
|
||||
continue;
|
||||
|
||||
if (msg.Thread == null && CheckTime(msg.LastPostTime, ThreadDeletionTime))
|
||||
{
|
||||
msg.Delete();
|
||||
this.RecurseDelete(msg); // A root-level thread has expired
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool GetLastPostTime(Mobile poster, bool onlyCheckRoot, ref DateTime lastPostTime)
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
bool wasSet = false;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
BulletinMessage msg = items[i] as BulletinMessage;
|
||||
|
||||
if (msg == null || msg.Poster != poster)
|
||||
continue;
|
||||
|
||||
if (onlyCheckRoot && msg.Thread != null)
|
||||
continue;
|
||||
|
||||
if (msg.Time > lastPostTime)
|
||||
{
|
||||
wasSet = true;
|
||||
lastPostTime = msg.Time;
|
||||
}
|
||||
}
|
||||
|
||||
return wasSet;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (this.CheckRange(from))
|
||||
{
|
||||
this.Cleanup();
|
||||
|
||||
NetState state = from.NetState;
|
||||
|
||||
state.Send(new BBDisplayBoard(this));
|
||||
if (state.ContainerGridLines)
|
||||
state.Send(new ContainerContent6017(from, this));
|
||||
else
|
||||
state.Send(new ContainerContent(from, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CheckRange(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
return true;
|
||||
|
||||
return (from.Map == this.Map && from.InRange(this.GetWorldLocation(), 2));
|
||||
}
|
||||
|
||||
public void PostMessage(Mobile from, BulletinMessage thread, string subject, string[] lines)
|
||||
{
|
||||
if (thread != null)
|
||||
thread.LastPostTime = DateTime.UtcNow;
|
||||
|
||||
this.AddItem(new BulletinMessage(from, thread, subject, lines));
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((string)this.m_BoardName);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
this.m_BoardName = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RecurseDelete(BulletinMessage msg)
|
||||
{
|
||||
List<Item> found = new List<Item>();
|
||||
List<Item> items = this.Items;
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= items.Count)
|
||||
continue;
|
||||
|
||||
BulletinMessage check = items[i] as BulletinMessage;
|
||||
|
||||
if (check == null)
|
||||
continue;
|
||||
|
||||
if (check.Thread == msg)
|
||||
{
|
||||
check.Delete();
|
||||
found.Add(check);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < found.Count; ++i)
|
||||
this.RecurseDelete((BulletinMessage)found[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public class BulletinMessage : Item
|
||||
{
|
||||
private Mobile m_Poster;
|
||||
private string m_Subject;
|
||||
private DateTime m_Time, m_LastPostTime;
|
||||
private BulletinMessage m_Thread;
|
||||
private string m_PostedName;
|
||||
private int m_PostedBody;
|
||||
private int m_PostedHue;
|
||||
private BulletinEquip[] m_PostedEquip;
|
||||
private string[] m_Lines;
|
||||
public BulletinMessage(Mobile poster, BulletinMessage thread, string subject, string[] lines)
|
||||
: base(0xEB0)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Poster = poster;
|
||||
this.m_Subject = subject;
|
||||
this.m_Time = DateTime.UtcNow;
|
||||
this.m_LastPostTime = this.m_Time;
|
||||
this.m_Thread = thread;
|
||||
this.m_PostedName = this.m_Poster.Name;
|
||||
this.m_PostedBody = this.m_Poster.Body;
|
||||
this.m_PostedHue = this.m_Poster.Hue;
|
||||
this.m_Lines = lines;
|
||||
|
||||
List<BulletinEquip> list = new List<BulletinEquip>();
|
||||
|
||||
for (int i = 0; i < poster.Items.Count; ++i)
|
||||
{
|
||||
Item item = poster.Items[i];
|
||||
|
||||
if (item.Layer >= Layer.OneHanded && item.Layer <= Layer.Mount)
|
||||
list.Add(new BulletinEquip(item.ItemID, item.Hue));
|
||||
}
|
||||
|
||||
this.m_PostedEquip = list.ToArray();
|
||||
}
|
||||
|
||||
public BulletinMessage(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public Mobile Poster
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Poster;
|
||||
}
|
||||
}
|
||||
public BulletinMessage Thread
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Thread;
|
||||
}
|
||||
}
|
||||
public string Subject
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Subject;
|
||||
}
|
||||
}
|
||||
public DateTime Time
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Time;
|
||||
}
|
||||
}
|
||||
public DateTime LastPostTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_LastPostTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_LastPostTime = value;
|
||||
}
|
||||
}
|
||||
public string PostedName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_PostedName;
|
||||
}
|
||||
}
|
||||
public int PostedBody
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_PostedBody;
|
||||
}
|
||||
}
|
||||
public int PostedHue
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_PostedHue;
|
||||
}
|
||||
}
|
||||
public BulletinEquip[] PostedEquip
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_PostedEquip;
|
||||
}
|
||||
}
|
||||
public string[] Lines
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Lines;
|
||||
}
|
||||
}
|
||||
public string GetTimeAsString()
|
||||
{
|
||||
return this.m_Time.ToString("MMM dd, yyyy");
|
||||
}
|
||||
|
||||
public override bool CheckTarget(Mobile from, Server.Targeting.Target targ, object targeted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsAccessibleTo(Mobile check)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write((Mobile)this.m_Poster);
|
||||
writer.Write((string)this.m_Subject);
|
||||
writer.Write((DateTime)this.m_Time);
|
||||
writer.Write((DateTime)this.m_LastPostTime);
|
||||
writer.Write((bool)(this.m_Thread != null));
|
||||
writer.Write((Item)this.m_Thread);
|
||||
writer.Write((string)this.m_PostedName);
|
||||
writer.Write((int)this.m_PostedBody);
|
||||
writer.Write((int)this.m_PostedHue);
|
||||
|
||||
writer.Write((int)this.m_PostedEquip.Length);
|
||||
|
||||
for (int i = 0; i < this.m_PostedEquip.Length; ++i)
|
||||
{
|
||||
writer.Write((int)this.m_PostedEquip[i].itemID);
|
||||
writer.Write((int)this.m_PostedEquip[i].hue);
|
||||
}
|
||||
|
||||
writer.Write((int)this.m_Lines.Length);
|
||||
|
||||
for (int i = 0; i < this.m_Lines.Length; ++i)
|
||||
writer.Write((string)this.m_Lines[i]);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
this.m_Poster = reader.ReadMobile();
|
||||
this.m_Subject = reader.ReadString();
|
||||
this.m_Time = reader.ReadDateTime();
|
||||
this.m_LastPostTime = reader.ReadDateTime();
|
||||
bool hasThread = reader.ReadBool();
|
||||
this.m_Thread = reader.ReadItem() as BulletinMessage;
|
||||
this.m_PostedName = reader.ReadString();
|
||||
this.m_PostedBody = reader.ReadInt();
|
||||
this.m_PostedHue = reader.ReadInt();
|
||||
|
||||
this.m_PostedEquip = new BulletinEquip[reader.ReadInt()];
|
||||
|
||||
for (int i = 0; i < this.m_PostedEquip.Length; ++i)
|
||||
{
|
||||
this.m_PostedEquip[i].itemID = reader.ReadInt();
|
||||
this.m_PostedEquip[i].hue = reader.ReadInt();
|
||||
}
|
||||
|
||||
this.m_Lines = new string[reader.ReadInt()];
|
||||
|
||||
for (int i = 0; i < this.m_Lines.Length; ++i)
|
||||
this.m_Lines[i] = reader.ReadString();
|
||||
|
||||
if (hasThread && this.m_Thread == null)
|
||||
this.Delete();
|
||||
|
||||
if (version == 0)
|
||||
ValidationQueue<BulletinMessage>.Add(this);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (!(this.Parent is BulletinBoard && ((BulletinBoard)this.Parent).Items.Contains(this)))
|
||||
this.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public class BBDisplayBoard : Packet
|
||||
{
|
||||
public BBDisplayBoard(BaseBulletinBoard board)
|
||||
: base(0x71)
|
||||
{
|
||||
string name = board.BoardName;
|
||||
|
||||
if (name == null)
|
||||
name = "";
|
||||
|
||||
this.EnsureCapacity(38);
|
||||
|
||||
byte[] buffer = Utility.UTF8.GetBytes(name);
|
||||
|
||||
this.m_Stream.Write((byte)0x00); // PacketID
|
||||
this.m_Stream.Write((int)board.Serial); // Bulletin board serial
|
||||
|
||||
// Bulletin board name
|
||||
if (buffer.Length >= 29)
|
||||
{
|
||||
this.m_Stream.Write(buffer, 0, 29);
|
||||
this.m_Stream.Write((byte)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Stream.Write(buffer, 0, buffer.Length);
|
||||
this.m_Stream.Fill(30 - buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageHeader : Packet
|
||||
{
|
||||
public BBMessageHeader(BaseBulletinBoard board, BulletinMessage msg)
|
||||
: base(0x71)
|
||||
{
|
||||
string poster = this.SafeString(msg.PostedName);
|
||||
string subject = this.SafeString(msg.Subject);
|
||||
string time = this.SafeString(msg.GetTimeAsString());
|
||||
|
||||
this.EnsureCapacity(22 + poster.Length + subject.Length + time.Length);
|
||||
|
||||
this.m_Stream.Write((byte)0x01); // PacketID
|
||||
this.m_Stream.Write((int)board.Serial); // Bulletin board serial
|
||||
this.m_Stream.Write((int)msg.Serial); // Message serial
|
||||
|
||||
BulletinMessage thread = msg.Thread;
|
||||
|
||||
if (thread == null)
|
||||
this.m_Stream.Write((int)0); // Thread serial--root
|
||||
else
|
||||
this.m_Stream.Write((int)thread.Serial); // Thread serial--parent
|
||||
|
||||
this.WriteString(poster);
|
||||
this.WriteString(subject);
|
||||
this.WriteString(time);
|
||||
}
|
||||
|
||||
public void WriteString(string v)
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes(v);
|
||||
int len = buffer.Length + 1;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
this.m_Stream.Write((byte)len);
|
||||
this.m_Stream.Write(buffer, 0, len - 1);
|
||||
this.m_Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
public string SafeString(string v)
|
||||
{
|
||||
if (v == null)
|
||||
return String.Empty;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageContent : Packet
|
||||
{
|
||||
public BBMessageContent(BaseBulletinBoard board, BulletinMessage msg)
|
||||
: base(0x71)
|
||||
{
|
||||
string poster = this.SafeString(msg.PostedName);
|
||||
string subject = this.SafeString(msg.Subject);
|
||||
string time = this.SafeString(msg.GetTimeAsString());
|
||||
|
||||
this.EnsureCapacity(22 + poster.Length + subject.Length + time.Length);
|
||||
|
||||
this.m_Stream.Write((byte)0x02); // PacketID
|
||||
this.m_Stream.Write((int)board.Serial); // Bulletin board serial
|
||||
this.m_Stream.Write((int)msg.Serial); // Message serial
|
||||
|
||||
this.WriteString(poster);
|
||||
this.WriteString(subject);
|
||||
this.WriteString(time);
|
||||
|
||||
this.m_Stream.Write((short)msg.PostedBody);
|
||||
this.m_Stream.Write((short)msg.PostedHue);
|
||||
|
||||
int len = msg.PostedEquip.Length;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
this.m_Stream.Write((byte)len);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
BulletinEquip eq = msg.PostedEquip[i];
|
||||
|
||||
this.m_Stream.Write((short)eq.itemID);
|
||||
this.m_Stream.Write((short)eq.hue);
|
||||
}
|
||||
|
||||
len = msg.Lines.Length;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
this.m_Stream.Write((byte)len);
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
this.WriteString(msg.Lines[i], true);
|
||||
}
|
||||
|
||||
public void WriteString(string v)
|
||||
{
|
||||
this.WriteString(v, false);
|
||||
}
|
||||
|
||||
public void WriteString(string v, bool padding)
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes(v);
|
||||
int tail = padding ? 2 : 1;
|
||||
int len = buffer.Length + tail;
|
||||
|
||||
if (len > 255)
|
||||
len = 255;
|
||||
|
||||
this.m_Stream.Write((byte)len);
|
||||
this.m_Stream.Write(buffer, 0, len - tail);
|
||||
|
||||
if (padding)
|
||||
this.m_Stream.Write((short)0); // padding compensates for a client bug
|
||||
else
|
||||
this.m_Stream.Write((byte)0);
|
||||
}
|
||||
|
||||
public string SafeString(string v)
|
||||
{
|
||||
if (v == null)
|
||||
return String.Empty;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
236
Scripts/Items/Functional/Campfire.cs
Normal file
236
Scripts/Items/Functional/Campfire.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum CampfireStatus
|
||||
{
|
||||
Burning,
|
||||
Extinguishing,
|
||||
Off
|
||||
}
|
||||
|
||||
public class Campfire : Item
|
||||
{
|
||||
public static readonly int SecureRange = 7;
|
||||
private static readonly Hashtable m_Table = new Hashtable();
|
||||
private readonly Timer m_Timer;
|
||||
private readonly DateTime m_Created;
|
||||
private readonly ArrayList m_Entries;
|
||||
public Campfire()
|
||||
: base(0xDE3)
|
||||
{
|
||||
this.Movable = false;
|
||||
this.Light = LightType.Circle300;
|
||||
|
||||
this.m_Entries = new ArrayList();
|
||||
|
||||
this.m_Created = DateTime.UtcNow;
|
||||
this.m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), new TimerCallback(OnTick));
|
||||
}
|
||||
|
||||
public Campfire(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Created
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Created;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CampfireStatus Status
|
||||
{
|
||||
get
|
||||
{
|
||||
switch ( this.ItemID )
|
||||
{
|
||||
case 0xDE3:
|
||||
return CampfireStatus.Burning;
|
||||
|
||||
case 0xDE9:
|
||||
return CampfireStatus.Extinguishing;
|
||||
|
||||
default:
|
||||
return CampfireStatus.Off;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.Status == value)
|
||||
return;
|
||||
|
||||
switch ( value )
|
||||
{
|
||||
case CampfireStatus.Burning:
|
||||
this.ItemID = 0xDE3;
|
||||
this.Light = LightType.Circle300;
|
||||
break;
|
||||
case CampfireStatus.Extinguishing:
|
||||
this.ItemID = 0xDE9;
|
||||
this.Light = LightType.Circle150;
|
||||
break;
|
||||
default:
|
||||
this.ItemID = 0xDEA;
|
||||
this.Light = LightType.ArchedWindowEast;
|
||||
this.ClearEntries();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static CampfireEntry GetEntry(Mobile player)
|
||||
{
|
||||
return (CampfireEntry)m_Table[player];
|
||||
}
|
||||
|
||||
public static void RemoveEntry(CampfireEntry entry)
|
||||
{
|
||||
m_Table.Remove(entry.Player);
|
||||
entry.Fire.m_Entries.Remove(entry);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
this.m_Timer.Stop();
|
||||
|
||||
this.ClearEntries();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
this.Delete();
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
TimeSpan age = now - this.Created;
|
||||
|
||||
if (age >= TimeSpan.FromSeconds(100.0))
|
||||
this.Delete();
|
||||
else if (age >= TimeSpan.FromSeconds(90.0))
|
||||
this.Status = CampfireStatus.Off;
|
||||
else if (age >= TimeSpan.FromSeconds(60.0))
|
||||
this.Status = CampfireStatus.Extinguishing;
|
||||
|
||||
if (this.Status == CampfireStatus.Off || this.Deleted)
|
||||
return;
|
||||
|
||||
foreach (CampfireEntry entry in new ArrayList(this.m_Entries))
|
||||
{
|
||||
if (!entry.Valid || entry.Player.NetState == null)
|
||||
{
|
||||
RemoveEntry(entry);
|
||||
}
|
||||
else if (!entry.Safe && now - entry.Start >= TimeSpan.FromSeconds(30.0))
|
||||
{
|
||||
entry.Safe = true;
|
||||
entry.Player.SendLocalizedMessage(500621); // The camp is now secure.
|
||||
}
|
||||
}
|
||||
|
||||
IPooledEnumerable eable = this.GetClientsInRange(SecureRange);
|
||||
|
||||
foreach (NetState state in eable)
|
||||
{
|
||||
PlayerMobile pm = state.Mobile as PlayerMobile;
|
||||
|
||||
if (pm != null && GetEntry(pm) == null)
|
||||
{
|
||||
CampfireEntry entry = new CampfireEntry(pm, this);
|
||||
|
||||
m_Table[pm] = entry;
|
||||
this.m_Entries.Add(entry);
|
||||
|
||||
pm.SendLocalizedMessage(500620); // You feel it would take a few moments to secure your camp.
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private void ClearEntries()
|
||||
{
|
||||
if (this.m_Entries == null)
|
||||
return;
|
||||
|
||||
foreach (CampfireEntry entry in new ArrayList(this.m_Entries))
|
||||
{
|
||||
RemoveEntry(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CampfireEntry
|
||||
{
|
||||
private readonly PlayerMobile m_Player;
|
||||
private readonly Campfire m_Fire;
|
||||
private readonly DateTime m_Start;
|
||||
private bool m_Safe;
|
||||
public CampfireEntry(PlayerMobile player, Campfire fire)
|
||||
{
|
||||
this.m_Player = player;
|
||||
this.m_Fire = fire;
|
||||
this.m_Start = DateTime.UtcNow;
|
||||
this.m_Safe = false;
|
||||
}
|
||||
|
||||
public PlayerMobile Player
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Player;
|
||||
}
|
||||
}
|
||||
public Campfire Fire
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Fire;
|
||||
}
|
||||
}
|
||||
public DateTime Start
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Start;
|
||||
}
|
||||
}
|
||||
public bool Valid
|
||||
{
|
||||
get
|
||||
{
|
||||
return !this.Fire.Deleted && this.Fire.Status != CampfireStatus.Off && this.Player.Map == this.Fire.Map && this.Player.InRange(this.Fire, Campfire.SecureRange);
|
||||
}
|
||||
}
|
||||
public bool Safe
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Valid && this.m_Safe;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Safe = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
513
Scripts/Items/Functional/ChickenCoop.cs
Normal file
513
Scripts/Items/Functional/ChickenCoop.cs
Normal file
@@ -0,0 +1,513 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x4513, 0x4514)]
|
||||
public class ChickenCoop : Item, ISecurable, IChopable
|
||||
{
|
||||
public static readonly int MaxStables = 3;
|
||||
|
||||
public override int LabelNumber { get { return 1112570; } } // a chicken coop
|
||||
|
||||
private SecureLevel m_Level;
|
||||
private Dictionary<Mobile, List<BaseCreature>> m_Stored = new Dictionary<Mobile, List<BaseCreature>>();
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level
|
||||
{
|
||||
get { return m_Level; }
|
||||
set { m_Level = value; }
|
||||
}
|
||||
|
||||
public Dictionary<Mobile, List<BaseCreature>> Stored { get { return m_Stored; } }
|
||||
|
||||
[Constructable]
|
||||
public ChickenCoop()
|
||||
: base(0x4513)
|
||||
{
|
||||
Weight = 20;
|
||||
m_Level = SecureLevel.CoOwners;
|
||||
}
|
||||
|
||||
public void OnChop(Mobile from)
|
||||
{
|
||||
if (CheckAccess(from))
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x3B3);
|
||||
from.SendLocalizedMessage(500461); // You destroy the item.
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
if (m_Stored != null && m_Stored.Count > 0)
|
||||
{
|
||||
List<List<BaseCreature>> masterList = new List<List<BaseCreature>>(m_Stored.Values);
|
||||
|
||||
for (int i = 0; i < masterList.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < masterList[i].Count; j++)
|
||||
{
|
||||
if (masterList[i][j] != null && !masterList[i][j].Deleted)
|
||||
masterList[i][j].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
m_Stored.Clear();
|
||||
}
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (CheckAccess(from))
|
||||
{
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
|
||||
list.Add(new StableEntry(this, from));
|
||||
|
||||
if (m_Stored.ContainsKey(from) && m_Stored[from].Count > 0)
|
||||
list.Add(new ClaimAllEntry(this, from));
|
||||
}
|
||||
}
|
||||
|
||||
private class StableEntry : ContextMenuEntry
|
||||
{
|
||||
private ChickenCoop m_Coop;
|
||||
private Mobile m_From;
|
||||
|
||||
public StableEntry(ChickenCoop coop, Mobile from)
|
||||
: base(6126, 12)
|
||||
{
|
||||
m_Coop = coop;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Coop.BeginStable(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
private class ClaimAllEntry : ContextMenuEntry
|
||||
{
|
||||
private ChickenCoop m_Coop;
|
||||
private Mobile m_From;
|
||||
|
||||
public ClaimAllEntry(ChickenCoop coop, Mobile from)
|
||||
: base(6127, 12)
|
||||
{
|
||||
m_Coop = coop;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Coop.Claim(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
public ChickenCoop(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ForceShowProperties { get { return ObjectPropertyList.Enabled; } }
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.AddNameProperties(list);
|
||||
}
|
||||
|
||||
private class ClaimListGump : Gump
|
||||
{
|
||||
private ChickenCoop m_Post;
|
||||
private Mobile m_From;
|
||||
private List<BaseCreature> m_List;
|
||||
|
||||
public ClaimListGump(ChickenCoop post, Mobile from, List<BaseCreature> list)
|
||||
: base(50, 50)
|
||||
{
|
||||
m_Post = post;
|
||||
m_From = from;
|
||||
m_List = list;
|
||||
|
||||
from.CloseGump(typeof(ClaimListGump));
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 325, 50 + (list.Count * 20), 9250);
|
||||
AddAlphaRegion(5, 5, 315, 40 + (list.Count * 20));
|
||||
|
||||
AddHtml(15, 15, 275, 20, "<BASEFONT COLOR=#FFFFFF>Select a pet to retrieve from the stables:</BASEFONT>", false, false);
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
BaseCreature pet = list[i];
|
||||
|
||||
if (pet == null || pet.Deleted)
|
||||
continue;
|
||||
|
||||
AddButton(15, 39 + (i * 20), 10006, 10006, i + 1, GumpButtonType.Reply, 0);
|
||||
AddHtml(32, 35 + (i * 20), 275, 18, String.Format("<BASEFONT COLOR=#C0C0EE>{0}</BASEFONT>", pet.Name), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
int index = info.ButtonID - 1;
|
||||
|
||||
if (index >= 0 && index < m_List.Count)
|
||||
m_Post.EndClaimList(m_From, m_List[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetMaxStabled(Mobile from)
|
||||
{
|
||||
int max = 3;
|
||||
return max;
|
||||
}
|
||||
|
||||
private class StableTarget : Target
|
||||
{
|
||||
private ChickenCoop m_Post;
|
||||
|
||||
public StableTarget(ChickenCoop post)
|
||||
: base(12, false, TargetFlags.None)
|
||||
{
|
||||
m_Post = post;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is ChickenLizard || targeted is Chicken || targeted is BattleChickenLizard)
|
||||
m_Post.EndStable(from, (BaseCreature)targeted);
|
||||
else if (targeted == from)
|
||||
from.SendLocalizedMessage(502672); // HA HA HA! Sorry, I am not an inn.
|
||||
else
|
||||
from.SendLocalizedMessage(1112558); // You may only stable chickens in the chicken coop.
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginClaimList(Mobile from)
|
||||
{
|
||||
if (Deleted || !from.CheckAlive() || !m_Stored.ContainsKey(from) || m_Stored[from] == null)
|
||||
return;
|
||||
|
||||
List<BaseCreature> stabled = m_Stored[from];
|
||||
|
||||
for (int i = 0; i < stabled.Count; i++)
|
||||
{
|
||||
BaseCreature pet = stabled[i] as BaseCreature;
|
||||
|
||||
if (pet == null || pet.Deleted)
|
||||
{
|
||||
pet.IsStabled = false;
|
||||
stabled.RemoveAt(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (stabled.Count > 0)
|
||||
from.SendGump(new ClaimListGump(this, from, stabled));
|
||||
else
|
||||
from.SendLocalizedMessage(502671); // But I have no animals stabled with me at the moment!
|
||||
}
|
||||
|
||||
public void EndClaimList(Mobile from, BaseCreature pet)
|
||||
{
|
||||
if (Deleted || !from.CheckAlive() || !m_Stored.ContainsKey(from))
|
||||
return;
|
||||
|
||||
if ((from.Followers + pet.ControlSlots) <= from.FollowersMax)
|
||||
{
|
||||
pet.SetControlMaster(from);
|
||||
|
||||
if (pet.Summoned)
|
||||
pet.SummonMaster = from;
|
||||
|
||||
pet.ControlTarget = from;
|
||||
pet.ControlOrder = OrderType.Follow;
|
||||
|
||||
pet.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
pet.IsStabled = false;
|
||||
|
||||
if (m_Stored[from].Contains(pet))
|
||||
m_Stored[from].Remove(pet);
|
||||
|
||||
from.SendLocalizedMessage(1042559); // Here you go... and good day to you!
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1049612, pet.Name); // ~1_NAME~ remained in the stables because you have too many followers.
|
||||
}
|
||||
}
|
||||
|
||||
public void BeginStable(Mobile from)
|
||||
{
|
||||
if (Deleted || !from.CheckAlive() || !CanUse() || !CheckAccess(from))
|
||||
return;
|
||||
|
||||
else if (GetCount() >= MaxStables)
|
||||
{
|
||||
from.SendLocalizedMessage(1114325); // There is no more room in your chicken coop!
|
||||
}
|
||||
else
|
||||
{
|
||||
/*from.SendLocalizedMessage(1042558); I charge 30 gold per pet for a real week's stable time.
|
||||
* I will withdraw it from thy bank account.
|
||||
* Which animal wouldst thou like to stable here?
|
||||
*/
|
||||
|
||||
from.Target = new StableTarget(this);
|
||||
from.SendLocalizedMessage(1112559); // Which chicken do you wish to stable?
|
||||
}
|
||||
}
|
||||
|
||||
private int GetCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (List<BaseCreature> bcList in m_Stored.Values)
|
||||
{
|
||||
if(bcList != null)
|
||||
count += bcList.Count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void EndStable(Mobile from, BaseCreature pet)
|
||||
{
|
||||
if (Deleted || !from.CheckAlive() || !CanUse() || !CheckAccess(from))
|
||||
return;
|
||||
|
||||
else if (!pet.Controlled || pet.ControlMaster != from)
|
||||
{
|
||||
from.SendLocalizedMessage(1042562); // You do not own that pet!
|
||||
}
|
||||
else if (pet.IsDeadPet)
|
||||
{
|
||||
from.SendLocalizedMessage(1049668); // Living pets only, please.
|
||||
}
|
||||
else if (pet.Summoned)
|
||||
{
|
||||
from.SendLocalizedMessage(502673); // I can not stable summoned creatures.
|
||||
}
|
||||
#region Mondain's Legacy
|
||||
else if (pet.Allured)
|
||||
{
|
||||
from.SendLocalizedMessage(1048053); // You can't stable that!
|
||||
}
|
||||
#endregion
|
||||
else if (pet.Body.IsHuman)
|
||||
{
|
||||
from.SendLocalizedMessage(502672); // HA HA HA! Sorry, I am not an inn.
|
||||
}
|
||||
else if (pet.Combatant != null && pet.InRange(pet.Combatant, 12) && pet.Map == pet.Combatant.Map)
|
||||
{
|
||||
from.SendLocalizedMessage(1042564); // I'm sorry. Your pet seems to be busy.
|
||||
}
|
||||
else if (GetCount() >= MaxStables)
|
||||
{
|
||||
from.SendLocalizedMessage(1114325); // There is no more room in your chicken coop!
|
||||
}
|
||||
else
|
||||
{
|
||||
pet.ControlTarget = null;
|
||||
pet.ControlOrder = OrderType.Stay;
|
||||
pet.Internalize();
|
||||
|
||||
pet.SetControlMaster(null);
|
||||
pet.SummonMaster = null;
|
||||
|
||||
pet.IsStabled = true;
|
||||
|
||||
if (Core.SE)
|
||||
pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully happy
|
||||
|
||||
if (!m_Stored.ContainsKey(from))
|
||||
m_Stored.Add(from, new List<BaseCreature>());
|
||||
|
||||
if (!m_Stored[from].Contains(pet))
|
||||
m_Stored[from].Add(pet);
|
||||
|
||||
from.SendMessage("Your chicken has been stabled.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Claim(Mobile from)
|
||||
{
|
||||
if (Deleted || !from.CheckAlive() || !m_Stored.ContainsKey(from))
|
||||
return;
|
||||
|
||||
bool claimed = false;
|
||||
int stabledCount = 0;
|
||||
|
||||
List<BaseCreature> stabled = m_Stored[from];
|
||||
|
||||
for (int i = 0; i < stabled.Count; ++i)
|
||||
{
|
||||
BaseCreature pet = stabled[i] as BaseCreature;
|
||||
|
||||
if (pet == null || pet.Deleted)
|
||||
{
|
||||
pet.IsStabled = false;
|
||||
stabled.RemoveAt(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
++stabledCount;
|
||||
|
||||
if ((from.Followers + pet.ControlSlots) <= from.FollowersMax)
|
||||
{
|
||||
pet.SetControlMaster(from);
|
||||
|
||||
if (pet.Summoned)
|
||||
pet.SummonMaster = from;
|
||||
|
||||
pet.ControlTarget = from;
|
||||
pet.ControlOrder = OrderType.Follow;
|
||||
|
||||
pet.MoveToWorld(from.Location, from.Map);
|
||||
|
||||
pet.IsStabled = false;
|
||||
|
||||
if (Core.SE)
|
||||
pet.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
|
||||
|
||||
stabled.RemoveAt(i);
|
||||
--i;
|
||||
|
||||
claimed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1049612, pet.Name); // ~1_NAME~ remained in the stables because you have too many followers.
|
||||
}
|
||||
}
|
||||
|
||||
if (claimed)
|
||||
{
|
||||
from.SendLocalizedMessage(1042559); // Here you go... and good day to you!
|
||||
}
|
||||
|
||||
else if (stabledCount == 0)
|
||||
from.SendLocalizedMessage(502671); // But I have no animals stabled with me at the moment!
|
||||
}
|
||||
|
||||
public bool CheckAccess(Mobile m)
|
||||
{
|
||||
BaseHouse h = BaseHouse.FindHouseAt(this);
|
||||
|
||||
return h != null && h.HasSecureAccess(m, m_Level);
|
||||
}
|
||||
|
||||
public bool CanUse()
|
||||
{
|
||||
return IsLockedDown;
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return true; } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
if (CheckAccess(e.Mobile) && IsLockedDown)
|
||||
{
|
||||
if (!e.Handled && e.HasKeyword(0x0008))
|
||||
{
|
||||
e.Handled = true;
|
||||
BeginStable(e.Mobile);
|
||||
}
|
||||
else if (!e.Handled && e.HasKeyword(0x0009))
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if (!Insensitive.Equals(e.Speech, "claim"))
|
||||
BeginClaimList(e.Mobile);
|
||||
else
|
||||
Claim(e.Mobile);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)2); // version
|
||||
|
||||
writer.Write((int)m_Level);
|
||||
writer.Write(m_Stored.Count);
|
||||
foreach (KeyValuePair<Mobile, List<BaseCreature>> kvp in m_Stored)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value.Count);
|
||||
|
||||
foreach(BaseCreature bc in kvp.Value)
|
||||
writer.Write(bc);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (Weight == 1)
|
||||
Weight = 20;
|
||||
|
||||
m_Level = (SecureLevel)reader.ReadInt();
|
||||
|
||||
if (version == 1)
|
||||
return;
|
||||
|
||||
int c = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
Mobile owner = reader.ReadMobile();
|
||||
int count = reader.ReadInt();
|
||||
List<BaseCreature> list = new List<BaseCreature>();
|
||||
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
Mobile chicken = reader.ReadMobile();
|
||||
|
||||
if (chicken != null && chicken is BaseCreature)
|
||||
{
|
||||
var bc = chicken as BaseCreature;
|
||||
bc.IsStabled = true;
|
||||
list.Add(bc);
|
||||
}
|
||||
}
|
||||
|
||||
if (owner != null && list.Count > 0)
|
||||
m_Stored.Add(owner, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
433
Scripts/Items/Functional/ChickenLizardEgg.cs
Normal file
433
Scripts/Items/Functional/ChickenLizardEgg.cs
Normal file
@@ -0,0 +1,433 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum EggStage
|
||||
{
|
||||
New,
|
||||
Stage1,
|
||||
Stage2,
|
||||
Mature,
|
||||
Burnt
|
||||
}
|
||||
|
||||
public enum Dryness
|
||||
{
|
||||
Moist,
|
||||
Dry,
|
||||
Parched,
|
||||
Dehydrated
|
||||
}
|
||||
|
||||
public class ChickenLizardEgg : Item
|
||||
{
|
||||
public virtual bool CanMutate { get { return true; } }
|
||||
|
||||
private DateTime m_IncubationStart;
|
||||
private TimeSpan m_TotalIncubationTime;
|
||||
private bool m_Incubating;
|
||||
private EggStage m_Stage;
|
||||
private int m_WaterLevel;
|
||||
private bool m_IsBattleChicken;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime IncubationStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_IncubationStart;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_IncubationStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan TotalIncubationTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_TotalIncubationTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_TotalIncubationTime = value;
|
||||
m_IncubationStart = DateTime.UtcNow;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Incubating
|
||||
{
|
||||
get { return m_Incubating; }
|
||||
set
|
||||
{
|
||||
if (m_Incubating && !value)
|
||||
{
|
||||
if (m_IncubationStart < DateTime.UtcNow)
|
||||
TotalIncubationTime += DateTime.UtcNow - m_IncubationStart;
|
||||
}
|
||||
|
||||
m_Incubating = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public EggStage Stage { get { return m_Stage; } set { m_Stage = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Dryness Dryness
|
||||
{
|
||||
get
|
||||
{
|
||||
int v = (int)m_Stage - m_WaterLevel;
|
||||
|
||||
if(v >= 2 && m_WaterLevel == 0)
|
||||
return Dryness.Dehydrated;
|
||||
if(v >= 2)
|
||||
return Dryness.Parched;
|
||||
if(v >= 1)
|
||||
return Dryness.Dry;
|
||||
|
||||
return Dryness.Moist;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsBattleChicken
|
||||
{
|
||||
get { return m_IsBattleChicken; }
|
||||
set { m_IsBattleChicken = value; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ChickenLizardEgg() : base(0x41BD)
|
||||
{
|
||||
m_Incubating = false;
|
||||
m_TotalIncubationTime = TimeSpan.Zero;
|
||||
m_Stage = EggStage.New;
|
||||
}
|
||||
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
int c = 1112468;
|
||||
|
||||
if (m_Stage == EggStage.Mature)
|
||||
c = m_IsBattleChicken ? 1112468 : 1112467;
|
||||
else if (m_Stage == EggStage.Burnt)
|
||||
c = 1112466;
|
||||
else
|
||||
{
|
||||
switch (Dryness)
|
||||
{
|
||||
case Dryness.Moist: c = 1112462; break;
|
||||
case Dryness.Dry: c = 1112463; break;
|
||||
case Dryness.Parched: c = 1112464; break;
|
||||
case Dryness.Dehydrated: c = 1112465; break;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
|
||||
{
|
||||
bool check = base.DropToMobile(from, target, p);
|
||||
|
||||
if (check && m_Incubating)
|
||||
Incubating = false;
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
public override bool DropToWorld(Mobile from, Point3D p)
|
||||
{
|
||||
bool check = base.DropToWorld(from, p);
|
||||
|
||||
if (check && m_Incubating)
|
||||
Incubating = false;
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
public override bool DropToItem(Mobile from, Item target, Point3D p)
|
||||
{
|
||||
bool check = base.DropToItem(from, target, p);
|
||||
|
||||
if (check && !(Parent is Incubator) && m_Incubating)
|
||||
Incubating = false;
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
public override void OnItemLifted(Mobile from, Item item)
|
||||
{
|
||||
if (m_Incubating)
|
||||
Incubating = false;
|
||||
|
||||
base.OnItemLifted(from, item);
|
||||
}
|
||||
|
||||
public void CheckStatus()
|
||||
{
|
||||
if (m_Stage == EggStage.Burnt)
|
||||
return;
|
||||
|
||||
if(m_Incubating && m_IncubationStart < DateTime.UtcNow)
|
||||
TotalIncubationTime += DateTime.UtcNow - m_IncubationStart;
|
||||
|
||||
if(m_TotalIncubationTime > TimeSpan.FromHours(24) && m_Stage == EggStage.New) //from new to stage 1
|
||||
{
|
||||
IncreaseStage();
|
||||
//Nothing, egg goes to stage 2 regardless if its watered or not
|
||||
}
|
||||
else if (m_TotalIncubationTime >= TimeSpan.FromHours(48) && m_Stage == EggStage.Stage1) //from stage 1 to stage 2
|
||||
{
|
||||
if(Dryness >= Dryness.Parched)
|
||||
{
|
||||
if(Utility.RandomBool())
|
||||
BurnEgg();
|
||||
}
|
||||
|
||||
IncreaseStage();
|
||||
}
|
||||
else if (m_TotalIncubationTime >= TimeSpan.FromHours(72) && m_Stage == EggStage.Stage2) //from stage 2 to mature egg
|
||||
{
|
||||
if(Dryness >= Dryness.Parched)
|
||||
{
|
||||
if(.25 < Utility.RandomDouble())
|
||||
BurnEgg();
|
||||
}
|
||||
|
||||
IncreaseStage();
|
||||
}
|
||||
else if (m_TotalIncubationTime >= TimeSpan.FromHours(120) && m_Stage == EggStage.Mature)
|
||||
{
|
||||
BurnEgg();
|
||||
IncreaseStage();
|
||||
}
|
||||
}
|
||||
|
||||
public void Pour(Mobile from, BaseBeverage bev)
|
||||
{
|
||||
if (!bev.IsEmpty && bev.Pourable && bev.Content == BeverageType.Water && bev.ValidateUse(from, false))
|
||||
{
|
||||
if (m_Stage == EggStage.Burnt)
|
||||
from.SendMessage("You decide not to water the burnt egg.");
|
||||
else if (m_WaterLevel < (int)m_Stage)
|
||||
{
|
||||
bev.Quantity--;
|
||||
|
||||
m_WaterLevel++;
|
||||
from.PlaySound(0x4E);
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
else
|
||||
from.SendMessage("You decide not to water the egg since it doesn't need it.");
|
||||
}
|
||||
}
|
||||
|
||||
public void IncreaseStage()
|
||||
{
|
||||
if (m_Stage != EggStage.Burnt)
|
||||
m_Stage++;
|
||||
|
||||
switch(m_Stage)
|
||||
{
|
||||
default:
|
||||
case EggStage.New:
|
||||
case EggStage.Stage1:
|
||||
ItemID = 0x41BE;
|
||||
break;
|
||||
case EggStage.Stage2:
|
||||
ItemID = 0x41BF;
|
||||
break;
|
||||
case EggStage.Mature:
|
||||
{
|
||||
ItemID = 0x41BF;
|
||||
|
||||
Hue = 555;
|
||||
|
||||
double chance = .10;
|
||||
if (Dryness == Dryness.Dry)
|
||||
chance = .05;
|
||||
else if (Dryness == Dryness.Parched)
|
||||
chance = .01;
|
||||
else if (Dryness == Dryness.Dehydrated)
|
||||
chance = 0;
|
||||
|
||||
|
||||
if (CanMutate && chance >= Utility.RandomDouble())
|
||||
{
|
||||
m_IsBattleChicken = true;
|
||||
Hue = GetRandomHiryuHue();
|
||||
}
|
||||
else
|
||||
Hue = 555;
|
||||
|
||||
break;
|
||||
}
|
||||
case EggStage.Burnt:
|
||||
ItemID = 0x41BF;
|
||||
Hue = 2026;
|
||||
break;
|
||||
}
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
||||
private int GetRandomHiryuHue()
|
||||
{
|
||||
switch (Utility.Random(12))
|
||||
{
|
||||
case 0: return 1173; //Cyan
|
||||
case 1: return 1160; //Strong Cyan
|
||||
case 2: return 675; //Light Green
|
||||
case 3: return 72; //Strong Green
|
||||
case 4: return 2213; //Gold
|
||||
case 5: return 1463; //Strong Yellow
|
||||
case 6: return 2425; //Agapite
|
||||
case 7: return 26; //Strong Purple
|
||||
case 8: return 1151; //Ice Green
|
||||
case 9: return 1152; //Ice Blue
|
||||
case 10: return 101; //Light Blue
|
||||
case 11: return 1159; //yellow blue
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void BurnEgg()
|
||||
{
|
||||
m_Stage = EggStage.Burnt;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
if(m_Stage == EggStage.Mature)
|
||||
from.SendGump(new ConfirmHatchGump1(from, this));
|
||||
else
|
||||
from.SendGump(new ConfirmHatchGump2(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public void TryHatchEgg(Mobile from)
|
||||
{
|
||||
if(m_Stage == EggStage.Mature)
|
||||
OnHatch(from);
|
||||
else
|
||||
CrumbleEgg(from);
|
||||
}
|
||||
|
||||
public virtual void OnHatch(Mobile from)
|
||||
{
|
||||
BaseCreature bc;
|
||||
|
||||
if (m_IsBattleChicken)
|
||||
{
|
||||
from.SendLocalizedMessage(1112478); //You hatch a battle chicken lizard!!
|
||||
bc = new BattleChickenLizard();
|
||||
bc.Hue = this.Hue;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1112477); //You hatch a chicken lizard.
|
||||
bc = new ChickenLizard();
|
||||
}
|
||||
|
||||
bc.MoveToWorld(from.Location, from.Map);
|
||||
Delete();
|
||||
}
|
||||
|
||||
public void CrumbleEgg(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(1112447); //You hatch the egg but it crumbles in your hands!
|
||||
Delete();
|
||||
}
|
||||
|
||||
private class ConfirmHatchGump1 : BaseConfirmGump
|
||||
{
|
||||
private ChickenLizardEgg m_Egg;
|
||||
private Mobile m_From;
|
||||
|
||||
public override int TitleNumber { get { return 1112444; } }
|
||||
public override int LabelNumber { get { return 1112446; } }
|
||||
|
||||
public ConfirmHatchGump1(Mobile from, ChickenLizardEgg egg)
|
||||
{
|
||||
m_Egg = egg;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void Confirm( Mobile from )
|
||||
{
|
||||
if(m_Egg != null)
|
||||
m_Egg.TryHatchEgg(from);
|
||||
}
|
||||
}
|
||||
|
||||
private class ConfirmHatchGump2 : BaseConfirmGump
|
||||
{
|
||||
private ChickenLizardEgg m_Egg;
|
||||
private Mobile m_From;
|
||||
|
||||
public override int TitleNumber { get { return 1112444; } }
|
||||
public override int LabelNumber { get { return 1112445; } }
|
||||
|
||||
public ConfirmHatchGump2(Mobile from, ChickenLizardEgg egg)
|
||||
{
|
||||
m_Egg = egg;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void Confirm(Mobile from)
|
||||
{
|
||||
if (m_Egg != null)
|
||||
m_Egg.TryHatchEgg(from);
|
||||
}
|
||||
}
|
||||
|
||||
public ChickenLizardEgg(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(m_IncubationStart);
|
||||
writer.Write(m_TotalIncubationTime);
|
||||
writer.Write(m_Incubating);
|
||||
writer.Write((int)m_Stage);
|
||||
writer.Write(m_WaterLevel);
|
||||
writer.Write(m_IsBattleChicken);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_IncubationStart = reader.ReadDateTime();
|
||||
m_TotalIncubationTime = reader.ReadTimeSpan();
|
||||
m_Incubating = reader.ReadBool();
|
||||
m_Stage = (EggStage)reader.ReadInt();
|
||||
m_WaterLevel = reader.ReadInt();
|
||||
m_IsBattleChicken = reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Scripts/Items/Functional/CircuitTrapTrainingKit.cs
Normal file
148
Scripts/Items/Functional/CircuitTrapTrainingKit.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.SkillHandlers;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CircuitTrapTrainingKit : Item, ICircuitTrap, IRemoveTrapTrainingKit
|
||||
{
|
||||
public override int LabelNumber { get { return 1159014; } } // Circuit Trap Training Kit
|
||||
|
||||
public int GumpTitle { get { return 1159005; } } // <center>Trap Disarm Mechanism</center>
|
||||
public int GumpDescription { get { return 1159006; } } // // <center>disarm the trap</center>
|
||||
|
||||
private CircuitCount _Count;
|
||||
public CircuitCount Count { get { return _Count; } }
|
||||
|
||||
public List<int> Path { get; set; } = new List<int>();
|
||||
public List<int> Progress { get; set; } = new List<int>();
|
||||
|
||||
public bool CanDecipher { get { return false; } }
|
||||
|
||||
[Constructable]
|
||||
public CircuitTrapTrainingKit()
|
||||
: base(41875)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
m.SendLocalizedMessage(1159008); // That appears to be trapped, using the remove trap skill would yield better results...
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRemoveTrap(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile)
|
||||
{
|
||||
if (Path == null || Path.Count == 0)
|
||||
{
|
||||
var skill = m.Skills[SkillName.RemoveTrap].Base;
|
||||
|
||||
if (skill < 80.0)
|
||||
{
|
||||
_Count = CircuitCount.Nine;
|
||||
}
|
||||
else if (skill < 100.0)
|
||||
{
|
||||
_Count = CircuitCount.Sixteen;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Count = CircuitCount.TwentyFive;
|
||||
}
|
||||
}
|
||||
|
||||
BaseGump.SendGump(new CircuitTrapGump((PlayerMobile)m, this));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSelfClose(Mobile m)
|
||||
{
|
||||
if (Progress != null)
|
||||
{
|
||||
Progress.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnProgress(Mobile m, int pick)
|
||||
{
|
||||
m.SendSound(0x1F4);
|
||||
}
|
||||
|
||||
public void OnFailed(Mobile m)
|
||||
{
|
||||
m.SendLocalizedMessage(1159013); // You fail to disarm the trap and reset it.
|
||||
}
|
||||
|
||||
public void OnComplete(Mobile m)
|
||||
{
|
||||
m.SendLocalizedMessage(1159009); // You successfully disarm the trap!
|
||||
|
||||
m.CheckTargetSkill(SkillName.RemoveTrap, this, 0, 100);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
Mobile m = RootParent as Mobile;
|
||||
|
||||
if (m != null)
|
||||
{
|
||||
if (m.HasGump(typeof(CircuitTrapGump)))
|
||||
{
|
||||
m.CloseGump(typeof(CircuitTrapGump));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CircuitTrapTrainingKit(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(Path.Count);
|
||||
for (int i = 0; i < Path.Count; i++)
|
||||
{
|
||||
writer.Write(Path[i]);
|
||||
}
|
||||
|
||||
writer.Write(Progress.Count);
|
||||
for (int i = 0; i < Progress.Count; i++)
|
||||
{
|
||||
writer.Write(Progress[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
var count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Path.Add(reader.ReadInt());
|
||||
}
|
||||
|
||||
count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Progress.Add(reader.ReadInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Scripts/Items/Functional/CitadelAltar.cs
Normal file
55
Scripts/Items/Functional/CitadelAltar.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CitadelAltar : PeerlessAltar
|
||||
{
|
||||
public override int KeyCount{ get{ return 3; } }
|
||||
public override MasterKey MasterKey{ get{ return new CitadelKey(); } }
|
||||
|
||||
public override Type[] Keys{ get{ return new Type[]
|
||||
{
|
||||
typeof( TigerClawKey ), typeof( SerpentFangKey ), typeof( DragonFlameKey )
|
||||
}; }}
|
||||
|
||||
public override BasePeerless Boss{ get{ return new Travesty(); } }
|
||||
|
||||
[Constructable]
|
||||
public CitadelAltar() : base( 0x207E )
|
||||
{
|
||||
BossLocation = new Point3D( 86, 1955, 0 );
|
||||
TeleportDest = new Point3D( 111, 1955, 0 );
|
||||
ExitDest = new Point3D( 1355, 779, 17 );
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(66, 1936, 51, 39),
|
||||
};
|
||||
|
||||
public CitadelAltar( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Scripts/Items/Functional/CoralTheOwl.cs
Normal file
104
Scripts/Items/Functional/CoralTheOwl.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CoralTheOwl : Item, Server.Engines.VeteranRewards.IRewardItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1123603; } } // Coral the Owl
|
||||
|
||||
private Timer m_NewsTimer;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsRewardItem { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public CoralTheOwl() : base(0x9A9B)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if(IsRewardItem)
|
||||
list.Add(1076217); // 1st Year Veteran Reward
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return true; } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
if (IsLockedDown && e.HasKeyword(0x30) && e.Mobile.Alive && e.Mobile.InLOS(this.Location) && e.Mobile.InRange(this, 12)) // *news*
|
||||
{
|
||||
TownCrierEntry tce = GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||
|
||||
if (tce == null)
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1005643); // I have no news at this time.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NewsTimer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(3.0), new TimerStateCallback(ShoutNews_Callback), new object[] { tce, 0 });
|
||||
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502978); // Some of the latest news!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShoutNews_Callback(object state)
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
TownCrierEntry tce = (TownCrierEntry)states[0];
|
||||
int index = (int)states[1];
|
||||
|
||||
if (index < 0 || index >= tce.Lines.Length)
|
||||
{
|
||||
if (m_NewsTimer != null)
|
||||
m_NewsTimer.Stop();
|
||||
|
||||
m_NewsTimer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, tce.Lines[index]);
|
||||
states[1] = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public CoralTheOwl( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
|
||||
writer.Write(IsRewardItem);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
IsRewardItem = reader.ReadBool();
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
IsRewardItem = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Scripts/Items/Functional/CylinderTrapTrainingKit.cs
Normal file
85
Scripts/Items/Functional/CylinderTrapTrainingKit.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.SkillHandlers;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CylinderTrapTrainingKit : PuzzleChest, IRemoveTrapTrainingKit
|
||||
{
|
||||
public override int LabelNumber { get { return 1159015; } } // Cylinder Trap Training Kit
|
||||
public int Title { get { return 1159017; } } // A Cylinder Trap
|
||||
|
||||
[Constructable]
|
||||
public CylinderTrapTrainingKit()
|
||||
: base(41875)
|
||||
{
|
||||
Solution = new PuzzleChestSolution();
|
||||
Movable = true;
|
||||
}
|
||||
|
||||
public override void DisplayTo(Mobile to)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CheckLocked(Mobile from)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnRemoveTrap(Mobile from)
|
||||
{
|
||||
PuzzleChestSolution solution = GetLastGuess(from);
|
||||
|
||||
if (solution != null)
|
||||
solution = new PuzzleChestSolution(solution);
|
||||
else
|
||||
solution = new PuzzleChestSolution(PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None);
|
||||
|
||||
from.CloseGump(typeof(PuzzleChest.PuzzleGump));
|
||||
from.CloseGump(typeof(PuzzleChest.StatusGump));
|
||||
from.SendGump(new PuzzleChest.PuzzleGump(from, this, solution, 0));
|
||||
}
|
||||
|
||||
public override void DoDamage(Mobile to)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
m.SendLocalizedMessage(1159008); // That appears to be trapped, using the remove trap skill would yield better results...
|
||||
}
|
||||
}
|
||||
|
||||
public override void LockPick(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(1159009); // You successfully disarm the trap!
|
||||
|
||||
from.CheckTargetSkill(SkillName.RemoveTrap, this, 0, 100);
|
||||
|
||||
Solution = new PuzzleChestSolution();
|
||||
}
|
||||
|
||||
public CylinderTrapTrainingKit(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
270
Scripts/Items/Functional/DeceitBrazier.cs
Normal file
270
Scripts/Items/Functional/DeceitBrazier.cs
Normal file
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DeceitBrazier : Item
|
||||
{
|
||||
private static readonly Type[] m_Creatures = new Type[]
|
||||
{
|
||||
#region Animals
|
||||
typeof(FireSteed), //Set the tents up people!
|
||||
#endregion
|
||||
|
||||
#region Undead
|
||||
typeof(Skeleton), typeof(SkeletalKnight), typeof(SkeletalMage), typeof(Mummy),
|
||||
typeof(BoneKnight), typeof(Lich), typeof(LichLord), typeof(BoneMagi),
|
||||
typeof(Wraith), typeof(Shade), typeof(Spectre), typeof(Zombie),
|
||||
typeof(RottingCorpse), typeof(Ghoul),
|
||||
#endregion
|
||||
|
||||
#region Demons
|
||||
typeof(Balron), typeof(Daemon), typeof(Imp), typeof(GreaterMongbat),
|
||||
typeof(Mongbat), typeof(IceFiend), typeof(Gargoyle), typeof(StoneGargoyle),
|
||||
typeof(FireGargoyle), typeof(HordeMinion),
|
||||
#endregion
|
||||
|
||||
#region Gazers
|
||||
typeof(Gazer), typeof(ElderGazer), typeof(GazerLarva),
|
||||
#endregion
|
||||
|
||||
#region Uncategorized
|
||||
typeof(Harpy), typeof(StoneHarpy), typeof(HeadlessOne), typeof(HellHound),
|
||||
typeof(HellCat), typeof(Phoenix), typeof(LavaLizard), typeof(SandVortex),
|
||||
typeof(ShadowWisp), typeof(SwampTentacle), typeof(PredatorHellCat), typeof(Wisp),
|
||||
#endregion
|
||||
|
||||
#region Arachnid
|
||||
typeof(GiantSpider), typeof(DreadSpider), typeof(FrostSpider), typeof(Scorpion),
|
||||
#endregion
|
||||
|
||||
#region Repond
|
||||
typeof(ArcticOgreLord), typeof(Cyclops), typeof(Ettin), typeof(EvilMage),
|
||||
typeof(FrostTroll), typeof(Ogre), typeof(OgreLord), typeof(Orc),
|
||||
typeof(OrcishLord), typeof(OrcishMage), typeof(OrcBrute), typeof(Ratman),
|
||||
typeof(RatmanMage), typeof(OrcCaptain), typeof(Troll), typeof(Titan),
|
||||
typeof(EvilMageLord), typeof(OrcBomber), typeof(RatmanArcher),
|
||||
#endregion
|
||||
|
||||
#region Reptilian
|
||||
typeof(Dragon), typeof(Drake), typeof(Snake), typeof(GreaterDragon),
|
||||
typeof(IceSerpent), typeof(GiantSerpent), typeof(IceSnake), typeof(LavaSerpent),
|
||||
typeof(Lizardman), typeof(Wyvern), typeof(WhiteWyrm),
|
||||
typeof(ShadowWyrm), typeof(SilverSerpent), typeof(LavaSnake),
|
||||
#endregion
|
||||
|
||||
#region Elementals
|
||||
typeof(EarthElemental), typeof(PoisonElemental), typeof(FireElemental), typeof(SnowElemental),
|
||||
typeof(IceElemental), typeof(ToxicElemental), typeof(WaterElemental), typeof(Efreet),
|
||||
typeof(AirElemental), typeof(Golem),
|
||||
#endregion
|
||||
|
||||
#region Random Critters
|
||||
typeof(Sewerrat), typeof(GiantRat), typeof(DireWolf), typeof(TimberWolf),
|
||||
typeof(Cougar), typeof(Alligator)
|
||||
#endregion
|
||||
};
|
||||
|
||||
public static Type[] Creatures
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Creatures;
|
||||
}
|
||||
}
|
||||
|
||||
private Timer m_Timer;
|
||||
private DateTime m_NextSpawn;
|
||||
private int m_SpawnRange;
|
||||
private TimeSpan m_NextSpawnDelay;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextSpawn
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_NextSpawn;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int SpawnRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SpawnRange;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_SpawnRange = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan NextSpawnDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_NextSpawnDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_NextSpawnDelay = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return 1023633;
|
||||
}
|
||||
}// Brazier
|
||||
|
||||
[Constructable]
|
||||
public DeceitBrazier()
|
||||
: base(0xE31)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle225;
|
||||
m_NextSpawn = DateTime.UtcNow;
|
||||
m_NextSpawnDelay = TimeSpan.FromMinutes(15.0);
|
||||
m_SpawnRange = 5;
|
||||
}
|
||||
|
||||
public DeceitBrazier(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((int)m_SpawnRange);
|
||||
writer.Write(m_NextSpawnDelay);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (version >= 0)
|
||||
{
|
||||
m_SpawnRange = reader.ReadInt();
|
||||
m_NextSpawnDelay = reader.ReadTimeSpan();
|
||||
}
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public virtual void HeedWarning()
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 500761);// Heed this warning well, and use this brazier at your own peril.
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m_NextSpawn < DateTime.UtcNow) // means we haven't spawned anything if the next spawn is below
|
||||
{
|
||||
if (Utility.InRange(m.Location, Location, 1) && !Utility.InRange(oldLocation, Location, 1) && m.Player && !(m.IsStaff() || m.Hidden))
|
||||
{
|
||||
if (m_Timer == null || !m_Timer.Running)
|
||||
m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerCallback(HeedWarning));
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMovement(m, oldLocation);
|
||||
}
|
||||
|
||||
public Point3D GetSpawnPosition()
|
||||
{
|
||||
Map map = Map;
|
||||
|
||||
if (map == null)
|
||||
return Location;
|
||||
|
||||
// Try 10 times to find a Spawnable location.
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int x = Location.X + (Utility.Random((m_SpawnRange * 2) + 1) - m_SpawnRange);
|
||||
int y = Location.Y + (Utility.Random((m_SpawnRange * 2) + 1) - m_SpawnRange);
|
||||
int z = Map.GetAverageZ(x, y);
|
||||
|
||||
if (Map.CanSpawnMobile(new Point2D(x, y), Z))
|
||||
return new Point3D(x, y, Z);
|
||||
else if (Map.CanSpawnMobile(new Point2D(x, y), z))
|
||||
return new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
return Location;
|
||||
}
|
||||
|
||||
public virtual void DoEffect(Point3D loc, Map map)
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
|
||||
Effects.PlaySound(loc, map, 0x225);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (Utility.InRange(from.Location, Location, 2))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_NextSpawn < DateTime.UtcNow)
|
||||
{
|
||||
Map map = Map;
|
||||
BaseCreature bc = (BaseCreature)Activator.CreateInstance(m_Creatures[Utility.Random(m_Creatures.Length)]);
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
Point3D spawnLoc = GetSpawnPosition();
|
||||
|
||||
DoEffect(spawnLoc, map);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), delegate()
|
||||
{
|
||||
bc.Home = Location;
|
||||
bc.RangeHome = m_SpawnRange;
|
||||
bc.FightMode = FightMode.Closest;
|
||||
|
||||
bc.MoveToWorld(spawnLoc, map);
|
||||
|
||||
DoEffect(spawnLoc, map);
|
||||
|
||||
bc.ForceReacquire();
|
||||
});
|
||||
|
||||
m_NextSpawn = DateTime.UtcNow + m_NextSpawnDelay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 500760); // The brazier fizzes and pops, but nothing seems to happen.
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Scripts/Items/Functional/DespiseAnkh.cs
Normal file
104
Scripts/Items/Functional/DespiseAnkh.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Quests;
|
||||
|
||||
namespace Server.Engines.Despise
|
||||
{
|
||||
public class DespiseAnkh : BaseAddon
|
||||
{
|
||||
private Alignment m_Alignment;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Alignment Alignment { get { return m_Alignment; } set { m_Alignment = value; } }
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public DespiseAnkh(Alignment alignment)
|
||||
{
|
||||
m_Alignment = alignment;
|
||||
|
||||
switch (alignment)
|
||||
{
|
||||
default:
|
||||
case Alignment.Good:
|
||||
AddComponent(new AddonComponent(4), 0, 0, 0);
|
||||
AddComponent(new AddonComponent(5), +1, 0, 0);
|
||||
break;
|
||||
case Alignment.Evil:
|
||||
AddComponent(new AddonComponent(2), 0, 0, 0);
|
||||
AddComponent(new AddonComponent(3), 0, -1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnComponentUsed(AddonComponent c, Mobile from)
|
||||
{
|
||||
if(from.InRange(c.Location, 3) && from.Backpack != null)
|
||||
{
|
||||
if (WispOrb.Orbs.Any(x => x.Owner == from))
|
||||
{
|
||||
LabelTo(from, 1153357); // Thou can guide but one of us.
|
||||
return;
|
||||
}
|
||||
|
||||
Alignment alignment = Alignment.Neutral;
|
||||
|
||||
if(from.Karma > 0 && m_Alignment == Alignment.Good)
|
||||
alignment = Alignment.Good;
|
||||
else if (from.Karma < 0 && m_Alignment == Alignment.Evil)
|
||||
alignment = Alignment.Evil;
|
||||
|
||||
if(alignment != Alignment.Neutral)
|
||||
{
|
||||
WispOrb orb = new WispOrb(from, alignment);
|
||||
from.Backpack.DropItem(orb);
|
||||
from.SendLocalizedMessage(1153355); // I will follow thy guidance.
|
||||
|
||||
if (from is PlayerMobile && QuestHelper.HasQuest<WhisperingWithWispsQuest>((PlayerMobile)from))
|
||||
{
|
||||
from.SendLocalizedMessage(1158304); // The Ankh pulses with energy in front of you! You are drawn to it! As you
|
||||
// place your hand on the ankh an inner voice speaks to you as you are joined to your Wisp companion...
|
||||
from.SendLocalizedMessage(1158320, null, 0x23); // You've completed a quest objective!
|
||||
from.PlaySound(0x5B5);
|
||||
|
||||
Server.Services.TownCryer.TownCryerSystem.CompleteQuest((PlayerMobile)from, 1158303, 1158308, 0x65C);
|
||||
}
|
||||
}
|
||||
else
|
||||
LabelTo(from, 1153350); // Thy spirit be not compatible with our goals!
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m is PlayerMobile &&
|
||||
!WispOrb.Orbs.Any(x => x.Owner == m) &&
|
||||
QuestHelper.HasQuest<WhisperingWithWispsQuest>((PlayerMobile)m) &&
|
||||
InRange(m.Location, 5) && !InRange(oldLocation, 5))
|
||||
{
|
||||
m.SendLocalizedMessage(1158311); // You have found an ankh. Use the ankh to continue your journey.
|
||||
}
|
||||
}
|
||||
|
||||
public DespiseAnkh(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
writer.Write((int)m_Alignment);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
m_Alignment = (Alignment)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
385
Scripts/Items/Functional/Doors.cs
Normal file
385
Scripts/Items/Functional/Doors.cs
Normal file
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum DoorFacing
|
||||
{
|
||||
WestCW,
|
||||
EastCCW,
|
||||
WestCCW,
|
||||
EastCW,
|
||||
SouthCW,
|
||||
NorthCCW,
|
||||
SouthCCW,
|
||||
NorthCW,
|
||||
//Sliding Doors
|
||||
SouthSW,
|
||||
SouthSE,
|
||||
WestSS,
|
||||
WestSN
|
||||
}
|
||||
|
||||
public class IronGateShort : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public IronGateShort(DoorFacing facing)
|
||||
: base(0x84c + (2 * (int)facing), 0x84d + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public IronGateShort(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class IronGate : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public IronGate(DoorFacing facing)
|
||||
: base(0x824 + (2 * (int)facing), 0x825 + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public IronGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LightWoodGate : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public LightWoodGate(DoorFacing facing)
|
||||
: base(0x839 + (2 * (int)facing), 0x83A + (2 * (int)facing), 0xEB, 0xF2, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public LightWoodGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DarkWoodGate : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public DarkWoodGate(DoorFacing facing)
|
||||
: base(0x866 + (2 * (int)facing), 0x867 + (2 * (int)facing), 0xEB, 0xF2, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public DarkWoodGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class MetalDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public MetalDoor(DoorFacing facing)
|
||||
: base(0x675 + (2 * (int)facing), 0x676 + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public MetalDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class BarredMetalDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public BarredMetalDoor(DoorFacing facing)
|
||||
: base(0x685 + (2 * (int)facing), 0x686 + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public BarredMetalDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class BarredMetalDoor2 : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public BarredMetalDoor2(DoorFacing facing)
|
||||
: base(0x1FED + (2 * (int)facing), 0x1FEE + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public BarredMetalDoor2(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class RattanDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public RattanDoor(DoorFacing facing)
|
||||
: base(0x695 + (2 * (int)facing), 0x696 + (2 * (int)facing), 0xEB, 0xF2, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public RattanDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DarkWoodDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public DarkWoodDoor(DoorFacing facing)
|
||||
: base(0x6A5 + (2 * (int)facing), 0x6A6 + (2 * (int)facing), 0xEA, 0xF1, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public DarkWoodDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class MediumWoodDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public MediumWoodDoor(DoorFacing facing)
|
||||
: base(0x6B5 + (2 * (int)facing), 0x6B6 + (2 * (int)facing), 0xEA, 0xF1, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public MediumWoodDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class MetalDoor2 : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public MetalDoor2(DoorFacing facing)
|
||||
: base(0x6C5 + (2 * (int)facing), 0x6C6 + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public MetalDoor2(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LightWoodDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public LightWoodDoor(DoorFacing facing)
|
||||
: base(0x6D5 + (2 * (int)facing), 0x6D6 + (2 * (int)facing), 0xEA, 0xF1, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public LightWoodDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class StrongWoodDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public StrongWoodDoor(DoorFacing facing)
|
||||
: base(0x6E5 + (2 * (int)facing), 0x6E6 + (2 * (int)facing), 0xEA, 0xF1, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public StrongWoodDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Scripts/Items/Functional/DragonTurtleEgg.cs
Normal file
49
Scripts/Items/Functional/DragonTurtleEgg.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DragonTurtleEgg : ChickenLizardEgg
|
||||
{
|
||||
public override bool CanMutate { get { return false; } }
|
||||
|
||||
[Constructable]
|
||||
public DragonTurtleEgg()
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
list.Add(1156238); // Dragon Turtle
|
||||
}
|
||||
|
||||
public override void OnHatch(Mobile from)
|
||||
{
|
||||
BaseCreature bc = new DragonTurtleHatchling();
|
||||
|
||||
from.SendLocalizedMessage(1156239); // You hatch a dragon turtle!
|
||||
|
||||
bc.MoveToWorld(from.Location, from.Map);
|
||||
Delete();
|
||||
}
|
||||
|
||||
public DragonTurtleEgg(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Scripts/Items/Functional/EtherealRetouchingTool.cs
Normal file
121
Scripts/Items/Functional/EtherealRetouchingTool.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using Server.Engines.VeteranRewards;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class EtherealRetouchingTool : Item, IRewardItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1113814; } } // Retouching Tool
|
||||
|
||||
public bool IsRewardItem { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public EtherealRetouchingTool()
|
||||
: base(0x42C6)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public EtherealRetouchingTool(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (IsRewardItem)
|
||||
list.Add(1080458); // 11th Year Veteran Reward
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
from.SendLocalizedMessage(1113815); // Target the ethereal mount you wish to retouch.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1042010); // You must have the object in your backpack to use it.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private EtherealRetouchingTool m_Tool;
|
||||
|
||||
public InternalTarget(EtherealRetouchingTool tool)
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Tool = tool;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (!m_Tool.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if (targeted is EtherealMount)
|
||||
{
|
||||
EtherealMount mount = targeted as EtherealMount;
|
||||
|
||||
if (!mount.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1045158); // You must have the item in your backpack to target it.
|
||||
}
|
||||
else if (mount is GMEthereal || mount is EtherealWarBoar)
|
||||
{
|
||||
from.SendLocalizedMessage(1071117); // You cannot use this item for it.
|
||||
}
|
||||
else if (RewardSystem.CheckIsUsableBy(from, m_Tool, null))
|
||||
{
|
||||
if (mount.Transparent)
|
||||
from.SendLocalizedMessage(1113816); // Your ethereal mount's body has been solidified.
|
||||
else
|
||||
from.SendLocalizedMessage(1113817); // Your ethereal mount's transparency has been restored.
|
||||
|
||||
mount.Transparent = mount.Transparent ? false : true;
|
||||
mount.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1046439); // That is not a valid target.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddProperty(EtherealMount mount, ObjectPropertyList list)
|
||||
{
|
||||
list.Add(1113818, mount.Transparent ? "#1078520" : "#1153298");
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.WriteEncodedInt(1); // version
|
||||
|
||||
writer.Write(IsRewardItem);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
if (version == 0)
|
||||
IsRewardItem = true;
|
||||
else
|
||||
IsRewardItem = reader.ReadBool();
|
||||
|
||||
if (LootType != LootType.Blessed)
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableCabbage.cs
Normal file
51
Scripts/Items/Functional/FarmableCabbage.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableCabbage : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableCabbage()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableCabbage(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Cabbage cabbage = new Cabbage();
|
||||
|
||||
cabbage.ItemID = Utility.Random(3195, 2);
|
||||
|
||||
return cabbage;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableCarrot.cs
Normal file
51
Scripts/Items/Functional/FarmableCarrot.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableCarrot : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableCarrot()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableCarrot(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return 3190;
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Carrot carrot = new Carrot();
|
||||
|
||||
carrot.ItemID = Utility.Random(3191, 2);
|
||||
|
||||
return carrot;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Scripts/Items/Functional/FarmableCotton.cs
Normal file
47
Scripts/Items/Functional/FarmableCotton.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableCotton : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableCotton()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableCotton(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return Utility.Random(3153, 4);
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
return new Cotton();
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Scripts/Items/Functional/FarmableCrop.cs
Normal file
93
Scripts/Items/Functional/FarmableCrop.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class FarmableCrop : Item
|
||||
{
|
||||
private bool m_Picked;
|
||||
public FarmableCrop(int itemID)
|
||||
: base(itemID)
|
||||
{
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public FarmableCrop(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract Item GetCropObject();
|
||||
|
||||
public abstract int GetPickedID();
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
Map map = this.Map;
|
||||
Point3D loc = this.Location;
|
||||
|
||||
if (this.Parent != null || this.Movable || this.IsLockedDown || this.IsSecure || map == null || map == Map.Internal)
|
||||
return;
|
||||
|
||||
if (!from.InRange(loc, 2) || !from.InLOS(this))
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
else if (!this.m_Picked)
|
||||
this.OnPicked(from, loc, map);
|
||||
}
|
||||
|
||||
public virtual void OnPicked(Mobile from, Point3D loc, Map map)
|
||||
{
|
||||
this.ItemID = this.GetPickedID();
|
||||
|
||||
Item spawn = this.GetCropObject();
|
||||
|
||||
if (spawn != null)
|
||||
spawn.MoveToWorld(loc, map);
|
||||
|
||||
this.m_Picked = true;
|
||||
|
||||
this.Unlink();
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(5.0), new TimerCallback(Delete));
|
||||
}
|
||||
|
||||
public void Unlink()
|
||||
{
|
||||
ISpawner se = this.Spawner;
|
||||
|
||||
if (se != null)
|
||||
{
|
||||
this.Spawner.Remove(this);
|
||||
this.Spawner = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(this.m_Picked);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
this.m_Picked = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
if (this.m_Picked)
|
||||
{
|
||||
this.Unlink();
|
||||
this.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableFlax.cs
Normal file
51
Scripts/Items/Functional/FarmableFlax.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableFlax : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableFlax()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableFlax(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return Utility.Random(6809, 3);
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Flax flax = new Flax();
|
||||
|
||||
flax.ItemID = Utility.Random(6812, 2);
|
||||
|
||||
return flax;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableLettuce.cs
Normal file
51
Scripts/Items/Functional/FarmableLettuce.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableLettuce : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableLettuce()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableLettuce(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Lettuce lettuce = new Lettuce();
|
||||
|
||||
lettuce.ItemID = Utility.Random(3184, 2);
|
||||
|
||||
return lettuce;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableOnion.cs
Normal file
51
Scripts/Items/Functional/FarmableOnion.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableOnion : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableOnion()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableOnion(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return 3183;
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Onion onion = new Onion();
|
||||
|
||||
onion.ItemID = Utility.Random(3181, 2);
|
||||
|
||||
return onion;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmablePumpkin.cs
Normal file
51
Scripts/Items/Functional/FarmablePumpkin.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmablePumpkin : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmablePumpkin()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmablePumpkin(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return Utility.Random(3166, 3);
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Pumpkin pumpkin = new Pumpkin();
|
||||
|
||||
pumpkin.ItemID = Utility.Random(3178, 3);
|
||||
|
||||
return pumpkin;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return Utility.Random(3166, 3);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Items/Functional/FarmableTurnip.cs
Normal file
51
Scripts/Items/Functional/FarmableTurnip.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableTurnip : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableTurnip()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableTurnip(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return Utility.Random(3169, 3);
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
Turnip turnip = new Turnip();
|
||||
|
||||
turnip.ItemID = Utility.Random(3385, 2);
|
||||
|
||||
return turnip;
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return 3254;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Scripts/Items/Functional/FarmableWheat.cs
Normal file
47
Scripts/Items/Functional/FarmableWheat.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FarmableWheat : FarmableCrop
|
||||
{
|
||||
[Constructable]
|
||||
public FarmableWheat()
|
||||
: base(GetCropID())
|
||||
{
|
||||
}
|
||||
|
||||
public FarmableWheat(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public static int GetCropID()
|
||||
{
|
||||
return Utility.Random(3157, 4);
|
||||
}
|
||||
|
||||
public override Item GetCropObject()
|
||||
{
|
||||
return new WheatSheaf();
|
||||
}
|
||||
|
||||
public override int GetPickedID()
|
||||
{
|
||||
return Utility.Random(3502, 2);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Scripts/Items/Functional/FireColumnTrap.cs
Normal file
148
Scripts/Items/Functional/FireColumnTrap.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FireColumnTrap : BaseTrap
|
||||
{
|
||||
private int m_MinDamage;
|
||||
private int m_MaxDamage;
|
||||
private bool m_WarningFlame;
|
||||
[Constructable]
|
||||
public FireColumnTrap()
|
||||
: base(0x1B71)
|
||||
{
|
||||
this.m_MinDamage = 10;
|
||||
this.m_MaxDamage = 40;
|
||||
|
||||
this.m_WarningFlame = true;
|
||||
}
|
||||
|
||||
public FireColumnTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
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.5);
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int MinDamage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_MinDamage;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_MinDamage = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual int MaxDamage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_MaxDamage;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_MaxDamage = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public virtual bool WarningFlame
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_WarningFlame;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_WarningFlame = value;
|
||||
}
|
||||
}
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (from.IsStaff())
|
||||
return;
|
||||
|
||||
if (this.WarningFlame)
|
||||
this.DoEffect();
|
||||
|
||||
if (from.Alive && this.CheckRange(from.Location, 0))
|
||||
{
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromSeconds(0.5), from, from, Utility.RandomMinMax(this.MinDamage, this.MaxDamage), 0, 100, 0, 0, 0);
|
||||
|
||||
if (!this.WarningFlame)
|
||||
this.DoEffect();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write(this.m_WarningFlame);
|
||||
writer.Write(this.m_MinDamage);
|
||||
writer.Write(this.m_MaxDamage);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this.m_WarningFlame = reader.ReadBool();
|
||||
this.m_MinDamage = reader.ReadInt();
|
||||
this.m_MaxDamage = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
this.m_WarningFlame = true;
|
||||
this.m_MinDamage = 10;
|
||||
this.m_MaxDamage = 40;
|
||||
}
|
||||
}
|
||||
|
||||
private void DoEffect()
|
||||
{
|
||||
Effects.SendLocationParticles(EffectItem.Create(this.Location, this.Map, EffectItem.DefaultDuration), 0x3709, 10, 30, 5052);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x225);
|
||||
}
|
||||
}
|
||||
}
|
||||
184
Scripts/Items/Functional/FlameSpurtTrap.cs
Normal file
184
Scripts/Items/Functional/FlameSpurtTrap.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FlameSpurtTrap : BaseTrap
|
||||
{
|
||||
private Item m_Spurt;
|
||||
private Timer m_Timer;
|
||||
[Constructable]
|
||||
public FlameSpurtTrap()
|
||||
: base(0x1B71)
|
||||
{
|
||||
this.Visible = false;
|
||||
}
|
||||
|
||||
public FlameSpurtTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void StartTimer()
|
||||
{
|
||||
if (this.m_Timer == null)
|
||||
this.m_Timer = Timer.DelayCall(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), new TimerCallback(Refresh));
|
||||
}
|
||||
|
||||
public virtual void StopTimer()
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
this.m_Timer.Stop();
|
||||
|
||||
this.m_Timer = null;
|
||||
}
|
||||
|
||||
public virtual void CheckTimer()
|
||||
{
|
||||
Map map = this.Map;
|
||||
|
||||
if (map != null && map.GetSector(this.GetWorldLocation()).Active)
|
||||
this.StartTimer();
|
||||
else
|
||||
this.StopTimer();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
base.OnLocationChange(oldLocation);
|
||||
|
||||
this.CheckTimer();
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
|
||||
this.CheckTimer();
|
||||
}
|
||||
|
||||
public override void OnSectorActivate()
|
||||
{
|
||||
base.OnSectorActivate();
|
||||
|
||||
this.StartTimer();
|
||||
}
|
||||
|
||||
public override void OnSectorDeactivate()
|
||||
{
|
||||
base.OnSectorDeactivate();
|
||||
|
||||
this.StopTimer();
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if (this.m_Spurt != null)
|
||||
this.m_Spurt.Delete();
|
||||
}
|
||||
|
||||
public virtual void Refresh()
|
||||
{
|
||||
if (this.Deleted)
|
||||
return;
|
||||
|
||||
bool foundPlayer = false;
|
||||
IPooledEnumerable eable = GetMobilesInRange(3);
|
||||
|
||||
foreach (Mobile mob in eable)
|
||||
{
|
||||
if (!mob.Player || !mob.Alive || mob.IsStaff())
|
||||
continue;
|
||||
|
||||
if (((this.Z + 8) >= mob.Z && (mob.Z + 16) > this.Z))
|
||||
{
|
||||
foundPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (!foundPlayer)
|
||||
{
|
||||
if (this.m_Spurt != null)
|
||||
this.m_Spurt.Delete();
|
||||
|
||||
this.m_Spurt = null;
|
||||
}
|
||||
else if (this.m_Spurt == null || this.m_Spurt.Deleted)
|
||||
{
|
||||
this.m_Spurt = new Static(0x3709);
|
||||
this.m_Spurt.MoveToWorld(this.Location, this.Map);
|
||||
|
||||
Effects.PlaySound(this.GetWorldLocation(), this.Map, 0x309);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m.IsPlayer())
|
||||
return true;
|
||||
|
||||
if (m.Player && m.Alive)
|
||||
{
|
||||
this.CheckTimer();
|
||||
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), m, m, Utility.RandomMinMax(1, 30));
|
||||
m.PlaySound(m.Female ? 0x327 : 0x437);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
base.OnMovement(m, oldLocation);
|
||||
|
||||
if (m.Location == oldLocation || !m.Player || !m.Alive || m.IsStaff())
|
||||
return;
|
||||
|
||||
if (this.CheckRange(m.Location, oldLocation, 1))
|
||||
{
|
||||
this.CheckTimer();
|
||||
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), m, m, Utility.RandomMinMax(1, 10));
|
||||
m.PlaySound(m.Female ? 0x327 : 0x437);
|
||||
|
||||
if (m.Body.IsHuman)
|
||||
m.Animate(20, 1, 1, true, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)this.m_Spurt);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Item item = reader.ReadItem();
|
||||
|
||||
if (item != null)
|
||||
item.Delete();
|
||||
|
||||
this.CheckTimer();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
161
Scripts/Items/Functional/GasTrap.cs
Normal file
161
Scripts/Items/Functional/GasTrap.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum GasTrapType
|
||||
{
|
||||
NorthWall,
|
||||
WestWall,
|
||||
Floor
|
||||
}
|
||||
|
||||
public class GasTrap : BaseTrap
|
||||
{
|
||||
private Poison m_Poison;
|
||||
[Constructable]
|
||||
public GasTrap()
|
||||
: this(GasTrapType.Floor)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GasTrap(GasTrapType type)
|
||||
: this(type, Poison.Lesser)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GasTrap(Poison poison)
|
||||
: this(GasTrapType.Floor, Poison.Lesser)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GasTrap(GasTrapType type, Poison poison)
|
||||
: base(GetBaseID(type))
|
||||
{
|
||||
this.m_Poison = poison;
|
||||
}
|
||||
|
||||
public GasTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Poison Poison
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Poison;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Poison = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public GasTrapType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
switch ( this.ItemID )
|
||||
{
|
||||
case 0x113C:
|
||||
return GasTrapType.NorthWall;
|
||||
case 0x1147:
|
||||
return GasTrapType.WestWall;
|
||||
case 0x11A8:
|
||||
return GasTrapType.Floor;
|
||||
}
|
||||
|
||||
return GasTrapType.WestWall;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ItemID = GetBaseID(value);
|
||||
}
|
||||
}
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds(0.0);
|
||||
}
|
||||
}
|
||||
public static int GetBaseID(GasTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case GasTrapType.NorthWall:
|
||||
return 0x113C;
|
||||
case GasTrapType.WestWall:
|
||||
return 0x1147;
|
||||
case GasTrapType.Floor:
|
||||
return 0x11A8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (this.m_Poison == null || !from.Player || !from.Alive || from.IsStaff())
|
||||
return;
|
||||
|
||||
Effects.SendLocationEffect(this.Location, this.Map, GetBaseID(this.Type) - 2, 16, 3, this.GetEffectHue(), 0);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x231);
|
||||
|
||||
from.ApplyPoison(from, this.m_Poison);
|
||||
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x22, 500855); // You are enveloped by a noxious gas cloud!
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
Poison.Serialize(this.m_Poison, writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
this.m_Poison = Poison.Deserialize(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Scripts/Items/Functional/GiantSpikeTrap.cs
Normal file
71
Scripts/Items/Functional/GiantSpikeTrap.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GiantSpikeTrap : BaseTrap
|
||||
{
|
||||
[Constructable]
|
||||
public GiantSpikeTrap()
|
||||
: base(1)
|
||||
{
|
||||
}
|
||||
|
||||
public GiantSpikeTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds(0.0);
|
||||
}
|
||||
}
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (from.IsStaff())
|
||||
return;
|
||||
|
||||
Effects.SendLocationEffect(this.Location, this.Map, 0x1D99, 48, 2, this.GetEffectHue(), 0);
|
||||
|
||||
if (from.Alive && this.CheckRange(from.Location, 0))
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), from, from, Utility.Dice(10, 7, 0));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
223
Scripts/Items/Functional/GoblinFloorTrap.cs
Normal file
223
Scripts/Items/Functional/GoblinFloorTrap.cs
Normal file
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GoblinFloorTrap : BaseTrap, IRevealableItem
|
||||
{
|
||||
private Mobile m_Owner;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get { return m_Owner; } set { m_Owner = value; } }
|
||||
|
||||
public override int LabelNumber { get { return 1113296; } } // Armed Floor Trap
|
||||
public bool CheckWhenHidden { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public GoblinFloorTrap() : this( null )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GoblinFloorTrap(Mobile from) : base( 0x4004 )
|
||||
{
|
||||
m_Owner = from;
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public override bool PassivelyTriggered{ get{ return true; } }
|
||||
public override TimeSpan PassiveTriggerDelay{ get{ return TimeSpan.FromSeconds( 1.0 ); } }
|
||||
public override int PassiveTriggerRange{ get{ return 1; } }
|
||||
public override TimeSpan ResetDelay{ get{ return TimeSpan.FromSeconds( 1.0 ); } }
|
||||
|
||||
public override void OnTrigger( Mobile from )
|
||||
{
|
||||
if (from.AccessLevel > AccessLevel.Player || !from.Alive)
|
||||
return;
|
||||
|
||||
if( m_Owner != null )
|
||||
{
|
||||
if( !m_Owner.CanBeHarmful( from ) || m_Owner == from )
|
||||
return;
|
||||
|
||||
if( m_Owner.Guild != null && m_Owner.Guild == from.Guild )
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendSound(0x22B);
|
||||
from.SendLocalizedMessage(1095157); // You stepped onto a goblin trap!
|
||||
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromSeconds(0.30), from, from, Utility.RandomMinMax(50, 75), 100, 0, 0, 0, 0);
|
||||
|
||||
if(m_Owner != null)
|
||||
from.DoHarmful(m_Owner);
|
||||
|
||||
Visible = true;
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(Rehide_Callback));
|
||||
|
||||
PublicOverheadMessage(Server.Network.MessageType.Regular, 0x65, 500813); // [Trapped]
|
||||
|
||||
new Blood().MoveToWorld(from.Location, from.Map);
|
||||
}
|
||||
|
||||
public virtual bool CheckReveal(Mobile m)
|
||||
{
|
||||
return m.CheckTargetSkill(SkillName.DetectHidden, this, 50.0, 100.0);
|
||||
}
|
||||
|
||||
public virtual void OnRevealed(Mobile m)
|
||||
{
|
||||
Unhide();
|
||||
}
|
||||
|
||||
public virtual bool CheckPassiveDetect(Mobile m)
|
||||
{
|
||||
if (Visible && 0.05 > Utility.RandomDouble())
|
||||
{
|
||||
if (m.NetState != null)
|
||||
{
|
||||
Packet p = new MessageLocalized(this.Serial, this.ItemID, Network.MessageType.Regular, 0x65, 3, 500813, this.Name, String.Empty);
|
||||
p.Acquire();
|
||||
m.NetState.Send(p);
|
||||
Packet.Release(p);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Unhide()
|
||||
{
|
||||
Visible = true;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(Rehide_Callback));
|
||||
}
|
||||
|
||||
public void Rehide_Callback()
|
||||
{
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
public GoblinFloorTrap( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write(m_Owner);
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
m_Owner = reader.ReadMobile();
|
||||
}
|
||||
}
|
||||
|
||||
public class GoblinFloorTrapKit : Item
|
||||
{
|
||||
[Constructable]
|
||||
public GoblinFloorTrapKit() : base (16704)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
Region r = from.Region;
|
||||
|
||||
if(!IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1054107); // This item must be in your backpack.
|
||||
}
|
||||
else if (from.Skills[SkillName.Tinkering].Value < 80)
|
||||
{
|
||||
from.SendLocalizedMessage(1113318); // You do not have enough skill to set the trap.
|
||||
}
|
||||
else if (from.Mounted || from.Flying)
|
||||
{
|
||||
from.SendLocalizedMessage(1113319); // You cannot set the trap while riding or flying.
|
||||
}
|
||||
else if (r is GuardedRegion && !((GuardedRegion)r).IsDisabled())
|
||||
{
|
||||
from.SendMessage("You cannot place a trap in a guard region.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private GoblinFloorTrapKit m_Kit;
|
||||
|
||||
public InternalTarget(GoblinFloorTrapKit kit) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Kit = kit;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if(targeted is IPoint3D)
|
||||
{
|
||||
Point3D p = new Point3D((IPoint3D)targeted);
|
||||
Region r = Region.Find(p, from.Map);
|
||||
|
||||
if (from.Skills[SkillName.Tinkering].Value < 80)
|
||||
{
|
||||
from.SendLocalizedMessage(1113318); // You do not have enough skill to set the trap.
|
||||
}
|
||||
else if (from.Mounted || from.Flying)
|
||||
{
|
||||
from.SendLocalizedMessage(1113319); // You cannot set the trap while riding or flying.
|
||||
}
|
||||
else if (r is GuardedRegion && !((GuardedRegion)r).IsDisabled())
|
||||
{
|
||||
from.SendMessage("You cannot place a trap in a guard region.");
|
||||
}
|
||||
if (from.InRange(p, 2))
|
||||
{
|
||||
GoblinFloorTrap trap = new GoblinFloorTrap(from);
|
||||
|
||||
trap.MoveToWorld(p, from.Map);
|
||||
from.SendLocalizedMessage(1113294); // You carefully arm the goblin trap.
|
||||
from.SendLocalizedMessage(1113297); // You hide the trap to the best of your ability.
|
||||
|
||||
m_Kit.Consume();
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GoblinFloorTrapKit( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
120
Scripts/Items/Functional/Grinder.cs
Normal file
120
Scripts/Items/Functional/Grinder.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Targeting;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flipable(0x9A97, 0x9A98)]
|
||||
public class Grinder : Item, ISecurable
|
||||
{
|
||||
public override int LabelNumber { get { return 1123599; } } // Grinder
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public Grinder()
|
||||
: base(0x9A97)
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
/*public bool CheckAccessible(Mobile from, Item item)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
return true; // Staff can access anything
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt(item);
|
||||
|
||||
if (house == null)
|
||||
return false;
|
||||
|
||||
switch (Level)
|
||||
{
|
||||
case SecureLevel.Owner: return house.IsOwner(from);
|
||||
case SecureLevel.CoOwners: return house.IsCoOwner(from);
|
||||
case SecureLevel.Friends: return house.IsFriend(from);
|
||||
case SecureLevel.Anyone: return true;
|
||||
case SecureLevel.Guild: return house.IsGuildMember(from);
|
||||
}
|
||||
|
||||
return false;
|
||||
}*/
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public Grinder(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
var house = BaseHouse.FindHouseAt(this);
|
||||
|
||||
if (house == null || !house.IsLockedDown(this))
|
||||
{
|
||||
from.SendLocalizedMessage(1114298); // This must be locked down in order to use it.
|
||||
}
|
||||
else if (from.InRange(GetWorldLocation(), 2) /*&& CheckAccessible(from, this)*/)
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public InternalTarget(Item item)
|
||||
: base(-1, true, TargetFlags.None)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is CoffeePod)
|
||||
{
|
||||
var pod = (CoffeePod)targeted;
|
||||
|
||||
if (!pod.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.AddToBackpack(new CoffeeGrounds(pod.Amount));
|
||||
pod.Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1155729); // That is not something that can be ground.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((int)Level);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
1080
Scripts/Items/Functional/HouseCraftables.cs
Normal file
1080
Scripts/Items/Functional/HouseCraftables.cs
Normal file
File diff suppressed because it is too large
Load Diff
286
Scripts/Items/Functional/HouseDoors.cs
Normal file
286
Scripts/Items/Functional/HouseDoors.cs
Normal file
@@ -0,0 +1,286 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MetalHouseDoor : BaseHouseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public MetalHouseDoor(DoorFacing facing)
|
||||
: base(facing, 0x675 + (2 * (int)facing), 0x676 + (2 * (int)facing), 0xEC, 0xF3, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public MetalHouseDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class DarkWoodHouseDoor : BaseHouseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public DarkWoodHouseDoor(DoorFacing facing)
|
||||
: base(facing, 0x6A5 + (2 * (int)facing), 0x6A6 + (2 * (int)facing), 0xEA, 0xF1, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public DarkWoodHouseDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class GenericHouseDoor : BaseHouseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public GenericHouseDoor(DoorFacing facing, int baseItemID, int openedSound, int closedSound)
|
||||
: this(facing, baseItemID, openedSound, closedSound, true)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GenericHouseDoor(DoorFacing facing, int baseItemID, int openedSound, int closedSound, bool autoAdjust)
|
||||
: base(facing, baseItemID + (autoAdjust ? (2 * (int)facing) : 0), baseItemID + 1 + (autoAdjust ? (2 * (int)facing) : 0), openedSound, closedSound, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public GenericHouseDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseHouseDoor : BaseDoor, ISecurable
|
||||
{
|
||||
private DoorFacing m_Facing;
|
||||
private SecureLevel m_Level;
|
||||
|
||||
public BaseHouseDoor(DoorFacing facing, int closedID, int openedID, int openedSound, int closedSound, Point3D offset)
|
||||
: base(closedID, openedID, openedSound, closedSound, offset)
|
||||
{
|
||||
m_Facing = facing;
|
||||
m_Level = SecureLevel.Anyone;
|
||||
}
|
||||
|
||||
public BaseHouseDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DoorFacing Facing
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Facing;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Facing = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Level;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Level = value;
|
||||
}
|
||||
}
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public BaseHouse FindHouse()
|
||||
{
|
||||
Point3D loc;
|
||||
|
||||
if (Open)
|
||||
loc = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z);
|
||||
else
|
||||
loc = Location;
|
||||
|
||||
return BaseHouse.FindHouseAt(loc, Map, 20);
|
||||
}
|
||||
|
||||
public bool CheckAccess(Mobile m)
|
||||
{
|
||||
BaseHouse house = FindHouse();
|
||||
|
||||
if (house == null)
|
||||
return false;
|
||||
|
||||
if (!house.IsAosRules)
|
||||
return true;
|
||||
|
||||
if (house.Public ? house.IsBanned(m) : !house.HasAccess(m))
|
||||
return false;
|
||||
|
||||
return house.HasSecureAccess(m, m_Level);
|
||||
}
|
||||
|
||||
public override void OnOpened(Mobile from)
|
||||
{
|
||||
BaseHouse house = FindHouse();
|
||||
|
||||
if (house != null && house.IsFriend(from) && from.IsPlayer() && house.RefreshDecay())
|
||||
from.SendLocalizedMessage(1043293); // Your house's age and contents have been refreshed.
|
||||
|
||||
if (!Core.AOS && house != null && house.Public && !house.IsFriend(from))
|
||||
house.AddVisit(from);
|
||||
}
|
||||
|
||||
public override bool UseLocks()
|
||||
{
|
||||
BaseHouse house = FindHouse();
|
||||
|
||||
return (house == null || !house.IsAosRules);
|
||||
}
|
||||
|
||||
public override void Use(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel == AccessLevel.Player && !CheckAccess(from))
|
||||
from.SendLocalizedMessage(1061637); // You are not allowed to access
|
||||
else
|
||||
base.Use(from);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write((int)m_Level);
|
||||
|
||||
writer.Write((int)m_Facing);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Level = (SecureLevel)reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if (version < 1)
|
||||
m_Level = SecureLevel.Anyone;
|
||||
|
||||
m_Facing = (DoorFacing)reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsInside(Mobile from)
|
||||
{
|
||||
int x,y,w,h;
|
||||
|
||||
const int r = 2;
|
||||
const int bs = r * 2 + 1;
|
||||
const int ss = r + 1;
|
||||
|
||||
switch ( m_Facing )
|
||||
{
|
||||
case DoorFacing.WestCW:
|
||||
case DoorFacing.EastCCW:
|
||||
x = -r;
|
||||
y = -r;
|
||||
w = bs;
|
||||
h = ss;
|
||||
break;
|
||||
case DoorFacing.EastCW:
|
||||
case DoorFacing.WestCCW:
|
||||
x = -r;
|
||||
y = 0;
|
||||
w = bs;
|
||||
h = ss;
|
||||
break;
|
||||
case DoorFacing.SouthCW:
|
||||
case DoorFacing.NorthCCW:
|
||||
x = -r;
|
||||
y = -r;
|
||||
w = ss;
|
||||
h = bs;
|
||||
break;
|
||||
case DoorFacing.NorthCW:
|
||||
case DoorFacing.SouthCCW:
|
||||
x = 0;
|
||||
y = -r;
|
||||
w = ss;
|
||||
h = bs;
|
||||
break;
|
||||
//No way to test the 'insideness' of SE Sliding doors on OSI, so leaving them default to false until furthur information gained
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
int rx = from.X - X;
|
||||
int ry = from.Y - Y;
|
||||
int az = Math.Abs(from.Z - Z);
|
||||
|
||||
return (rx >= x && rx < (x + w) && ry >= y && ry < (y + h) && az <= 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
764
Scripts/Items/Functional/HouseRaffleStone.cs
Normal file
764
Scripts/Items/Functional/HouseRaffleStone.cs
Normal file
@@ -0,0 +1,764 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Server.Accounting;
|
||||
using Server.ContextMenus;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum HouseRaffleState
|
||||
{
|
||||
Inactive,
|
||||
Active,
|
||||
Completed
|
||||
}
|
||||
|
||||
public enum HouseRaffleExpireAction
|
||||
{
|
||||
None,
|
||||
HideStone,
|
||||
DeleteStone
|
||||
}
|
||||
|
||||
public class RaffleEntry
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly IPAddress m_Address;
|
||||
private readonly DateTime m_Date;
|
||||
public RaffleEntry(Mobile from)
|
||||
{
|
||||
this.m_From = from;
|
||||
|
||||
if (this.m_From.NetState != null)
|
||||
this.m_Address = this.m_From.NetState.Address;
|
||||
else
|
||||
this.m_Address = IPAddress.None;
|
||||
|
||||
this.m_Date = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public RaffleEntry(GenericReader reader, int version)
|
||||
{
|
||||
switch ( version )
|
||||
{
|
||||
case 3: // HouseRaffleStone version changes
|
||||
case 2:
|
||||
case 1:
|
||||
case 0:
|
||||
{
|
||||
this.m_From = reader.ReadMobile();
|
||||
this.m_Address = Utility.Intern(reader.ReadIPAddress());
|
||||
this.m_Date = reader.ReadDateTime();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile From
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_From;
|
||||
}
|
||||
}
|
||||
public IPAddress Address
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Address;
|
||||
}
|
||||
}
|
||||
public DateTime Date
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Date;
|
||||
}
|
||||
}
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(this.m_From);
|
||||
writer.Write(this.m_Address);
|
||||
writer.Write(this.m_Date);
|
||||
}
|
||||
}
|
||||
|
||||
[FlipableAttribute(0xEDD, 0xEDE)]
|
||||
public class HouseRaffleStone : Item
|
||||
{
|
||||
public static readonly TimeSpan DefaultDuration = TimeSpan.FromDays(7.0);
|
||||
public static readonly TimeSpan ExpirationTime = TimeSpan.FromDays(30.0);
|
||||
private static readonly List<HouseRaffleStone> m_AllStones = new List<HouseRaffleStone>();
|
||||
private const int EntryLimitPerIP = 4;
|
||||
private const int DefaultTicketPrice = 5000;
|
||||
private const int MessageHue = 1153;
|
||||
private HouseRaffleRegion m_Region;
|
||||
private Rectangle2D m_Bounds;
|
||||
private Map m_Facet;
|
||||
private Mobile m_Winner;
|
||||
private HouseRaffleDeed m_Deed;
|
||||
private HouseRaffleState m_State;
|
||||
private DateTime m_Started;
|
||||
private TimeSpan m_Duration;
|
||||
private HouseRaffleExpireAction m_ExpireAction;
|
||||
private int m_TicketPrice;
|
||||
private List<RaffleEntry> m_Entries;
|
||||
[Constructable]
|
||||
public HouseRaffleStone()
|
||||
: base(0xEDD)
|
||||
{
|
||||
this.m_Region = null;
|
||||
this.m_Bounds = new Rectangle2D();
|
||||
this.m_Facet = null;
|
||||
|
||||
this.m_Winner = null;
|
||||
this.m_Deed = null;
|
||||
|
||||
this.m_State = HouseRaffleState.Inactive;
|
||||
this.m_Started = DateTime.MinValue;
|
||||
this.m_Duration = DefaultDuration;
|
||||
this.m_ExpireAction = HouseRaffleExpireAction.None;
|
||||
this.m_TicketPrice = DefaultTicketPrice;
|
||||
|
||||
this.m_Entries = new List<RaffleEntry>();
|
||||
|
||||
this.Movable = false;
|
||||
|
||||
m_AllStones.Add(this);
|
||||
}
|
||||
|
||||
public HouseRaffleStone(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public HouseRaffleState CurrentState
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_State;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.m_State != value)
|
||||
{
|
||||
if (value == HouseRaffleState.Active)
|
||||
{
|
||||
this.m_Entries.Clear();
|
||||
this.m_Winner = null;
|
||||
this.m_Deed = null;
|
||||
this.m_Started = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
this.m_State = value;
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public Rectangle2D PlotBounds
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Bounds;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Bounds = value;
|
||||
|
||||
this.InvalidateRegion();
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public Map PlotFacet
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Facet;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Facet = value;
|
||||
|
||||
this.InvalidateRegion();
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public Mobile Winner
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Winner;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Winner = value;
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public HouseRaffleDeed Deed
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Deed;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Deed = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public DateTime Started
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Started;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Started = value;
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Duration;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Duration = value;
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsExpired
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.m_State != HouseRaffleState.Completed)
|
||||
return false;
|
||||
|
||||
return (this.m_Started + this.m_Duration + ExpirationTime <= DateTime.UtcNow);
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public HouseRaffleExpireAction ExpireAction
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_ExpireAction;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_ExpireAction = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Seer)]
|
||||
public int TicketPrice
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_TicketPrice;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_TicketPrice = Math.Max(0, value);
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
public List<RaffleEntry> Entries
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Entries;
|
||||
}
|
||||
}
|
||||
public override string DefaultName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "a house raffle stone";
|
||||
}
|
||||
}
|
||||
public override bool DisplayWeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static void CheckEnd_OnTick()
|
||||
{
|
||||
for (int i = 0; i < m_AllStones.Count; i++)
|
||||
m_AllStones[i].CheckEnd();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
for (int i = m_AllStones.Count - 1; i >= 0; i--)
|
||||
{
|
||||
HouseRaffleStone stone = m_AllStones[i];
|
||||
|
||||
if (stone.IsExpired)
|
||||
{
|
||||
switch ( stone.ExpireAction )
|
||||
{
|
||||
case HouseRaffleExpireAction.HideStone:
|
||||
{
|
||||
if (stone.Visible)
|
||||
{
|
||||
stone.Visible = false;
|
||||
stone.ItemID = 0x1B7B; // Non-blocking ItemID
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case HouseRaffleExpireAction.DeleteStone:
|
||||
{
|
||||
stone.Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(1.0), new TimerCallback(CheckEnd_OnTick));
|
||||
}
|
||||
|
||||
public static string FormatLocation(Point3D loc, Map map, bool displayMap)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
int xLong = 0, yLat = 0;
|
||||
int xMins = 0, yMins = 0;
|
||||
bool xEast = false, ySouth = false;
|
||||
|
||||
if (Sextant.Format(loc, map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
|
||||
result.AppendFormat("{0}<7D>{1}'{2},{3}<7D>{4}'{5}", yLat, yMins, ySouth ? "S" : "N", xLong, xMins, xEast ? "E" : "W");
|
||||
else
|
||||
result.AppendFormat("{0},{1}", loc.X, loc.Y);
|
||||
|
||||
if (displayMap)
|
||||
result.AppendFormat(" ({0})", map);
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
public bool ValidLocation()
|
||||
{
|
||||
return (this.m_Bounds.Start != Point2D.Zero && this.m_Bounds.End != Point2D.Zero && this.m_Facet != null && this.m_Facet != Map.Internal);
|
||||
}
|
||||
|
||||
public Point3D GetPlotCenter()
|
||||
{
|
||||
int x = this.m_Bounds.X + this.m_Bounds.Width / 2;
|
||||
int y = this.m_Bounds.Y + this.m_Bounds.Height / 2;
|
||||
int z = (this.m_Facet == null) ? 0 : this.m_Facet.GetAverageZ(x, y);
|
||||
|
||||
return new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
public string FormatLocation()
|
||||
{
|
||||
if (!this.ValidLocation())
|
||||
return "no location set";
|
||||
|
||||
return FormatLocation(this.GetPlotCenter(), this.m_Facet, true);
|
||||
}
|
||||
|
||||
public string FormatPrice()
|
||||
{
|
||||
if (this.m_TicketPrice == 0)
|
||||
return "FREE";
|
||||
else
|
||||
return String.Format("{0} gold", this.m_TicketPrice);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (this.ValidLocation())
|
||||
list.Add(this.FormatLocation());
|
||||
|
||||
switch (this.m_State)
|
||||
{
|
||||
case HouseRaffleState.Active:
|
||||
{
|
||||
list.Add(1060658, "ticket price\t{0}", this.FormatPrice()); // ~1_val~: ~2_val~
|
||||
list.Add(1060659, "ends\t{0}", this.m_Started + this.m_Duration); // ~1_val~: ~2_val~
|
||||
break;
|
||||
}
|
||||
case HouseRaffleState.Completed:
|
||||
{
|
||||
list.Add(1060658, "winner\t{0}", (this.m_Winner == null) ? "unknown" : this.m_Winner.Name); // ~1_val~: ~2_val~
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
base.OnSingleClick(from);
|
||||
|
||||
switch (this.m_State)
|
||||
{
|
||||
case HouseRaffleState.Active:
|
||||
{
|
||||
this.LabelTo(from, 1060658, String.Format("Ends\t{0}", this.m_Started + this.m_Duration)); // ~1_val~: ~2_val~
|
||||
break;
|
||||
}
|
||||
case HouseRaffleState.Completed:
|
||||
{
|
||||
this.LabelTo(from, 1060658, String.Format("Winner\t{0}", (this.m_Winner == null) ? "Unknown" : this.m_Winner.Name)); // ~1_val~: ~2_val~
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (from.AccessLevel >= AccessLevel.Seer)
|
||||
{
|
||||
list.Add(new EditEntry(from, this));
|
||||
|
||||
if (this.m_State == HouseRaffleState.Inactive)
|
||||
list.Add(new ActivateEntry(from, this));
|
||||
else
|
||||
list.Add(new ManagementEntry(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (this.m_State != HouseRaffleState.Active || !from.CheckAlive())
|
||||
return;
|
||||
|
||||
if (!from.InRange(this.GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.HasEntered(from))
|
||||
{
|
||||
from.SendMessage(MessageHue, "You have already entered this plot's raffle.");
|
||||
}
|
||||
else if (this.IsAtIPLimit(from))
|
||||
{
|
||||
from.SendMessage(MessageHue, "You may not enter this plot's raffle.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendGump(new WarningGump(1150470, 0x7F00, String.Format("You are about to purchase a raffle ticket for the house plot located at {0}. The ticket price is {1}. Tickets are non-refundable and you can only purchase one ticket per account. Do you wish to continue?", this.FormatLocation(), this.FormatPrice()), 0xFFFFFF, 420, 280, new WarningGumpCallback(Purchase_Callback), null)); // CONFIRM TICKET PURCHASE
|
||||
}
|
||||
}
|
||||
|
||||
public void Purchase_Callback(Mobile from, bool okay, object state)
|
||||
{
|
||||
if (this.Deleted || this.m_State != HouseRaffleState.Active || !from.CheckAlive() || this.HasEntered(from) || this.IsAtIPLimit(from))
|
||||
return;
|
||||
|
||||
Account acc = from.Account as Account;
|
||||
|
||||
if (acc == null)
|
||||
return;
|
||||
|
||||
if (okay)
|
||||
{
|
||||
Container bank = from.FindBankNoCreate();
|
||||
|
||||
if (this.m_TicketPrice == 0 || (from.Backpack != null && from.Backpack.ConsumeTotal(typeof(Gold), this.m_TicketPrice)) || Mobiles.Banker.Withdraw(from, m_TicketPrice, true))
|
||||
{
|
||||
this.m_Entries.Add(new RaffleEntry(from));
|
||||
|
||||
from.SendMessage(MessageHue, "You have successfully entered the plot's raffle.");
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(MessageHue, "You do not have the {0} required to enter the raffle.", this.FormatPrice());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage(MessageHue, "You have chosen not to enter the raffle.");
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckEnd()
|
||||
{
|
||||
if (this.m_State != HouseRaffleState.Active || this.m_Started + this.m_Duration > DateTime.UtcNow)
|
||||
return;
|
||||
|
||||
this.m_State = HouseRaffleState.Completed;
|
||||
|
||||
if (this.m_Region != null && this.m_Entries.Count != 0)
|
||||
{
|
||||
int winner = Utility.Random(this.m_Entries.Count);
|
||||
|
||||
this.m_Winner = this.m_Entries[winner].From;
|
||||
|
||||
if (this.m_Winner != null)
|
||||
{
|
||||
this.m_Deed = new HouseRaffleDeed(this, this.m_Winner);
|
||||
|
||||
this.m_Winner.SendMessage(MessageHue, "Congratulations, {0}! You have won the raffle for the plot located at {1}.", this.m_Winner.Name, this.FormatLocation());
|
||||
|
||||
if (this.m_Winner.AddToBackpack(this.m_Deed))
|
||||
{
|
||||
this.m_Winner.SendMessage(MessageHue, "The writ of lease has been placed in your backpack.");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Winner.BankBox.DropItem(this.m_Deed);
|
||||
this.m_Winner.SendMessage(MessageHue, "As your backpack is full, the writ of lease has been placed in your bank box.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.InvalidateProperties();
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
if (this.m_Region != null)
|
||||
{
|
||||
this.m_Region.Unregister();
|
||||
this.m_Region = null;
|
||||
}
|
||||
|
||||
m_AllStones.Remove(this);
|
||||
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)3); // version
|
||||
|
||||
writer.WriteEncodedInt((int)this.m_State);
|
||||
writer.WriteEncodedInt((int)this.m_ExpireAction);
|
||||
|
||||
writer.Write(this.m_Deed);
|
||||
|
||||
writer.Write(this.m_Bounds);
|
||||
writer.Write(this.m_Facet);
|
||||
|
||||
writer.Write(this.m_Winner);
|
||||
|
||||
writer.Write(this.m_TicketPrice);
|
||||
writer.Write(this.m_Started);
|
||||
writer.Write(this.m_Duration);
|
||||
|
||||
writer.Write(this.m_Entries.Count);
|
||||
|
||||
foreach (RaffleEntry entry in this.m_Entries)
|
||||
entry.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
this.m_State = (HouseRaffleState)reader.ReadEncodedInt();
|
||||
|
||||
goto case 2;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
this.m_ExpireAction = (HouseRaffleExpireAction)reader.ReadEncodedInt();
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
this.m_Deed = reader.ReadItem<HouseRaffleDeed>();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
bool oldActive = (version < 3) ? reader.ReadBool() : false;
|
||||
|
||||
this.m_Bounds = reader.ReadRect2D();
|
||||
this.m_Facet = reader.ReadMap();
|
||||
|
||||
this.m_Winner = reader.ReadMobile();
|
||||
|
||||
this.m_TicketPrice = reader.ReadInt();
|
||||
this.m_Started = reader.ReadDateTime();
|
||||
this.m_Duration = reader.ReadTimeSpan();
|
||||
|
||||
int entryCount = reader.ReadInt();
|
||||
this.m_Entries = new List<RaffleEntry>(entryCount);
|
||||
|
||||
for (int i = 0; i < entryCount; i++)
|
||||
{
|
||||
RaffleEntry entry = new RaffleEntry(reader, version);
|
||||
|
||||
if (entry.From == null)
|
||||
continue; // Character was deleted
|
||||
|
||||
this.m_Entries.Add(entry);
|
||||
}
|
||||
|
||||
this.InvalidateRegion();
|
||||
|
||||
m_AllStones.Add(this);
|
||||
|
||||
if (version < 3)
|
||||
{
|
||||
if (oldActive)
|
||||
this.m_State = HouseRaffleState.Active;
|
||||
else if (this.m_Winner != null)
|
||||
this.m_State = HouseRaffleState.Completed;
|
||||
else
|
||||
this.m_State = HouseRaffleState.Inactive;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InvalidateRegion()
|
||||
{
|
||||
if (this.m_Region != null)
|
||||
{
|
||||
this.m_Region.Unregister();
|
||||
this.m_Region = null;
|
||||
}
|
||||
|
||||
if (this.ValidLocation())
|
||||
{
|
||||
this.m_Region = new HouseRaffleRegion(this);
|
||||
this.m_Region.Register();
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasEntered(Mobile from)
|
||||
{
|
||||
Account acc = from.Account as Account;
|
||||
|
||||
if (acc == null)
|
||||
return false;
|
||||
|
||||
foreach (RaffleEntry entry in this.m_Entries)
|
||||
{
|
||||
if (entry.From != null)
|
||||
{
|
||||
Account entryAcc = entry.From.Account as Account;
|
||||
|
||||
if (entryAcc == acc)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsAtIPLimit(Mobile from)
|
||||
{
|
||||
if (from.NetState == null)
|
||||
return false;
|
||||
|
||||
IPAddress address = from.NetState.Address;
|
||||
int tickets = 0;
|
||||
|
||||
foreach (RaffleEntry entry in this.m_Entries)
|
||||
{
|
||||
if (Utility.IPMatchClassC(entry.Address, address))
|
||||
{
|
||||
if (++tickets >= EntryLimitPerIP)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private class RaffleContextMenuEntry : ContextMenuEntry
|
||||
{
|
||||
protected readonly Mobile m_From;
|
||||
protected readonly HouseRaffleStone m_Stone;
|
||||
public RaffleContextMenuEntry(Mobile from, HouseRaffleStone stone, int label)
|
||||
: base(label)
|
||||
{
|
||||
this.m_From = from;
|
||||
this.m_Stone = stone;
|
||||
}
|
||||
}
|
||||
|
||||
private class EditEntry : RaffleContextMenuEntry
|
||||
{
|
||||
public EditEntry(Mobile from, HouseRaffleStone stone)
|
||||
: base(from, stone, 5101)// Edit
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (this.m_Stone.Deleted || this.m_From.AccessLevel < AccessLevel.Seer)
|
||||
return;
|
||||
|
||||
this.m_From.SendGump(new PropertiesGump(this.m_From, this.m_Stone));
|
||||
}
|
||||
}
|
||||
|
||||
private class ActivateEntry : RaffleContextMenuEntry
|
||||
{
|
||||
public ActivateEntry(Mobile from, HouseRaffleStone stone)
|
||||
: base(from, stone, 5113)// Start
|
||||
{
|
||||
if (!stone.ValidLocation())
|
||||
this.Flags |= Network.CMEFlags.Disabled;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (this.m_Stone.Deleted || this.m_From.AccessLevel < AccessLevel.Seer || !this.m_Stone.ValidLocation())
|
||||
return;
|
||||
|
||||
this.m_Stone.CurrentState = HouseRaffleState.Active;
|
||||
}
|
||||
}
|
||||
|
||||
private class ManagementEntry : RaffleContextMenuEntry
|
||||
{
|
||||
public ManagementEntry(Mobile from, HouseRaffleStone stone)
|
||||
: base(from, stone, 5032)// Game Monitor
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (this.m_Stone.Deleted || this.m_From.AccessLevel < AccessLevel.Seer)
|
||||
return;
|
||||
|
||||
this.m_From.SendGump(new HouseRaffleManagementGump(this.m_Stone));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Scripts/Items/Functional/Incubator.cs
Normal file
159
Scripts/Items/Functional/Incubator.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Engines;
|
||||
using Server.Multis;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute(0x407C, 0x407D)]
|
||||
public class Incubator : Container, ISecurable
|
||||
{
|
||||
public static readonly int MaxEggs = 6;
|
||||
|
||||
public override int LabelNumber { get { return 1112479; } } //an incubator
|
||||
|
||||
private SecureLevel m_Level;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level
|
||||
{
|
||||
get { return m_Level; }
|
||||
set { m_Level = value; }
|
||||
}
|
||||
|
||||
public override int DefaultGumpID { get { return 1156; } }
|
||||
public override int DefaultDropSound { get { return 66; } }
|
||||
|
||||
[Constructable]
|
||||
public Incubator()
|
||||
: base(0x407C)
|
||||
{
|
||||
m_Level = SecureLevel.CoOwners;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
|
||||
{
|
||||
bool canDrop = base.OnDragDropInto(from, item, p);
|
||||
|
||||
if (canDrop && item is ChickenLizardEgg)
|
||||
{
|
||||
ChickenLizardEgg egg = (ChickenLizardEgg)item;
|
||||
|
||||
if (egg.TotalIncubationTime > TimeSpan.FromHours(120))
|
||||
egg.BurnEgg();
|
||||
else
|
||||
{
|
||||
egg.IncubationStart = DateTime.UtcNow;
|
||||
egg.Incubating = true;
|
||||
}
|
||||
}
|
||||
|
||||
return canDrop;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item item)
|
||||
{
|
||||
bool canDrop = base.OnDragDrop(from, item);
|
||||
|
||||
if (canDrop && item is ChickenLizardEgg)
|
||||
{
|
||||
ChickenLizardEgg egg = (ChickenLizardEgg)item;
|
||||
|
||||
if (egg.TotalIncubationTime > TimeSpan.FromHours(120))
|
||||
egg.BurnEgg();
|
||||
else
|
||||
{
|
||||
egg.IncubationStart = DateTime.UtcNow;
|
||||
egg.Incubating = true;
|
||||
}
|
||||
}
|
||||
|
||||
return canDrop;
|
||||
}
|
||||
|
||||
public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
|
||||
{
|
||||
if (!BaseHouse.CheckSecured(this))
|
||||
{
|
||||
m.SendLocalizedMessage(1113711); //The incubator must be secured for the egg to grow, not locked down.
|
||||
return false;
|
||||
}
|
||||
if (!(item is ChickenLizardEgg))
|
||||
{
|
||||
m.SendMessage("This will only accept chicken eggs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MaxEggs > -1 && Items.Count >= MaxEggs)
|
||||
{
|
||||
m.SendMessage("You can only put {0} chicken eggs in the incubator at a time.", MaxEggs.ToString()); //TODO: Get Message
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CheckEggs_Callback()
|
||||
{
|
||||
if (!BaseHouse.CheckSecured(this))
|
||||
return;
|
||||
|
||||
foreach (Item item in Items)
|
||||
{
|
||||
if (item is ChickenLizardEgg)
|
||||
((ChickenLizardEgg)item).CheckStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("IncreaseStage", AccessLevel.Counselor, new CommandEventHandler(IncreaseStage_OnCommand));
|
||||
}
|
||||
|
||||
public static void IncreaseStage_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
e.Mobile.SendMessage("Target the egg.");
|
||||
e.Mobile.BeginTarget(12, false, Server.Targeting.TargetFlags.None, new TargetCallback(IncreaseStage_OnTarget));
|
||||
}
|
||||
|
||||
public static void IncreaseStage_OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is ChickenLizardEgg)
|
||||
{
|
||||
((ChickenLizardEgg)targeted).TotalIncubationTime += TimeSpan.FromHours(24);
|
||||
((ChickenLizardEgg)targeted).CheckStatus();
|
||||
}
|
||||
}
|
||||
|
||||
public Incubator(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((int)m_Level);
|
||||
|
||||
if (Items.Count > 0)
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(CheckEggs_Callback));
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Level = (SecureLevel)reader.ReadInt();
|
||||
|
||||
if (Items.Count > 0)
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(60), new TimerCallback(CheckEggs_Callback));
|
||||
}
|
||||
}
|
||||
}
|
||||
173
Scripts/Items/Functional/JewelryBox/JewelryBox.cs
Normal file
173
Scripts/Items/Functional/JewelryBox/JewelryBox.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Multis;
|
||||
using Server.ContextMenus;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Furniture]
|
||||
[FlipableAttribute(0x9F1C, 0x9F1D)]
|
||||
public class JewelryBox : Container, IDyable
|
||||
{
|
||||
public override int LabelNumber { get { return 1157694; } } // Jewelry Box
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
public JewelryBoxFilter Filter { get; set; }
|
||||
|
||||
public override int DefaultMaxItems { get { return 500; } }
|
||||
|
||||
public bool IsFull { get { return DefaultMaxItems <= Items.Count; } }
|
||||
|
||||
[Constructable]
|
||||
public JewelryBox()
|
||||
: base(0x9F1C)
|
||||
{
|
||||
Weight = 10.0;
|
||||
Filter = new JewelryBoxFilter();
|
||||
Level = SecureLevel.CoOwners;
|
||||
}
|
||||
|
||||
public bool Dye(Mobile from, DyeTub sender)
|
||||
{
|
||||
if (Deleted)
|
||||
return false;
|
||||
|
||||
Hue = sender.DyedHue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
base.OnDoubleClick(from);
|
||||
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
else if (!IsLockedDown && !IsSecure)
|
||||
{
|
||||
from.SendLocalizedMessage(1157727); // The jewelry box must be secured before you can use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendGump(new JewelryBoxGump(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckAccessible(Mobile from, Item item)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
return true; // Staff can access anything
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt(item);
|
||||
|
||||
if (house == null)
|
||||
return false;
|
||||
|
||||
switch (Level)
|
||||
{
|
||||
case SecureLevel.Owner: return house.IsOwner(from);
|
||||
case SecureLevel.CoOwners: return house.IsCoOwner(from);
|
||||
case SecureLevel.Friends: return house.IsFriend(from);
|
||||
case SecureLevel.Anyone: return true;
|
||||
case SecureLevel.Guild: return house.IsGuildMember(from);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public bool IsAccept(Item item)
|
||||
{
|
||||
foreach (Type type in _AcceptList)
|
||||
if (item.GetType().IsSubclassOf(type))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private Type[] _AcceptList =
|
||||
{
|
||||
typeof(BaseRing), typeof(BaseBracelet), typeof(BaseNecklace), typeof(BaseEarrings), typeof(BaseTalisman)
|
||||
};
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!IsLockedDown && !IsSecure)
|
||||
{
|
||||
from.SendLocalizedMessage(1157727); // The jewelry box must be secured before you can use it.
|
||||
return false;
|
||||
}
|
||||
else if (!CheckAccessible(from, this))
|
||||
{
|
||||
PrivateOverheadMessage(MessageType.Regular, 946, 1010563, from.NetState); // This container is secure.
|
||||
return false;
|
||||
}
|
||||
else if (!IsAccept(dropped))
|
||||
{
|
||||
from.SendLocalizedMessage(1157724); // This is not a ring, bracelet, necklace, earring, or talisman.
|
||||
return false;
|
||||
}
|
||||
else if (IsFull)
|
||||
{
|
||||
from.SendLocalizedMessage(1157723); // The jewelry box is full.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1), () => from.SendGump(new JewelryBoxGump(from, this)));
|
||||
return base.OnDragDrop(from, dropped);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplaysContent { get { return false; } }
|
||||
|
||||
public override int GetTotal(TotalType type)
|
||||
{
|
||||
if (type == TotalType.Weight)
|
||||
{
|
||||
int weight = base.GetTotal(type);
|
||||
|
||||
if (weight > 0)
|
||||
return (int)Math.Max(1, (base.GetTotal(type) * 0.3));
|
||||
}
|
||||
|
||||
return base.GetTotal(type);
|
||||
}
|
||||
|
||||
public JewelryBox(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
|
||||
writer.Write((int)Level);
|
||||
Filter.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
Filter = new JewelryBoxFilter(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
125
Scripts/Items/Functional/JewelryBox/JewelryBoxFilter.cs
Normal file
125
Scripts/Items/Functional/JewelryBox/JewelryBoxFilter.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class JewelryBoxFilter
|
||||
{
|
||||
public bool IsDefault
|
||||
{
|
||||
get { return (!Ring && !Bracelet && !Earrings && !Necklace && !Talisman); }
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Ring = false;
|
||||
m_Bracelet = false;
|
||||
m_Earrings = false;
|
||||
m_Necklace = false;
|
||||
m_Talisman = false;
|
||||
}
|
||||
|
||||
private bool m_Ring;
|
||||
|
||||
public bool Ring
|
||||
{
|
||||
get { return m_Ring; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
Clear();
|
||||
|
||||
m_Ring = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_Bracelet;
|
||||
public bool Bracelet
|
||||
{
|
||||
get { return m_Bracelet; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
Clear();
|
||||
|
||||
m_Bracelet = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_Earrings;
|
||||
public bool Earrings
|
||||
{
|
||||
get { return m_Earrings; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
Clear();
|
||||
|
||||
m_Earrings = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_Necklace;
|
||||
public bool Necklace
|
||||
{
|
||||
get { return m_Necklace; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
Clear();
|
||||
|
||||
m_Necklace = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_Talisman;
|
||||
public bool Talisman
|
||||
{
|
||||
get { return m_Talisman; }
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
Clear();
|
||||
|
||||
m_Talisman = value;
|
||||
}
|
||||
}
|
||||
|
||||
public JewelryBoxFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public JewelryBoxFilter(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
Ring = reader.ReadBool();
|
||||
Bracelet = reader.ReadBool();
|
||||
Earrings = reader.ReadBool();
|
||||
Necklace = reader.ReadBool();
|
||||
Talisman = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
if (IsDefault)
|
||||
{
|
||||
writer.Write((int)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write((bool)Ring);
|
||||
writer.Write((bool)Bracelet);
|
||||
writer.Write((bool)Earrings);
|
||||
writer.Write((bool)Necklace);
|
||||
writer.Write((bool)Talisman);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
420
Scripts/Items/Functional/JewelryBox/JewelryBoxGump.cs
Normal file
420
Scripts/Items/Functional/JewelryBox/JewelryBoxGump.cs
Normal file
@@ -0,0 +1,420 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class JewelryBoxGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private JewelryBox m_Box;
|
||||
private List<Item> m_List;
|
||||
|
||||
private int m_Page;
|
||||
|
||||
private const int LabelColor = 0x7FFF;
|
||||
|
||||
public bool CheckFilter(Item item)
|
||||
{
|
||||
JewelryBoxFilter f = m_Box.Filter;
|
||||
|
||||
if (f.IsDefault)
|
||||
return true;
|
||||
|
||||
if (f.Ring && item is BaseRing)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (f.Bracelet && item is BaseBracelet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (f.Earrings && item is BaseEarrings)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (f.Necklace && item is BaseNecklace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (f.Talisman && item is BaseTalisman)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetPageCount(int count)
|
||||
{
|
||||
return (count + 49) / 50;
|
||||
}
|
||||
|
||||
public int GetIndexForPage(int page)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
while (page-- > 0)
|
||||
index += GetCountForIndex(index);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
public int GetCountForIndex(int index)
|
||||
{
|
||||
int slots = 0;
|
||||
int count = 0;
|
||||
|
||||
List<Item> list = m_List;
|
||||
|
||||
for (int i = index; i >= 0 && i < list.Count; ++i)
|
||||
{
|
||||
var recipe = list[i];
|
||||
|
||||
if (CheckFilter(recipe))
|
||||
{
|
||||
int add;
|
||||
|
||||
add = 1;
|
||||
|
||||
if ((slots + add) > 50)
|
||||
break;
|
||||
|
||||
slots += add;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public JewelryBoxGump(Mobile from, JewelryBox box)
|
||||
: this(from, box, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public JewelryBoxGump(Mobile from, JewelryBox box, int page)
|
||||
: base(100, 100)
|
||||
{
|
||||
from.CloseGump(typeof(JewelryBoxGump));
|
||||
|
||||
m_From = from;
|
||||
m_Box = box;
|
||||
m_Page = page;
|
||||
|
||||
m_List = new List<Item>();
|
||||
|
||||
foreach (Item item in m_Box.Items)
|
||||
{
|
||||
if (!CheckFilter(item))
|
||||
continue;
|
||||
|
||||
m_List.Add(item);
|
||||
}
|
||||
|
||||
int index = GetIndexForPage(page);
|
||||
int count = GetCountForIndex(index);
|
||||
int pageCount = GetPageCount(m_List.Count);
|
||||
int currentpage = pageCount > 0 ? (page + 1) : 0;
|
||||
|
||||
int tableIndex = 0;
|
||||
|
||||
for (int i = index; i < (index + count) && i >= 0 && i < m_List.Count; ++i)
|
||||
{
|
||||
var item = m_List[i];
|
||||
|
||||
if (!CheckFilter(item))
|
||||
continue;
|
||||
|
||||
++tableIndex;
|
||||
}
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddImage(0, 0, 0x9CCA);
|
||||
AddHtmlLocalized(40, 2, 500, 20, 1114513, "#1157694", 0x7FF0, false, false); // <DIV ALIGN=CENTER>~1_TOKEN~</DIV>
|
||||
|
||||
AddHtmlLocalized(50, 30, 100, 20, 1157695, 0x7FF0, false, false); // Select Filter:
|
||||
|
||||
AddHtmlLocalized(41, 350, 123, 20, 1157698, String.Format("{0}@{1}", m_List.Count, m_Box.DefaultMaxItems), 0x7FF0, false, false); // Items: ~1_NUM~ of ~2_MAX~
|
||||
AddHtmlLocalized(212, 350, 123, 20, 1153561, String.Format("{0}@{1}", currentpage, pageCount), 0x7FF0, false, false); // Page ~1_CUR~ of ~2_MAX~
|
||||
AddHtmlLocalized(416, 350, 100, 20, 1153562, 0x7FF0, false, false); // <DIV ALIGN="CENTER">PAGE</DIV>
|
||||
|
||||
JewelryBoxFilter f = box.Filter;
|
||||
|
||||
AddHtmlLocalized(200, 30, 90, 20, 1154607, f.Ring ? 0x421F : LabelColor, false, false); // Ring
|
||||
AddButton(160, 30, 0xFA5, 0xFA7, 101, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(325, 30, 90, 20, 1079905, f.Bracelet ? 0x421F : LabelColor, false, false); // Bracelet
|
||||
AddButton(285, 30, 0xFA5, 0xFA7, 102, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(450, 30, 90, 20, 1079903, f.Earrings ? 0x421F : LabelColor, false, false); // Earrings
|
||||
AddButton(410, 30, 0xFA5, 0xFA7, 104, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(200, 55, 90, 20, 1157697, f.Necklace ? 0x421F : LabelColor, false, false); // Necklace
|
||||
AddButton(160, 55, 0xFA5, 0xFA7, 108, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(325, 55, 90, 20, 1071023, f.Talisman ? 0x421F : LabelColor, false, false); // Talisman
|
||||
AddButton(285, 55, 0xFA5, 0xFA7, 116, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(450, 55, 90, 20, 1062229, f.IsDefault ? 0x421F : LabelColor, false, false); // All
|
||||
AddButton(410, 55, 0xFA5, 0xFA7, 132, GumpButtonType.Reply, 0);
|
||||
|
||||
tableIndex = 0;
|
||||
|
||||
AddButton(356, 353, 0x15E3, 0x15E7, 11, GumpButtonType.Reply, 0); // First page
|
||||
AddButton(376, 350, 0xFAE, 0xFB0, 1, GumpButtonType.Reply, 0); // Previous page
|
||||
|
||||
AddButton(526, 350, 0xFA5, 0xFA7, 2, GumpButtonType.Reply, 0); // Next Page
|
||||
AddButton(560, 353, 0x15E1, 0x15E5, 12, GumpButtonType.Reply, 0); // Last page
|
||||
|
||||
AddHtmlLocalized(270, 385, 100, 20, 1157696, LabelColor, false, false); // ADD JEWELRY
|
||||
AddButton(225, 385, 0xFAB, 0xFAD, 3, GumpButtonType.Reply, 0);
|
||||
|
||||
int x = 0;
|
||||
|
||||
for (int i = index; i < (index + count) && i >= 0 && i < m_List.Count; ++i)
|
||||
{
|
||||
Item item = m_List[i];
|
||||
|
||||
int xoffset = ((x / 5) * 50);
|
||||
int yoffset = ((i % 5) * 50);
|
||||
|
||||
x++;
|
||||
|
||||
AddECHandleInput();
|
||||
AddButton(50 + xoffset, 90 + yoffset, 0x92F, 0x92F, item.Serial, GumpButtonType.Reply, 0);
|
||||
AddItemProperty(item.Serial);
|
||||
AddItem(57 + xoffset, 108 + yoffset, item.ItemID, item.Hue);
|
||||
AddECHandleInput();
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private JewelryBox m_Box;
|
||||
private int m_Page;
|
||||
|
||||
public InternalTarget(Mobile from, JewelryBox box, int page)
|
||||
: base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Box = box;
|
||||
m_Page = page;
|
||||
}
|
||||
|
||||
public void TryDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!m_Box.CheckAccessible(from, m_Box))
|
||||
{
|
||||
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
|
||||
}
|
||||
else if (!dropped.IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1157726); // You must be carrying the item to add it to the jewelry box.
|
||||
return;
|
||||
}
|
||||
else if (m_Box.IsAccept(dropped))
|
||||
{
|
||||
if (m_Box.IsFull)
|
||||
{
|
||||
from.SendLocalizedMessage(1157723); // The jewelry box is full.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Box.DropItem(dropped);
|
||||
from.Target = new InternalTarget(from, m_Box, m_Page);
|
||||
}
|
||||
}
|
||||
else if (dropped is Container)
|
||||
{
|
||||
Container c = dropped as Container;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = c.Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i < c.Items.Count && m_Box.IsAccept(c.Items[i]))
|
||||
{
|
||||
if (m_Box.IsFull)
|
||||
{
|
||||
from.SendLocalizedMessage(1157723); // The jewelry box is full.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Box.DropItem(c.Items[i]);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
from.CloseGump(typeof(JewelryBoxGump));
|
||||
from.SendGump(new JewelryBoxGump(from, m_Box, m_Page));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1157724); // This is not a ring, bracelet, necklace, earring, or talisman.
|
||||
from.SendGump(new JewelryBoxGump(from, m_Box, m_Page));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1157724); // This is not a ring, bracelet, necklace, earring, or talisman.
|
||||
from.SendGump(new JewelryBoxGump(from, m_Box, m_Page));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (m_Box != null && !m_Box.Deleted && targeted is Item)
|
||||
{
|
||||
TryDrop(from, (Item)targeted);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
|
||||
{
|
||||
if (m_Box != null && !m_Box.Deleted)
|
||||
{
|
||||
from.CloseGump(typeof(JewelryBoxGump));
|
||||
from.SendGump(new JewelryBoxGump(from, m_Box, m_Page));
|
||||
from.SendLocalizedMessage(1157726); // You must be carrying the item to add it to the jewelry box.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (!m_Box.CheckAccessible(m_From, m_Box))
|
||||
{
|
||||
m_From.SendLocalizedMessage(1061637); // You are not allowed to access this.
|
||||
return;
|
||||
}
|
||||
|
||||
JewelryBoxFilter f = m_Box.Filter;
|
||||
|
||||
int index = info.ButtonID;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 0: { break; }
|
||||
case 1: // Previous page
|
||||
{
|
||||
if (m_Page > 0)
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Next Page
|
||||
{
|
||||
if (GetIndexForPage(m_Page + 1) < m_List.Count)
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case 3: // ADD JEWELRY
|
||||
{
|
||||
m_From.Target = new InternalTarget(m_From, m_Box, m_Page);
|
||||
m_From.SendLocalizedMessage(1157725); // Target rings, bracelets, necklaces, earrings, or talisman in your backpack. You may also target a sub-container to add contents to the the jewelry box. When done, press ESC.
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
break;
|
||||
}
|
||||
case 11: // First page
|
||||
{
|
||||
if (m_Page > 0)
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 12: // Last Page
|
||||
{
|
||||
int pagecount = GetPageCount(m_List.Count);
|
||||
|
||||
if (m_Page != pagecount && m_Page >= 1)
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, pagecount));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box, m_Page));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 101: // Ring
|
||||
{
|
||||
f.Ring = true;
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
case 102: // Bracelet
|
||||
{
|
||||
f.Bracelet = true;
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
case 104: // Earrings
|
||||
{
|
||||
f.Earrings = true;
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
case 108: // Necklace
|
||||
{
|
||||
f.Necklace = true;
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
case 116: // Talisman
|
||||
{
|
||||
f.Talisman = true;
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
case 132: // ALL
|
||||
{
|
||||
f.Clear();
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Item item = m_Box.Items.Find(x => x.Serial == index);
|
||||
m_From.AddToBackpack(item);
|
||||
m_From.SendGump(new JewelryBoxGump(m_From, m_Box));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
362
Scripts/Items/Functional/LargeForge.cs
Normal file
362
Scripts/Items/Functional/LargeForge.cs
Normal file
@@ -0,0 +1,362 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Server.Engines.Craft.Forge]
|
||||
public class LargeForgeWest : Item
|
||||
{
|
||||
private InternalItem m_Item;
|
||||
private InternalItem2 m_Item2;
|
||||
[Constructable]
|
||||
public LargeForgeWest()
|
||||
: base(0x199A)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = new InternalItem(this);
|
||||
this.m_Item2 = new InternalItem2(this);
|
||||
}
|
||||
|
||||
public LargeForgeWest(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X, this.Y + 1, this.Z);
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Location = new Point3D(this.X, this.Y + 2, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
writer.Write(this.m_Item2);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as InternalItem;
|
||||
this.m_Item2 = reader.ReadItem() as InternalItem2;
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
private class InternalItem : Item
|
||||
{
|
||||
private LargeForgeWest m_Item;
|
||||
public InternalItem(LargeForgeWest item)
|
||||
: base(0x1996)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X, this.Y - 1, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as LargeForgeWest;
|
||||
}
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
private class InternalItem2 : Item
|
||||
{
|
||||
private LargeForgeWest m_Item;
|
||||
public InternalItem2(LargeForgeWest item)
|
||||
: base(0x1992)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem2(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X, this.Y - 2, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as LargeForgeWest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
public class LargeForgeEast : Item
|
||||
{
|
||||
private InternalItem m_Item;
|
||||
private InternalItem2 m_Item2;
|
||||
[Constructable]
|
||||
public LargeForgeEast()
|
||||
: base(0x197A)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = new InternalItem(this);
|
||||
this.m_Item2 = new InternalItem2(this);
|
||||
}
|
||||
|
||||
public LargeForgeEast(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X + 1, this.Y, this.Z);
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Location = new Point3D(this.X + 2, this.Y, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
if (this.m_Item2 != null)
|
||||
this.m_Item2.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
writer.Write(this.m_Item2);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as InternalItem;
|
||||
this.m_Item2 = reader.ReadItem() as InternalItem2;
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
private class InternalItem : Item
|
||||
{
|
||||
private LargeForgeEast m_Item;
|
||||
public InternalItem(LargeForgeEast item)
|
||||
: base(0x197E)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X - 1, this.Y, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as LargeForgeEast;
|
||||
}
|
||||
}
|
||||
|
||||
[Server.Engines.Craft.Forge]
|
||||
private class InternalItem2 : Item
|
||||
{
|
||||
private LargeForgeEast m_Item;
|
||||
public InternalItem2(LargeForgeEast item)
|
||||
: base(0x1982)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Item = item;
|
||||
}
|
||||
|
||||
public InternalItem2(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Location = new Point3D(this.X - 2, this.Y, this.Z);
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Map = this.Map;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
if (this.m_Item != null)
|
||||
this.m_Item.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(this.m_Item);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Item = reader.ReadItem() as LargeForgeEast;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Scripts/Items/Functional/MushroomTrap.cs
Normal file
85
Scripts/Items/Functional/MushroomTrap.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MushroomTrap : BaseTrap
|
||||
{
|
||||
[Constructable]
|
||||
public MushroomTrap()
|
||||
: base(0x1125)
|
||||
{
|
||||
}
|
||||
|
||||
public MushroomTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (!from.Alive || this.ItemID != 0x1125 || from.IsStaff())
|
||||
return;
|
||||
|
||||
this.ItemID = 0x1126;
|
||||
Effects.PlaySound(this.Location, this.Map, 0x306);
|
||||
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromSeconds(0.5), from, from, Utility.Dice(2, 4, 0));
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerCallback(OnMushroomReset));
|
||||
}
|
||||
|
||||
public virtual void OnMushroomReset()
|
||||
{
|
||||
if (Region.Find(this.Location, this.Map).IsPartOf<DungeonRegion>())
|
||||
this.ItemID = 0x1125; // reset
|
||||
else
|
||||
this.Delete();
|
||||
}
|
||||
|
||||
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 (this.ItemID == 0x1126)
|
||||
this.OnMushroomReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
200
Scripts/Items/Functional/ParoxysmusAltar.cs
Normal file
200
Scripts/Items/Functional/ParoxysmusAltar.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ParoxysmusAltar : PeerlessAltar
|
||||
{
|
||||
public static Dictionary<Mobile, Timer> ProtectionTable = new Dictionary<Mobile, Timer>();
|
||||
|
||||
public override int KeyCount { get { return 16; } }
|
||||
public override MasterKey MasterKey { get { return new ParoxysmusKey(); } }
|
||||
|
||||
public override Type[] Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Type[]
|
||||
{
|
||||
typeof( CoagulatedLegs ), typeof( PartiallyDigestedTorso ),
|
||||
typeof( GelatanousSkull ), typeof( SpleenOfThePutrefier )
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override BasePeerless Boss { get { return new ChiefParoxysmus(); } }
|
||||
|
||||
[Constructable]
|
||||
public ParoxysmusAltar() : base(0x207A)
|
||||
{
|
||||
Hue = 0x465;
|
||||
|
||||
BossLocation = new Point3D(6517, 357, 0);
|
||||
TeleportDest = new Point3D(6519, 381, 0);
|
||||
ExitDest = new Point3D(5623, 3038, 15);
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6501, 351, 35, 48),
|
||||
};
|
||||
|
||||
public static void AddProtection(Mobile m)
|
||||
{
|
||||
if (ProtectionTable != null && !ProtectionTable.ContainsKey(m))
|
||||
{
|
||||
ProtectionTable[m] = Timer.DelayCall(TimeSpan.FromMinutes(5), () => Damage(m));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsUnderEffects(Mobile m)
|
||||
{
|
||||
return ProtectionTable != null && ProtectionTable.ContainsKey(m);
|
||||
}
|
||||
|
||||
public static void Damage(Mobile m)
|
||||
{
|
||||
Timer t;
|
||||
|
||||
if (ProtectionTable.TryGetValue(m, out t))
|
||||
{
|
||||
if (t != null)
|
||||
{
|
||||
t.Stop();
|
||||
}
|
||||
|
||||
ProtectionTable.Remove(m);
|
||||
}
|
||||
}
|
||||
|
||||
public ParoxysmusAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write(ProtectionTable.Count);
|
||||
|
||||
foreach (var kvp in ProtectionTable)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value.Next);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
DateTime end = reader.ReadDateTime();
|
||||
|
||||
ProtectionTable[m] = Timer.DelayCall(end - DateTime.UtcNow, () => Damage(m));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
IPooledEnumerable eable = Map.GetItemsInBounds(new Rectangle2D(6516, 492, 5, 1));
|
||||
|
||||
foreach (Item item in eable)
|
||||
{
|
||||
if (item.Movable)
|
||||
item.Delete();
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Item gate = new ParoxysmusIronGate(this);
|
||||
gate.MoveToWorld(new Point3D(6518, 492, -50), Map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ParoxysmusIronGate : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PeerlessAltar Altar { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public ParoxysmusIronGate()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ParoxysmusIronGate(PeerlessAltar altar)
|
||||
: base(0x857)
|
||||
{
|
||||
Altar = altar;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public ParoxysmusIronGate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClickDead(Mobile from)
|
||||
{
|
||||
base.OnDoubleClickDead(from);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.Alive)
|
||||
return;
|
||||
|
||||
if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(Network.MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
else if (Altar != null && Altar.Fighters.Contains(from))
|
||||
{
|
||||
from.SendLocalizedMessage(1075070); // The rusty gate cracks open as you step through...
|
||||
from.MoveToWorld(Altar.TeleportDest, Altar.Map);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Item)Altar);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Altar = reader.ReadItem() as PeerlessAltar;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Scripts/Items/Functional/Portcullis.cs
Normal file
74
Scripts/Items/Functional/Portcullis.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PortcullisNS : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public PortcullisNS()
|
||||
: base(0x6F5, 0x6F5, 0xF0, 0xEF, new Point3D(0, 0, 20))
|
||||
{
|
||||
}
|
||||
|
||||
public PortcullisNS(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool UseChainedFunctionality
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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 class PortcullisEW : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public PortcullisEW()
|
||||
: base(0x6F6, 0x6F6, 0xF0, 0xEF, new Point3D(0, 0, 20))
|
||||
{
|
||||
}
|
||||
|
||||
public PortcullisEW(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool UseChainedFunctionality
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
605
Scripts/Items/Functional/PowerGenerator.cs
Normal file
605
Scripts/Items/Functional/PowerGenerator.cs
Normal file
@@ -0,0 +1,605 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PowerGenerator : BaseAddon
|
||||
{
|
||||
[Constructable]
|
||||
public PowerGenerator()
|
||||
: this(Utility.RandomMinMax(3, 6))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public PowerGenerator(int sideLength)
|
||||
{
|
||||
this.AddGeneratorComponent(0x73, 0, 0, 0);
|
||||
this.AddGeneratorComponent(0x76, -1, 0, 0);
|
||||
this.AddGeneratorComponent(0x75, 0, -1, 0);
|
||||
this.AddGeneratorComponent(0x37F4, 0, 0, 13);
|
||||
|
||||
this.AddComponent(new ControlPanel(sideLength), 1, 0, -2);
|
||||
}
|
||||
|
||||
public PowerGenerator(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ShareHue
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
private void AddGeneratorComponent(int itemID, int x, int y, int z)
|
||||
{
|
||||
AddonComponent component = new AddonComponent(itemID);
|
||||
component.Name = "a power generator";
|
||||
component.Hue = 0x451;
|
||||
|
||||
this.AddComponent(component, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
public class ControlPanel : AddonComponent
|
||||
{
|
||||
private static readonly TimeSpan m_UseTimeout = TimeSpan.FromMinutes(2.0);
|
||||
private readonly Hashtable m_DamageTable = new Hashtable();
|
||||
private int m_SideLength;
|
||||
private Node[] m_Path;
|
||||
private Mobile m_User;
|
||||
private DateTime m_LastUse;
|
||||
public ControlPanel(int sideLength)
|
||||
: base(0xBDC)
|
||||
{
|
||||
this.Hue = 0x835;
|
||||
|
||||
this.SideLength = sideLength;
|
||||
}
|
||||
|
||||
public ControlPanel(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
private enum PathDirection
|
||||
{
|
||||
Left,
|
||||
Up,
|
||||
Right,
|
||||
Down
|
||||
}
|
||||
[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.InitPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
public Node[] Path
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Path;
|
||||
}
|
||||
}
|
||||
public override string DefaultName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "a control panel";
|
||||
}
|
||||
}
|
||||
public void InitPath()
|
||||
{
|
||||
// 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.m_User != null)
|
||||
{
|
||||
this.m_User.CloseGump(typeof(GameGump));
|
||||
this.m_User = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(this, 3))
|
||||
{
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.m_User != null)
|
||||
{
|
||||
if (this.m_User == from)
|
||||
return;
|
||||
|
||||
if (this.m_User.Deleted || this.m_User.Map != this.Map || !this.m_User.InRange(this, 3) ||
|
||||
this.m_User.NetState == null || DateTime.UtcNow - this.m_LastUse >= m_UseTimeout)
|
||||
{
|
||||
this.m_User.CloseGump(typeof(GameGump));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("Someone is currently using the control panel.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.m_User = from;
|
||||
this.m_LastUse = DateTime.UtcNow;
|
||||
|
||||
from.SendGump(new GameGump(this, from, 0, false));
|
||||
}
|
||||
|
||||
public void DoDamage(Mobile to)
|
||||
{
|
||||
to.Send(new UnicodeMessage(this.Serial, this.ItemID, MessageType.Regular, 0x3B2, 3, "", "", "The generator shoots an arc of electricity at you!"));
|
||||
to.BoltEffect(0);
|
||||
to.LocalOverheadMessage(MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *");
|
||||
to.NonlocalOverheadMessage(MessageType.Regular, 0xC9, true, string.Format("* {0} spasms from electric shock *", to.Name));
|
||||
|
||||
AOS.Damage(to, to, 60, 0, 0, 0, 0, 100);
|
||||
|
||||
if (!to.Alive)
|
||||
return;
|
||||
|
||||
if (this.m_DamageTable[to] == null)
|
||||
{
|
||||
to.Frozen = true;
|
||||
|
||||
DamageTimer timer = new DamageTimer(this, to);
|
||||
this.m_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.SendMessage("You scrounge some gems from the wreckage.");
|
||||
|
||||
for (int i = 0; i < this.SideLength; i++)
|
||||
{
|
||||
from.AddToBackpack(new ArcaneGem());
|
||||
}
|
||||
|
||||
from.AddToBackpack(new Diamond(this.SideLength));
|
||||
|
||||
Item ore = new ShadowIronOre(9);
|
||||
ore.MoveToWorld(new Point3D(this.X - 1, this.Y, this.Z + 2), this.Map);
|
||||
|
||||
ore = new ShadowIronOre(14);
|
||||
ore.MoveToWorld(new Point3D(this.X - 2, this.Y - 1, this.Z + 2), this.Map);
|
||||
|
||||
this.Delete();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt((int)0); // version
|
||||
|
||||
writer.WriteEncodedInt((int)this.m_SideLength);
|
||||
|
||||
writer.WriteEncodedInt((int)this.m_Path.Length);
|
||||
for (int i = 0; i < this.m_Path.Length; i++)
|
||||
{
|
||||
Node cur = this.m_Path[i];
|
||||
|
||||
writer.WriteEncodedInt(cur.X);
|
||||
writer.WriteEncodedInt(cur.Y);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
this.m_SideLength = reader.ReadEncodedInt();
|
||||
|
||||
this.m_Path = new Node[reader.ReadEncodedInt()];
|
||||
for (int i = 0; i < this.m_Path.Length; i++)
|
||||
{
|
||||
this.m_Path[i] = new Node(reader.ReadEncodedInt(), reader.ReadEncodedInt());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class GameGump : Gump
|
||||
{
|
||||
private readonly ControlPanel m_Panel;
|
||||
private readonly Mobile m_From;
|
||||
private readonly int m_Step;
|
||||
public GameGump(ControlPanel panel, Mobile from, int step, bool hint)
|
||||
: base(5, 30)
|
||||
{
|
||||
this.m_Panel = panel;
|
||||
this.m_From = from;
|
||||
this.m_Step = step;
|
||||
|
||||
int sideLength = panel.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.AddHtml(229, 35, 300, 45, "GENERATOR CONTROL PANEL", false, false);
|
||||
|
||||
this.AddHtml(223, 60, 300, 70, "Use the Directional Controls to", false, false);
|
||||
this.AddHtml(253, 75, 300, 85, "Close the Grid Circuit", false, false);
|
||||
|
||||
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 = panel.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.AddHtml(405, 345, 140, 40, "Attempt to Decipher the Circuit Path", false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private enum NodeHue
|
||||
{
|
||||
Gray,
|
||||
Blue,
|
||||
Red
|
||||
}
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (this.m_Panel.Deleted || info.ButtonID == 0 || !this.m_From.CheckAlive())
|
||||
{
|
||||
this.m_Panel.m_User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.m_From.Map != this.m_Panel.Map || !this.m_From.InRange(this.m_Panel, 3))
|
||||
{
|
||||
this.m_From.SendLocalizedMessage(500446); // That is too far away.
|
||||
this.m_Panel.m_User = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Node nextNode = this.m_Panel.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 GameGump(this.m_Panel, this.m_From, this.m_Step, true));
|
||||
this.m_Panel.m_LastUse = DateTime.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Panel.DoDamage(this.m_From);
|
||||
this.m_Panel.m_User = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Node curNode = this.m_Panel.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_Panel.Path.Length - 1)
|
||||
{
|
||||
this.m_Panel.Solve(this.m_From);
|
||||
this.m_Panel.m_User = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_From.PlaySound(0x1F4);
|
||||
this.m_From.SendGump(new GameGump(this.m_Panel, this.m_From, this.m_Step + 1, false));
|
||||
this.m_Panel.m_LastUse = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.m_Panel.DoDamage(this.m_From);
|
||||
this.m_Panel.m_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);
|
||||
}
|
||||
}
|
||||
|
||||
private class DamageTimer : Timer
|
||||
{
|
||||
private readonly ControlPanel m_Panel;
|
||||
private readonly Mobile m_To;
|
||||
private int m_Step;
|
||||
public DamageTimer(ControlPanel panel, Mobile to)
|
||||
: base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0))
|
||||
{
|
||||
this.m_Panel = panel;
|
||||
this.m_To = to;
|
||||
this.m_Step = 0;
|
||||
|
||||
this.Priority = TimerPriority.TwoFiftyMS;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (this.m_Panel.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()
|
||||
{
|
||||
this.m_Panel.m_DamageTable.Remove(this.m_To);
|
||||
this.m_To.Frozen = false;
|
||||
|
||||
this.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
534
Scripts/Items/Functional/PrimevalLichPuzzle.cs
Normal file
534
Scripts/Items/Functional/PrimevalLichPuzzle.cs
Normal file
@@ -0,0 +1,534 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Items;
|
||||
|
||||
//
|
||||
// This implements the Primeval Lich Lever Puzzle for SA.
|
||||
//
|
||||
// To install, copy this file anywhere into the scripts directory tree. Next edit
|
||||
// ChampionSpawn.cs and add the following line of code at the end of the Start() and Stop()
|
||||
// methods in the ChampionSpawn.cs file:
|
||||
//
|
||||
// PrimevalLichPuzzle.Update(this);
|
||||
//
|
||||
// Next compile and be sure that the Primeval Lich championSpawn is created. Then you can
|
||||
// use the command [genlichpuzzle to create the puzzle controller. After that the puzzle
|
||||
// will become active/inactive automatically.
|
||||
//
|
||||
// The "key" property on the puzzle controller shows the solution levers,
|
||||
// numbered (west to east) as 1 thru 8 for testing purposes.
|
||||
//
|
||||
namespace Server.Engines.CannedEvil
|
||||
{
|
||||
public class PrimevalLichPuzzleLever : Item
|
||||
{
|
||||
private PrimevalLichPuzzle m_Controller;
|
||||
private byte m_Code;
|
||||
// Constructor
|
||||
public PrimevalLichPuzzleLever(byte code, PrimevalLichPuzzle controller)
|
||||
: base(0x108C)
|
||||
{
|
||||
m_Code = code;
|
||||
m_Controller = controller;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
// serialization code
|
||||
public PrimevalLichPuzzleLever(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (null == m)
|
||||
return;
|
||||
|
||||
if (null == m_Controller || m_Controller.Deleted || !m_Controller.Active)
|
||||
{
|
||||
Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != m_Controller.Successful)
|
||||
m.SendLocalizedMessage(1112374); // The puzzle has already been completed.
|
||||
else
|
||||
{
|
||||
ItemID ^= 2;
|
||||
Effects.PlaySound(Location, Map, 0x3E8);
|
||||
m_Controller.LeverPulled(m_Code, m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write((byte)m_Code);
|
||||
writer.Write(m_Controller);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_Code = reader.ReadByte();
|
||||
m_Controller = reader.ReadItem() as PrimevalLichPuzzle;
|
||||
|
||||
// remove if no controller exists or is deleted
|
||||
if (null == m_Controller || m_Controller.Deleted)
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public class PrimevalLichPuzzle : Item
|
||||
{
|
||||
// expected location of the Priveval Lich champion altar
|
||||
private static readonly Point3D altarLoc = new Point3D(7001, 1008, -15);
|
||||
|
||||
// location to place the Primeval Lich puzzle controller
|
||||
private static readonly Point3D controlLoc = new Point3D(6999, 977, -15);
|
||||
|
||||
// puzzle lever data
|
||||
private static readonly int[][] leverdata =
|
||||
{ // 3D coord, hue for levers
|
||||
new int[] { 6981, 977, -15, 1204 }, // red
|
||||
new int[] { 6984, 977, -15, 1150 }, // white
|
||||
new int[] { 6987, 977, -15, 1175 }, // black
|
||||
new int[] { 6990, 977, -15, 1264 }, // blue
|
||||
new int[] { 7009, 977, -15, 1275 }, // purple
|
||||
new int[] { 7012, 977, -15, 1272 }, // green
|
||||
new int[] { 7015, 977, -15, 1260 }, // gold
|
||||
new int[] { 7018, 977, -15, 1166 }, // pink
|
||||
};
|
||||
|
||||
// these are serialized
|
||||
private static PrimevalLichPuzzle m_Instance;
|
||||
private ChampionSpawn m_Altar;
|
||||
private long m_Key;
|
||||
private Mobile m_Successful;
|
||||
private List<PrimevalLichPuzzleLever> m_Levers;
|
||||
|
||||
// these are not serialized
|
||||
private byte m_NextKey;
|
||||
private int m_Correct;
|
||||
private Timer l_Timer;
|
||||
|
||||
// Constructor
|
||||
public PrimevalLichPuzzle(Mobile m)
|
||||
: base(0x1BC3)
|
||||
{
|
||||
if(null == m || null != m_Instance)
|
||||
{
|
||||
Delete();
|
||||
//Probably not needed, OnAfterDelete sets it null anyway
|
||||
if (m_Instance != null && m_Instance.Deleted)
|
||||
m_Instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
m_Instance = this;
|
||||
MoveToWorld(controlLoc, Map.Felucca);
|
||||
|
||||
m_Levers = new List<PrimevalLichPuzzleLever>();
|
||||
|
||||
m_Altar = FindAltar();
|
||||
|
||||
if (null == m_Altar)
|
||||
{
|
||||
m.SendMessage(33, "Primeval Lich champion spawn not found.");
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePuzzleState(m_Altar);
|
||||
}
|
||||
}
|
||||
|
||||
// serialization code
|
||||
public PrimevalLichPuzzle(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Successful
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Successful;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public long Key
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Key;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get
|
||||
{
|
||||
return(!Deleted && null != m_Altar && m_Altar.Active);
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public ChampionSpawn ChampionAltar
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Altar;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Altar = value;
|
||||
}
|
||||
}
|
||||
public override string DefaultName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "puzzle control";
|
||||
}
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("GenLichPuzzle", AccessLevel.Administrator, new CommandEventHandler(GenLichPuzzle_OnCommand));
|
||||
CommandSystem.Register("DeleteLichPuzzle", AccessLevel.Administrator, new CommandEventHandler(DeleteLichPuzzle_OnCommand));
|
||||
}
|
||||
|
||||
[Usage("DeleteLichPuzzle")]
|
||||
[Description("Deletes the Primeval Lich lever puzzle.")]
|
||||
public static void DeleteLichPuzzle_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
WeakEntityCollection.Delete("primevallich");
|
||||
}
|
||||
|
||||
[Usage("GenLichPuzzle")]
|
||||
[Description("Generates the Primeval Lich lever puzzle.")]
|
||||
public static void GenLichPuzzle_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
GenLichPuzzle(e.Mobile);
|
||||
}
|
||||
|
||||
public static void GenLichPuzzle(Mobile m)
|
||||
{
|
||||
if (null != m_Instance)
|
||||
{
|
||||
if (m != null)
|
||||
{
|
||||
m.SendMessage("Primeval Lich lever puzzle already exists: please delete the existing one first ...");
|
||||
}
|
||||
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "Primeval Lich lever puzzle already exists: please delete the existing one first ...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m != null)
|
||||
{
|
||||
m.SendMessage("Generating Primeval Lich lever puzzle...");
|
||||
}
|
||||
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "Generating Primeval Lich lever puzzle...");
|
||||
|
||||
PrimevalLichPuzzle control = new PrimevalLichPuzzle(m);
|
||||
if (null == control || control.Deleted)
|
||||
{
|
||||
if (m != null)
|
||||
{
|
||||
m.SendMessage(33, "There was a problem generating the puzzle.");
|
||||
}
|
||||
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "There was a problem generating the puzzle.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m != null)
|
||||
{
|
||||
m.SendMessage("The puzzle was successfully generated.");
|
||||
}
|
||||
|
||||
Utility.WriteConsoleColor(ConsoleColor.Green, "The puzzle was successfully generated.");
|
||||
WeakEntityCollection.Add("primevallich", control);
|
||||
}
|
||||
}
|
||||
|
||||
// static hook for the ChampionSpawn code to update the puzzle state
|
||||
public static void Update(ChampionSpawn altar)
|
||||
{
|
||||
if (null != m_Instance)
|
||||
{
|
||||
if (m_Instance.Deleted)
|
||||
m_Instance = null;
|
||||
else if (m_Instance.ChampionAltar == altar)
|
||||
m_Instance.UpdatePuzzleState(altar);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
RemovePuzzleLevers();
|
||||
if (this == m_Instance)
|
||||
m_Instance = null;
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
// process a lever pull
|
||||
public void LeverPulled(byte key, Mobile m)
|
||||
{
|
||||
if (!Active || null == m)
|
||||
return;
|
||||
|
||||
// teleport if this is a dummy key
|
||||
if (0 == key)
|
||||
{
|
||||
Point3D loc = m_Altar.GetSpawnLocation();
|
||||
m.MoveToWorld(loc, Map);
|
||||
|
||||
ResetLevers();
|
||||
return;
|
||||
}
|
||||
// if the lever is correct, increment the count of correct levers pulled
|
||||
else if (key == m_NextKey)
|
||||
m_Correct++;
|
||||
|
||||
// stop and restart the lever reset timer
|
||||
if (null != l_Timer)
|
||||
l_Timer.Stop();
|
||||
l_Timer = Timer.DelayCall(TimeSpan.FromSeconds(30.0), new TimerCallback(ResetLevers));
|
||||
|
||||
// if this is the last key, check for correct solution and give messages/rewards
|
||||
if (6 == m_NextKey++)
|
||||
{
|
||||
// all 6 were correct, so set successful and give a reward
|
||||
if (6 == m_Correct)
|
||||
{
|
||||
m_Successful = m;
|
||||
GiveReward(m);
|
||||
}
|
||||
|
||||
// send a message based of the number of correct levers pulled
|
||||
m.SendLocalizedMessage(1112378 + m_Correct);
|
||||
ResetLevers();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write((PrimevalLichPuzzle)m_Instance);
|
||||
writer.Write((ChampionSpawn)m_Altar);
|
||||
writer.Write((long)m_Key);
|
||||
writer.Write((Mobile)m_Successful);
|
||||
writer.WriteItemList(m_Levers, true);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
m_Instance = reader.ReadItem() as PrimevalLichPuzzle;
|
||||
m_Altar = reader.ReadItem() as ChampionSpawn;
|
||||
m_Key = reader.ReadLong();
|
||||
m_Successful = reader.ReadMobile();
|
||||
m_Levers = reader.ReadStrongItemList<PrimevalLichPuzzleLever>();
|
||||
break;
|
||||
}
|
||||
|
||||
if (null == m_Levers)
|
||||
m_Levers = new List<PrimevalLichPuzzleLever>();
|
||||
// if ( null != m_Instance && m_Instance.Deleted && this == m_Instance )
|
||||
// {
|
||||
// m_Instance = null;
|
||||
// return;
|
||||
// }
|
||||
// // remove if no altar exists
|
||||
// if ( null == m_Altar )
|
||||
// Timer.DelayCall( TimeSpan.FromSeconds( 0.0 ), new TimerCallback( Delete ) );
|
||||
// ResetLevers();
|
||||
}
|
||||
|
||||
// search for Primeval Lich altar within 10 spaces of the expected location
|
||||
private ChampionSpawn FindAltar()
|
||||
{
|
||||
foreach (Item item in Map.Felucca.GetItemsInRange(altarLoc, 10))
|
||||
{
|
||||
if (item is ChampionSpawn)
|
||||
{
|
||||
ChampionSpawn champ = (ChampionSpawn)item;
|
||||
if (ChampionSpawnType.Infuse == champ.Type)
|
||||
return champ;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// internal code to update the puzzle state
|
||||
private void UpdatePuzzleState(ChampionSpawn altar)
|
||||
{
|
||||
if (!Deleted && null != altar && altar == m_Altar)
|
||||
{
|
||||
if (ChampionSpawnType.Infuse != m_Altar.Type || !Active)
|
||||
RemovePuzzleLevers();
|
||||
else if (0 == m_Levers.Count)
|
||||
CreatePuzzleLevers();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreatePuzzleLevers()
|
||||
{
|
||||
// remove any existing puzzle levers
|
||||
RemovePuzzleLevers();
|
||||
|
||||
// generate a new key for the puzzle
|
||||
int len = leverdata.Length;
|
||||
|
||||
if (8 == len)
|
||||
{
|
||||
// initialize new keymap
|
||||
byte[] keymap = new byte[len];
|
||||
int ndx;
|
||||
byte code = 1;
|
||||
int newkey = 0;
|
||||
while (code <= 6)
|
||||
{
|
||||
ndx = Utility.Random(len);
|
||||
if (0 == keymap[ndx])
|
||||
{
|
||||
keymap[ndx] = code++;
|
||||
newkey = newkey * 10 + ndx + 1;
|
||||
}
|
||||
}
|
||||
m_Key = newkey;
|
||||
|
||||
// create the puzzle levers
|
||||
PrimevalLichPuzzleLever lever;
|
||||
int[] val;
|
||||
|
||||
if (null == m_Levers)
|
||||
m_Levers = new List<PrimevalLichPuzzleLever>();
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
lever = new PrimevalLichPuzzleLever(keymap[i], this);
|
||||
if (null != lever)
|
||||
{
|
||||
val = leverdata[i];
|
||||
lever.MoveToWorld(new Point3D(val[0], val[1], val[2]), Map.Felucca);
|
||||
lever.Hue = val[3];
|
||||
m_Levers.Add(lever);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove any existing puzzle levers
|
||||
private void RemovePuzzleLevers()
|
||||
{
|
||||
if (null != l_Timer)
|
||||
{
|
||||
l_Timer.Stop();
|
||||
l_Timer = null;
|
||||
}
|
||||
|
||||
if (null != m_Levers)
|
||||
{
|
||||
foreach (Item item in m_Levers)
|
||||
{
|
||||
if (item != null && !item.Deleted)
|
||||
item.Delete();
|
||||
}
|
||||
m_Levers.Clear();
|
||||
}
|
||||
|
||||
m_Successful = null;
|
||||
m_Key = 0;
|
||||
}
|
||||
|
||||
// reset puzzle levers to default position
|
||||
private void ResetLevers()
|
||||
{
|
||||
if (null != l_Timer)
|
||||
{
|
||||
l_Timer.Stop();
|
||||
l_Timer = null;
|
||||
}
|
||||
|
||||
if (null != m_Levers)
|
||||
{
|
||||
foreach (PrimevalLichPuzzleLever l in m_Levers)
|
||||
{
|
||||
if (null != l && !l.Deleted)
|
||||
{
|
||||
l.ItemID = 0x108C;
|
||||
Effects.PlaySound(l.Location, Map, 0x3E8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_Correct = 0;
|
||||
m_NextKey = 1;
|
||||
}
|
||||
|
||||
// distribute a reward to the puzzle solver
|
||||
private void GiveReward(Mobile m)
|
||||
{
|
||||
if (null == m)
|
||||
return;
|
||||
|
||||
Item item = null;
|
||||
|
||||
switch ( Utility.Random(1) )
|
||||
{
|
||||
case 0:
|
||||
item = ScrollOfTranscendence.CreateRandom(10, 10);
|
||||
break;
|
||||
case 1:
|
||||
// black bone container
|
||||
break;
|
||||
case 2:
|
||||
// red bone container
|
||||
break;
|
||||
case 3:
|
||||
// gruesome standard
|
||||
break;
|
||||
case 4:
|
||||
// bag of gems
|
||||
break;
|
||||
case 5:
|
||||
// random piece of spawn decoration
|
||||
break;
|
||||
}
|
||||
|
||||
// drop the item in backpack or bankbox
|
||||
if (null != item)
|
||||
{
|
||||
Container pack = m.Backpack;
|
||||
if (null == pack || !pack.TryDropItem(m, item, false))
|
||||
m.BankBox.DropItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
// generate a new keymap
|
||||
private void GenKey()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
217
Scripts/Items/Functional/PrismOfLightAltar.cs
Normal file
217
Scripts/Items/Functional/PrismOfLightAltar.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PrismOfLightAltar : PeerlessAltar
|
||||
{
|
||||
private int m_ID;
|
||||
public override int KeyCount { get { return 3; } }
|
||||
public override MasterKey MasterKey { get { return new PrismOfLightKey(); } }
|
||||
public List<Item> Pedestals = new List<Item>();
|
||||
|
||||
public override Type[] Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Type[]
|
||||
{
|
||||
typeof(JaggedCrystals), typeof(BrokenCrystals), typeof(PiecesOfCrystal),
|
||||
typeof(CrushedCrystals), typeof(ScatteredCrystals), typeof(ShatteredCrystals)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override BasePeerless Boss { get { return new ShimmeringEffusion(); } }
|
||||
|
||||
[Constructable]
|
||||
public PrismOfLightAltar() : base(0x2206)
|
||||
{
|
||||
Visible = false;
|
||||
|
||||
BossLocation = new Point3D(6520, 122, -20);
|
||||
TeleportDest = new Point3D(6520, 139, -20);
|
||||
ExitDest = new Point3D(3785, 1107, 20);
|
||||
|
||||
m_ID = 0;
|
||||
}
|
||||
|
||||
public override void ClearContainer()
|
||||
{
|
||||
base.ClearContainer();
|
||||
|
||||
Pedestals.ForEach(x => x.Hue = ((PrismOfLightPillar)x).OrgHue);
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(6500, 111, 45, 35),
|
||||
};
|
||||
|
||||
public PrismOfLightAltar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write(Pedestals, true);
|
||||
|
||||
writer.Write((int)m_ID);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Pedestals = reader.ReadStrongItemList();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_ID = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetID()
|
||||
{
|
||||
int id = m_ID;
|
||||
m_ID += 1;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public class PrismOfLightPillar : Container
|
||||
{
|
||||
public override int LabelNumber { get { return 1024643; } } // pedestal
|
||||
|
||||
private PrismOfLightAltar m_Altar;
|
||||
private int m_OrgHue;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public PrismOfLightAltar Altar
|
||||
{
|
||||
get { return m_Altar; }
|
||||
set
|
||||
{
|
||||
m_Altar = value;
|
||||
|
||||
if (!m_Altar.Pedestals.Contains(this))
|
||||
m_Altar.Pedestals.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ID { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int OrgHue
|
||||
{
|
||||
get { return m_OrgHue; }
|
||||
set
|
||||
{
|
||||
m_OrgHue = value;
|
||||
Hue = m_OrgHue;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public PrismOfLightPillar(PrismOfLightAltar altar, int hue)
|
||||
: base(0x207D)
|
||||
{
|
||||
OrgHue = hue;
|
||||
Movable = false;
|
||||
|
||||
m_Altar = altar;
|
||||
|
||||
if (m_Altar != null)
|
||||
{
|
||||
ID = m_Altar.GetID();
|
||||
m_Altar.Pedestals.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public PrismOfLightPillar(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (m_Altar == null)
|
||||
return false;
|
||||
|
||||
if (dropped.GetType() == m_Altar.Keys[ID])
|
||||
{
|
||||
if (m_Altar.OnDragDrop(from, dropped))
|
||||
{
|
||||
Hue = 36;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1072682); // This is not the proper key.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1); // version
|
||||
|
||||
writer.Write((int)m_OrgHue);
|
||||
|
||||
writer.Write((int)ID);
|
||||
writer.Write((Item)m_Altar);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_OrgHue = reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
ID = reader.ReadInt();
|
||||
m_Altar = reader.ReadItem() as PrismOfLightAltar;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version < 1)
|
||||
{
|
||||
if (m_OrgHue == 0)
|
||||
m_OrgHue = Hue;
|
||||
|
||||
if (!m_Altar.Pedestals.Contains(this))
|
||||
m_Altar.Pedestals.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
736
Scripts/Items/Functional/PublicMoongate.cs
Normal file
736
Scripts/Items/Functional/PublicMoongate.cs
Normal file
@@ -0,0 +1,736 @@
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server.Commands;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
#endregion
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PublicMoongate : Item
|
||||
{
|
||||
public static List<PublicMoongate> Moongates { get; private set; }
|
||||
|
||||
static PublicMoongate()
|
||||
{
|
||||
Moongates = new List<PublicMoongate>();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("MoonGen", AccessLevel.Administrator, MoonGen_OnCommand);
|
||||
CommandSystem.Register("MoonGenDelete", AccessLevel.Administrator, MoonGenDelete_OnCommand);
|
||||
}
|
||||
|
||||
[Usage("MoonGen")]
|
||||
[Description("Generates public moongates. Removes all old moongates.")]
|
||||
public static void MoonGen_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
DeleteAll();
|
||||
|
||||
var count = 0;
|
||||
|
||||
if (!Siege.SiegeShard)
|
||||
{
|
||||
count += MoonGen(PMList.Trammel);
|
||||
}
|
||||
|
||||
count += MoonGen(PMList.Felucca);
|
||||
count += MoonGen(PMList.Ilshenar);
|
||||
count += MoonGen(PMList.Malas);
|
||||
count += MoonGen(PMList.Tokuno);
|
||||
count += MoonGen(PMList.TerMur);
|
||||
|
||||
World.Broadcast(0x35, true, "{0} moongates generated.", count);
|
||||
}
|
||||
|
||||
private static int MoonGen(PMList list)
|
||||
{
|
||||
foreach (var entry in list.Entries)
|
||||
{
|
||||
var o = new PublicMoongate();
|
||||
|
||||
o.MoveToWorld(entry.Location, list.Map);
|
||||
|
||||
if (entry.Number == 1060642) // Umbra
|
||||
{
|
||||
o.Hue = 0x497;
|
||||
}
|
||||
}
|
||||
|
||||
return list.Entries.Length;
|
||||
}
|
||||
|
||||
[Usage("MoonGenDelete")]
|
||||
[Description("Removes all public moongates.")]
|
||||
public static void MoonGenDelete_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
DeleteAll();
|
||||
}
|
||||
|
||||
public static void DeleteAll()
|
||||
{
|
||||
var count = Moongates.Count;
|
||||
|
||||
var index = count;
|
||||
|
||||
while (--index >= 0)
|
||||
{
|
||||
if(index < Moongates.Count)
|
||||
Moongates[index].Delete();
|
||||
}
|
||||
|
||||
Moongates.Clear();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
World.Broadcast(0x35, true, "{0:#,0} moongates removed.", count);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<PublicMoongate> FindGates(Map map)
|
||||
{
|
||||
PublicMoongate o;
|
||||
|
||||
var i = Moongates.Count;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
o = Moongates[i];
|
||||
|
||||
if (o == null || o.Deleted)
|
||||
{
|
||||
Moongates.RemoveAt(i);
|
||||
}
|
||||
else if (o.Map == map)
|
||||
{
|
||||
yield return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int LabelNumber {get {return 1023952;} } // Blue Moongate
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public PublicMoongate()
|
||||
: base(0xF6C)
|
||||
{
|
||||
Movable = false;
|
||||
Light = LightType.Circle300;
|
||||
|
||||
Moongates.Add(this);
|
||||
}
|
||||
|
||||
public PublicMoongate(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
Moongates.Add(this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Moongates.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
Moongates.Remove(this);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m.InRange(GetWorldLocation(), 1))
|
||||
{
|
||||
UseGate(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m.Player && m.CanSee(this))
|
||||
{
|
||||
UseGate(m);
|
||||
}
|
||||
|
||||
return m.Map == Map && m.InRange(this, 1);
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m.Player && !Utility.InRange(m.Location, Location, 1) && Utility.InRange(oldLocation, Location, 1))
|
||||
{
|
||||
m.CloseGump(typeof(MoongateGump));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanUseGate(Mobile m, bool message)
|
||||
{
|
||||
if (m.IsStaff())
|
||||
{
|
||||
//Staff can always use a gate!
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m.Criminal)
|
||||
{
|
||||
// Thou'rt a criminal and cannot escape so easily.
|
||||
m.SendLocalizedMessage(1005561, "", 0x22);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SpellHelper.CheckCombat(m))
|
||||
{
|
||||
// Wouldst thou flee during the heat of battle??
|
||||
m.SendLocalizedMessage(1005564, "", 0x22);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.Spell != null)
|
||||
{
|
||||
// You are too busy to do that at the moment.
|
||||
m.SendLocalizedMessage(1049616);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.Holding != null)
|
||||
{
|
||||
// You cannot teleport while dragging an object.
|
||||
m.SendLocalizedMessage(1071955);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool UseGate(Mobile m)
|
||||
{
|
||||
if (!CanUseGate(m, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m.CloseGump(typeof(MoongateGump));
|
||||
m.SendGump(new MoongateGump(m, this));
|
||||
|
||||
PlaySound(m);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void PlaySound(Mobile m)
|
||||
{
|
||||
if (!m.Hidden || m.IsPlayer())
|
||||
{
|
||||
Effects.PlaySound(m.Location, m.Map, 0x20E);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendSound(0x20E);
|
||||
}
|
||||
}
|
||||
|
||||
protected PMEntry FindEntry()
|
||||
{
|
||||
return FindEntry(PMList.GetList(Map));
|
||||
}
|
||||
|
||||
protected PMEntry FindEntry(PMList list)
|
||||
{
|
||||
if (list != null)
|
||||
{
|
||||
return PMList.FindEntry(list, Location);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class PMEntry
|
||||
{
|
||||
public Point3D Location { get; private set; }
|
||||
public int Number { get; private set; }
|
||||
public TextDefinition Desc { get; private set; }
|
||||
|
||||
public PMEntry(Point3D loc, int number)
|
||||
: this(loc, number, String.Empty)
|
||||
{ }
|
||||
|
||||
public PMEntry(Point3D loc, int number, TextDefinition desc)
|
||||
{
|
||||
Location = loc;
|
||||
Number = number;
|
||||
Desc = desc;
|
||||
}
|
||||
}
|
||||
|
||||
public class PMList
|
||||
{
|
||||
public static readonly PMList Trammel = new PMList(
|
||||
1012000,
|
||||
1012012,
|
||||
Map.Trammel,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
|
||||
new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
|
||||
new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
|
||||
new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
|
||||
new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
|
||||
new PMEntry(new Point3D(1828, 2948, -20), 1012008), // Trinsic
|
||||
new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
|
||||
/* Dynamic Z for Magincia to support both old and new maps. */
|
||||
new PMEntry(new Point3D(3563, 2139, Map.Trammel.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
|
||||
new PMEntry(new Point3D(3450, 2677, 25), 1078098) // New Haven
|
||||
});
|
||||
|
||||
public static readonly PMList Felucca = new PMList(
|
||||
1012001,
|
||||
1012013,
|
||||
Map.Felucca,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
|
||||
new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
|
||||
new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
|
||||
new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
|
||||
new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
|
||||
new PMEntry(new Point3D(1828, 2948, -20), 1012008), // Trinsic
|
||||
new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
|
||||
/* Dynamic Z for Magincia to support both old and new maps. */
|
||||
new PMEntry(new Point3D(3563, 2139, Map.Felucca.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
|
||||
new PMEntry(new Point3D(2711, 2234, 0), 1019001) // Buccaneer's Den
|
||||
});
|
||||
|
||||
public static readonly PMList Ilshenar = new PMList(
|
||||
1012002,
|
||||
1012014,
|
||||
Map.Ilshenar,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1215, 467, -13), 1012015), // Compassion
|
||||
new PMEntry(new Point3D(722, 1366, -60), 1012016), // Honesty
|
||||
new PMEntry(new Point3D(744, 724, -28), 1012017), // Honor
|
||||
new PMEntry(new Point3D(281, 1016, 0), 1012018), // Humility
|
||||
new PMEntry(new Point3D(987, 1011, -32), 1012019), // Justice
|
||||
new PMEntry(new Point3D(1174, 1286, -30), 1012020), // Sacrifice
|
||||
new PMEntry(new Point3D(1532, 1340, -3), 1012021), // Spirituality
|
||||
new PMEntry(new Point3D(528, 216, -45), 1012022), // Valor
|
||||
new PMEntry(new Point3D(1721, 218, 96), 1019000) // Chaos
|
||||
});
|
||||
|
||||
public static readonly PMList Malas = new PMList(
|
||||
1060643,
|
||||
1062039,
|
||||
Map.Malas,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1015, 527, -65), 1060641), // Luna
|
||||
new PMEntry(new Point3D(1997, 1386, -85), 1060642) // Umbra
|
||||
});
|
||||
|
||||
public static readonly PMList Tokuno = new PMList(
|
||||
1063258,
|
||||
1063415,
|
||||
Map.Tokuno,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(1169, 998, 41), 1063412), // Isamu-Jima
|
||||
new PMEntry(new Point3D(802, 1204, 25), 1063413), // Makoto-Jima
|
||||
new PMEntry(new Point3D(270, 628, 15), 1063414) // Homare-Jima
|
||||
});
|
||||
|
||||
public static readonly PMList TerMur = new PMList(
|
||||
1113602,
|
||||
1113604,
|
||||
Map.TerMur,
|
||||
new[]
|
||||
{
|
||||
new PMEntry(new Point3D(850, 3525, -38), 1113603), // Royal City
|
||||
Core.TOL
|
||||
? new PMEntry(new Point3D(719, 1863, 40), 1156262)
|
||||
: new PMEntry(new Point3D(926, 3989, -36), 1112572) // Valley of Eodon
|
||||
// Holy City
|
||||
});
|
||||
|
||||
public static readonly PMList[] UORLists = {Trammel, Felucca};
|
||||
public static readonly PMList[] UORListsYoung = {Trammel};
|
||||
public static readonly PMList[] LBRLists = {Trammel, Felucca, Ilshenar};
|
||||
public static readonly PMList[] LBRListsYoung = {Trammel, Ilshenar};
|
||||
public static readonly PMList[] AOSLists = {Trammel, Felucca, Ilshenar, Malas};
|
||||
public static readonly PMList[] AOSListsYoung = {Trammel, Ilshenar, Malas};
|
||||
public static readonly PMList[] SELists = {Trammel, Felucca, Ilshenar, Malas, Tokuno};
|
||||
public static readonly PMList[] SEListsYoung = {Trammel, Ilshenar, Malas, Tokuno};
|
||||
public static readonly PMList[] SALists = {Trammel, Felucca, Ilshenar, Malas, Tokuno, TerMur};
|
||||
public static readonly PMList[] SAListsYoung = {Trammel, Ilshenar, Malas, Tokuno, TerMur};
|
||||
public static readonly PMList[] RedLists = {Felucca};
|
||||
public static readonly PMList[] SigilLists = {Felucca};
|
||||
|
||||
public static readonly PMList[] AllLists = { Trammel, Felucca, Ilshenar, Malas, Tokuno, TerMur };
|
||||
|
||||
public static PMList GetList(Map map)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (map == Map.Trammel)
|
||||
{
|
||||
return Trammel;
|
||||
}
|
||||
|
||||
if (map == Map.Felucca)
|
||||
{
|
||||
return Felucca;
|
||||
}
|
||||
|
||||
if (map == Map.Ilshenar)
|
||||
{
|
||||
return Ilshenar;
|
||||
}
|
||||
|
||||
if (map == Map.Malas)
|
||||
{
|
||||
return Malas;
|
||||
}
|
||||
|
||||
if (map == Map.Tokuno)
|
||||
{
|
||||
return Tokuno;
|
||||
}
|
||||
|
||||
if (map == Map.TerMur)
|
||||
{
|
||||
return TerMur;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int IndexOfEntry(PMEntry entry)
|
||||
{
|
||||
var list = AllLists.FirstOrDefault(o => o.Entries.Contains(entry));
|
||||
|
||||
return IndexOfEntry(list, entry);
|
||||
}
|
||||
|
||||
public static int IndexOfEntry(PMList list, PMEntry entry)
|
||||
{
|
||||
if (list != null && entry != null)
|
||||
{
|
||||
return Array.IndexOf(list.Entries, entry);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static PMEntry FindEntry(PMList list, Point3D loc)
|
||||
{
|
||||
if (list != null)
|
||||
{
|
||||
return list.Entries.FirstOrDefault(o => o.Location == loc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PMEntry FindEntry(Map map, Point3D loc)
|
||||
{
|
||||
var list = GetList(map);
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
return FindEntry(list, loc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private readonly int m_Number;
|
||||
private readonly int m_SelNumber;
|
||||
private readonly Map m_Map;
|
||||
private readonly PMEntry[] m_Entries;
|
||||
|
||||
public PMList(int number, int selNumber, Map map, PMEntry[] entries)
|
||||
{
|
||||
m_Number = number;
|
||||
m_SelNumber = selNumber;
|
||||
m_Map = map;
|
||||
m_Entries = entries;
|
||||
}
|
||||
|
||||
public int Number { get { return m_Number; } }
|
||||
public int SelNumber { get { return m_SelNumber; } }
|
||||
public Map Map { get { return m_Map; } }
|
||||
public PMEntry[] Entries { get { return m_Entries; } }
|
||||
}
|
||||
|
||||
public class MoongateGump : Gump
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly Item m_Moongate;
|
||||
private readonly PMList[] m_Lists;
|
||||
|
||||
public MoongateGump(Mobile mobile, Item moongate)
|
||||
: base(100, 100)
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
m_Moongate = moongate;
|
||||
|
||||
PMList[] checkLists;
|
||||
|
||||
if (mobile.Player)
|
||||
{
|
||||
if (mobile.IsStaff())
|
||||
{
|
||||
var flags = mobile.NetState == null ? ClientFlags.None : mobile.NetState.Flags;
|
||||
|
||||
if (Core.SA && (flags & ClientFlags.TerMur) != 0)
|
||||
{
|
||||
checkLists = PMList.SALists;
|
||||
}
|
||||
else if (Core.SE && (flags & ClientFlags.Tokuno) != 0)
|
||||
{
|
||||
checkLists = PMList.SELists;
|
||||
}
|
||||
else if (Core.AOS && (flags & ClientFlags.Malas) != 0)
|
||||
{
|
||||
checkLists = PMList.AOSLists;
|
||||
}
|
||||
else if ((flags & ClientFlags.Ilshenar) != 0)
|
||||
{
|
||||
checkLists = PMList.LBRLists;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLists = PMList.UORLists;
|
||||
}
|
||||
}
|
||||
else if (Sigil.ExistsOn(mobile))
|
||||
{
|
||||
checkLists = PMList.SigilLists;
|
||||
}
|
||||
else if (SpellHelper.RestrictRedTravel && mobile.Murderer && !Siege.SiegeShard)
|
||||
{
|
||||
checkLists = PMList.RedLists;
|
||||
}
|
||||
else
|
||||
{
|
||||
var flags = mobile.NetState == null ? ClientFlags.None : mobile.NetState.Flags;
|
||||
var young = mobile is PlayerMobile && ((PlayerMobile)mobile).Young;
|
||||
|
||||
if (Core.SA && (flags & ClientFlags.TerMur) != 0)
|
||||
{
|
||||
checkLists = young ? PMList.SAListsYoung : PMList.SALists;
|
||||
}
|
||||
else if (Core.SE && (flags & ClientFlags.Tokuno) != 0)
|
||||
{
|
||||
checkLists = young ? PMList.SEListsYoung : PMList.SELists;
|
||||
}
|
||||
else if (Core.AOS && (flags & ClientFlags.Malas) != 0)
|
||||
{
|
||||
checkLists = young ? PMList.AOSListsYoung : PMList.AOSLists;
|
||||
}
|
||||
else if ((flags & ClientFlags.Ilshenar) != 0)
|
||||
{
|
||||
checkLists = young ? PMList.LBRListsYoung : PMList.LBRLists;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLists = young ? PMList.UORListsYoung : PMList.UORLists;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
checkLists = PMList.SELists;
|
||||
}
|
||||
|
||||
m_Lists = new PMList[checkLists.Length];
|
||||
|
||||
for (var i = 0; i < m_Lists.Length; ++i)
|
||||
{
|
||||
m_Lists[i] = checkLists[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < m_Lists.Length; ++i)
|
||||
{
|
||||
if (m_Lists[i].Map == mobile.Map)
|
||||
{
|
||||
var temp = m_Lists[i];
|
||||
|
||||
m_Lists[i] = m_Lists[0];
|
||||
m_Lists[0] = temp;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 380, 280, 5054);
|
||||
|
||||
AddButton(10, 210, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 210, 140, 25, 1011036, false, false); // OKAY
|
||||
|
||||
AddButton(10, 235, 4005, 4007, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(45, 235, 140, 25, 1011012, false, false); // CANCEL
|
||||
|
||||
AddHtmlLocalized(5, 5, 200, 20, 1012011, false, false); // Pick your destination:
|
||||
|
||||
for (var i = 0; i < checkLists.Length; ++i)
|
||||
{
|
||||
if (Siege.SiegeShard && checkLists[i].Number == 1012000) // Trammel
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddButton(10, 35 + (i * 25), 2117, 2118, 0, GumpButtonType.Page, Array.IndexOf(m_Lists, checkLists[i]) + 1);
|
||||
AddHtmlLocalized(30, 35 + (i * 25), 150, 20, checkLists[i].Number, false, false);
|
||||
}
|
||||
|
||||
for (var i = 0; i < m_Lists.Length; ++i)
|
||||
{
|
||||
RenderPage(i, Array.IndexOf(checkLists, m_Lists[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 0) // Cancel
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_Mobile.Deleted || m_Moongate.Deleted || m_Mobile.Map == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var switches = info.Switches;
|
||||
|
||||
if (switches.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var switchID = switches[0];
|
||||
var listIndex = switchID / 100;
|
||||
var listEntry = switchID % 100;
|
||||
|
||||
if (listIndex < 0 || listIndex >= m_Lists.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var list = m_Lists[listIndex];
|
||||
|
||||
if (listEntry < 0 || listEntry >= list.Entries.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var entry = list.Entries[listEntry];
|
||||
|
||||
if (m_Mobile.Map == list.Map && m_Mobile.InRange(entry.Location, 1))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019003); // You are already there.
|
||||
return;
|
||||
}
|
||||
if (m_Mobile.IsStaff())
|
||||
{
|
||||
//Staff can always use a gate!
|
||||
}
|
||||
else if (!m_Mobile.InRange(m_Moongate.GetWorldLocation(), 1) || m_Mobile.Map != m_Moongate.Map)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019002); // You are too far away to use the gate.
|
||||
return;
|
||||
}
|
||||
else if (m_Mobile.Player && SpellHelper.RestrictRedTravel && m_Mobile.Murderer && list.Map != Map.Felucca && !Siege.SiegeShard)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
return;
|
||||
}
|
||||
else if (Sigil.ExistsOn(m_Mobile) && list.Map != Faction.Facet)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
return;
|
||||
}
|
||||
else if (m_Mobile.Criminal)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
return;
|
||||
}
|
||||
else if (SpellHelper.CheckCombat(m_Mobile))
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
return;
|
||||
}
|
||||
else if (m_Mobile.Spell != null)
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
return;
|
||||
}
|
||||
|
||||
BaseCreature.TeleportPets(m_Mobile, entry.Location, list.Map);
|
||||
|
||||
m_Mobile.Combatant = null;
|
||||
m_Mobile.Warmode = false;
|
||||
m_Mobile.Hidden = true;
|
||||
|
||||
m_Mobile.MoveToWorld(entry.Location, list.Map);
|
||||
|
||||
Effects.PlaySound(entry.Location, list.Map, 0x1FE);
|
||||
|
||||
CityTradeSystem.OnPublicMoongateUsed(m_Mobile);
|
||||
}
|
||||
|
||||
private void RenderPage(int index, int offset)
|
||||
{
|
||||
var list = m_Lists[index];
|
||||
|
||||
if (Siege.SiegeShard && list.Number == 1012000) // Trammel
|
||||
return;
|
||||
|
||||
AddPage(index + 1);
|
||||
|
||||
AddButton(10, 35 + (offset * 25), 2117, 2118, 0, GumpButtonType.Page, index + 1);
|
||||
AddHtmlLocalized(30, 35 + (offset * 25), 150, 20, list.SelNumber, false, false);
|
||||
|
||||
var entries = list.Entries;
|
||||
|
||||
for (var i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
AddRadio(200, 35 + (i * 25), 210, 211, false, (index * 100) + i);
|
||||
AddHtmlLocalized(225, 35 + (i * 25), 150, 20, entries[i].Number, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
129
Scripts/Items/Functional/SawTrap.cs
Normal file
129
Scripts/Items/Functional/SawTrap.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum SawTrapType
|
||||
{
|
||||
WestWall,
|
||||
NorthWall,
|
||||
WestFloor,
|
||||
NorthFloor
|
||||
}
|
||||
|
||||
public class SawTrap : BaseTrap
|
||||
{
|
||||
[Constructable]
|
||||
public SawTrap()
|
||||
: this(SawTrapType.NorthFloor)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SawTrap(SawTrapType type)
|
||||
: base(GetBaseID(type))
|
||||
{
|
||||
}
|
||||
|
||||
public SawTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SawTrapType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
switch ( this.ItemID )
|
||||
{
|
||||
case 0x1103:
|
||||
return SawTrapType.NorthWall;
|
||||
case 0x1116:
|
||||
return SawTrapType.WestWall;
|
||||
case 0x11AC:
|
||||
return SawTrapType.NorthFloor;
|
||||
case 0x11B1:
|
||||
return SawTrapType.WestFloor;
|
||||
}
|
||||
|
||||
return SawTrapType.NorthWall;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ItemID = GetBaseID(value);
|
||||
}
|
||||
}
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds(0.0);
|
||||
}
|
||||
}
|
||||
public static int GetBaseID(SawTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case SawTrapType.NorthWall:
|
||||
return 0x1103;
|
||||
case SawTrapType.WestWall:
|
||||
return 0x1116;
|
||||
case SawTrapType.NorthFloor:
|
||||
return 0x11AC;
|
||||
case SawTrapType.WestFloor:
|
||||
return 0x11B1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (!from.Alive || from.IsStaff())
|
||||
return;
|
||||
|
||||
Effects.SendLocationEffect(this.Location, this.Map, GetBaseID(this.Type) + 1, 6, 3, this.GetEffectHue(), 0);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x21C);
|
||||
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), from, from, Utility.RandomMinMax(5, 15));
|
||||
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x22, 500853); // You stepped onto a blade trap!
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
142
Scripts/Items/Functional/ScaleCollar.cs
Normal file
142
Scripts/Items/Functional/ScaleCollar.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ScaleCollar : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1112480; } } //a scale collar
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public ScaleCollar() : base(4235)
|
||||
{
|
||||
Hue = 2125;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack) && m_Timer == null)
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
from.SendLocalizedMessage(1112481); //Which battle chicken do you wish to ensnare?
|
||||
}
|
||||
else if (IsChildOf(from.Backpack) && m_Timer != null)
|
||||
{
|
||||
from.SendLocalizedMessage(501789); //You must wait before trying again.
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1042004); // That must be in your pack for you to use it.
|
||||
}
|
||||
|
||||
public void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (targeted is BattleChickenLizard && !((BattleChickenLizard)targeted).Controlled)
|
||||
{
|
||||
BattleChickenLizard bcl = (BattleChickenLizard)targeted;
|
||||
|
||||
int chance = 50 / (int)Math.Max(1, from.GetDistanceToSqrt(bcl.Location));
|
||||
|
||||
if (chance > Utility.Random(100))
|
||||
{
|
||||
bcl.Frozen = true;
|
||||
|
||||
m_Timer = new InternalTimer(this, bcl, from);
|
||||
from.SendLocalizedMessage(1112484); //You successfully ensnare the chicken! You best hurry before it frees itself from it!
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1112483); //The collar falls to the ground as the chicken deftly avoids it.
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTick(BaseCreature lizard, Mobile owner)
|
||||
{
|
||||
if (lizard != null && lizard.Controlled)
|
||||
{
|
||||
lizard.Frozen = false;
|
||||
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
else
|
||||
lizard.FixedEffect(0x376A, 1, 32);
|
||||
}
|
||||
|
||||
public void EndTimer(BaseCreature lizard, Mobile owner)
|
||||
{
|
||||
if (lizard != null && lizard.Alive)
|
||||
{
|
||||
lizard.Frozen = false;
|
||||
|
||||
if (owner != null && !lizard.Controlled)
|
||||
owner.SendLocalizedMessage(1112482); //The chicken frees itself of the collar!!
|
||||
}
|
||||
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private ScaleCollar m_Collar;
|
||||
|
||||
public InternalTarget(ScaleCollar collar) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
m_Collar = collar;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if(m_Collar != null)
|
||||
m_Collar.OnTarget(from, targeted);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private ScaleCollar m_Collar;
|
||||
private BattleChickenLizard m_Lizard;
|
||||
private DateTime m_EndTime;
|
||||
private Mobile m_Owner;
|
||||
|
||||
public InternalTimer(ScaleCollar collar, BattleChickenLizard lizard, Mobile owner) : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
|
||||
{
|
||||
m_Collar = collar;
|
||||
m_Lizard = lizard;
|
||||
m_Owner = owner;
|
||||
m_EndTime = DateTime.UtcNow + TimeSpan.FromSeconds(30);
|
||||
|
||||
lizard.FixedEffect(0x376A, 1, 32);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_EndTime < DateTime.UtcNow)
|
||||
m_Collar.EndTimer(m_Lizard, m_Owner);
|
||||
else
|
||||
m_Collar.OnTick(m_Lizard, m_Owner);
|
||||
}
|
||||
}
|
||||
|
||||
public ScaleCollar(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
172
Scripts/Items/Functional/SecretDoors.cs
Normal file
172
Scripts/Items/Functional/SecretDoors.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SecretStoneDoor1 : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretStoneDoor1(DoorFacing facing)
|
||||
: base(0xE8 + (2 * (int)facing), 0xE9 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretStoneDoor1(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class SecretDungeonDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretDungeonDoor(DoorFacing facing)
|
||||
: base(0x314 + (2 * (int)facing), 0x315 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretDungeonDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class SecretStoneDoor2 : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretStoneDoor2(DoorFacing facing)
|
||||
: base(0x324 + (2 * (int)facing), 0x325 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretStoneDoor2(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class SecretWoodenDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretWoodenDoor(DoorFacing facing)
|
||||
: base(0x334 + (2 * (int)facing), 0x335 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretWoodenDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class SecretLightWoodDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretLightWoodDoor(DoorFacing facing)
|
||||
: base(0x344 + (2 * (int)facing), 0x345 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretLightWoodDoor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class SecretStoneDoor3 : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public SecretStoneDoor3(DoorFacing facing)
|
||||
: base(0x354 + (2 * (int)facing), 0x355 + (2 * (int)facing), 0xED, 0xF4, BaseDoor.GetOffset(facing))
|
||||
{
|
||||
}
|
||||
|
||||
public SecretStoneDoor3(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer) // Default Serialize method
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader) // Default Deserialize method
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
395
Scripts/Items/Functional/SeedBox/SeedBox.cs
Normal file
395
Scripts/Items/Functional/SeedBox/SeedBox.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
using System;
|
||||
using Server;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.VeteranRewards;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using System.Linq;
|
||||
using Server.ContextMenus;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Plants
|
||||
{
|
||||
[FlipableAttribute(19288, 19290)]
|
||||
public class SeedBox : Container, IRewardItem, ISecurable
|
||||
{
|
||||
public static readonly int MaxSeeds = 5000;
|
||||
public static readonly int MaxUnique = 300;
|
||||
|
||||
public override int DefaultMaxItems { get { return MaxUnique; } }
|
||||
public override bool DisplaysContent { get { return false; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsRewardItem { get; set; }
|
||||
|
||||
public List<SeedEntry> Entries { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int TotalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if(Entries != null)
|
||||
Entries.ForEach(e => count += e == null || e.Seed == null ? 0 : e.Seed.Amount);
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int UniqueCount
|
||||
{
|
||||
get { return Entries == null ? 0 : Entries.Where(e => e != null && e.Seed != null && e.Seed.Amount > 0).Count(); }
|
||||
}
|
||||
|
||||
public override double DefaultWeight { get { return 10.0; } }
|
||||
|
||||
[Constructable]
|
||||
public SeedBox() : base(19288)
|
||||
{
|
||||
Entries = new List<SeedEntry>();
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
|
||||
Level = SecureLevel.Owner;
|
||||
}
|
||||
|
||||
public override int GetTotal(TotalType type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (IsChildOf(m.Backpack) || (CheckAccessible(m) && m.InRange(this.GetWorldLocation(), 3)))
|
||||
{
|
||||
if (m is PlayerMobile)
|
||||
BaseGump.SendGump(new SeedBoxGump((PlayerMobile)m, this));
|
||||
}
|
||||
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
base.OnDoubleClick(m);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public bool CheckAccessible(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
return true;
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt(this);
|
||||
|
||||
if (house == null)
|
||||
return true;
|
||||
|
||||
switch (Level)
|
||||
{
|
||||
case SecureLevel.Owner: return house.IsOwner(from);
|
||||
case SecureLevel.CoOwners: return house.IsCoOwner(from);
|
||||
case SecureLevel.Friends: return house.IsFriend(from);
|
||||
case SecureLevel.Anyone: return true;
|
||||
case SecureLevel.Guild: return house.IsGuildMember(from);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (dropped is Seed)
|
||||
{
|
||||
return TryAddSeed(from, (Seed)dropped);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1151838); // This item cannot be stored in the seed box.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryAddSeed(Mobile from, Seed seed, int index = -1)
|
||||
{
|
||||
if (!from.Backpack.CheckHold(from, seed, true, true) || seed.Amount <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!from.InRange(this.GetWorldLocation(), 3) || from.Map != this.Map)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (TotalCount + seed.Amount <= MaxSeeds)
|
||||
{
|
||||
SeedEntry entry = GetExisting(seed);
|
||||
int oldcount = UniqueCount;
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
entry.Seed.Amount += seed.Amount;
|
||||
seed.Delete();
|
||||
|
||||
entry.Seed.InvalidateProperties();
|
||||
}
|
||||
else if (UniqueCount < MaxUnique)
|
||||
{
|
||||
entry = new SeedEntry(seed);
|
||||
DropItem(seed);
|
||||
|
||||
seed.Movable = false;
|
||||
seed.InvalidateProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1151839); // There is not enough room in the box.
|
||||
}
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
if (Entries.Contains(entry))
|
||||
{
|
||||
if (index > -1 && index < Entries.Count - 1)
|
||||
{
|
||||
Entries.Remove(entry);
|
||||
AddEntry(entry, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index > -1 && index < Entries.Count)
|
||||
{
|
||||
AddEntry(entry, index);
|
||||
}
|
||||
else
|
||||
AddEntry(entry);
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage(1151846); // You put the seed in the seedbox.
|
||||
|
||||
if (from is PlayerMobile)
|
||||
{
|
||||
var gump = new SeedBoxGump((PlayerMobile)from, this);
|
||||
gump.CheckPage(entry);
|
||||
|
||||
BaseGump.SendGump(gump);
|
||||
}
|
||||
|
||||
InvalidateProperties();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1151839); // There is not enough room in the box.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void AddEntry(SeedEntry entry, int index = -1)
|
||||
{
|
||||
if (index == -1)
|
||||
{
|
||||
TrimEntries();
|
||||
Entries.Add(entry);
|
||||
}
|
||||
else if (index >= 0 && index < Entries.Count)
|
||||
{
|
||||
Entries.Insert(index, entry);
|
||||
}
|
||||
|
||||
if (Entries.Count > 0)
|
||||
{
|
||||
if (ItemID == 19288)
|
||||
{
|
||||
ItemID = 19289;
|
||||
}
|
||||
else if (ItemID == 19290)
|
||||
{
|
||||
ItemID = 19291;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveEntry(SeedEntry entry)
|
||||
{
|
||||
Entries.Remove(entry);
|
||||
TrimEntries();
|
||||
|
||||
if (Entries.Count == 0)
|
||||
{
|
||||
if (ItemID == 19289)
|
||||
{
|
||||
ItemID = 19288;
|
||||
}
|
||||
else if (ItemID == 19291)
|
||||
{
|
||||
ItemID = 19290;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DropSeed(Mobile from, SeedEntry entry, int amount)
|
||||
{
|
||||
if (amount > entry.Seed.Amount)
|
||||
amount = entry.Seed.Amount;
|
||||
|
||||
Seed seed;
|
||||
|
||||
if (amount == entry.Seed.Amount)
|
||||
{
|
||||
seed = entry.Seed;
|
||||
entry.Seed = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
seed = new Seed(entry.Seed.PlantType, entry.Seed.PlantHue, true);
|
||||
seed.Amount = amount;
|
||||
|
||||
entry.Seed.Amount -= amount;
|
||||
}
|
||||
|
||||
seed.Movable = true;
|
||||
|
||||
if (from.Backpack == null || !from.Backpack.TryDropItem(from, seed, false))
|
||||
{
|
||||
seed.MoveToWorld(from.Location, from.Map);
|
||||
from.SendLocalizedMessage(1151844); // There is not enough room in your backpack!
|
||||
}
|
||||
|
||||
if (entry.Seed != null && entry.Seed.Amount <= 0)
|
||||
{
|
||||
entry.Seed.Delete();
|
||||
entry.Seed = null;
|
||||
}
|
||||
|
||||
if (entry.Seed == null || entry.Seed.Amount <= 0)
|
||||
{
|
||||
RemoveEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public SeedEntry GetExisting(Seed seed)
|
||||
{
|
||||
return Entries.FirstOrDefault(e => e != null && e.Seed != null && e.Seed.PlantType == seed.PlantType && e.Seed.PlantHue == seed.PlantHue);
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (IsRewardItem)
|
||||
{
|
||||
list.Add(1076220); // 4th Year Veteran Reward
|
||||
}
|
||||
|
||||
list.Add(1151847, String.Format("{0}\t{1}", TotalCount.ToString(), MaxSeeds.ToString())); // Seeds in Box: ~1_val~ / ~2_val~
|
||||
list.Add(1151848, String.Format("{0}\t{1}", UniqueCount.ToString(), MaxUnique.ToString())); // Unique Seeds In Box: ~1_val~ / ~2_val~
|
||||
}
|
||||
|
||||
private void CheckEntries()
|
||||
{
|
||||
List<Item> toDelete = new List<Item>(this.Items);
|
||||
|
||||
foreach (var item in toDelete.Where(i => i != null && i.Amount == 0))
|
||||
item.Delete();
|
||||
|
||||
List<SeedEntry> entries = new List<SeedEntry>(Entries);
|
||||
|
||||
foreach(var entry in entries.Where(e => e != null && (e.Seed == null || e.Seed.Amount == 0 || e.Seed.Deleted)))
|
||||
Entries.Remove(entry);
|
||||
|
||||
ColUtility.Free(entries);
|
||||
ColUtility.Free(toDelete);
|
||||
}
|
||||
|
||||
public void TrimEntries()
|
||||
{
|
||||
int lastIndex = Entries.FindLastIndex(e => e != null);
|
||||
|
||||
if (lastIndex + 1 < Entries.Count - 1)
|
||||
{
|
||||
Entries.RemoveRange(lastIndex + 1, (Entries.Count - 1) - lastIndex);
|
||||
}
|
||||
|
||||
Entries.TrimExcess();
|
||||
}
|
||||
|
||||
public SeedBox(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)1);
|
||||
|
||||
writer.Write(IsRewardItem);
|
||||
writer.Write((int)Level);
|
||||
|
||||
writer.Write(Entries.Count);
|
||||
for (int i = 0; i < Entries.Count; i++)
|
||||
{
|
||||
SeedEntry entry = Entries[i];
|
||||
|
||||
if (entry == null)
|
||||
{
|
||||
writer.Write(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(1);
|
||||
entry.Serialize(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
|
||||
Entries = new List<SeedEntry>();
|
||||
|
||||
IsRewardItem = reader.ReadBool();
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
switch (reader.ReadInt())
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
Entries.Add(null);
|
||||
break;
|
||||
case 1:
|
||||
SeedEntry entry = new SeedEntry(reader);
|
||||
|
||||
if (entry.Seed != null)
|
||||
Entries.Add(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(
|
||||
() =>
|
||||
{
|
||||
foreach (var item in Items.Where(i => i.Movable))
|
||||
item.Movable = false;
|
||||
});
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), CheckEntries);
|
||||
}
|
||||
}
|
||||
}
|
||||
299
Scripts/Items/Functional/SeedBox/SeedBoxGump.cs
Normal file
299
Scripts/Items/Functional/SeedBox/SeedBoxGump.cs
Normal file
@@ -0,0 +1,299 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using Server.Engines.Plants;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Plants
|
||||
{
|
||||
public class SeedBoxGump : BaseGump
|
||||
{
|
||||
public SeedBox Box { get; set; }
|
||||
public int Page { get; set; }
|
||||
|
||||
public int Pages { get { return (int)Math.Ceiling((double)Box.Entries.Count / 20.0); } }
|
||||
|
||||
public SeedBoxGump(PlayerMobile user, SeedBox box, int page = 1) : base(user, 100, 100)
|
||||
{
|
||||
Box = box;
|
||||
Page = page;
|
||||
|
||||
user.CloseGump(this.GetType());
|
||||
}
|
||||
|
||||
public override void AddGumpLayout()
|
||||
{
|
||||
AddImage(0, 0, 2172);
|
||||
|
||||
int start = (Page - 1) * 20;
|
||||
int index = 0;
|
||||
|
||||
AddHtmlLocalized(100, 345, 300, 20, 1151850, String.Format("{0}\t{1}", Page.ToString(), Pages.ToString()), 0xFFFF, false, false);
|
||||
|
||||
if (Page > 1)
|
||||
{
|
||||
AddButton(45, 345, 5603, 5603, 1, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
if (Page < Pages)
|
||||
{
|
||||
AddButton(235, 345, 5601, 5601, 2, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
for (int i = start; i < Box.Entries.Count && i < start + 20; i++)
|
||||
{
|
||||
SeedEntry entry = Box.Entries[i];
|
||||
|
||||
if (entry == null || entry.Seed == null)
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int x; int y;
|
||||
|
||||
if (index < 4)
|
||||
{
|
||||
x = 15 + (index * 70);
|
||||
y = 15;
|
||||
}
|
||||
else if (index < 8)
|
||||
{
|
||||
x = 15 + ((index - 4) * 70);
|
||||
y = 82;
|
||||
}
|
||||
else if (index < 12)
|
||||
{
|
||||
x = 15 + ((index - 8) * 70);
|
||||
y = 149;
|
||||
}
|
||||
else if (index < 16)
|
||||
{
|
||||
x = 15 + ((index - 12) * 70);
|
||||
y = 216;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 15 + ((index - 16) * 70);
|
||||
y = 283;
|
||||
}
|
||||
|
||||
AddButton(x, y, entry.Image, entry.Image, i + 100, GumpButtonType.Reply, 0);
|
||||
AddItem(x, y + 30, 0xDCF, entry.Seed.Hue);
|
||||
|
||||
AddItemProperty(entry.Seed.Serial);
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckPage(SeedEntry entry)
|
||||
{
|
||||
int index = Box.Entries.IndexOf(entry);
|
||||
|
||||
Page = (int)Math.Ceiling((double)(index + 1) / 20);
|
||||
}
|
||||
|
||||
public override void OnResponse(RelayInfo info)
|
||||
{
|
||||
if (Box.Deleted)
|
||||
return;
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0: break;
|
||||
case 1: // page back
|
||||
Page--;
|
||||
|
||||
if (Page < 1)
|
||||
Page = 1;
|
||||
|
||||
Refresh();
|
||||
break;
|
||||
case 2: // page forward
|
||||
Page++;
|
||||
|
||||
if (Page > Pages)
|
||||
Page = Pages;
|
||||
|
||||
Refresh();
|
||||
break;
|
||||
default:
|
||||
int id = info.ButtonID - 100;
|
||||
|
||||
if (id >= 0 && id < Box.Entries.Count)
|
||||
{
|
||||
SeedEntry entry = Box.Entries[id];
|
||||
|
||||
if (entry == null)
|
||||
return;
|
||||
|
||||
Refresh();
|
||||
BaseGump.SendGump(new SeedInfoGump(User, Box, entry, this));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SeedInfoGump : BaseGump
|
||||
{
|
||||
public SeedBox Box { get; set; }
|
||||
public SeedEntry Entry { get; set; }
|
||||
|
||||
public static int TextHue = 0x696969;
|
||||
|
||||
public SeedInfoGump(PlayerMobile user, SeedBox box, SeedEntry entry, SeedBoxGump par) : base(user, parent: par)
|
||||
{
|
||||
Box = box;
|
||||
Entry = entry;
|
||||
|
||||
user.CloseGump(this.GetType());
|
||||
}
|
||||
|
||||
public override void AddGumpLayout()
|
||||
{
|
||||
if (Entry == null || Entry.Seed == null)
|
||||
{
|
||||
User.CloseGump(this.GetType());
|
||||
return;
|
||||
}
|
||||
|
||||
AddBackground(0, 0, 300, 280, 5170);
|
||||
|
||||
string args;
|
||||
int seedloc = Entry.Seed.GetLabel(out args);
|
||||
int index = Box.Entries.IndexOf(Entry);
|
||||
|
||||
AddHtmlLocalized(30, 25, 270, 20, seedloc, args, C32216(TextHue), false, false);
|
||||
|
||||
AddHtmlLocalized(50, 60, 150, 20, 1151840, C32216(TextHue), false, false); // Remove: 1
|
||||
AddButton(30, 60, 10740, 10740, 1, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(50, 90, 150, 20, 1151841, Entry.Seed.Amount.ToString(), C32216(TextHue), false, false); // Remove: ~1_val~
|
||||
AddButton(30, 90, 10740, 10740, 2, GumpButtonType.Reply, 0);
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
AddHtmlLocalized(50, 120, 150, 20, 1151851, C32216(TextHue), false, false); // Insert Seed Before
|
||||
AddButton(30, 120, 10740, 10740, 3, GumpButtonType.Reply, 0);
|
||||
}
|
||||
else
|
||||
AddImage(30, 120, 10740);
|
||||
|
||||
if (Box.Entries.Count < SeedBox.MaxUnique)
|
||||
{
|
||||
AddHtmlLocalized(50, 150, 150, 20, 1151852, C32216(TextHue), false, false); // Insert Seed After
|
||||
AddButton(30, 150, 10740, 10740, 4, GumpButtonType.Reply, 0);
|
||||
}
|
||||
else
|
||||
AddImage(30, 150, 10740);
|
||||
|
||||
if (index < Box.Entries.Count && Box.Entries.Count < SeedBox.MaxUnique)
|
||||
{
|
||||
AddHtmlLocalized(50, 180, 150, 20, 1151842, C32216(TextHue), false, false); // Shift Right
|
||||
AddButton(30, 180, 10740, 10740, 5, GumpButtonType.Reply, 0);
|
||||
}
|
||||
else
|
||||
AddImage(30, 180, 10740);
|
||||
|
||||
if (index > 0 && Box.Entries[index - 1] == null)
|
||||
{
|
||||
AddHtmlLocalized(50, 210, 150, 20, 1151843, C32216(TextHue), false, false); // Shift Left
|
||||
AddButton(30, 210, 10740, 10740, 6, GumpButtonType.Reply, 0);
|
||||
}
|
||||
else
|
||||
AddImage(30, 210, 10740);
|
||||
}
|
||||
|
||||
public override void OnResponse(RelayInfo info)
|
||||
{
|
||||
if (Box.Deleted)
|
||||
return;
|
||||
|
||||
int index = Box.Entries.IndexOf(Entry);
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 0: break;
|
||||
case 1:
|
||||
Box.DropSeed(User, Entry, 1);
|
||||
|
||||
RefreshParent();
|
||||
break;
|
||||
case 2:
|
||||
Box.DropSeed(User, Entry, Entry.Seed.Amount);
|
||||
|
||||
RefreshParent();
|
||||
break;
|
||||
case 3:
|
||||
User.SendLocalizedMessage(1151849); // Click this button and target a seed to add it here.
|
||||
User.BeginTarget(-1, false, TargetFlags.None, (from, targeted) =>
|
||||
{
|
||||
Seed seed = targeted as Seed;
|
||||
|
||||
if (seed != null)
|
||||
{
|
||||
if (Box != null && !Box.Deleted && index > 0)
|
||||
{
|
||||
Box.TryAddSeed(User, seed, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1151838); // This item cannot be stored in the seed box.
|
||||
|
||||
RefreshParent();
|
||||
});
|
||||
break;
|
||||
case 4:
|
||||
if (Box.Entries.Count < SeedBox.MaxUnique)
|
||||
{
|
||||
User.SendLocalizedMessage(1151849); // Click this button and target a seed to add it here.
|
||||
User.BeginTarget(-1, false, TargetFlags.None, (from, targeted) =>
|
||||
{
|
||||
Seed seed = targeted as Seed;
|
||||
|
||||
if (seed != null)
|
||||
{
|
||||
if (Box != null && !Box.Deleted && index > 0)
|
||||
{
|
||||
Box.TryAddSeed(User, seed, index + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1151838); // This item cannot be stored in the seed box.
|
||||
|
||||
RefreshParent();
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 5: // shift right
|
||||
if (index >= 0 && index < Box.Entries.Count && Box.Entries.Count < SeedBox.MaxUnique)
|
||||
{
|
||||
Box.Entries.Insert(index, null);
|
||||
|
||||
if (index + 2 < Box.Entries.Count && Box.Entries[index + 2] == null)
|
||||
Box.Entries.RemoveAt(index + 2);
|
||||
|
||||
if (Parent is SeedBoxGump)
|
||||
((SeedBoxGump)Parent).CheckPage(Entry);
|
||||
|
||||
RefreshParent(true);
|
||||
}
|
||||
break;
|
||||
case 6: // shift left
|
||||
if (index >= 0 && index < Box.Entries.Count && Box.Entries[index - 1] == null)
|
||||
{
|
||||
Box.Entries.Remove(Entry);
|
||||
Box.Entries.Insert(index - 1, Entry);
|
||||
Box.TrimEntries();
|
||||
if(Parent is SeedBoxGump)
|
||||
((SeedBoxGump)Parent).CheckPage(Entry);
|
||||
RefreshParent(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Scripts/Items/Functional/SeedBox/SeedEntry.cs
Normal file
37
Scripts/Items/Functional/SeedBox/SeedEntry.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Engines.Plants;
|
||||
|
||||
namespace Server.Engines.Plants
|
||||
{
|
||||
public class SeedEntry
|
||||
{
|
||||
public Seed Seed { get; set; }
|
||||
public int Image { get; set; }
|
||||
|
||||
public SeedEntry(Seed seed)
|
||||
{
|
||||
Seed = seed;
|
||||
|
||||
seed.ShowType = true;
|
||||
|
||||
Image = Utility.Random(2183, 3);
|
||||
}
|
||||
|
||||
public SeedEntry(GenericReader reader)
|
||||
{
|
||||
int v = reader.ReadInt();
|
||||
|
||||
Seed = reader.ReadItem() as Seed;
|
||||
Image = reader.ReadInt();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write((int)0);
|
||||
|
||||
writer.Write(Seed);
|
||||
writer.Write(Image);
|
||||
}
|
||||
}
|
||||
}
|
||||
190
Scripts/Items/Functional/SerpentNest.cs
Normal file
190
Scripts/Items/Functional/SerpentNest.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SerpentNest : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1112582; } } // a serpent's nest
|
||||
|
||||
[Constructable]
|
||||
public SerpentNest()
|
||||
: base(0x2233)
|
||||
{
|
||||
this.Hue = 0x456;
|
||||
this.Movable = false;
|
||||
}
|
||||
|
||||
public SerpentNest(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!from.InRange(this, 1))
|
||||
{
|
||||
SendLocalizedMessageTo(from, 1076766); // That is too far away.
|
||||
return;
|
||||
}
|
||||
|
||||
from.RevealingAction();
|
||||
|
||||
if (0.025 > Utility.RandomDouble())
|
||||
{
|
||||
from.AddToBackpack(new RareSerpentEgg());
|
||||
from.SendLocalizedMessage(1112581); // You reach in and find a rare serpent egg!!
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
from.SendLocalizedMessage(1112578); // You try to reach the eggs, but the hole is too deep.
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
from.SendLocalizedMessage(1112579); // You reach in but clumsily destroy the eggs inside the nest.
|
||||
this.Collapse(from);
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
from.SendLocalizedMessage(1112580); // Beware! You've hatched the eggs!!
|
||||
this.HatchEggs(from);
|
||||
|
||||
from.PrivateOverheadMessage(MessageType.Regular, 33, 1112940, from.NetState); // Your hand remains stuck!!!
|
||||
from.Frozen = true;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5.0), new TimerCallback(
|
||||
delegate
|
||||
{
|
||||
from.Frozen = false;
|
||||
from.PrivateOverheadMessage(MessageType.Regular, 65, 1112941, from.NetState); // You manage to free your hand!
|
||||
}));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Collapse(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(1112583); // The nest collapses.
|
||||
|
||||
this.Delete();
|
||||
}
|
||||
|
||||
public void HatchEggs(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(1112577); // A swarm of snakes springs forth from the nest and attacks you!!!
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
BaseCreature snake = (BaseCreature)Activator.CreateInstance(m_SnakeTypes[Utility.Random(m_SnakeTypes.Length)]);
|
||||
|
||||
snake.RemoveOnSave = true;
|
||||
snake.MoveToWorld(this.Map.GetSpawnPosition(this.Location, 1), this.Map);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
this.Collapse(from);
|
||||
}
|
||||
|
||||
private static Type[] m_SnakeTypes = new Type[]
|
||||
{
|
||||
typeof( LavaSnake ), typeof( Snake ),
|
||||
typeof( CoralSnake ), typeof( GiantSerpent )
|
||||
};
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
BaseCreature snake = m as BaseCreature;
|
||||
|
||||
if (snake != null && snake.CharmMaster != null)
|
||||
{
|
||||
snake.CharmMaster.SendLocalizedMessage(1112588); // The snake begins searching for rare eggs.
|
||||
snake.Frozen = true;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(Utility.RandomMinMax(1, 5)), new TimerCallback(
|
||||
delegate
|
||||
{
|
||||
if (!snake.Alive)
|
||||
return;
|
||||
|
||||
snake.Frozen = false;
|
||||
|
||||
Mobile from = snake.CharmMaster;
|
||||
|
||||
if (from == null || this.Deleted)
|
||||
return;
|
||||
|
||||
if (0.1 > Utility.RandomDouble())
|
||||
{
|
||||
from.SendLocalizedMessage(1112586); // The snake finds a rare egg and drags it out of the nest!
|
||||
new RareSerpentEgg().MoveToWorld(Location, Map);
|
||||
|
||||
this.Collapse(from);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
from.SendLocalizedMessage(1112585); // Beware! The snake has hatched some of the eggs!!
|
||||
this.HatchEggs(from);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
from.SendLocalizedMessage(1112584); // The snake searches the nest and finds nothing.
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
from.SendLocalizedMessage(1112584); // The snake searches the nest and finds nothing.
|
||||
this.Collapse(from);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snake.EndCharm();
|
||||
}));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
148
Scripts/Items/Functional/SerpentPillar.cs
Normal file
148
Scripts/Items/Functional/SerpentPillar.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SerpentPillar : Item
|
||||
{
|
||||
private bool m_Active;
|
||||
private string m_Word;
|
||||
private Rectangle2D m_Destination;
|
||||
[Constructable]
|
||||
public SerpentPillar()
|
||||
: this(null, new Rectangle2D(), false)
|
||||
{
|
||||
}
|
||||
|
||||
public SerpentPillar(string word, Rectangle2D destination)
|
||||
: this(word, destination, true)
|
||||
{
|
||||
}
|
||||
|
||||
public SerpentPillar(string word, Rectangle2D destination, bool active)
|
||||
: base(0x233F)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Active = active;
|
||||
this.m_Word = word;
|
||||
this.m_Destination = destination;
|
||||
}
|
||||
|
||||
public SerpentPillar(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Active
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Active;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Active = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Word
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Word;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Word = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Rectangle2D Destination
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Destination;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Destination = value;
|
||||
}
|
||||
}
|
||||
public override bool HandlesOnSpeech
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (!e.Handled && from.InRange(this, 10) && e.Speech.ToLower() == this.Word)
|
||||
{
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(from, from.Map);
|
||||
|
||||
if (boat == null)
|
||||
return;
|
||||
|
||||
if (!this.Active)
|
||||
{
|
||||
if (boat.TillerMan != null)
|
||||
boat.TillerManSay(502507); // Ar, Legend has it that these pillars are inactive! No man knows how it might be undone!
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Map map = from.Map;
|
||||
|
||||
for (int i = 0; i < 5; i++) // Try 5 times
|
||||
{
|
||||
int x = Utility.Random(this.Destination.X, this.Destination.Width);
|
||||
int y = Utility.Random(this.Destination.Y, this.Destination.Height);
|
||||
int z = map.GetAverageZ(x, y);
|
||||
|
||||
Point3D dest = new Point3D(x, y, z);
|
||||
|
||||
if (boat.CanFit(dest, map, boat.ItemID))
|
||||
{
|
||||
int xOffset = x - boat.X;
|
||||
int yOffset = y - boat.Y;
|
||||
int zOffset = z - boat.Z;
|
||||
|
||||
boat.Teleport(xOffset, yOffset, zOffset);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (boat.TillerMan != null)
|
||||
boat.TillerManSay(502508); // Ar, I refuse to take that matey through here!
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write((bool)this.m_Active);
|
||||
writer.Write((string)this.m_Word);
|
||||
writer.Write((Rectangle2D)this.m_Destination);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
this.m_Active = reader.ReadBool();
|
||||
this.m_Word = reader.ReadString();
|
||||
this.m_Destination = reader.ReadRect2D();
|
||||
}
|
||||
}
|
||||
}
|
||||
183
Scripts/Items/Functional/SerpentsJawbone.cs
Normal file
183
Scripts/Items/Functional/SerpentsJawbone.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Gumps;
|
||||
using System.Collections.Generic;
|
||||
using Server.Network;
|
||||
using Server.ContextMenus;
|
||||
using Server.Multis;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SerpentsJawbone : Item, ISecurable
|
||||
{
|
||||
public static Dictionary<int, Point3D> Locations { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Locations = new Dictionary<int, Point3D>();
|
||||
|
||||
Locations[1157135] = new Point3D(1156, 1143, -24); // The Village of Lakeshire
|
||||
Locations[1157619] = new Point3D(644, 854, -56); // The Rat Fort
|
||||
Locations[1157620] = new Point3D(1363, 1075, -13); // Reg Volom
|
||||
Locations[1016410] = new Point3D(1572, 1046, -8); // Twin Oaks Tavern
|
||||
Locations[1157621] = new Point3D(984, 622, -80); // The Oasis
|
||||
Locations[1078308] = new Point3D(1746, 1221, -1); // Blood Dungeon
|
||||
Locations[1111764] = new Point3D(912, 1362, -21); // Cyclops Dungeon
|
||||
Locations[1111765] = new Point3D(824, 774, -80); // Exodus Dungeon
|
||||
Locations[1111766] = new Point3D(349, 1434, 16); // The Kirin Passage
|
||||
Locations[1157622] = new Point3D(971, 303, 54); // Pass of Karnaugh
|
||||
Locations[1157623] = new Point3D(1033, 1154, -24); // The Rat Cave
|
||||
Locations[1078315] = new Point3D(541, 466, -72); // Terort Skitas
|
||||
Locations[1111825] = new Point3D(1450, 1477, -29); // Twisted Weald
|
||||
Locations[1113002] = new Point3D(642, 1307, -55); // Wisp Dungeon
|
||||
Locations[1157624] = new Point3D(753, 497, -62); // Gwenno's Memorial
|
||||
Locations[1157625] = new Point3D(1504, 628, -14); // Desert Gypsy Camp
|
||||
Locations[1113000] = new Point3D(1785, 573, 71); // Rock Dungeon
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level { get; set; }
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public override int LabelNumber { get { return 1157654; } } // Serpent's Jawbone
|
||||
|
||||
[Constructable]
|
||||
public SerpentsJawbone()
|
||||
: base(0x9F74)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if ((IsLockedDown || IsSecure) && from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.SendGump(new InternalGump(from as PlayerMobile, this));
|
||||
}
|
||||
else if (!from.InRange(GetWorldLocation(), 2))
|
||||
{
|
||||
from.SendLocalizedMessage(500295); // You are too far away to do that.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(502692); // This must be in a house and be locked down to work.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalGump : Gump
|
||||
{
|
||||
public Item Jawbone { get; set; }
|
||||
public PlayerMobile User { get; set; }
|
||||
|
||||
public InternalGump(PlayerMobile pm, Item jawbone)
|
||||
: base(100, 100)
|
||||
{
|
||||
Jawbone = jawbone;
|
||||
User = pm;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 370, 428, 0x1400);
|
||||
|
||||
AddHtmlLocalized(10, 10, 350, 18, 1114513, "#1156704", 0x56BA, false, false); // <DIV ALIGN=CENTER>~1_TOKEN~</DIV>
|
||||
|
||||
ColUtility.For(Locations, (i, key, value) =>
|
||||
{
|
||||
AddButton(10, 41 + (i * 20), 1209, 1210, key, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(50, 41 + (i * 20), 150, 20, key, 0x7FFF, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID > 0)
|
||||
{
|
||||
int id = info.ButtonID;
|
||||
|
||||
if (Locations.ContainsKey(id))
|
||||
{
|
||||
Point3D p = Locations[id];
|
||||
|
||||
if (CheckTravel(p))
|
||||
{
|
||||
BaseCreature.TeleportPets(User, p, Map.Ilshenar);
|
||||
User.Combatant = null;
|
||||
User.Warmode = false;
|
||||
User.Hidden = true;
|
||||
|
||||
User.MoveToWorld(p, Map.Ilshenar);
|
||||
|
||||
Effects.PlaySound(p, Map.Ilshenar, 0x1FE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckTravel(Point3D p)
|
||||
{
|
||||
if (!User.InRange(Jawbone.GetWorldLocation(), 2) || User.Map != Jawbone.Map)
|
||||
{
|
||||
User.SendLocalizedMessage(500295); // You are too far away to do that.
|
||||
}
|
||||
else if (SpellHelper.RestrictRedTravel && User.Murderer)
|
||||
{
|
||||
User.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
}
|
||||
else if (Factions.Sigil.ExistsOn(User))
|
||||
{
|
||||
User.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
}
|
||||
else if (User.Criminal)
|
||||
{
|
||||
User.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
|
||||
}
|
||||
else if (SpellHelper.CheckCombat(User))
|
||||
{
|
||||
User.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
|
||||
}
|
||||
else if (User.Spell != null)
|
||||
{
|
||||
User.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
|
||||
}
|
||||
else if (User.Map == Map.Ilshenar && User.InRange(p, 1))
|
||||
{
|
||||
User.SendLocalizedMessage(1019003); // You are already there.
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public SerpentsJawbone(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)Level);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
306
Scripts/Items/Functional/SliderTrapTrainingKit.cs
Normal file
306
Scripts/Items/Functional/SliderTrapTrainingKit.cs
Normal file
@@ -0,0 +1,306 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.SkillHandlers;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public interface ISliderKit : IEntity
|
||||
{
|
||||
int[] Order { get; }
|
||||
int Style { get; }
|
||||
|
||||
void Complete(Mobile m);
|
||||
}
|
||||
|
||||
public class SliderTrapTrainingKit : Item, ISliderKit, IRemoveTrapTrainingKit
|
||||
{
|
||||
public override int LabelNumber { get { return 1159016; } } // Slider Trap Training Kit
|
||||
|
||||
private int _Style;
|
||||
|
||||
public int[] Order { get; set; } = new int[9];
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Test
|
||||
{
|
||||
get { return false; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
TestOrder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Style
|
||||
{
|
||||
get { return _Style; }
|
||||
set
|
||||
{
|
||||
if (_Style != value)
|
||||
{
|
||||
_Style = value;
|
||||
|
||||
if (_Style < 0)
|
||||
_Style = 0;
|
||||
|
||||
if (_Style > 7)
|
||||
_Style = 7;
|
||||
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SliderTrapTrainingKit()
|
||||
: base(41875)
|
||||
{
|
||||
_Style = -1;
|
||||
Style = Utility.Random(8);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
Order[i] = 0;
|
||||
}
|
||||
|
||||
var randomIndex = Utility.Random(Order.Length);
|
||||
var startID = 0x9CEE + (_Style * 9); // start at 1+ because the upper left picture is alwasy omitted
|
||||
var list = new List<int>();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
list.Add(startID + i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
if (i != randomIndex)
|
||||
{
|
||||
var add = list[Utility.Random(list.Count)];
|
||||
Order[i] = add;
|
||||
list.Remove(add);
|
||||
}
|
||||
}
|
||||
|
||||
int invCount = 0;
|
||||
for (int i = 0; i < Order.Length - 1; i++)
|
||||
{
|
||||
for (int j = i + 1; j < Order.Length; j++)
|
||||
{
|
||||
if (Order[j] != 0 && Order[i] != 0 && Order[i] > Order[j])
|
||||
invCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (invCount % 2 == 1)
|
||||
{
|
||||
if (randomIndex > 2)
|
||||
{
|
||||
var temp = Order[0];
|
||||
Order[0] = Order[1];
|
||||
Order[1] = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
var temp = Order[Order.Length-1];
|
||||
Order[Order.Length-1] = Order[Order.Length-2];
|
||||
Order[Order.Length-2] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (IsChildOf(m.Backpack))
|
||||
{
|
||||
m.SendLocalizedMessage(1159008); // That appears to be trapped, using the remove trap skill would yield better results...
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendMessage("That is not your chest!"); // TODO: Could not find cliloc, but this is the message given
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRemoveTrap(Mobile from)
|
||||
{
|
||||
if (from is PlayerMobile)
|
||||
{
|
||||
BaseGump.SendGump(new SliderTrapGump((PlayerMobile)from, this));
|
||||
}
|
||||
}
|
||||
|
||||
public void Complete(Mobile from)
|
||||
{
|
||||
from.SendLocalizedMessage(1159009); // You successfully disarm the trap!
|
||||
|
||||
from.CheckTargetSkill(SkillName.RemoveTrap, this, 0, 100);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
private void TestOrder()
|
||||
{
|
||||
var startID = 0x9CEE + (_Style * 9); // start at 1+ because the upper left picture is alwasy omitted
|
||||
var list = new List<int>();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
list.Add(startID + i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
if (i != 1)
|
||||
{
|
||||
Order[i] = list[0];
|
||||
list.RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Order[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SliderTrapTrainingKit(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(_Style);
|
||||
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
writer.Write(Order[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
_Style = reader.ReadInt();
|
||||
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
Order[i] = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SliderTrapGump : BaseGump
|
||||
{
|
||||
public ISliderKit Kit { get; set; }
|
||||
public int[] Order { get { return Kit.Order; } }
|
||||
|
||||
public SliderTrapGump(PlayerMobile pm, ISliderKit kit)
|
||||
: base(pm, 100, 100)
|
||||
{
|
||||
pm.CloseGump(GetType());
|
||||
Kit = kit;
|
||||
}
|
||||
|
||||
public override void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 270, 445, 0x6DB);
|
||||
AddImage(15, 20, 0x9CED + (Kit.Style * 9));
|
||||
AddAlphaRegion(15, 20, 80, 133);
|
||||
|
||||
for (int i = 0; i < Order.Length; i++)
|
||||
{
|
||||
var order = Order[i];
|
||||
|
||||
if (order == 0)
|
||||
continue;
|
||||
|
||||
var x = i % 3 == 0 ? 15 : i % 3 == 1 ? 95 : 175;
|
||||
var y = i <= 2 ? 20 : i <= 5 ? 153 : 286;
|
||||
|
||||
AddButton(x, y, order, order, i + 1, GumpButtonType.Reply, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(RelayInfo info)
|
||||
{
|
||||
if (!Kit.Deleted && info.ButtonID >= 1 && info.ButtonID <= 9)
|
||||
{
|
||||
var pick = info.ButtonID - 1;
|
||||
var empty = Array.IndexOf(Order, 0);
|
||||
|
||||
if (ValidMove(pick, empty))
|
||||
{
|
||||
User.SendSound(0x42);
|
||||
|
||||
var id = Order[pick];
|
||||
Order[pick] = 0;
|
||||
Order[empty] = id;
|
||||
|
||||
if (CheckSolution(User))
|
||||
{
|
||||
Kit.Complete(User);
|
||||
}
|
||||
else
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
User.SendSound(0x051);
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidMove(int pick, int empty)
|
||||
{
|
||||
switch (pick)
|
||||
{
|
||||
case 0: return empty == 1 || empty == 3;
|
||||
case 1: return empty == 0 || empty == 2 || empty == 4;
|
||||
case 2: return empty == 1 || empty == 5;
|
||||
case 3: return empty == 0 || empty == 4 || empty == 6;
|
||||
case 4: return empty == 1 || empty == 3 || empty == 5 || empty == 7;
|
||||
case 5: return empty == 2 || empty == 4 || empty == 8;
|
||||
case 6: return empty == 3 || empty == 7;
|
||||
case 7: return empty == 4 || empty == 6 || empty == 8;
|
||||
case 8: return empty == 5 || empty == 7;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckSolution(Mobile m)
|
||||
{
|
||||
var start = 0x9CEE + (Kit.Style * 9);
|
||||
|
||||
return Order[0] == 0 &&
|
||||
Order[1] == start &&
|
||||
Order[2] == start + 1 &&
|
||||
Order[3] == start + 2 &&
|
||||
Order[4] == start + 3 &&
|
||||
Order[5] == start + 4 &&
|
||||
Order[6] == start + 5 &&
|
||||
Order[7] == start + 6 &&
|
||||
Order[8] == start + 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Scripts/Items/Functional/SlidingDoors.cs
Normal file
88
Scripts/Items/Functional/SlidingDoors.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PaperSlidingDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public PaperSlidingDoor(DoorFacing facing)
|
||||
: base(0x2A05 + (2 * (int)facing), 0x2A06 + (2 * (int)facing), 0x539, 0x539, new Point3D(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
public PaperSlidingDoor(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 class ClothSlidingDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public ClothSlidingDoor(DoorFacing facing)
|
||||
: base(0x2A0D + (2 * (int)facing), 0x2A0E + (2 * (int)facing), 0x539, 0x539, new Point3D(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
public ClothSlidingDoor(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 class WoodenSlidingDoor : BaseDoor
|
||||
{
|
||||
[Constructable]
|
||||
public WoodenSlidingDoor(DoorFacing facing)
|
||||
: base(0x2A15 + (2 * (int)facing), 0x2A16 + (2 * (int)facing), 0x539, 0x539, new Point3D(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
public WoodenSlidingDoor(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
128
Scripts/Items/Functional/SpiderWebbing.cs
Normal file
128
Scripts/Items/Functional/SpiderWebbing.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpiderWebbing : Item
|
||||
{
|
||||
private Timer m_Timer;
|
||||
private static List<Mobile> m_WebVictims = new List<Mobile>();
|
||||
|
||||
public SpiderWebbing(Mobile m)
|
||||
: base(0xEE3 + Utility.Random(4))
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
BeginWebbing(m);
|
||||
|
||||
m_Timer = new InternalTimer(this, m);
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
public SpiderWebbing(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public void BeginWebbing(Mobile m)
|
||||
{
|
||||
m.RevealingAction();
|
||||
m.Frozen = true;
|
||||
m.SendLocalizedMessage(1113247); // You are wrapped in spider webbing and cannot move!
|
||||
m_WebVictims.Add(m);
|
||||
BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Webbing, 1153789, 1153825));
|
||||
}
|
||||
|
||||
public static bool IsTrapped(Mobile m)
|
||||
{
|
||||
return m_WebVictims != null && m_WebVictims.Contains(m);
|
||||
}
|
||||
|
||||
public static void RemoveEffects(Mobile m)
|
||||
{
|
||||
m.Frozen = false;
|
||||
m.SendLocalizedMessage(1113248); // You escape the spider's web!
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Webbing);
|
||||
m_WebVictims.Remove(m);
|
||||
}
|
||||
|
||||
public override bool BlocksFit { get { return true; } }
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
if (m_Timer != null)
|
||||
{
|
||||
m_Timer.Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
var list = new List<Mobile>(m_WebVictims);
|
||||
|
||||
foreach (var m in list)
|
||||
{
|
||||
RemoveEffects(m);
|
||||
}
|
||||
|
||||
ColUtility.Free(list);
|
||||
ColUtility.Free(m_WebVictims);
|
||||
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
public override bool OnMoveOver(Mobile m)
|
||||
{
|
||||
if (m is BaseCreature && ((BaseCreature)m).IsMonster)
|
||||
return true;
|
||||
|
||||
if (m.AccessLevel == AccessLevel.Player && m.Alive)
|
||||
{
|
||||
BeginWebbing(m);
|
||||
m.PlaySound(0x204);
|
||||
m.FixedEffect(0x376A, 10, 16);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_Target;
|
||||
private Item m_Item;
|
||||
private int m_Ticks;
|
||||
|
||||
public InternalTimer(Item item, Mobile target)
|
||||
: base(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0))
|
||||
{
|
||||
m_Item = item;
|
||||
m_Target = target;
|
||||
m_Ticks = 10;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Ticks--;
|
||||
|
||||
if (!m_Target.Alive || m_Ticks == 0)
|
||||
{
|
||||
m_Item.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
198
Scripts/Items/Functional/SpikeTrap.cs
Normal file
198
Scripts/Items/Functional/SpikeTrap.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum SpikeTrapType
|
||||
{
|
||||
WestWall,
|
||||
NorthWall,
|
||||
WestFloor,
|
||||
NorthFloor
|
||||
}
|
||||
|
||||
public class SpikeTrap : BaseTrap
|
||||
{
|
||||
[Constructable]
|
||||
public SpikeTrap()
|
||||
: this(SpikeTrapType.WestFloor)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SpikeTrap(SpikeTrapType type)
|
||||
: base(GetBaseID(type))
|
||||
{
|
||||
}
|
||||
|
||||
public SpikeTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SpikeTrapType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
switch ( this.ItemID )
|
||||
{
|
||||
case 4360:
|
||||
case 4361:
|
||||
case 4366:
|
||||
return SpikeTrapType.WestWall;
|
||||
case 4379:
|
||||
case 4380:
|
||||
case 4385:
|
||||
return SpikeTrapType.NorthWall;
|
||||
case 4506:
|
||||
case 4507:
|
||||
case 4511:
|
||||
return SpikeTrapType.WestFloor;
|
||||
case 4512:
|
||||
case 4513:
|
||||
case 4517:
|
||||
return SpikeTrapType.NorthFloor;
|
||||
}
|
||||
|
||||
return SpikeTrapType.WestWall;
|
||||
}
|
||||
set
|
||||
{
|
||||
bool extended = this.Extended;
|
||||
|
||||
this.ItemID = (extended ? GetExtendedID(value) : GetBaseID(value));
|
||||
}
|
||||
}
|
||||
public bool Extended
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ItemID == GetExtendedID(this.Type));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
this.ItemID = GetExtendedID(this.Type);
|
||||
else
|
||||
this.ItemID = GetBaseID(this.Type);
|
||||
}
|
||||
}
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds(6.0);
|
||||
}
|
||||
}
|
||||
public static int GetBaseID(SpikeTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case SpikeTrapType.WestWall:
|
||||
return 4360;
|
||||
case SpikeTrapType.NorthWall:
|
||||
return 4379;
|
||||
case SpikeTrapType.WestFloor:
|
||||
return 4506;
|
||||
case SpikeTrapType.NorthFloor:
|
||||
return 4512;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetExtendedID(SpikeTrapType type)
|
||||
{
|
||||
return GetBaseID(type) + GetExtendedOffset(type);
|
||||
}
|
||||
|
||||
public static int GetExtendedOffset(SpikeTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case SpikeTrapType.WestWall:
|
||||
return 6;
|
||||
case SpikeTrapType.NorthWall:
|
||||
return 6;
|
||||
|
||||
case SpikeTrapType.WestFloor:
|
||||
return 5;
|
||||
case SpikeTrapType.NorthFloor:
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (!from.Alive || from.IsStaff())
|
||||
return;
|
||||
|
||||
Effects.SendLocationEffect(this.Location, this.Map, GetBaseID(this.Type) + 1, 18, 3, this.GetEffectHue(), 0);
|
||||
Effects.PlaySound(this.Location, this.Map, 0x22C);
|
||||
IPooledEnumerable eable = GetMobilesInRange(0);
|
||||
|
||||
foreach (Mobile mob in eable)
|
||||
{
|
||||
if (mob.Alive && !mob.IsDeadBondedPet)
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), mob, mob, Utility.RandomMinMax(1, 6) * 6);
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), new TimerCallback(OnSpikeExtended));
|
||||
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x22, 500852); // You stepped onto a spike trap!
|
||||
}
|
||||
|
||||
public virtual void OnSpikeExtended()
|
||||
{
|
||||
this.Extended = true;
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5.0), new TimerCallback(OnSpikeRetracted));
|
||||
}
|
||||
|
||||
public virtual void OnSpikeRetracted()
|
||||
{
|
||||
this.Extended = false;
|
||||
Effects.SendLocationEffect(this.Location, this.Map, GetExtendedID(this.Type) - 1, 6, 3, this.GetEffectHue(), 0);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
this.Extended = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
607
Scripts/Items/Functional/StealableArtifactsSpawner.cs
Normal file
607
Scripts/Items/Functional/StealableArtifactsSpawner.cs
Normal file
@@ -0,0 +1,607 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class StealableArtifactsSpawner : Item
|
||||
{
|
||||
private static readonly StealableEntry[] m_Entries = new StealableEntry[]
|
||||
{
|
||||
// Doom - Artifact rarity 1
|
||||
new StealableEntry(Map.Malas, new Point3D(317, 56, -1), 72, 108, typeof(RockArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(360, 31, 8), 72, 108, typeof(SkullCandleArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(369, 372, -1), 72, 108, typeof(BottleArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(378, 372, 0), 72, 108, typeof(DamagedBooksArtifact)),
|
||||
// Doom - Artifact rarity 2
|
||||
new StealableEntry(Map.Malas, new Point3D(432, 16, -1), 144, 216, typeof(StretchedHideArtifact)),
|
||||
new StealableEntry(Map.Malas, Core.TOL ? new Point3D(462, 17, -1) : new Point3D(489, 9, 0), 144, 216, typeof(BrazierArtifact)),
|
||||
// Doom - Artifact rarity 3
|
||||
new StealableEntry(Map.Malas, new Point3D(471, 96, -1), 288, 432, typeof(LampPostArtifact), GetLampPostHue()),
|
||||
new StealableEntry(Map.Malas, new Point3D(421, 198, 2), 288, 432, typeof(BooksNorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(431, 189, -1), 288, 432, typeof(BooksWestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(435, 196, -1), 288, 432, typeof(BooksFaceDownArtifact)),
|
||||
// Doom - Artifact rarity 5
|
||||
new StealableEntry(Map.Malas, new Point3D(447, 9, 8), 1152, 1728, typeof(StuddedLeggingsArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(423, 28, 0), 1152, 1728, typeof(EggCaseArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(347, 44, 4), 1152, 1728, typeof(SkinnedGoatArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(497, 57, -1), 1152, 1728, typeof(GruesomeStandardArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(381, 375, 11), 1152, 1728, typeof(BloodyWaterArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(489, 369, 2), 1152, 1728, typeof(TarotCardsArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(497, 369, 5), 1152, 1728, typeof(BackpackArtifact)),
|
||||
// Doom - Artifact rarity 6
|
||||
new StealableEntry(Map.Malas, new Point3D(499,372, -1), 2304, 3456, typeof(BambooStoolArtifact)),
|
||||
// Doom - Artifact rarity 7
|
||||
new StealableEntry(Map.Malas, Core.TOL ? new Point3D(485, 8, 6) : new Point3D(475, 23, 4), 4608, 6912, typeof(StuddedTunicArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(423, 28, 0), 4608, 6912, typeof(CocoonArtifact)),
|
||||
// Doom - Artifact rarity 8
|
||||
new StealableEntry(Map.Malas, new Point3D(354, 36, -1), 9216, 13824, typeof(SkinnedDeerArtifact)),
|
||||
#region New Doom Artifacts
|
||||
new StealableEntry(Map.Malas, new Point3D(274, 231, 0), 9216, 13824, typeof(HangingPlatemailTunic)),
|
||||
new StealableEntry(Map.Malas, new Point3D(445, 119, -1), 9216, 13824, typeof(HangingPlatemailLeggings)),
|
||||
new StealableEntry(Map.Malas, new Point3D(421, 197, -1), 9216, 13824, typeof(HangingPlatemailArms)),
|
||||
#endregion
|
||||
// Doom - Artifact rarity 9
|
||||
new StealableEntry(Map.Malas, new Point3D(433, 11, -1), 18432, 27648, typeof(SaddleArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(403, 31, 4), 18432, 27648, typeof(LeatherTunicArtifact)),
|
||||
#region New Doom Artifacts
|
||||
new StealableEntry(Map.Malas, new Point3D(378, 371, -1), 18432, 27648, typeof(ArtifactBookshelf)),
|
||||
new StealableEntry(Map.Malas, new Point3D(487, 364, -1), 18432, 27648, typeof(ArcaneTable)),
|
||||
#endregion
|
||||
// Doom - Artifact rarity 10
|
||||
new StealableEntry(Map.Malas, Core.TOL ? new Point3D(396, 8, 4) : new Point3D(257, 70, -2), 36864, 55296, typeof(ZyronicClaw)),
|
||||
new StealableEntry(Map.Malas, Core.TOL ? new Point3D(261, 97, -1) : new Point3D(354, 176, 7), 36864, 55296, typeof(TitansHammer)),
|
||||
new StealableEntry(Map.Malas, new Point3D(369, 389, -1), 36864, 55296, typeof(BladeOfTheRighteous)),
|
||||
new StealableEntry(Map.Malas, new Point3D(467, 92, 4), 36864, 55296, typeof(InquisitorsResolution)),
|
||||
// Doom - Artifact rarity 12
|
||||
new StealableEntry(Map.Malas, new Point3D(487, 364, -1), 147456, 221184, typeof(RuinedPaintingArtifact)),
|
||||
#region New Doom Artifacts
|
||||
new StealableEntry(Map.Malas, Core.TOL ? new Point3D(263, 28, 0) : new Point3D(365, 7, -1), 147456, 221184, typeof(IncenseBurner)),
|
||||
#endregion
|
||||
|
||||
// Yomotsu Mines - Artifact rarity 1
|
||||
new StealableEntry(Map.Malas, new Point3D(18, 110, -1), 72, 108, typeof(Basket1Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(66, 114, -1), 72, 108, typeof(Basket2Artifact)),
|
||||
// Yomotsu Mines - Artifact rarity 2
|
||||
new StealableEntry(Map.Malas, new Point3D(63, 12, 11), 144, 216, typeof(Basket4Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(5, 29, -1), 144, 216, typeof(Basket5NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(30, 81, 3), 144, 216, typeof(Basket5WestArtifact)),
|
||||
// Yomotsu Mines - Artifact rarity 3
|
||||
new StealableEntry(Map.Malas, new Point3D(115, 7, -1), 288, 432, typeof(Urn1Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(85, 13, -1), 288, 432, typeof(Urn2Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(110, 53, -1), 288, 432, typeof(Sculpture1Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(108, 37, -1), 288, 432, typeof(Sculpture2Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(121, 14, -1), 288, 432, typeof(TeapotNorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(121, 115, -1), 288, 432, typeof(TeapotWestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(84, 40, -1), 288, 432, typeof(TowerLanternArtifact)),
|
||||
// Yomotsu Mines - Artifact rarity 9
|
||||
new StealableEntry(Map.Malas, new Point3D(94, 7, -1), 18432, 27648, typeof(ManStatuetteSouthArtifact)),
|
||||
|
||||
// Fan Dancer's Dojo - Artifact rarity 1
|
||||
new StealableEntry(Map.Malas, new Point3D(113, 640, -2), 72, 108, typeof(Basket3NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(102, 355, -1), 72, 108, typeof(Basket3WestArtifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 2
|
||||
new StealableEntry(Map.Malas, new Point3D(99, 370, -1), 144, 216, typeof(Basket6Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(100, 357, -1), 144, 216, typeof(ZenRock1Artifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 3
|
||||
new StealableEntry(Map.Malas, new Point3D(73, 473, -1), 288, 432, typeof(FanNorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(99, 372, -1), 288, 432, typeof(FanWestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(92, 326, -1), 288, 432, typeof(BowlsVerticalArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(97, 470, -1), 288, 432, typeof(ZenRock2Artifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(103, 691, -1), 288, 432, typeof(ZenRock3Artifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 4
|
||||
new StealableEntry(Map.Malas, new Point3D(103, 336, 4), 576, 864, typeof(Painting1NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(59, 381, 4), 576, 864, typeof(Painting1WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(84, 401, 2), 576, 864, typeof(Painting2NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(59, 392, 2), 576, 864, typeof(Painting2WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(107, 483, -1), 576, 864, typeof(TripleFanNorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(50, 475, -1), 576, 864, typeof(TripleFanWestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(107, 460, -1), 576, 864, typeof(BowlArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(90, 502, -1), 576, 864, typeof(CupsArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(107, 688, -1), 576, 864, typeof(BowlsHorizontalArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(112, 676, -1), 576, 864, typeof(SakeArtifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 5
|
||||
new StealableEntry(Map.Malas, new Point3D(135, 614, -1), 1152, 1728, typeof(SwordDisplay1NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(50, 482, -1), 1152, 1728, typeof(SwordDisplay1WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(119, 672, -1), 1152, 1728, typeof(Painting3Artifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 6
|
||||
new StealableEntry(Map.Malas, new Point3D(90, 326, -1), 2304, 3456, typeof(Painting4NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(99, 354, -1), 2304, 3456, typeof(Painting4WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(179, 652, -1), 2304, 3456, typeof(SwordDisplay2NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(118, 627, -1), 2304, 3456, typeof(SwordDisplay2WestArtifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 7
|
||||
new StealableEntry(Map.Malas, new Point3D(90, 483, -1), 4608, 6912, typeof(FlowersArtifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 8
|
||||
new StealableEntry(Map.Malas, new Point3D(71, 562, -1), 9216, 13824, typeof(DolphinLeftArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(102, 677, -1), 9216, 13824, typeof(DolphinRightArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(61, 499, 0), 9216, 13824, typeof(SwordDisplay3SouthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(182, 669, -1), 9216, 13824, typeof(SwordDisplay3EastArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(162, 647, -1), 9216, 13824, typeof(SwordDisplay4WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(124, 624, 0), 9216, 13824, typeof(Painting5NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(146, 649, 2), 9216, 13824, typeof(Painting5WestArtifact)),
|
||||
// Fan Dancer's Dojo - Artifact rarity 9
|
||||
new StealableEntry(Map.Malas, new Point3D(100, 488, -1), 18432, 27648, typeof(SwordDisplay4NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(175, 606, 0), 18432, 27648, typeof(SwordDisplay5NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(157, 608, -1), 18432, 27648, typeof(SwordDisplay5WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(187, 643, 1), 18432, 27648, typeof(Painting6NorthArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(146, 623, 1), 18432, 27648, typeof(Painting6WestArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(178, 629, -1), 18432, 27648, typeof(ManStatuetteEastArtifact)),
|
||||
|
||||
// Abyss - Artifact rarity 5
|
||||
new StealableEntry(Map.TerMur, new Point3D(717, 416, 50), 1152, 1728, typeof(DyingPlantArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(951, 542, -14), 1152, 1728, typeof(LargePewterBowlArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(877, 527, -13), 1152, 1728, typeof(CrownOfArcaneTemperament)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(345, 621, 26), 1152, 1728, typeof(LightInTheVoid)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(585, 853, -45), 1152, 1728, typeof(StaffOfResonance)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(843, 665, 27), 1152, 1728, typeof(ValkyriesGlaive)),
|
||||
// Abyss - Artifact rarity 6
|
||||
new StealableEntry(Map.TerMur, new Point3D(785, 442, -15), 2304, 3456, typeof(LargeDyingPlantArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(849, 281, -6), 2304, 3456, typeof(GargishLuckTotemArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(916, 374, -6), 2304, 3456, typeof(BookOfTruthArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(669, 819, -108), 2304, 3456, typeof(GargishTraditionalVaseArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(715, 782, 27), 2304, 3456, typeof(GargishProtectiveTotemArtifact)),
|
||||
// Abyss - Artifact rarity 7
|
||||
new StealableEntry(Map.TerMur, new Point3D(368, 605, 26), 4608, 6912, typeof(GargishBentasVaseArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(670, 441, 50), 4608, 6912, typeof(GargishPortraitArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(555, 670, 55), 4608, 6912, typeof(GargishKnowledgeTotemArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(948, 393, 88), 4608, 6912, typeof(GargishMemorialStatueArtifact)),
|
||||
// Abyss - Artifact rarity 8
|
||||
new StealableEntry(Map.TerMur, new Point3D(926, 598, -5), 9216, 13824, typeof(PushmePullyuArtifact)),
|
||||
// UnderWorld - Artifact rarity 3
|
||||
new StealableEntry(Map.TerMur, new Point3D(1046, 1106, -63), 288, 432, typeof(MysteriousSupperArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1239, 1019, -37), 288, 432, typeof(JugsOfGoblinRotgutArtifact)),
|
||||
// UnderWorld - Artifact rarity 4
|
||||
new StealableEntry(Map.TerMur, new Point3D(1015, 1013, -35), 576, 864, typeof(StolenBottlesOfLiquor1Artifact)), // [2a]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1015, 1029, -35), 576, 864, typeof(StolenBottlesOfLiquor2Artifact)), // [2b]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1210, 1035, -22), 576, 864, typeof(BottlesOfSpoiledWine1Artifact)), // [2]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1077, 975, -23), 576, 864, typeof(NaverysWeb1Artifact)), // [1]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1094, 990, -23), 576, 864, typeof(NaverysWeb2Artifact)), // [2]
|
||||
// UnderWorld - Artifact rarity 5
|
||||
new StealableEntry(Map.TerMur, new Point3D(1049, 1109, -65), 1152, 1728, typeof(BloodySpoonArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1047, 1108, -65), 1152, 1728, typeof(MysticsGuard)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1137, 1134, -38), 1152, 1728, typeof(RemnantsOfMeatLoafArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1134, 1204, 7), 1152, 1728, typeof(HalfEatenSupperArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1083, 983, -19), 1152, 1728, typeof(NaverysWeb3Artifact)), // [3]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1081, 992, -21), 1152, 1728, typeof(NaverysWeb4Artifact)), // [4]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1146, 1011, -52), 1152, 1728, typeof(NaverysWeb5Artifact)), // [2]
|
||||
new StealableEntry(Map.TerMur, new Point3D(1119, 974, -41), 1152, 1728, typeof(NaverysWeb6Artifact)), // [1]
|
||||
// UnderWorld - Artifact rarity 6
|
||||
new StealableEntry(Map.TerMur, new Point3D(1015, 1018, -35), 2304, 3456, typeof(BatteredPanArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1007, 975, -22), 2304, 3456, typeof(RustedPanArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1188, 1015, -35), 2304, 3456, typeof(BottlesOfSpoiledWine2Artifact)),
|
||||
// UnderWorld - Artifact rarity 7
|
||||
new StealableEntry(Map.TerMur, new Point3D(1015, 1026, -35), 4608, 6912, typeof(StolenBottlesOfLiquor3Artifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1226, 963, -22), 4608, 6912, typeof(BottlesOfSpoiledWine3Artifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1089, 1126, -36), 4608, 6912, typeof(DriedUpInkWellArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1227, 964, -29), 4608, 6912, typeof(FakeCopperIngotsArtifact)),
|
||||
// UnderWorld - Artifact rarity 8
|
||||
new StealableEntry(Map.TerMur, new Point3D(1031, 998, -38), 9216, 13824, typeof(StolenBottlesOfLiquor4Artifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1017, 1150, -64), 9216, 13824, typeof(RottedOarsArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1226, 966, -29), 9216, 13824, typeof(PricelessTreasureArtifact)),
|
||||
// UnderWorld - Artifact rarity 9
|
||||
new StealableEntry(Map.TerMur, new Point3D(1066, 1193, -36), 18432, 27648, typeof(TyballsFlaskStandArtifact)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(1131, 1128, -42), 18432, 27648, typeof(BlockAndTackleArtifact)),
|
||||
|
||||
//Ararat Stealables (Exploring the Deep) - Artifact rarity 8
|
||||
new StealableEntry(Map.Trammel, new Point3D(6303, 1664, 11), 9216, 13824, typeof(SternAnchorOfBmvArarat)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(6303, 1756, 20), 9216, 13824, typeof(ShipsBellOfBmvArarat)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(6313, 1753, -14), 9216, 13824, typeof(FigureheadOfBmvArarat)),
|
||||
|
||||
// Castle Blackthorne Stealables - Rarity 8 - does not show rarity on items
|
||||
new StealableEntry(Map.Trammel, new Point3D(6436, 2606, 11), 9216, 13824, typeof(KingsGildedStatue)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(6298, 2673, 0), 9216, 13824, typeof(KingsPainting1)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(6455, 2700, 0), 9216, 13824, typeof(KingsPainting2)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(6436, 2606, 11), 9216, 13824, typeof(KingsGildedStatue)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(6298, 2673, 0), 9216, 13824, typeof(KingsPainting1)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(6455, 2700, 0), 9216, 13824, typeof(KingsPainting2)),
|
||||
|
||||
//TOL - Artifact rarity 11 - does not show rarity on item
|
||||
new StealableEntry(Map.TerMur, new Point3D(538, 1496, 40), 36864, 55296, typeof(StretchedDinosaurHide)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(174, 1808, 80), 36864, 55296, typeof(CarvedMyrmydexGlyph)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(630, 1689, 100), 36864, 55296, typeof(WakuOnASpit)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(688, 2125, 45), 36864, 55296, typeof(SacredLavaRock)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(393, 1838, 0), 36864, 55296, typeof(WhiteTigerFigurine)),
|
||||
new StealableEntry(Map.TerMur, new Point3D(421, 1571, 40), 36864, 55296, typeof(DragonTurtleHatchlingNet)),
|
||||
|
||||
// Wrong - Artifact rarity 8
|
||||
new StealableEntry(Map.Trammel, new Point3D(5790, 579, 10), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(5790, 579, 10), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(5865, 559, 15), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(5865, 559, 15), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(5832, 576, 10), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(5832, 576, 10), 18432, 27648, typeof(BlanketOfDarkness)),
|
||||
|
||||
// Wrong - Arfifact rarity 10
|
||||
new StealableEntry(Map.Trammel, new Point3D(5703, 521, 0), 36864, 55296, typeof(TortureRackSouth)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(5703, 521, 0), 36864, 55296, typeof(TortureRackSouth)),
|
||||
new StealableEntry(Map.Trammel, new Point3D(5680, 537, 0), 46864, 55296, typeof(TortureRackEast)),
|
||||
new StealableEntry(Map.Felucca, new Point3D(5680, 537, 0), 46864, 55296, typeof(TortureRackEast)),
|
||||
|
||||
// Bedlam - Artifact Rarity 8
|
||||
new StealableEntry(Map.Malas, new Point3D(168, 1609, 0), 9216, 13824, typeof(AcademicBooksArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(165, 1650, 0), 9216, 13824, typeof(AcademicBooksArtifact)),
|
||||
new StealableEntry(Map.Malas, new Point3D(85, 1644, 20), 9216, 13824, typeof(AcademicBooksArtifact)),
|
||||
};
|
||||
|
||||
private static Type[] m_TypesOfEntries = null;
|
||||
private static StealableArtifactsSpawner m_Instance;
|
||||
private Timer m_RespawnTimer;
|
||||
private StealableInstance[] m_Artifacts;
|
||||
private Hashtable m_Table;
|
||||
public StealableArtifactsSpawner(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
m_Instance = this;
|
||||
}
|
||||
|
||||
private StealableArtifactsSpawner()
|
||||
: base(1)
|
||||
{
|
||||
this.Movable = false;
|
||||
|
||||
this.m_Artifacts = new StealableInstance[m_Entries.Length];
|
||||
this.m_Table = new Hashtable(m_Entries.Length);
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; i++)
|
||||
{
|
||||
this.m_Artifacts[i] = new StealableInstance(m_Entries[i]);
|
||||
}
|
||||
|
||||
this.m_RespawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), new TimerCallback(CheckRespawn));
|
||||
}
|
||||
|
||||
public static StealableEntry[] Entries
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Entries;
|
||||
}
|
||||
}
|
||||
public static Type[] TypesOfEntires
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_TypesOfEntries == null)
|
||||
{
|
||||
m_TypesOfEntries = new Type[m_Entries.Length];
|
||||
|
||||
for (int i = 0; i < m_Entries.Length; i++)
|
||||
m_TypesOfEntries[i] = m_Entries[i].Type;
|
||||
}
|
||||
|
||||
return m_TypesOfEntries;
|
||||
}
|
||||
}
|
||||
public static StealableArtifactsSpawner Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Instance;
|
||||
}
|
||||
}
|
||||
public override string DefaultName
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Stealable Artifacts Spawner - Internal";
|
||||
}
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("GenStealArties", AccessLevel.Administrator, new CommandEventHandler(GenStealArties_OnCommand));
|
||||
CommandSystem.Register("RemoveStealArties", AccessLevel.Administrator, new CommandEventHandler(RemoveStealArties_OnCommand));
|
||||
CommandSystem.Register("StealArtiesForceRespawn", AccessLevel.GameMaster, new CommandEventHandler(StealArtiesForceRespawn_OnCommand));
|
||||
}
|
||||
|
||||
private static void StealArtiesForceRespawn_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if(Instance != null &&
|
||||
Instance.m_Artifacts != null)
|
||||
{
|
||||
foreach (StealableInstance instance in Instance.m_Artifacts)
|
||||
{
|
||||
instance.ForceRespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Create()
|
||||
{
|
||||
if (m_Instance != null && !m_Instance.Deleted)
|
||||
return false;
|
||||
|
||||
m_Instance = new StealableArtifactsSpawner();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Remove()
|
||||
{
|
||||
if (m_Instance == null)
|
||||
return false;
|
||||
|
||||
m_Instance.Delete();
|
||||
m_Instance = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StealableInstance GetStealableInstance(Item item)
|
||||
{
|
||||
if (Instance == null)
|
||||
return null;
|
||||
|
||||
return (StealableInstance)Instance.m_Table[item];
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if (this.m_RespawnTimer != null)
|
||||
{
|
||||
this.m_RespawnTimer.Stop();
|
||||
this.m_RespawnTimer = null;
|
||||
}
|
||||
|
||||
foreach (StealableInstance si in this.m_Artifacts)
|
||||
{
|
||||
if (si.Item != null)
|
||||
si.Item.Delete();
|
||||
}
|
||||
|
||||
m_Instance = null;
|
||||
}
|
||||
|
||||
public void CheckRespawn()
|
||||
{
|
||||
foreach (StealableInstance si in this.m_Artifacts)
|
||||
{
|
||||
si.CheckRespawn();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.WriteEncodedInt(this.m_Artifacts.Length);
|
||||
|
||||
for (int i = 0; i < this.m_Artifacts.Length; i++)
|
||||
{
|
||||
StealableInstance si = this.m_Artifacts[i];
|
||||
|
||||
writer.Write((Item)si.Item);
|
||||
writer.WriteDeltaTime((DateTime)si.NextRespawn);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
this.m_Artifacts = new StealableInstance[m_Entries.Length];
|
||||
this.m_Table = new Hashtable(m_Entries.Length);
|
||||
|
||||
int length = reader.ReadEncodedInt();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Item item = reader.ReadItem();
|
||||
DateTime nextRespawn = reader.ReadDeltaTime();
|
||||
|
||||
if (i < this.m_Artifacts.Length)
|
||||
{
|
||||
StealableInstance si = new StealableInstance(m_Entries[i], item, nextRespawn);
|
||||
this.m_Artifacts[i] = si;
|
||||
|
||||
if (si.Item != null)
|
||||
this.m_Table[si.Item] = si;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = length; i < m_Entries.Length; i++)
|
||||
{
|
||||
this.m_Artifacts[i] = new StealableInstance(m_Entries[i]);
|
||||
}
|
||||
|
||||
this.m_RespawnTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMinutes(15.0), new TimerCallback(CheckRespawn));
|
||||
}
|
||||
|
||||
private static int GetLampPostHue()
|
||||
{
|
||||
if (0.9 > Utility.RandomDouble())
|
||||
return 0;
|
||||
|
||||
return Utility.RandomList(0x455, 0x47E, 0x482, 0x486, 0x48F, 0x4F2, 0x58C, 0x66C);
|
||||
}
|
||||
|
||||
[Usage("GenStealArties")]
|
||||
[Description("Generates the stealable artifacts spawner.")]
|
||||
private static void GenStealArties_OnCommand(CommandEventArgs args)
|
||||
{
|
||||
Mobile from = args.Mobile;
|
||||
|
||||
if (Create())
|
||||
from.SendMessage("Stealable artifacts spawner generated.");
|
||||
else
|
||||
from.SendMessage("Stealable artifacts spawner already present.");
|
||||
}
|
||||
|
||||
[Usage("RemoveStealArties")]
|
||||
[Description("Removes the stealable artifacts spawner and every not yet stolen stealable artifacts.")]
|
||||
private static void RemoveStealArties_OnCommand(CommandEventArgs args)
|
||||
{
|
||||
Mobile from = args.Mobile;
|
||||
|
||||
if (Remove())
|
||||
from.SendMessage("Stealable artifacts spawner removed.");
|
||||
else
|
||||
from.SendMessage("Stealable artifacts spawner not present.");
|
||||
}
|
||||
|
||||
public class StealableEntry
|
||||
{
|
||||
private readonly Map m_Map;
|
||||
private readonly Point3D m_Location;
|
||||
private readonly int m_MinDelay;
|
||||
private readonly int m_MaxDelay;
|
||||
private readonly Type m_Type;
|
||||
private readonly int m_Hue;
|
||||
public StealableEntry(Map map, Point3D location, int minDelay, int maxDelay, Type type)
|
||||
: this(map, location, minDelay, maxDelay, type, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public StealableEntry(Map map, Point3D location, int minDelay, int maxDelay, Type type, int hue)
|
||||
{
|
||||
this.m_Map = map;
|
||||
this.m_Location = location;
|
||||
this.m_MinDelay = minDelay;
|
||||
this.m_MaxDelay = maxDelay;
|
||||
this.m_Type = type;
|
||||
this.m_Hue = hue;
|
||||
}
|
||||
|
||||
public Map Map
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Map;
|
||||
}
|
||||
}
|
||||
public Point3D Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Location;
|
||||
}
|
||||
}
|
||||
public int MinDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_MinDelay;
|
||||
}
|
||||
}
|
||||
public int MaxDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_MaxDelay;
|
||||
}
|
||||
}
|
||||
public Type Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Type;
|
||||
}
|
||||
}
|
||||
public int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Hue;
|
||||
}
|
||||
}
|
||||
public Item CreateInstance()
|
||||
{
|
||||
Item item = (Item)Activator.CreateInstance(this.m_Type);
|
||||
|
||||
if (this.m_Hue > 0)
|
||||
item.Hue = this.m_Hue;
|
||||
|
||||
item.Movable = false;
|
||||
item.MoveToWorld(this.Location, this.Map);
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
public class StealableInstance
|
||||
{
|
||||
private readonly StealableEntry m_Entry;
|
||||
private Item m_Item;
|
||||
private DateTime m_NextRespawn;
|
||||
public StealableInstance(StealableEntry entry)
|
||||
: this(entry, null, DateTime.UtcNow)
|
||||
{
|
||||
}
|
||||
|
||||
public StealableInstance(StealableEntry entry, Item item, DateTime nextRespawn)
|
||||
{
|
||||
this.m_Item = item;
|
||||
this.m_NextRespawn = nextRespawn;
|
||||
this.m_Entry = entry;
|
||||
}
|
||||
|
||||
public StealableEntry Entry
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Entry;
|
||||
}
|
||||
}
|
||||
public Item Item
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Item;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.m_Item != null && value == null)
|
||||
{
|
||||
int delay = Utility.RandomMinMax(this.Entry.MinDelay, this.Entry.MaxDelay);
|
||||
this.NextRespawn = DateTime.UtcNow + TimeSpan.FromMinutes(delay);
|
||||
}
|
||||
|
||||
if (Instance != null)
|
||||
{
|
||||
if (this.m_Item != null)
|
||||
Instance.m_Table.Remove(this.m_Item);
|
||||
|
||||
if (value != null)
|
||||
Instance.m_Table[value] = this;
|
||||
}
|
||||
|
||||
this.m_Item = value;
|
||||
}
|
||||
}
|
||||
public DateTime NextRespawn
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_NextRespawn;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_NextRespawn = value;
|
||||
}
|
||||
}
|
||||
public void CheckRespawn()
|
||||
{
|
||||
if (this.Item != null && (this.Item.Deleted || this.Item.Movable || this.Item.Parent != null))
|
||||
this.Item = null;
|
||||
|
||||
if (this.Item == null && DateTime.UtcNow >= this.NextRespawn)
|
||||
{
|
||||
this.Item = this.Entry.CreateInstance();
|
||||
}
|
||||
}
|
||||
public void ForceRespawn()
|
||||
{
|
||||
if (this.Item != null && (this.Item.Deleted || this.Item.Movable || this.Item.Parent != null))
|
||||
this.Item = null;
|
||||
|
||||
if (this.Item == null)
|
||||
{
|
||||
this.Item = this.Entry.CreateInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
Scripts/Items/Functional/StoneFaceTrap.cs
Normal file
205
Scripts/Items/Functional/StoneFaceTrap.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum StoneFaceTrapType
|
||||
{
|
||||
NorthWestWall,
|
||||
NorthWall,
|
||||
WestWall
|
||||
}
|
||||
|
||||
public class StoneFaceTrap : BaseTrap
|
||||
{
|
||||
[Constructable]
|
||||
public StoneFaceTrap()
|
||||
: base(0x10FC)
|
||||
{
|
||||
this.Light = LightType.Circle225;
|
||||
}
|
||||
|
||||
public StoneFaceTrap(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public StoneFaceTrapType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
switch ( this.ItemID )
|
||||
{
|
||||
case 0x10F5:
|
||||
case 0x10F6:
|
||||
case 0x10F7:
|
||||
return StoneFaceTrapType.NorthWestWall;
|
||||
case 0x10FC:
|
||||
case 0x10FD:
|
||||
case 0x10FE:
|
||||
return StoneFaceTrapType.NorthWall;
|
||||
case 0x110F:
|
||||
case 0x1110:
|
||||
case 0x1111:
|
||||
return StoneFaceTrapType.WestWall;
|
||||
}
|
||||
|
||||
return StoneFaceTrapType.NorthWestWall;
|
||||
}
|
||||
set
|
||||
{
|
||||
bool breathing = this.Breathing;
|
||||
|
||||
this.ItemID = (breathing ? GetFireID(value) : GetBaseID(value));
|
||||
}
|
||||
}
|
||||
public bool Breathing
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ItemID == GetFireID(this.Type));
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
this.ItemID = GetFireID(this.Type);
|
||||
else
|
||||
this.ItemID = GetBaseID(this.Type);
|
||||
}
|
||||
}
|
||||
public override bool PassivelyTriggered
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override TimeSpan PassiveTriggerDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public override int PassiveTriggerRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
public override TimeSpan ResetDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
public static int GetBaseID(StoneFaceTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case StoneFaceTrapType.NorthWestWall:
|
||||
return 0x10F5;
|
||||
case StoneFaceTrapType.NorthWall:
|
||||
return 0x10FC;
|
||||
case StoneFaceTrapType.WestWall:
|
||||
return 0x110F;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetFireID(StoneFaceTrapType type)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case StoneFaceTrapType.NorthWestWall:
|
||||
return 0x10F7;
|
||||
case StoneFaceTrapType.NorthWall:
|
||||
return 0x10FE;
|
||||
case StoneFaceTrapType.WestWall:
|
||||
return 0x1111;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override void OnTrigger(Mobile from)
|
||||
{
|
||||
if (!from.Alive || from.IsStaff())
|
||||
return;
|
||||
|
||||
Effects.PlaySound(this.Location, this.Map, 0x359);
|
||||
|
||||
this.Breathing = true;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerCallback(FinishBreath));
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), new TimerCallback(TriggerDamage));
|
||||
}
|
||||
|
||||
public virtual void FinishBreath()
|
||||
{
|
||||
this.Breathing = false;
|
||||
}
|
||||
|
||||
public virtual void TriggerDamage()
|
||||
{
|
||||
IPooledEnumerable eable = GetMobilesInRange(1);
|
||||
foreach (Mobile mob in eable)
|
||||
{
|
||||
if (mob.Alive && !mob.IsDeadBondedPet && mob.IsPlayer())
|
||||
Spells.SpellHelper.Damage(TimeSpan.FromTicks(1), mob, mob, Utility.Dice(3, 15, 0));
|
||||
}
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
this.Breathing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class StoneFaceTrapNoDamage : StoneFaceTrap
|
||||
{
|
||||
[Constructable]
|
||||
public StoneFaceTrapNoDamage()
|
||||
{
|
||||
}
|
||||
|
||||
public StoneFaceTrapNoDamage(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void TriggerDamage()
|
||||
{
|
||||
// nothing..
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
226
Scripts/Items/Functional/StrangeContraption.cs
Normal file
226
Scripts/Items/Functional/StrangeContraption.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Quests.Collector;
|
||||
using Server.Engines.Quests.Hag;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class StrangeContraptionComponent : AddonComponent
|
||||
{
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
public StrangeContraptionComponent(int id, int hue = 0)
|
||||
: base(id)
|
||||
{
|
||||
Name = "a strange contraption";
|
||||
Hue = hue;
|
||||
}
|
||||
|
||||
public StrangeContraptionComponent(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (ItemID == 6434)
|
||||
{
|
||||
list.Add(new DeviceEntry(from, this));
|
||||
}
|
||||
}
|
||||
|
||||
private class DeviceEntry : ContextMenuEntry
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly AddonComponent m_Component;
|
||||
|
||||
public DeviceEntry(Mobile mobile, AddonComponent c)
|
||||
: base(3006190, 16) // Appraise for Cleanup
|
||||
{
|
||||
m_Mobile = mobile;
|
||||
m_Component = c;
|
||||
}
|
||||
|
||||
public bool CanDrop(Mobile m)
|
||||
{
|
||||
if (!StrangeContraptionAddon.Table.ContainsKey(m))
|
||||
return true;
|
||||
|
||||
if (StrangeContraptionAddon.Table[m] < DateTime.UtcNow)
|
||||
{
|
||||
StrangeContraptionAddon.Table.Remove(m);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage(1060001); // You throw the switch, but the mechanism cannot be engaged again so soon.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (m_Mobile.InRange(m_Component.Location, 2))
|
||||
{
|
||||
if (CanDrop(m_Mobile))
|
||||
{
|
||||
Container pack = m_Mobile.Backpack as Container;
|
||||
|
||||
if (pack == null)
|
||||
return;
|
||||
|
||||
Item pmc = pack.FindItemByType(typeof(PlagueBeastMutationCore));
|
||||
Item obs = pack.FindItemByType(typeof(Obsidian));
|
||||
Item mb = pack.FindItemByType(typeof(MoonfireBrew));
|
||||
|
||||
if (pmc != null && obs != null && mb != null)
|
||||
{
|
||||
m_Mobile.PlaySound(0x21E);
|
||||
m_Mobile.SendLocalizedMessage(1055143); // You add the required ingredients and activate the contraption. It rumbles and smokes and then falls silent. The water shines for a brief moment, and you feel confident that it is now much less tainted then before.
|
||||
m_Mobile.Karma += 500;
|
||||
|
||||
pmc.Delete();
|
||||
obs.Delete();
|
||||
mb.Delete();
|
||||
|
||||
StrangeContraptionAddon.Table[m_Mobile] = DateTime.UtcNow + TimeSpan.FromHours(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1055142, "", 0x59); // You do not have the necessary ingredients. The contraptions rumbles angrily but does nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public class StrangeContraptionAddon : BaseAddon
|
||||
{
|
||||
public static StrangeContraptionAddon InstanceTram { get; set; }
|
||||
public static StrangeContraptionAddon InstanceFel { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Core.T2A)
|
||||
{
|
||||
if (InstanceTram == null)
|
||||
{
|
||||
StrangeContraptionAddon item = new StrangeContraptionAddon();
|
||||
item.MoveToWorld(new Point3D(5668, 1925, 0), Map.Trammel);
|
||||
}
|
||||
|
||||
if (InstanceFel == null)
|
||||
{
|
||||
StrangeContraptionAddon item = new StrangeContraptionAddon();
|
||||
item.MoveToWorld(new Point3D(5668, 1925, 0), Map.Felucca);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<Mobile, DateTime> Table = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
public StrangeContraptionAddon()
|
||||
{
|
||||
// Table
|
||||
AddComponent(new AddonComponent(2923), 1, 2, 1);
|
||||
AddComponent(new AddonComponent(2924), 1, 1, 1);
|
||||
|
||||
// Book
|
||||
AddComponent(new AddonComponent(0x0FF4), 1, 2, 7);
|
||||
|
||||
// Water
|
||||
AddComponent(new AddonComponent(6063), -1, 0, 1);
|
||||
AddComponent(new AddonComponent(6066), 0, 0, 1);
|
||||
AddComponent(new AddonComponent(6064), -1, 1, 1);
|
||||
AddComponent(new AddonComponent(6065), 0, 1, 1);
|
||||
|
||||
AddComponent(new StrangeContraptionComponent(4758), 0, -1, 1);
|
||||
AddComponent(new StrangeContraptionComponent(4758), 0, 0, 1);
|
||||
AddComponent(new StrangeContraptionComponent(2813), 2, 0, 19);
|
||||
AddComponent(new StrangeContraptionComponent(2815), 1, 0, 19);
|
||||
AddComponent(new StrangeContraptionComponent(2816), 2, 0, 16);
|
||||
AddComponent(new StrangeContraptionComponent(2818), 1, 0, 16);
|
||||
AddComponent(new StrangeContraptionComponent(4715), 1, 0, 1);
|
||||
AddComponent(new StrangeContraptionComponent(2643), 1, 0, 3);
|
||||
AddComponent(new StrangeContraptionComponent(6434), 2, 0, 1);
|
||||
AddComponent(new StrangeContraptionComponent(4758, 1545), -1, 0, 0);
|
||||
AddComponent(new StrangeContraptionComponent(4272, 1545), - 1, 0, 1);
|
||||
AddComponent(new StrangeContraptionComponent(6039, 999), 2, 0, 20);
|
||||
AddComponent(new StrangeContraptionComponent(6040, 999), 1, 0, 20);
|
||||
}
|
||||
|
||||
public override void OnComponentUsed(AddonComponent comp, Mobile from)
|
||||
{
|
||||
if (comp.ItemID == 0x0FF4)
|
||||
{
|
||||
if (!from.InRange(comp.GetWorldLocation(), 2))
|
||||
{
|
||||
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
|
||||
}
|
||||
else
|
||||
{
|
||||
Gump g = new Gump(35, 70);
|
||||
g.AddImage(0, 0, 500);
|
||||
g.AddHtmlLocalized(40, 17, 150, 220, 1055141, false, false);
|
||||
from.SendGump(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StrangeContraptionAddon(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();
|
||||
|
||||
if (Core.T2A)
|
||||
{
|
||||
if (Map == Map.Trammel)
|
||||
{
|
||||
InstanceTram = this;
|
||||
}
|
||||
else if (Map == Map.Felucca)
|
||||
{
|
||||
InstanceFel = this;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Items/Functional/Switches.cs
Normal file
86
Scripts/Items/Functional/Switches.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class UnderworldSwitchWE : BaseSwitch
|
||||
{
|
||||
[Constructable]
|
||||
public UnderworldSwitchWE()
|
||||
: base(0x1091, 0x1092, 1042901, 1042900, true)
|
||||
{
|
||||
//1042901 = You hear a deep rumbling as something seems to happen.
|
||||
//1042900 = There seems to be no further effect right now.
|
||||
//true = It do something, it is not useless or broken switch.
|
||||
}
|
||||
|
||||
public UnderworldSwitchWE(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void DoSomethingSpecial(Mobile from)
|
||||
{
|
||||
foreach (Item item in this.GetItemsInRange(8))
|
||||
{
|
||||
if (item.ItemID == 0x3660 && item.Hue == 1000) //Dark Globe of Sosaria
|
||||
{
|
||||
Timer m_timerA = new MoveTimer(item, 1);
|
||||
m_timerA.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private class MoveTimer : Timer
|
||||
{
|
||||
private readonly Item item;
|
||||
private readonly int num;
|
||||
private int m_Stage;
|
||||
private int m_Cicle;
|
||||
public MoveTimer(Item sphere, int coord)
|
||||
: base(TimeSpan.FromSeconds(0.0), TimeSpan.FromSeconds(1.5))
|
||||
{
|
||||
this.item = sphere;
|
||||
this.num = coord;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (this.item.Deleted)
|
||||
{
|
||||
this.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
this.m_Stage++;
|
||||
|
||||
if (this.m_Cicle == 0)
|
||||
this.item.Z += 1;
|
||||
else if (this.m_Cicle == 1)
|
||||
this.item.Z += 0;
|
||||
else
|
||||
this.item.Z += -1;
|
||||
|
||||
if (this.m_Stage == 8)
|
||||
this.m_Cicle++;
|
||||
else if (this.m_Stage == 14)
|
||||
this.m_Cicle++;
|
||||
else if (this.m_Stage == 22)
|
||||
this.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Scripts/Items/Functional/TwistedWealdAltar.cs
Normal file
56
Scripts/Items/Functional/TwistedWealdAltar.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TwistedWealdAltar : PeerlessAltar
|
||||
{
|
||||
public override int KeyCount{ get{ return 3; } }
|
||||
public override MasterKey MasterKey{ get{ return new TwistedWealdKey(); } }
|
||||
|
||||
public override Type[] Keys{ get{ return new Type[]
|
||||
{
|
||||
typeof( BlightedCotton ), typeof( GnawsFang ), typeof( IrksBrain ),
|
||||
typeof( LissithsSilk ), typeof( SabrixsEye ), typeof( ThornyBriar )
|
||||
}; }}
|
||||
|
||||
public override BasePeerless Boss{ get{ return new DreadHorn(); } }
|
||||
|
||||
[Constructable]
|
||||
public TwistedWealdAltar() : base( 0x207C )
|
||||
{
|
||||
BossLocation = new Point3D( 2137, 1247, -60 );
|
||||
TeleportDest = new Point3D( 2151, 1261, -60 );
|
||||
ExitDest = new Point3D( 1448, 1537, -28 );
|
||||
}
|
||||
|
||||
public override Rectangle2D[] BossBounds
|
||||
{
|
||||
get { return m_Bounds; }
|
||||
}
|
||||
|
||||
private Rectangle2D[] m_Bounds = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D(2126, 1237, 33, 38),
|
||||
};
|
||||
|
||||
public TwistedWealdAltar( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
395
Scripts/Items/Functional/WallSafe.cs
Normal file
395
Scripts/Items/Functional/WallSafe.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Server.Gumps;
|
||||
using Server.Accounting;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flipable(0x8B8F, 0x8B90)]
|
||||
public class WallSafe : Item, IAddon, ISecurable, IChopable
|
||||
{
|
||||
public const int MaxGold = 100000000;
|
||||
public const int HistoryMax = 15;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int HoldAmount { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public SecureLevel Level
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Item Deed { get { return new WallSafeDeed(); } }
|
||||
|
||||
public override int LabelNumber { get { return 1119751; } } // Wall Safe
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
public List<string> History { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public WallSafe(Mobile m) : base(0x8B8F)
|
||||
{
|
||||
Owner = m;
|
||||
Movable = false;
|
||||
|
||||
Level = SecureLevel.CoOwners;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
SetSecureLevelEntry.AddTo(from, this, list);
|
||||
}
|
||||
|
||||
public void OnChop(Mobile from)
|
||||
{
|
||||
if (HoldAmount > 0)
|
||||
from.SendLocalizedMessage(1155841); // You can't use a bladed item on a wall safe with a balance.
|
||||
else
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(this);
|
||||
|
||||
if (house != null && (house.IsOwner(from) || (house.Addons.ContainsKey(this) && house.Addons[this] == from)))
|
||||
{
|
||||
Effects.PlaySound(GetWorldLocation(), Map, 0x3B3);
|
||||
from.SendLocalizedMessage(500461); // You destroy the item.
|
||||
|
||||
Delete();
|
||||
|
||||
house.Addons.Remove(this);
|
||||
|
||||
Item deed = Deed;
|
||||
|
||||
if (deed != null)
|
||||
from.AddToBackpack(deed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CouldFit(IPoint3D p, Map map)
|
||||
{
|
||||
if (!map.CanFit(p.X, p.Y, p.Z, this.ItemData.Height))
|
||||
return false;
|
||||
|
||||
if (this.ItemID == 0x2375)
|
||||
return BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map); // North wall
|
||||
else
|
||||
return BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map); // West wall
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile && m.InRange(this.Location, 3))
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt(m);
|
||||
|
||||
if (house != null && house.HasSecureAccess(m, Level))
|
||||
{
|
||||
m.SendGump(new WallSafeGump((PlayerMobile)m, this));
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(1061637); // You are not allowed to access this.
|
||||
}
|
||||
}
|
||||
|
||||
public void AddHistory(string str)
|
||||
{
|
||||
if (History == null)
|
||||
History = new List<string>();
|
||||
|
||||
History.Add(str);
|
||||
|
||||
if (History.Count > HistoryMax)
|
||||
History.RemoveAt(0);
|
||||
}
|
||||
|
||||
public WallSafe(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write(Owner);
|
||||
writer.Write(HoldAmount);
|
||||
writer.Write((int)Level);
|
||||
|
||||
writer.Write(History == null ? 0 : History.Count);
|
||||
|
||||
if (History != null)
|
||||
History.ForEach(s => writer.Write(s));
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Owner = reader.ReadMobile();
|
||||
HoldAmount = reader.ReadInt();
|
||||
Level = (SecureLevel)reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
History = new List<string>();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string str = reader.ReadString();
|
||||
History.Add(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WallSafeDeed : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1155857; } } // Currency Wall Safe
|
||||
|
||||
[Constructable]
|
||||
public WallSafeDeed() : base(0x14F0)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (IsChildOf(m.Backpack))
|
||||
{
|
||||
m.BeginTarget(8, false, Server.Targeting.TargetFlags.None, (from, targeted) =>
|
||||
{
|
||||
if (targeted is IPoint3D)
|
||||
{
|
||||
IPoint3D p = targeted as IPoint3D;
|
||||
BaseHouse house = BaseHouse.FindHouseAt(new Point3D(p), m.Map, 16);
|
||||
|
||||
if (house != null && BaseHouse.FindHouseAt(m) == house && house.IsCoOwner(m))
|
||||
{
|
||||
Point3D pnt = new Point3D(p.X, p.Y, m.Z);
|
||||
|
||||
bool northWall = BaseAddon.IsWall(pnt.X, pnt.Y - 1, pnt.Z, m.Map);
|
||||
bool westWall = BaseAddon.IsWall(pnt.X - 1, pnt.Y, pnt.Z, m.Map);
|
||||
|
||||
if (northWall && westWall)
|
||||
{
|
||||
switch (from.Direction & Direction.Mask)
|
||||
{
|
||||
case Direction.North:
|
||||
case Direction.South: northWall = true; westWall = false; break;
|
||||
|
||||
case Direction.East:
|
||||
case Direction.West: northWall = false; westWall = true; break;
|
||||
|
||||
default: from.SendMessage("Turn to face the wall on which to place the safe."); return;
|
||||
}
|
||||
}
|
||||
|
||||
int itemID = 0;
|
||||
|
||||
if (northWall)
|
||||
itemID = 0x8B8F;
|
||||
else if(westWall)
|
||||
itemID = 0x8B90;
|
||||
else
|
||||
m.SendLocalizedMessage(500268); // This object needs to be mounted on something.
|
||||
|
||||
if (itemID != 0)
|
||||
{
|
||||
Item safe = new WallSafe(m);
|
||||
safe.MoveToWorld(pnt, m.Map);
|
||||
|
||||
safe.ItemID = itemID;
|
||||
|
||||
house.Addons[safe] = m;
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(500274); // You can only place this in a house that you own!
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(1080058); // This must be in your backpack to use it.
|
||||
}
|
||||
|
||||
public WallSafeDeed(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 class WallSafeGump : Gump
|
||||
{
|
||||
public WallSafe Safe { get; set; }
|
||||
public PlayerMobile User { get; set; }
|
||||
|
||||
public WallSafeGump(PlayerMobile pm, WallSafe safe)
|
||||
: base(50, 50)
|
||||
{
|
||||
User = pm;
|
||||
Safe = safe;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 400, 500, 83);
|
||||
|
||||
AddHtmlLocalized(0, 10, 400, 16, 1113302, "#1155860", 0xFFFF, false, false);
|
||||
|
||||
int secureAmount = 0;
|
||||
Account acct = User.Account as Account;
|
||||
|
||||
if (acct != null)
|
||||
secureAmount = acct.GetSecureAccountAmount(User);
|
||||
|
||||
AddHtmlLocalized(20, 35, 380, 16, 1155859, Safe.HoldAmount.ToString("N0", CultureInfo.GetCultureInfo("en-US")), 0xFFFF, false, false); // Gold Deposited: ~1_AMOUNT~
|
||||
AddHtmlLocalized(20, 65, 380, 16, 1155864, String.Format("{0}\t{1}", User.Name, secureAmount.ToString("N0", CultureInfo.GetCultureInfo("en-US"))), 0xFFFF, false, false); // ~1_NAME~'s Secure Account: ~2_AMOUNT~
|
||||
|
||||
AddHtmlLocalized(20, 125, 100, 16, 1155861, 0xFFFF, false, false); // Deposit
|
||||
AddButton(75, 125, 4005, 4006, 1, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(220, 125, 100, 16, 1155862, 0xFFFF, false, false); // Withdraw
|
||||
AddButton(300, 125, 4005, 4006, 2, GumpButtonType.Reply, 0);
|
||||
|
||||
AddHtmlLocalized(20, 165, 200, 16, 1155863, 0xFFFF, false, false); // Sale Transactions:
|
||||
|
||||
if (Safe.History != null && Safe.History.Count > 0)
|
||||
{
|
||||
int y = 195;
|
||||
for (int i = Safe.History.Count - 1; i >= 0 && i < WallSafe.HistoryMax; i--)
|
||||
{
|
||||
AddHtml(20, y, 380, 16, Safe.History[i], false, false);
|
||||
y += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(Server.Network.NetState state, RelayInfo info)
|
||||
{
|
||||
Account account = User.Account as Account;
|
||||
int secureAmount = 0;
|
||||
|
||||
if (account != null)
|
||||
secureAmount = account.GetSecureAccountAmount(User);
|
||||
|
||||
switch (info.ButtonID)
|
||||
{
|
||||
case 1:
|
||||
User.SendLocalizedMessage(1155865); // Enter amount to deposit:
|
||||
User.BeginPrompt<Account>(
|
||||
(from, text, acct) =>
|
||||
{
|
||||
int v = 0;
|
||||
|
||||
if (text != null && !String.IsNullOrEmpty(text))
|
||||
{
|
||||
v = Utility.ToInt32(text);
|
||||
|
||||
if (v <= 0 || v > secureAmount)
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
else if (acct != null)
|
||||
{
|
||||
int left = WallSafe.MaxGold - Safe.HoldAmount;
|
||||
|
||||
if (v > left)
|
||||
{
|
||||
Safe.HoldAmount = WallSafe.MaxGold;
|
||||
acct.WithdrawFromSecure(User, left);
|
||||
Safe.AddHistory(String.Format("<basefont color=green>{0} +{1}", User.Name, left.ToString("N0", CultureInfo.GetCultureInfo("en-US"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
Safe.HoldAmount += v;
|
||||
acct.WithdrawFromSecure(User, v);
|
||||
Safe.AddHistory(String.Format("<basefont color=green>{0} +{1}", User.Name, v.ToString("N0", CultureInfo.GetCultureInfo("en-US"))));
|
||||
}
|
||||
|
||||
from.SendGump(new WallSafeGump(User, Safe));
|
||||
}
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
},
|
||||
(from, text, acct) =>
|
||||
{
|
||||
from.SendGump(new WallSafeGump(User, Safe));
|
||||
}, account);
|
||||
break;
|
||||
case 2:
|
||||
User.SendLocalizedMessage(1155866); // Enter amount to withdraw:
|
||||
User.BeginPrompt<Account>(
|
||||
(from, text, acct) =>
|
||||
{
|
||||
int v = 0;
|
||||
|
||||
if (text != null && !String.IsNullOrEmpty(text))
|
||||
{
|
||||
v = Utility.ToInt32(text);
|
||||
|
||||
if (v <= 0 || v > Safe.HoldAmount)
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
else if (acct != null)
|
||||
{
|
||||
int left = Account.MaxSecureAmount - secureAmount;
|
||||
|
||||
if (v > left)
|
||||
{
|
||||
acct.DepositToSecure(User, left);
|
||||
Safe.HoldAmount -= left;
|
||||
Safe.AddHistory(String.Format("<basefont color=red>{0} -{1}", User.Name, left.ToString("N0", CultureInfo.GetCultureInfo("en-US"))));
|
||||
}
|
||||
else
|
||||
{
|
||||
acct.DepositToSecure(User, v);
|
||||
Safe.HoldAmount -= v;
|
||||
Safe.AddHistory(String.Format("<basefont color=red>{0} -{1}", User.Name, v.ToString("N0", CultureInfo.GetCultureInfo("en-US"))));
|
||||
}
|
||||
|
||||
from.SendGump(new WallSafeGump(User, Safe));
|
||||
}
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
},
|
||||
(from, text, acct) =>
|
||||
{
|
||||
from.SendGump(new WallSafeGump(User, Safe));
|
||||
}, account);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user