context: using Server;
  using System;
  using Server.Multis;
  using Server.ContextMenus;
  using System.Collections.Generic;
  using Server.Gumps;
  using Server.Targeting;
  using Server.Items;
  using System.Linq;
  
  namespace Server.Mobiles
  {
      public class GalleonPilot : BaseCreature
      {
          [CommandProperty(AccessLevel.GameMaster)]
          public BaseGalleon Galleon { get; private set; }
  
          public List<Item> OriginalItems { get; private set; }
  
          public GalleonPilot(BaseGalleon galleon)
              : base(AIType.AI_Vendor, FightMode.None, 2, 1, 0.5, 2)
          {
              Body = 0x190;
              CantWalk = true;
              Galleon = galleon;
              Blessed = true;
  
              InitBody();
              InitOutfit();
  
              OriginalItems = new List<Item>();
  
              foreach (Item item in Items)
                  OriginalItems.Add(item);
  
              SetSkill(SkillName.Cartography, 100.0);
          }
  
          public virtual void InitBody()
          {
              InitStats(100, 100, 25);
  
              SpeechHue = Utility.RandomDyedHue();
              Hue = Utility.RandomSkinHue();
  
              if (Blessed && !Core.AOS)
                  NameHue = 0x35;
  
              if (Female = GetGender())
              {
                  Body = 0x191;
                  Name = NameList.RandomName("female");
              }
              else
              {
                  Body = 0x190;
                  Name = NameList.RandomName("male");
              }
          }
  
          public virtual bool GetGender()
          {
              return Utility.RandomBool();
          }
  
          public virtual int GetHairHue()
          {
              return Utility.RandomHairHue();
          }
  
          public virtual int GetShoeHue()
          {
              if (0.1 > Utility.RandomDouble())
                  return 0;
  
              return Utility.RandomNeutralHue();
          }
  
          public virtual void InitOutfit()
          {
              if (Core.SE && this.Map == Map.Tokuno)
              {
  
                  if (Utility.Random(2) == 0)
                      SetWearable(new Kasa(GetRandomHue()));
                  if (Utility.Random(2) == 0)
                      SetWearable(new Obi(GetRandomHue()));
                  if (Utility.RandomDouble() < 0.25)
                  {
                      if (Female)
                          SetWearable(new FemaleKimono(GetRandomHue()));
                      else
                      {
                          if (Utility.Random(2) == 0)
                              SetWearable(new MaleKimono(GetRandomHue()));
                          else
                              SetWearable(new Kamishimo(GetRandomHue()));
                      }
                  }
                  else
                  {
                      switch (Utility.Random(2))
                      {
                          case 0:
                              {
                                  SetWearable(new FancyShirt(GetRandomHue()));
                                  SetWearable(new JinBaori(GetRandomHue())); break;
                              }
                          case 1: SetWearable(new HakamaShita(GetRandomHue())); break;
  
                      }
                      switch (Utility.Random(2))
                      {
                          case 0: SetWearable(new Hakama(GetRandomHue())); break;
                          case 1: SetWearable(new TattsukeHakama(GetRandomHue())); break;
  
                      }
                  }
                  switch (Utility.Random(2))
                  {
                      case 0: SetWearable(new Sandals(GetShoeHue())); break;
                      case 1: SetWearable(new Waraji(GetShoeHue())); break;
  
                  }
              }
              else
              {
                  switch (Utility.Random(3))
                  {
                      case 0: SetWearable(new FancyShirt(GetRandomHue())); break;
                      case 1: SetWearable(new Doublet(GetRandomHue())); break;
                      case 2: SetWearable(new Shirt(GetRandomHue())); break;
                  }
  
  
  
                  switch (Utility.Random(4))
                  {
                      case 0: SetWearable(new Shoes(GetShoeHue())); break;
                      case 1: SetWearable(new Boots(GetShoeHue())); break;
                      case 2: SetWearable(new Sandals(GetShoeHue())); break;
                      case 3: SetWearable(new ThighBoots(GetShoeHue())); break;
                  }
  
  
  
                  if (Female)
                  {
                      switch (Utility.Random(6))
                      {
                          case 0: SetWearable(new ShortPants(GetRandomHue())); break;
                          case 1:
                          case 2: SetWearable(new Kilt(GetRandomHue())); break;
                          case 3:
                          case 4:
                          case 5: SetWearable(new Skirt(GetRandomHue())); break;
                      }
                  }
                  else
                  {
                      switch (Utility.Random(2))
                      {
                          case 0: SetWearable(new LongPants(GetRandomHue())); break;
                          case 1: SetWearable(new ShortPants(GetRandomHue())); break;
                      }
                  }
              }
              int hairHue = GetHairHue();
  
              Utility.AssignRandomHair(this, hairHue);
              Utility.AssignRandomFacialHair(this, hairHue);
          }
  
          public virtual int GetRandomHue()
          {
              switch (Utility.Random(5))
              {
                  default:
                  case 0: return Utility.RandomBlueHue();
                  case 1: return Utility.RandomGreenHue();
                  case 2: return Utility.RandomRedHue();
                  case 3: return Utility.RandomYellowHue();
                  case 4: return Utility.RandomNeutralHue();
              }
          }
  
          public void SetFacing(Direction dir)
          {
              Direction = dir;
          }
  
          public override void GetProperties(ObjectPropertyList list)
          {
              base.GetProperties(list);
  
              if (Galleon != null)
              {
                  list.Add(Galleon.Status);
                  list.Add(1116580 + (int)Galleon.DamageTaken); //State: Prisine
              }
          }
  
          public override void OnDoubleClick(Mobile from)
          {
              if (Galleon == null || !Galleon.IsOwner(from))
                  base.OnDoubleClick(from);
              else if (Galleon != null && Galleon.Contains(from))
                  Galleon.BeginRename(from);
              else if (Galleon != null)
                  Galleon.BeginDryDock(from);
          }
  
          public override bool OnDragDrop(Mobile from, Item dropped)
          {
              if (dropped is MapItem && Galleon != null && Galleon.CanCommand(from) && Galleon.Contains(from))
              {
                  Galleon.AssociateMap((MapItem)dropped);
              }
  
              return false;
          }
  
          public override bool CheckNonlocalLift(Mobile from, Item item)
          {
              if (Galleon == null || from == null)
                  return false;
  
              if (Galleon.GetSecurityLevel(from) >= SecurityLevel.Captain)
                  return true;
  
              return base.CheckNonlocalLift(from, item);
          }
  
          public override bool AllowEquipFrom(Mobile from)
          {
              if (Galleon == null || from == null)
                  return false;
  
              if (Galleon.GetSecurityLevel(from) >= SecurityLevel.Captain)
                  return true;
  
              return base.AllowEquipFrom(from);
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
  
              if (Galleon != null && Galleon.Contains(from))
              {
                  SecurityLevel level = Galleon.GetSecurityLevel(from);
  
                  if (level > SecurityLevel.NA)
                  {
                      list.Add(new EmergencyRepairEntry(this, from));
                      list.Add(new ShipRepairEntry(this, from));
                  }
  
                  if (level == SecurityLevel.Captain)
                  {
                      list.Add(new RenameShipEntry(this, from));
                      list.Add(new MoveTillermanEntry(this, from));
                      list.Add(new SecuritySettingsEntry(this, from));
                      list.Add(new ResetSecuritySettings(this, from));
                  }
              }
              else
                  list.Add(new DryDockEntry(Galleon, from));
          }
  
          private class EmergencyRepairEntry : ContextMenuEntry
          {
              private GalleonPilot m_Pilot;
              private Mobile m_From;
  
              public EmergencyRepairEntry(GalleonPilot pilot, Mobile from)
                  : base(1116589, 5) // Emergency Repairs
              {
                  m_Pilot = pilot;
                  m_From = from;
              }
  
              public override void OnClick()
              {
                  if (m_Pilot != null && m_Pilot.Galleon != null)
                  {
                      BaseGalleon g = m_Pilot.Galleon;
  
                      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}", BaseBoat.EmergencyRepairClothCost.ToString(), BaseBoat.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 GalleonPilot m_Pilot;
              private Mobile m_From;
  
              public ShipRepairEntry(GalleonPilot pilot, Mobile from)
                  : base(1116590, 5) // Permanent Repairs
              {
                  m_Pilot = pilot;
                  m_From = from;
              }
  
              public override void OnClick()
              {
                  if (m_Pilot != null && m_Pilot.Galleon != null)
                  {
                      if (!BaseGalleon.IsNearLandOrDocks(m_Pilot.Galleon))
                          m_From.SendLocalizedMessage(1116594); // Your ship must be near shore or a sea market in order to effect permanent repairs.
                      else if (m_Pilot.Galleon.DamageTaken == DamageLevel.Pristine)
                          m_From.SendLocalizedMessage(1116596); // Your ship is in pristine condition and does not need repairs.
                      else
                          m_Pilot.Galleon.TryRepairs(m_From);
                  }
              }
          }
  
          private class RenameShipEntry : ContextMenuEntry
          {
              private GalleonPilot m_Pilot;
              private Mobile m_From;
  
              public RenameShipEntry(GalleonPilot pilot, Mobile from)
                  : base(1111680, 5) // Rename
              {
                  m_Pilot = pilot;
                  m_From = from;
              }
  
              public override void OnClick()
              {
                  if (m_Pilot != null && m_Pilot.Galleon != null)
                      m_Pilot.Galleon.BeginRename(m_From);
              }
          }
  
          private class MoveTillermanEntry : ContextMenuEntry
          {
              private GalleonPilot m_Pilot;
              private Mobile m_From;
  
              public MoveTillermanEntry(GalleonPilot pilot, Mobile from)
                  : base(1116729, 5) // Move Tillerman
              {
                  m_Pilot = pilot;
                  m_From = from;
              }
  
              public override void OnClick()
              {
                  m_From.Target = new RelocateTarget(m_Pilot, m_Pilot.Galleon);
                  m_From.SendLocalizedMessage(1116736); // Where do you wish to station the pilot?
              }
          }
  
          private class RelocateTarget : Target
          {
              private GalleonPilot m_Pilot;
              private BaseGalleon m_Galleon;
  
              public RelocateTarget(GalleonPilot pilot, BaseGalleon galleon)
                  : base(12, false, TargetFlags.None)
              {
                  m_Pilot = pilot;
                  m_Galleon = galleon;
              }
  
              protected override void OnTarget(Mobile from, object targeted)
              {
                  if (targeted is IPoint3D && from.Map != null)
                  {
  
gt:                     IPoint3D pnt = (IPoint3D)targeted;