context: using System;
  using Server.Engines.Craft;
  using System.Linq;
  using Server.ContextMenus;
  using System.Collections.Generic;
  
  namespace Server.Items
  {
      public interface IRangeDamage
      {
          void AlterRangedDamage(ref int phys, ref int fire, ref int cold, ref int pois, ref int nrgy, ref int chaos, ref int direct);
      }
  
      [Alterable(typeof(DefTailoring), typeof(GargishLeatherWingArmor), true)]
      public class BaseQuiver : Container, ICraftable, ISetItem, IVvVItem, IOwnerRestricted, IRangeDamage, IArtifact
      {
          private bool _VvVItem;
          private Mobile _Owner;
          private string _OwnerName;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool IsVvVItem
          {
              get { return _VvVItem; }
              set { _VvVItem = value; InvalidateProperties(); }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile Owner
          {
              get { return _Owner; }
              set { _Owner = value; if (_Owner != null) _OwnerName = _Owner.Name; InvalidateProperties(); }
          }
  
          public virtual string OwnerName
          {
              get { return _OwnerName; }
              set { _OwnerName = value; InvalidateProperties(); }
          }
  
          public override int DefaultGumpID
          {
              get
              {
                  return 0x108;
              }
          }
          public override int DefaultMaxItems
          {
              get
              {
                  return 1;
              }
          }
          public override int DefaultMaxWeight
          {
              get
              {
                  return 50;
              }
          }
          public override double DefaultWeight
          {
              get
              {
                  return 2.0;
              }
          }
  
          public override bool DisplayWeight
          {
              get
              {
                  if (IsVvVItem)
                      return true;
  
                  return base.DisplayWeight;
              }
          }
  
          public virtual int ArtifactRarity { get { return 0; } }
  
          private AosAttributes m_Attributes;
          private AosSkillBonuses m_AosSkillBonuses;
          private AosElementAttributes m_Resistances;
          private int m_Capacity;
          //private int m_LowerAmmoCost;
          private int m_WeightReduction;
          private int m_DamageIncrease;
  
  		public virtual bool CanAlter { get { return true; } }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool IsArrowAmmo { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosAttributes Attributes
          {
              get
              {
                  return m_Attributes;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosSkillBonuses SkillBonuses
          {
              get
              {
                  return m_AosSkillBonuses;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AosElementAttributes Resistances
          {
              get
              {
                  return m_Resistances;
              }
              set
              {
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int Capacity
          {
              get
              {
                  return m_Capacity;
              }
              set
              {
                  m_Capacity = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int LowerAmmoCost
          {
              get
              {
                  return m_Attributes.LowerAmmoCost;
              }
              set
              {
                  m_Attributes.LowerAmmoCost = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int WeightReduction
          {
              get
              {
                  return m_WeightReduction;
              }
              set
              {
                  m_WeightReduction = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int DamageIncrease
          {
              get
              {
                  return m_DamageIncrease;
              }
              set
              {
                  m_DamageIncrease = value;
                  InvalidateProperties();
              }
          }
  
          private Mobile m_Crafter;
          private ItemQuality m_Quality;
          private bool m_PlayerConstructed;
  
          [CommandProperty(AccessLevel.GameMaster)]
          public Mobile Crafter
          {
              get
              {
                  return m_Crafter;
              }
              set
              {
                  m_Crafter = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public ItemQuality Quality
          {
              get
              {
                  return m_Quality;
              }
              set
              {
                  m_Quality = value;
                  InvalidateProperties();
              }
          }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool PlayerConstructed
          {
              get
              {
                  return m_PlayerConstructed;
              }
              set
              {
                  m_PlayerConstructed = value;
              }
          }
  		
          public Item Ammo
          {
              get
              {
                  return Items.Count > 0 ? Items[0] : null;
              }
          }
  
          public BaseQuiver()
              : this(0x2FB7)
          {
          }
  
          public BaseQuiver(int itemID)
              : base(itemID)
          {
              Weight = 2.0;
              Capacity = 500;
              Layer = Layer.Cloak;
  
              m_Attributes = new AosAttributes(this);
              m_AosSkillBonuses = new AosSkillBonuses(this);
              m_Resistances = new AosElementAttributes(this);
              m_SetAttributes = new AosAttributes(this);
              m_SetSkillBonuses = new AosSkillBonuses(this);
              DamageIncrease = 10;
              IsArrowAmmo = true;
          }
  
          public BaseQuiver(Serial serial)
              : base(serial)
          {
          }
  
          public override bool DisplaysContent { get { return false; } }
  
          public override void OnAfterDuped(Item newItem)
          {
              var quiver = newItem as BaseQuiver;
  
              if (quiver != null)
              {
                  quiver.m_Attributes = new AosAttributes(newItem, m_Attributes);
                  quiver.m_AosSkillBonuses = new AosSkillBonuses(newItem, m_AosSkillBonuses);
                  quiver.m_Resistances = new AosElementAttributes(newItem, m_Resistances);
                  quiver.m_SetAttributes = new AosAttributes(newItem, m_SetAttributes);
                  quiver.m_SetSkillBonuses = new AosSkillBonuses(newItem, m_SetSkillBonuses);
              }
  
              var wing = newItem as GargishLeatherWingArmor;
  
              if (wing != null)
              {
                  int phys, fire, cold, pois, nrgy, chaos, direct;
                  phys = fire = cold = pois = nrgy = chaos = direct = 0;
  
                  AlterRangedDamage(ref phys, ref fire, ref cold, ref pois, ref nrgy, ref chaos, ref direct);
  
                  wing.AosElementDamages.Physical = phys;
                  wing.AosElementDamages.Fire = fire;
                  wing.AosElementDamages.Cold = cold;
                  wing.AosElementDamages.Poison = pois;
                  wing.AosElementDamages.Energy = nrgy;
                  wing.AosElementDamages.Chaos = chaos;
                  wing.AosElementDamages.Direct = direct;
              }
  
              base.OnAfterDuped(newItem);
          }
  
          public override void UpdateTotal(Item sender, TotalType type, int delta)
          {
              InvalidateProperties();
  
              base.UpdateTotal(sender, type, delta);
          }
  
          public override int GetTotal(TotalType type)
          {
              int total = base.GetTotal(type);
  
              if (type == TotalType.Weight)
                  total -= total * m_WeightReduction / 100;
  
              return total;
          }
  
          private static readonly Type[] m_Ammo = new Type[]
          {
              typeof(Arrow), typeof(Bolt)
          };
  
          public bool CheckType(Item item)
          {
              Type type = item.GetType();
              Item ammo = Ammo;
  
              if (ammo != null)
              {
                  if (ammo.GetType() == type)
                      return true;
              }
              else
              {
                  for (int i = 0; i < m_Ammo.Length; i++)
                  {
                      if (type == m_Ammo[i])
                          return true;
                  }
              }
  
              return false;
          }
  
          public override bool CheckHold(Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight)
          {
              if (!Movable)
                  return false;
  
              if (!CheckType(item))
              {
                  if (message)
                      m.SendLocalizedMessage(1074836); // The container can not hold that type of object.
  
                  return false;
              }
  
              Item ammo = Ammo;
  
              if(ammo != null && ammo.Amount > 0)
              {
                  if (IsArrowAmmo && item is Bolt)
                      return false;
  
                  if (!IsArrowAmmo && item is Arrow)
                      return false;
              }
  
              if (!checkItems || Items.Count < DefaultMaxItems)
              {
                  int currentAmount = 0;
  
                  Items.ForEach(i => currentAmount += i.Amount);
  
                  if (item.Amount + currentAmount <= m_Capacity)
                      return base.CheckHold(m, item, message, checkItems, plusItems, plusWeight);
              }
  
              return false;
          }
  
          public override bool CheckStack(Mobile from, Item item)
          {
              if (!CheckType(item))
              {
                  return false;
              }
  
              Item ammo = Ammo;
  
              if (ammo != null)
              {
                  int currentAmount = Items.Sum(i => i.Amount);
  
                  if (item.Amount + currentAmount <= m_Capacity)
                      return base.CheckStack(from, item);
              }
  
              return false;
          }
  
          public override void AddItem(Item dropped)
          {
              base.AddItem(dropped);
  
              InvalidateWeight();
              IsArrowAmmo = dropped is Arrow;
          }
  		
          public override void RemoveItem(Item dropped)
          {
              base.RemoveItem(dropped);
  
              InvalidateWeight();
          }
  		
          public override void OnAdded(object parent)
          {
              if (parent is Mobile)
              {
                  Mobile mob = (Mobile)parent;
  
                  m_Attributes.AddStatBonuses(mob);
                  m_AosSkillBonuses.AddTo(mob);
  
                  BaseRanged ranged = mob.Weapon as BaseRanged;
  
                  if (ranged != null)
                      ranged.InvalidateProperties();
  
                  #region Mondain's Legacy Sets
                  if (IsSetItem)
                  {
                      m_SetEquipped = SetHelper.FullSetEquipped(mob, SetID, Pieces);
  
                      if (m_SetEquipped)
                      {
                          m_LastEquipped = true;
                          SetHelper.AddSetBonus(mob, SetID);
                      }
                  }
                  #endregion
              }
          }
  		
          public override void OnRemoved(object parent)
          {
              if (parent is Mobile)
              {
                  Mobile mob = (Mobile)parent;
  
                  m_Attributes.RemoveStatBonuses(mob);
                  m_AosSkillBonuses.Remove();
  
                  #region Mondain's Legacy Sets
                  if (IsSetItem && m_SetEquipped)
                      SetHelper.RemoveSetBonus(mob, SetID, this);
                  #endregion
              }
          }
  
          public override bool OnDragLift(Mobile from)
          {
              #region Mondain's Legacy Sets
              if (Parent is Mobile && from == Parent)
              {
                  if (IsSetItem && m_SetEquipped)
                      SetHelper.RemoveSetBonus(from, SetID, this);
              }
              #endregion
  
              return base.OnDragLift(from);
          }
  
          public override bool CanEquip(Mobile m)
          {
              #region Stygian Abyss
              if (m.Race == Race.Gargoyle)
              {
                  m.SendLocalizedMessage(1111708); // Gargoyles can't wear 
                  return false;
              }
              #endregion
  
              if (m.IsPlayer())
              {
                  if (_Owner != null && m != _Owner)
                  {
                      m.SendLocalizedMessage(501023); // You must be the owner to use this item.
                      return false;
                  }
  
                  if (this is IAccountRestricted && ((IAccountRestricted)this).Account != null)
                  {
                      Accounting.Account acct = m.Account as Accounting.Account;
  
                      if (acct == null || acct.Username != ((IAccountRestricted)this).Account)
                      {
                          m.SendLocalizedMessage(1071296); // This item is Account Bound and your character is not bound to it. You cannot use this item.
                          return false;
                      }
                  }
  
                  if (IsVvVItem && !Engines.VvV.ViceVsVirtueSystem.IsVvV(m))
                  {
                      m.SendLocalizedMessage(1155496); // This item can only be used by VvV participants!
                      return false;
                  }
              }
  
              if (m.NetState != null && !m.NetState.SupportsExpansion(Expansion.ML))
              {
                  m.SendLocalizedMessage(1072791); // You must upgrade to Mondain's Legacy in order to use that item.				
                  return false;
              }
  
              return true;
          }
  
          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 BasePhysicalResistance + m_Resistances.Physical; } }
          public override int FireResistance { get { return BaseFireResistance + m_Resistances.Fire; } }
          public override int ColdResistance { get { return BaseColdResistance + m_Resistances.Cold; } }
          public override int PoisonResistance { get { return BasePoisonResistance + m_Resistances.Poison; } }
          public override int EnergyResistance { get { return BaseEnergyResistance + m_Resistances.Energy; } }
  
          public override void AddWeightProperty(ObjectPropertyList list)
          {
              base.AddWeightProperty(list);
  
              if (IsVvVItem)
                  list.Add(1154937); // VvV Item
          }
  
          public override void AddCraftedProperties(ObjectPropertyList list)
          {
              if (OwnerName != null)
              {
                  list.Add(1153213, OwnerName);
              }
  
              if (m_Crafter != null)
              {
                  list.Add(1050043, m_Crafter.TitleName); // crafted by ~1_NAME~
              }
  
              if (m_Quality == ItemQuality.Exceptional)
                  list.Add(1063341); // exceptional
          }
  
          public override void AddNameProperties(ObjectPropertyList list)
          {
              base.AddNameProperties(list);
  
              m_AosSkillBonuses.GetProperties(list);
  
              Item ammo = Ammo;
  
              if (ammo != null)
              {
                  if (ammo is Arrow)
                      list.Add(1075265, "{0}\t{1}", ammo.Amount, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows
                  else if (ammo is Bolt)
                      list.Add(1075266, "{0}\t{1}", ammo.Amount, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ bolts
              }
              else
                  list.Add(1075265, "{0}\t{1}", 0, Capacity); // Ammo: ~1_QUANTITY~/~2_CAPACITY~ arrows
  
  
              if (ArtifactRarity > 0)
              {
                  list.Add(1061078, ArtifactRarity.ToString()); // artifact rarity ~1_val~
              }
  
              int prop;
  
              if ((prop = m_DamageIncrease) != 0)
                  list.Add(1074762, prop.ToString()); // Damage modifier: ~1_PERCENT~%
  			
              int phys, fire, cold, pois, nrgy, chaos, direct;
              phys = fire = cold = pois = nrgy = chaos = direct = 0;
  
              AlterRangedDamage(ref phys, ref fire, ref cold, ref pois, ref nrgy, ref chaos, ref direct);
  
              if (phys != 0)
                  list.Add(1060403, phys.ToString()); // physical damage ~1_val~%
  
              if (fire != 0)
                  list.Add(1060405, fire.ToString()); // fire damage ~1_val~%
  
              if (cold != 0)
                  list.Add(1060404, cold.ToString()); // cold damage ~1_val~%
  
              if (pois != 0)
                  list.Add(1060406, pois.ToString()); // poison damage ~1_val~%
  
              if (nrgy != 0)
                  list.Add(1060407, nrgy.ToString()); // energy damage ~1_val
  
              if (chaos != 0)
                  list.Add(1072846, chaos.ToString()); // chaos damage ~1_val~%
  
              if (direct != 0)
                  list.Add(1079978, direct.ToString()); // Direct Damage: ~1_PERCENT~%
  
              if ((prop = m_Attributes.DefendChance) != 0)
                  list.Add(1060408, prop.ToString()); // defense chance increase ~1_val~%
  
              if ((prop = m_Attributes.BonusDex) != 0)
                  list.Add(1060409, prop.ToString()); // dexterity bonus ~1_val~
  
              if ((prop = m_Attributes.EnhancePotions) != 0)
                  list.Add(1060411, prop.ToString()); // enhance potions ~1_val~%
  
              if ((prop = m_Attributes.CastRecovery) != 0)
                  list.Add(1060412, prop.ToString()); // faster cast recovery ~1_val~
  
              if ((prop = m_Attributes.CastSpeed) != 0)
                  list.Add(1060413, prop.ToString()); // faster casting ~1_val~
  
              if ((prop = m_Attributes.AttackChance) != 0)
                  list.Add(1060415, prop.ToString()); // hit chance increase ~1_val~%
  
              if ((prop = m_Attributes.BonusHits) != 0)
                  list.Add(1060431, prop.ToString()); // hit point increase ~1_val~
  
              if ((prop = m_Attributes.BonusInt) != 0)
                  list.Add(1060432, prop.ToString()); // intelligence bonus ~1_val~
  
              if ((prop = m_Attributes.LowerManaCost) != 0)
                  list.Add(1060433, prop.ToString()); // lower mana cost ~1_val~%
  
              if ((prop = m_Attributes.LowerRegCost) != 0)
                  list.Add(1060434, prop.ToString()); // lower reagent cost ~1_val~%	
  
              if ((prop = m_Attributes.Luck) != 0)
                  list.Add(1060436, prop.ToString()); // luck ~1_val~
  
              if ((prop = m_Attributes.BonusMana) != 0)
                  list.Add(1060439, prop.ToString()); // mana increase ~1_val~
  
              if ((prop = m_Attributes.RegenMana) != 0)
                  list.Add(1060440, prop.ToString()); // mana regeneration ~1_val~
  
              if ((prop = m_Attributes.NightSight) != 0)
                  list.Add(1060441); // night sight
  
              if ((prop = m_Attributes.ReflectPhysical) != 0)
                  list.Add(1060442, prop.ToString()); // reflect physical damage ~1_val~%
  
              if ((prop = m_Attributes.RegenStam) != 0)
                  list.Add(1060443, prop.ToString()); // stamina regeneration ~1_val~
  
              if ((prop = m_Attributes.RegenHits) != 0)
                  list.Add(1060444, prop.ToString()); // hit point regeneration ~1_val~
  
              if ((prop = m_Attributes.SpellDamage) != 0)
                  list.Add(1060483, prop.ToString()); // spell damage increase ~1_val~%
  
              if ((prop = m_Attributes.BonusStam) != 0)
                  list.Add(1060484, prop.ToString()); // stamina increase ~1_val~
  
              if ((prop = m_Attributes.BonusStr) != 0)
                  list.Add(1060485, prop.ToString()); // strength bonus ~1_val~
  
              if ((prop = m_Attributes.WeaponSpeed) != 0)
                  list.Add(1060486, prop.ToString()); // swing speed increase ~1_val~%
  
              if ((prop = m_Attributes.LowerAmmoCost) > 0)
                  list.Add(1075208, prop.ToString()); // Lower Ammo Cost ~1_Percentage~%
  
              #region Mondain's Legacy Sets
              if (IsSetItem)
              {
                  list.Add(1073491, Pieces.ToString()); // Part of a Weapon/Armor Set (~1_val~ pieces)
  
                  if (SetID == SetItem.Bestial)
                      list.Add(1151541, BestialSetHelper.GetTotalBerserk(this).ToString()); // Berserk ~1_VAL~
  
                  if (BardMasteryBonus)
                      list.Add(1151553); // Activate: Bard Mastery Bonus x2<br>(Effect: 1 min. Cooldown: 30 min.)
  
                  if (m_SetEquipped)
                  {
                      list.Add(1073492); // Full Weapon/Armor Set Present					
                      SetHelper.GetSetProperties(list, this);
                  }
              }
              #endregion
  
              base.AddResistanceProperties(list);
  
              double weight = 0;
  
              if (ammo != null)
                  weight = ammo.Weight * ammo.Amount;
  
              list.Add(1072241, "{0}\t{1}\t{2}\t{3}", Items.Count, DefaultMaxItems, (int)weight, DefaultMaxWeight); // Contents: ~1_COUNT~/~2_MAXCOUNT items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones
  
              if ((prop = m_WeightReduction) != 0)
                  list.Add(1072210, prop.ToString()); // Weight reduction: ~1_PERCENTAGE~%	
  
              #region Mondain's Legacy Sets
              if (IsSetItem && !m_SetEquipped)
              {
                  list.Add(1072378); // <br>Only when full set is present:				
                  SetHelper.GetSetProperties(list, this);
              }
              #endregion
          }
  
  		public override void OnSingleClick(Mobile from)
  		{
  			base.OnSingleClick(from);
  
  			if (m_Crafter != null)
  			{
  				LabelTo(from, 1050043, m_Crafter.TitleName); // crafted by ~1_NAME~
  			}
  		}
  
          public int SetResistBonus(ResistanceType resist)
          {
              switch (resist)
              {
                  case ResistanceType.Physical: return PhysicalResistance;
                  case ResistanceType.Fire: return FireResistance;
                  case ResistanceType.Cold: return ColdResistance;
                  case ResistanceType.Poison: return PoisonResistance;
                  case ResistanceType.Energy: return EnergyResistance;
              }
  
              return 0;
          }
          
          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,
              DamageModifier = 0x00000002,
              LowerAmmoCost = 0x00000004,
              WeightReduction = 0x00000008,
              Crafter = 0x00000010,
              Quality = 0x00000020,
              Capacity = 0x00000040,
  
              #region Mondain's Legacy Sets
              SetAttributes =      0x00000100,
              SetHue =             0x00000200,
              LastEquipped =       0x00000400,
              SetEquipped =        0x00000800,
              SetSkillAttributes = 0x00002000,
              SetPhysical =      0x00004000,
              SetFire =          0x00008000,
              SetCold =          0x00010000,
              SetPoison =        0x00020000,
              SetEnergy =        0x00040000,
              #endregion
  
              DamageIncrease = 0x00000080
          }
  
          public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
          {
              base.GetContextMenuEntries(from, list);
              if(from.Items.Contains(this) || (from.Backpack != null && IsChildOf(from.Backpack)))
                  list.Add(new RefillQuiverEntry(this));
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
  
              writer.Write(4); // version
  
              writer.Write(_VvVItem);
              writer.Write(_Owner);
              writer.Write(_OwnerName);
  
              // Version 3 takes out LowerAmmoCost
  
              SaveFlag flags = SaveFlag.None;
  
              // Version 2
              writer.Write(IsArrowAmmo);
  
              // Version 1
              m_AosSkillBonuses.Serialize(writer);
              m_Resistances.Serialize(writer);
  
              SetSaveFlag(ref flags, SaveFlag.Attributes, !m_Attributes.IsEmpty);
              //SetSaveFlag(ref flags, SaveFlag.LowerAmmoCost, m_LowerAmmoCost != 0);
              SetSaveFlag(ref flags, SaveFlag.WeightReduction, m_WeightReduction != 0);
              SetSaveFlag(ref flags, SaveFlag.DamageIncrease, m_DamageIncrease != 0);
              SetSaveFlag(ref flags, SaveFlag.Crafter, m_Crafter != null);
              SetSaveFlag(ref flags, SaveFlag.Quality, true);
              SetSaveFlag(ref flags, SaveFlag.Capacity, m_Capacity > 0);
  
              #region Mondain's Legacy Sets
              SetSaveFlag(ref flags, SaveFlag.SetAttributes, !m_SetAttributes.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.SetSkillAttributes, !m_SetSkillBonuses.IsEmpty);
              SetSaveFlag(ref flags, SaveFlag.SetHue, m_SetHue != 0);
              SetSaveFlag(ref flags, SaveFlag.LastEquipped, m_LastEquipped);
              SetSaveFlag(ref flags, SaveFlag.SetEquipped, m_SetEquipped);
              SetSaveFlag(ref flags, SaveFlag.SetPhysical, m_SetPhysicalBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.SetFire, m_SetFireBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.SetCold, m_SetColdBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.SetPoison, m_SetPoisonBonus != 0);
              SetSaveFlag(ref flags, SaveFlag.SetEnergy, m_SetEnergyBonus != 0);
              #endregion
  
              writer.WriteEncodedInt((int)flags);
  
              if (GetSaveFlag(flags, SaveFlag.Attributes))
                  m_Attributes.Serialize(writer);
  
              //if (GetSaveFlag(flags, SaveFlag.LowerAmmoCost))
              //    writer.Write((int)m_LowerAmmoCost);
  
              if (GetSaveFlag(flags, SaveFlag.WeightReduction))
                  writer.Write((int)m_WeightReduction);
  
              if (GetSaveFlag(flags, SaveFlag.DamageIncrease))
                  writer.Write((int)m_DamageIncrease);
  
              if (GetSaveFlag(flags, SaveFlag.Crafter))
                  writer.Write((Mobile)m_Crafter);
  
              if (GetSaveFlag(flags, SaveFlag.Quality))
                  writer.Write((int)m_Quality);
  
              if (GetSaveFlag(flags, SaveFlag.Capacity))
                  writer.Write((int)m_Capacity);
  
              #region Mondain's Legacy Sets
              if (GetSaveFlag(flags, SaveFlag.SetPhysical))
                  writer.WriteEncodedInt((int)m_SetPhysicalBonus);
  
              if (GetSaveFlag(flags, SaveFlag.SetFire))
                  writer.WriteEncodedInt((int)m_SetFireBonus);
  
              if (GetSaveFlag(flags, SaveFlag.SetCold))
                  writer.WriteEncodedInt((int)m_SetColdBonus);
  
              if (GetSaveFlag(flags, SaveFlag.SetPoison))
                  writer.WriteEncodedInt((int)m_SetPoisonBonus);
  
              if (GetSaveFlag(flags, SaveFlag.SetEnergy))
                  writer.WriteEncodedInt((int)m_SetEnergyBonus);
  
              if (GetSaveFlag(flags, SaveFlag.SetAttributes))
                  m_SetAttributes.Serialize(writer);
  
              if (GetSaveFlag(flags, SaveFlag.SetSkillAttributes))
                  m_SetSkillBonuses.Serialize(writer);
  
              if (GetSaveFlag(flags, SaveFlag.SetHue))
                  writer.Write((int)m_SetHue);
  
              if (GetSaveFlag(flags, SaveFlag.LastEquipped))
                  writer.Write((bool)m_LastEquipped);
  
              if (GetSaveFlag(flags, SaveFlag.SetEquipped))
                  writer.Write((bool)m_SetEquipped);
              #endregion
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
  
              int version = reader.ReadInt();
  
              switch (version)
              {
                  case 4:
                      {
                          _VvVItem = reader.ReadBool();
                          _Owner = reader.ReadMobile();
                          _OwnerName = reader.ReadString();
                          goto case 3;
                      }
                  case 3:
                  case 2:
                      IsArrowAmmo = reader.ReadBool();
                      goto case 1;
                  case 1:
                      {
                          if(version == 1)
                          {
                              IsArrowAmmo = (Ammo == null || Ammo is Arrow);
                          }
                          m_AosSkillBonuses = new AosSkillBonuses(this, reader);
  
gt:                         m_Resistances = new AosElementAttributes(this, reader);