context: using System;
  using System.Text;
  using Server.Engines.CannedEvil;
  using Server.Items;
  using Server.Mobiles;
  using System.Collections.Generic;
  using Server.Accounting;
  
  namespace Server.Misc
  {
      public class Titles
      {
          public const int MinFame = 0;
          public const int MaxFame = 32000;
  
          public static void AwardFame(Mobile m, int offset, bool message)
          {
              if (offset > 0)
              {
                  if (m.Fame >= MaxFame)
                      return;
  
                  offset -= m.Fame / 100;
  
                  if (offset < 0)
                      offset = 0;
              }
              else if (offset < 0)
              {
                  if (m.Fame <= MinFame)
                      return;
  
                  offset -= m.Fame / 100;
  
                  if (offset > 0)
                      offset = 0;
              }
  
              if ((m.Fame + offset) > MaxFame)
                  offset = MaxFame - m.Fame;
              else if ((m.Fame + offset) < MinFame)
                  offset = MinFame - m.Fame;
  
              m.Fame += offset;
  
              if (message)
              {
                  if (offset > 40)
                      m.SendLocalizedMessage(1019054); // You have gained a lot of fame.
                  else if (offset > 20)
                      m.SendLocalizedMessage(1019053); // You have gained a good amount of fame.
                  else if (offset > 10)
                      m.SendLocalizedMessage(1019052); // You have gained some fame.
                  else if (offset > 0)
                      m.SendLocalizedMessage(1019051); // You have gained a little fame.
                  else if (offset < -40)
                      m.SendLocalizedMessage(1019058); // You have lost a lot of fame.
                  else if (offset < -20)
                      m.SendLocalizedMessage(1019057); // You have lost a good amount of fame.
                  else if (offset < -10)
                      m.SendLocalizedMessage(1019056); // You have lost some fame.
                  else if (offset < 0)
                      m.SendLocalizedMessage(1019055); // You have lost a little fame.
              }
          }
  
          public const int MinKarma = -32000;
          public const int MaxKarma = 32000;
  
          public static void AwardKarma(Mobile m, int offset, bool message)
          {
              #region Mondain's Legacy
              if (m.Talisman is BaseTalisman)
              {
                  BaseTalisman talisman = (BaseTalisman)m.Talisman;
  
                  if (talisman.KarmaLoss > 0)
                      offset *= (1 + (int)(((double)talisman.KarmaLoss) / 100));
                  else if (talisman.KarmaLoss < 0)
                      offset *= (1 - (int)(((double)-talisman.KarmaLoss) / 100));
              }
              #endregion
  
              #region Heritage Items
              int karmaLoss = AosAttributes.GetValue(m, AosAttribute.IncreasedKarmaLoss);
  
              if (karmaLoss != 0 && offset < 0)
              {
                  offset -= (int)(offset * (karmaLoss / 100.0));
              }
              #endregion
  
              if (offset > 0)
              {
                  if (m is PlayerMobile && ((PlayerMobile)m).KarmaLocked)
                      return;
  
                  if (m.Karma >= MaxKarma)
                      return;
  
                  offset -= m.Karma / 100;
  
                  if (offset < 0)
                      offset = 0;
              }
              else if (offset < 0)
              {
                  if (m.Karma <= MinKarma)
                      return;
  
                  offset -= m.Karma / 100;
  
                  if (offset > 0)
                      offset = 0;
              }
  
              if ((m.Karma + offset) > MaxKarma)
                  offset = MaxKarma - m.Karma;
              else if ((m.Karma + offset) < MinKarma)
                  offset = MinKarma - m.Karma;
  
              bool wasPositiveKarma = (m.Karma >= 0);
  
              m.Karma += offset;
  
              if (message)
              {
                  if (offset > 40)
                      m.SendLocalizedMessage(1019062); // You have gained a lot of karma.
                  else if (offset > 20)
                      m.SendLocalizedMessage(1019061); // You have gained a good amount of karma.
                  else if (offset > 10)
                      m.SendLocalizedMessage(1019060); // You have gained some karma.
                  else if (offset > 0)
                      m.SendLocalizedMessage(1019059); // You have gained a little karma.
                  else if (offset < -40)
                      m.SendLocalizedMessage(1019066); // You have lost a lot of karma.
                  else if (offset < -20)
                      m.SendLocalizedMessage(1019065); // You have lost a good amount of karma.
                  else if (offset < -10)
                      m.SendLocalizedMessage(1019064); // You have lost some karma.
                  else if (offset < 0)
                      m.SendLocalizedMessage(1019063); // You have lost a little karma.
              }
  
              if (!Core.AOS && wasPositiveKarma && m.Karma < 0 && m is PlayerMobile && !((PlayerMobile)m).KarmaLocked)
              {
                  ((PlayerMobile)m).KarmaLocked = true;
                  m.SendLocalizedMessage(1042511, "", 0x22); // Karma is locked.  A mantra spoken at a shrine will unlock it again.
              }
          }
  
          public static List<string> GetFameKarmaEntries(Mobile m)
          {
              List<string> list = new List<string>();
              int fame = m.Fame;
              int karma = m.Karma;
  
              for (int i = 0; i < m_FameEntries.Length; ++i)
              {
                  FameEntry fe = m_FameEntries[i];
  
                  if (fame >= fe.m_Fame)
                  {
                      KarmaEntry[] karmaEntries = fe.m_Karma;
  
                      for (int j = 0; j < karmaEntries.Length; ++j)
                      {
                          KarmaEntry ke = karmaEntries[j];
                          StringBuilder title = new StringBuilder();
  
                          if ((karma >= 0 && ke.m_Karma >= 0 && karma >= ke.m_Karma) || (karma < 0 && ke.m_Karma < 0 && karma < ke.m_Karma))
                          {
                              list.Add(title.AppendFormat(ke.m_Title, m.Name, m.Female ? "Lady" : "Lord").ToString());
                          }
                      }
                  }
              }
  
              return list;
          }
  
          public static string[] HarrowerTitles = new string[] { "Spite", "Opponent", "Hunter", "Venom", "Executioner", "Annihilator", "Champion", "Assailant", "Purifier", "Nullifier" };
  
          public static string ComputeFameTitle(Mobile beheld)
          {
              int fame = beheld.Fame;
              int karma = beheld.Karma;
  
              for (int i = 0; i < m_FameEntries.Length; ++i)
              {
                  FameEntry fe = m_FameEntries[i];
  
                  if (fame <= fe.m_Fame || i == (m_FameEntries.Length - 1))
                  {
                      KarmaEntry[] karmaEntries = fe.m_Karma;
  
                      for (int j = 0; j < karmaEntries.Length; ++j)
                      {
                          KarmaEntry ke = karmaEntries[j];
  
                          if (karma <= ke.m_Karma || j == (karmaEntries.Length - 1))
                          {
                              return String.Format(ke.m_Title, beheld.Name, beheld.Female ? "Lady" : "Lord");
                          }
                      }
  
                      return String.Empty;
                  }
              }
              return String.Empty;
          }
  
          public static string ComputeTitle(Mobile beholder, Mobile beheld)
          {
              StringBuilder title = new StringBuilder();
  
              bool showSkillTitle = beheld.ShowFameTitle && ((beholder == beheld) || (beheld.Fame >= 5000));
  
              if (Core.SA && beheld.ShowFameTitle && beheld is PlayerMobile && ((PlayerMobile)beheld).FameKarmaTitle != null)
              {
                  title.AppendFormat(((PlayerMobile)beheld).FameKarmaTitle, beheld.Name, beheld.Female ? "Lady" : "Lord");
              }
  			else if (beheld.ShowFameTitle || (beholder == beheld))
              {
                  title.Append(ComputeFameTitle(beheld));
              }
              else
              {
                  title.Append(beheld.Name);
              }
  
              if (beheld is PlayerMobile && ((PlayerMobile)beheld).DisplayChampionTitle)
              {
                  PlayerMobile.ChampionTitleInfo info = ((PlayerMobile)beheld).ChampionTitles;
  
                  if (Core.SA)
                  {
                      if (((PlayerMobile)beheld).CurrentChampTitle != null)
                          title.AppendFormat(((PlayerMobile)beheld).CurrentChampTitle);
                  }
  				else if (info.Harrower > 0)
                      title.AppendFormat(": {0} of Evil", HarrowerTitles[Math.Min(HarrowerTitles.Length, info.Harrower) - 1]);
                  else
                  {
                      int highestValue = 0, highestType = 0;
                      for (int i = 0; i < ChampionSpawnInfo.Table.Length; i++)
                      {
                          int v = info.GetValue(i);
  
                          if (v > highestValue)
                          {
                              highestValue = v;
                              highestType = i;
                          }
                      }
  
                      int offset = 0;
                      if (highestValue > 800)
                          offset = 3;
                      else if (highestValue > 300)
                          offset = (int)(highestValue / 300);
  
                      if (offset > 0)
                      {
                          ChampionSpawnInfo champInfo = ChampionSpawnInfo.GetInfo((ChampionSpawnType)highestType);
                          title.AppendFormat(": {0} of the {1}", champInfo.LevelNames[Math.Min(offset, champInfo.LevelNames.Length) - 1], champInfo.Name);
                      }
                  }
              }
  
              string customTitle = beheld.Title;
  
              if (Core.SA)
              {
                  if (beheld is PlayerMobile && ((PlayerMobile)beheld).PaperdollSkillTitle != null)
                      title.Append(", ").Append(((PlayerMobile)beheld).PaperdollSkillTitle);
              }
              else if (customTitle != null && (customTitle = customTitle.Trim()).Length > 0)
              {
                  title.AppendFormat(" {0}", customTitle);
              }
              else if (showSkillTitle && beheld.Player)
              {
                  string skillTitle = GetSkillTitle(beheld);
  
                  if (skillTitle != null)
                  {
                      title.Append(", ").Append(skillTitle);
                  }
              }
  
              return title.ToString();
          }
  
          public static string GetSkillTitle(Mobile mob)
          {
              Skill highest = GetHighestSkill(mob);// beheld.Skills.Highest;
  
              if (highest != null && highest.BaseFixedPoint >= 300)
              {
                  //Level System
                  PlayerMobile pm = mob as PlayerMobile;
                  Configured c = new Configured();
                  string d = LevelCore.Display(pm, new Configured());
  
                  string skillLevel = GetSkillLevel(highest);
                  string skillTitle = highest.Info.Title;
  
                  if (mob.Female && skillTitle.EndsWith("man"))
                      skillTitle = skillTitle.Substring(0, skillTitle.Length - 3) + "woman";
  
                  return String.Concat(skillLevel, " ", skillTitle);
              }
  
              return null;
          }
  
          public static string GetSkillTitle(Mobile mob, Skill skill)
          {
  
gt:             string skillLevel = GetSkillLevel(skill);