context: using Server.Engines.PartySystem;
  using Server.Gumps;
  using Server.Items;
  using Server.Mobiles;
  using Server.Network;
  using System;
  
  namespace Server.Engines.Quests.Doom
  {
      public class Chyloth : BaseQuester
      {
          private static readonly int[] m_Offsets = new int[]
          {
              -1, -1,
              -1, 0,
              -1, 1,
              0, -1,
              0, 1,
              1, -1,
              1, 0,
              1, 1
          };
  
          private Mobile m_AngryAt;
          private BellOfTheDead m_Bell;
  
          [Constructable]
          public Chyloth()
              : base("the Ferryman")
          {
          }
  
          public Chyloth(Serial serial)
              : base(serial)
          {
          }
  
          public BellOfTheDead Bell
          {
              get
              {
                  return m_Bell;
              }
              set
              {
                  m_Bell = value;
              }
          }
          public Mobile AngryAt
          {
              get
              {
                  return m_AngryAt;
              }
              set
              {
                  m_AngryAt = value;
              }
          }
          public static void TeleportToFerry(Mobile from)
          {
              Point3D loc = new Point3D(408, 251, 2);
              Map map = Map.Malas;
  
              Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3728, 10, 10, 0, 0, 2023, 0);
              Effects.PlaySound(loc, map, 0x1FE);
  
              BaseCreature.TeleportPets(from, loc, map);
  
              from.MoveToWorld(loc, map);
          }
  
          public override void InitBody()
          {
              InitStats(100, 100, 25);
  
              Hue = 0x8455;
              Body = 0x190;
  
              Name = "Chyloth";
          }
  
          public override void InitOutfit()
          {
              EquipItem(new ChylothShroud());
              EquipItem(new ChylothStaff());
          }
  
          public virtual void BeginGiveWarning()
          {
              if (Deleted || m_AngryAt == null)
                  return;
  
              Timer.DelayCall(TimeSpan.FromSeconds(4.0), new TimerCallback(EndGiveWarning));
          }
  
          public virtual void EndGiveWarning()
          {
              if (Deleted || m_AngryAt == null)
                  return;
  
              PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050013, m_AngryAt.Name); // You have summoned me in vain ~1_NAME~!  Only the dead may cross!
              PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050014); // Why have you disturbed me, mortal?!?
  
              BeginSummonDragon();
          }
  
          public virtual void BeginSummonDragon()
          {
              if (Deleted || m_AngryAt == null)
                  return;
  
              Timer.DelayCall(TimeSpan.FromSeconds(30.0), new TimerCallback(EndSummonDragon));
          }
  
          public virtual void BeginRemove(TimeSpan delay)
          {
              Timer.DelayCall(delay, new TimerCallback(EndRemove));
          }
  
          public virtual void EndRemove()
          {
              if (Deleted)
                  return;
  
              Point3D loc = Location;
              Map map = Map;
  
              Effects.SendLocationParticles(EffectItem.Create(loc, map, EffectItem.DefaultDuration), 0x3728, 10, 10, 0, 0, 2023, 0);
              Effects.PlaySound(loc, map, 0x1FE);
  
              Delete();
          }
  
          public virtual void EndSummonDragon()
          {
              if (Deleted || m_AngryAt == null)
                  return;
  
              Map map = m_AngryAt.Map;
  
              if (map == null)
                  return;
  
              if (!m_AngryAt.Region.IsPartOf("Doom"))
                  return;
  
              PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050015); // Feel the wrath of my legions!!!
              PublicOverheadMessage(MessageType.Regular, 0x3B2, false, "MUHAHAHAHA HAHAH HAHA"); // A wee bit crazy, aren't we?
  
              SkeletalDragon dragon = new SkeletalDragon();
  
              int offset = Utility.Random(8) * 2;
  
              bool foundLoc = false;
  
              for (int i = 0; i < m_Offsets.Length; i += 2)
              {
                  int x = m_AngryAt.X + m_Offsets[(offset + i) % m_Offsets.Length];
                  int y = m_AngryAt.Y + m_Offsets[(offset + i + 1) % m_Offsets.Length];
  
                  if (map.CanSpawnMobile(x, y, m_AngryAt.Z))
                  {
                      dragon.MoveToWorld(new Point3D(x, y, m_AngryAt.Z), map);
                      foundLoc = true;
                      break;
                  }
                  else
                  {
                      int z = map.GetAverageZ(x, y);
  
                      if (map.CanSpawnMobile(x, y, z))
                      {
                          dragon.MoveToWorld(new Point3D(x, y, z), map);
                          foundLoc = true;
                          break;
                      }
                  }
              }
  
              if (!foundLoc)
                  dragon.MoveToWorld(m_AngryAt.Location, map);
  
              dragon.Combatant = m_AngryAt;
  
              if (m_Bell != null)
                  m_Bell.Dragon = dragon;
          }
  
          public override bool OnDragDrop(Mobile from, Item dropped)
          {
              if (dropped is GoldenSkull)
              {
                  dropped.Delete();
  
                  PublicOverheadMessage(MessageType.Regular, 0x3B2, 1050046, from.Name); // Very well, ~1_NAME~, I accept your token. You may cross.
                  BeginRemove(TimeSpan.FromSeconds(4.0));
  
                  Party p = PartySystem.Party.Get(from);
  
                  if (p != null)
                  {
  
gt:                     for (int i = 0; i < p.Members.Count; ++i)