context: using System;
  using System.Collections.Generic;
  using Server.Items;
  
  namespace Server.Mobiles
  {
      [CorpseName("a travesty's corpse")]
      public class Travesty : BasePeerless
      {
          public override WeaponAbility GetWeaponAbility()
          {
              if (Weapon == null)
                  return null;
  
              BaseWeapon weapon = Weapon as BaseWeapon;
  
              return Utility.RandomBool() ? weapon.PrimaryAbility : weapon.SecondaryAbility;
          }
  
          private DateTime m_NextBodyChange;
          private DateTime m_NextMirrorImage;
          private bool m_SpawnedHelpers;
          private Timer m_Timer;
  
          private bool _CanDiscord;
          private bool _CanPeace;
          private bool _CanProvoke;
  
          public override bool CanDiscord { get { return _CanDiscord; } }
          public override bool CanPeace { get { return _CanPeace; } }
          public override bool CanProvoke { get { return _CanProvoke; } }
  
          [Constructable]
          public Travesty()
              : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
          {
              Name = "Travesty";
              Body = 0x108;
  
              BaseSoundID = 0x46E;
  
              SetStr(900, 950);
              SetDex(900, 950);
              SetInt(900, 950);
  
              SetHits(35000);
  
              SetDamage(11, 18);
  
              SetDamageType(ResistanceType.Physical, 100);
  
              SetResistance(ResistanceType.Physical, 50, 70);
              SetResistance(ResistanceType.Fire, 50, 70);
              SetResistance(ResistanceType.Cold, 50, 70);
              SetResistance(ResistanceType.Poison, 50, 70);
              SetResistance(ResistanceType.Energy, 50, 70);
  
              SetSkill(SkillName.Wrestling, 300.0, 320.0);
              SetSkill(SkillName.Tactics, 100.0, 120.0);
              SetSkill(SkillName.MagicResist, 100.0, 120.0);
              SetSkill(SkillName.Anatomy, 100.0, 120.0);
              SetSkill(SkillName.Healing, 100.0, 120.0);
              SetSkill(SkillName.Poisoning, 100.0, 120.0);
              SetSkill(SkillName.DetectHidden, 100.0);
              SetSkill(SkillName.Hiding, 100.0);
              SetSkill(SkillName.Parry, 100.0, 110.0);
              SetSkill(SkillName.Magery, 100.0, 120.0);
              SetSkill(SkillName.EvalInt, 100.0, 120.0);
              SetSkill(SkillName.Meditation, 100.0, 120.0);
              SetSkill(SkillName.Necromancy, 100.0, 120.0);
              SetSkill(SkillName.SpiritSpeak, 100.0, 120.0);
              SetSkill(SkillName.Focus, 100.0, 120.0);
              SetSkill(SkillName.Spellweaving, 100.0, 120.0);
              SetSkill(SkillName.Discordance, 100.0, 120.0);
              SetSkill(SkillName.Bushido, 100.0, 120.0);
              SetSkill(SkillName.Ninjitsu, 100.0, 120.0);
              SetSkill(SkillName.Chivalry, 100.0, 120.0);
  
              SetSkill(SkillName.Musicianship, 100.0, 120.0);
              SetSkill(SkillName.Discordance, 100.0, 120.0);
              SetSkill(SkillName.Provocation, 100.0, 120.0);
              SetSkill(SkillName.Peacemaking, 100.0, 120.0);
  
              Fame = 30000;
              Karma = -30000;
  
              VirtualArmor = 50;
              PackTalismans(5);
              PackResources(8);
  
              for (int i = 0; i < Utility.RandomMinMax(1, 6); i++)
              {
                  PackItem(Loot.RandomScroll(0, Loot.ArcanistScrollTypes.Length, SpellbookType.Arcanist));
              }
          }
  
          public override bool ShowFameTitle { get { return false; } }
  
          public Travesty(Serial serial)
              : base(serial)
          {
          }
  
          public override void OnDeath(Container c)
          {
              base.OnDeath(c);
  
              c.DropItem(new EyeOfTheTravesty());
              c.DropItem(new OrdersFromMinax());
  
              switch (Utility.Random(3))
              {
                  case 0:
                      c.DropItem(new TravestysSushiPreparations());
                      break;
                  case 1:
                      c.DropItem(new TravestysFineTeakwoodTray());
                      break;
                  case 2:
                      c.DropItem(new TravestysCollectionOfShells());
                      break;
              }
  
              if (Utility.RandomDouble() < 0.10)
                  c.DropItem(new HumanFeyLeggings());
  
              if (Utility.RandomDouble() < 0.6)
                  c.DropItem(new ParrotItem());
  
              if (Utility.RandomDouble() < 0.1)
                  c.DropItem(new TragicRemainsOfTravesty());
  
              if (Utility.RandomDouble() < 0.05)
                  c.DropItem(new ImprisonedDog());
  
              if (Utility.RandomDouble() < 0.05)
                  c.DropItem(new MarkOfTravesty());
  
              if (Utility.RandomDouble() < 0.025)
                  c.DropItem(new CrimsonCincture());
  
              if (Utility.RandomDouble() < 0.025)
              {
                  switch (Utility.Random(4))
                  {
                      case 0:
                          c.DropItem(new AssassinLegs());
                          break;
                      case 1:
                          c.DropItem(new AssassinArms());
                          break;
                      case 2:
                          c.DropItem(new AssassinGloves());
                          break;
                      case 3:
                          c.DropItem(new MalekisHonor());
                          break;
                  }
              }
          }
  
          public override void OnDamage(int amount, Mobile from, bool willKill)
          {
              if (0.1 > Utility.RandomDouble() && m_NextMirrorImage < DateTime.UtcNow)
              {
                  new Server.Spells.Ninjitsu.MirrorImage(this, null).Cast();
  
                  m_NextMirrorImage = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(20, 45));
              }
  
              if (0.25 > Utility.RandomDouble() && DateTime.UtcNow > m_NextBodyChange)
              {
                  ChangeBody();
              }
  
              base.OnDamage(amount, from, willKill);
          }
  
          public override void GenerateLoot()
          {
              AddLoot(LootPack.AosSuperBoss, 8);
          }
  
          public override void Serialize(GenericWriter writer)
          {
              base.Serialize(writer);
              writer.Write((int)0); // version
          }
  
          public override void Deserialize(GenericReader reader)
          {
              base.Deserialize(reader);
              int version = reader.ReadInt();
          }
  
          public void ChangeBody()
          {
              List<Mobile> list = new List<Mobile>();
  
              IPooledEnumerable eable = Map.GetMobilesInRange(Location, 5);
  
              foreach (Mobile m in eable)
              {
                  if (m.Player && m.AccessLevel == AccessLevel.Player && m.Alive)
                      list.Add(m);
              }
  
              eable.Free();
  
              if (list.Count == 0 || IsBodyMod)
              {
                  return;
              }
  
              Mobile attacker = list[Utility.Random(list.Count)];
  
              BodyMod = attacker.Body;
              HueMod = attacker.Hue;
              NameMod = attacker.Name;
              Female = attacker.Female;
              Title = "(Travesty)";
              HairItemID = attacker.HairItemID;
              HairHue = attacker.HairHue;
              FacialHairItemID = attacker.FacialHairItemID;
              FacialHairHue = attacker.FacialHairHue;
  
              foreach (Item item in attacker.Items)
              {
                  if (item.Layer < Layer.Mount &&
                      item.Layer != Layer.Backpack &&
                      item.Layer != Layer.Mount &&
                      item.Layer != Layer.Bank &&
                      item.Layer != Layer.Hair &&
                      item.Layer != Layer.Face &&
                      item.Layer != Layer.FacialHair)
                  {
  
gt:                     if (FindItemOnLayer(item.Layer) == null)