context: using System;
  using Server.Items;
  using Server.NpcConfiguration;
  
  namespace Server.Mobiles
  {
      public class Paragon
      {
          public static Map[] Maps = new Map[]  // Maps that paragons will spawn on
          {
              Map.Ilshenar
          };
  
          private class ParagonStamRegen : Timer
          {
              private BaseCreature m_Owner;
  
              public ParagonStamRegen(Mobile m) : base(NpcConfig.FastRegenRate, NpcConfig.FastRegenRate)
              {
                  this.Priority = TimerPriority.FiftyMS;
  
                  m_Owner = m as BaseCreature;
              }
  
              protected override void OnTick()
              {
                  if (!m_Owner.Deleted && m_Owner.IsParagon && m_Owner.Map != Map.Internal)
                  {
                      m_Owner.Stam++;
  
                      Delay = Interval = (m_Owner.Stam < (m_Owner.StamMax * .75)) ? NpcConfig.FastRegenRate : NpcConfig.CPUSaverRate;
                  }
                  else
                  {
                      Stop();
                  }
              }
          }
  
          public static Type[] Artifacts = new Type[]
          {
              typeof(GoldBricks), typeof(PhillipsWoodenSteed),
              typeof(AlchemistsBauble), typeof(ArcticDeathDealer),
              typeof(BlazeOfDeath), typeof(BowOfTheJukaKing),
              typeof(BurglarsBandana), typeof(CavortingClub),
              typeof(EnchantedTitanLegBone), typeof(GwennosHarp),
              typeof(IolosLute), typeof(LunaLance),
              typeof(NightsKiss), typeof(NoxRangersHeavyCrossbow),
              typeof(OrcishVisage), typeof(PolarBearMask),
              typeof(ShieldOfInvulnerability), typeof(StaffOfPower),
              typeof(VioletCourage), typeof(HeartOfTheLion),
              typeof(WrathOfTheDryad), typeof(PixieSwatter),
              typeof(GlovesOfThePugilist)
          };
  
          // Buffs
          public static double HitsBuff = 5.0;
          public static double StrBuff = 1.05;
          public static double IntBuff = 1.20;
          public static double DexBuff = 1.20;
          public static double SkillsBuff = 1.20;
          public static double SpeedBuff = 1.20;
          public static double FameBuff = 1.40;
          public static double KarmaBuff = 1.40;
          public static int DamageBuff = 5;
  
          public static void Convert(BaseCreature bc)
          {
              if (bc.IsParagon || !bc.CanBeParagon)
              {
                  return;
              }
  
              bc.Hue = NpcConfig.Hue;
  
              if (bc.HitsMaxSeed >= 0)
              {
                  bc.HitsMaxSeed = (int)(bc.HitsMaxSeed * HitsBuff);
              }
  
              bc.RawStr = (int)(bc.RawStr * StrBuff);
              bc.RawInt = (int)(bc.RawInt * IntBuff);
              bc.RawDex = (int)(bc.RawDex * DexBuff);
  
              bc.Hits = bc.HitsMax;
              bc.Mana = bc.ManaMax;
              bc.Stam = bc.StamMax;
  
              for (int i = 0; i < bc.Skills.Length; i++)
              {
                  Skill skill = (Skill)bc.Skills[i];
  
                  if (skill.Base > 0.0)
                  {
                      skill.Base *= SkillsBuff;
                  }
              }
  
              bc.PassiveSpeed /= SpeedBuff;
              bc.ActiveSpeed /= SpeedBuff;
              bc.CurrentSpeed = bc.PassiveSpeed;
  
              bc.DamageMin += DamageBuff;
              bc.DamageMax += DamageBuff;
  
              if (bc.Fame > 0)
              {
                  bc.Fame = (int)(bc.Fame * FameBuff);
              }
  
              if (bc.Fame > 32000)
              {
                  bc.Fame = 32000;
              }
  
              // TODO: Mana regeneration rate = Sqrt( buffedFame ) / 4
  
              if (bc.Karma != 0)
              {
                  bc.Karma = (int)(bc.Karma * KarmaBuff);
  
                  if (Math.Abs(bc.Karma) > 32000)
                  {
                      bc.Karma = 32000 * Math.Sign(bc.Karma);
                  }
  
                  new ParagonStamRegen(bc).Start(); 
              }
          }
  
          public static void UnConvert(BaseCreature bc)
          {
              if (!bc.IsParagon)
                  return;
  
              bc.Hue = 0;
  
              if (bc.HitsMaxSeed >= 0)
              {
                  bc.HitsMaxSeed = (int)(bc.HitsMaxSeed / HitsBuff);
              }
  
              bc.RawStr = (int)(bc.RawStr / StrBuff);
              bc.RawInt = (int)(bc.RawInt / IntBuff);
              bc.RawDex = (int)(bc.RawDex / DexBuff);
  
              bc.Hits = bc.HitsMax;
              bc.Mana = bc.ManaMax;
              bc.Stam = bc.StamMax;
  
              for (int i = 0; i < bc.Skills.Length; i++)
              {
                  Skill skill = (Skill)bc.Skills[i];
  
                  if (skill.Base > 0.0)
                  {
                      skill.Base /= SkillsBuff;
                  }
              }
  
              bc.PassiveSpeed *= SpeedBuff;
              bc.ActiveSpeed *= SpeedBuff;
              bc.CurrentSpeed = bc.PassiveSpeed;
  
              bc.DamageMin -= DamageBuff;
              bc.DamageMax -= DamageBuff;
  
              if (bc.Fame > 0)
              {
                  bc.Fame = (int)(bc.Fame / FameBuff);
              }
  
              if (bc.Karma != 0)
              {
                  bc.Karma = (int)(bc.Karma / KarmaBuff);
              }
          }
  
          public static bool CheckConvert(BaseCreature bc)
          {
              return CheckConvert(bc, bc.Location, bc.Map);
          }
  
          public static bool CheckConvert(BaseCreature bc, Point3D location, Map m)
          {
              if (!Core.AOS)
              {
                  return false;
              }
  
              if (Array.IndexOf(Maps, m) == -1)
              {
                  return false;
              }
  
              if (bc is BaseChampion || bc is Harrower || bc is BaseVendor || bc is BaseEscortable || bc.Summoned || bc.Controlled || bc is Clone || bc.IsParagon)
              {
                  return false;
              }
  
              if (bc is DreadHorn || bc is MonstrousInterredGrizzle || bc is Travesty || bc is ChiefParoxysmus || bc is LadyMelisande || bc is ShimmeringEffusion)
              {
                  return false;
              }
  
              int fame = bc.Fame;
  
              if (fame > 32000)
              {
                  fame = 32000;
              }
  
  
gt:             double chance = 1 / Math.Round(20.0 - (fame / 3200));