context: using Server.Items;
  using System;
  using System.Collections.Generic;
  using System.Linq;
  
  namespace Server.Mobiles
  {
      [PropertyObject]
      public class AbilityProfile
      {
          [CommandProperty(AccessLevel.GameMaster)]
          public MagicalAbility MagicalAbility { get; private set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public AreaEffect[] AreaEffects { get; private set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public SpecialAbility[] SpecialAbilities { get; private set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public WeaponAbility[] WeaponAbilities { get; private set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public bool TokunoTame { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int RegenHits { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int RegenStam { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int RegenMana { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public int DamageIndex { get; set; }
  
          [CommandProperty(AccessLevel.GameMaster)]
          public BaseCreature Creature { get; private set; }
  
          public List<object> Advancements { get; private set; }
  
          public AbilityProfile(BaseCreature bc)
          {
              Creature = bc;
              DamageIndex = -1;
          }
  
          public void OnTame()
          {
              if (Creature.ControlMaster is PlayerMobile)
              {
                  Engines.Quests.TamingPetQuest.CheckTame((PlayerMobile)Creature.ControlMaster);
              }
  
              if (Creature.Map == Map.Tokuno)
              {
                  TokunoTame = true;
              }
          }
  
          public bool AddAbility(MagicalAbility ability, bool advancement = true)
          {
              if (Creature.Controlled)
              {
                  MagicalAbility oldAbility = MagicalAbility;
  
                  if (IsSpecialMagicalAbility(oldAbility))
                  {
                      RemoveSpecialMagicalAbility(oldAbility);
                  }
  
                  OnRemoveMagicalAbility(oldAbility, ability);
  
                  MagicalAbility = ability;
              }
              else
              {
                  MagicalAbility |= ability;
              }
  
              OnAddAbility(ability, advancement);
              return true;
          }
  
          public bool AddAbility(SpecialAbility ability, bool advancement = true)
          {
              if (SpecialAbilities == null)
              {
                  SpecialAbilities = new SpecialAbility[] { ability };
              }
              else if (!SpecialAbilities.Any(a => a == ability))
              {
                  SpecialAbility[] temp = SpecialAbilities;
  
                  SpecialAbilities = new SpecialAbility[temp.Length + 1];
  
                  for (int i = 0; i < temp.Length; i++)
                      SpecialAbilities[i] = temp[i];
  
                  SpecialAbilities[temp.Length] = ability;
              }
  
              OnAddAbility(ability, advancement);
  
              return true;
          }
  
          public bool AddAbility(AreaEffect ability, bool advancement = true)
          {
              if (AreaEffects == null)
              {
                  AreaEffects = new AreaEffect[] { ability };
              }
              else if (!AreaEffects.Any(a => a == ability))
              {
                  AreaEffect[] temp = AreaEffects;
  
                  AreaEffects = new AreaEffect[temp.Length + 1];
  
                  for (int i = 0; i < temp.Length; i++)
                      AreaEffects[i] = temp[i];
  
                  AreaEffects[temp.Length] = ability;
              }
  
              OnAddAbility(ability, advancement);
  
              return true;
          }
  
          public bool AddAbility(WeaponAbility ability, bool advancement = true)
          {
              if (WeaponAbilities == null)
              {
                  WeaponAbilities = new WeaponAbility[] { ability };
              }
              else if (!WeaponAbilities.Any(a => a == ability))
              {
                  WeaponAbility[] temp = WeaponAbilities;
  
                  WeaponAbilities = new WeaponAbility[temp.Length + 1];
  
                  for (int i = 0; i < temp.Length; i++)
                      WeaponAbilities[i] = temp[i];
  
                  WeaponAbilities[temp.Length] = ability;
              }
  
              OnAddAbility(ability, advancement);
  
              return true;
          }
  
          public void RemoveAbility(MagicalAbility ability)
          {
              if ((MagicalAbility & ability) != 0)
              {
                  MagicalAbility ^= ability;
                  RemovePetAdvancement(ability);
              }
          }
  
          public void RemoveAbility(SpecialAbility ability)
          {
              if (SpecialAbilities == null || !SpecialAbilities.Any(a => a == ability))
                  return;
  
              List<SpecialAbility> list = SpecialAbilities.ToList();
  
              list.Remove(ability);
              RemovePetAdvancement(ability);
  
              SpecialAbilities = list.ToArray();
  
              ColUtility.Free(list);
          }
  
          public void RemoveAbility(WeaponAbility ability)
          {
              if (WeaponAbilities == null || !WeaponAbilities.Any(a => a == ability))
                  return;
  
              List<WeaponAbility> list = WeaponAbilities.ToList();
  
              list.Remove(ability);
              RemovePetAdvancement(ability);
  
              WeaponAbilities = list.ToArray();
  
              ColUtility.Free(list);
          }
  
          public void RemoveAbility(AreaEffect ability)
          {
              if (AreaEffects == null || !AreaEffects.Any(a => a == ability))
                  return;
  
              List<AreaEffect> list = AreaEffects.ToList();
  
              list.Remove(ability);
              RemovePetAdvancement(ability);
  
              AreaEffects = list.ToArray();
  
              ColUtility.Free(list);
          }
  
          public bool AddAbility(SkillName skill, bool advancement = true)
          {
              OnAddAbility(skill, advancement);
              return true;
          }
  
          public bool CanAddAbility(object o)
          {
              if (!Creature.Controlled)
                  return true;
  
              if (o is MagicalAbility)
                  return true;
  
              if (o is SpecialAbility && (SpecialAbilities == null || SpecialAbilities.Length == 0))
                  return true;
  
              if (o is AreaEffect && (AreaEffects == null || AreaEffects.Length == 0))
                  return true;
  
              if (o is WeaponAbility && (WeaponAbilities == null || WeaponAbilities.Length < 2))
                  return true;
  
              return false;
          }
  
          public void OnAddAbility(object newAbility, bool advancement)
          {
              if (advancement)
              {
                  AddPetAdvancement(newAbility);
              }
  
              if (newAbility is MagicalAbility)
              {
                  AddMagicalAbility((MagicalAbility)newAbility);
              }
  
              TrainingPoint trainPoint = PetTrainingHelper.GetTrainingPoint(newAbility);
  
              if (trainPoint != null && trainPoint.Requirements != null)
              {
                  foreach (TrainingPointRequirement req in trainPoint.Requirements.Where(r => r != null))
                  {
                      if (req.Requirement is SkillName)
                      {
                          double skill = Creature.Skills[(SkillName)req.Requirement].Base;
                          double toAdd = req.Cost == 100 ? 20 : 40;
  
                          if ((SkillName)req.Requirement == SkillName.Hiding)
                              toAdd = 100;
  
                          if (skill < toAdd)
                              Creature.Skills[(SkillName)req.Requirement].Base = toAdd;
                      }
                      else if (req.Requirement is WeaponAbility)
                      {
                          AddAbility((WeaponAbility)req.Requirement);
                      }
                  }
              }
          }
  
          public void AddPetAdvancement(object o)
          {
              if (Creature.Controlled)
              {
                  if (Advancements == null)
                      Advancements = new List<object>();
  
                  if (!Advancements.Contains(o))
                  {
                      Advancements.Add(o);
                  }
              }
          }
  
          public void RemovePetAdvancement(object o)
          {
              if (Creature.Controlled && Advancements != null && Advancements.Contains(o))
              {
                  Advancements.Remove(o);
              }
          }
  
          public bool HasAbility(object o)
          {
              if (o is MagicalAbility)
              {
                  return (MagicalAbility & (MagicalAbility)o) != 0;
              }
  
              if (o is SpecialAbility && SpecialAbilities != null)
              {
                  return SpecialAbilities.Any(a => a == (SpecialAbility)o);
              }
  
              if (o is AreaEffect && AreaEffects != null)
              {
                  return AreaEffects.Any(a => a == (AreaEffect)o);
              }
  
              if (o is WeaponAbility && WeaponAbilities != null)
              {
                  return WeaponAbilities.Any(a => a == (WeaponAbility)o);
              }
  
              return false;
          }
  
          public int AbilityCount()
          {
              int count = 0;
  
              if (MagicalAbility != MagicalAbility.None)
                  count++;
  
              if (SpecialAbilities != null)
                  count += SpecialAbilities.Where(a => !a.NaturalAbility).Count();
  
              if (AreaEffects != null)
                  count += AreaEffects.Length;
  
  
gt:             if (WeaponAbilities != null)