context: using System;
  using Server.Gumps;
  using Server.Items;
  using Server.Mobiles;
  using Server.Multis;
  
  namespace Server.Regions
  {
      public class HouseRegion : BaseRegion
      {
          public static readonly int HousePriority = Region.DefaultPriority + 1;
          public static TimeSpan CombatHeatDelay = TimeSpan.FromSeconds(30.0);
          private readonly BaseHouse m_House;
          private bool m_Recursion;
          public HouseRegion(BaseHouse house)
              : base(null, house.Map, HousePriority, GetArea(house))
          {
              this.m_House = house;
  
              Point3D ban = house.RelativeBanLocation;
  
              this.GoLocation = new Point3D(house.X + ban.X, house.Y + ban.Y, house.Z + ban.Z);
          }
  
          public BaseHouse House
          {
              get
              {
                  return this.m_House;
              }
          }
          public static void Initialize()
          {
              EventSink.Login += new LoginEventHandler(OnLogin);
          }
  
          public static void OnLogin(LoginEventArgs e)
          {
              BaseHouse house = BaseHouse.FindHouseAt(e.Mobile);
  
              if (house != null && !house.Public && !house.IsFriend(e.Mobile))
                  e.Mobile.Location = house.BanLocation;
          }
  
          public override bool AllowHousing(Mobile from, Point3D p)
          {
              return false;
          }
  
          public override bool SendInaccessibleMessage(Item item, Mobile from)
          {
              if (item is Container)
                  item.SendLocalizedMessageTo(from, 501647); // That is secure.
              else
                  item.SendLocalizedMessageTo(from, 1061637); // You are not allowed to access this.
  
              return true;
          }
  
          public override bool CheckAccessibility(Item item, Mobile from)
          {
              return this.m_House.CheckAccessibility(item, from);
          }
  
          // Use OnLocationChanged instead of OnEnter because it can be that we enter a house region even though we're not actually inside the house
          public override void OnLocationChanged(Mobile m, Point3D oldLocation)
          {
              if (this.m_Recursion)
                  return;
  
              base.OnLocationChanged(m, oldLocation);
  
              this.m_Recursion = true;
  
              if (m is BaseCreature && ((BaseCreature)m).NoHouseRestrictions)
              {
              }
              else if (m is BaseCreature && ((BaseCreature)m).IsHouseSummonable && !(BaseCreature.Summoning || this.m_House.IsInside(oldLocation, 16)))
              {
              }
              else if ((this.m_House.Public || !this.m_House.IsAosRules) && this.m_House.IsBanned(m) && this.m_House.IsInside(m))
              {
                  m.Location = this.m_House.BanLocation;
  
                  if (!Core.SE)
                      m.SendLocalizedMessage(501284); // You may not enter.
              }
              else if (this.m_House.IsAosRules && !this.m_House.Public && !this.m_House.HasAccess(m) && this.m_House.IsInside(m))
              {
                  m.Location = this.m_House.BanLocation;
  
                  if (!Core.SE)
                      m.SendLocalizedMessage(501284); // You may not enter.
              }
              else if (this.m_House.IsCombatRestricted(m) && this.m_House.IsInside(m) && !this.m_House.IsInside(oldLocation, 16))
              {
                  m.Location = this.m_House.BanLocation;
                  m.SendLocalizedMessage(1061637); // You are not allowed to access this.
              }
              else if (this.m_House is HouseFoundation)
              {
                  HouseFoundation foundation = (HouseFoundation)this.m_House;
  
                  if (foundation.Customizer != null && foundation.Customizer != m && this.m_House.IsInside(m))
                      m.Location = this.m_House.BanLocation;
              }
  
              if (this.m_House.InternalizedVendors.Count > 0 && this.m_House.IsInside(m) && !this.m_House.IsInside(oldLocation, 16) && this.m_House.IsOwner(m) && m.Alive && !m.HasGump(typeof(NoticeGump)))
              {
                  /* This house has been customized recently, and vendors that work out of this
                  * house have been temporarily relocated.  You must now put your vendors back to work.
                  * To do this, walk to a location inside the house where you wish to station
                  * your vendor, then activate the context-sensitive menu on your avatar and
                  * select "Get Vendor".
                  */
                  m.SendGump(new NoticeGump(1060635, 30720, 1061826, 32512, 320, 180, null, null));
              }
  
              this.m_Recursion = false;
          }
  
          public override bool OnMoveInto(Mobile from, Direction d, Point3D newLocation, Point3D oldLocation)
          {
              if (!base.OnMoveInto(from, d, newLocation, oldLocation))
                  return false;
  
              if (from is BaseCreature && ((BaseCreature)from).NoHouseRestrictions)
              {
              }
              else if (from is BaseCreature && !((BaseCreature)from).Controlled) // Untamed creatures cannot enter public houses
              {
                  return false;
              }
              else if (from is BaseCreature && ((BaseCreature)from).IsHouseSummonable && !(BaseCreature.Summoning || this.m_House.IsInside(oldLocation, 16)))
              {
                  return false;
              }
              else if (from is BaseCreature && !((BaseCreature)from).Controlled && this.m_House.IsAosRules && !this.m_House.Public)
              {
                  return false;
              }
              else if ((this.m_House.Public || !this.m_House.IsAosRules) && this.m_House.IsBanned(from) && this.m_House.IsInside(newLocation, 16))
              {
                  from.Location = this.m_House.BanLocation;
  
                  if (!Core.SE)
                      from.SendLocalizedMessage(501284); // You may not enter.
  
                  return false;
              }
              else if (this.m_House.IsAosRules && !this.m_House.Public && !this.m_House.HasAccess(from) && this.m_House.IsInside(newLocation, 16))
              {
                  if (!Core.SE)
                      from.SendLocalizedMessage(501284); // You may not enter.
  
                  return false;
              }
              else if (this.m_House.IsCombatRestricted(from) && !this.m_House.IsInside(oldLocation, 16) && this.m_House.IsInside(newLocation, 16))
              {
                  from.SendLocalizedMessage(1061637); // You are not allowed to access this.
                  return false;
              }
              else if (this.m_House is HouseFoundation)
              {
                  HouseFoundation foundation = (HouseFoundation)this.m_House;
  
                  if (foundation.Customizer != null && foundation.Customizer != from && this.m_House.IsInside(newLocation, 16))
                      return false;
              }
  
              if (this.m_House.InternalizedVendors.Count > 0 && this.m_House.IsInside(from) && !this.m_House.IsInside(oldLocation, 16) && this.m_House.IsOwner(from) && from.Alive && !from.HasGump(typeof(NoticeGump)))
              {
                  /* This house has been customized recently, and vendors that work out of this
                  * house have been temporarily relocated.  You must now put your vendors back to work.
                  * To do this, walk to a location inside the house where you wish to station
                  * your vendor, then activate the context-sensitive menu on your avatar and
                  * select "Get Vendor".
                  */
                  from.SendGump(new NoticeGump(1060635, 30720, 1061826, 32512, 320, 180, null, null));
              }
  
              return true;
          }
  
          public override bool OnDecay(Item item)
          {
              if ((this.m_House.IsLockedDown(item) || this.m_House.IsSecure(item)) && this.m_House.IsInside(item))
                  return false;
              else
                  return base.OnDecay(item);
          }
  
          public override TimeSpan GetLogoutDelay(Mobile m)
          {
              if (this.m_House.IsFriend(m) && this.m_House.IsInside(m))
              {
                  for (int i = 0; i < m.Aggressed.Count; ++i)
                  {
                      AggressorInfo info = m.Aggressed[i];
  
                      if (info.Defender.Player && (DateTime.UtcNow - info.LastCombatTime) < CombatHeatDelay)
                          return base.GetLogoutDelay(m);
                  }
  
                  return TimeSpan.Zero;
              }
  
              return base.GetLogoutDelay(m);
          }
  
          public override void OnSpeech(SpeechEventArgs e)
          {
              base.OnSpeech(e);
  
              Mobile from = e.Mobile;
              Item sign = this.m_House.Sign;
  
              bool isOwner = this.m_House.IsOwner(from);
              bool isCoOwner = isOwner || this.m_House.IsCoOwner(from);
  
gt:             bool isFriend = isCoOwner || this.m_House.IsFriend(from);