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

5019
Scripts/Multis/BaseHouse.cs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,197 @@
using System;
using Server;
using Server.Regions;
using Server.Targeting;
using Server.Engines.CannedEvil;
using Server.Network;
using Server.Gumps;
using Server.Items;
using System.Linq;
namespace Server.Multis
{
public abstract class BaseBoatDeed : Item
{
[CommandProperty(AccessLevel.GameMaster)]
public int MultiID { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Point3D Offset { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Direction BoatDirection { get; set; }
public BaseBoatDeed(int id, Point3D offset)
: base(0x14F2)
{
Weight = 1.0;
if (!Core.AOS)
LootType = LootType.Newbied;
MultiID = id;
Offset = offset;
BoatDirection = Direction.North;
}
public BaseBoatDeed(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(MultiID);
writer.Write(Offset);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 0:
{
MultiID = reader.ReadInt();
Offset = reader.ReadPoint3D();
break;
}
}
}
public override void OnDoubleClick(Mobile from)
{
BaseBoat boat = BaseBoat.FindBoatAt(from, from.Map);
if (from.AccessLevel < AccessLevel.GameMaster && (from.Map == Map.Ilshenar || from.Map == Map.Malas))
{
from.SendLocalizedMessage(1010567, null, 0x25); // You may not place a boat from this location.
}
else if (Core.HS && BaseBoat.HasBoat(from) && !Boat.IsRowBoat)
{
from.SendLocalizedMessage(1116758); // You already have a ship deployed!
}
else if (from.Region.IsPartOf(typeof(HouseRegion)) || boat != null && (boat.GetType() == Boat.GetType() || !boat.IsRowBoat && !(this is RowBoatDeed)))
{
from.SendLocalizedMessage(1010568, null, 0x25); // You may not place a ship while on another ship or inside a house.
}
else if (!from.HasGump(typeof(BoatPlacementGump)))
{
if (Core.SE)
from.SendLocalizedMessage(502482); // Where do you wish to place the ship?
else
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502482); // Where do you wish to place the ship?
from.SendGump(new BoatPlacementGump(this, from));
}
}
public abstract BaseBoat Boat { get; }
public void OnPlacement(Mobile from, Point3D p, int itemID, Direction d)
{
if (Deleted)
{
return;
}
else
{
Map map = from.Map;
if (map == null)
return;
if (from.AccessLevel < AccessLevel.GameMaster && (map == Map.Ilshenar || map == Map.Malas))
{
from.SendLocalizedMessage(1043284); // A ship can not be created here.
return;
}
BaseBoat b = BaseBoat.FindBoatAt(from, from.Map);
if (from.Region.IsPartOf(typeof(HouseRegion)) || b != null && (b.GetType() == Boat.GetType() || !b.IsRowBoat && !(this is RowBoatDeed)))
{
from.SendLocalizedMessage(1010568, null, 0x25); // You may not place a ship while on another ship or inside a house.
return;
}
BoatDirection = d;
BaseBoat boat = Boat;
if (boat == null)
return;
p = new Point3D(p.X - Offset.X, p.Y - Offset.Y, p.Z - Offset.Z);
if (BaseBoat.IsValidLocation(p, map) && boat.CanFit(p, map, itemID))
{
if (boat.IsRowBoat)
{
BaseBoat lastrowboat = World.Items.Values.OfType<BaseBoat>().Where(x => x.Owner == from && x.IsRowBoat && x.Map != Map.Internal && !x.GetMobilesOnBoard().Any()).OrderByDescending(y => y.Serial).FirstOrDefault();
if (lastrowboat != null)
lastrowboat.Delete();
}
else
{
Delete();
}
boat.Owner = from;
boat.ItemID = itemID;
if (boat is BaseGalleon)
{
((BaseGalleon)boat).SecurityEntry = new SecurityEntry((BaseGalleon)boat);
((BaseGalleon)boat).BaseBoatHue = RandomBasePaintHue();
}
if (boat.IsClassicBoat)
{
uint keyValue = boat.CreateKeys(from);
if (boat.PPlank != null)
boat.PPlank.KeyValue = keyValue;
if (boat.SPlank != null)
boat.SPlank.KeyValue = keyValue;
}
boat.MoveToWorld(p, map);
boat.OnAfterPlacement(true);
var addon = LighthouseAddon.GetLighthouse(from);
if (addon != null)
{
if (boat.CanLinkToLighthouse)
from.SendLocalizedMessage(1154592); // You have linked your boat lighthouse.
else
from.SendLocalizedMessage(1154597); // Failed to link to lighthouse.
}
}
else
{
boat.Delete();
from.SendLocalizedMessage(1043284); // A ship can not be created here.
}
}
}
private int RandomBasePaintHue()
{
if (0.6 > Utility.RandomDouble())
{
return Utility.RandomMinMax(1701, 1754);
}
return Utility.RandomMinMax(1801, 1908);
}
}
}

View File

