context: using System;
  using System.Collections.Generic;
  using Server.Factions.AI;
  using Server.Items;
  using Server.Mobiles;
  using Server.Network;
  
  namespace Server.Factions
  {
      public abstract class BaseFactionGuard : BaseCreature
      {
          private static readonly Type[] m_StrongPotions = new Type[]
          {
              typeof(GreaterHealPotion), typeof(GreaterHealPotion), typeof(GreaterHealPotion),
              typeof(GreaterCurePotion), typeof(GreaterCurePotion), typeof(GreaterCurePotion),
              typeof(GreaterStrengthPotion), typeof(GreaterStrengthPotion),
              typeof(GreaterAgilityPotion), typeof(GreaterAgilityPotion),
              typeof(TotalRefreshPotion), typeof(TotalRefreshPotion),
              typeof(GreaterExplosionPotion)
          };
          private static readonly Type[] m_WeakPotions = new Type[]
          {
              typeof(HealPotion), typeof(HealPotion), typeof(HealPotion),
              typeof(CurePotion), typeof(CurePotion), typeof(CurePotion),
              typeof(StrengthPotion), typeof(StrengthPotion),
              typeof(AgilityPotion), typeof(AgilityPotion),
              typeof(RefreshPotion), typeof(RefreshPotion),
              typeof(ExplosionPotion)
          };
          private const int ListenRange = 12;
          private Faction m_Faction;
          private Town m_Town;
          private Orders m_Orders;
          private DateTime m_OrdersEnd;
          public BaseFactionGuard(string title)
              : base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
          {
              this.m_Orders = new Orders(this);
              this.Title = title;
  
              this.RangeHome = 6;
          }
  
          public BaseFactionGuard(Serial serial)
              : base(serial)
          {
          }
  
          public override bool BardImmune
          {
              get
              {
                  return true;
              }
          }
          [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
          public Faction Faction
          {
              get
              {
                  return this.m_Faction;
              }
              set
              {
                  this.Unregister();
                  this.m_Faction = value;
                  this.Register();
              }
          }
          public Orders Orders
          {
              get
              {
                  return this.m_Orders;
              }
          }
          [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
          public Town Town
          {
              get
              {
                  return this.m_Town;
              }
              set
              {
                  this.Unregister();
                  this.m_Town = value;
                  this.Register();
              }
          }
          public abstract GuardAI GuardAI { get; }
          public override TimeSpan ReacquireDelay
          {
              get
              {
                  return TimeSpan.FromSeconds(2.0);
              }
          }
          public override bool ClickTitle
          {
              get
              {
                  return false;
              }
          }
          protected override BaseAI ForcedAI
          {
              get
              {
                  return new FactionGuardAI(this);
              }
          }
          public void Register()
          {
              if (this.m_Town != null && this.m_Faction != null)
                  this.m_Town.RegisterGuard(this);
          }
  
          public void Unregister()
          {
              if (this.m_Town != null)
                  this.m_Town.UnregisterGuard(this);
          }
  
          public override bool IsEnemy(Mobile m)
          {
              Faction ourFaction = this.m_Faction;
              Faction theirFaction = Faction.Find(m);
  
              if (theirFaction == null && m is BaseFactionGuard)
                  theirFaction = ((BaseFactionGuard)m).Faction;
  
              if (ourFaction != null && theirFaction != null && ourFaction != theirFaction)
              {
                  ReactionType reactionType = this.Orders.GetReaction(theirFaction).Type;
  
                  if (reactionType == ReactionType.Attack)
                      return true;
  
                  if (theirFaction != null)
                  {
                      List<AggressorInfo> list = m.Aggressed;
  
                      for (int i = 0; i < list.Count; ++i)
                      {
                          AggressorInfo ai = list[i];
  
                          if (ai.Defender is BaseFactionGuard)
                          {
                              BaseFactionGuard bf = (BaseFactionGuard)ai.Defender;
  
                              if (bf.Faction == ourFaction)
                                  return true;
                          }
                      }
                  }
              }
  
              return false;
          }
  
          public override void OnMovement(Mobile m, Point3D oldLocation)
          {
              if (m.Player && m.Alive && this.InRange(m, 10) && !this.InRange(oldLocation, 10) && this.InLOS(m) && this.m_Orders.GetReaction(Faction.Find(m)).Type == ReactionType.Warn)
              {
                  this.Direction = this.GetDirectionTo(m);
  
                  string warning = null;
  
                  switch ( Utility.Random(6) )
                  {
                      case 0:
                          warning = "I warn you, {0}, you would do well to leave this area before someone shows you the world of gray.";
                          break;
                      case 1:
                          warning = "It would be wise to leave this area, {0}, lest your head become my commanders' trophy.";
                          break;
                      case 2:
                          warning = "You are bold, {0}, for one of the meager {1}. Leave now, lest you be taught the taste of dirt.";
                          break;
                      case 3:
                          warning = "Your presence here is an insult, {0}. Be gone now, knave.";
                          break;
                      case 4:
                          warning = "Dost thou wish to be hung by your toes, {0}? Nay? Then come no closer.";
                          break;
                      case 5:
                          warning = "Hey, {0}. Yeah, you. Get out of here before I beat you with a stick.";
                          break;
                  }
  
                  Faction faction = Faction.Find(m);
  
                  this.Say(warning, m.Name, faction == null ? "civilians" : faction.Definition.FriendlyName);
              }
          }
  
          public override bool HandlesOnSpeech(Mobile from)
          {
              if (this.InRange(from, ListenRange))
                  return true;
  
              return base.HandlesOnSpeech(from);
          }
  
          public override void OnSpeech(SpeechEventArgs e)
          {
              base.OnSpeech(e);
  
              Mobile from = e.Mobile;
  
              if (!e.Handled && this.InRange(from, ListenRange) && from.Alive)
              {
                  if (e.HasKeyword(0xE6) && (Insensitive.Equals(e.Speech, "orders") || this.WasNamed(e.Speech))) // *orders*
                  {
                      if (this.m_Town == null || !this.m_Town.IsSheriff(from))
                      {
                          this.Say(1042189); // I don't work for you!
                      }
  
gt:                     else if (Town.FromRegion(this.Region) == this.m_Town)