Fixed potential crash bug with prematurely removing objects from sectors.

Deprecated BaseMulti.RefreshComponents.
Dynamically changing BaseMulti.ItemID will now perform any needed sector updates.
This commit is contained in:
krrios 2006-06-16 22:31:18 +00:00
parent ab2a22c178
commit 3d09d84101
2 changed files with 175 additions and 201 deletions

View file

@ -34,17 +34,37 @@ namespace Server.Items
{ {
} }
public override int ItemID {
get {
return base.ItemID;
}
set {
if ( base.ItemID != value ) {
Map facet = ( this.Parent == null ? this.Map : null );
if ( facet != null ) {
facet.OnLeave( this );
}
base.ItemID = value;
if ( facet != null ) {
facet.OnEnter( this );
}
}
}
}
[Obsolete( "Replace with calls to OnLeave and OnEnter surrounding component invalidation.", true )]
public virtual void RefreshComponents() public virtual void RefreshComponents()
{ {
if ( Parent != null ) if ( this.Parent == null ) {
return; Map facet = this.Map;
Map map = Map; if ( facet != null ) {
facet.OnLeave( this );
if ( map != null ) facet.OnEnter( this );
{ }
map.OnLeave( this );
map.OnEnter( this );
} }
} }

View file

@ -24,29 +24,24 @@ using System.Collections.Generic;
using Server.Items; using Server.Items;
using Server.Network; using Server.Network;
namespace Server namespace Server {
{ public class RegionRect : IComparable {
public class RegionRect : IComparable
{
private Region m_Region; private Region m_Region;
private Rectangle3D m_Rect; private Rectangle3D m_Rect;
public Region Region { get { return m_Region; } } public Region Region { get { return m_Region; } }
public Rectangle3D Rect { get { return m_Rect; } } public Rectangle3D Rect { get { return m_Rect; } }
public RegionRect( Region region, Rectangle3D rect ) public RegionRect( Region region, Rectangle3D rect ) {
{
m_Region = region; m_Region = region;
m_Rect = rect; m_Rect = rect;
} }
public bool Contains( Point3D loc ) public bool Contains( Point3D loc ) {
{
return m_Rect.Contains( loc ); return m_Rect.Contains( loc );
} }
int IComparable.CompareTo( object obj ) int IComparable.CompareTo( object obj ) {
{
if ( obj == null ) if ( obj == null )
return 1; return 1;
@ -60,8 +55,7 @@ namespace Server
} }
public class Sector public class Sector {
{
private int m_X, m_Y; private int m_X, m_Y;
private Map m_Owner; private Map m_Owner;
private List<Mobile> m_Mobiles; private List<Mobile> m_Mobiles;
@ -79,195 +73,173 @@ namespace Server
private static List<BaseMulti> m_DefaultMultiList = new List<BaseMulti>(); private static List<BaseMulti> m_DefaultMultiList = new List<BaseMulti>();
private static List<RegionRect> m_DefaultRectList = new List<RegionRect>(); private static List<RegionRect> m_DefaultRectList = new List<RegionRect>();
public Sector( int x, int y, Map owner ) public Sector( int x, int y, Map owner ) {
{
m_X = x; m_X = x;
m_Y = y; m_Y = y;
m_Owner = owner; m_Owner = owner;
m_Active = false; m_Active = false;
} }
public void OnClientChange( NetState oldState, NetState newState ) private void Add<T>( ref List<T> list, T value ) {
{ if ( list == null ) {
if ( m_Clients != null ) list = new List<T>();
{ }
m_Clients.Remove( oldState );
if ( newState == null && m_Clients.Count == 0 ) list.Add( value );
{ }
m_Clients = null;
return; private void Remove<T>( ref List<T> list, T value ) {
if ( list != null ) {
list.Remove( value );
if ( list.Count == 0 ) {
list = null;
}
} }
} }
if ( newState != null ) private void Replace<T>( ref List<T> list, T oldValue, T newValue ) {
{ if ( oldValue != null && newValue != null ) {
if ( m_Clients == null ) int index = ( list != null ? list.IndexOf( oldValue ) : -1 );
m_Clients = new List<NetState>();
m_Clients.Add( newState ); 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 OnEnter( Mobile m ) public void OnClientChange( NetState oldState, NetState newState ) {
{ Replace( ref m_Clients, oldState, newState );
if ( m_Mobiles == null )
m_Mobiles = new List<Mobile>();
m_Mobiles.Add( m );
if ( m.NetState != null )
{
if ( m_Clients == null )
m_Clients = new List<NetState>();
m_Clients.Add( m.NetState );
} }
if ( m.Player ) public void OnEnter( Item item ) {
{ Add( ref m_Items, item );
if ( m_Players == null ) }
{
m_Players = new List<Mobile>(); 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 ); m_Owner.ActivateSectors( m_X, m_Y );
} }
m_Players.Add( m ); Add( ref m_Players, mob );
} }
} }
public void OnEnter( Item item ) public void OnLeave( Mobile mob ) {
{ Remove( ref m_Mobiles, mob );
if ( m_Items == null )
m_Items = new List<Item>();
m_Items.Add( item ); if ( mob.NetState != null ) {
Remove( ref m_Clients, mob.NetState );
} }
public void OnEnter( Region r, Rectangle3D rect ) if ( mob.Player && m_Players != null ) {
{ Remove( ref m_Players, mob );
if ( m_RegionRects == null )
m_RegionRects = new List<RegionRect>();
RegionRect regRect = new RegionRect( r, rect ); 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.Add( regRect );
m_RegionRects.Sort(); m_RegionRects.Sort();
if ( m_Mobiles != null && m_Mobiles.Count > 0 ) UpdateMobileRegions();
{
List<Mobile> list = new List<Mobile>( m_Mobiles );
for ( int i = 0; i < list.Count; ++i )
list[i].UpdateRegion();
}
} }
public void OnMultiEnter( BaseMulti m ) public void OnLeave( Region region ) {
{ if ( m_RegionRects != null ) {
if ( m_Multis == null ) for ( int i = m_RegionRects.Count - 1; i >= 0; i-- ) {
m_Multis = new List<BaseMulti>();
m_Multis.Add( m );
}
public void OnMultiLeave( BaseMulti m )
{
m_Multis.Remove( m );
if ( m_Multis.Count == 0 )
m_Multis = null;
}
public void OnLeave( Region r )
{
for ( int i = m_RegionRects.Count - 1; i >= 0; i-- )
{
RegionRect regRect = m_RegionRects[i]; RegionRect regRect = m_RegionRects[i];
if ( regRect.Region == r ) if ( regRect.Region == region ) {
m_RegionRects.RemoveAt( i ); m_RegionRects.RemoveAt( i );
} }
if ( m_Mobiles != null && m_Mobiles.Count > 0 )
{
List<Mobile> list = new List<Mobile>( m_Mobiles );
for ( int i = 0; i < list.Count; ++i )
list[i].UpdateRegion();
} }
if ( m_RegionRects.Count == 0 ) if ( m_RegionRects.Count == 0 ) {
m_RegionRects = null; m_RegionRects = null;
} }
public void OnLeave( Mobile m )
{
m_Mobiles.Remove( m );
if ( m_Clients != null && m.NetState != null )
{
m_Clients.Remove( m.NetState );
if ( m_Clients.Count == 0 )
m_Clients = null;
} }
if ( m.Player ) UpdateMobileRegions();
{ }
m_Players.Remove( m );
if ( m_Players.Count == 0 ) private void UpdateMobileRegions() {
{ if ( m_Mobiles != null ) {
m_Owner.DeactivateSectors( m_X, m_Y ); List<Mobile> sandbox = new List<Mobile>( m_Mobiles );
m_Players = null;
foreach ( Mobile mob in sandbox ) {
mob.UpdateRegion();
}
} }
} }
if ( m_Mobiles.Count == 0 ) public void OnMultiEnter( BaseMulti multi ) {
m_Mobiles = null; Add( ref m_Multis, multi );
} }
public void OnLeave( Item item ) public void OnMultiLeave( BaseMulti multi ) {
{ Remove( ref m_Multis, multi );
m_Items.Remove( item );
if ( m_Items.Count == 0 )
m_Items = null;
} }
public void Activate() public void Activate() {
{ if ( !Active && m_Owner != Map.Internal ) {
if ( !Active && m_Owner != Map.Internal ) if ( m_Items != null ) {
{ foreach ( Item item in m_Items ) {
for ( int i = 0; m_Items != null && i < m_Items.Count; i++ ) item.OnSectorActivate();
m_Items[i].OnSectorActivate(); }
}
for ( int i = 0; m_Mobiles != null && i < m_Mobiles.Count; i++ ) if ( m_Mobiles != null ) {
m_Mobiles[i].OnSectorActivate(); foreach ( Mobile mob in m_Mobiles ) {
mob.OnSectorActivate();
}
}
m_Active = true; m_Active = true;
} }
} }
public void Deactivate() public void Deactivate() {
{ if ( Active ) {
if ( Active ) if ( m_Items != null ) {
{ foreach ( Item item in m_Items ) {
for ( int i = 0; m_Items != null && i < m_Items.Count; i++ ) item.OnSectorDeactivate();
m_Items[i].OnSectorDeactivate(); }
}
for ( int i = 0; m_Mobiles != null && i < m_Mobiles.Count; i++ ) if ( m_Mobiles != null ) {
m_Mobiles[i].OnSectorDeactivate(); foreach ( Mobile mob in m_Mobiles ) {
mob.OnSectorDeactivate();
}
}
m_Active = false; m_Active = false;
} }
} }
public List<RegionRect> RegionRects public List<RegionRect> RegionRects {
{ get {
get
{
if ( m_RegionRects == null ) if ( m_RegionRects == null )
return m_DefaultRectList; return m_DefaultRectList;
@ -275,10 +247,8 @@ namespace Server
} }
} }
public List<BaseMulti> Multis public List<BaseMulti> Multis {
{ get {
get
{
if ( m_Multis == null ) if ( m_Multis == null )
return m_DefaultMultiList; return m_DefaultMultiList;
@ -286,10 +256,8 @@ namespace Server
} }
} }
public List<Mobile> Mobiles public List<Mobile> Mobiles {
{ get {
get
{
if ( m_Mobiles == null ) if ( m_Mobiles == null )
return m_DefaultMobileList; return m_DefaultMobileList;
@ -297,10 +265,8 @@ namespace Server
} }
} }
public List<Item> Items public List<Item> Items {
{ get {
get
{
if ( m_Items == null ) if ( m_Items == null )
return m_DefaultItemList; return m_DefaultItemList;
@ -308,10 +274,8 @@ namespace Server
} }
} }
public List<NetState> Clients public List<NetState> Clients {
{ get {
get
{
if ( m_Clients == null ) if ( m_Clients == null )
return m_DefaultClientList; return m_DefaultClientList;
@ -319,10 +283,8 @@ namespace Server
} }
} }
public List<Mobile> Players public List<Mobile> Players {
{ get {
get
{
if ( m_Players == null ) if ( m_Players == null )
return m_DefaultMobileList; return m_DefaultMobileList;
@ -330,34 +292,26 @@ namespace Server
} }
} }
public bool Active public bool Active {
{ get {
get
{
return ( m_Active && m_Owner != Map.Internal ); return ( m_Active && m_Owner != Map.Internal );
} }
} }
public Map Owner public Map Owner {
{ get {
get
{
return m_Owner; return m_Owner;
} }
} }
public int X public int X {
{ get {
get
{
return m_X; return m_X;
} }
} }
public int Y public int Y {
{ get {
get
{
return m_Y; return m_Y;
} }
} }