context: using System;
  using System.Collections.Generic;
  using Server.Commands;
  using Server.Gumps;
  using Server.Mobiles;
  using Server.Network;
  using Server.Spells;
  using Server.MainConfiguration;
  
  namespace Server.Items
  {
      public class PublicMoongate : Item
      {
          [Constructable]
          public PublicMoongate()
              : base(0xF6C)
          {
              Movable = false;
              Light = LightType.Circle300;
          }
  
          public PublicMoongate(Serial serial)
              : base(serial)
          {
          }
  
          public override bool ForceShowProperties
          {
              get
              {
                  return ObjectPropertyList.Enabled;
              }
          }
          public override bool HandlesOnMovement
          {
              get
              {
                  return true;
              }
          }
          public static void Initialize()
          {
              CommandSystem.Register("MoonGen", AccessLevel.Administrator, new CommandEventHandler(MoonGen_OnCommand));
          }
  
          [Usage("MoonGen")]
          [Description("Generates public moongates. Removes all old moongates.")]
          public static void MoonGen_OnCommand(CommandEventArgs e)
          {
              DeleteAll();
  
              int count = 0;
              if (MainConfig.MainTrammelGenEnabled)
              {
                  count += MoonGen(PMList.Trammel);
              }
              if (MainConfig.MainFeluccaGenEnabled)
              {
                  count += MoonGen(PMList.Felucca);
              }
              if (MainConfig.MainIlshenarGenEnabled)
              {
                  count += MoonGen(PMList.Ilshenar);
              }
              if (MainConfig.MainMalasGenEnabled)
              {
                  count += MoonGen(PMList.Malas);
              }
              if (MainConfig.MainTokunoGenEnabled)
              {
                  count += MoonGen(PMList.Tokuno);
              }
              if (MainConfig.MainTerMurGenEnabled)
              {
                  count += MoonGen(PMList.TerMur);
              }
  
              World.Broadcast(0x35, true, "{0} moongates generated.", count);
          }
  
          public override void OnDoubleClick(Mobile from)
          {
              if (!from.Player)
              {
                  return;
              }
  
              if (from.InRange(GetWorldLocation(), 1))
              {
                  UseGate(from);
              }
              else
              {
                  from.SendLocalizedMessage(500446); // That is too far away.
              }
          }
  
          public override bool OnMoveOver(Mobile m)
          {
              // Changed so criminals are not blocked by it.
              if (m.Player)
              {
                  UseGate(m);
              }
  
              return true;
          }
  
          public override void OnMovement(Mobile m, Point3D oldLocation)
          {
              if (m is PlayerMobile)
              {
                  if (!Utility.InRange(m.Location, Location, 1) && Utility.InRange(oldLocation, Location, 1))
                  {
                      m.CloseGump(typeof(MoongateGump));
                  }
              }
          }
  
          public bool UseGate(Mobile m)
          {
              if (m.Criminal)
              {
                  m.SendLocalizedMessage(1005561, "", 0x22); // Thou'rt a criminal and cannot escape so easily.
                  return false;
              }
              else if (SpellHelper.CheckCombat(m))
              {
                  m.SendLocalizedMessage(1005564, "", 0x22); // Wouldst thou flee during the heat of battle??
                  return false;
              }
              else if (m.Spell != null)
              {
                  m.SendLocalizedMessage(1049616); // You are too busy to do that at the moment.
                  return false;
              }
              else if (m.Holding != null)
              {
                  m.SendLocalizedMessage(1071955); // You cannot teleport while dragging an object.
                  return false;
              }
              else
              {
                  m.CloseGump(typeof(MoongateGump));
                  m.SendGump(new MoongateGump(m, this));
  
                  if (!m.Hidden || m.IsPlayer())
                  {
                      Effects.PlaySound(m.Location, m.Map, 0x20E);
                  }
  
                  return true;
              }
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              writer.Write((int)0); // version
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
  
              int version = reader.ReadInt();
          }
  
          private static void DeleteAll()
          {
              List<Item> list = new List<Item>();
  
              foreach (Item item in World.Items.Values)
              {
                  if (item is PublicMoongate)
                  {
                      list.Add(item);
                  }
              }
  
              foreach (Item item in list)
              {
                  item.Delete();
              }
  
              if (list.Count > 0)
              {
                  World.Broadcast(0x35, true, "{0} moongates removed.", list.Count);
              }
          }
  
          private static int MoonGen(PMList list)
          {
              foreach (PMEntry entry in list.Entries)
              {
                  Item item = new PublicMoongate();
  
                  item.MoveToWorld(entry.Location, list.Map);
  
                  if (entry.Number == 1060642) // Umbra
                  {
                      item.Hue = 0x497;
                  }
              }
  
              return list.Entries.Length;
          }
      }
  
      public class PMEntry
      {
          private readonly Point3D m_Location;
          private readonly int m_Number;
          public PMEntry(Point3D loc, int number)
          {
              m_Location = loc;
              m_Number = number;
          }
  
          public Point3D Location
          {
              get
              {
                  return m_Location;
              }
          }
          public int Number
          {
              get
              {
                  return m_Number;
              }
          }
      }
  
      public class PMList
      {
          public static readonly PMList Trammel = new PMList(1012000, 1012012, Map.Trammel, new PMEntry[]
              {
                  new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
                  new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
                  new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
                  new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
                  new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
                  new PMEntry(new Point3D(1828, 2948,-20), 1012008), // Trinsic
                  new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
                  /* Dynamic Z for Magincia to support both old and new maps. */
                  new PMEntry(new Point3D(3563, 2139, Map.Trammel.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
                  new PMEntry(new Point3D(3450, 2677, 25), 1078098)// New Haven
              });
          public static readonly PMList Felucca = new PMList(1012001, 1012013, Map.Felucca, new PMEntry[]
              {
                  new PMEntry(new Point3D(4467, 1283, 5), 1012003), // Moonglow
                  new PMEntry(new Point3D(1336, 1997, 5), 1012004), // Britain
                  new PMEntry(new Point3D(1499, 3771, 5), 1012005), // Jhelom
                  new PMEntry(new Point3D(771, 752, 5), 1012006), // Yew
                  new PMEntry(new Point3D(2701, 692, 5), 1012007), // Minoc
                  new PMEntry(new Point3D(1828, 2948,-20), 1012008), // Trinsic
                  new PMEntry(new Point3D(643, 2067, 5), 1012009), // Skara Brae
                  /* Dynamic Z for Magincia to support both old and new maps. */
                  new PMEntry(new Point3D(3563, 2139, Map.Felucca.GetAverageZ(3563, 2139)), 1012010), // (New) Magincia
                  new PMEntry(new Point3D(2711, 2234, 0), 1019001)// Buccaneer's Den
              });
          public static readonly PMList Ilshenar = new PMList(1012002, 1012014, Map.Ilshenar, new PMEntry[]
              {
  
gt:                 new PMEntry(new Point3D(1215, 467, -13), 1012015), // Compassion