Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View 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();
}
}
}

View 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();
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View File

@@ -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();
}
}
}

View 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);
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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);
}
}
}
}

View 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();
}
}
}

View 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());
}
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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.
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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);
}
}
}

View 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;
}
}
}
}
}

View 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;
}
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}
}

View 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));
}
}
}
}

View 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));
}
}
}

View 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);
}
}
}

View 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);
}
}
}
}

View 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;
}
}
}
}
}

View 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;
}
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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();
}
}
}
}

View 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()
{
}
}
}

View 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);
}
}
}
}

View 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);
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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);
}
}
}

View 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;
}
}
}
}

View 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);
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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();
}
}
}

View 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;
}
}
}

View 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();
}
}
}

View 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();
}
}
}
}
}

View 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;
}
}
}

View 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();
}
}
}
}
}

View 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();
}
}
}

View 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();
}
}
}
}

View 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();
}
}
}
}

View 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();
}
}
}

View 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;
}
}
}
}