context: #region Header
  
  // **********
  // ServUO - Ethereals.cs
  // **********
  
  #endregion
  
  #region References
  
  using System;
  using Server.Engines.VeteranRewards;
  using Server.Multis;
  using Server.Spells;
  
  #endregion
  
  namespace Server.Mobiles
  {
      public class EtherealMount : Item, IMount, IMountItem, IRewardItem
      {
          private bool m_IsDonationItem;
          private int m_MountedID;
          private int m_RegularID;
          private Mobile m_Rider;
  
          [Constructable]
          public EtherealMount(int itemID, int mountID)
              : base(itemID)
          {
              m_MountedID = mountID;
              m_RegularID = itemID;
              m_Rider = null;
  
              Layer = Layer.Invalid;
  
              LootType = LootType.Blessed;
          }
  
          public EtherealMount(Serial serial)
              : base(serial)
          {
          }
  
          public override double DefaultWeight
          {
              get { return 1.0; }
          }
  
          [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
          public bool IsDonationItem
          {
              get { return m_IsDonationItem; }
              set
              {
                  m_IsDonationItem = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int MountedID
          {
              get { return m_MountedID; }
              set
              {
                  if (m_MountedID != value)
                  {
                      m_MountedID = value;
  
                      if (m_Rider != null)
                      {
                          ItemID = value;
                      }
                  }
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int RegularID
          {
              get { return m_RegularID; }
              set
              {
                  if (m_RegularID != value)
                  {
                      m_RegularID = value;
  
                      if (m_Rider == null)
                      {
                          ItemID = value;
                      }
                  }
              }
          }
  
          public override bool DisplayLootType
          {
              get { return false; }
          }
  
          public virtual int FollowerSlots
          {
              get { return 1; }
          }
  
          public virtual int EtherealHue
          {
              get { return 0x4001; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile Rider
          {
              get { return m_Rider; }
              set
              {
                  if (value == m_Rider)
                  {
                      return;
                  }
  
                  if (value == null)
                  {
                      Internalize();
                      UnmountMe();
  
                      RemoveFollowers();
                      m_Rider = null;
                  }
                  else
                  {
                      if (m_Rider != null)
                      {
                          Dismount(m_Rider);
                      }
  
                      Dismount(value);
  
                      RemoveFollowers();
                      m_Rider = value;
                      AddFollowers();
  
                      MountMe();
                  }
              }
          }
  
          public void OnRiderDamaged(int amount, Mobile from, bool willKill)
          {
          }
  
          public IMount Mount
          {
              get { return this; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool IsRewardItem { get; set; }
  
          public static void Dismount(Mobile m)
          {
              var mount = m.Mount;
  
              if (mount != null)
              {
                  mount.Rider = null;
              }
          }
  
          public static void StopMounting(Mobile mob)
          {
              if (mob.Spell is EtherealSpell)
              {
                  ((EtherealSpell) mob.Spell).Stop();
              }
          }
  
          public override void GetProperties(ObjectPropertyList list)
          {
              base.GetProperties(list);
  
              if (m_IsDonationItem)
              {
                  list.Add("Donation Ethereal");
                  list.Add("7.5 sec slower cast time if not a 9mo. Veteran");
              }
  
              if (Core.ML && IsRewardItem)
              {
                  list.Add(RewardSystem.GetRewardYearLabel(this, new object[] {})); // X Year Veteran Reward
              }
          }
  
          public void RemoveFollowers()
          {
              if (m_Rider != null)
              {
                  m_Rider.Followers -= FollowerSlots;
              }
  
              if (m_Rider != null && m_Rider.Followers < 0)
              {
                  m_Rider.Followers = 0;
              }
          }
  
          public void AddFollowers()
          {
              if (m_Rider != null)
              {
                  m_Rider.Followers += FollowerSlots;
              }
          }
  
          public virtual bool Validate(Mobile from)
          {
              #region SA
  
              if (from.Race == Race.Gargoyle)
              {
                  from.SendLocalizedMessage(1112281); // gargs can't mount
                  return false;
              }
  
              #endregion
  
              if (Parent == null)
              {
                  from.SayTo(from, 1010095); // This must be on your person to use.
                  return false;
              }
  
              if (IsRewardItem && !RewardSystem.CheckIsUsableBy(from, this, null))
              {
                  // CheckIsUsableBy sends the message
                  return false;
              }
  
              if (!BaseMount.CheckMountAllowed(from, true))
              {
                  // CheckMountAllowed sends the message
                  return false;
              }
  
              if (from.Mounted)
              {
                  from.SendLocalizedMessage(1005583); // Please dismount first.
                  return false;
              }
  
              if (from.IsBodyMod && !from.Body.IsHuman)
              {
                  from.SendLocalizedMessage(1061628); // You can't do that while polymorphed.
                  return false;
              }
  
              if (from.HasTrade)
              {
                  from.SendLocalizedMessage(1042317, "", 0x41); // You may not ride at this time
                  return false;
              }
  
              if ((from.Followers + FollowerSlots) > from.FollowersMax)
              {
                  from.SendLocalizedMessage(1049679); // You have too many followers to summon your mount.
                  return false;
              }
  
              if (!DesignContext.Check(from))
              {
                  // Check sends the message
                  return false;
              }
  
              return true;
          }
  
          public override void OnDoubleClick(Mobile from)
          {
              if (Validate(from))
              {
                  new EtherealSpell(this, from).Cast();
              }
          }
  
          public override void OnSingleClick(Mobile from)
          {
              base.OnSingleClick(from);
  
              LabelTo(from, m_IsDonationItem ? "Donation Ethereal" : "Veteran Reward");
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              writer.Write(3); // version
  
              writer.Write(m_IsDonationItem);
              writer.Write(IsRewardItem);
  
              writer.Write(m_MountedID);
              writer.Write(m_RegularID);
              writer.Write(m_Rider);
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
              LootType = LootType.Blessed;
  
              var version = reader.ReadInt();
  
              switch (version)
              {
                  case 3:
                      m_IsDonationItem = reader.ReadBool();
                      goto case 2;
                  case 2:
                      IsRewardItem = reader.ReadBool();
                      goto case 0;
                  case 1:
                      reader.ReadInt();
                      goto case 0;
                  case 0:
                  {
                      m_MountedID = reader.ReadInt();
  
gt:                     m_RegularID = reader.ReadInt();