context: using System;
  using Server.Mobiles;
  using Server.Spells;
  using System.Linq;
  using Server.Engines.Quests;
  
  namespace Server.Items
  {
      public class Whirlpool : Item
      {
          public override int LabelNumber { get { return 1033459; } } // whirlpool
  
          private bool m_Active, m_Creatures, m_CombatCheck, m_CriminalCheck;
          private Point3D m_PointDest;
          private Map m_MapDest;
          private bool m_SourceEffect;
          private bool m_DestEffect;
          private int m_SoundID;
          private TimeSpan m_Delay;
          
          [Constructable]
          public Whirlpool(Point3D pointDest, Map mapDest)
              : this(pointDest, mapDest, false)
          {
          }
  
          [Constructable]
          public Whirlpool(Point3D pointDest, Map mapDest, bool creatures)
              : base(0x3789)
          {
              Movable = false;
              Hue = 2592;
  
              m_Active = true;
              m_PointDest = pointDest;
              m_MapDest = mapDest;
              m_Creatures = creatures;
  
              m_CombatCheck = false;
              m_CriminalCheck = false;
          }
  
          public Whirlpool(Serial serial)
              : base(serial)
          {
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool SourceEffect
          {
              get { return m_SourceEffect; }
              set
              {
                  m_SourceEffect = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool DestEffect
          {
              get { return m_DestEffect; }
              set
              {
                  m_DestEffect = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int SoundID
          {
              get { return m_SoundID; }
              set
              {
                  m_SoundID = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public TimeSpan Delay
          {
              get { return m_Delay; }
              set
              {
                  m_Delay = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool Active
          {
              get { return m_Active; }
              set
              {
                  m_Active = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Point3D PointDest
          {
              get { return m_PointDest; }
              set
              {
                  m_PointDest = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Map MapDest
          {
              get { return m_MapDest; }
              set
              {
                  m_MapDest = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool Creatures
          {
              get { return m_Creatures; }
              set
              {
                  m_Creatures = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool CombatCheck
          {
              get { return m_CombatCheck; }
              set
              {
                  m_CombatCheck = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool CriminalCheck
          {
              get { return m_CriminalCheck; }
              set
              {
                  m_CriminalCheck = value;
                  InvalidateProperties();
              }
          }
  
          public override void OnDoubleClick(Mobile from)
          {
              if (from.Holding != null)
              {
                  from.SendLocalizedMessage(1071955); // You cannot teleport while dragging an object.
                  return;
              }
              PlayerMobile mobile = from as PlayerMobile;
  
              if (mobile == null)
                  return;
  
              if (mobile.IsStaff())
              {
                  StartTeleport(mobile);
                  return;
              }
  
              if (!mobile.Alive || !mobile.IsPlayer())
                  return;
  
              else if (m_Active && CanTeleport(from))
              {
                  int equipment = mobile.Items.Where(i => (i is CanvassRobe || i is BootsOfBallast || i is NictitatingLens || i is AquaPendant || i is GargishNictitatingLens) && (i.Parent is Mobile && ((Mobile)i.Parent).FindItemOnLayer(i.Layer) == i)).Count();
  
                  if (equipment < 4)
                  {
                      mobile.Kill();
                      return;
                  }
                  else
                  {
                      StartTeleport(from);
                      return;
                  }
              }
          }
  
          public virtual bool CanTeleport(Mobile m)
          {
              if (!m_Creatures && !m.Player)
              {
                  return false;
              }
              else if (m_CriminalCheck && m.Criminal)
              {
                  m.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
                  return false;
              }
              else if (m_CombatCheck && SpellHelper.CheckCombat(m))
              {
                  m.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
                  return false;
              }
  
              return true;
          }
  
          public virtual void StartTeleport(Mobile m)
          {
              if (m.Holding != null)
              {
                  m.SendLocalizedMessage(1071955); // You cannot teleport while dragging an object.
                  return;
              }
              else if (m_Delay == TimeSpan.Zero)
              {
                  DoTeleport(m);
              }
              else
              {
                  Timer.DelayCall(m_Delay, DoTeleport, m);
              }
          }
  
          public virtual void DoTeleport(Mobile m)
          {
              Map map = m_MapDest;
  
              if (map == null || map == Map.Internal)
              {
                  map = m.Map;
              }
  
              Point3D p = m_PointDest;
  
  
gt:             if (p == Point3D.Zero)