context: using Server.Engines.Quests;
  using Server.Items;
  using Server.Multis;
  using System;
  using System.Collections.Generic;
  
  namespace Server.Mobiles
  {
      public class PirateCaptain : BaseShipCaptain
      {
          public static List<string> m_RedNames;
  
          public static void Initialize()
          {
              m_RedNames = new List<string>();
  
              foreach (Mobile mob in World.Mobiles.Values)
              {
                  if (mob != null && mob is PlayerMobile && mob.Murderer)
                      m_RedNames.Add(mob.Name);
              }
          }
  
          private DateTime m_NextTalk;
          private int m_PirateName;
          private int m_Adjective;
          private int m_Noun;
  
          public int PirateName => m_PirateName;
          public int Adjective => m_Adjective;
          public int Noun => m_Noun;
  
          public override bool AlwaysMurderer => true;
          public override bool Commandable => false;
  
          #region Bounty Quest
          private ProfessionalBountyQuest m_Quest;
          private bool m_IsCaught;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool IsCaught { get { return m_IsCaught; } set { m_IsCaught = value; } }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ProfessionalBountyQuest Quest { get { return m_Quest; } set { m_Quest = value; } }
          #endregion
  
          [Constructable]
          public PirateCaptain()
              : this(null)
          {
          }
  
          public PirateCaptain(BaseGalleon galleon)
              : base(galleon, AIType.AI_Melee, FightMode.Weakest, 25, 1, .2, .4)
          {
              PickRandomName();
  
              if (m_PirateName > 0 && (m_PirateName == 1116679 || m_PirateName == 1116680 || m_PirateName == 1116683))
                  Female = true;
  
              SpeechHue = Utility.RandomDyedHue();
              Title = "the dread pirate";
              Hue = Race.RandomSkinHue();
  
              Body = Female ? 0x191 : 0x190;
  
              SetStr(500, 750);
              SetDex(125, 175);
              SetInt(61, 75);
  
              SetHits(4500, 5000);
  
              SetDamage(23, 35);
  
              SetSkill(SkillName.Fencing, 115.0, 120.0);
              SetSkill(SkillName.Macing, 115.0, 120.0);
              SetSkill(SkillName.MagicResist, 115.0, 120.0);
              SetSkill(SkillName.Swords, 115.0, 120.0);
              SetSkill(SkillName.Tactics, 115.0, 120.0);
              SetSkill(SkillName.Wrestling, 115.0, 120.0);
              SetSkill(SkillName.Anatomy, 115.0, 120.0);
  
              Item hat;
              Item fancyShirt = new FancyShirt();
              Item shirt = new Shirt(GetRandomShirtHue())
              {
                  Layer = Layer.OuterTorso
              };
  
              if (Utility.RandomBool())
                  hat = new Bandana();
              else
                  hat = new TricorneHat();
  
              hat.Hue = Utility.RandomNeutralHue();
  
              AddItem(new Boots());
              AddItem(shirt);
              AddItem(fancyShirt);
              AddItem(hat);
              AddItem(new Cloak(Utility.RandomNeutralHue()));
  
              switch (Utility.Random(7))
              {
                  case 0: AddItem(new Longsword()); break;
                  case 1: AddItem(new Cutlass()); break;
                  case 2: AddItem(new Broadsword()); break;
                  case 5: AddItem(new Dagger()); break;
              }
  
              Utility.AssignRandomHair(this);
  
              Fame = 22000;
              Karma = -22000;
          }
  
          public static int GetRandomShirtHue()
          {
              return Utility.RandomMinMax(2498, 2644);
          }
  
          public override void GenerateLoot()
          {
              AddLoot(LootPack.SuperBoss, 2);
          }
  
          public void PickRandomName()
          {
              m_Adjective = Utility.RandomMinMax(1116631, 1116650);
              m_Noun = Utility.RandomMinMax(1116651, 1116670);
  
              if (m_RedNames.Count == 0 || 0.90 > Utility.RandomDouble())
                  m_PirateName = Utility.RandomMinMax(1116671, 1116686);
              else
              {
                  m_PirateName = -1;
                  Name = GetRandomRedName();
              }
          }
  
          public string GetRandomRedName()
          {
              return m_RedNames[Utility.Random(m_RedNames.Count)];
          }
  
          public override void AddNameProperties(ObjectPropertyList list)
          {
              string args;
  
              if (m_PirateName > 0)
                  args = string.Format("#{0}\t#{1}\t#{2}", m_Adjective, m_Noun, m_PirateName);
              else
                  args = string.Format("#{0}\t#{1}\t{2}", m_Adjective, m_Noun, Name);
  
              list.Add(1116690, args);
          }
  
          public override void OnThink()
          {
              base.OnThink();
  
              if (!IsCaught || m_NextTalk > DateTime.UtcNow)
                  return;
  
              IPooledEnumerable eable = GetMobilesInRange(7);
              foreach (Mobile mob in eable)
              {
                  if (mob is PlayerMobile)
                  {
                      OnTalk();
                      break;
                  }
              }
              eable.Free();
          }
  
          public void OnTalk()
          {
              Say(Utility.RandomMinMax(1149701, 1149720));
              m_NextTalk = DateTime.UtcNow + TimeSpan.FromMinutes(1);
          }
  
          #region Quest Stuff
          public bool TryBound(Mobile from, BaseQuest quest)
          {
              if (from == null || Galleon == null || !Galleon.Contains(this) || quest == null)
                  return false;
  
              if (m_IsCaught)
              {
                  from.SendMessage("That pirate is already bound to a ship!");
                  return false;
              }
  
              Combatant = null;
              Warmode = false;
              m_IsCaught = true;
              return true;
          }
  
          public void OnBound(ProfessionalBountyQuest quest)
          {
              if (quest == null || quest.Pole == null)
                  return;
  
              BindingPole pole = quest.Pole;
  
              int x = pole.X;
              int y = pole.Y;
  
              while (x == pole.X && y == pole.Y)
              {
                  x = Utility.RandomMinMax(pole.X - 1, pole.X + 1);
                  y = Utility.RandomMinMax(pole.Y - 1, pole.Y + 1);
              }
  
              Frozen = true;
  
              Item toDisarm = FindItemOnLayer(Layer.OneHanded);
              if (toDisarm == null || !toDisarm.Movable)
                  toDisarm = FindItemOnLayer(Layer.TwoHanded);
  
              if (toDisarm != null)
              {
                  if (Backpack != null)
                      Backpack.DropItem(toDisarm);
                  else
                      toDisarm.Delete();
              }
  
              m_Quest = quest;
  
              if (quest.Galleon != null)
                  quest.Galleon.CapturedCaptain = this;
  
              Timer.DelayCall(TimeSpan.FromSeconds(2.5), new TimerStateCallback(MoveCaptainToShip), new object[] { x, y, pole });
          }
  
          private void MoveCaptainToShip(object obj)
          {
              object[] objs = (object[])obj;
              int x = (int)objs[0];
              int y = (int)objs[1];
              Item pole = objs[2] as Item;
  
              if (pole != null)
                  MoveToWorld(new Point3D(x, y, pole.Z), pole.Map);
  
              Blessed = true;
              Title = "[Captured Captain]";
          }
  
          public override bool OnBeforeDeath()
          {
              List<PlayerMobile> hasQuest = new List<PlayerMobile>();
              List<DamageStore> rights = GetLootingRights();
              for (int i = 0; i < rights.Count; i++)
              {
                  if (!rights[i].m_HasRight)
                      continue;
  
                  Mobile mob = rights[i].m_Mobile;
  
                  //if they have the quest and looting rights, give them a certificate
                  if (mob is PlayerMobile && mob.NetState != null && QuestHelper.GetQuest((PlayerMobile)mob, typeof(ProfessionalBountyQuest)) != null)
                      hasQuest.Add((PlayerMobile)mob);
              }
  
              if (hasQuest.Count > 0)
              {
                  PlayerMobile questee = hasQuest[Utility.Random(hasQuest.Count)];
                  BaseQuest q = QuestHelper.GetQuest(questee, typeof(ProfessionalBountyQuest));
  
                  if (q != null && q is ProfessionalBountyQuest)
                  {
                      ((ProfessionalBountyQuest)q).OnPirateDeath(this);
                      questee.AddToBackpack(new DeathCertificate(this));
                  }
              }
  
              if (m_IsCaught && m_Quest != null)
              {
                  for (int i = 0; i < m_Quest.Objectives.Count; i++)
                  {
                      if (m_Quest.Objectives[i] is BountyQuestObjective && ((BountyQuestObjective)m_Quest.Objectives[i]).CapturedCaptain == this)
                      {
                          ((BountyQuestObjective)m_Quest.Objectives[i]).CapturedCaptain = null;
                          ((BountyQuestObjective)m_Quest.Objectives[i]).Captured = false;
                          m_Quest = null;
                      }
                  }
              }
  
              return base.OnBeforeDeath();
          }
          #endregion
  
          public PirateCaptain(Serial serial)
              : base(serial)
          {
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
              writer.Write(1);
  
              writer.Write(m_IsCaught);
              writer.Write(m_Adjective);
              writer.Write(m_Noun);
              writer.Write(m_PirateName);
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
              int version = reader.ReadInt();
  
              m_IsCaught = reader.ReadBool();
  
gt:             m_Adjective = reader.ReadInt();