context: using System;
  using System.Collections.Generic;
  using Server.ContextMenus;
  using Server.Engines.Craft;
  using Server.Engines.XmlSpawner2;
  using Server.Factions;
  using Server.Network;
  using Server.Mobiles;
  using AMA = Server.Items.ArmorMeditationAllowance;
  using AMT = Server.Items.ArmorMaterialType;
  
  namespace Server.Items
  {
      public abstract class BaseArmor : Item, IScissorable, IFactionItem, ICraftable, IWearableDurability, ISetItem
      {
          #region Factions
          private FactionItem m_FactionState;
  
          public FactionItem FactionItemState
          {
              get
              {
                  return this.m_FactionState;
              }
              set
              {
                  this.m_FactionState = value;
  
                  if (this.m_FactionState == null)
                      this.Hue = CraftResources.GetHue(this.Resource);
  
                  this.LootType = (this.m_FactionState == null ? LootType.Regular : LootType.Blessed);
              }
          }
          #endregion
  
          /* Armor internals work differently now (Jun 19 2003)
          * 
          * The attributes defined below default to -1.
          * If the value is -1, the corresponding virtual 'Aos/Old' property is used.
          * If not, the attribute value itself is used. Here's the list:
          *  - ArmorBase
          *  - StrBonus
          *  - DexBonus
          *  - IntBonus
          *  - StrReq
          *  - DexReq
          *  - IntReq
          *  - MeditationAllowance
          */
  
          // Instance values. These values must are unique to each armor piece.
          private int m_MaxHitPoints;
          private int m_HitPoints;
          private Mobile m_Crafter;
          private ArmorQuality m_Quality;
          private ArmorDurabilityLevel m_Durability;
          private ArmorProtectionLevel m_Protection;
          private CraftResource m_Resource;
          private bool m_Identified, m_PlayerConstructed;
          private int m_PhysicalBonus, m_FireBonus, m_ColdBonus, m_PoisonBonus, m_EnergyBonus;
  
          #region Runic Reforging
          private bool m_BlockRepair;
          private ItemPower m_ItemPower;
          private ReforgedPrefix m_ReforgedPrefix;
          private ReforgedSuffix m_ReforgedSuffix;
          #endregion
  
          #region Stygian Abyss
          private int m_GorgonLenseCharges;
          private LenseType m_GorgonLenseType;
  
          private int m_TimesImbued;
          private int m_PhysImbuing;
          private int m_FireImbuing;
          private int m_ColdImbuing;
          private int m_PoisonImbuing;
          private int m_EnergyImbuing;
          #endregion
  
          private AosAttributes m_AosAttributes;
          private AosArmorAttributes m_AosArmorAttributes;
          private AosSkillBonuses m_AosSkillBonuses;
          private SAAbsorptionAttributes m_SAAbsorptionAttributes;
  
          // Overridable values. These values are provided to override the defaults which get defined in the individual armor scripts.
          private int m_ArmorBase = -1;
          private int m_StrBonus = -1, m_DexBonus = -1, m_IntBonus = -1;
          private int m_StrReq = -1, m_DexReq = -1, m_IntReq = -1;
          private AMA m_Meditate = (AMA)(-1);
  
          public virtual bool AllowMaleWearer
          {
              get
              {
                  return true;
              }
          }
          public virtual bool AllowFemaleWearer
          {
              get
              {
                  return true;
              }
          }
  
          public abstract AMT MaterialType { get; }
  
          public virtual int RevertArmorBase
          {
              get
              {
                  return this.ArmorBase;
              }
          }
          public virtual int ArmorBase
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual AMA DefMedAllowance
          {
              get
              {
                  return AMA.None;
              }
          }
          public virtual AMA AosMedAllowance
          {
              get
              {
                  return this.DefMedAllowance;
              }
          }
          public virtual AMA OldMedAllowance
          {
              get
              {
                  return this.DefMedAllowance;
              }
          }
  
          public virtual int AosStrBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int AosDexBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int AosIntBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int AosStrReq
          {
              get
              {
                  return 0;
              }
          }
          public virtual int AosDexReq
          {
              get
              {
                  return 0;
              }
          }
          public virtual int AosIntReq
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual int OldStrBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int OldDexBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int OldIntBonus
          {
              get
              {
                  return 0;
              }
          }
          public virtual int OldStrReq
          {
              get
              {
                  return 0;
              }
          }
          public virtual int OldDexReq
          {
              get
              {
                  return 0;
              }
          }
          public virtual int OldIntReq
          {
              get
              {
                  return 0;
              }
          }
  
          public virtual bool CanFortify
          {
              get
              {
                  return m_TimesImbued == 0;
              }
          }
  
          public virtual bool UseIntOrDexProperty
          {
              get
              {
                  return false;
              }
          }
          public virtual int IntOrDexPropertyValue
          {
              get
              {
                  return 0;
              }
          }
  
          public override void OnAfterDuped(Item newItem)
          {
              BaseArmor armor = newItem as BaseArmor;
  
              if (armor == null)
                  return;
  
              armor.m_AosAttributes = new AosAttributes(newItem, this.m_AosAttributes);
              armor.m_AosArmorAttributes = new AosArmorAttributes(newItem, this.m_AosArmorAttributes);
              armor.m_AosSkillBonuses = new AosSkillBonuses(newItem, this.m_AosSkillBonuses);
              armor.m_SAAbsorptionAttributes = new SAAbsorptionAttributes(newItem, this.m_SAAbsorptionAttributes);
              armor.m_SetAttributes = new AosAttributes(newItem, this.m_SetAttributes);
              armor.m_SetSkillBonuses = new AosSkillBonuses(newItem, this.m_SetSkillBonuses);
          }
  
          #region Personal Bless Deed
          private Mobile m_BlessedBy;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile BlessedBy
          {
              get
              {
                  return this.m_BlessedBy;
              }
              set
              {
                  this.m_BlessedBy = value;
                  this.InvalidateProperties();
              }
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
  
              if (this.BlessedFor == from && this.BlessedBy == from && this.RootParent == from)
              {
                  list.Add(new UnBlessEntry(from, this));
              }
          }
  
          private class UnBlessEntry : ContextMenuEntry
          {
              private readonly Mobile m_From;
              private readonly BaseArmor m_Item;
  
              public UnBlessEntry(Mobile from, BaseArmor item)
                  : base(6208, -1)
              {
                  this.m_From = from;
                  this.m_Item = item;
              }
  
              public override void OnClick()
              {
                  this.m_Item.BlessedFor = null;
                  this.m_Item.BlessedBy = null;
  
                  Container pack = this.m_From.Backpack;
  
                  if (pack != null)
                  {
                      pack.DropItem(new PersonalBlessDeed(this.m_From));
                      this.m_From.SendLocalizedMessage(1062200); // A personal bless deed has been placed in your backpack.
                  }
              }
          }
          #endregion
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AMA MeditationAllowance
          {
              get
              {
                  return (this.m_Meditate == (AMA)(-1) ? Core.AOS ? this.AosMedAllowance : this.OldMedAllowance : this.m_Meditate);
              }
              set
              {
                  this.m_Meditate = value;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int BaseArmorRating
          {
              get
              {
                  if (this.m_ArmorBase == -1)
                      return this.ArmorBase;
                  else
                      return this.m_ArmorBase;
              }
              set
              { 
                  this.m_ArmorBase = value;
                  this.Invalidate(); 
              }
          }
  
          public double BaseArmorRatingScaled
          {
              get
              {
                  return (this.BaseArmorRating * this.ArmorScalar);
              }
          }
  
          public virtual double ArmorRating
          {
              get
              {
                  int ar = this.BaseArmorRating;
  
                  if (this.m_Protection != ArmorProtectionLevel.Regular)
                      ar += 10 + (5 * (int)this.m_Protection);
  
                  switch ( this.m_Resource )
                  {
                      case CraftResource.DullCopper:
                          ar += 2;
                          break;
                      case CraftResource.ShadowIron:
                          ar += 4;
                          break;
                      case CraftResource.Copper:
                          ar += 6;
                          break;
                      case CraftResource.Bronze:
                          ar += 8;
                          break;
                      case CraftResource.Gold:
                          ar += 10;
                          break;
                      case CraftResource.Agapite:
                          ar += 12;
                          break;
                      case CraftResource.Verite:
                          ar += 14;
                          break;
                      case CraftResource.Valorite:
                          ar += 16;
                          break;
                      case CraftResource.SpinedLeather:
                          ar += 10;
                          break;
                      case CraftResource.HornedLeather:
                          ar += 13;
                          break;
                      case CraftResource.BarbedLeather:
                          ar += 16;
                          break;
                  }
  
                  ar += -8 + (8 * (int)this.m_Quality);
                  return this.ScaleArmorByDurability(ar);
              }
          }
  
          public double ArmorRatingScaled
          {
              get
              {
                  return (this.ArmorRating * this.ArmorScalar);
              }
          }
  
          #region Stygian Abyss
          [CommandProperty(AccessLevel.GameMaster)]
          public int GorgonLenseCharges
          {
              get { return m_GorgonLenseCharges; }
              set { m_GorgonLenseCharges = value; if (value == 0) m_GorgonLenseType = LenseType.None; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public LenseType GorgonLenseType
          {
              get { return m_GorgonLenseType; }
              set { m_GorgonLenseType = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int TimesImbued
          {
              get { return m_TimesImbued; }
              set { m_TimesImbued = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int PhysImbuing
          {
              get { return m_PhysImbuing; }
              set { m_PhysImbuing = value; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int FireImbuing
          {
              get { return m_FireImbuing; }
              set { m_FireImbuing = value; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int ColdImbuing
          {
              get { return m_ColdImbuing; }
              set { m_ColdImbuing = value; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int PoisonImbuing
          {
              get { return m_PoisonImbuing; }
              set { m_PoisonImbuing = value; }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int EnergyImbuing
          {
              get { return m_EnergyImbuing; }
              set { m_EnergyImbuing = value; }
          }
          #endregion
  
          #region Runic Reforging
          [CommandProperty(AccessLevel.GameMaster)]
          public ReforgedPrefix ReforgedPrefix 
          { 
              get { return m_ReforgedPrefix; } 
              set { m_ReforgedPrefix = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ReforgedSuffix ReforgedSuffix 
          { 
              get { return m_ReforgedSuffix; }
              set { m_ReforgedSuffix = value; InvalidateProperties(); } 
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool BlockRepair
          {
              get { return m_BlockRepair; }
              set { m_BlockRepair = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ItemPower ItemPower
          { 
              get { return m_ItemPower; } 
              set { m_ItemPower = value; InvalidateProperties(); } 
          }
          #endregion
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int StrBonus
          {
              get
              {
                  return (this.m_StrBonus == -1 ? Core.AOS ? this.AosStrBonus : this.OldStrBonus : this.m_StrBonus);
              }
              set
              {
                  this.m_StrBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int DexBonus
          {
              get
              {
                  return (this.m_DexBonus == -1 ? Core.AOS ? this.AosDexBonus : this.OldDexBonus : this.m_DexBonus);
              }
              set
              {
                  this.m_DexBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int IntBonus
          {
              get
              {
                  return (this.m_IntBonus == -1 ? Core.AOS ? this.AosIntBonus : this.OldIntBonus : this.m_IntBonus);
              }
              set
              {
                  this.m_IntBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int StrRequirement
          {
              get
              {
                  return (this.m_StrReq == -1 ? Core.AOS ? this.AosStrReq : this.OldStrReq : this.m_StrReq);
              }
              set
              {
                  this.m_StrReq = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int DexRequirement
          {
              get
              {
                  return (this.m_DexReq == -1 ? Core.AOS ? this.AosDexReq : this.OldDexReq : this.m_DexReq);
              }
              set
              {
                  this.m_DexReq = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int IntRequirement
          {
              get
              {
                  return (this.m_IntReq == -1 ? Core.AOS ? this.AosIntReq : this.OldIntReq : this.m_IntReq);
              }
              set
              {
                  this.m_IntReq = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool Identified
          {
              get
              {
                  return this.m_Identified;
              }
              set
              {
                  this.m_Identified = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool PlayerConstructed
          {
              get
              {
                  return this.m_PlayerConstructed;
              }
              set
              {
                  this.m_PlayerConstructed = value;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public CraftResource Resource
          {
              get
              {
                  return this.m_Resource;
              }
              set
              {
                  if (this.m_Resource != value)
                  {
                      this.UnscaleDurability();
  
                      this.m_Resource = value;
  
                      if (CraftItem.RetainsColor(this.GetType()))
                      {
                          this.Hue = CraftResources.GetHue(this.m_Resource);
                      }
  
                      this.Invalidate();
                      this.InvalidateProperties();
  
                      if (this.Parent is Mobile)
                          ((Mobile)this.Parent).UpdateResistances();
  
                      this.ScaleDurability();
                  }
              }
          }
  
          public virtual double ArmorScalar
          {
              get
              {
                  int pos = (int)this.BodyPosition;
  
                  if (pos >= 0 && pos < m_ArmorScalars.Length)
                      return m_ArmorScalars[pos];
  
                  return 1.0;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int MaxHitPoints
          {
              get
              {
                  return this.m_MaxHitPoints;
              }
              set
              {
                  this.m_MaxHitPoints = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int HitPoints
          {
              get 
              {
                  return this.m_HitPoints;
              }
              set 
              {
                  if (value != this.m_HitPoints && this.MaxHitPoints > 0)
                  {
                      this.m_HitPoints = value;
  
                      if (this.m_HitPoints < 0)
                          this.Delete();
                      else if (this.m_HitPoints > this.MaxHitPoints)
                          this.m_HitPoints = this.MaxHitPoints;
  
                      this.InvalidateProperties();
                  }
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile Crafter
          {
              get
              {
                  return this.m_Crafter;
              }
              set
              {
                  this.m_Crafter = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ArmorQuality Quality
          {
              get
              {
                  return this.m_Quality;
              }
              set
              {
                  this.UnscaleDurability();
                  this.m_Quality = value;
                  this.Invalidate();
                  this.InvalidateProperties();
                  this.ScaleDurability();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ArmorDurabilityLevel Durability
          {
              get
              {
                  return this.m_Durability;
              }
              set
              {
                  this.UnscaleDurability();
                  this.m_Durability = value;
                  this.ScaleDurability();
                  this.InvalidateProperties();
              }
          }
  
          public virtual int ArtifactRarity
          {
              get
              {
                  return 0;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ArmorProtectionLevel ProtectionLevel
          {
              get
              {
                  return this.m_Protection;
              }
              set
              {
                  if (this.m_Protection != value)
                  {
                      this.m_Protection = value;
  
                      this.Invalidate();
                      this.InvalidateProperties();
  
                      if (this.Parent is Mobile)
                          ((Mobile)this.Parent).UpdateResistances();
                  }
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosAttributes Attributes
          {
              get
              {
                  return this.m_AosAttributes;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosArmorAttributes ArmorAttributes
          {
              get
              {
                  return this.m_AosArmorAttributes;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosSkillBonuses SkillBonuses
          {
              get
              {
                  return this.m_AosSkillBonuses;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public SAAbsorptionAttributes AbsorptionAttributes
          {
              get
              {
                  return this.m_SAAbsorptionAttributes;
              }
              set
              {
              }
          }
  
          public int ComputeStatReq(StatType type)
          {
              int v;
  
              if (type == StatType.Str)
                  v = this.StrRequirement;
              else if (type == StatType.Dex)
                  v = this.DexRequirement;
              else
                  v = this.IntRequirement;
  
              return AOS.Scale(v, 100 - this.GetLowerStatReq());
          }
  
          public int ComputeStatBonus(StatType type)
          {
              if (type == StatType.Str)
                  return this.StrBonus + this.Attributes.BonusStr;
              else if (type == StatType.Dex)
                  return this.DexBonus + this.Attributes.BonusDex;
              else
                  return this.IntBonus + this.Attributes.BonusInt;
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int PhysicalBonus
          {
              get
              {
                  return this.m_PhysicalBonus;
              }
              set
              {
                  this.m_PhysicalBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int FireBonus
          {
              get
              {
                  return this.m_FireBonus;
              }
              set
              {
                  this.m_FireBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int ColdBonus
          {
              get
              {
                  return this.m_ColdBonus;
              }
              set
              {
                  this.m_ColdBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int PoisonBonus
          {
              get
              {
                  return this.m_PoisonBonus;
              }
              set
              {
                  this.m_PoisonBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int EnergyBonus
          {
              get
              {
                  return this.m_EnergyBonus;
              }
              set
              {
                  this.m_EnergyBonus = value;
                  this.InvalidateProperties();
              }
          }
  
          public virtual int BasePhysicalResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseFireResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseColdResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BasePoisonResistance
          {
              get
              {
                  return 0;
              }
          }
          public virtual int BaseEnergyResistance
          {
              get
              {
                  return 0;
              }
          }
  
          public override int PhysicalResistance
          {
              get
              {
                  return this.BasePhysicalResistance + this.GetProtOffset() + this.GetResourceAttrs().ArmorPhysicalResist + this.m_PhysicalBonus + (this.m_SetEquipped ? this.m_SetPhysicalBonus : 0);
              }
          }
  
          public override int FireResistance
          {
              get
              {
                  return this.BaseFireResistance + this.GetProtOffset() + this.GetResourceAttrs().ArmorFireResist + this.m_FireBonus + (this.m_SetEquipped ? this.m_SetFireBonus : 0);
              }
          }
  
          public override int ColdResistance
          {
              get
              {
                  return this.BaseColdResistance + this.GetProtOffset() + this.GetResourceAttrs().ArmorColdResist + this.m_ColdBonus + (this.m_SetEquipped ? this.m_SetColdBonus : 0);
              }
          }
  
          public override int PoisonResistance
          {
              get
              {
                  return this.BasePoisonResistance + this.GetProtOffset() + this.GetResourceAttrs().ArmorPoisonResist + this.m_PoisonBonus + (this.m_SetEquipped ? this.m_SetPoisonBonus : 0);
              }
          }
  
          public override int EnergyResistance
          {
              get
              {
                  return this.BaseEnergyResistance + this.GetProtOffset() + this.GetResourceAttrs().ArmorEnergyResist + this.m_EnergyBonus + (this.m_SetEquipped ? this.m_SetEnergyBonus : 0);
              }
          }
  
          public virtual int InitMinHits
          {
              get
              {
                  return 0;
              }
          }
          public virtual int InitMaxHits
          {
              get
              {
                  return 0;
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ArmorBodyType BodyPosition
          {
              get
              {
                  switch ( this.Layer )
                  {
                      default:
                      case Layer.Neck:
                          return ArmorBodyType.Gorget;
                      case Layer.TwoHanded:
                          return ArmorBodyType.Shield;
                      case Layer.Gloves:
                          return ArmorBodyType.Gloves;
                      case Layer.Helm:
                          return ArmorBodyType.Helmet;
                      case Layer.Arms:
                          return ArmorBodyType.Arms;
  
                      case Layer.InnerLegs:
                      case Layer.OuterLegs:
                      case Layer.Pants:
                          return ArmorBodyType.Legs;
  
                      case Layer.InnerTorso:
                      case Layer.OuterTorso:
                      case Layer.Shirt:
                          return ArmorBodyType.Chest;
                  }
              }
          }
  
          public void DistributeBonuses(int amount)
          {
              for (int i = 0; i < amount; ++i)
              {
                  switch ( Utility.Random(5) )
                  {
                      case 0:
                          ++this.m_PhysicalBonus;
                          break;
                      case 1:
                          ++this.m_FireBonus;
                          break;
                      case 2:
                          ++this.m_ColdBonus;
                          break;
                      case 3:
                          ++this.m_PoisonBonus;
                          break;
                      case 4:
                          ++this.m_EnergyBonus;
                          break;
                  }
              }
  
              this.InvalidateProperties();
          }
  
          public CraftAttributeInfo GetResourceAttrs()
          {
              CraftResourceInfo info = CraftResources.GetInfo(this.m_Resource);
  
              if (info == null)
                  return CraftAttributeInfo.Blank;
  
              return info.AttributeInfo;
          }
  
          public int GetProtOffset()
          {
              switch ( this.m_Protection )
              {
                  case ArmorProtectionLevel.Guarding:
                      return 1;
                  case ArmorProtectionLevel.Hardening:
                      return 2;
                  case ArmorProtectionLevel.Fortification:
                      return 3;
                  case ArmorProtectionLevel.Invulnerability:
                      return 4;
              }
  
              return 0;
          }
  
          public void UnscaleDurability()
          {
              int scale = 100 + this.GetDurabilityBonus();
  
              this.m_HitPoints = ((this.m_HitPoints * 100) + (scale - 1)) / scale;
              this.m_MaxHitPoints = ((this.m_MaxHitPoints * 100) + (scale - 1)) / scale;
              this.InvalidateProperties();
          }
  
          public void ScaleDurability()
          {
              int scale = 100 + this.GetDurabilityBonus();
  
              this.m_HitPoints = ((this.m_HitPoints * scale) + 99) / 100;
              this.m_MaxHitPoints = ((this.m_MaxHitPoints * scale) + 99) / 100;
              this.InvalidateProperties();
          }
  
          public int GetDurabilityBonus()
          {
              int bonus = 0;
  
              if (this.m_Quality == ArmorQuality.Exceptional)
                  bonus += 20;
  
              switch ( this.m_Durability )
              {
                  case ArmorDurabilityLevel.Durable:
                      bonus += 20;
                      break;
                  case ArmorDurabilityLevel.Substantial:
                      bonus += 50;
                      break;
                  case ArmorDurabilityLevel.Massive:
                      bonus += 70;
                      break;
                  case ArmorDurabilityLevel.Fortified:
                      bonus += 100;
                      break;
                  case ArmorDurabilityLevel.Indestructible:
                      bonus += 120;
                      break;
              }
  
              if (Core.AOS)
              {
                  bonus += this.m_AosArmorAttributes.DurabilityBonus;
  
                  if (this.m_Resource == CraftResource.Heartwood)
                      return bonus;
  
                  CraftResourceInfo resInfo = CraftResources.GetInfo(this.m_Resource);
                  CraftAttributeInfo attrInfo = null;
  
                  if (resInfo != null)
                      attrInfo = resInfo.AttributeInfo;
  
                  if (attrInfo != null)
                      bonus += attrInfo.ArmorDurability;
              }
  
              return bonus;
          }
  
          public bool Scissor(Mobile from, Scissors scissors)
          {
              if (!this.IsChildOf(from.Backpack))
              {
                  from.SendLocalizedMessage(502437); // Items you wish to cut must be in your backpack.
                  return false;
              }
  
              if (Ethics.Ethic.IsImbued(this))
              {
                  from.SendLocalizedMessage(502440); // Scissors can not be used on that to produce anything.
                  return false;
              }
  
              CraftSystem system = DefTailoring.CraftSystem;
  
              CraftItem item = system.CraftItems.SearchFor(this.GetType());
  
              if (item != null && item.Resources.Count == 1 && item.Resources.GetAt(0).Amount >= 2)
              {
                  try
                  {
                      Item res = (Item)Activator.CreateInstance(CraftResources.GetInfo(this.m_Resource).ResourceTypes[0]);
  
                      this.ScissorHelper(from, res, this.m_PlayerConstructed ? (item.Resources.GetAt(0).Amount / 2) : 1);
                      return true;
                  }
                  catch
                  {
                  }
              }
  
              from.SendLocalizedMessage(502440); // Scissors can not be used on that to produce anything.
              return false;
          }
  
          private static double[] m_ArmorScalars = { 0.07, 0.07, 0.14, 0.15, 0.22, 0.35 };
  
          public static double[] ArmorScalars
          {
              get
              {
                  return m_ArmorScalars;
              }
              set
              {
                  m_ArmorScalars = value;
              }
          }
  
          public static void ValidateMobile(Mobile m)
          {
              for (int i = m.Items.Count - 1; i >= 0; --i)
              {
                  if (i >= m.Items.Count)
                      continue;
  
                  Item item = m.Items[i];
  
                  if (item is BaseArmor)
                  {
                      BaseArmor armor = (BaseArmor)item;
  
                      if (m.Race == Race.Gargoyle && !armor.CanBeWornByGargoyles)
                      {
                          m.SendLocalizedMessage(1111708); // Gargoyles can't wear this.
                          m.AddToBackpack(armor);
                      }
                      if (armor.RequiredRace != null && m.Race != armor.RequiredRace)
                      {
                          if (armor.RequiredRace == Race.Elf)
                              m.SendLocalizedMessage(1072203); // Only Elves may use this.
                          else if (armor.RequiredRace == Race.Gargoyle)
                              m.SendLocalizedMessage(1111707); // Only gargoyles can wear this.
                          else
                              m.SendMessage("Only {0} may use this.", armor.RequiredRace.PluralName);
  
                          m.AddToBackpack(armor);
                      }
                      else if (!armor.AllowMaleWearer && !m.Female && m.AccessLevel < AccessLevel.GameMaster)
                      {
                          if (armor.AllowFemaleWearer)
                              m.SendLocalizedMessage(1010388); // Only females can wear this.
                          else
                              m.SendMessage("You may not wear this.");
  
                          m.AddToBackpack(armor);
                      }
                      else if (!armor.AllowFemaleWearer && m.Female && m.AccessLevel < AccessLevel.GameMaster)
                      {
                          if (armor.AllowMaleWearer)
                              m.SendLocalizedMessage(1063343); // Only males can wear this.
                          else
                              m.SendMessage("You may not wear this.");
  
                          m.AddToBackpack(armor);
                      }
                  }
              }
          }
  
          public int GetLowerStatReq()
          {
              if (!Core.AOS)
                  return 0;
  
              int v = this.m_AosArmorAttributes.LowerStatReq;
  
              if (this.m_Resource == CraftResource.Heartwood)
                  return v;
  
              CraftResourceInfo info = CraftResources.GetInfo(this.m_Resource);
  
              if (info != null)
              {
                  CraftAttributeInfo attrInfo = info.AttributeInfo;
  
                  if (attrInfo != null)
                      v += attrInfo.ArmorLowerRequirements;
              }
  
              if (v > 100)
                  v = 100;
  
              return v;
          }
  
          public override void OnAdded(object parent)
          {
              if (parent is Mobile)
              {
                  Mobile from = (Mobile)parent;
  
                  if (Core.AOS)
                      this.m_AosSkillBonuses.AddTo(from);
  
                  #region Mondain's Legacy Sets
                  if (this.IsSetItem)
                  {
                      this.m_SetEquipped = SetHelper.FullSetEquipped(from, this.SetID, this.Pieces);
  
                      if (this.m_SetEquipped)
                      {
                          this.m_LastEquipped = true;
                          SetHelper.AddSetBonus(from, this.SetID);
                      }
                  }
                  #endregion
  
                  from.Delta(MobileDelta.Armor); // Tell them armor rating has changed
              }
          }
  
          public virtual double ScaleArmorByDurability(double armor)
          {
              int scale = 100;
  
              if (this.m_MaxHitPoints > 0 && this.m_HitPoints < this.m_MaxHitPoints)
                  scale = 50 + ((50 * this.m_HitPoints) / this.m_MaxHitPoints);
  
              return (armor * scale) / 100;
          }
  
          protected void Invalidate()
          {
              if (this.Parent is Mobile)
                  ((Mobile)this.Parent).Delta(MobileDelta.Armor); // Tell them armor rating has changed
          }
  
          public BaseArmor(Serial serial)
              : base(serial)
          {
          }
  
          private static void SetSaveFlag(ref SaveFlag flags, SaveFlag toSet, bool setIf)
          {
              if (setIf)
                  flags |= toSet;
          }
  
          private static bool GetSaveFlag(SaveFlag flags, SaveFlag toGet)
          {
              return ((flags & toGet) != 0);
          }
  
          [Flags]
          private enum SaveFlag
          {
              None = 0x00000000,
              Attributes = 0x00000001,
              ArmorAttributes = 0x00000002,
              PhysicalBonus = 0x00000004,
              FireBonus = 0x00000008,
              ColdBonus = 0x00000010,
              PoisonBonus = 0x00000020,
              EnergyBonus = 0x00000040,
              Identified = 0x00000080,
              MaxHitPoints = 0x00000100,
              HitPoints = 0x00000200,
              Crafter = 0x00000400,
              Quality = 0x00000800,
              Durability = 0x00001000,
              Protection = 0x00002000,
              Resource = 0x00004000,
              BaseArmor = 0x00008000,
              StrBonus = 0x00010000,
              DexBonus = 0x00020000,
              IntBonus = 0x00040000,
              StrReq = 0x00080000,
              DexReq = 0x00100000,
              IntReq = 0x00200000,
              MedAllowance = 0x00400000,
              SkillBonuses = 0x00800000,
              PlayerConstructed = 0x01000000,
              xAbsorptionAttributes = 0x02000000,
              TimesImbued = 0x04000000
          }
  
          #region Mondain's Legacy Sets
          private static void SetSaveFlag(ref SetFlag flags, SetFlag toSet, bool setIf)
          {
              if (setIf)
                  flags |= toSet;
          }
  
          private static bool GetSaveFlag(SetFlag flags, SetFlag toGet)
          {
              return ((flags & toGet) != 0);
          }
  
          [Flags]
          private enum SetFlag
          {
              None = 0x00000000,
              Attributes = 0x00000001,
              ArmorAttributes = 0x00000002,
              SkillBonuses = 0x00000004,
              PhysicalBonus = 0x00000008,
              FireBonus = 0x00000010,
              ColdBonus = 0x00000020,
              PoisonBonus = 0x00000040,
              EnergyBonus = 0x00000080,
              Hue = 0x00000100,
              LastEquipped = 0x00000200,
              SetEquipped = 0x00000400,
              SetSelfRepair = 0x00000800,
          }
          #endregion
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              writer.Write((int)9); // version
  
              // Version 9
              #region Runic Reforging
              writer.Write((int)m_ReforgedPrefix);
              writer.Write((int)m_ReforgedSuffix);
              writer.Write((int)m_ItemPower);
              writer.Write(m_BlockRepair);
              #endregion
  
              #region Stygian Abyss
              writer.Write(m_GorgonLenseCharges);
              writer.Write((int)m_GorgonLenseType);
  
              writer.Write(m_PhysImbuing);
              writer.Write(m_FireImbuing);
              writer.Write(m_ColdImbuing);
              writer.Write(m_PoisonImbuing);
              writer.Write(m_EnergyImbuing);
  
              // Version 8
              writer.Write((int)this.m_TimesImbued);
              #endregion
  
              writer.Write((Mobile)this.m_BlessedBy);
  
              SetFlag sflags = SetFlag.None;
  
              SetSaveFlag(ref sflags, SetFlag.Attributes, !this.m_SetAttributes.IsEmpty);
              SetSaveFlag(ref sflags, SetFlag.SkillBonuses, !this.m_SetSkillBonuses.IsEmpty);
              SetSaveFlag(ref sflags, SetFlag.PhysicalBonus, this.m_SetPhysicalBonus != 0);
              SetSaveFlag(ref sflags, SetFlag.FireBonus, this.m_SetFireBonus != 0);
              SetSaveFlag(ref sflags, SetFlag.ColdBonus, this.m_SetColdBonus != 0);
              SetSaveFlag(ref sflags, SetFlag.PoisonBonus, this.m_SetPoisonBonus != 0);
              SetSaveFlag(ref sflags, SetFlag.EnergyBonus, this.m_SetEnergyBonus != 0);
              SetSaveFlag(ref sflags, SetFlag.Hue, this.m_SetHue != 0);
              SetSaveFlag(ref sflags, SetFlag.LastEquipped, this.m_LastEquipped);
              SetSaveFlag(ref sflags, SetFlag.SetEquipped, this.m_SetEquipped);
              SetSaveFlag(ref sflags, SetFlag.SetSelfRepair, this.m_SetSelfRepair != 0);
  
              writer.WriteEncodedInt((int)sflags);
  
              if (GetSaveFlag(sflags, SetFlag.Attributes))
                  this.m_SetAttributes.Serialize(writer);
  
              if (GetSaveFlag(sflags, SetFlag.SkillBonuses))
                  this.m_SetSkillBonuses.Serialize(writer);
  
              if (GetSaveFlag(sflags, SetFlag.PhysicalBonus))
                  writer.WriteEncodedInt((int)this.m_SetPhysicalBonus);
  
              if (GetSaveFlag(sflags, SetFlag.FireBonus))
                  writer.WriteEncodedInt((int)this.m_SetFireBonus);
  
              if (GetSaveFlag(sflags, SetFlag.ColdBonus))
                  writer.WriteEncodedInt((int)this.m_SetColdBonus);
  
              if (GetSaveFlag(sflags, SetFlag.PoisonBonus))
                  writer.WriteEncodedInt((int)this.m_SetPoisonBonus);
  
              if (GetSaveFlag(sflags, SetFlag.EnergyBonus))
                  writer.WriteEncodedInt((int)this.m_SetEnergyBonus);
  
              if (GetSaveFlag(sflags, SetFlag.Hue))
                  writer.WriteEncodedInt((int)this.m_SetHue);
  
              if (GetSaveFlag(sflags, SetFlag.LastEquipped))
                  writer.Write((bool)this.m_LastEquipped);
  
              if (GetSaveFlag(sflags, SetFlag.SetEquipped))
                  writer.Write((bool)this.m_SetEquipped);
  
              if (GetSaveFlag(sflags, SetFlag.SetSelfRepair))
                  writer.WriteEncodedInt((int)this.m_SetSelfRepair);
  
              // Version 7
              SaveFlag flags = SaveFlag.None;
  
              SetSaveFlag(ref flags, SaveFlag.Attributes, !this.m_AosAttributes.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.ArmorAttributes, !this.m_AosArmorAttributes.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.PhysicalBonus, this.m_PhysicalBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.FireBonus, this.m_FireBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.ColdBonus, this.m_ColdBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.PoisonBonus, this.m_PoisonBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.EnergyBonus, this.m_EnergyBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.Identified, this.m_Identified != false);
              SetSaveFlag(ref flags, SaveFlag.MaxHitPoints, this.m_MaxHitPoints != 0);
              SetSaveFlag(ref flags, SaveFlag.HitPoints, this.m_HitPoints != 0);
              SetSaveFlag(ref flags, SaveFlag.Crafter, this.m_Crafter != null);
              SetSaveFlag(ref flags, SaveFlag.Quality, this.m_Quality != ArmorQuality.Regular);
              SetSaveFlag(ref flags, SaveFlag.Durability, this.m_Durability != ArmorDurabilityLevel.Regular);
              SetSaveFlag(ref flags, SaveFlag.Protection, this.m_Protection != ArmorProtectionLevel.Regular);
              SetSaveFlag(ref flags, SaveFlag.Resource, this.m_Resource != this.DefaultResource);
              SetSaveFlag(ref flags, SaveFlag.BaseArmor, this.m_ArmorBase != -1);
              SetSaveFlag(ref flags, SaveFlag.StrBonus, this.m_StrBonus != -1);
              SetSaveFlag(ref flags, SaveFlag.DexBonus, this.m_DexBonus != -1);
              SetSaveFlag(ref flags, SaveFlag.IntBonus, this.m_IntBonus != -1);
              SetSaveFlag(ref flags, SaveFlag.StrReq, this.m_StrReq != -1);
              SetSaveFlag(ref flags, SaveFlag.DexReq, this.m_DexReq != -1);
              SetSaveFlag(ref flags, SaveFlag.IntReq, this.m_IntReq != -1);
              SetSaveFlag(ref flags, SaveFlag.MedAllowance, this.m_Meditate != (AMA)(-1));
              SetSaveFlag(ref flags, SaveFlag.SkillBonuses, !this.m_AosSkillBonuses.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.PlayerConstructed, this.m_PlayerConstructed != false);
              SetSaveFlag(ref flags, SaveFlag.xAbsorptionAttributes, !this.m_SAAbsorptionAttributes.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.TimesImbued, this.m_TimesImbued != 0);
  
              writer.WriteEncodedInt((int)flags);
  
              if (GetSaveFlag(flags, SaveFlag.Attributes))
                  this.m_AosAttributes.Serialize(writer);
  
              if (GetSaveFlag(flags, SaveFlag.ArmorAttributes))
                  this.m_AosArmorAttributes.Serialize(writer);
  
              if (GetSaveFlag(flags, SaveFlag.PhysicalBonus))
                  writer.WriteEncodedInt((int)this.m_PhysicalBonus);
  
              if (GetSaveFlag(flags, SaveFlag.FireBonus))
                  writer.WriteEncodedInt((int)this.m_FireBonus);
  
              if (GetSaveFlag(flags, SaveFlag.ColdBonus))
                  writer.WriteEncodedInt((int)this.m_ColdBonus);
  
              if (GetSaveFlag(flags, SaveFlag.PoisonBonus))
                  writer.WriteEncodedInt((int)this.m_PoisonBonus);
  
              if (GetSaveFlag(flags, SaveFlag.EnergyBonus))
                  writer.WriteEncodedInt((int)this.m_EnergyBonus);
  
              if (GetSaveFlag(flags, SaveFlag.MaxHitPoints))
                  writer.WriteEncodedInt((int)this.m_MaxHitPoints);
  
              if (GetSaveFlag(flags, SaveFlag.HitPoints))
                  writer.WriteEncodedInt((int)this.m_HitPoints);
  
              if (GetSaveFlag(flags, SaveFlag.Crafter))
                  writer.Write((Mobile)this.m_Crafter);
  
              if (GetSaveFlag(flags, SaveFlag.Quality))
                  writer.WriteEncodedInt((int)this.m_Quality);
  
              if (GetSaveFlag(flags, SaveFlag.Durability))
                  writer.WriteEncodedInt((int)this.m_Durability);
  
              if (GetSaveFlag(flags, SaveFlag.Protection))
                  writer.WriteEncodedInt((int)this.m_Protection);
  
              if (GetSaveFlag(flags, SaveFlag.Resource))
                  writer.WriteEncodedInt((int)this.m_Resource);
  
              if (GetSaveFlag(flags, SaveFlag.BaseArmor))
                  writer.WriteEncodedInt((int)this.m_ArmorBase);
  
              if (GetSaveFlag(flags, SaveFlag.StrBonus))
                  writer.WriteEncodedInt((int)this.m_StrBonus);
  
              if (GetSaveFlag(flags, SaveFlag.DexBonus))
                  writer.WriteEncodedInt((int)this.m_DexBonus);
  
              if (GetSaveFlag(flags, SaveFlag.IntBonus))
                  writer.WriteEncodedInt((int)this.m_IntBonus);
  
              if (GetSaveFlag(flags, SaveFlag.StrReq))
                  writer.WriteEncodedInt((int)this.m_StrReq);
  
              if (GetSaveFlag(flags, SaveFlag.DexReq))
                  writer.WriteEncodedInt((int)this.m_DexReq);
  
              if (GetSaveFlag(flags, SaveFlag.IntReq))
                  writer.WriteEncodedInt((int)this.m_IntReq);
  
              if (GetSaveFlag(flags, SaveFlag.MedAllowance))
                  writer.WriteEncodedInt((int)this.m_Meditate);
  
              if (GetSaveFlag(flags, SaveFlag.SkillBonuses))
                  this.m_AosSkillBonuses.Serialize(writer);
  
              if (GetSaveFlag(flags, SaveFlag.xAbsorptionAttributes))
                  this.m_SAAbsorptionAttributes.Serialize(writer);
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
  
              int version = reader.ReadInt();
  
              switch ( version )
              {
                  case 9:
                      {
                          #region Runic Reforging
                          m_ReforgedPrefix = (ReforgedPrefix)reader.ReadInt();
                          m_ReforgedSuffix = (ReforgedSuffix)reader.ReadInt();
                          m_ItemPower = (ItemPower)reader.ReadInt();
                          m_BlockRepair = reader.ReadBool();
                          #endregion
  
                          #region Stygian Abyss
                          m_GorgonLenseCharges = reader.ReadInt();
                          m_GorgonLenseType = (LenseType)reader.ReadInt();
  
                          m_PhysImbuing = reader.ReadInt();
                          m_FireImbuing = reader.ReadInt();
                          m_ColdImbuing = reader.ReadInt();
                          m_PoisonImbuing = reader.ReadInt();
                          m_EnergyImbuing = reader.ReadInt();
                          goto case 8;
                      }
                  case 8:
                      {
                          this.m_TimesImbued = reader.ReadInt();
                          #endregion
  
                          this.m_BlessedBy = reader.ReadMobile();
  
                          SetFlag sflags = (SetFlag)reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.Attributes))
                              this.m_SetAttributes = new AosAttributes(this, reader);
                          else
                              this.m_SetAttributes = new AosAttributes(this);
  
                          if (GetSaveFlag(sflags, SetFlag.ArmorAttributes))
                              this.m_SetSelfRepair = (new AosArmorAttributes(this, reader)).SelfRepair;
  
                          if (GetSaveFlag(sflags, SetFlag.SkillBonuses))
                              this.m_SetSkillBonuses = new AosSkillBonuses(this, reader);
                          else
                              this.m_SetSkillBonuses = new AosSkillBonuses(this);
  
                          if (GetSaveFlag(sflags, SetFlag.PhysicalBonus))
                              this.m_SetPhysicalBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.FireBonus))
                              this.m_SetFireBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.ColdBonus))
                              this.m_SetColdBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.PoisonBonus))
                              this.m_SetPoisonBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.EnergyBonus))
                              this.m_SetEnergyBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.Hue))
                              this.m_SetHue = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(sflags, SetFlag.LastEquipped))
                              this.m_LastEquipped = reader.ReadBool();
  
                          if (GetSaveFlag(sflags, SetFlag.SetEquipped))
                              this.m_SetEquipped = reader.ReadBool();
  
                          if (GetSaveFlag(sflags, SetFlag.SetSelfRepair))
                              this.m_SetSelfRepair = reader.ReadEncodedInt();
  
                          goto case 5;
                      }
                  case 7:
                  case 6:
                  case 5:
                      {
                          SaveFlag flags = (SaveFlag)reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.Attributes))
                              this.m_AosAttributes = new AosAttributes(this, reader);
                          else
                              this.m_AosAttributes = new AosAttributes(this);
  
                          if (GetSaveFlag(flags, SaveFlag.ArmorAttributes))
                              this.m_AosArmorAttributes = new AosArmorAttributes(this, reader);
                          else
                              this.m_AosArmorAttributes = new AosArmorAttributes(this);
  
                          if (GetSaveFlag(flags, SaveFlag.PhysicalBonus))
                              this.m_PhysicalBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.FireBonus))
                              this.m_FireBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.ColdBonus))
                              this.m_ColdBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.PoisonBonus))
                              this.m_PoisonBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.EnergyBonus))
                              this.m_EnergyBonus = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.Identified))
                              this.m_Identified = (version >= 7 || reader.ReadBool());
  
                          if (GetSaveFlag(flags, SaveFlag.MaxHitPoints))
                              this.m_MaxHitPoints = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.HitPoints))
                              this.m_HitPoints = reader.ReadEncodedInt();
  
                          if (GetSaveFlag(flags, SaveFlag.Crafter))
                              this.m_Crafter = reader.ReadMobile();
  
                          if (GetSaveFlag(flags, SaveFlag.Quality))
                              this.m_Quality = (ArmorQuality)reader.ReadEncodedInt();
                          else
                              this.m_Quality = ArmorQuality.Regular;
  
                          if (version == 5 && this.m_Quality == ArmorQuality.Low)
                              this.m_Quality = ArmorQuality.Regular;
  
                          if (GetSaveFlag(flags, SaveFlag.Durability))
                          {
                              this.m_Durability = (ArmorDurabilityLevel)reader.ReadEncodedInt();
  
                              if (this.m_Durability > ArmorDurabilityLevel.Indestructible)
                                  this.m_Durability = ArmorDurabilityLevel.Durable;
                          }
  
                          if (GetSaveFlag(flags, SaveFlag.Protection))
                          {
                              this.m_Protection = (ArmorProtectionLevel)reader.ReadEncodedInt();
  
                              if (this.m_Protection > ArmorProtectionLevel.Invulnerability)
                                  this.m_Protection = ArmorProtectionLevel.Defense;
                          }
  
                          if (GetSaveFlag(flags, SaveFlag.Resource))
                              this.m_Resource = (CraftResource)reader.ReadEncodedInt();
                          else
                              this.m_Resource = this.DefaultResource;
  
                          if (this.m_Resource == CraftResource.None)
                              this.m_Resource = this.DefaultResource;
  
                          if (GetSaveFlag(flags, SaveFlag.BaseArmor))
                              this.m_ArmorBase = reader.ReadEncodedInt();
                          else
                              this.m_ArmorBase = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.StrBonus))
                              this.m_StrBonus = reader.ReadEncodedInt();
                          else
                              this.m_StrBonus = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.DexBonus))
                              this.m_DexBonus = reader.ReadEncodedInt();
                          else
                              this.m_DexBonus = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.IntBonus))
                              this.m_IntBonus = reader.ReadEncodedInt();
                          else
                              this.m_IntBonus = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.StrReq))
                              this.m_StrReq = reader.ReadEncodedInt();
                          else
                              this.m_StrReq = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.DexReq))
                              this.m_DexReq = reader.ReadEncodedInt();
                          else
                              this.m_DexReq = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.IntReq))
                              this.m_IntReq = reader.ReadEncodedInt();
                          else
                              this.m_IntReq = -1;
  
                          if (GetSaveFlag(flags, SaveFlag.MedAllowance))
                              this.m_Meditate = (AMA)reader.ReadEncodedInt();
                          else
                              this.m_Meditate = (AMA)(-1);
  
                          if (GetSaveFlag(flags, SaveFlag.SkillBonuses))
                              this.m_AosSkillBonuses = new AosSkillBonuses(this, reader);
  
                          if (GetSaveFlag(flags, SaveFlag.PlayerConstructed))
                              this.m_PlayerConstructed = true;
  
                          if (version > 7 && GetSaveFlag(flags, SaveFlag.xAbsorptionAttributes))
                              this.m_SAAbsorptionAttributes = new SAAbsorptionAttributes(this, reader);
                          else
                              this.m_SAAbsorptionAttributes = new SAAbsorptionAttributes(this);
  
                          break;
                      }
                  case 4:
                      {
                          this.m_AosAttributes = new AosAttributes(this, reader);
                          this.m_AosArmorAttributes = new AosArmorAttributes(this, reader);
                          goto case 3;
                      }
                  case 3:
                      {
                          this.m_PhysicalBonus = reader.ReadInt();
                          this.m_FireBonus = reader.ReadInt();
                          this.m_ColdBonus = reader.ReadInt();
                          this.m_PoisonBonus = reader.ReadInt();
                          this.m_EnergyBonus = reader.ReadInt();
                          goto case 2;
                      }
                  case 2:
                  case 1:
                      {
                          this.m_Identified = reader.ReadBool();
                          goto case 0;
                      }
                  case 0:
                      {
                          this.m_ArmorBase = reader.ReadInt();
                          this.m_MaxHitPoints = reader.ReadInt();
                          this.m_HitPoints = reader.ReadInt();
                          this.m_Crafter = reader.ReadMobile();
                          this.m_Quality = (ArmorQuality)reader.ReadInt();
                          this.m_Durability = (ArmorDurabilityLevel)reader.ReadInt();
                          this.m_Protection = (ArmorProtectionLevel)reader.ReadInt();
  
                          AMT mat = (AMT)reader.ReadInt();
  
                          if (this.m_ArmorBase == this.RevertArmorBase)
                              this.m_ArmorBase = -1;
  
                          /*m_BodyPos = (ArmorBodyType)*/reader.ReadInt();
  
                          if (version < 4)
                          {
                              this.m_AosAttributes = new AosAttributes(this);
                              this.m_AosArmorAttributes = new AosArmorAttributes(this);
                          }
  
                          if (version < 3 && this.m_Quality == ArmorQuality.Exceptional)
                              this.DistributeBonuses(6);
  
                          if (version >= 2)
                          {
                              this.m_Resource = (CraftResource)reader.ReadInt();
                          }
                          else
                          {
                              OreInfo info;
  
                              switch ( reader.ReadInt() )
                              {
                                  default:
                                  case 0:
                                      info = OreInfo.Iron;
                                      break;
                                  case 1:
                                      info = OreInfo.DullCopper;
                                      break;
                                  case 2:
                                      info = OreInfo.ShadowIron;
                                      break;
                                  case 3:
                                      info = OreInfo.Copper;
                                      break;
                                  case 4:
                                      info = OreInfo.Bronze;
                                      break;
                                  case 5:
                                      info = OreInfo.Gold;
                                      break;
                                  case 6:
                                      info = OreInfo.Agapite;
                                      break;
                                  case 7:
                                      info = OreInfo.Verite;
                                      break;
                                  case 8:
                                      info = OreInfo.Valorite;
                                      break;
                              }
  
                              this.m_Resource = CraftResources.GetFromOreInfo(info, mat);
                          }
  
                          this.m_StrBonus = reader.ReadInt();
                          this.m_DexBonus = reader.ReadInt();
                          this.m_IntBonus = reader.ReadInt();
                          this.m_StrReq = reader.ReadInt();
                          this.m_DexReq = reader.ReadInt();
                          this.m_IntReq = reader.ReadInt();
  
                          if (this.m_StrBonus == this.OldStrBonus)
                              this.m_StrBonus = -1;
  
                          if (this.m_DexBonus == this.OldDexBonus)
                              this.m_DexBonus = -1;
  
                          if (this.m_IntBonus == this.OldIntBonus)
                              this.m_IntBonus = -1;
  
                          if (this.m_StrReq == this.OldStrReq)
                              this.m_StrReq = -1;
  
                          if (this.m_DexReq == this.OldDexReq)
                              this.m_DexReq = -1;
  
                          if (this.m_IntReq == this.OldIntReq)
                              this.m_IntReq = -1;
  
                          this.m_Meditate = (AMA)reader.ReadInt();
  
                          if (this.m_Meditate == this.OldMedAllowance)
                              this.m_Meditate = (AMA)(-1);
  
                          if (this.m_Resource == CraftResource.None)
                          {
                              if (mat == ArmorMaterialType.Studded || mat == ArmorMaterialType.Leather)
                                  this.m_Resource = CraftResource.RegularLeather;
                              else if (mat == ArmorMaterialType.Spined)
                                  this.m_Resource = CraftResource.SpinedLeather;
                              else if (mat == ArmorMaterialType.Horned)
                                  this.m_Resource = CraftResource.HornedLeather;
                              else if (mat == ArmorMaterialType.Barbed)
                                  this.m_Resource = CraftResource.BarbedLeather;
                              else
                                  this.m_Resource = CraftResource.Iron;
                          }
  
                          if (this.m_MaxHitPoints == 0 && this.m_HitPoints == 0)
                              this.m_HitPoints = this.m_MaxHitPoints = Utility.RandomMinMax(this.InitMinHits, this.InitMaxHits);
  
                          break;
                      }
              }
  
              #region Mondain's Legacy Sets
              if (this.m_SetAttributes == null)
                  this.m_SetAttributes = new AosAttributes(this);
  
              if (this.m_SetSkillBonuses == null)
                  this.m_SetSkillBonuses = new AosSkillBonuses(this);
              #endregion
  
              if (this.m_AosSkillBonuses == null)
                  this.m_AosSkillBonuses = new AosSkillBonuses(this);
  
              if (Core.AOS && this.Parent is Mobile)
                  this.m_AosSkillBonuses.AddTo((Mobile)this.Parent);
  
              int strBonus = this.ComputeStatBonus(StatType.Str);
              int dexBonus = this.ComputeStatBonus(StatType.Dex);
  
gt:             int intBonus = this.ComputeStatBonus(StatType.Int);