using System;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Multis;

namespace Server.Items
{
    public interface IHelm
    {
        void RefreshItemID(int mod);
    }

    public interface ICannonPlace
    {
        void RefreshItemID(int mod);
    }

    public interface ICannon
    {
        void RefreshItemID(int mod);
    }

    public class SingleHelm : BaseGalleonItem, IHelm
    {
        public SingleHelm(BaseGalleon galleon, int northItemID, Point3D initOffset)
            : base(galleon, northItemID, initOffset)
        {
            Name = "Wheel";
        }

        public SingleHelm(Serial serial)
            : base(serial)
        {
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (Ship.IsDriven)
            {
                Ship.LeaveCommand(from);
                from.SendMessage("You are no longer piloting this vessel");
            }
            else
            {
                if (Ship != null)
                {
					if (!from.Mounted)
					{
						if (from == Ship.Owner)
						{
							from.SendMessage("You are now piloting this vessel");
							Ship.TakeCommand(from);
						}
						else if (Ship.PlayerAccess != null)
						{
							if (Ship.PlayerAccess.ContainsKey((PlayerMobile)from))
							{
								if (Ship.PlayerAccess[(PlayerMobile)from] == 2)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if (Ship.PlayerAccess[(PlayerMobile)from] == 3)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if (Ship.PlayerAccess[(PlayerMobile)from] == 4)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if ((from.Guild != null) && (from.Guild == Ship.Owner.Guild))
								{
									if (Ship.Guild == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Guild == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Guild == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
								else if ((from.Party != null) && (from.Party == Ship.Owner.Party) )
								{
									if (Ship.Party == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Party == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Party == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
								else if(Ship.Public != null)
								{
									if (Ship.Public == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Public == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Public == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
							}
							else
							{
								from.SendMessage("You are not allowed to do that");
							}
						}
						else
						{
							from.SendMessage("You are not allowed to do that");
						}
					}
					else
					{
						from.SendMessage("You can not control the ship while mounted");
					}                   
                }
            }
        }

        #region Serialization
        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); //current version is 0


        }
        #endregion
    }

    public class MultiHelm : BaseGalleonMultiItem, IHelm
    {
        public MultiHelm(BaseGalleon galleon, int northItemID, Point3D initOffset, int sxNorthItemId, int dxNorthItemId)
            : base(galleon, northItemID, initOffset)
        {
            AddComponent(new GalleonMultiComponent(sxNorthItemId, this, new Point3D(-1, 0, 0)));
            AddComponent(new GalleonMultiComponent(dxNorthItemId, this, new Point3D(1, 0, 0)));
        }

        public MultiHelm(BaseGalleon galleon, int northItemID, Point3D initOffset, int relatedNorthItemId, Point3D relatedOffset)
            : base(galleon, northItemID, initOffset)
        {
            AddComponent(new GalleonMultiComponent(relatedNorthItemId, this, relatedOffset));
        }

        public MultiHelm(Serial serial)
            : base(serial)
        {
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (Ship.IsDriven)
            {
                Ship.LeaveCommand(from);
                from.SendMessage("You are no longer piloting this vessel."); //Added message; Dian
            }
            else
            {
                if (Ship != null)
                {
					if (!from.Mounted)
					{
						if (from == Ship.Owner)
						{
							from.SendMessage("You are now piloting this vessel");
							Ship.TakeCommand(from);
						}
						else if (Ship.PlayerAccess != null)
						{
							if (Ship.PlayerAccess.ContainsKey((PlayerMobile)from))
							{
								if (Ship.PlayerAccess[(PlayerMobile)from] == 2)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if (Ship.PlayerAccess[(PlayerMobile)from] == 3)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if (Ship.PlayerAccess[(PlayerMobile)from] == 4)
								{
									from.SendMessage("You are now piloting this vessel");
									Ship.TakeCommand(from);
								}
								else if ((from.Guild == Ship.Owner.Guild) && (from.Guild != null))
								{
									if (Ship.Guild == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Guild == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Guild == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
								else if ((from.Party == Ship.Owner.Party) && (from.Party != null))
								{
									if (Ship.Party == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Party == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Party == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
								else
								{
									if (Ship.Public == 2)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Public == 3)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
									else if (Ship.Public == 4)
									{
										from.SendMessage("You are now piloting this vessel");
										Ship.TakeCommand(from);
									}
								}
							}
							else
							{
								from.SendMessage("You are not allowed to do that");
							}
						}
						else
						{
							from.SendMessage("You are not allowed to do that");
						}
					}
					else
					{
						from.SendMessage("You can not control the ship while mounted");
					}

                }
            }
        }

        #region Serialization
        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); //current version is 0
        }
        #endregion
    }

    public class GalleonHold : BaseGalleonMultiContainer
    {
        private int _maxWeight;

        [CommandProperty(AccessLevel.GameMaster)]
        public override int MaxWeight { get { return _maxWeight; } }
		
        public GalleonHold(BaseGalleon galleon, int northItemId, Point3D initOffset, List<Tuple<int, Point3D>> componentList, int HoldMaxWeight = 16000)
            : base(galleon, northItemId, initOffset)
        {
            Name = "Cargo Hold";
            _maxWeight = HoldMaxWeight;

            foreach (Tuple<int, Point3D> comp in componentList)
            {
                AddComponent(new GalleonMultiComponent(comp.Item1, this, comp.Item2));
            }

            LiftOverride = true;
        }

        public GalleonHold(Serial serial)
            : base(serial)
        {
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (Ship == null || !Ship.IsOnBoard(from))
            {
                if (Ship.TillerManItem != null)
                    Ship.TillerManItem.Say(502490); // You must be on the ship to open the hold.
                if (Ship.TillerManMobile != null)
                    Ship.TillerManMobile.TillerManSay(502490); // You must be on the ship to open the hold.
            }
            else if (Ship.IsMovingShip)
            {
                if (Ship.TillerManItem != null)
                    Ship.TillerManItem.Say(502491); // I can not open the hold while the ship is moving.
                if (Ship.TillerManMobile != null)
                    Ship.TillerManMobile.TillerManSay(502491); // I can not open the hold while the ship is moving.
            }
            else
            {				
				if (Ship != null)
				{
					if (from == Ship.Owner)
					{
						base.OnDoubleClick(from);
					}
					else if (Ship.PlayerAccess != null)
					{
						if (Ship.PlayerAccess.ContainsKey((PlayerMobile)from))
						{
							if (Ship.PlayerAccess[(PlayerMobile)from] == 3)
							{
								base.OnDoubleClick(from);
							}
							else if (Ship.PlayerAccess[(PlayerMobile)from] == 4)
							{
								base.OnDoubleClick(from);
							}
							else if ((from.Guild == Ship.Owner.Guild) && (from.Guild != null))
							{
								if (Ship.Guild == 3)
								{
									base.OnDoubleClick(from);
								}
								else if (Ship.Guild == 4)
								{
									base.OnDoubleClick(from);
								}
								else if ((from.Party == Ship.Owner.Party) && (from.Party != null))
								{
									if (Ship.Party == 3)
									{
										base.OnDoubleClick(from);
									}
									else if (Ship.Party == 4)
									{
										base.OnDoubleClick(from);
									}
									else
									{
										if (Ship.Public == 3)
										{
											base.OnDoubleClick(from);
										}
										else if (Ship.Public == 4)
										{
											base.OnDoubleClick(from);
										}
									}
								}
							}
						}
					}
				}
			}
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1); // current version is 1

            // version 1
            writer.Write((int)_maxWeight);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
                        _maxWeight = (int)reader.ReadInt();
                        break;
                    }
            }
        }
    }

    public class SingleCannonPlace : BaseGalleonItem, ICannonPlace
    {
        [CommandProperty(AccessLevel.GameMaster)]
        public LightShipCannon LinkedLightCannon { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public HeavyShipCannon LinkedHeavyCannon { get; set; }

	
        public SingleCannonPlace(BaseGalleon galleon, int northItemId, Point3D initOffset)
            : base(galleon, northItemId, initOffset)
        {
            Name = " ";
        }

        public SingleCannonPlace(Serial serial)
            : base(serial)
        {
        }

        #region Serialization
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1);

            //version 1
            writer.Write(LinkedLightCannon);
			writer.Write(LinkedHeavyCannon);

        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
						LinkedLightCannon = reader.ReadItem() as LightShipCannon;
						LinkedHeavyCannon = reader.ReadItem() as HeavyShipCannon;
                        
                        break;
                    }
            }
        }
        #endregion
    }

    public class MultiCannonPlace : BaseGalleonMultiItem, ICannonPlace
    {
        public MultiCannonPlace(BaseGalleon galleon, int northItemId, Point3D initOffset, int sxNorthItemId)
            : base(galleon, northItemId, initOffset)
        {
            Name = " ";
            AddComponent(new GalleonMultiComponent(sxNorthItemId, this, new Point3D(0, 1, 0)));
        }

        public MultiCannonPlace(BaseGalleon galleon, int northItemId, Point3D initOffset, int sxNorthItemId, int dxNorthItemId)
            : base(galleon, northItemId, initOffset)
        {
            Name = " ";
            AddComponent(new GalleonMultiComponent(sxNorthItemId, this, new Point3D(0, 1, 0)));
            AddComponent(new GalleonMultiComponent(dxNorthItemId, this, new Point3D(0, -1, 0)));
        }

        public MultiCannonPlace(Serial serial)
            : base(serial)
        {
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public LightShipCannon LinkedLightCannon { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public HeavyShipCannon LinkedHeavyCannon { get; set; }


        #region Serialization
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1);

            //version 1
			writer.Write((LightShipCannon)LinkedLightCannon);
            writer.Write((HeavyShipCannon)LinkedHeavyCannon);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            switch (version)
            {
                case 1:
                    {
                        LinkedLightCannon = reader.ReadItem() as LightShipCannon;
						LinkedHeavyCannon = reader.ReadItem() as HeavyShipCannon;
						
                        break;
                    }
            }
        }
        #endregion
    }

    public class MainMast : BaseGalleonItem
    {
        #region Properties
        [CommandProperty(AccessLevel.GameMaster)]
        public override int Hue
        {
            get { return base.Hue; }
            set
            {
                if (base.Hue == value)
                    return;

                base.Hue = value;
            }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Owner
        {
            get { if (Ship != null) return Ship.Owner; return null; }
            set { if (Ship != null) Ship.Owner = value; }
        }		
		
        [CommandProperty(AccessLevel.GameMaster)]
        public bool Anchored
        {
            get { if (Ship != null) return Ship.Anchored; return false; }
            set { if (Ship != null) Ship.Anchored = value; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public ushort Durability
        {
            get { if (Ship != null) return Ship.Durability; return 0; }
            set { if (Ship != null) Ship.Durability = value; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public GalleonStatus Status
        {
            get { if (Galleon != null) return Galleon.Status; return GalleonStatus.Low; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public SpeedCode CurrentSpeed
        {
            get { if (Ship != null) return Ship.Speed; return SpeedCode.Stop; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Direction Facing
        {
            get { if (Ship != null) return Ship.Direction; return Direction.North; }
            set { if (Ship != null) Ship.Facing = value; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool IsDriven
        {
            get { if (Ship != null) return Ship.IsDriven; return false; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool IsMoving
        {
            get { if (Ship != null) return Ship.IsMoving; return false; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Direction Moving
        {
            get { if (Ship != null) return Ship.Moving; return Direction.North; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public Mobile Pilot
        {
            get { if (Ship != null) return Ship.Pilot; return null; }
            set { if (Ship != null) Ship.Pilot = value; }
        }
        #endregion

        public MainMast(BaseGalleon galleon, int baseNorthId, Point3D initOffset)
            : base(galleon, baseNorthId, initOffset)
        {
        }

        public MainMast(Serial serial)
            : base(serial)
        {
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (Ship != null)
                Ship.OnDoubleClick(from);
        }

        #region Serialization
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            reader.ReadInt();
        }
        #endregion
    }

    public class BritainHull : BaseGalleonItem
    {
        private static int[,] _internalItemIDMods = new int[,]
        {
            {1536, 1260, 1812, 2088 },
            {0, -276, 276, 552 },
            {0, -276, 276, 552 },
        };

        public BritainHull(BaseGalleon galleon, int northItemId)
            : base(galleon, northItemId)
        {
        }

        public BritainHull(Serial serial)
            : base(serial)
        {
        }

        public override void RefreshItemID(int itemIDModifier)
        {
            if (Galleon is BaseGalleon)
            {
                BaseGalleon trans = (BaseGalleon)Galleon;
                ItemID = (BaseItemID + _internalItemIDMods[(int)trans.Status, (int)trans.Facing / 2]);
            }
        }

        #region Serialization
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            reader.ReadInt();
        }
        #endregion
    }

    public enum BoatRopeSide { Port, Starboard }

    public class BoatRope : BaseGalleonItem, ILockable
    {
        [CommandProperty(AccessLevel.GameMaster, true)]
        public override bool ShareHue
        {
            get { return false; }
        }

        [CommandProperty(AccessLevel.GameMaster)]
        public BoatRopeSide Side { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool Locked { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public uint KeyValue { get; set; }

        [CommandProperty(AccessLevel.GameMaster)]
        public bool Starboard { get { return (Side == BoatRopeSide.Starboard); } }

        public BoatRope(BaseGalleon boat, int northItemID, Point3D initOffset, BoatRopeSide side, uint keyValue)
            : base(boat, northItemID, initOffset)
        {
            KeyValue = keyValue;
            Side = side;
            Locked = true;
            Movable = false;
            Name = "Mooring Line";
        }

        public BoatRope(Serial serial)
            : base(serial)
        {
        }

        public override void OnDoubleClickDead(Mobile from)
        {
            base.OnDoubleClick(from);
            from.MoveToWorld(this.Location, this.Map);
        }

        public override void OnDoubleClick(Mobile from)
        {
            if (Ship != null && !Ship.Contains(from))
            {
                this.Ship.Refresh();

                if (from == Ship.Owner)
                {
                    from.SendMessage("Welcome aboard, Captain!");
                    base.OnDoubleClick(from);
                    from.MoveToWorld(this.Location, this.Map);
					Ship.Embark(from);
                }
                else if (Ship.PlayerAccess != null)
                {
                    if (Ship.PlayerAccess.ContainsKey((PlayerMobile)from))
                    {
                        if (Ship.PlayerAccess[(PlayerMobile)from] == 1)
                        {
                            from.SendMessage("Welcome aboard, you are now a passenger!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.PlayerAccess[(PlayerMobile)from] == 2)
                        {
                            from.SendMessage("Welcome aboard, you are now a crew!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.PlayerAccess[(PlayerMobile)from] == 3)
                        {
                            from.SendMessage("Welcome aboard, you are now an officer!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.PlayerAccess[(PlayerMobile)from] == 4)
                        {
                            from.SendMessage("Welcome aboard, you are now a captain!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else
                        {
                            from.SendMessage("You don't have access to the ship");
                            base.OnDoubleClick(from);
                        }
                    }
                    else if ((Ship.Owner != null) && (from.Guild == Ship.Owner.Guild) && (from.Guild != null))
                    {
                        if (Ship.Guild == 1)
                        {
                            from.SendMessage("Welcome aboard, you are now a passenger!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Guild == 2)
                        {
                            from.SendMessage("Welcome aboard, you are now a crew!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Guild == 3)
                        {
                            from.SendMessage("Welcome aboard, you are now an officer!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Guild == 4)
                        {
                            from.SendMessage("Welcome aboard, you are now a captain!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else
                        {
                            from.SendMessage("You don't have access to the ship");
                            base.OnDoubleClick(from);
                        }
                    }
                    else if ((Ship.Owner != null) && (from.Party == Ship.Owner.Party) && (from.Party != null))
                    {
                        if (Ship.Party == 1)
                        {
                            from.SendMessage("Welcome aboard, you are now a passenger!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Party == 2)
                        {
                            from.SendMessage("Welcome aboard, you are now a crew!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Party == 3)
                        {
                            from.SendMessage("Welcome aboard, you are now an officer!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else if (Ship.Party == 4)
                        {
                            from.SendMessage("Welcome aboard, you are now a captain!");
                            base.OnDoubleClick(from);
                            from.MoveToWorld(this.Location, this.Map);
							Ship.Embark(from);
                        }
                        else
                        {
                            from.SendMessage("You don't have access to the ship");
                            base.OnDoubleClick(from);
                        }
                    }
                    else if (Ship.Public == 1)
                    {
                        from.SendMessage("Welcome aboard, you are now a passenger!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Public == 2)
                    {
                        from.SendMessage("Welcome aboard, you are now a crew!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Public == 3)
                    {
                        from.SendMessage("Welcome aboard, you are now an officer!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Public == 4)
                    {
                        from.SendMessage("Welcome aboard, you are now a captain!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else
                    {
                        from.SendMessage("You don't have access to the ship");
                        base.OnDoubleClick(from);
                    }
                }
                else if ((Ship.Owner != null) && (from.Guild == Ship.Owner.Guild) && (from.Guild != null))
                {
                    if (Ship.Guild == 1)
                    {
                        from.SendMessage("Welcome aboard, you are now a passenger!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Guild == 2)
                    {
                        from.SendMessage("Welcome aboard, you are now a crew!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Guild == 3)
                    {
                        from.SendMessage("Welcome aboard, you are now an officer!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Guild == 4)
                    {
                        from.SendMessage("Welcome aboard, you are now a captain!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else
                    {
                        from.SendMessage("You don't have access to the ship");
                        base.OnDoubleClick(from);
                    }
                }
                else if ((Ship.Owner != null) && (from.Party == Ship.Owner.Party) && (from.Party != null))
                {
                    if (Ship.Party == 1)
                    {
                        from.SendMessage("Welcome aboard, you are now a passenger!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Party == 2)
                    {
                        from.SendMessage("Welcome aboard, you are now a crew!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Party == 3)
                    {
                        from.SendMessage("Welcome aboard, you are now an officer!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else if (Ship.Party == 4)
                    {
                        from.SendMessage("Welcome aboard, you are now a captain!");
                        base.OnDoubleClick(from);
                        from.MoveToWorld(this.Location, this.Map);
						Ship.Embark(from);
                    }
                    else
                    {
                        from.SendMessage("You don't have access to the ship");
                        base.OnDoubleClick(from);
                    }
                }
                else if (Ship.Public == 1)
                {
                    from.SendMessage("Welcome aboard, you are now a passenger!");
                    base.OnDoubleClick(from);
                    from.MoveToWorld(this.Location, this.Map);
					Ship.Embark(from);
                }
                else if (Ship.Public == 2)
                {
                    from.SendMessage("Welcome aboard, you are now a crew!");
                    base.OnDoubleClick(from);
                    from.MoveToWorld(this.Location, this.Map);
					Ship.Embark(from);
                }
                else if (Ship.Public == 3)
                {
                    from.SendMessage("Welcome aboard, you are now an officer!");
                    base.OnDoubleClick(from);
                    from.MoveToWorld(this.Location, this.Map);
					Ship.Embark(from);
                }
                else if (Ship.Public == 4)
                {
                    from.SendMessage("Welcome aboard, you are now a captain!");
                    base.OnDoubleClick(from);
                    from.MoveToWorld(this.Location, this.Map);
					Ship.Embark(from);
                }
                else
                {
                    from.SendMessage("You don't have access to the ship");
                    base.OnDoubleClick(from);
                }
            }
            else if (Ship != null && Ship.Contains(from))
            {
                Map map = Map;

                if (map == null)
                    return;

                int rx = 0, ry = 0;

                if (Side == BoatRopeSide.Port)
                {
                    if (Ship.Facing == Direction.North)
                        rx = 1;
                    else if (Ship.Facing == Direction.South)
                        rx = -1;
                    else if (Ship.Facing == Direction.East)
                        ry = 1;
                    else if (Ship.Facing == Direction.West)
                        ry = -1;
                }
                else if (Side == BoatRopeSide.Starboard)
                {
                    if (Ship.Facing == Direction.North)
                        rx = -1;
                    else if (Ship.Facing == Direction.South)
                        rx = 1;
                    else if (Ship.Facing == Direction.East)
                        ry = -1;
                    else if (Ship.Facing == Direction.West)
                        ry = 1;
                }

                for (int i = 1; i <= 6; ++i)
                {
                    int x = X + (i * rx);
                    int y = Y + (i * ry);
                    int z;

                    for (int j = -16; j <= 16; ++j)
                    {
                        z = from.Z + j;

                        if (map.CanFit(x, y, z, 16, false, false) && !Server.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;

                            from.Location = new Point3D(x, y, z);
							Ship.Disembark(from);
                            return;
                        }
                    }

                    z = map.GetAverageZ(x, y);

                    if (map.CanFit(x, y, z, 16, false, false) && !Server.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;

                        from.Location = new Point3D(x, y, z);
						Ship.Disembark(from);
                        return;
                    }
                }
            }
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)1);//version

            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 1:
                    {
                        Side = (BoatRopeSide)reader.ReadInt();
                        Locked = reader.ReadBool();
                        KeyValue = reader.ReadUInt();

                        if (Ship == null)
                            Delete();

                        break;
                    }
            }
        }
    }
}
