context: using Server.Items;
  using Server.Misc;
  using Server.Regions;
  using System;
  using System.Collections.Generic;
  using System.Linq;
  
  namespace Server.Mobiles
  {
      public class CorgulTheSoulBinder : BaseSeaChampion
      {
          private DateTime m_NextDismount;
          private DateTime m_NextArea;
          private DateTime m_NextReturn;
          private bool m_HasDone2ndSpawn;
          private CorgulAltar m_Altar;
          private readonly List<BaseCreature> m_Helpers = new List<BaseCreature>();
  
          public override bool CanDamageBoats => false;
          public override bool TaintedLifeAura => true;
          public override int Meat => 5;
          public override double TreasureMapChance => .25;
          public override int TreasureMapLevel => 7;
          public override Poison PoisonImmune => Poison.Deadly;
  
          public override bool TeleportsTo => true;
          public override TimeSpan TeleportDuration => TimeSpan.FromSeconds(Utility.RandomMinMax(10, 50));
          public override double TeleportProb => 1.0;
          public override bool TeleportsPets => true;
  
          public override Type[] UniqueList => new Type[] { typeof(CorgulsEnchantedSash), typeof(CorgulsHandbookOnMysticism), typeof(CorgulsHandbookOnTheUndead) };
          public override Type[] SharedList => new Type[] { typeof(HelmOfVengence), typeof(RingOfTheSoulbinder), typeof(RuneEngravedPegLeg), typeof(CullingBlade) };
          public override Type[] DecorativeList => new Type[] { typeof(EnchantedBladeDeed), typeof(EnchantedVortexDeed) };
  
          public override bool NoGoodies => true;
          public override bool CanGivePowerscrolls => false;
  
          private readonly int _SpawnPerLoc = 15;
  
          private readonly Point3D[] _SpawnLocs =
          {
              new Point3D(6447, 1262, 10),
              new Point3D(6424, 1279, 10),
              new Point3D(6406, 1250, 10),
              new Point3D(6423, 1220, 10),
              new Point3D(6461, 1237, 10),
          };
  
          [Constructable]
          public CorgulTheSoulBinder()
              : this(null)
          {
          }
  
          public CorgulTheSoulBinder(CorgulAltar altar)
              : base(null, AIType.AI_NecroMage, FightMode.Closest)
          {
              m_Altar = altar;
              Name = "Corgul the Soulbinder";
              BaseSoundID = 609;
              Body = 0x4C;
              Hue = 2076;
  
              m_NextDismount = DateTime.UtcNow;
              m_NextArea = DateTime.UtcNow;
              m_HasDone2ndSpawn = false;
  
              SetStr(800, 900);
              SetDex(121, 165);
              SetInt(300, 400);
  
              SetMana(4500);
              SetHits(65000);
  
              SetDamage(19, 24);
  
              SetDamageType(ResistanceType.Physical, 10);
              SetDamageType(ResistanceType.Fire, 10);
              SetDamageType(ResistanceType.Cold, 30);
              SetDamageType(ResistanceType.Poison, 40);
              SetDamageType(ResistanceType.Energy, 10);
  
              SetResistance(ResistanceType.Physical, 50, 60);
              SetResistance(ResistanceType.Fire, 80, 90);
              SetResistance(ResistanceType.Cold, 85, 95);
              SetResistance(ResistanceType.Poison, 80, 90);
              SetResistance(ResistanceType.Energy, 80, 90);
  
              SetSkill(SkillName.Wrestling, 110.0, 120.0);
              SetSkill(SkillName.Tactics, 110.0, 120.0);
              SetSkill(SkillName.Magery, 110.9, 120.0);
              SetSkill(SkillName.EvalInt, 110.9, 120.0);
              SetSkill(SkillName.Meditation, 110.9, 120.0);
              SetSkill(SkillName.Necromancy, 110.9, 120.0);
              SetSkill(SkillName.SpiritSpeak, 110.9, 120.0);
  
              Fame = 25000;
              Karma = -25000;
  
              m_NextReturn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(120, 180));
          }
  
          public double SharedChance => Map != null && Map.Rules == MapRules.FeluccaRules ? .12 : .08;
          public double DecorativeChance => Map != null && Map.Rules == MapRules.FeluccaRules ? .40 : .25;
  
          public override bool OnBeforeDeath()
          {
              List<DamageStore> rights = GetLootingRights();
  
              Mobile winner = null;
  
              if (rights != null && rights.Count > 0)
              {
                  rights.Sort();
  
                  if (rights.Count >= 5)
                      winner = rights[Utility.Random(5)].m_Mobile;
                  else if (rights.Count > 1)
                      winner = rights[Utility.Random(rights.Count)].m_Mobile;
                  else
                      winner = rights[0].m_Mobile;
              }
  
              if (winner != null)
                  GiveArtifact(winner, CreateArtifact(UniqueList));
  
              if (IsSoulboundEnemies)
                  EtherealSandShower.Do(Location, Map, 50, 100, 500);
  
              return base.OnBeforeDeath();
          }
  
          public override Item GetArtifact()
          {
              double random = Utility.RandomDouble();
  
              if (SharedChance >= random)
                  return CreateArtifact(SharedList);
              else if (DecorativeChance >= random)
                  return CreateArtifact(DecorativeList);
              return null;
          }
  
          public void SpawnHelpers()
          {
              foreach (Point3D pnt in _SpawnLocs)
              {
                  for (int i = 0; i < _SpawnPerLoc; i++)
                  {
                      BaseCreature bc;
  
                      switch (Utility.Random(7))
                      {
                          default:
                          case 0: bc = new BoundSoul(); break;
                          case 1: bc = new SoulboundApprenticeMage(); break;
                          case 2: bc = new SoulboundBattleMage(); break;
                          case 3: bc = new SoulboundPirateCaptain(); break;
                          case 4: bc = new SoulboundPirateRaider(); break;
                          case 5: bc = new SoulboundSpellSlinger(); break;
                          case 6: bc = new SoulboundSwashbuckler(); break;
                      }
  
                      m_Helpers.Add(bc);
                      SpawnMobile(bc, pnt);
                  }
              }
          }
  
          public void SpawnMobile(BaseCreature bc, Point3D p)
          {
              if (Map == null || bc == null)
              {
                  if (bc != null)
                      bc.Delete();
                  return;
              }
  
              int x, y, z = 0;
  
              for (int i = 0; i < 25; i++)
              {
                  x = Utility.RandomMinMax(p.X - 4, p.X + 4);
                  y = Utility.RandomMinMax(p.Y - 4, p.Y + 4);
                  z = Map.GetAverageZ(x, y);
  
                  if (Map.CanSpawnMobile(x, y, z))
                  {
                      p = new Point3D(x, y, z);
                      break;
                  }
              }
  
              bc.MoveToWorld(p, Map);
              bc.Home = p;
              bc.RangeHome = 5;
          }
  
          public override void OnThink()
          {
              base.OnThink();
  
              if (m_NextReturn < DateTime.UtcNow)
              {
                  Point3D p = CorgulAltar.SpawnLoc;
  
                  if (Region.IsPartOf<CorgulRegion>() && !Utility.InRange(Location, p, 15))
                  {
                      PlaySound(0x1FE);
                      FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
  
                      Location = p;
                      ProcessDelta();
  
                      PlaySound(0x1FE);
                      FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
  
                      m_NextReturn = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(120, 180));
                  }
              }
  
              if (Combatant == null)
                  return;
  
              if (DateTime.UtcNow > m_NextDismount && 0.1 > Utility.RandomDouble())
                  DoDismount();
  
              else if (DateTime.UtcNow > m_NextArea && 0.1 > Utility.RandomDouble())
                  DoAreaAttack();
  
  
gt:             if (!m_HasDone2ndSpawn && m_Helpers.Count > 0)