@@ -0,0 +1,210 @@
using System;
using Server;
using Server.Gumps;
using Server.Items;
namespace Server.Multis
{
public abstract class BaseDockedBoat : Item
{
[CommandProperty(AccessLevel.GameMaster)]
public int MultiID { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Point3D Offset { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public string ShipName
{
get
{
if (BoatItem == null || BoatItem.ShipName == null || BoatItem.ShipName.Trim().Length == 0)
return "Unnamed Ship";
return BoatItem.ShipName;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Direction BoatDirection { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public BaseBoat BoatItem { get; set; }
public BaseDockedBoat(int id, Point3D offset, BaseBoat boat)
: base(0x14F4)
{
Weight = 1.0;
LootType = LootType.Blessed;
MultiID = id;
Offset = offset;
BoatDirection = Direction.North;
BoatItem = boat;
Hue = boat.Hue;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (BoatItem != null && !BoatItem.Deleted)
BoatItem.Delete();
}
public BaseDockedBoat(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)6); // version
writer.Write(MultiID);
writer.Write(Offset);
writer.Write(BoatItem);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 6:
{
MultiID = reader.ReadInt();
Offset = reader.ReadPoint3D();
BoatItem = reader.ReadItem() as BaseBoat;
break;
}
case 5:
{
MultiID = reader.ReadInt();
Offset = reader.ReadPoint3D();
reader.ReadString();
BoatItem = reader.ReadItem() as BaseBoat;
break;
}
}
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
else if (Core.HS && BaseBoat.HasBoat(from))
{
from.SendLocalizedMessage(1116758); //You already have a ship deployed!
}
else if (!from.HasGump(typeof(BoatPlacementGump)))
{
from.SendLocalizedMessage(502482); // Where do you wish to place the ship?
from.SendGump(new BoatPlacementGump(this, from));
}
}
public abstract BaseBoat Boat { get; }
public override void AddNameProperty(ObjectPropertyList list)
{
list.Add(1041644, ShipName); //The ~1_VAL~ (Dry Docked)
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(LabelNumber);
}
public override void OnSingleClick(Mobile from)
{
if (ShipName != null)
LabelTo(from, ShipName);
else
base.OnSingleClick(from);
}
public void OnPlacement(Mobile from, Point3D p, int itemID, Direction d)
{
if (Deleted)
{
return;
}
else if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
else
{
Map map = from.Map;
if (map == null)
return;
BoatDirection = d;
BaseBoat boat = BoatItem;
if (boat == null || boat.Deleted)
boat = Boat;
if (boat == null)
return;
Mobile oldOwner = boat.Owner;
boat.BoatItem = this;
boat.Owner = from;
if (oldOwner != from && boat is BaseGalleon)
((BaseGalleon)boat).SecurityEntry = new SecurityEntry((BaseGalleon)boat);
p = new Point3D(p.X - Offset.X, p.Y - Offset.Y, p.Z - Offset.Z);
if (BaseBoat.IsValidLocation(p, map) && boat.CanFit(p, map, itemID) && map != Map.Ilshenar && map != Map.Malas)
{
boat.SetFacing(d);
boat.MoveToWorld(p, map);
boat.OnPlacement(from);
boat.Refresh();
boat.OnAfterPlacement(false);
var addon = LighthouseAddon.GetLighthouse(from);
if (addon != null)
{
if (boat.CanLinkToLighthouse)
from.SendLocalizedMessage(1154592); // You have linked your boat lighthouse.
else
from.SendLocalizedMessage(1154597); // Failed to link to lighthouse.
}
if (boat.IsClassicBoat)
{
uint keyValue = boat.CreateKeys(from);
if (boat.PPlank != null)
boat.PPlank.KeyValue = keyValue;
if (boat.SPlank != null)
boat.SPlank.KeyValue = keyValue;
}
Internalize();
}
else
{
from.SendLocalizedMessage(1043284); // A ship can not be created here.
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Multis
{
public class ConfirmDryDockGump : Gump
{
private Mobile m_From;
private Mobile m_Dockmaster;
private BaseBoat m_Boat;
public ConfirmDryDockGump( Mobile from, BaseBoat boat, Mobile dockmaster ) : base( 150, 200 )
{
m_From = from;
m_Dockmaster = dockmaster;
m_Boat = boat;
m_From.CloseGump( typeof( ConfirmDryDockGump ) );
AddPage( 0 );
AddBackground( 0, 0, 220, 170, 5054 );
AddBackground( 10, 10, 200, 150, 3000 );
bool needsWarning = boat is BaseGalleon && ((BaseGalleon)boat).HasPaint;
//if (needsWarning)
// AddHtml(20, 20, 180, 80, "Do you wish to dry dock this boat?<br>WARNING: You will lose any non-permanent boat paint applied to your galleon.", true, true);
//else
AddHtmlLocalized(20, 20, 180, 80, 1018319, true, needsWarning); // Do you wish to dry dock this boat?
AddHtmlLocalized( 55, 100, 140, 25, 1011011, false, false ); // CONTINUE
AddButton( 20, 100, 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 55, 125, 140, 25, 1011012, false, false ); // CANCEL
AddButton( 20, 125, 4005, 4007, 1, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState state, RelayInfo info )
{
if ( info.ButtonID == 2 )
m_Boat.EndDryDock( m_From, m_Dockmaster );
}
}
}

View File

@@ -0,0 +1,123 @@
using System;
using Server;
using Server.Multis;
using Server.Network;
namespace Server.Items
{
public class Hold : Container
{
public override int LabelNumber { get { return 1149699; } } // cargo hold
[CommandProperty(AccessLevel.GameMaster)]
public BaseBoat Boat { get; private set; }
public override int DefaultMaxWeight { get { return 400; } }
public Hold(BaseBoat boat) : base(0x3EAE)
{
Boat = boat;
Movable = false;
}
public Hold(Serial serial) : base(serial)
{
}
public virtual void SetFacing(Direction dir)
{
switch (dir)
{
case Direction.East: ItemID = 0x3E65; break;
case Direction.West: ItemID = 0x3E93; break;
case Direction.North: ItemID = 0x3EAE; break;
case Direction.South: ItemID = 0x3EB9; break;
}
}
public override bool OnDragDrop(Mobile from, Item item)
{
if (Boat == null || !Boat.Contains(from) || Boat.IsMoving)
return false;
return base.OnDragDrop(from, item);
}
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
{
if (Boat == null || !Boat.Contains(from) || Boat.IsMoving)
return false;
return base.OnDragDropInto(from, item, p);
}
public override bool CheckItemUse(Mobile from, Item item)
{
if (item != this && (Boat == null || !Boat.Contains(from) || Boat.IsMoving))
return false;
return base.CheckItemUse(from, item);
}
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
{
if (Boat == null || !Boat.Contains(from) || Boat.IsMoving)
return false;
return base.CheckLift(from, item, ref reject);
}
public override void OnAfterDelete()
{
if (Boat != null)
Boat.Delete();
}
public override void OnDoubleClick(Mobile from)
{
if (Boat == null || !Boat.Contains(from))
{
if (Boat.TillerMan != null)
Boat.TillerManSay(502490); // You must be on the ship to open the hold.
}
else if (Boat.IsMoving && Boat.IsClassicBoat)
{
if (Boat.TillerMan != null)
Boat.TillerManSay(502491); // I can not open the hold while the ship is moving.
}
else
base.OnDoubleClick(from);
}
public override bool IsDecoContainer { get { return false; } }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(Boat);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 0:
{
Boat = reader.ReadItem() as BaseBoat;
if (Boat == null || Parent != null)
Delete();
Movable = false;
break;
}
}
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class LargeBoat : BaseBoat
{
public override int NorthID{ get{ return 0x10; } }
public override int EastID{ get{ return 0x11; } }
public override int SouthID{ get{ return 0x12; } }
public override int WestID{ get{ return 0x13; } }
public override int HoldDistance{ get{ return 5; } }
public override int TillerManDistance{ get{ return -5; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, -1 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, -1 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 0, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new LargeDockedBoat( this ); } }
[Constructable]
public LargeBoat(Direction d) : base(d, true)
{
}
public LargeBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class LargeBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041209; } } // large ship deed
public override BaseBoat Boat { get { return new LargeBoat(this.BoatDirection); } }
[Constructable]
public LargeBoatDeed() : base( 0x10, new Point3D( 0, -1, 0 ) )
{
}
public LargeBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class LargeDockedBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116745; } } //Large Ship
public override BaseBoat Boat { get { return new LargeBoat(this.BoatDirection); } }
public LargeDockedBoat( BaseBoat boat ) : base( 0x10, new Point3D( 0, -1, 0 ), boat )
{
}
public LargeDockedBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class LargeDragonBoat : BaseBoat
{
public override int NorthID{ get{ return 0x14; } }
public override int EastID{ get{ return 0x15; } }
public override int SouthID{ get{ return 0x16; } }
public override int WestID{ get{ return 0x17; } }
public override int HoldDistance{ get{ return 5; } }
public override int TillerManDistance{ get{ return -5; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, -1 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, -1 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 0, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new LargeDockedDragonBoat( this ); } }
[Constructable]
public LargeDragonBoat(Direction d) : base(d, true)
{
}
public LargeDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class LargeDragonBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041210; } }// large dragon ship deed
public override BaseBoat Boat { get { return new LargeDragonBoat(this.BoatDirection); } }
[Constructable]
public LargeDragonBoatDeed() : base( 0x14, new Point3D( 0, -1, 0 ) )
{
}
public LargeDragonBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class LargeDockedDragonBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116746; } } //Large Dragon Ship
public override BaseBoat Boat{ get{ return new LargeDragonBoat(this.BoatDirection); } }
public LargeDockedDragonBoat( BaseBoat boat ) : base( 0x14, new Point3D( 0, -1, 0 ), boat )
{
}
public LargeDockedDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class MediumBoat : BaseBoat
{
public override int NorthID{ get{ return 0x8; } }
public override int EastID{ get{ return 0x9; } }
public override int SouthID{ get{ return 0xA; } }
public override int WestID{ get{ return 0xB; } }
public override int HoldDistance{ get{ return 4; } }
public override int TillerManDistance{ get{ return -5; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, 0 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, 0 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 1, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new MediumDockedBoat( this ); } }
[Constructable]
public MediumBoat(Direction d) : base(d, true)
{
}
public MediumBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class MediumBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041207; } } // medium ship deed
public override BaseBoat Boat { get { return new MediumBoat(this.BoatDirection); } }
[Constructable]
public MediumBoatDeed() : base( 0x8, Point3D.Zero )
{
}
public MediumBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class MediumDockedBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116743; } } //Medium Ship
public override BaseBoat Boat { get { return new MediumBoat(this.BoatDirection); } }
public MediumDockedBoat( BaseBoat boat ) : base( 0x8, Point3D.Zero, boat )
{
}
public MediumDockedBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class MediumDragonBoat : BaseBoat
{
public override int NorthID{ get{ return 0xC; } }
public override int EastID{ get{ return 0xD; } }
public override int SouthID{ get{ return 0xE; } }
public override int WestID{ get{ return 0xF; } }
public override int HoldDistance{ get{ return 4; } }
public override int TillerManDistance{ get{ return -5; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, 0 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, 0 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 1, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new MediumDockedDragonBoat( this ); } }
[Constructable]
public MediumDragonBoat(Direction d) : base(d, true)
{
}
public MediumDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class MediumDragonBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041208; } } // medium dragon ship deed
public override BaseBoat Boat { get { return new MediumDragonBoat(this.BoatDirection); } }
[Constructable]
public MediumDragonBoatDeed() : base( 0xC, Point3D.Zero )
{
}
public MediumDragonBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class MediumDockedDragonBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116744; } } //Medium Dragon Ship
public override BaseBoat Boat { get { return new MediumDragonBoat(this.BoatDirection); } }
public MediumDockedDragonBoat( BaseBoat boat ) : base( 0xC, Point3D.Zero, boat )
{
}
public MediumDockedDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,353 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Multis;
using Server.ContextMenus;
using Server.Mobiles;
namespace Server.Items
{
public enum PlankSide { Port, Starboard }
public class Plank : Item, ILockable
{
private Timer m_CloseTimer;
public Plank(BaseBoat boat, PlankSide side, uint keyValue)
: base(0x3EB1 + (int)side)
{
Boat = boat;
Side = side;
KeyValue = keyValue;
Locked = true;
Movable = false;
}
public Plank(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);//version
writer.Write(Boat);
writer.Write((int)Side);
writer.Write(Locked);
writer.Write(KeyValue);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 0:
{
Boat = reader.ReadItem() as BaseBoat;
Side = (PlankSide)reader.ReadInt();
Locked = reader.ReadBool();
KeyValue = reader.ReadUInt();
if (Boat == null)
Delete();
break;
}
}
if (IsOpen)
{
m_CloseTimer = new CloseTimer(this);
m_CloseTimer.Start();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public BaseBoat Boat { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public PlankSide Side { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool Locked { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public uint KeyValue { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool IsOpen { get { return ItemID == 0x3ED5 || ItemID == 0x3ED4 || ItemID == 0x3E84 || ItemID == 0x3E89; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Starboard { get { return Side == PlankSide.Starboard; } }
public void SetFacing(Direction dir)
{
if (IsOpen)
{
switch (dir)
{
case Direction.North: ItemID = Starboard ? 0x3ED4 : 0x3ED5; break;
case Direction.East: ItemID = Starboard ? 0x3E84 : 0x3E89; break;
case Direction.South: ItemID = Starboard ? 0x3ED5 : 0x3ED4; break;
case Direction.West: ItemID = Starboard ? 0x3E89 : 0x3E84; break;
}
}
else
{
switch (dir)
{
case Direction.North: ItemID = Starboard ? 0x3EB2 : 0x3EB1; break;
case Direction.East: ItemID = Starboard ? 0x3E85 : 0x3E8A; break;
case Direction.South: ItemID = Starboard ? 0x3EB1 : 0x3EB2; break;
case Direction.West: ItemID = Starboard ? 0x3E8A : 0x3E85; break;
}
}
}
public void Open()
{
if (IsOpen || Deleted)
return;
if (m_CloseTimer != null)
m_CloseTimer.Stop();
if (Locked)
{
m_CloseTimer = new CloseTimer(this);
m_CloseTimer.Start();
}
switch (ItemID)
{
case 0x3EB1: ItemID = 0x3ED5; break;
case 0x3E8A: ItemID = 0x3E89; break;
case 0x3EB2: ItemID = 0x3ED4; break;
case 0x3E85: ItemID = 0x3E84; break;
}
}
public override bool OnMoveOver(Mobile from)
{
if (IsOpen)
{
if (from.Player && Boat != null && !Boat.Contains(from) && Locked) // If the plank is locked, no one can enter the ship from the outside.
return false;
if ((from.Player && (from.Direction & Direction.Running) != 0) || (Boat != null && !Boat.Contains(from)))
return true;
Map map = Map;
if (map == null)
return false;
int rx = 0, ry = 0;
if (ItemID == 0x3ED4)
rx = 1;
else if (ItemID == 0x3ED5)
rx = -1;
else if (ItemID == 0x3E84)
ry = 1;
else if (ItemID == 0x3E89)
ry = -1;
for (int i = 1; i <= 6; ++i)
{
int x = X + (i * rx);
int y = Y + (i * ry);
int z;
for (int j = -8; j <= 8; ++j)
{
z = from.Z + j;
if (map.CanFit(x, y, z, 16, false, false) && !Spells.SpellHelper.CheckMulti(new Point3D(x, y, z), map) && !Region.Find(new Point3D(x, y, z), map).IsPartOf(typeof(Factions.StrongholdRegion)))
{
if (i == 1 && j >= -2 && j <= 2)
return true;
from.Location = new Point3D(x, y, z);
return false;
}
}
z = map.GetAverageZ(x, y);
if (map.CanFit(x, y, z, 16, false, false) && !Spells.SpellHelper.CheckMulti(new Point3D(x, y, z), map) && !Region.Find(new Point3D(x, y, z), map).IsPartOf(typeof(Factions.StrongholdRegion)))
{
if (i == 1)
return true;
from.Location = new Point3D(x, y, z);
return false;
}
}
return true;
}
else
{
return false;
}
}
public bool CanClose()
{
Map map = Map;
if (map == null || Deleted)
return false;
IPooledEnumerable eable = GetObjectsInRange(0);
foreach (object o in eable)
{
if (o != this)
{
eable.Free();
return false;
}
}
eable.Free();
return true;
}
public void Close()
{
if (!IsOpen || !CanClose() || Deleted)
return;
if (m_CloseTimer != null)
m_CloseTimer.Stop();
m_CloseTimer = null;
switch (ItemID)
{
case 0x3ED5: ItemID = 0x3EB1; break;
case 0x3E89: ItemID = 0x3E8A; break;
case 0x3ED4: ItemID = 0x3EB2; break;
case 0x3E84: ItemID = 0x3E85; break;
}
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (!from.Alive && Boat.Contains(from))
{
list.Add(new PlanksContext(from, this));
}
}
public class PlanksContext : ContextMenuEntry
{
private Plank m_Plank;
private Mobile m_From;
public PlanksContext(Mobile from, Plank plank) : base(6132, 10)
{
m_Plank = plank;
m_From = from;
}
public override void OnClick()
{
m_Plank.OnDoubleClick(m_From);
}
}
public override void OnDoubleClickDead(Mobile from)
{
OnDoubleClick(from);
}
public override void OnDoubleClick(Mobile from)
{
if (Boat == null)
return;
Boat.Refresh();
if (BaseBoat.IsDriving(from))
{
from.SendLocalizedMessage(1116610); // You can't do that while piloting a ship!
return;
}
if (from.InRange(GetWorldLocation(), 8))
{
if (Boat.Contains(from))
{
if (IsOpen)
Close();
else
Open();
}
else
{
if (!IsOpen)
{
if (!Locked)
{
Open();
}
else if (from.AccessLevel >= AccessLevel.GameMaster)
{
from.LocalOverheadMessage(Network.MessageType.Regular, 0x00, 502502); // That is locked but your godly powers allow access
Open();
}
else
{
from.LocalOverheadMessage(Network.MessageType.Regular, 0x00, 502503); // That is locked.
}
}
else if (!Locked)
{
Point3D p = new Point3D(X, Y, Z + 3);
BaseCreature.TeleportPets(from, p, Map);
from.Location = p;
}
else if (from.AccessLevel >= AccessLevel.GameMaster)
{
from.LocalOverheadMessage(Network.MessageType.Regular, 0x00, 502502); // That is locked but your godly powers allow access
Point3D p = new Point3D(X, Y, Z + 3);
BaseCreature.TeleportPets(from, p, Map);
from.Location = p;
}
else
{
from.LocalOverheadMessage(Network.MessageType.Regular, 0x00, 502503); // That is locked.
}
}
}
}
private class CloseTimer : Timer
{
private Plank m_Plank;
public CloseTimer(Plank plank)
: base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(5.0))
{
m_Plank = plank;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Plank.Close();
}
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using Server;
using Server.Prompts;
namespace Server.Multis
{
public class RenameBoatPrompt : Prompt
{
public override int MessageCliloc { get { return 502580; } }
private BaseBoat m_Boat;
public RenameBoatPrompt( BaseBoat boat )
{
m_Boat = boat;
}
public override void OnResponse( Mobile from, string text )
{
m_Boat.EndRename( from, text );
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class SmallBoat : BaseBoat
{
public override int NorthID{ get{ return 0x0; } }
public override int EastID{ get{ return 0x1; } }
public override int SouthID{ get{ return 0x2; } }
public override int WestID{ get{ return 0x3; } }
public override int HoldDistance{ get{ return 4; } }
public override int TillerManDistance{ get{ return -4; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, 0 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, 0 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 1, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new SmallDockedBoat( this ); } }
[Constructable]
public SmallBoat(Direction d) : base(d, true)
{
}
public SmallBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class SmallBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041205; } } // small ship deed
public override BaseBoat Boat { get { return new SmallBoat(this.BoatDirection); } }
[Constructable]
public SmallBoatDeed() : base( 0x0, Point3D.Zero )
{
}
public SmallBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class SmallDockedBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116741; } } //Small Ship
public override BaseBoat Boat { get { return new SmallBoat(this.BoatDirection); } }
public SmallDockedBoat( BaseBoat boat ) : base( 0x0, Point3D.Zero, boat )
{
}
public SmallDockedBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using Server;
using Server.Items;
namespace Server.Multis
{
public class SmallDragonBoat : BaseBoat
{
public override int NorthID{ get{ return 0x4; } }
public override int EastID{ get{ return 0x5; } }
public override int SouthID{ get{ return 0x6; } }
public override int WestID{ get{ return 0x7; } }
public override int HoldDistance{ get{ return 4; } }
public override int TillerManDistance{ get{ return -4; } }
public override Point2D StarboardOffset{ get{ return new Point2D( 2, 0 ); } }
public override Point2D PortOffset{ get{ return new Point2D( -2, 0 ); } }
public override Point3D MarkOffset{ get{ return new Point3D( 0, 1, 3 ); } }
public override BaseDockedBoat DockedBoat{ get{ return new SmallDockedDragonBoat( this ); } }
[Constructable]
public SmallDragonBoat(Direction d) : base(d, true)
{
}
public SmallDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class SmallDragonBoatDeed : BaseBoatDeed
{
public override int LabelNumber{ get{ return 1041206; } } // small dragon ship deed
public override BaseBoat Boat { get { return new SmallDragonBoat(this.BoatDirection); } }
[Constructable]
public SmallDragonBoatDeed() : base( 0x4, Point3D.Zero )
{
}
public SmallDragonBoatDeed( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
public class SmallDockedDragonBoat : BaseDockedBoat
{
public override int LabelNumber { get { return 1116742; } } //Small Dragon Ship
public override BaseBoat Boat { get { return new SmallDragonBoat(this.BoatDirection); } }
public SmallDockedDragonBoat( BaseBoat boat ) : base( 0x4, Point3D.Zero, boat )
{
}
public SmallDockedDragonBoat( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
}
}

View File

@@ -0,0 +1,193 @@
using System;
using System.IO;
using Server;
using Server.Multis;
namespace Server.Misc
{
public class Strandedness
{
private static Point2D[] m_Felucca = new Point2D[]
{
new Point2D( 2528, 3568 ), new Point2D( 2376, 3400 ), new Point2D( 2528, 3896 ),
new Point2D( 2168, 3904 ), new Point2D( 1136, 3416 ), new Point2D( 1432, 3648 ),
new Point2D( 1416, 4000 ), new Point2D( 4512, 3936 ), new Point2D( 4440, 3120 ),
new Point2D( 4192, 3672 ), new Point2D( 4720, 3472 ), new Point2D( 3744, 2768 ),
new Point2D( 3480, 2432 ), new Point2D( 3560, 2136 ), new Point2D( 3792, 2112 ),
new Point2D( 2800, 2296 ), new Point2D( 2736, 2016 ), new Point2D( 4576, 1456 ),
new Point2D( 4680, 1152 ), new Point2D( 4304, 1104 ), new Point2D( 4496, 984 ),
new Point2D( 4248, 696 ), new Point2D( 4040, 616 ), new Point2D( 3896, 248 ),
new Point2D( 4176, 384 ), new Point2D( 3672, 1104 ), new Point2D( 3520, 1152 ),
new Point2D( 3720, 1360 ), new Point2D( 2184, 2152 ), new Point2D( 1952, 2088 ),
new Point2D( 2056, 1936 ), new Point2D( 1720, 1992 ), new Point2D( 472, 2064 ),
new Point2D( 656, 2096 ), new Point2D( 3008, 3592 ), new Point2D( 2784, 3472 ),
new Point2D( 5456, 2400 ), new Point2D( 5976, 2424 ), new Point2D( 5328, 3112 ),
new Point2D( 5792, 3152 ), new Point2D( 2120, 3616 ), new Point2D( 2136, 3128 ),
new Point2D( 1632, 3528 ), new Point2D( 1328, 3160 ), new Point2D( 1072, 3136 ),
new Point2D( 1128, 2976 ), new Point2D( 960, 2576 ), new Point2D( 752, 1832 ),
new Point2D( 184, 1488 ), new Point2D( 592, 1440 ), new Point2D( 368, 1216 ),
new Point2D( 232, 752 ), new Point2D( 696, 744 ), new Point2D( 304, 1000 ),
new Point2D( 840, 376 ), new Point2D( 1192, 624 ), new Point2D( 1200, 192 ),
new Point2D( 1512, 240 ), new Point2D( 1336, 456 ), new Point2D( 1536, 648 ),
new Point2D( 1104, 952 ), new Point2D( 1864, 264 ), new Point2D( 2136, 200 ),
new Point2D( 2160, 528 ), new Point2D( 1904, 512 ), new Point2D( 2240, 784 ),
new Point2D( 2536, 776 ), new Point2D( 2488, 216 ), new Point2D( 2336, 72 ),
new Point2D( 2648, 288 ), new Point2D( 2680, 576 ), new Point2D( 2896, 88 ),
new Point2D( 2840, 344 ), new Point2D( 3136, 72 ), new Point2D( 2968, 520 ),
new Point2D( 3192, 328 ), new Point2D( 3448, 208 ), new Point2D( 3432, 608 ),
new Point2D( 3184, 752 ), new Point2D( 2800, 704 ), new Point2D( 2768, 1016 ),
new Point2D( 2448, 1232 ), new Point2D( 2272, 920 ), new Point2D( 2072, 1080 ),
new Point2D( 2048, 1264 ), new Point2D( 1808, 1528 ), new Point2D( 1496, 1880 ),
new Point2D( 1656, 2168 ), new Point2D( 2096, 2320 ), new Point2D( 1816, 2528 ),
new Point2D( 1840, 2640 ), new Point2D( 1928, 2952 ), new Point2D( 2120, 2712 ),
new Point2D( 4551, 2345 )
};
private static Point2D[] m_Trammel = m_Felucca;
private static Point2D[] m_Ilshenar = new Point2D[]
{
new Point2D( 1252, 1180 ), new Point2D( 1562, 1090 ), new Point2D( 1444, 1016 ),
new Point2D( 1324, 968 ), new Point2D( 1418, 806 ), new Point2D( 1722, 874 ),
new Point2D( 1456, 684 ), new Point2D( 1036, 866 ), new Point2D( 612, 476 ),
new Point2D( 1476, 372 ), new Point2D( 762, 472 ), new Point2D( 812, 1162 ),
new Point2D( 1422, 1144 ), new Point2D( 1254, 1066 ), new Point2D( 1598, 870 ),
new Point2D( 1358, 866 ), new Point2D( 510, 302 ), new Point2D( 510, 392 )
};
private static Point2D[] m_Tokuno = new Point2D[]
{
//Makoto-Jima
new Point2D( 837, 1351 ), new Point2D( 941, 1241 ), new Point2D( 959, 1185 ),
new Point2D( 923, 1091 ), new Point2D( 904, 983 ), new Point2D( 845, 944 ),
new Point2D( 829, 896 ), new Point2D( 794, 852 ), new Point2D( 766, 821 ),
new Point2D( 695, 814 ), new Point2D( 576, 835 ), new Point2D( 518, 840 ),
new Point2D( 519, 902 ), new Point2D( 502, 950 ), new Point2D( 503, 1045 ),
new Point2D( 547, 1131 ), new Point2D( 518, 1204 ), new Point2D( 506, 1243 ),
new Point2D( 526, 1271 ), new Point2D( 562, 1295 ), new Point2D( 616, 1335 ),
new Point2D( 789, 1347 ), new Point2D( 712, 1359 ),
//Homare-Jima
new Point2D( 202, 498 ), new Point2D( 116, 600 ), new Point2D( 107, 699 ),
new Point2D( 162, 799 ), new Point2D( 158, 889 ), new Point2D( 169, 989 ),
new Point2D( 194, 1101 ), new Point2D( 250, 1163 ), new Point2D( 295, 1176 ),
new Point2D( 280, 1194 ), new Point2D( 286, 1102 ), new Point2D( 250, 1000 ),
new Point2D( 260, 906 ), new Point2D( 360, 838 ), new Point2D( 389, 763 ),
new Point2D( 415, 662 ), new Point2D( 500, 597 ), new Point2D( 570, 572 ),
new Point2D( 631, 577 ), new Point2D( 692, 500 ), new Point2D( 723, 445 ),
new Point2D( 672, 379 ), new Point2D( 626, 332 ), new Point2D( 494, 291 ),
new Point2D( 371, 336 ), new Point2D( 324, 334 ), new Point2D( 270, 362 ),
//Isamu-Jima
new Point2D( 1240, 1076 ), new Point2D( 1189, 1115 ), new Point2D( 1046, 1039 ),
new Point2D( 1025, 885 ), new Point2D( 907, 809 ), new Point2D( 840, 506 ),
new Point2D( 799, 396 ), new Point2D( 720, 258 ), new Point2D( 744, 158 ),
new Point2D( 904, 37 ), new Point2D( 974, 91 ), new Point2D( 1020, 187 ),
new Point2D( 1035, 288 ), new Point2D( 1104, 395 ), new Point2D( 1215, 462 ),
new Point2D( 1275, 488 ), new Point2D( 1348, 611 ), new Point2D( 1363, 739 ),
new Point2D( 1364, 765 ), new Point2D( 1364, 876 ), new Point2D( 1300, 936 ),
new Point2D( 1240, 1003 )
};
public static void Initialize()
{
EventSink.Login += new LoginEventHandler( EventSink_Login );
}
private static bool IsStranded( Mobile from )
{
Map map = from.Map;
if ( map == null || from.AccessLevel > AccessLevel.Player )
return false;
BaseBoat boat = BaseBoat.FindBoatAt(from, map);
if(boat != null && !boat.Deleted)
return false;
object surface = map.GetTopSurface( from.Location );
if ( surface is LandTile )
{
int id = ((LandTile)surface).ID;
return (id >= 168 && id <= 171)
|| (id >= 310 && id <= 311);
}
else if ( surface is StaticTile )
{
int id = ((StaticTile)surface).ID;
return (id >= 0x1796 && id <= 0x17B2);
}
return false;
}
public static void EventSink_Login( LoginEventArgs e )
{
Mobile from = e.Mobile;
if ( !IsStranded( from ) )
return;
Map map = from.Map;
Point2D[] list;
if( map == Map.Felucca )
list = m_Felucca;
else if( map == Map.Trammel )
list = m_Trammel;
else if( map == Map.Ilshenar )
list = m_Ilshenar;
else if( map == Map.Tokuno )
list = m_Tokuno;
else
return;
Point2D p = Point2D.Zero;
double pdist = double.MaxValue;
for ( int i = 0; i < list.Length; ++i )
{
double dist = from.GetDistanceToSqrt( list[i] );
if ( dist < pdist )
{
p = list[i];
pdist = dist;
}
}
int x = p.X, y = p.Y;
int z;
bool canFit = false;
z = map.GetAverageZ( x, y );
canFit = map.CanSpawnMobile( x, y, z );
for ( int i = 1; !canFit && i <= 40; i += 2 )
{
for ( int xo = -1; !canFit && xo <= 1; ++xo )
{
for ( int yo = -1; !canFit && yo <= 1; ++yo )
{
if ( xo == 0 && yo == 0 )
continue;
x = p.X + (xo * i);
y = p.Y + (yo * i);
z = map.GetAverageZ( x, y );
canFit = map.CanSpawnMobile( x, y, z );
}
}
}
if ( canFit )
from.Location = new Point3D( x, y, z );
}
}
}

View File

@@ -0,0 +1,297 @@
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.ContextMenus;
using System.Collections.Generic;
namespace Server.Items
{
public class TillerMan : Item
{
public virtual bool Babbles { get { return true; } }
public BaseBoat Boat { get; private set; }
private DateTime _NextBabble;
public TillerMan(BaseBoat boat)
: base(0x3E4E)
{
Boat = boat;
Movable = false;
}
public TillerMan(Serial serial)
: base(serial)
{
}
public virtual void SetFacing(Direction dir)
{
switch (dir)
{
case Direction.South: ItemID = 0x3E4B; break;
case Direction.North: ItemID = 0x3E4E; break;
case Direction.West: ItemID = 0x3E50; break;
case Direction.East: ItemID = 0x3E55; break; //Issue 99. Was Using Incorrect Graphic.
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (Boat.IsRowBoat)
return;
list.Add(Boat.Status);
list.Add(1116580 + (int)Boat.DamageTaken); //State: Prisine
}
public virtual void Say(int number)
{
PublicOverheadMessage(MessageType.Regular, 0x3B2, number);
}
public virtual void Say(int number, string args)
{
PublicOverheadMessage(MessageType.Regular, 0x3B2, number, args);
}
public override void AddNameProperty(ObjectPropertyList list)
{
if (Boat != null && Boat.ShipName != null)
list.Add(1042884, Boat.ShipName); // the tiller man of the ~1_SHIP_NAME~
else
base.AddNameProperty(list);
}
public override void OnSingleClick(Mobile from)
{
if (Boat != null && Boat.ShipName != null)
LabelTo(from, 1042884, Boat.ShipName); // the tiller man of the ~1_SHIP_NAME~
else
base.OnSingleClick(from);
}
public Mobile Pilot { get { return Boat != null ? Boat.Pilot : null; } }
public override void OnDoubleClickDead(Mobile m)
{
OnDoubleClick(m);
}
public override void OnDoubleClick(Mobile from)
{
from.RevealingAction();
BaseBoat boat = BaseBoat.FindBoatAt(from, from.Map);
Item mount = from.FindItemOnLayer(Layer.Mount);
if (boat == null || Boat == null || Boat != boat)
{
from.SendLocalizedMessage(1116724); // You cannot pilot a ship unless you are aboard it!
}
else if (Pilot != null && Pilot != from && Pilot == Boat.Owner)
{
from.SendLocalizedMessage(502221); // Someone else is already using this item.
}
else if (from.Flying)
{
from.SendLocalizedMessage(1116615); // You cannot pilot a ship while flying!
}
else if (from.Mounted && !(mount is BoatMountItem))
{
from.SendLocalizedMessage(1010097); // You cannot use this while mounted or flying.
}
else if (Pilot == null && Boat.Scuttled)
{
from.SendLocalizedMessage(1116725); // This ship is too damaged to sail!
}
else if (Pilot != null)
{
if (from != Pilot) // High authorized player takes control of the ship
{
boat.RemovePilot(from);
boat.LockPilot(from);
}
else
{
boat.RemovePilot(from);
}
}
else
{
boat.LockPilot(from);
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is MapItem && Boat != null && Boat.CanCommand(from) && Boat.Contains(from))
{
Boat.AssociateMap((MapItem)dropped);
}
return false;
}
public override void OnAfterDelete()
{
if (Boat != null)
Boat.Delete();
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (Boat.IsRowBoat)
return;
if (Boat != null)
{
if (Boat.Contains(from))
{
if (Boat.IsOwner(from))
list.Add(new RenameShipEntry(this, from));
list.Add(new EmergencyRepairEntry(this, from));
list.Add(new ShipRepairEntry(this, from));
}
else if (Boat.IsOwner(from))
{
list.Add(new DryDockEntry(Boat, from));
}
}
}
public void Babble()
{
if (Babbles)
{
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1114137, RandomBabbleArgs());
// Ar! Did I ever tell thee about the time I was in ~1_CITY~ and I met ~2_GENDER~ ~3_STORY~ Anyway, 'tis a dull story.
_NextBabble = DateTime.UtcNow + TimeSpan.FromMinutes(Utility.RandomMinMax(3, 10));
}
}
private string RandomBabbleArgs()
{
return string.Format("#{0}\t#{1}\t#{2}", Utility.Random(1114138, 13).ToString(),
Utility.Random(1114151, 2).ToString(),
Utility.RandomMinMax(1114153, 1114221).ToString());
}
public override void OnLocationChange(Point3D oldLocation)
{
if (_NextBabble < DateTime.UtcNow && 0.1 > Utility.RandomDouble())
{
Babble();
}
}
private class EmergencyRepairEntry : ContextMenuEntry
{
private TillerMan m_TillerMan;
private Mobile m_From;
public EmergencyRepairEntry(TillerMan tillerman, Mobile from)
: base(1116589, 5)
{
m_TillerMan = tillerman;
m_From = from;
}
public override void OnClick()
{
if (m_TillerMan != null && m_TillerMan.Boat != null)
{
BaseBoat g = m_TillerMan.Boat;
if (!g.Scuttled)
m_From.SendLocalizedMessage(1116595); //Your ship is not in need of emergency repairs in order to sail.
else if (g.IsUnderEmergencyRepairs())
{
TimeSpan left = g.GetEndEmergencyRepairs();
m_From.SendLocalizedMessage(1116592, left != TimeSpan.Zero ? left.TotalMinutes.ToString() : "0"); //Your ship is underway with emergency repairs holding for an estimated ~1_TIME~ more minutes.
}
else if (!g.TryEmergencyRepair(m_From))
m_From.SendLocalizedMessage(1116591, String.Format("{0}\t{1}", BaseGalleon.EmergencyRepairClothCost.ToString(), BaseGalleon.EmergencyRepairWoodCost)); //You need a minimum of ~1_CLOTH~ yards of cloth and ~2_WOOD~ pieces of lumber to effect emergency repairs.
}
}
}
private class ShipRepairEntry : ContextMenuEntry
{
private TillerMan m_TillerMan;
private Mobile m_From;
public ShipRepairEntry(TillerMan tillerman, Mobile from)
: base(1116590, 5)
{
m_TillerMan = tillerman;
m_From = from;
}
public override void OnClick()
{
if (m_TillerMan != null && m_TillerMan.Boat != null)
{
if (!BaseGalleon.IsNearLandOrDocks(m_TillerMan.Boat))
m_From.SendLocalizedMessage(1116594); //Your ship must be near shore or a sea market in order to effect permanent repairs.
else if (m_TillerMan.Boat.DamageTaken == DamageLevel.Pristine)
m_From.SendLocalizedMessage(1116596); //Your ship is in pristine condition and does not need repairs.
else
m_TillerMan.Boat.TryRepairs(m_From);
}
}
}
private class RenameShipEntry : ContextMenuEntry
{
private TillerMan m_TillerMan;
private readonly Mobile m_From;
public RenameShipEntry(TillerMan tillerman, Mobile from)
: base(1111680, 3)
{
m_TillerMan = tillerman;
m_From = from;
}
public override void OnClick()
{
if (m_TillerMan != null && m_TillerMan.Boat != null)
m_TillerMan.Boat.BeginRename(m_From);
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);//version
writer.Write(Boat);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 0:
{
Boat = reader.ReadItem() as BaseBoat;
if (Boat == null)
Delete();
break;
}
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class BankerCamp : BaseCamp
{
[Constructable]
public BankerCamp()
: base(0x1F6)
{
Visible = true;
}
public BankerCamp(Serial serial)
: base(serial)
{
}
public override void AddComponents()
{
BaseDoor west, east;
this.AddItem(west = new LightWoodGate(DoorFacing.WestCW), -4, 4, 7);
this.AddItem(east = new LightWoodGate(DoorFacing.EastCCW), -3, 4, 7);
west.Link = east;
east.Link = west;
this.AddItem(new Sign(SignType.Bank, SignFacing.West), -5, 5, -4);
this.AddMobile(new Banker(), -4, 3, 7);
this.AddMobile(new Banker(), 4, -2, 0);
SetDecayTime();
}
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,335 @@
using System;
using System.Collections.Generic;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public abstract class BaseCamp : BaseMulti
{
public static void Initialize()
{
Timer.DelayCall(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), OnTick);
}
public static List<BaseCamp> _Camps = new List<BaseCamp>();
private List<Item> m_Items;
private List<Mobile> m_Mobiles;
[CommandProperty(AccessLevel.GameMaster)]
public DateTime TimeOfDecay { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public BaseCreature Prisoner { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public BaseContainer Treasure1 { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public BaseContainer Treasure2 { get; set; }
public override bool HandlesOnMovement
{
get { return true; }
}
[CommandProperty(AccessLevel.GameMaster)]
public virtual TimeSpan DecayDelay { get { return TimeSpan.FromMinutes(30.0); } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Decaying { get { return TimeOfDecay != DateTime.MinValue; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool ForceDecay
{
get { return false; }
set { SetDecayTime(); }
}
[CommandProperty(AccessLevel.GameMaster)]
public bool RestrictDecay { get; set; }
public BaseCamp(int multiID)
: base(multiID)
{
m_Items = new List<Item>();
m_Mobiles = new List<Mobile>();
Visible = false;
CheckAddComponents();
_Camps.Add(this);
}
public BaseCamp(Serial serial)
: base(serial)
{
}
public virtual int EventRange
{
get
{
return 10;
}
}
public void CheckAddComponents()
{
if (Deleted)
return;
AddComponents();
}
public virtual void AddComponents()
{
}
public virtual void CheckDecay()
{
if (RestrictDecay)
return;
if (!Decaying)
{
if (((Treasure1 == null || Treasure1.Items.Count == 0) && (Treasure2 == null || Treasure2.Items.Count == 0)) ||
(Prisoner != null && (Prisoner.Deleted || !Prisoner.CantWalk)))
{
SetDecayTime();
}
}
else if(TimeOfDecay < DateTime.UtcNow)
{
Delete();
}
}
public virtual void SetDecayTime()
{
if (Deleted || RestrictDecay)
return;
TimeOfDecay = DateTime.UtcNow + DecayDelay;
}
public virtual void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (Map == null)
return;
m_Items.Add(item);
int zavg = this.Map.GetAverageZ(X + xOffset, Y + yOffset);
if (!Map.CanFit(X + xOffset, Y + yOffset, zavg, item.ItemData.Height))
{
for (int z = 1; z <= 39; z++)
{
if (Map.CanFit(X + xOffset, Y + yOffset, zavg + z, item.ItemData.Height))
{
zavg += z;
break;
}
}
}
item.MoveToWorld(new Point3D(X + xOffset, Y + yOffset, zavg + zOffset), Map);
}
public virtual void AddMobile(Mobile m, int xOffset, int yOffset, int zOffset)
{
if (Map == null)
return;
if(!m_Mobiles.Contains(m))
m_Mobiles.Add(m);
int zavg = Map.GetAverageZ(X + xOffset, Y + yOffset);
if (!Map.CanSpawnMobile(X + xOffset, Y + yOffset, zavg))
{
for (int z = 1; z <= 39; z++)
{
if (Map.CanSpawnMobile(X + xOffset, Y + yOffset, zavg + z))
{
zavg += z;
break;
}
}
}
m.MoveToWorld(new Point3D(X + xOffset, Y + yOffset, zavg + zOffset), Map);
SetCreature(m as BaseCreature);
}
private void SetCreature(BaseCreature bc)
{
if (bc != null)
{
//int zavg = Map.GetAverageZ(bc.X, bc.Y);
IPoint3D p = bc.Location; //new Point3D(bc.X, bc.Y, zavg);
Server.Spells.SpellHelper.GetSurfaceTop(ref p);
Point3D loc = new Point3D(p);
bc.RangeHome = bc.IsPrisoner ? 0 : 6;
bc.Home = loc;
if (bc.Location != loc)
bc.Location = loc;
if (bc is BaseVendor || bc is Banker)
bc.Direction = Direction.South;
}
}
public virtual void OnEnter(Mobile m)
{
}
public virtual void OnExit(Mobile m)
{
}
public override void OnLocationChange(Point3D old)
{
foreach (var item in m_Items)
{
item.Location = new Point3D(X + (item.X - old.X), Y + (item.Y - old.Y), Z + (item.Z - old.Z));
}
foreach (var m in m_Mobiles)
{
m.Location = new Point3D(X + (m.X - old.X), Y + (m.Y - old.Y), Z + (m.Z - old.Z));
SetCreature(m as BaseCreature);
}
}
public override void OnMapChange()
{
foreach (var item in m_Items)
{
item.Map = Map;
}
foreach (var m in m_Mobiles)
{
m.Map = Map;
}
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
bool inOldRange = Utility.InRange(oldLocation, Location, EventRange);
bool inNewRange = Utility.InRange(m.Location, Location, EventRange);
if (inNewRange && !inOldRange)
OnEnter(m);
else if (inOldRange && !inNewRange)
OnExit(m);
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
for (int i = 0; i < m_Items.Count; ++i)
m_Items[i].Delete();
for (int i = 0; i < m_Mobiles.Count; ++i)
{
BaseCreature bc = (BaseCreature)m_Mobiles[i];
if (!bc.IsPrisoner)
m_Mobiles[i].Delete();
else if (m_Mobiles[i].CantWalk)
m_Mobiles[i].Delete();
}
m_Items.Clear();
m_Mobiles.Clear();
_Camps.Remove(this);
}
protected virtual void AddCampChests()
{
Treasure1 = new TreasureLevel1();
((TreasureLevel1)Treasure1).Locked = false;
AddItem(Treasure1, 2, 2, 0);
Treasure2 = new TreasureLevel3();
AddItem(Treasure2, -2, -2, 0);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)2); // version
writer.Write(Prisoner);
writer.Write(Treasure1);
writer.Write(Treasure2);
writer.Write(m_Items, true);
writer.Write(m_Mobiles, true);
writer.WriteDeltaTime(TimeOfDecay);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 2:
{
Prisoner = reader.ReadMobile() as BaseCreature;
Treasure1 = reader.ReadItem() as BaseContainer;
Treasure2 = reader.ReadItem() as BaseContainer;
goto case 0;
}
case 1:
case 0:
{
m_Items = reader.ReadStrongItemList();
m_Mobiles = reader.ReadStrongMobileList();
TimeOfDecay = reader.ReadDeltaTime();
break;
}
}
if (version == 0 && ItemID == 0x10EE)
{
ItemID = 0x1F6D;
}
if (version == 1)
Delete();
if (Prisoner != null)
Prisoner.IsPrisoner = true;
_Camps.Add(this);
}
public static void OnTick()
{
List<BaseCamp> list = new List<BaseCamp>(_Camps);
list.ForEach(c =>
{
if (!c.Deleted && c.Map != null && c.Map != Map.Internal && !c.RestrictDecay)
c.CheckDecay();
});
ColUtility.Free(list);
}
}
}

View File

@@ -0,0 +1,160 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class BrigandCamp : BaseCamp
{
[Constructable]
public BrigandCamp()
: base(0x1F6D)
{
}
public BrigandCamp(Serial serial)
: base(serial)
{
}
public virtual Mobile Brigands
{
get
{
return new Brigand();
}
}
public virtual Mobile Executioners
{
get
{
return new Executioner();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public override TimeSpan DecayDelay { get { return TimeSpan.FromMinutes(5.0); } }
public override void AddComponents()
{
Visible = false;
AddItem(new Static(0x10ee), 0, 0, 0);
AddItem(new Static(0xfac), 0, 7, 0);
switch ( Utility.Random(3) )
{
case 0:
{
AddItem(new Item(0xDE3), 0, 7, 0); // Campfire
AddItem(new Item(0x974), 0, 7, 1); // Cauldron
break;
}
case 1:
{
AddItem(new Item(0x1E95), 0, 7, 1); // Rabbit on a spit
break;
}
default:
{
AddItem(new Item(0x1E94), 0, 7, 1); // Chicken on a spit
break;
}
}
AddCampChests();
for (int i = 0; i < 4; i ++)
{
AddMobile(Brigands, Utility.RandomMinMax(-7, 7), Utility.RandomMinMax(-7, 7), 0);
}
switch ( Utility.Random(2) )
{
case 0:
Prisoner = new Noble();
break;
default:
Prisoner = new SeekerOfAdventure();
break;
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Prisoner.YellHue = Utility.RandomList(0x57, 0x67, 0x77, 0x87, 0x117);
AddMobile(Prisoner, Utility.RandomMinMax(-2, 2), Utility.RandomMinMax(-2, 2), 0);
}
// Don't refresh decay timer
public override void OnEnter(Mobile m)
{
if (m.Player && Prisoner != null && Prisoner.CantWalk)
{
int number;
switch ( Utility.Random(8) )
{
case 0:
number = 502261;
break; // HELP!
case 1:
number = 502262;
break; // Help me!
case 2:
number = 502263;
break; // Canst thou aid me?!
case 3:
number = 502264;
break; // Help a poor prisoner!
case 4:
number = 502265;
break; // Help! Please!
case 5:
number = 502266;
break; // Aaah! Help me!
case 6:
number = 502267;
break; // Go and get some help!
default:
number = 502268;
break; // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
}
Prisoner.Yell(number);
}
}
public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (item != null)
item.Movable = false;
base.AddItem(item, xOffset, yOffset, zOffset);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 1: break;
case 0:
{
Prisoner = reader.ReadMobile() as BaseCreature;
break;
}
}
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using Server.Mobiles;
namespace Server.Multis
{
public class ElfBrigandCamp : BrigandCamp
{
[Constructable]
public ElfBrigandCamp()
: base()
{
}
public ElfBrigandCamp(Serial serial)
: base(serial)
{
}
public override Mobile Brigands
{
get
{
return new ElfBrigand();
}
}
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,52 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class HealerCamp : BaseCamp
{
[Constructable]
public HealerCamp()
: base(0x1F4)
{
}
public HealerCamp(Serial serial)
: base(serial)
{
}
public override void AddComponents()
{
BaseDoor west, east;
this.AddItem(west = new LightWoodGate(DoorFacing.WestCW), -4, 4, 7);
this.AddItem(east = new LightWoodGate(DoorFacing.EastCCW), -3, 4, 7);
west.Link = east;
east.Link = west;
this.AddItem(new Sign(SignType.Healer, SignFacing.West), -5, 5, -4);
this.AddMobile(new Healer(), -4, 3, 7);
this.AddMobile(new Healer(), 4, -2, 0);
SetDecayTime();
}
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,187 @@
/*using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class HumanBrigandCamp : BaseCamp
{
[Constructable]
public HumanBrigandCamp()
: base(0x1F6D)
{
}
public HumanBrigandCamp(Serial serial)
: base(serial)
{
}
public virtual Mobile Camper
{
get
{
return new HumanBrigand();
}
}
public override void AddComponents()
{
AddItem(new Item(0xFAC), 0, 0, 0); // fire pit
AddItem(new Item(0xDE3), 0, 0, 0); // camp fire
AddItem(new Item(0x974), 0, 0, 1); // cauldron
for (int i = 0; i < 2; i ++)
{
LockableContainer cont = null;
switch ( Utility.Random(3) )
{
case 0:
cont = new MetalChest();
break;
case 1:
cont = new WoodenChest();
break;
case 2:
cont = new SmallCrate();
break;
}
cont.Movable = false;
cont.Locked = true;
cont.TrapType = TrapType.ExplosionTrap;
cont.TrapPower = Utility.RandomMinMax(30, 40);
cont.TrapLevel = 2;
cont.RequiredSkill = 76;
cont.LockLevel = 66;
cont.MaxLockLevel = 116;
cont.DropItem(new Gold(Utility.RandomMinMax(100, 400)));
cont.DropItem(new Arrow(10));
cont.DropItem(new Bolt(10));
if (Utility.RandomDouble() < 0.8)
{
switch ( Utility.Random(4) )
{
case 0:
cont.DropItem(new LesserCurePotion());
break;
case 1:
cont.DropItem(new LesserExplosionPotion());
break;
case 2:
cont.DropItem(new LesserHealPotion());
break;
case 3:
cont.DropItem(new LesserPoisonPotion());
break;
}
}
if (Utility.RandomDouble() < 0.5)
{
Item item = Loot.RandomArmorOrShieldOrWeapon();
if (item is BaseWeapon)
BaseRunicTool.ApplyAttributesTo((BaseWeapon)item, false, 0, Utility.RandomMinMax(1, 5), 10, 100);
else if (item is BaseArmor)
BaseRunicTool.ApplyAttributesTo((BaseArmor)item, false, 0, Utility.RandomMinMax(1, 5), 10, 100);
cont.DropItem(item);
}
Point3D loc = GetRandomSpawnPoint(3);
AddItem(cont, loc.X, loc.Y, loc.Z);
Treasure1 = cont;
}
switch ( Utility.Random(2) )
{
case 0:
Prisoner = new Noble();
break;
case 1:
Prisoner = new SeekerOfAdventure();
break;
}
for (int i = 0; i < 4; i ++)
{
Point3D loc = GetRandomSpawnPoint(5);
AddMobile(Camper,loc.X, loc.Y, loc.Z);
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Point3D p = GetRandomSpawnPoint(3);
AddMobile(Prisoner, p.X, p.Y, p.Z);
}
public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (item != null)
item.Movable = false;
base.AddItem(item, xOffset, yOffset, zOffset);
}
public virtual Point3D GetRandomSpawnPoint(int range)
{
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((range * 2) + 1) - range);
int y = Location.Y + (Utility.Random((range * 2) + 1) - range);
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 override void OnEnter(Mobile m)
{
base.OnEnter(m);
if (m.Player && Prisoner != null)
{
Prisoner.Yell(Utility.RandomMinMax(502261, 502268));
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1: break;
case 0:
Prisoner = reader.ReadMobile() as BaseCreature;
break;
}
}
}
}*/

View File

@@ -0,0 +1,152 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class LizardmenCamp : BaseCamp
{
[Constructable]
public LizardmenCamp()
: base(0x1F6D)
{
}
public LizardmenCamp(Serial serial)
: base(serial)
{
}
public virtual Mobile Lizardmen
{
get
{
return new Lizardman();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public override TimeSpan DecayDelay { get { return TimeSpan.FromMinutes(5.0); } }
public override void AddComponents()
{
AddItem(new Static(0x10ee), 0, 0, 0);
AddItem(new Static(0xfac), 0, 7, 0);
switch ( Utility.Random(3) )
{
case 0:
{
AddItem(new Item(0xDE3), 0, 7, 0); // Campfire
AddItem(new Item(0x974), 0, 7, 1); // Cauldron
break;
}
case 1:
{
AddItem(new Item(0x1E95), 0, 7, 1); // Rabbit on a spit
break;
}
default:
{
AddItem(new Item(0x1E94), 0, 7, 1); // Chicken on a spit
break;
}
}
AddItem(new Item(0x41F), 4, 4, 0); // Gruesome Standart South
AddCampChests();
for (int i = 0; i < 4; i ++)
{
AddMobile(Lizardmen, Utility.RandomMinMax(-7, 7), Utility.RandomMinMax(-7, 7), 0);
}
switch ( Utility.Random(2) )
{
case 0:
Prisoner = new Noble();
break;
default:
Prisoner = new SeekerOfAdventure();
break;
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Prisoner.YellHue = Utility.RandomList(0x57, 0x67, 0x77, 0x87, 0x117);
AddMobile(Prisoner, Utility.RandomMinMax(-2, 2), Utility.RandomMinMax(-2, 2), 0);
}
// Don't refresh decay timer
public override void OnEnter(Mobile m)
{
if (m.Player && Prisoner != null && Prisoner.CantWalk)
{
int number;
switch ( Utility.Random(8) )
{
case 0:
number = 502261;
break; // HELP!
case 1:
number = 502262;
break; // Help me!
case 2:
number = 502263;
break; // Canst thou aid me?!
case 3:
number = 502264;
break; // Help a poor prisoner!
case 4:
number = 502265;
break; // Help! Please!
case 5:
number = 502266;
break; // Aaah! Help me!
case 6:
number = 502267;
break; // Go and get some help!
default:
number = 502268;
break; // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
}
Prisoner.Yell(number);
}
}
public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (item != null)
item.Movable = false;
base.AddItem(item, xOffset, yOffset, zOffset);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 1:
break;
case 0:
{
Prisoner = reader.ReadMobile() as BaseCreature;
break;
}
}
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class MageCamp : BaseCamp
{
[Constructable]
public MageCamp()
: base(0x1F5)
{
}
public MageCamp(Serial serial)
: base(serial)
{
}
public override void AddComponents()
{
BaseDoor west, east;
AddItem(west = new LightWoodGate(DoorFacing.WestCW), -4, 4, 7);
AddItem(east = new LightWoodGate(DoorFacing.EastCCW), -3, 4, 7);
west.Link = east;
east.Link = west;
AddItem(new Sign(SignType.Mage, SignFacing.West), -5, 5, -4);
AddMobile(new Mage(), -4, 3, 7);
AddMobile(new Mage(), 4, -2, 0);
SetDecayTime();
}
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,164 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class OrcCamp : BaseCamp
{
[Constructable]
public OrcCamp()
: base(0x1F6D)
{
}
public OrcCamp(Serial serial)
: base(serial)
{
}
public virtual Mobile Orcs
{
get
{
return new Orc();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public override TimeSpan DecayDelay { get { return TimeSpan.FromMinutes(5.0); } }
public override void AddComponents()
{
Visible = false;
AddItem(new Static(0x10ee), 0, 0, 0);
AddItem(new Static(0xfac), 0, 7, 0);
switch ( Utility.Random(3) )
{
case 0:
{
AddItem(new Item(0xDE3), 0, 7, 0); // Campfire
AddItem(new Item(0x974), 0, 7, 1); // Cauldron
break;
}
case 1:
{
AddItem(new Item(0x1E95), 0, 7, 1); // Rabbit on a spit
break;
}
default:
{
AddItem(new Item(0x1E94), 0, 7, 1); // Chicken on a spit
break;
}
}
AddItem(new Item(0x428), -5, -4, 0); // Gruesome Standart West
AddCampChests();
for (int i = 0; i < 3; i ++)
{
AddMobile(Orcs, Utility.RandomMinMax(-7, 7), Utility.RandomMinMax(-7, 7), 0);
}
AddMobile(new OrcCaptain(), Utility.RandomMinMax(-7, 7), Utility.RandomMinMax(-7, 7), 0);
switch ( Utility.Random(2) )
{
case 0:
Prisoner = new Noble();
break;
default:
Prisoner = new SeekerOfAdventure();
break;
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Prisoner.YellHue = Utility.RandomList(0x57, 0x67, 0x77, 0x87, 0x117);
AddMobile(Prisoner, Utility.RandomMinMax(-2, 2), Utility.RandomMinMax(-2, 2), 0);
}
// Don't refresh decay timer
public override void OnEnter(Mobile m)
{
if (m.Player && Prisoner != null && Prisoner.CantWalk)
{
int number;
switch ( Utility.Random(8) )
{
case 0:
number = 502261;
break; // HELP!
case 1:
number = 502262;
break; // Help me!
case 2:
number = 502263;
break; // Canst thou aid me?!
case 3:
number = 502264;
break; // Help a poor prisoner!
case 4:
number = 502265;
break; // Help! Please!
case 5:
number = 502266;
break; // Aaah! Help me!
case 6:
number = 502267;
break; // Go and get some help!
default:
number = 502268;
break; // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
}
Prisoner.Yell(number);
}
}
// Don't refresh decay timer
public override void OnExit(Mobile m)
{
}
public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (item != null)
item.Movable = false;
base.AddItem(item, xOffset, yOffset, zOffset);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)2); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 2: break;
case 1:
{
Prisoner = reader.ReadMobile() as BaseCreature;
break;
}
case 0:
{
Prisoner = reader.ReadMobile() as BaseCreature;
reader.ReadItem();
break;
}
}
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class PrisonerCamp : BaseCamp
{
private BaseDoor m_Gate;
[Constructable]
public PrisonerCamp() : base( 0x1D4C )
{
}
public override void AddComponents()
{
IronGate gate = new IronGate( DoorFacing.EastCCW );
m_Gate = gate;
gate.KeyValue = Key.RandomValue();
gate.Locked = true;
AddItem( gate, -2, 1, 0 );
AddCampChests();
switch (Utility.Random(4))
{
case 0:
{
AddMobile(new Orc(), 0, -2, 0);
AddMobile(new OrcishMage(), 0, 1, 0);
AddMobile(new OrcishLord(), 0, -2, 0);
AddMobile(new OrcCaptain(), 0, 1, 0);
AddMobile(new Orc(), 0, -1, 0);
AddMobile(new OrcChopper(), 0, -2, 0);
} break;
case 1:
{
AddMobile(new Ratman(), 0, -2, 0);
AddMobile(new Ratman(), 0, 1, 0);
AddMobile(new RatmanMage(), 0, -2, 0);
AddMobile(new Ratman(), 0, 1, 0);
AddMobile(new RatmanArcher(), 0, -1, 0);
AddMobile(new Ratman(), 0, -2, 0);
} break;
case 2:
{
AddMobile(new Lizardman(), 0, -2, 0);
AddMobile(new Lizardman(), 0, 1, 0);
AddMobile(new Lizardman(), 0, -2, 0);
AddMobile(new Lizardman(), 0, 1, 0);
AddMobile(new Lizardman(), 0, -1, 0);
AddMobile(new Lizardman(), 0, -2, 0);
} break;
case 3:
{
AddMobile(new Brigand(), 0, -2, 0);
AddMobile(new Brigand(), 0, 1, 0);
AddMobile(new Brigand(), 0, -2, 0);
AddMobile(new Brigand(), 0, 1, 0);
AddMobile(new Brigand(), 0, -1, 0);
AddMobile(new Brigand(), 0, -2, 0);
} break;
}
switch ( Utility.Random( 2 ) )
{
case 0: Prisoner = new Noble(); break;
case 1: Prisoner = new SeekerOfAdventure(); break;
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Prisoner.YellHue = Utility.RandomList( 0x57, 0x67, 0x77, 0x87, 0x117 );
AddMobile( Prisoner, -2, 0, 0 );
}
public override void OnEnter( Mobile m )
{
base.OnEnter( m );
if ( m.Player && Prisoner != null && m_Gate != null && m_Gate.Locked )
{
int number;
switch ( Utility.Random( 10 ) )
{
default:
case 0: number = 502264; break; // Help a poor prisoner!
case 1: number = 502266; break; // Aaah! Help me!
case 2: number = 1046000; break; // Help! These savages wish to end my life!
case 3: number = 1046003; break; // Quickly! Kill them for me! HELP!!
case 4: number = 502261; break; // HELP!
case 5: number = 502262; break; // Help me!
case 6: number = 502263; break; // Canst thou aid me?!
case 7: number = 502265; break; // Help! Please!
case 8: number = 502267; break; // Go and get some help!
case 9: number = 502268; break; // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
}
Prisoner.Yell( number );
}
}
public PrisonerCamp( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_Gate );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
m_Gate = reader.ReadItem() as BaseDoor;
break;
case 0:
{
Prisoner = reader.ReadMobile() as BaseCreature;
m_Gate = reader.ReadItem() as BaseDoor;
break;
}
}
}
}
}

View File

@@ -0,0 +1,164 @@
using System;
using Server.Items;
using Server.Mobiles;
namespace Server.Multis
{
public class RatCamp : BaseCamp
{
[Constructable]
public RatCamp()
: base(0x1F6D)// dummy garbage at center
{
}
public RatCamp(Serial serial)
: base(serial)
{
}
public virtual Mobile Ratmen
{
get
{
return new Ratman();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public override TimeSpan DecayDelay { get { return TimeSpan.FromMinutes(5.0); } }
public override void AddComponents()
{
Visible = false;
AddItem(new Static(0x10ee), 0, 0, 0);
AddItem(new Static(0xfac), 0, 6, 0);
switch ( Utility.Random(3) )
{
case 0:
{
AddItem(new Item(0xDE3), 0, 6, 0); // Campfire
AddItem(new Item(0x974), 0, 6, 1); // Cauldron
break;
}
case 1:
{
AddItem(new Item(0x1E95), 0, 6, 1); // Rabbit on a spit
break;
}
default:
{
AddItem(new Item(0x1E94), 0, 6, 1); // Chicken on a spit
break;
}
}
AddItem(new Item(0x41F), 5, 5, 0); // Gruesome Standart South
AddCampChests();
for (int i = 0; i < 4; i ++)
{
AddMobile(Ratmen, Utility.RandomMinMax(-7, 7), Utility.RandomMinMax(-7, 7), 0);
}
switch ( Utility.Random(2) )
{
case 0:
Prisoner = new Noble();
break;
default:
Prisoner = new SeekerOfAdventure();
break;
}
Prisoner.IsPrisoner = true;
Prisoner.CantWalk = true;
Prisoner.YellHue = Utility.RandomList(0x57, 0x67, 0x77, 0x87, 0x117);
AddMobile(Prisoner, Utility.RandomMinMax(-2, 2), Utility.RandomMinMax(-2, 2), 0);
}
// Don't refresh decay timer
public override void OnEnter(Mobile m)
{
if (m.Player && Prisoner != null && Prisoner.CantWalk)
{
int number;
switch ( Utility.Random(8) )
{
case 0:
number = 502261;
break; // HELP!
case 1:
number = 502262;
break; // Help me!
case 2:
number = 502263;
break; // Canst thou aid me?!
case 3:
number = 502264;
break; // Help a poor prisoner!
case 4:
number = 502265;
break; // Help! Please!
case 5:
number = 502266;
break; // Aaah! Help me!
case 6:
number = 502267;
break; // Go and get some help!
default:
number = 502268;
break; // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
}
Prisoner.Yell(number);
}
}
// Don't refresh decay timer
public override void OnExit(Mobile m)
{
}
public override void AddItem(Item item, int xOffset, int yOffset, int zOffset)
{
if (item != null)
item.Movable = false;
base.AddItem(item, xOffset, yOffset, zOffset);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)2); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 2: break;
case 1:
{
Prisoner = reader.ReadMobile() as BaseCreature;
break;
}
case 0:
{
Prisoner = reader.ReadMobile() as BaseCreature;
reader.ReadItem();
break;
}
}
}
}
}

View File

@@ -0,0 +1,373 @@
#region References
using System.Collections.Generic;
using System.IO;
using System.Linq;
#endregion
namespace Server.Multis
{
public class ComponentVerification
{
public int[] ItemTable { get { return m_ItemTable; } }
public int[] MultiTable { get { return m_MultiTable; } }
private readonly int[] m_ItemTable;
private readonly int[] m_MultiTable;
public ComponentVerification()
{
m_ItemTable = CreateTable(TileData.MaxItemValue);
m_MultiTable = CreateTable(0x4000);
LoadItems(
"Data/Components/walls.txt",
//
"South1",
"South2",
"South3",
"Corner",
"East1",
"East2",
"East3",
"Post",
"WindowS",
"AltWindowS",
"WindowE",
"AltWindowE",
"SecondAltWindowS",
"SecondAltWindowE");
LoadItems(
"Data/Components/teleprts.txt",
//
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"F13",
"F14",
"F15",
"F16");
LoadItems(
"Data/Components/stairs.txt",
//
"Block",
"North",
"East",
"South",
"West",
"Squared1",
"Squared2",
"Rounded1",
"Rounded2");
LoadItems(
"Data/Components/roof.txt",
//
"North",
"East",
"South",
"West",
"NSCrosspiece",
"EWCrosspiece",
"NDent",
"EDent",
"SDent",
"WDent",
"NTPiece",
"ETPiece",
"STPiece",
"WTPiece",
"XPiece",
"Extra Piece");
LoadItems(
"Data/Components/floors.txt",
//
"F1",
"F2",
"F3",
"F4",
"F5",
"F6",
"F7",
"F8",
"F9",
"F10",
"F11",
"F12",
"F13",
"F14",
"F15",
"F16");
LoadItems(
"Data/Components/misc.txt",
//
"Piece1",
"Piece2",
"Piece3",
"Piece4",
"Piece5",
"Piece6",
"Piece7",
"Piece8");
LoadItems(
"Data/Components/doors.txt",
//
"Piece1",
"Piece2",
"Piece3",
"Piece4",
"Piece5",
"Piece6",
"Piece7",
"Piece8");
LoadMultis(
"Data/Components/stairs.txt",
//
"MultiNorth",
"MultiEast",
"MultiSouth",
"MultiWest");
}
public bool IsItemValid(int itemID)
{
if (itemID <= 0 || itemID >= m_ItemTable.Length)
{
return false;
}
return CheckValidity(m_ItemTable[itemID]);
}
public bool IsMultiValid(int multiID)
{
if (multiID <= 0 || multiID >= m_MultiTable.Length)
{
return false;
}
return CheckValidity(m_MultiTable[multiID]);
}
public bool CheckValidity(int val)
{
if (val == -1)
{
return false;
}
return (val == 0 || ((int)ExpansionInfo.CoreExpansion.CustomHousingFlag & val) != 0);
}
private static int[] CreateTable(int length)
{
var table = new int[length];
for (var i = 0; i < table.Length; ++i)
{
table[i] = -1;
}
return table;
}
private void LoadItems(string path, params string[] itemColumns)
{
LoadSpreadsheet(m_ItemTable, path, itemColumns);
}
private void LoadMultis(string path, params string[] multiColumns)
{
LoadSpreadsheet(m_MultiTable, path, multiColumns);
}
private static void LoadSpreadsheet(int[] table, string path, params string[] tileColumns)
{
var ss = new Spreadsheet(path);
var tileCIDs = new int[tileColumns.Length];
for (var i = 0; i < tileColumns.Length; ++i)
{
tileCIDs[i] = ss.GetColumnID(tileColumns[i]);
}
var featureCID = ss.GetColumnID("FeatureMask");
foreach (var record in ss.Records)
{
var fid = record.GetInt32(featureCID);
foreach (var itemID in tileCIDs.Select(v => record.GetInt32(v)).Where(id => id > 0 && id < table.Length))
{
table[itemID] = fid;
}
}
}
}
public class Spreadsheet
{
private readonly ColumnInfo[] m_Columns;
private readonly DataRecord[] m_Records;
public Spreadsheet(string path)
{
using (var ip = new StreamReader(path))
{
var types = ReadLine(ip);
var names = ReadLine(ip);
m_Columns = new ColumnInfo[types.Length];
for (var i = 0; i < m_Columns.Length; ++i)
{
m_Columns[i] = new ColumnInfo(i, types[i], names[i]);
}
var records = new List<DataRecord>();
string[] values;
while ((values = ReadLine(ip)) != null)
{
var data = new object[m_Columns.Length];
for (var i = 0; i < m_Columns.Length; ++i)
{
var ci = m_Columns[i];
switch (ci.m_Type)
{
case "int":
data[i] = Utility.ToInt32(values[ci.m_DataIndex]);
break;
case "string":
data[i] = values[ci.m_DataIndex];
break;
}
}
records.Add(new DataRecord(this, data));
}
m_Records = records.ToArray();
}
}
public DataRecord[] Records { get { return m_Records; } }
public int GetColumnID(string name)
{
for (var i = 0; i < m_Columns.Length; ++i)
{
if (m_Columns[i].m_Name == name)
{
return i;
}
}
return -1;
}
private static string[] ReadLine(StreamReader ip)
{
string line;
while ((line = ip.ReadLine()) != null)
{
if (line.Length == 0)
{
continue;
}
return line.Split('\t');
}
return null;
}
private class ColumnInfo
{
public readonly int m_DataIndex;
public readonly string m_Type;
public readonly string m_Name;
public ColumnInfo(int dataIndex, string type, string name)
{
m_DataIndex = dataIndex;
m_Type = type;
m_Name = name;
}
}
}
public class DataRecord
{
private readonly Spreadsheet m_Spreadsheet;
private readonly object[] m_Data;
public DataRecord(Spreadsheet ss, object[] data)
{
m_Spreadsheet = ss;
m_Data = data;
}
public Spreadsheet Spreadsheet { get { return m_Spreadsheet; } }
public object[] Data { get { return m_Data; } }
public object this[string name] { get { return this[m_Spreadsheet.GetColumnID(name)]; } }
public object this[int id]
{
get
{
if (id < 0)
{
return null;
}
return m_Data[id];
}
}
public int GetInt32(string name)
{
return GetInt32(this[name]);
}
public int GetInt32(int id)
{
return GetInt32(this[id]);
}
public int GetInt32(object obj)
{
if (obj is int)
{
return (int)obj;
}
return 0;
}
public string GetString(string name)
{
return this[name] as string;
}
}
}

View File

@@ -0,0 +1,816 @@
using System;
using System.Linq;
using System.Collections.Generic;
using Server.Items;
namespace Server.Multis
{
public enum ContestHouseType
{
Keep,
Castle,
Other
}
public class BaseContestHouse : BaseHouse
{
public ContestHouseType HouseType { get; set; }
public List<Item> Fixtures { get; private set; }
public virtual int SignPostID { get { return 9; } }
public override Point3D BaseBanLocation
{
get
{
return new Point3D(Components.Min.X, Components.Height - 1 - Components.Center.Y, 0);
}
}
public override Rectangle2D[] Area
{
get
{
MultiComponentList mcl = Components;
return new Rectangle2D[] { new Rectangle2D(mcl.Min.X, mcl.Min.Y, mcl.Width, mcl.Height) };
}
}
public BaseContestHouse(ContestHouseType type, int multiID, Mobile owner, int MaxLockDown, int MaxSecure)
: base(multiID, owner, MaxLockDown, MaxSecure)
{
HouseType = type;
AutoAddFixtures();
}
protected void SetSign(int xOffset, int yOffset, int zOffset, bool post)
{
SetSign(xOffset, yOffset, zOffset);
var hanger = new Static(0xB9E);
hanger.MoveToWorld(new Point3D(X + xOffset, Y + yOffset, Z + zOffset), Map);
AddFixture(hanger);
if (post)
{
var signPost = new Static(SignPostID);
signPost.MoveToWorld(new Point3D(X + xOffset, Y + yOffset - 1, Z + zOffset), Map);
AddFixture(signPost);
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (Fixtures != null)
{
foreach (var item in Fixtures)
{
item.Delete();
}
}
}
public override void OnLocationChange(Point3D oldLocation)
{
base.OnLocationChange(oldLocation);
int x = base.Location.X - oldLocation.X;
int y = base.Location.Y - oldLocation.Y;
int z = base.Location.Z - oldLocation.Z;
if (Fixtures != null)
{
foreach (var item in Fixtures)
{
item.Location = new Point3D(item.X + x, item.Y + y, item.Z + z);
}
}
}
public override void OnMapChange()
{
base.OnMapChange();
if (Fixtures != null)
{
foreach (var item in Fixtures)
{
item.Map = Map;
}
}
}
public void AddTeleporters(int id, Point3D offset1, Point3D offset2)
{
var tele1 = new HouseTeleporter(id);
var tele2 = new HouseTeleporter(id);
tele1.Target = tele2;
tele2.Target = tele1;
tele1.MoveToWorld(new Point3D(X + offset1.X, Y + offset1.Y, offset1.Z), Map);
tele2.MoveToWorld(new Point3D(X + offset2.X, Y + offset2.Y, offset2.Z), Map);
AddFixture(tele1);
AddFixture(tele2);
}
public void AddFixture(Item item)
{
if (Fixtures == null)
{
Fixtures = new List<Item>();
}
Fixtures.Add(item);
}
public override bool IsInside(Point3D p, int height)
{
bool isInside = base.IsInside(p, height);
if (!isInside)
{
return Fixtures != null && Fixtures.OfType<HouseTeleporter>().Any(fix => fix.Location == p);
}
return isInside;
}
public virtual void AutoAddFixtures()
{
var components = MultiData.GetComponents(ItemID);
var teleporters = new Dictionary<int, List<MultiTileEntry>>();
foreach (var entry in components.List.Where(e => e.m_Flags == 0))
{
// Telepoters
if (entry.m_ItemID >= 0x181D && entry.m_ItemID <= 0x1828)
{
if (teleporters.ContainsKey(entry.m_ItemID))
{
teleporters[entry.m_ItemID].Add(entry);
}
else
{
teleporters[entry.m_ItemID] = new List<MultiTileEntry>();
teleporters[entry.m_ItemID].Add(entry);
}
}
else
{
ItemData data = TileData.ItemTable[entry.m_ItemID & TileData.MaxItemValue];
// door
if ((data.Flags & TileFlag.Door) != 0)
{
AddDoor(entry.m_ItemID, entry.m_OffsetX, entry.m_OffsetY, entry.m_OffsetZ);
}
else
{
Item st = new Static((int)entry.m_ItemID);
st.MoveToWorld(new Point3D(X + entry.m_OffsetX, Y + entry.m_OffsetY, entry.m_OffsetZ), Map);
AddFixture(st);
}
}
}
foreach (var door in Doors.OfType<BaseDoor>())
{
foreach (var check in Doors.OfType<BaseDoor>().Where(d => d != door))
{
if (door.InRange(check.Location, 1))
{
door.Link = check;
check.Link = door;
}
}
}
foreach (var kvp in teleporters)
{
if (kvp.Value.Count > 2)
{
Utility.WriteConsoleColor(ConsoleColor.Yellow, String.Format("Warning: More than 2 teleporters detected for {0}!", kvp.Key.ToString("X")));
}
else if (kvp.Value.Count <= 1)
{
Utility.WriteConsoleColor(ConsoleColor.Yellow, String.Format("Warning: 1 or less teleporters detected for {0}!", kvp.Key.ToString("X")));
continue;
}
AddTeleporters(kvp.Key, new Point3D(kvp.Value[0].m_OffsetX, kvp.Value[0].m_OffsetY, kvp.Value[0].m_OffsetZ), new Point3D(kvp.Value[1].m_OffsetX, kvp.Value[1].m_OffsetY, kvp.Value[1].m_OffsetZ));
}
teleporters.Clear();
}
public BaseContestHouse(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);//version
writer.Write((int)HouseType);
writer.Write(Fixtures != null ? Fixtures.Count : 0);
if (Fixtures != null)
{
foreach (var item in Fixtures)
{
writer.Write(item);
}
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
HouseType = (ContestHouseType)reader.ReadInt();
int count = reader.ReadInt();
for(int i = 0; i < count; i++)
{
var item = reader.ReadItem();
if (item != null)
{
AddFixture(item);
}
}
}
}
public class TrinsicKeep : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-11, -11, 23, 23), new Rectangle2D(-10, 13, 6, 1),
new Rectangle2D(-2, 13, 6, 1), new Rectangle2D(6, 13, 7, 1)
};
public TrinsicKeep(Mobile owner)
: base(ContestHouseType.Keep, 0x147E, owner, 2113, 18)
{
SetSign(-11, 13, 7, false);
}
public TrinsicKeep(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
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 GothicRoseCastle : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-15, -15, 31, 31),
new Rectangle2D(-14, 16, 11, 1),
new Rectangle2D(-2, 16, 6, 1),
new Rectangle2D(5, 16, 11, 1)
};
public GothicRoseCastle(Mobile owner)
: base(ContestHouseType.Castle, 0x147F, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public GothicRoseCastle(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 ElsaCastle : BaseContestHouse
{
public ElsaCastle(Mobile owner)
: base(ContestHouseType.Castle, 0x1480, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public ElsaCastle(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 Spires : BaseContestHouse
{
public Spires(Mobile owner)
: base(ContestHouseType.Castle, 0x1481, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public Spires(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 CastleOfOceania : BaseContestHouse
{
public CastleOfOceania(Mobile owner)
: base(ContestHouseType.Castle, 0x1482, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public CastleOfOceania(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 FeudalCastle : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-15, -15, 31, 31),
new Rectangle2D(5, 16, 1, 1),
new Rectangle2D(7, 16, 4, 1),
new Rectangle2D(12, 16, 1, 1)
};
public FeudalCastle(Mobile owner)
: base(ContestHouseType.Castle, 0x1483, owner, 3281, 28)
{
SetSign(-15, 16, 7, true);
}
public FeudalCastle(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
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 RobinsNest : BaseContestHouse
{
public RobinsNest(Mobile owner)
: base(ContestHouseType.Keep, 0x1484, owner, 2113, 18)
{
SetSign(-11, 13, 7, false);
}
public RobinsNest(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1);//version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0)
{
AddTeleporters(0x1822, new Point3D(4, 3, 47), new Point3D(11, -10, 67));
}
}
}
public class TraditionalKeep : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-11, -11, 23, 23),
new Rectangle2D(-10, 13, 6, 1),
new Rectangle2D(-2, 13, 6, 1),
new Rectangle2D(6, 13, 7, 1),
};
public TraditionalKeep(Mobile owner)
: base(ContestHouseType.Keep, 0x1485, owner, 2113, 18)
{
SetSign(-11, 13, 7, false);
}
public TraditionalKeep(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
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 VillaCrowley : BaseContestHouse
{
public VillaCrowley(Mobile owner)
: base(ContestHouseType.Keep, 0x1486, owner, 2113, 18)
{
SetSign(-11, 13, 7, true);
}
public VillaCrowley(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 DarkthornKeep : BaseContestHouse
{
public DarkthornKeep(Mobile owner)
: base(ContestHouseType.Keep, 0x1487, owner, 2113, 18)
{
SetSign(-11, 13, 7, false);
}
public DarkthornKeep(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 SandalwoodKeep : BaseContestHouse
{
public override int SignPostID { get { return 353; } }
public SandalwoodKeep(Mobile owner)
: base(ContestHouseType.Keep, 0x1488, owner, 2113, 18)
{
SetSign(-11, 13, 7, true);
}
public SandalwoodKeep(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1);//version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
if (version == 0)
{
AddTeleporters(0x1820, new Point3D(9, 5, 7), new Point3D(7, -7, 47));
AddTeleporters(0x181E, new Point3D(8, 5, 7), new Point3D(9, 5, 27));
}
}
}
public class CasaMoga : BaseContestHouse
{
public CasaMoga(Mobile owner)
: base(ContestHouseType.Keep, 0x1489, owner, 2113, 18)
{
SetSign(-11, 13, 7, false);
}
public CasaMoga(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 RobinsRoost : BaseContestHouse
{
public RobinsRoost(Mobile owner)
: base(ContestHouseType.Castle, 0x148A, owner, 3281, 28)
{
SetSign(-15, 16, 7, true);
}
public RobinsRoost(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 Camelot : BaseContestHouse
{
public Camelot(Mobile owner)
: base(ContestHouseType.Castle, 0x148B, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public Camelot(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 LacrimaeInCaelo : BaseContestHouse
{
public LacrimaeInCaelo(Mobile owner)
: base(ContestHouseType.Castle, 0x148C, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public LacrimaeInCaelo(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 OkinawaSweetDreamCastle : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-15, -15, 31, 31),
new Rectangle2D(-14, 16, 6, 1),
new Rectangle2D(-7, 16, 8, 1),
new Rectangle2D(10, 16, 5, 1)
};
public override Rectangle2D[] Area { get { return AreaArray; } }
public OkinawaSweetDreamCastle(Mobile owner)
: base(ContestHouseType.Castle, 0x148D, owner, 3281, 28)
{
SetSign(-15, 16, 7, true);
}
public OkinawaSweetDreamCastle(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 TheSandstoneCastle : BaseContestHouse
{
public TheSandstoneCastle(Mobile owner)
: base(ContestHouseType.Castle, 0x148E, owner, 3281, 28)
{
SetSign(-15, 16, 7, true);
}
public TheSandstoneCastle(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 GrimswindSisters : BaseContestHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[]
{
new Rectangle2D(-15, -15, 31, 31),
new Rectangle2D(-14, 16, 9, 1),
new Rectangle2D(-3, 16, 8, 1),
new Rectangle2D(7, 16, 9, 1)
};
public override Rectangle2D[] Area { get { return AreaArray; } }
public GrimswindSisters(Mobile owner)
: base(ContestHouseType.Castle, 0x148F, owner, 3281, 28)
{
SetSign(-15, 16, 7, false);
}
public GrimswindSisters(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();
}
}
}

1157
Scripts/Multis/Deeds.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
namespace Server.Multis
{
public class DynamicDecay
{
private static Dictionary<DecayLevel, DecayStageInfo> m_Stages;
static DynamicDecay()
{
m_Stages = new Dictionary<DecayLevel, DecayStageInfo>();
Register(DecayLevel.LikeNew, TimeSpan.FromHours(1), TimeSpan.FromHours(1));
Register(DecayLevel.Slightly, TimeSpan.FromDays(1), TimeSpan.FromDays(2));
Register(DecayLevel.Somewhat, TimeSpan.FromDays(1), TimeSpan.FromDays(2));
Register(DecayLevel.Fairly, TimeSpan.FromDays(1), TimeSpan.FromDays(2));
Register(DecayLevel.Greatly, TimeSpan.FromDays(1), TimeSpan.FromDays(2));
Register(DecayLevel.IDOC, TimeSpan.FromHours(12), TimeSpan.FromHours(24));
}
public static bool Enabled
{
get
{
return Core.ML;
}
}
public static void Register(DecayLevel level, TimeSpan min, TimeSpan max)
{
DecayStageInfo info = new DecayStageInfo(min, max);
if (m_Stages.ContainsKey(level))
m_Stages[level] = info;
else
m_Stages.Add(level, info);
}
public static bool Decays(DecayLevel level)
{
return m_Stages.ContainsKey(level);
}
public static TimeSpan GetRandomDuration(DecayLevel level)
{
if (!m_Stages.ContainsKey(level))
return TimeSpan.Zero;
DecayStageInfo info = m_Stages[level];
long min = info.MinDuration.Ticks;
long max = info.MaxDuration.Ticks;
return TimeSpan.FromTicks(min + (long)(Utility.RandomDouble() * (max - min)));
}
}
public class DecayStageInfo
{
private readonly TimeSpan m_MinDuration;
private readonly TimeSpan m_MaxDuration;
public DecayStageInfo(TimeSpan min, TimeSpan max)
{
this.m_MinDuration = min;
this.m_MaxDuration = max;
}
public TimeSpan MinDuration
{
get
{
return this.m_MinDuration;
}
}
public TimeSpan MaxDuration
{
get
{
return this.m_MaxDuration;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,385 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Regions;
using Server.Spells;
using Server.Mobiles;
namespace Server.Multis
{
public enum HousePlacementResult
{
Valid,
BadRegion,
BadLand,
BadStatic,
BadItem,
NoSurface,
BadRegionHidden,
BadRegionTemp,
InvalidCastleKeep,
BadRegionRaffle,
NoQueenLoyalty
}
public class HousePlacement
{
// Any land tile which matches one of these ID numbers is considered a road and cannot be placed over.
public static int[] RoadIDs { get { return m_RoadIDs; } }
private static readonly int[] m_RoadIDs = new int[]
{
0x0071, 0x0078,
0x00E8, 0x00EB,
0x07AE, 0x07B1,
0x3FF4, 0x3FF4,
0x3FF8, 0x3FFB,
0x0442, 0x0479, // Sand stones
0x0501, 0x0510, // Sand stones
0x0009, 0x0015, // Furrows
0x0150, 0x015C // Furrows
};
private const int YardSize = 5;
public static HousePlacementResult Check(Mobile from, int multiID, Point3D center, out ArrayList toMove)
{
// If this spot is considered valid, every item and mobile in this list will be moved under the house sign
toMove = new ArrayList();
Map map = from.Map;
if (map == null || map == Map.Internal)
return HousePlacementResult.BadLand; // A house cannot go here
if (from.AccessLevel >= AccessLevel.GameMaster)
return HousePlacementResult.Valid; // Staff can place anywhere
if (map == Map.Ilshenar || SpellHelper.IsFeluccaT2A(map, center) || SpellHelper.IsEodon(map, center))
return HousePlacementResult.BadRegion; // No houses in Ilshenar/T2A/Eodon
if (map == Map.Malas && (multiID == 0x007C || multiID == 0x007E))
return HousePlacementResult.InvalidCastleKeep;
#region SA
if (map == Map.TerMur && !Server.Engines.Points.PointsSystem.QueensLoyalty.IsNoble(from))
{
return HousePlacementResult.NoQueenLoyalty;
}
#endregion
var noHousingRegion = (NoHousingRegion)Region.Find(center, map).GetRegion(typeof(NoHousingRegion));
if (noHousingRegion != null)
return HousePlacementResult.BadRegion;
// This holds data describing the internal structure of the house
MultiComponentList mcl = MultiData.GetComponents(multiID);
if (multiID >= 0x13EC && multiID < 0x1D00)
HouseFoundation.AddStairsTo(ref mcl); // this is a AOS house, add the stairs
// Location of the nortwest-most corner of the house
Point3D start = new Point3D(center.X + mcl.Min.X, center.Y + mcl.Min.Y, center.Z);
// These are storage lists. They hold items and mobiles found in the map for further processing
List<Item> items = new List<Item>();
List<Mobile> mobiles = new List<Mobile>();
// These are also storage lists. They hold location values indicating the yard and border locations.
List<Point2D> yard = new List<Point2D>(), borders = new List<Point2D>();
/* RULES:
*
* 1) All tiles which are around the -outside- of the foundation must not have anything impassable.
* 2) No impassable object or land tile may come in direct contact with any part of the house.
* 3) Five tiles from the front and back of the house must be completely clear of all house tiles.
* 4) The foundation must rest flatly on a surface. Any bumps around the foundation are not allowed.
* 5) No foundation tile may reside over terrain which is viewed as a road.
*/
for (int x = 0; x < mcl.Width; ++x)
{
for (int y = 0; y < mcl.Height; ++y)
{
int tileX = start.X + x;
int tileY = start.Y + y;
StaticTile[] addTiles = mcl.Tiles[x][y];
if (addTiles.Length == 0)
continue; // There are no tiles here, continue checking somewhere else
Point3D testPoint = new Point3D(tileX, tileY, center.Z);
Region reg = Region.Find(testPoint, map);
if (!reg.AllowHousing(from, testPoint)) // Cannot place houses in dungeons, towns, treasure map areas etc
{
if (reg.IsPartOf<TempNoHousingRegion>())
return HousePlacementResult.BadRegionTemp;
if (reg.IsPartOf<TreasureRegion>() || reg.IsPartOf<HouseRegion>())
return HousePlacementResult.BadRegionHidden;
if (reg.IsPartOf<HouseRaffleRegion>())
return HousePlacementResult.BadRegionRaffle;
return HousePlacementResult.BadRegion;
}
LandTile landTile = map.Tiles.GetLandTile(tileX, tileY);
int landID = landTile.ID & TileData.MaxLandValue;
StaticTile[] oldTiles = map.Tiles.GetStaticTiles(tileX, tileY, true);
Sector sector = map.GetSector(tileX, tileY);
items.Clear();
for (int i = 0; i < sector.Items.Count; ++i)
{
Item item = sector.Items[i];
if (item.Visible && item.X == tileX && item.Y == tileY)
items.Add(item);
}
mobiles.Clear();
for (int i = 0; i < sector.Mobiles.Count; ++i)
{
Mobile m = sector.Mobiles[i];
if (m.X == tileX && m.Y == tileY)
mobiles.Add(m);
}
int landStartZ = 0, landAvgZ = 0, landTopZ = 0;
map.GetAverageZ(tileX, tileY, ref landStartZ, ref landAvgZ, ref landTopZ);
bool hasFoundation = false;
for (int i = 0; i < addTiles.Length; ++i)
{
StaticTile addTile = addTiles[i];
if (addTile.ID == 0x1) // Nodraw
continue;
TileFlag addTileFlags = TileData.ItemTable[addTile.ID & TileData.MaxItemValue].Flags;
bool isFoundation = (addTile.Z == 0 && (addTileFlags & TileFlag.Wall) != 0);
bool hasSurface = false;
if (isFoundation)
hasFoundation = true;
int addTileZ = center.Z + addTile.Z;
int addTileTop = addTileZ + addTile.Height;
if ((addTileFlags & TileFlag.Surface) != 0)
addTileTop += 16;
if (addTileTop > landStartZ && landAvgZ > addTileZ)
return HousePlacementResult.BadLand; // Broke rule #2
if (isFoundation && ((TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) == 0) && landAvgZ == center.Z)
hasSurface = true;
for (int j = 0; j < oldTiles.Length; ++j)
{
StaticTile oldTile = oldTiles[j];
ItemData id = TileData.ItemTable[oldTile.ID & TileData.MaxItemValue];
if ((id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0)) && addTileTop > oldTile.Z && (oldTile.Z + id.CalcHeight) > addTileZ)
return HousePlacementResult.BadStatic; // Broke rule #2
/*else if ( isFoundation && !hasSurface && (id.Flags & TileFlag.Surface) != 0 && (oldTile.Z + id.CalcHeight) == center.Z )
hasSurface = true;*/
}
for (int j = 0; j < items.Count; ++j)
{
Item item = items[j];
ItemData id = item.ItemData;
if (addTileTop > item.Z && (item.Z + id.CalcHeight) > addTileZ)
{
if (item.Movable)
toMove.Add(item);
else if ((id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0)))
return HousePlacementResult.BadItem; // Broke rule #2
}
/*else if ( isFoundation && !hasSurface && (id.Flags & TileFlag.Surface) != 0 && (item.Z + id.CalcHeight) == center.Z )
{
hasSurface = true;
}*/
}
if (isFoundation && !hasSurface)
return HousePlacementResult.NoSurface; // Broke rule #4
for (int j = 0; j < mobiles.Count; ++j)
{
Mobile m = mobiles[j];
if (addTileTop > m.Z && (m.Z + 16) > addTileZ)
toMove.Add(m);
}
}
for (int i = 0; i < m_RoadIDs.Length; i += 2)
{
if (landID >= m_RoadIDs[i] && landID <= m_RoadIDs[i + 1])
return HousePlacementResult.BadLand; // Broke rule #5
}
if (hasFoundation)
{
for (int xOffset = -1; xOffset <= 1; ++xOffset)
{
for (int yOffset = -YardSize; yOffset <= YardSize; ++yOffset)
{
Point2D yardPoint = new Point2D(tileX + xOffset, tileY + yOffset);
if (!yard.Contains(yardPoint))
yard.Add(yardPoint);
}
}
for (int xOffset = -1; xOffset <= 1; ++xOffset)
{
for (int yOffset = -1; yOffset <= 1; ++yOffset)
{
if (xOffset == 0 && yOffset == 0)
continue;
// To ease this rule, we will not add to the border list if the tile here is under a base floor (z<=8)
int vx = x + xOffset;
int vy = y + yOffset;
if (vx >= 0 && vx < mcl.Width && vy >= 0 && vy < mcl.Height)
{
StaticTile[] breakTiles = mcl.Tiles[vx][vy];
bool shouldBreak = false;
for (int i = 0; !shouldBreak && i < breakTiles.Length; ++i)
{
StaticTile breakTile = breakTiles[i];
if (breakTile.Height == 0 && breakTile.Z <= 8 && TileData.ItemTable[breakTile.ID & TileData.MaxItemValue].Surface)
shouldBreak = true;
}
if (shouldBreak)
continue;
}
Point2D borderPoint = new Point2D(tileX + xOffset, tileY + yOffset);
if (!borders.Contains(borderPoint))
borders.Add(borderPoint);
}
}
}
}
}
for (int i = 0; i < borders.Count; ++i)
{
Point2D borderPoint = borders[i];
LandTile landTile = map.Tiles.GetLandTile(borderPoint.X, borderPoint.Y);
int landID = landTile.ID & TileData.MaxLandValue;
if ((TileData.LandTable[landID].Flags & TileFlag.Impassable) != 0)
return HousePlacementResult.BadLand;
for (int j = 0; j < m_RoadIDs.Length; j += 2)
{
if (landID >= m_RoadIDs[j] && landID <= m_RoadIDs[j + 1])
return HousePlacementResult.BadLand; // Broke rule #5
}
StaticTile[] tiles = map.Tiles.GetStaticTiles(borderPoint.X, borderPoint.Y, true);
for (int j = 0; j < tiles.Length; ++j)
{
StaticTile tile = tiles[j];
ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
if (id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0 && (tile.Z + id.CalcHeight) > (center.Z + 2)))
return HousePlacementResult.BadStatic; // Broke rule #1
}
Sector sector = map.GetSector(borderPoint.X, borderPoint.Y);
List<Item> sectorItems = sector.Items;
for (int j = 0; j < sectorItems.Count; ++j)
{
Item item = sectorItems[j];
if (item.X != borderPoint.X || item.Y != borderPoint.Y || item.Movable)
continue;
ItemData id = item.ItemData;
if (id.Impassable || (id.Surface && (id.Flags & TileFlag.Background) == 0 && (item.Z + id.CalcHeight) > (center.Z + 2)))
return HousePlacementResult.BadItem; // Broke rule #1
}
}
List<Sector> _sectors = new List<Sector>();
List<BaseHouse> _houses = new List<BaseHouse>();
for (int i = 0; i < yard.Count; i++)
{
Sector sector = map.GetSector(yard[i]);
if (!_sectors.Contains(sector))
{
_sectors.Add(sector);
if (sector.Multis != null)
{
for (int j = 0; j < sector.Multis.Count; j++)
{
if (sector.Multis[j] is BaseHouse)
{
BaseHouse _house = (BaseHouse)sector.Multis[j];
if (!_houses.Contains(_house))
{
_houses.Add(_house);
}
}
}
}
}
}
for (int i = 0; i < yard.Count; ++i)
{
foreach (BaseHouse b in _houses)
{
if (b.Contains(yard[i]))
return HousePlacementResult.BadStatic; // Broke rule #3
}
/*Point2D yardPoint = yard[i];
IPooledEnumerable eable = map.GetMultiTilesAt( yardPoint.X, yardPoint.Y );
foreach ( StaticTile[] tile in eable )
{
for ( int j = 0; j < tile.Length; ++j )
{
if ( (TileData.ItemTable[tile[j].ID & TileData.MaxItemValue].Flags & (TileFlag.Impassable | TileFlag.Surface)) != 0 )
{
eable.Free();
return HousePlacementResult.BadStatic; // Broke rule #3
}
}
}
eable.Free();*/
}
return HousePlacementResult.Valid;
}
}
}

File diff suppressed because it is too large Load Diff

342
Scripts/Multis/HouseSign.cs Normal file
View File

@@ -0,0 +1,342 @@
using System;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Gumps;
namespace Server.Multis
{
public class HouseSign : Item
{
private BaseHouse m_Owner;
private Mobile m_OrgOwner;
public HouseSign(BaseHouse owner)
: base(0xBD2)
{
m_Owner = owner;
m_OrgOwner = m_Owner.Owner;
Movable = false;
}
public HouseSign(Serial serial)
: base(serial)
{
}
public string GetName()
{
if (Name == null)
return "An Unnamed House";
return Name;
}
public BaseHouse Owner
{
get
{
return m_Owner;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool RestrictDecay
{
get
{
return (m_Owner != null && m_Owner.RestrictDecay);
}
set
{
if (m_Owner != null)
m_Owner.RestrictDecay = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Mobile OriginalOwner
{
get
{
return m_OrgOwner;
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (m_Owner != null && !m_Owner.Deleted)
m_Owner.Delete();
}
public override void AddNameProperty(ObjectPropertyList list)
{
list.Add(1061638); // A House Sign
}
public override bool ForceShowProperties
{
get
{
return ObjectPropertyList.Enabled;
}
}
private bool m_GettingProperties;
public bool GettingProperties
{
get
{
return m_GettingProperties;
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1061639, Utility.FixHtml(GetName())); // Name: ~1_NAME~
list.Add(1061640, (m_Owner == null || m_Owner.Owner == null) ? "nobody" : m_Owner.Owner.Name); // Owner: ~1_OWNER~
if (m_Owner != null)
{
list.Add(m_Owner.Public ? 1061641 : 1061642); // This House is Open to the Public : This is a Private Home
m_GettingProperties = true;
DecayLevel level = m_Owner.DecayLevel;
m_GettingProperties = false;
if (level == DecayLevel.DemolitionPending)
{
list.Add(1062497); // Demolition Pending
}
else if (level != DecayLevel.Ageless)
{
if (level == DecayLevel.Collapsed)
level = DecayLevel.IDOC;
list.Add(1062028, String.Format("#{0}", 1043009 + (int)level)); // Condition: This structure is ...
}
}
}
public override void OnSingleClick(Mobile from)
{
if (m_Owner != null && BaseHouse.DecayEnabled && m_Owner.DecayPeriod != TimeSpan.Zero)
{
string message;
switch ( m_Owner.DecayLevel )
{
case DecayLevel.Ageless:
message = "ageless";
break;
case DecayLevel.Fairly:
message = "fairly worn";
break;
case DecayLevel.Greatly:
message = "greatly worn";
break;
case DecayLevel.LikeNew:
message = "like new";
break;
case DecayLevel.Slightly:
message = "slightly worn";
break;
case DecayLevel.Somewhat:
message = "somewhat worn";
break;
default:
message = "in danger of collapsing";
break;
}
LabelTo(from, "This house is {0}.", message);
}
base.OnSingleClick(from);
}
public void ShowSign(Mobile m)
{
if (m_Owner != null && m.AccessLevel == AccessLevel.Player)
{
if ((Core.ML && m_Owner.IsFriend(m)) || !Core.ML)
{
m_Owner.RefreshDecay();
}
if (!Core.AOS && m_Owner.IsFriend(m))
{
m.SendLocalizedMessage(501293); // Welcome back to the house, friend!
}
}
if (m_Owner.IsAosRules)
{
m.SendGump(new HouseGumpAOS(HouseGumpPageAOS.Information, m, m_Owner));
}
else
{
m.SendGump(new HouseGump(m, m_Owner));
}
}
public void ClaimGump_Callback(Mobile from, bool okay, object state)
{
if (okay && m_Owner != null && m_Owner.Owner == null && m_Owner.DecayLevel != DecayLevel.DemolitionPending)
{
bool canClaim = false;
if (m_Owner.CoOwners == null || m_Owner.CoOwners.Count == 0)
canClaim = m_Owner.IsFriend(from);
else
canClaim = m_Owner.IsCoOwner(from);
if (canClaim && !BaseHouse.AtAccountHouseLimit(from))
{
m_Owner.Owner = from;
m_Owner.LastTraded = DateTime.UtcNow;
}
}
InvalidateProperties();
ShowSign(from);
}
public override void OnDoubleClick(Mobile m)
{
if (m_Owner == null)
return;
if (m.AccessLevel < AccessLevel.GameMaster && m_Owner.Owner == null && m_Owner.DecayLevel != DecayLevel.DemolitionPending)
{
bool canClaim = false;
if (m_Owner.CoOwners == null || m_Owner.CoOwners.Count == 0)
canClaim = m_Owner.IsFriend(m);
else
canClaim = m_Owner.IsCoOwner(m);
if (canClaim && !BaseHouse.AtAccountHouseLimit(m))
{
/* You do not currently own any house on any shard with this account,
* and this house currently does not have an owner. If you wish, you
* may choose to claim this house and become its rightful owner. If
* you do this, it will become your Primary house and automatically
* refresh. If you claim this house, you will be unable to place
* another house or have another house transferred to you for the
* next 7 days. Do you wish to claim this house?
*/
m.SendGump(new WarningGump(501036, 32512, 1049719, 32512, 420, 280, new WarningGumpCallback(ClaimGump_Callback), null));
}
}
ShowSign(m);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (BaseHouse.NewVendorSystem && from.Alive && Owner != null && Owner.IsAosRules)
{
if (Owner.AreThereAvailableVendorsFor(from))
list.Add(new VendorsEntry(this));
if (Owner.VendorInventories.Count > 0)
list.Add(new ReclaimVendorInventoryEntry(this));
}
}
private class VendorsEntry : ContextMenuEntry
{
private readonly HouseSign m_Sign;
public VendorsEntry(HouseSign sign)
: base(6211)
{
m_Sign = sign;
}
public override void OnClick()
{
Mobile from = Owner.From;
if (!from.CheckAlive() || m_Sign.Deleted || m_Sign.Owner == null || !m_Sign.Owner.AreThereAvailableVendorsFor(from))
return;
if (from.Map != m_Sign.Map || !from.InRange(m_Sign, 5))
{
from.SendLocalizedMessage(1062429); // You must be within five paces of the house sign to use this option.
}
else
{
from.SendGump(new HouseGumpAOS(HouseGumpPageAOS.Vendors, from, m_Sign.Owner));
}
}
}
private class ReclaimVendorInventoryEntry : ContextMenuEntry
{
private readonly HouseSign m_Sign;
public ReclaimVendorInventoryEntry(HouseSign sign)
: base(6213)
{
m_Sign = sign;
}
public override void OnClick()
{
Mobile from = Owner.From;
if (m_Sign.Deleted || m_Sign.Owner == null || m_Sign.Owner.VendorInventories.Count == 0 || !from.CheckAlive())
return;
if (from.Map != m_Sign.Map || !from.InRange(m_Sign, 5))
{
from.SendLocalizedMessage(1062429); // You must be within five paces of the house sign to use this option.
}
else
{
from.CloseGump(typeof(VendorInventoryGump));
from.SendGump(new VendorInventoryGump(m_Sign.Owner, from));
}
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(m_Owner);
writer.Write(m_OrgOwner);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Owner = reader.ReadItem() as BaseHouse;
m_OrgOwner = reader.ReadMobile();
break;
}
}
if (Name == "a house sign")
Name = null;
}
}
}

View File

@@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
using Server.Mobiles;
namespace Server.Items
{
public class HouseTeleporter : Item, ISecurable
{
private Item m_Target;
private SecureLevel m_Level;
[CommandProperty(AccessLevel.GameMaster)]
public BaseHouse House
{
get
{
return BaseHouse.FindHouseAt(this);
}
}
[Constructable]
public HouseTeleporter(int itemID)
: this(itemID, null)
{
}
public HouseTeleporter(int itemID, Item target)
: base(itemID)
{
Movable = false;
m_Level = SecureLevel.Anyone;
m_Target = target;
}
public HouseTeleporter(Serial serial)
: base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public Item Target
{
get
{
return m_Target;
}
set
{
m_Target = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public SecureLevel Level
{
get
{
return m_Level;
}
set
{
m_Level = value;
}
}
public virtual bool CheckAccess(Mobile m)
{
BaseHouse house = BaseHouse.FindHouseAt(this);
if (house != null && house.IsCombatRestricted(m))
{
m.SendLocalizedMessage(1071514); // You cannot use this item during the heat of battle.
return false;
}
if (house != null && (house.Public ? house.IsBanned(m) : !house.HasAccess(m)))
{
m.SendLocalizedMessage(1115577); // You cannot teleport from here to the destination because you do not have the correct house permissions.
return false;
}
if (house == null || !house.HasSecureAccess(m, m_Level))
{
m.SendLocalizedMessage(1115577); // You cannot teleport from here to the destination because you do not have the correct house permissions.
return false;
}
return true;
}
public override bool OnMoveOver(Mobile m)
{
if (m is PlayerMobile && ((PlayerMobile)m).DesignContext != null)
{
return true;
}
if (m_Target != null && !m_Target.Deleted)
{
if (CheckAccess(m))
{
if (!m.Hidden || m.IsPlayer())
new EffectTimer(Location, Map, 2023, 0x1F0, TimeSpan.FromSeconds(0.4)).Start();
new DelayTimer(this, m).Start();
}
}
return true;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1); // version
writer.Write((int)m_Level);
writer.Write((Item)m_Target);
}
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:
{
m_Target = reader.ReadItem();
if (version < 0)
m_Level = SecureLevel.Anyone;
break;
}
}
}
public virtual void OnAfterTeleport(Mobile m)
{
}
public class EffectTimer : Timer
{
private readonly Point3D m_Location;
private readonly Map m_Map;
private readonly int m_EffectID;
private readonly int m_SoundID;
public EffectTimer(Point3D p, Map map, int effectID, int soundID, TimeSpan delay)
: base(delay)
{
m_Location = p;
m_Map = map;
m_EffectID = effectID;
m_SoundID = soundID;
}
protected override void OnTick()
{
Effects.SendLocationParticles(EffectItem.Create(m_Location, m_Map, EffectItem.DefaultDuration), 0x3728, 10, 10, m_EffectID, 0);
if (m_SoundID != -1)
Effects.PlaySound(m_Location, m_Map, m_SoundID);
}
}
private class DelayTimer : Timer
{
private readonly HouseTeleporter m_Teleporter;
private readonly Mobile m_Mobile;
public DelayTimer(HouseTeleporter tp, Mobile m)
: base(TimeSpan.FromSeconds(1.0))
{
m_Teleporter = tp;
m_Mobile = m;
}
protected override void OnTick()
{
Item target = m_Teleporter.m_Target;
if (target != null && !target.Deleted)
{
Mobile m = m_Mobile;
if (m.X == m_Teleporter.X && m.Y == m_Teleporter.Y && Math.Abs(m.Z - m_Teleporter.Z) <= 1 && m.Map == m_Teleporter.Map)
{
Point3D p = target.GetWorldTop();
Map map = target.Map;
Server.Mobiles.BaseCreature.TeleportPets(m, p, map);
m.MoveToWorld(p, map);
if (!m.Hidden || m.IsPlayer())
{
Effects.PlaySound(target.Location, target.Map, 0x1FE);
Effects.SendLocationParticles(EffectItem.Create(m_Teleporter.Location, m_Teleporter.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023, 0);
Effects.SendLocationParticles(EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023, 0);
new EffectTimer(target.Location, target.Map, 2023, -1, TimeSpan.FromSeconds(0.4)).Start();
}
m_Teleporter.OnAfterTeleport(m);
}
}
}
}
}
}

View File

@@ -0,0 +1,710 @@
using Server;
using System;
using Server.Items;
using Server.Mobiles;
using Server.Spells;
using Server.Gumps;
using System.Collections.Generic;
using Server.ContextMenus;
using Server.Targeting;
namespace Server.Multis
{
public class HouseTeleporterTile : HouseTeleporter, IFlipable
{
public static void Initialize()
{
if(TileData.ItemTable.Length >= 0x574A)
TileData.ItemTable[0x574A].Flags = TileFlag.None;
}
public static int MaxCharges = 1000;
private int _Charges;
public override int ItemID
{
get { return base.ItemID; }
set
{
base.ItemID = value;
HueChange();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public HouseTeleporterTile Link
{
get
{
if(Target != null && Target.Deleted)
Target = null;
return Target as HouseTeleporterTile;
}
set
{
Target = value;
}
}
private bool IsMoveOver { get { return ItemID == 0x574A || ItemID == 0xA1CB || ItemID == 0xA1CC || ItemID == 0x40BB; } }
[CommandProperty(AccessLevel.GameMaster)]
public int Charges
{
get { return _Charges; }
set
{
_Charges = value;
HueChange();
InvalidateProperties();
}
}
public void HueChange()
{
if (UsesCharges && ItemID == 0x574A)
{
if (_Charges == 0)
{
Hue = 340;
}
else if (_Charges >= 1 && Hue != 541)
{
Hue = 541;
}
}
else
{
Hue = 0;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool UsesCharges { get; set; }
public override int LabelNumber { get { return Link == null ? 1114916 : 1113917; } } // house teleporter (unlinked) -or- House Teleporter
public HouseTeleporterTile(bool vetReward)
: base(vetReward ? 0x40BB : 0x574A, null)
{
UsesCharges = !vetReward;
Movable = true;
Weight = 1.0;
LootType = LootType.Blessed;
if (vetReward)
{
UsesCharges = false;
}
else
{
UsesCharges = true;
Charges = MaxCharges;
}
}
public void OnFlip(Mobile from)
{
bool flip = false;
switch (ItemID)
{
case 0x108C:
ItemID = 0x1093;
flip = true;
break;
case 0x1093:
ItemID = 0x108C;
flip = true;
break;
case 0x108D:
ItemID = 0x1094;
flip = true;
break;
case 0x1094:
ItemID = 0x108D;
flip = true;
break;
case 0x108E:
ItemID = 0x1095;
flip = true;
break;
case 0x1095:
ItemID = 0x108E;
flip = true;
break;
case 0x1090:
case 0x108F:
ItemID = 0x1091;
flip = true;
break;
case 0x1091:
ItemID = 0x1090;
flip = true;
break;
case 0xA1CB:
ItemID = 0xA1CC;
flip = true;
break;
case 0xA1CC:
ItemID = 0xA1CB;
flip = true;
break;
case 0xA2BA:
ItemID = 0xA2BC;
flip = true;
break;
case 0xA2BC:
ItemID = 0xA2BA;
flip = true;
break;
case 0xA2BB:
ItemID = 0xA2BD;
flip = true;
break;
case 0xA2BD:
ItemID = 0xA2BB;
flip = true;
break;
}
if (!flip)
from.SendLocalizedMessage(1042273); // You cannot turn that.
}
public override bool OnMoveOver(Mobile m)
{
if (IsMoveOver)
{
base.OnMoveOver(m);
}
return true;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
if (from.InRange(Location, 2) || IsChildOf(from.Backpack))
{
if (UsesCharges)
{
list.Add(new RechargeEntry(from, this));
list.Add(new ChangeTypeEntry(from, this));
}
}
base.GetContextMenuEntries(from, list);
}
private class RechargeEntry : ContextMenuEntry
{
private readonly Mobile Mobile;
private readonly HouseTeleporterTile Item;
public RechargeEntry(Mobile mobile, HouseTeleporterTile item)
: base(1076197, 2)
{
Mobile = mobile;
Item = item;
BaseHouse house = BaseHouse.FindHouseAt(item);
Enabled = Item.IsLockedDown && house != null && house.IsOwner(Mobile);
}
public override void OnClick()
{
if (Item == null || Item.Deleted)
return;
Mobile.SendLocalizedMessage(1158897); // Target the gate scrolls you wish to recharge this item with...
Mobile.Target = new InternalTarget(Item);
}
}
private class InternalTarget : Target
{
private readonly HouseTeleporterTile Item;
public InternalTarget(HouseTeleporterTile item)
: base(2, false, TargetFlags.None)
{
Item = item;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (from == null || Item == null || Item.Deleted)
{
return;
}
if (targeted is Item)
{
Item item = targeted as Item;
if (!item.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1054107); // This item must be in your backpack.
return;
}
if (item is GateTravelScroll)
{
GateTravelScroll scroll = item as GateTravelScroll;
if (Item.Charges >= MaxCharges)
{
from.SendLocalizedMessage(1115126); // The House Teleporter cannot be charged any further.
}
else
{
int left = MaxCharges - Item.Charges;
int scrollsNeeded = Math.Max(1, left / 5);
if (scroll.Amount <= scrollsNeeded)
{
Item.Charges = Math.Min(MaxCharges, Item.Charges + (scroll.Amount * 5));
scroll.Delete();
}
else
{
scroll.Amount -= scrollsNeeded;
Item.Charges = MaxCharges;
}
from.SendLocalizedMessage(1115127); // The Gate Travel scroll crumbles to dust as it strengthens the House Teleporter.
}
}
else
{
from.SendLocalizedMessage(1158898); // Target gate scroll to recharge the teleporter.
}
}
}
}
private class ChangeTypeEntry : ContextMenuEntry
{
private readonly Mobile Mobile;
private readonly Item Item;
public ChangeTypeEntry(Mobile mobile, Item item)
: base(1158896, 2)
{
Mobile = mobile;
Item = item;
BaseHouse house = BaseHouse.FindHouseAt(item);
Enabled = Item.IsLockedDown && house != null && house.IsOwner(Mobile);
}
public override void OnClick()
{
if (Item == null || Item.Deleted)
return;
if (!Mobile.HasGump(typeof(HouseTeleporterTypeGump)))
{
BaseGump.SendGump(new HouseTeleporterTypeGump((PlayerMobile)Mobile, Item));
}
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (UsesCharges)
{
list.Add(1060741, _Charges.ToString()); // charges: ~1_val~
}
}
public bool CheckBaseAccess(Mobile m)
{
return base.CheckAccess(m);
}
public override bool CheckAccess(Mobile m)
{
BaseHouse house = BaseHouse.FindHouseAt(this);
BaseHouse linkHouse = Link == null ? null : BaseHouse.FindHouseAt(Link);
if (house == null || Link == null || !IsLockedDown || !Link.IsLockedDown || linkHouse == null) // TODO: Messages for these?
{
return false;
}
if (UsesCharges && _Charges == 0)
{
m.SendLocalizedMessage(1115121); // There are no charges left in this teleporter.
return false;
}
if (UsesCharges && Link.Charges == 0)
{
m.SendLocalizedMessage(1115120); // There are no more charges left in the remote teleporter.
return false;
}
if (CheckBaseAccess(m) && Link.CheckBaseAccess(m))
{
return CheckTravel(m, Link.Location, Link.Map);
}
return false;
}
public bool CheckTravel(Mobile from, Point3D dest, Map destMap)
{
if (Factions.Sigil.ExistsOn(from))
{
from.SendLocalizedMessage(1061632); // You can't do that while carrying the sigil.
return false;
}
else if (from.Criminal)
{
from.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
return false;
}
else if (SpellHelper.CheckCombat(from))
{
from.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
return false;
}
else if (destMap == Map.Felucca && from is PlayerMobile && ((PlayerMobile)from).Young)
{
from.SendLocalizedMessage(1049543); // You decide against traveling to Felucca while you are still young.
return false;
}
else if (SpellHelper.RestrictRedTravel && from.Murderer && destMap.Rules != MapRules.FeluccaRules && !Siege.SiegeShard)
{
from.SendLocalizedMessage(1019004); // You are not allowed to travel there.
return false;
}
else if (Server.Engines.CityLoyalty.CityTradeSystem.HasTrade(from))
{
from.SendLocalizedMessage(1151733); // You cannot do that while carrying a Trade Order.
return false;
}
else if (from.Holding != null)
{
from.SendLocalizedMessage(1071955); // You cannot teleport while dragging an object.
return false;
}
else if (from.Target != null)
{
from.SendLocalizedMessage(500310); // You are too busy with something else.
return false;
}
return true;
}
public override void OnDoubleClick(Mobile m)
{
if(IsChildOf(m.Backpack))
{
m.SendLocalizedMessage(1114918); // Select a House Teleporter to link to.
m.BeginTarget(-1, false, Server.Targeting.TargetFlags.None, (from, targeted) =>
{
if(targeted is HouseTeleporterTile)
{
var tile = targeted as HouseTeleporterTile;
if(tile.IsChildOf(m.Backpack))
{
tile.Link = this;
Link = tile;
if (UsesCharges && tile.UsesCharges) //TODO: Can you link non-charged with charged?
{
from.SendLocalizedMessage(1115119); // The two House Teleporters are now linked and the charges remaining have been rebalanced.
if (!UsesCharges)
UsesCharges = true;
if (!tile.UsesCharges)
tile.UsesCharges = true;
int charges = _Charges + tile.Charges;
Charges = charges / 2;
tile.Charges = charges / 2;
}
else if (!UsesCharges && !tile.UsesCharges)
{
from.SendLocalizedMessage(1114919); // The two House Teleporters are now linked.
}
else
{
from.SendMessage("Those cannot be linked."); // TODO: Message?
}
}
else
{
from.SendLocalizedMessage(1114917); // This must be in your backpack to link it.
}
}
});
}
else if (!IsMoveOver)
{
if (Target != null && !Target.Deleted && InRange(m, 1))
{
if (CheckAccess(m))
{
if (!m.Hidden || m.IsPlayer())
new EffectTimer(m.Location, m.Map, 2023, 0x1F0, TimeSpan.FromSeconds(0.4)).Start();
new DelayTimer(this, m).Start();
}
}
}
else
{
m.SendLocalizedMessage(1114917); // This must be in your backpack to link it.
}
}
private class DelayTimer : Timer
{
private readonly HouseTeleporter m_Teleporter;
private readonly Mobile m_Mobile;
public DelayTimer(HouseTeleporter tp, Mobile m)
: base(TimeSpan.FromSeconds(1.0))
{
m_Teleporter = tp;
m_Mobile = m;
}
protected override void OnTick()
{
Item target = m_Teleporter.Target;
if (target != null && !target.Deleted)
{
Mobile m = m_Mobile;
Point3D p = target.GetWorldTop();
Map map = target.Map;
Server.Mobiles.BaseCreature.TeleportPets(m, p, map);
m.MoveToWorld(p, map);
if (!m.Hidden || m.IsPlayer())
{
Effects.PlaySound(target.Location, target.Map, 0x1FE);
Effects.SendLocationParticles(EffectItem.Create(m_Teleporter.Location, m_Teleporter.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023, 0);
Effects.SendLocationParticles(EffectItem.Create(target.Location, target.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023, 0);
new EffectTimer(target.Location, target.Map, 2023, -1, TimeSpan.FromSeconds(0.4)).Start();
}
m_Teleporter.OnAfterTeleport(m);
}
}
}
public override void OnAfterTeleport(Mobile m)
{
if (UsesCharges)
{
Charges = Math.Max(0, _Charges - 1);
if (Link != null)
{
Link.Charges = Math.Max(0, Link.Charges - 1);
if (!Link.UsesCharges)
{
Link.UsesCharges = true;
}
}
}
}
public HouseTeleporterTile(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(_Charges);
writer.Write(UsesCharges);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
_Charges = reader.ReadInt();
UsesCharges = reader.ReadBool();
if (ItemID == 0x40B9)
ItemID = 0x574A;
}
}
public class HouseTeleporterTypeGump : BaseGump
{
public Item Teleporter { get; set; }
public HouseTeleporterTypeGump(PlayerMobile pm, Item item)
: base(pm, 100, 100)
{
Teleporter = item;
}
public override void AddGumpLayout()
{
AddPage(0);
AddBackground(0, 0, 310, 400, 0x6DB);
AddImage(54, 0, 0x6E4);
AddHtmlLocalized(10, 10, 290, 18, 1114513, "#1113917", 0x0, false, false); // <DIV ALIGN=CENTER>~1_TOKEN~</DIV>
AddItem(35, 80, 0x574A);
AddButton(105, 80, 0x845, 0x846, 22346, GumpButtonType.Reply, 0);
AddItem(35, 140, 0x108C);
AddButton(105, 140, 0x845, 0x846, 4236, GumpButtonType.Reply, 0);
AddItem(35, 200, 0x108D);
AddButton(105, 200, 0x845, 0x846, 4237, GumpButtonType.Reply, 0);
AddItem(35, 260, 0x108E);
AddButton(105, 260, 0x845, 0x846, 4238, GumpButtonType.Reply, 0);
AddItem(35, 320, 0x108F);
AddButton(105, 320, 0x845, 0x846, 4239, GumpButtonType.Reply, 0);
AddItem(235, 80, 0x1090);
AddButton(195, 80, 0x845, 0x846, 4240, GumpButtonType.Reply, 0);
AddItem(235, 140, 0x9CDE);
AddButton(195, 140, 0x845, 0x846, 40158, GumpButtonType.Reply, 0);
AddItem(235, 200, 0xA1CB);
AddButton(195, 200, 0x845, 0x846, 41419, GumpButtonType.Reply, 0);
AddItem(235, 260, 0xA2BA);
AddButton(195, 260, 0x845, 0x846, 41658, GumpButtonType.Reply, 0);
AddItem(235, 320, 0xA2BB);
AddButton(195, 320, 0x845, 0x846, 41659, GumpButtonType.Reply, 0);
}
public override void OnResponse(RelayInfo info)
{
if (info.ButtonID != 0)
{
Teleporter.ItemID = info.ButtonID;
Refresh();
}
}
}
public class HouseTeleporterTileBag : Bag
{
public override int LabelNumber { get { return 1113917; } }
[Constructable]
public HouseTeleporterTileBag()
: this(false)
{
}
[Constructable]
public HouseTeleporterTileBag(bool reward)
{
Hue = 1336;
var tele1 = new HouseTeleporterTile(reward);
var tele2 = new HouseTeleporterTile(reward);
tele1.Link = tele2;
tele2.Link = tele1;
DropItem(tele1);
DropItem(tele2);
DropItem(new HouseTeleporterInstructions(reward));
}
public HouseTeleporterTileBag(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
public class HouseTeleporterInstructions : Item
{
public override int LabelNumber { get { return 1115122; } } // Care Instructions
public bool VetReward { get; set; }
public HouseTeleporterInstructions(bool reward)
: base(0xFF4)
{
VetReward = reward;
Hue = 195;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
list.Add(1115123); // Congratulations on becoming the<br> owner of your very own house<br> teleporter set!
list.Add(1115124); // To use them, lock one down in your<br> home then lock the other down in<br> the home of a trusted friend.
if (!VetReward)
{
list.Add(1115125); // Drop Gate Travel scrolls onto these<br> to recharge them.
}
}
public HouseTeleporterInstructions(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
writer.Write(VetReward);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
VetReward = reader.ReadBool();
}
}
}

927
Scripts/Multis/Houses.cs Normal file
View File

@@ -0,0 +1,927 @@
using System;
using Server.Items;
using Server.Multis.Deeds;
namespace Server.Multis
{
public class SmallOldHouse : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-3,-3,7,7), new Rectangle2D(-1, 4, 3, 1) };
public SmallOldHouse(Mobile owner, int id)
: base(id, owner, 425, 3)
{
uint keyValue = CreateKeys(owner);
AddSouthDoor(0, 3, 7, keyValue);
SetSign(2, 4, 5);
}
public SmallOldHouse(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(2, 4, 0);
}
}
public override int DefaultPrice
{
get
{
return 43800;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[0];
}
}
public override HouseDeed GetDeed()
{
switch ( ItemID )
{
case 0x64:
return new StonePlasterHouseDeed();
case 0x66:
return new FieldStoneHouseDeed();
case 0x68:
return new SmallBrickHouseDeed();
case 0x6A:
return new WoodHouseDeed();
case 0x6C:
return new WoodPlasterHouseDeed();
case 0x6E:
default:
return new ThatchedRoofCottageDeed();
}
}
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 GuildHouse : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-7, -7, 14, 14), new Rectangle2D(-2, 7, 4, 1) };
public GuildHouse(Mobile owner)
: base(0x74, owner, 1100, 8)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(-1, 6, 7, keyValue);
SetSign(4, 8, 16);
AddSouthDoor(-3, -1, 7);
AddSouthDoor(3, -1, 7);
}
public GuildHouse(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 144500;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.ThreeStoryFoundations[20];
}
}
public override int ConvertOffsetX
{
get
{
return -1;
}
}
public override int ConvertOffsetY
{
get
{
return -1;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(4, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new BrickHouseDeed();
}
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 TwoStoryHouse : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-7, 0, 14, 7), new Rectangle2D(-7, -7, 9, 7), new Rectangle2D(-4, 7, 4, 1) };
public TwoStoryHouse(Mobile owner, int id)
: base(id, owner, 1370, 10)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(-3, 6, 7, keyValue);
SetSign(2, 8, 16);
AddSouthDoor(-3, 0, 7);
AddSouthDoor(id == 0x76 ? -2 : -3, 0, 27);
}
public TwoStoryHouse(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(2, 8, 0);
}
}
public override int DefaultPrice
{
get
{
return 192400;
}
}
public override HouseDeed GetDeed()
{
switch( ItemID )
{
case 0x76:
return new TwoStoryWoodPlasterHouseDeed();
case 0x78:
default:
return new TwoStoryStonePlasterHouseDeed();
}
}
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 Tower : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-7, -7, 16, 14), new Rectangle2D(-1, 7, 4, 2), new Rectangle2D(-11, 0, 4, 7), new Rectangle2D(9, 0, 4, 7) };
public Tower(Mobile owner)
: base(0x7A, owner, 2119, 15)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(false, 0, 6, 6, keyValue);
SetSign(5, 8, 16);
AddSouthDoor(false, 3, -2, 6);
AddEastDoor(false, 1, 4, 26);
AddEastDoor(false, 1, 4, 46);
}
public Tower(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 433200;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.ThreeStoryFoundations[37];
}
}
public override int ConvertOffsetY
{
get
{
return -1;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(5, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new TowerDeed();
}
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 Keep : BaseHouse//warning: ODD shape!
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-11, -11, 7, 8), new Rectangle2D(-11, 5, 7, 8), new Rectangle2D(6, -11, 7, 8), new Rectangle2D(6, 5, 7, 8), new Rectangle2D(-9, -3, 5, 8), new Rectangle2D(6, -3, 5, 8), new Rectangle2D(-4, -9, 10, 20), new Rectangle2D(-1, 11, 4, 1) };
public Keep(Mobile owner)
: base(0x7C, owner, 2625, 18)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(false, 0, 10, 6, keyValue);
SetSign(5, 12, 16);
}
public Keep(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 665200;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(5, 13, 0);
}
}
public override HouseDeed GetDeed()
{
return new KeepDeed();
}
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 Castle : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-15, -15, 31, 31), new Rectangle2D(-1, 16, 4, 1) };
public Castle(Mobile owner)
: base(0x7E, owner, 4076, 28)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(false, 0, 15, 6, keyValue);
SetSign(5, 17, 16);
AddSouthDoors(false, 0, 11, 6, true);
AddSouthDoors(false, 0, 5, 6, false);
AddSouthDoors(false, -1, -11, 6, false);
}
public Castle(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 1022800;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(5, 17, 0);
}
}
protected override bool IsInsideSpecial(Point3D p, StaticTile[] tiles)
{
return p.X >= X - 10 && p.X <= X + 10 && p.Y >= Y - 10 && p.Y <= Y + 10;
}
public override HouseDeed GetDeed()
{
return new CastleDeed();
}
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 LargePatioHouse : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-7, -7, 15, 14), new Rectangle2D(-5, 7, 4, 1) };
public LargePatioHouse(Mobile owner)
: base(0x8C, owner, 1100, 8)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(-4, 6, 7, keyValue);
SetSign(1, 8, 16);
AddEastDoor(1, 4, 7);
AddEastDoor(1, -4, 7);
AddSouthDoor(4, -1, 7);
}
public LargePatioHouse(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 152800;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.ThreeStoryFoundations[29];
}
}
public override int ConvertOffsetY
{
get
{
return -1;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(1, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new LargePatioDeed();
}
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 LargeMarbleHouse : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-7, -7, 15, 14), new Rectangle2D(-6, 7, 6, 1) };
public LargeMarbleHouse(Mobile owner)
: base(0x96, owner, 1370, 10)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(false, -4, 3, 4, keyValue);
SetSign(1, 8, 11);
}
public LargeMarbleHouse(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 192000;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.ThreeStoryFoundations[29];
}
}
public override int ConvertOffsetY
{
get
{
return -1;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(1, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new LargeMarbleDeed();
}
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 SmallTower : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-3, -3, 8, 7), new Rectangle2D(2, 4, 3, 1) };
public SmallTower(Mobile owner)
: base(0x98, owner, 580, 4)
{
uint keyValue = CreateKeys(owner);
AddSouthDoor(false, 3, 3, 6, keyValue);
SetSign(1, 4, 5);
}
public SmallTower(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 88500;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[6];
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(1, 4, 0);
}
}
public override HouseDeed GetDeed()
{
return new SmallTowerDeed();
}
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 LogCabin : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-3, -6, 8, 13) };
public LogCabin(Mobile owner)
: base(0x9A, owner, 1100, 8)
{
uint keyValue = CreateKeys(owner);
AddSouthDoor(1, 4, 8, keyValue);
SetSign(5, 8, 20);
AddSouthDoor(1, 0, 29);
}
public LogCabin(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 97800;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[12];
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(5, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new LogCabinDeed();
}
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 SandStonePatio : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-5, -4, 12, 8), new Rectangle2D(-2, 4, 3, 1) };
public SandStonePatio(Mobile owner)
: base(0x9C, owner, 850, 6)
{
uint keyValue = CreateKeys(owner);
AddSouthDoor(-1, 3, 6, keyValue);
SetSign(4, 6, 24);
}
public SandStonePatio(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 90900;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[35];
}
}
public override int ConvertOffsetY
{
get
{
return -1;
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(4, 6, 0);
}
}
public override HouseDeed GetDeed()
{
return new SandstonePatioDeed();
}
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 TwoStoryVilla : BaseHouse
{
public static Rectangle2D[] AreaArray = new Rectangle2D[] { new Rectangle2D(-5, -5, 11, 11), new Rectangle2D(2, 6, 4, 1) };
public TwoStoryVilla(Mobile owner)
: base(0x9E, owner, 1100, 8)
{
uint keyValue = CreateKeys(owner);
AddSouthDoors(3, 1, 5, keyValue);
SetSign(3, 8, 24);
AddEastDoor(1, 0, 25);
AddSouthDoor(-3, -1, 25);
}
public TwoStoryVilla(Serial serial)
: base(serial)
{
}
public override int DefaultPrice
{
get
{
return 136500;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[31];
}
}
public override Rectangle2D[] Area
{
get
{
return AreaArray;
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(3, 8, 0);
}
}
public override HouseDeed GetDeed()
{
return new VillaDeed();
}
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 SmallShop : BaseHouse
{
public static Rectangle2D[] AreaArray1 = new Rectangle2D[] { new Rectangle2D(-3,-3,7,7), new Rectangle2D(-1, 4, 4, 1) };
public static Rectangle2D[] AreaArray2 = new Rectangle2D[] { new Rectangle2D(-3,-3,7,7), new Rectangle2D(-2, 4, 3, 1) };
public SmallShop(Mobile owner, int id)
: base(id, owner, 425, 3)
{
uint keyValue = CreateKeys(owner);
BaseDoor door = MakeDoor(false, DoorFacing.EastCW);
door.KeyValue = keyValue;
if (door is BaseHouseDoor)
((BaseHouseDoor)door).Facing = DoorFacing.EastCCW;
AddDoor(door, -2, 0, id == 0xA2 ? 24 : 27);
//AddSouthDoor( false, -2, 0, 27 - (id == 0xA2 ? 3 : 0), keyValue );
SetSign(3, 4, 7 - (id == 0xA2 ? 2 : 0));
}
public SmallShop(Serial serial)
: base(serial)
{
}
public override Rectangle2D[] Area
{
get
{
return (ItemID == 0x40A2 ? AreaArray1 : AreaArray2);
}
}
public override Point3D BaseBanLocation
{
get
{
return new Point3D(3, 4, 0);
}
}
public override int DefaultPrice
{
get
{
return 63000;
}
}
public override HousePlacementEntry ConvertEntry
{
get
{
return HousePlacementEntry.TwoStoryFoundations[0];
}
}
public override HouseDeed GetDeed()
{
switch ( ItemID )
{
case 0xA0:
return new StoneWorkshopDeed();
case 0xA2:
default:
return new MarbleWorkshopDeed();
}
}
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,389 @@
using System;
using System.Collections.Generic;
using Server.Items;
using Server.Network;
namespace Server.Multis
{
public class MovingCrate : Container
{
public static readonly int MaxItemsPerSubcontainer = 20;
public static readonly int Rows = 3;
public static readonly int Columns = 5;
public static readonly int HorizontalSpacing = 25;
public static readonly int VerticalSpacing = 25;
private BaseHouse m_House;
private Timer m_InternalizeTimer;
public MovingCrate(BaseHouse house)
: base(0xE3D)
{
this.Hue = 0x8A5;
this.Movable = false;
this.m_House = house;
}
public MovingCrate(Serial serial)
: base(serial)
{
}
public override int LabelNumber
{
get
{
return 1061690;
}
}// Packing Crate
public BaseHouse House
{
get
{
return this.m_House;
}
set
{
this.m_House = value;
}
}
public override int DefaultMaxItems
{
get
{
return 0;
}
}
public override int DefaultMaxWeight
{
get
{
return 0;
}
}
public override bool IsDecoContainer
{
get
{
return false;
}
}
/*
public override void AddNameProperties( ObjectPropertyList list )
{
base.AddNameProperties( list );
if ( House != null && House.InternalizedVendors.Count > 0 )
list.Add( 1061833, House.InternalizedVendors.Count.ToString() ); // This packing crate contains ~1_COUNT~ vendors/barkeepers.
}
*/
public override void DropItem(Item dropped)
{
// 1. Try to stack the item
foreach (Item item in this.Items)
{
if (item is PackingBox)
{
List<Item> subItems = item.Items;
for (int i = 0; i < subItems.Count; i++)
{
Item subItem = subItems[i];
if (!(subItem is Container) && subItem.StackWith(null, dropped, false))
return;
}
}
}
// 2. Try to drop the item into an existing container
foreach (Item item in this.Items)
{
if (item is PackingBox)
{
Container box = (Container)item;
List<Item> subItems = box.Items;
if (subItems.Count < MaxItemsPerSubcontainer)
{
box.DropItem(dropped);
return;
}
}
}
// 3. Drop the item into a new container
Container subContainer = new PackingBox();
subContainer.DropItem(dropped);
Point3D location = this.GetFreeLocation();
if (location != Point3D.Zero)
{
this.AddItem(subContainer);
subContainer.Location = location;
}
else
{
base.DropItem(subContainer);
}
}
public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
{
if (m.AccessLevel < AccessLevel.GameMaster)
{
m.SendLocalizedMessage(1061145); // You cannot place items into a house moving crate.
return false;
}
return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight);
}
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
{
return base.CheckLift(from, item, ref reject) && this.House != null && !this.House.Deleted && this.House.IsOwner(from);
}
public override bool CheckItemUse(Mobile from, Item item)
{
return base.CheckItemUse(from, item) && this.House != null && !this.House.Deleted && this.House.IsOwner(from);
}
public override void OnItemRemoved(Item item)
{
base.OnItemRemoved(item);
if (this.TotalItems == 0)
this.Delete();
}
public void RestartTimer()
{
if (this.m_InternalizeTimer == null)
{
this.m_InternalizeTimer = new InternalizeTimer(this);
this.m_InternalizeTimer.Start();
}
else
{
this.m_InternalizeTimer.Stop();
this.m_InternalizeTimer.Start();
}
}
public void Hide()
{
if (this.m_InternalizeTimer != null)
{
this.m_InternalizeTimer.Stop();
this.m_InternalizeTimer = null;
}
List<Item> toRemove = new List<Item>();
foreach (Item item in this.Items)
if (item is PackingBox && item.Items.Count == 0)
toRemove.Add(item);
foreach (Item item in toRemove)
item.Delete();
if (this.TotalItems == 0)
this.Delete();
else
this.Internalize();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (this.House != null && this.House.MovingCrate == this)
this.House.MovingCrate = null;
if (this.m_InternalizeTimer != null)
this.m_InternalizeTimer.Stop();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(1);
writer.Write((Item)this.m_House);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
this.m_House = reader.ReadItem() as BaseHouse;
if (this.m_House != null)
{
this.m_House.MovingCrate = this;
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Hide));
}
else
{
Timer.DelayCall(TimeSpan.Zero, this.Delete);
}
if (version == 0)
this.MaxItems = -1; // reset to default
}
private Point3D GetFreeLocation()
{
bool[,] positions = new bool[Rows, Columns];
foreach (Item item in this.Items)
{
if (item is PackingBox)
{
int i = (item.Y - this.Bounds.Y) / VerticalSpacing;
if (i < 0)
i = 0;
else if (i >= Rows)
i = Rows - 1;
int j = (item.X - this.Bounds.X) / HorizontalSpacing;
if (j < 0)
j = 0;
else if (j >= Columns)
j = Columns - 1;
positions[i, j] = true;
}
}
for (int i = 0; i < Rows; i++)
{
for (int j = 0; j < Columns; j++)
{
if (!positions[i, j])
{
int x = this.Bounds.X + j * HorizontalSpacing;
int y = this.Bounds.Y + i * VerticalSpacing;
return new Point3D(x, y, 0);
}
}
}
return Point3D.Zero;
}
public class InternalizeTimer : Timer
{
private readonly MovingCrate m_Crate;
public InternalizeTimer(MovingCrate crate)
: base(TimeSpan.FromMinutes(5.0))
{
this.m_Crate = crate;
this.Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
this.m_Crate.Hide();
}
}
}
public class PackingBox : BaseContainer
{
public PackingBox()
: base(0x9A8)
{
this.Movable = false;
}
public PackingBox(Serial serial)
: base(serial)
{
}
public override int LabelNumber
{
get
{
return 1061690;
}
}// Packing Crate
public override int DefaultGumpID
{
get
{
return 0x4B;
}
}
public override int DefaultDropSound
{
get
{
return 0x42;
}
}
public override Rectangle2D Bounds
{
get
{
return new Rectangle2D(16, 51, 168, 73);
}
}
public override int DefaultMaxItems
{
get
{
return 0;
}
}
public override int DefaultMaxWeight
{
get
{
return 0;
}
}
public override void SendCantStoreMessage(Mobile to, Item item)
{
to.SendLocalizedMessage(1061145); // You cannot place items into a house moving crate.
}
public override void OnItemRemoved(Item item)
{
base.OnItemRemoved(item);
if (item.GetBounce() == null && this.TotalItems == 0)
this.Delete();
}
public override void OnItemBounceCleared(Item item)
{
base.OnItemBounceCleared(item);
if (this.TotalItems == 0)
this.Delete();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(1); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
if (version == 0)
this.MaxItems = -1; // reset to default
}
}
}

View File

@@ -0,0 +1,124 @@
using System;
using Server.Multis;
using Server.Regions;
namespace Server.Items
{
public class NoHousingItem : Item
{
private NoHousingDelayTimer m_Timer;
private Rectangle3D[] m_Area;
private SimpleNoHousingRegion m_Region;
[Constructable]
public NoHousingItem(BaseHouse house)
: base(0x2FD5)
{
this.m_Timer = new NoHousingDelayTimer(this);
this.m_Timer.Start();
this.m_Area = house.Region.Area;
this.m_Region = new SimpleNoHousingRegion(house.Region.Map, this.m_Area);
this.m_Region.Register();
this.Visible = false;
this.Movable = false;
}
public NoHousingItem(Serial serial)
: base(serial)
{
}
public override void OnAfterDelete()
{
if (this.m_Region != null)
this.m_Region.Unregister();
if (this.m_Timer != null && this.m_Timer.Running)
this.m_Timer.Stop();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
if (this.m_Timer != null)
writer.Write(this.m_Timer.Next);
else
writer.Write(DateTime.UtcNow);
writer.Write(this.m_Area.Length);
foreach (Rectangle3D rect in this.m_Area)
writer.Write(rect);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
DateTime next = reader.ReadDateTime();
this.m_Area = new Rectangle3D[reader.ReadInt()];
for (int i = 0; i < this.m_Area.Length; i++)
this.m_Area[i] = reader.ReadRect3D();
this.m_Region = new SimpleNoHousingRegion(this.Map, this.m_Area);
this.m_Region.Register();
if (next < DateTime.UtcNow)
{
this.m_Timer = new NoHousingDelayTimer(this, next - DateTime.UtcNow);
this.m_Timer.Start();
}
else
this.Delete();
}
private class SimpleNoHousingRegion : BaseRegion
{
public SimpleNoHousingRegion(Map map, Rectangle3D[] area)
: base(null, map, Region.DefaultPriority, area)
{
}
public override bool AllowHousing(Mobile from, Point3D p)
{
return false;
}
}
private class NoHousingDelayTimer : Timer
{
private readonly NoHousingItem m_Item;
public NoHousingDelayTimer(NoHousingItem item)
: this(item, DefaultDelay)
{
}
public NoHousingDelayTimer(NoHousingItem item, TimeSpan delay)
: base(delay)
{
this.m_Item = item;
this.Priority = TimerPriority.OneMinute;
}
public static TimeSpan DefaultDelay
{
get
{
return TimeSpan.FromMinutes(Utility.RandomMinMax(60, 120));
}
}
protected override void OnTick()
{
if (this.m_Item != null && !this.m_Item.Deleted)
this.m_Item.Delete();
}
}
}
}

View File

@@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using Server.Items;
namespace Server.Multis
{
public class PreviewHouse : BaseMulti
{
private List<Item> m_Components;
private Timer m_Timer;
public PreviewHouse(int multiID)
: base(multiID)
{
m_Components = new List<Item>();
MultiComponentList mcl = Components;
for (int i = 1; i < mcl.List.Length; ++i)
{
MultiTileEntry entry = mcl.List[i];
if (entry.m_Flags == 0)
{
Item item = new Static((int)entry.m_ItemID);
item.MoveToWorld(new Point3D(X + entry.m_OffsetX, Y + entry.m_OffsetY, Z + entry.m_OffsetZ), Map);
m_Components.Add(item);
}
}
if (multiID >= 0x13ec && multiID <= 0x147d)
{
AddSignAndPost(mcl);
AddExteriorStairs(mcl);
}
m_Timer = new DecayTimer(this);
m_Timer.Start();
}
public void AddSignAndPost(MultiComponentList mcl)
{
int xoffset = mcl.Min.X;
int y = mcl.Height - 1 - mcl.Center.Y;
Item signpost = new Static((int)9);
signpost.MoveToWorld(new Point3D(X + xoffset, Y + y, Z + 7), Map);
m_Components.Add(signpost);
xoffset = Components.Min.X;
y = Components.Height - Components.Center.Y;
Item signhanger = new Static((int)0xB98);
signhanger.MoveToWorld(new Point3D(X + xoffset, Y + y, Z + 7), Map);
m_Components.Add(signhanger);
Item housesign = new Static((int)0xBD2);
housesign.MoveToWorld(new Point3D(X + xoffset, Y + y, Z + 7), Map);
m_Components.Add(housesign);
}
public void AddExteriorStairs(MultiComponentList mcl)
{
// this won't work correctly without declaring a new mcl so it can then be resized
MultiComponentList mclNew = new MultiComponentList(MultiData.GetComponents(ItemID));
mclNew.Resize(mclNew.Width, mclNew.Height + 1);
int xCenter = mcl.Center.X;
int yCenter = mcl.Center.Y;
int y = mcl.Height;
for (int x = 1; x < mclNew.Width; ++x)
{
Item stair = new Static((int)0x751);
stair.MoveToWorld(new Point3D(x - xCenter, y - yCenter, 0), Map);
m_Components.Add(stair);
}
}
public PreviewHouse(Serial serial)
: base(serial)
{
}
public override void OnLocationChange(Point3D oldLocation)
{
base.OnLocationChange(oldLocation);
if (m_Components == null)
return;
int xOffset = X - oldLocation.X;
int yOffset = Y - oldLocation.Y;
int zOffset = Z - oldLocation.Z;
for (int i = 0; i < m_Components.Count; ++i)
{
Item item = m_Components[i];
item.MoveToWorld(new Point3D(item.X + xOffset, item.Y + yOffset, item.Z + zOffset), Map);
}
}
public override void OnMapChange()
{
base.OnMapChange();
if (m_Components == null)
return;
for (int i = 0; i < m_Components.Count; ++i)
{
Item item = m_Components[i];
item.Map = Map;
}
}
public override void OnDelete()
{
base.OnDelete();
if (m_Components == null)
return;
for (int i = 0; i < m_Components.Count; ++i)
{
Item item = m_Components[i];
item.Delete();
}
}
public override void OnAfterDelete()
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = null;
base.OnAfterDelete();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
writer.Write(m_Components);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Components = reader.ReadStrongItemList();
break;
}
}
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
}
private class DecayTimer : Timer
{
private readonly Item m_Item;
public DecayTimer(Item item)
: base(TimeSpan.FromSeconds(20.0))
{
m_Item = item;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
}