context: using Server.Commands;
  using Server.ContextMenus;
  using Server.Engines.Exodus;
  using Server.Engines.PartySystem;
  using Server.Gumps;
  using Server.Mobiles;
  using Server.Network;
  using System;
  using System.Collections.Generic;
  using System.Linq;
  
  namespace Server.Items
  {
      public class ExodusTomeAltar : BaseDecayingItem
      {
          public override int LabelNumber => 1153602;  // Exodus Summoning Tome 
          public static ExodusTomeAltar Altar { get; set; }
          public TimeSpan DelayExit => TimeSpan.FromMinutes(10);
          private Point3D m_TeleportDest = new Point3D(764, 640, 0);
          public override int Lifespan => 420;
          public override bool UseSeconds => false;
          private readonly List<RitualArray> m_Rituals;
          private Mobile m_Owner;
          private Item m_ExodusAlterAddon;
  
          public List<RitualArray> Rituals => m_Rituals;
          public Mobile Owner
          {
              get { return m_Owner; }
              set { m_Owner = value; }
          }
  
          [Constructable]
          public ExodusTomeAltar(Mobile from)
              : base(0x1C11)
          {
              Hue = 1943;
              Movable = false;
              LootType = LootType.Regular;
              Weight = 0.0;
  
              m_Rituals = new List<RitualArray>();
              m_ExodusAlterAddon = new ExodusAlterAddon
              {
                  Movable = false
              };
          }
  
          public ExodusTomeAltar(Serial serial) : base(serial)
          {
          }
  
          private class BeginTheRitual : ContextMenuEntry
          {
              private readonly Mobile m_Mobile;
              private readonly ExodusTomeAltar m_altar;
  
              public BeginTheRitual(ExodusTomeAltar altar, Mobile from) : base(1153608, 2) // Begin the Ritual
              {
                  m_Mobile = from;
                  m_altar = altar;
  
                  if (altar.Owner != from)
                      Flags |= CMEFlags.Disabled;
              }
  
              public override void OnClick()
              {
                  if (m_altar.Owner == m_Mobile)
                  {
                      m_altar.SendConfirmationsExodus(m_Mobile);
                  }
                  else
                  {
                      m_Mobile.SendLocalizedMessage(1153610); // Only the altar owner can commence with the ritual. 
                  }
              }
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
  
              list.Add(new BeginTheRitual(this, from));
          }
  
          public override void OnDoubleClick(Mobile from)
          {
              if (!from.HasGump(typeof(AltarGump)))
              {
                  from.SendGump(new AltarGump(from));
              }
          }
  
          public override bool OnDragDrop(Mobile from, Item dropped)
          {
              return false;
          }
  
          public override void OnAfterDelete()
          {
              base.OnAfterDelete();
  
              if (m_ExodusAlterAddon != null)
                  m_ExodusAlterAddon.Delete();
  
              if (Altar != null)
                  Altar = null;
          }
  
          public override void OnMapChange()
          {
              if (Deleted)
                  return;
  
              if (m_ExodusAlterAddon != null)
                  m_ExodusAlterAddon.Map = Map;
          }
  
          public override void OnLocationChange(Point3D oldLoc)
          {
              if (Deleted)
                  return;
  
              if (m_ExodusAlterAddon != null)
                  m_ExodusAlterAddon.Location = new Point3D(X - 1, Y - 1, Z - 18);
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
              writer.Write(0); // version
  
              writer.Write(m_ExodusAlterAddon);
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
              int version = reader.ReadInt();
  
              m_ExodusAlterAddon = reader.ReadItem();
          }
  
          public bool CheckParty(Mobile from, Mobile m)
          {
              Party party = Party.Get(from);
  
              if (party != null)
              {
                  foreach (PartyMemberInfo info in party.Members)
                  {
                      if (info.Mobile == m)
                      {
                          return true;
                      }
                  }
              }
  
              return false;
          }
  
          public virtual void SendConfirmationsExodus(Mobile from)
          {
              Party party = Party.Get(from);
  
              if (party != null)
              {
                  int MemberRange = party.Members.Where(x => !from.InRange(x.Mobile, 5)).Count();
  
                  if (MemberRange != 0)
                  {
                      from.SendLocalizedMessage(1153611); // One or more members of your party are not close enough to you to perform the ritual.
                      return;
                  }
  
                  RobeofRite robe;
  
                  foreach (PartyMemberInfo info in party.Members)
                  {
                      robe = info.Mobile.FindItemOnLayer(Layer.OuterTorso) as RobeofRite;
  
                      if (!m_Rituals.Where(z => z.RitualMobile == info.Mobile && z.Ritual1 && z.Ritual2).Any() || robe == null)
                      {
                          from.SendLocalizedMessage(1153609, info.Mobile.Name); // ~1_PLAYER~ has not fulfilled all the requirements of the Ritual! You cannot commence until they do.
                          return;
                      }
                  }
  
                  foreach (PartyMemberInfo info in party.Members)
                  {
                      SendBattleground(info.Mobile);
                  }
              }
              else
              {
                  from.SendLocalizedMessage(1153596); // You must join a party with the players you wish to perform the ritual with. 
              }
          }
  
          public virtual void SendBattleground(Mobile from)
          {
              if (VerLorRegController.Active && VerLorRegController.Mobile != null && ExodusSummoningAlter.CheckExodus())
              {
                  // teleport party member
                  from.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
                  from.PlaySound(0x1FE);
                  from.MoveToWorld(m_TeleportDest, Map.Ilshenar);
  
gt:                 BaseCreature.TeleportPets(from, m_TeleportDest, Map.Ilshenar);