context: using System;
  using System.Collections;
  using Server.Items;
  using Server.Network;
  using Server.Spells;
  
  namespace Server.Mobiles
  {
      [CorpseName("a monstrous interred grizzle corpse")]
      public class MonstrousInterredGrizzle : BasePeerless
      {
          private static readonly int[] m_Tiles = new int[]
          {
              -2, 0,
              2, 0,
              2, -2,
              2, 2,
              -2, -2,
              -2, 2,
              0, 2,
              1, 0,
              0, -2
          };
          private static Hashtable m_Table;
          private readonly DateTime m_NextDrop = DateTime.UtcNow;
          [Constructable]
          public MonstrousInterredGrizzle()
              : base(AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4)
          {
              this.Name = "a monstrous interred grizzle";
              this.Body = 0x103;			
              this.BaseSoundID = 589;
  
              this.SetStr(1198, 1207);
              this.SetDex(127, 135);
              this.SetInt(595, 646);
  
              this.SetHits(50000);
  
              this.SetDamage(27, 31);
  
              this.SetDamageType(ResistanceType.Physical, 60);
              this.SetDamageType(ResistanceType.Fire, 20);
              this.SetDamageType(ResistanceType.Energy, 20);
  
              this.SetResistance(ResistanceType.Physical, 48, 52);
              this.SetResistance(ResistanceType.Fire, 77, 82);
              this.SetResistance(ResistanceType.Cold, 56, 61);
              this.SetResistance(ResistanceType.Poison, 32, 40);
              this.SetResistance(ResistanceType.Energy, 69, 71);
  
              this.SetSkill(SkillName.Wrestling, 112.6, 116.9);
              this.SetSkill(SkillName.Tactics, 118.5, 119.2);
              this.SetSkill(SkillName.MagicResist, 120);
              this.SetSkill(SkillName.Anatomy, 111.0, 111.7);
              this.SetSkill(SkillName.Magery, 100.0);
              this.SetSkill(SkillName.EvalInt, 100);
              this.SetSkill(SkillName.Meditation, 100);
  
              this.Fame = 24000;
              this.Karma = -24000;
  
              this.VirtualArmor = 80;
              this.PackResources(8);
              this.PackTalismans(5);
  
              for (int i = 0; i < Utility.RandomMinMax(1, 6); i++)
              {
                  this.PackItem(Loot.RandomScroll(0, Loot.ArcanistScrollTypes.Length, SpellbookType.Arcanist));
              }
          }
  
          public MonstrousInterredGrizzle(Serial serial)
              : base(serial)
          {
          }
  
          public override bool GivesMLMinorArtifact
          {
              get
              {
                  return true;
              }
          }
          public override int TreasureMapLevel
          {
              get
              {
                  return 5;
              }
          }
          public static bool UnderCacophonicAttack(Mobile from)
          {
              if (m_Table == null)
                  m_Table = new Hashtable();
  			
              return m_Table[from] != null;
          }
  
          public override void GenerateLoot()
          {
              this.AddLoot(LootPack.AosSuperBoss, 8);
          }
  
          public override void OnDeath(Container c)
          {
              base.OnDeath(c);		
  			
              c.DropItem(new GrizzledBones());
  			
              switch ( Utility.Random(4) )
              {
                  case 0:
                      c.DropItem(new TombstoneOfTheDamned());
                      break;
                  case 1:
                      c.DropItem(new GlobOfMonstreousInterredGrizzle());
                      break;
                  case 2:
                      c.DropItem(new MonsterousInterredGrizzleMaggots());
                      break;
                  case 3:
                      c.DropItem(new GrizzledSkullCollection());
                      break;
              }
  
              if (Utility.RandomDouble() < 0.10)
                  c.DropItem(new HumanFeyLeggings());
  			
              if (Utility.RandomDouble() < 0.6)				
                  c.DropItem(new ParrotItem());
  				
              if (Utility.RandomDouble() < 0.05)				
                  c.DropItem(new GrizzledMareStatuette());
  							
              if (Utility.RandomDouble() < 0.025)
                  c.DropItem(new CrimsonCincture());
  				
              if (Utility.RandomDouble() < 0.05)
              {
                  switch ( Utility.Random(5) )
                  {
                      case 0:
                          c.DropItem(new GrizzleGauntlets());
                          break;
                      case 1:
                          c.DropItem(new GrizzleGreaves());
                          break;
                      case 2:
                          c.DropItem(new GrizzleHelm());
                          break;
                      case 3:
                          c.DropItem(new GrizzleTunic());
                          break;
                      case 4:
                          c.DropItem(new GrizzleVambraces());
                          break;
                  }
              }
          }
  
          public override void OnGaveMeleeAttack(Mobile defender)
          {
              base.OnGaveMeleeAttack(defender);
  
              if (Utility.RandomDouble() < 0.15)
                  this.CacophonicAttack(defender);
          }
  
          public override void OnDamage(int amount, Mobile from, bool willKill)
          { 
              if (Utility.RandomDouble() < 0.15)
                  this.CacophonicAttack(from);
  				
              if (Utility.RandomDouble() < 0.3)
                  this.DropOoze();
  			
              base.OnDamage(amount, from, willKill);
          }
  
          public override void OnThink()
          {
              base.OnThink();
  			
              if (this.Combatant == null)
                  return;	
  				
              if (this.Hits > 0.8 * this.HitsMax && Utility.RandomDouble() < 0.0025)
                  this.FireRing();
          }
  
          public override void FireRing()
          {
              for (int i = 0; i < m_Tiles.Length; i += 2) 
              {
                  Point3D p = this.Location;
  				
                  p.X += m_Tiles[i];
                  p.Y += m_Tiles[i + 1];
  				
                  IPoint3D po = p as IPoint3D;
  				
                  SpellHelper.GetSurfaceTop(ref po);
  				
                  Effects.SendLocationEffect(po, this.Map, Utility.RandomBool() ? 0x3E31 : 0x3E27, 100);
              }
          }
  
          public override int GetDeathSound()
          {
              return 0x57F;
          }
  
          public override int GetAttackSound()
          {
              return 0x580;
          }
  
          public override int GetIdleSound()
          {
              return 0x581;
          }
  
          public override int GetAngerSound()
          {
              return 0x582;
          }
  
          public override int GetHurtSound()
          {
              return 0x583;
          }
  
          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 virtual void CacophonicAttack(Mobile to)
          {
              if (m_Table == null)
                  m_Table = new Hashtable();
  		
              if (to.Alive && to.Player && m_Table[to] == null)
              {
                  to.Send(SpeedControl.WalkSpeed);
                  to.SendLocalizedMessage(1072069); // A cacophonic sound lambastes you, suppressing your ability to move.
                  to.PlaySound(0x584);
  				
                  m_Table[to] = Timer.DelayCall(TimeSpan.FromSeconds(30), new TimerStateCallback(EndCacophonic_Callback), to);
  
                  BuffInfo.AddBuff(to, new BuffInfo(BuffIcon.HowlOfCacophony, 1153793, 1153820, TimeSpan.FromSeconds(30), to, "60\t5\t5"));
              }
          }
  
          public virtual void CacophonicEnd(Mobile from)
          {
              if (m_Table == null)
                  m_Table = new Hashtable();
  				
              m_Table[from] = null;
  
              BuffInfo.RemoveBuff(from, BuffIcon.HowlOfCacophony);
  
              from.Send(SpeedControl.Disable);
          }
  
          public virtual void DropOoze()
          {
              int amount = Utility.RandomMinMax(1, 3);
              bool corrosive = Utility.RandomBool();
  			
              for (int i = 0; i < amount; i ++)
              {
                  Item ooze = new InfernalOoze(corrosive);				
                  Point3D p = new Point3D(this.Location);
  				
                  for (int j = 0; j < 5; j ++)
                  {
  
gt:                     p = this.GetSpawnPosition(2);