#region References using System; using System.Collections.Generic; using Server.Items; using Server.Network; #endregion namespace Server { public class RegionRect : IComparable { private readonly Region m_Region; private Rectangle3D m_Rect; public Region Region => m_Region; public Rectangle3D Rect => m_Rect; public RegionRect(Region region, Rectangle3D rect) { m_Region = region; m_Rect = rect; } public bool Contains(Point3D loc) { return m_Rect.Contains(loc); } int IComparable.CompareTo(object obj) { if (obj == null) { return 1; } var regRect = obj as RegionRect; if (regRect == null) { throw new ArgumentException("obj is not a RegionRect", "obj"); } return ((IComparable)m_Region).CompareTo(regRect.m_Region); } } public class Sector { private readonly int m_X; private readonly int m_Y; private readonly Map m_Owner; private List m_Mobiles; private List m_Players; private List m_Items; private List m_Clients; private List m_Multis; private List m_RegionRects; private bool m_Active; // TODO: Can we avoid this? private static readonly List m_DefaultMobileList = new List(); private static readonly List m_DefaultPlayerList = new List(); private static readonly List m_DefaultItemList = new List(); private static readonly List m_DefaultClientList = new List(); private static readonly List m_DefaultMultiList = new List(); private static readonly List m_DefaultRectList = new List(); public Sector(int x, int y, Map owner) { m_X = x; m_Y = y; m_Owner = owner; m_Active = false; } private void Add(ref List list, T value) { if (list == null) { list = new List(); } list.Add(value); } private void Remove(ref List list, T value) { if (list != null) { list.Remove(value); if (list.Count == 0) { list = null; } } } private void Replace(ref List list, T oldValue, T newValue) { if (oldValue != null && newValue != null) { var index = list != null ? list.IndexOf(oldValue) : -1; if (index >= 0) { list[index] = newValue; } else { Add(ref list, newValue); } } else if (oldValue != null) { Remove(ref list, oldValue); } else if (newValue != null) { Add(ref list, newValue); } } public void OnClientChange(NetState oldState, NetState newState) { Replace(ref m_Clients, oldState, newState); } public void OnEnter(Item item) { Add(ref m_Items, item); } public void OnLeave(Item item) { Remove(ref m_Items, item); } public void OnEnter(Mobile mob) { Add(ref m_Mobiles, mob); if (mob.NetState != null) { Add(ref m_Clients, mob.NetState); } if (mob.Player) { if (m_Players == null) { m_Owner.ActivateSectors(m_X, m_Y); } Add(ref m_Players, mob); } } public void OnLeave(Mobile mob) { Remove(ref m_Mobiles, mob); if (mob.NetState != null) { Remove(ref m_Clients, mob.NetState); } if (mob.Player && m_Players != null) { Remove(ref m_Players, mob); if (m_Players == null) { m_Owner.DeactivateSectors(m_X, m_Y); } } } public void OnEnter(Region region, Rectangle3D rect) { Add(ref m_RegionRects, new RegionRect(region, rect)); m_RegionRects.Sort(); UpdateMobileRegions(); } public void OnLeave(Region region) { if (m_RegionRects != null) { for (var i = m_RegionRects.Count - 1; i >= 0; i--) { var regRect = m_RegionRects[i]; if (regRect.Region == region) { m_RegionRects.RemoveAt(i); } } if (m_RegionRects.Count == 0) { m_RegionRects = null; } } UpdateMobileRegions(); } private void UpdateMobileRegions() { if (m_Mobiles != null) { var sandbox = new List(m_Mobiles); foreach (var mob in sandbox) { mob.UpdateRegion(); } } } public void OnMultiEnter(BaseMulti multi) { Add(ref m_Multis, multi); } public void OnMultiLeave(BaseMulti multi) { Remove(ref m_Multis, multi); } public void Activate() { if (!Active && m_Owner != Map.Internal) { if (m_Items != null) { foreach (var item in m_Items) { item.OnSectorActivate(); } } if (m_Mobiles != null) { foreach (var mob in m_Mobiles) { mob.OnSectorActivate(); } } m_Active = true; } } public void Deactivate() { if (Active) { if (m_Items != null) { foreach (var item in m_Items) { item.OnSectorDeactivate(); } } if (m_Mobiles != null) { foreach (var mob in m_Mobiles) { mob.OnSectorDeactivate(); } } m_Active = false; } } public List RegionRects { get { if (m_RegionRects == null) { return m_DefaultRectList; } return m_RegionRects; } } public List Multis { get { if (m_Multis == null) { return m_DefaultMultiList; } return m_Multis; } } public List Mobiles { get { if (m_Mobiles == null) { return m_DefaultMobileList; } return m_Mobiles; } } public List Items { get { if (m_Items == null) { return m_DefaultItemList; } return m_Items; } } public List Clients { get { if (m_Clients == null) { return m_DefaultClientList; } return m_Clients; } } public List Players { get { if (m_Players == null) { return m_DefaultPlayerList; } return m_Players; } } public bool Active => m_Active && m_Owner != Map.Internal; public Map Owner => m_Owner; public int X => m_X; public int Y => m_Y; } }