/*************************************************************************** * Sector.cs * ------------------- * begin : May 1, 2002 * copyright : (C) The RunUO Software Team * email : info@runuo.com * * $Id$ * ***************************************************************************/ /*************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * ***************************************************************************/ using System; using System.Collections; using System.Collections.Generic; using Server.Items; using Server.Network; namespace Server { public class RegionRect : IComparable { private Region m_Region; private Rectangle3D m_Rect; public Region Region { get { return m_Region; } } public Rectangle3D Rect { get { return 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; RegionRect 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 int m_X, m_Y; private 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 List m_DefaultMobileList = new List(); private static List m_DefaultItemList = new List(); private static List m_DefaultClientList = new List(); private static List m_DefaultMultiList = new List(); private static 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 ) { int 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 ( int i = m_RegionRects.Count - 1; i >= 0; i-- ) { RegionRect 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 ) { List sandbox = new List( m_Mobiles ); foreach ( Mobile 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 ( Item item in m_Items ) { item.OnSectorActivate(); } } if ( m_Mobiles != null ) { foreach ( Mobile mob in m_Mobiles ) { mob.OnSectorActivate(); } } m_Active = true; } } public void Deactivate() { if ( Active ) { if ( m_Items != null ) { foreach ( Item item in m_Items ) { item.OnSectorDeactivate(); } } if ( m_Mobiles != null ) { foreach ( Mobile 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_DefaultMobileList; return m_Players; } } public bool Active { get { return ( m_Active && m_Owner != Map.Internal ); } } public Map Owner { get { return m_Owner; } } public int X { get { return m_X; } } public int Y { get { return m_Y; } } } }