fix: Prepares for IPooledEnumerable removal (#1548)
### Summary - Removes `IPooledEnumerable` (non-generic) - Changes `IPooledEnumerable<T>` so that `Free()` is replaced with the `IDisposable` pattern
This commit is contained in:
parent
c2d6578955
commit
d57f1fecc1
92 changed files with 644 additions and 907 deletions
|
|
@ -82,8 +82,6 @@ public static class Effects
|
|||
OutgoingEffectPackets.CreateSoundEffect(buffer, soundID, p);
|
||||
state.Send(buffer);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,8 +125,6 @@ public static class Effects
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public static void SendLocationEffect(
|
||||
|
|
@ -196,8 +192,6 @@ public static class Effects
|
|||
state.Send(regular);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public static void SendTargetEffect(IEntity target, int itemID, int speed, int duration, int hue = 0, int renderMode = 0)
|
||||
|
|
@ -258,8 +252,6 @@ public static class Effects
|
|||
state.Send(regular);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public static void SendMovingEffect(
|
||||
|
|
@ -478,8 +470,6 @@ public static class Effects
|
|||
state.Send(regular);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public static void SendPacket(Point3D origin, Map map, Span<byte> effectBuffer)
|
||||
|
|
@ -496,7 +486,5 @@ public static class Effects
|
|||
state.Mobile.ProcessDelta();
|
||||
state.Send(effectBuffer);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -346,8 +346,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(removeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
Delta(ItemDelta.Update);
|
||||
|
|
@ -1148,8 +1146,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
RemDelta(ItemDelta.Update);
|
||||
|
|
@ -1179,8 +1175,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(removeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
var oldInternalLocation = m_Location;
|
||||
|
|
@ -1200,8 +1194,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
m_Map.OnMove(oldInternalLocation, this);
|
||||
|
||||
RemDelta(ItemDelta.Update);
|
||||
|
|
@ -1403,8 +1395,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
SendOPLPacketTo(state);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void Delete()
|
||||
|
|
@ -1516,8 +1506,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(removeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
var oldLoc = m_Location;
|
||||
|
|
@ -1539,8 +1527,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
RemDelta(ItemDelta.Update);
|
||||
}
|
||||
else
|
||||
|
|
@ -3302,8 +3288,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void PublicOverheadMessage(MessageType type, int hue, int number, string args = "")
|
||||
|
|
@ -3336,8 +3320,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void OnAfterDelete()
|
||||
|
|
@ -3589,8 +3571,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
items.Add(item);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (z == int.MinValue)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -3792,8 +3772,6 @@ public class Item : IHued, IComparable<Item>, ISpawnable, IObjectPropertyListEnt
|
|||
state.Send(removeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual int GetDropSound() => -1;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,24 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Map.cs *
|
||||
* *
|
||||
* 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 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Server.Buffers;
|
||||
using Server.Collections;
|
||||
using Server.Items;
|
||||
using Server.Logging;
|
||||
using Server.Network;
|
||||
|
|
@ -24,295 +38,6 @@ public enum MapRules
|
|||
FeluccaRules = None
|
||||
}
|
||||
|
||||
public interface IPooledEnumerable : IEnumerable
|
||||
{
|
||||
void Free();
|
||||
}
|
||||
|
||||
public interface IPooledEnumerable<T> : IPooledEnumerable, IEnumerable<T>
|
||||
{
|
||||
}
|
||||
|
||||
public static class PooledEnumeration
|
||||
{
|
||||
public delegate IEnumerable<T> Selector<out T>(Sector sector, Rectangle2D bounds);
|
||||
|
||||
static PooledEnumeration()
|
||||
{
|
||||
ClientSelector = SelectClients;
|
||||
EntitySelector = SelectEntities;
|
||||
MobileSelector = SelectMobiles<Mobile>;
|
||||
ItemSelector = SelectItems<Item>;
|
||||
MultiSelector = SelectMultis;
|
||||
MultiTileSelector = SelectMultiTiles;
|
||||
}
|
||||
|
||||
public static Selector<NetState> ClientSelector { get; set; }
|
||||
public static Selector<IEntity> EntitySelector { get; set; }
|
||||
public static Selector<Mobile> MobileSelector { get; set; }
|
||||
public static Selector<Item> ItemSelector { get; set; }
|
||||
public static Selector<BaseMulti> MultiSelector { get; set; }
|
||||
public static Selector<StaticTile[]> MultiTileSelector { get; set; }
|
||||
|
||||
public static IEnumerable<NetState> SelectClients(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var clients = new List<NetState>(s.Clients.Count);
|
||||
foreach (var client in s.Clients)
|
||||
{
|
||||
var m = client.Mobile;
|
||||
|
||||
if (m?.Deleted == false && bounds.Contains(m.Location))
|
||||
{
|
||||
clients.Add(client);
|
||||
}
|
||||
}
|
||||
|
||||
return clients;
|
||||
}
|
||||
|
||||
public static IEnumerable<IEntity> SelectEntities(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var entities = new List<IEntity>(s.Mobiles.Count + s.Items.Count);
|
||||
for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j)
|
||||
{
|
||||
if (j >= 0)
|
||||
{
|
||||
Item item = s.Items[j];
|
||||
if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob is { Deleted: false } && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectMobiles<T>(Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
var entities = new List<T>(s.Mobiles.Count);
|
||||
for (int i = s.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectItems<T>(Sector s, Rectangle2D bounds) where T : Item
|
||||
{
|
||||
var entities = new List<T>(s.Items.Count);
|
||||
for (int i = s.Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<BaseMulti> SelectMultis(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var entities = new List<BaseMulti>(s.Multis.Count);
|
||||
for (int i = s.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti multi = s.Multis[i];
|
||||
if (multi is { Deleted: false } && bounds.Contains(multi.Location))
|
||||
{
|
||||
entities.Add(multi);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<StaticTile[]> SelectMultiTiles(Sector s, Rectangle2D bounds)
|
||||
{
|
||||
for (int l = s.Multis.Count - 1; l >= 0; --l)
|
||||
{
|
||||
BaseMulti o = s.Multis[l];
|
||||
if (o?.Deleted != false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiComponentList c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Map.PooledEnumerable<NetState> GetClients(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<NetState>.Instantiate(map, bounds, ClientSelector ?? SelectClients);
|
||||
|
||||
public static Map.PooledEnumerable<IEntity> GetEntities(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<IEntity>.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
|
||||
|
||||
public static Map.PooledEnumerable<Mobile> GetMobiles(Map map, Rectangle2D bounds) =>
|
||||
GetMobiles<Mobile>(map, bounds);
|
||||
|
||||
public static Map.PooledEnumerable<T> GetMobiles<T>(Map map, Rectangle2D bounds) where T : Mobile =>
|
||||
Map.PooledEnumerable<T>.Instantiate(map, bounds, SelectMobiles<T>);
|
||||
|
||||
public static Map.PooledEnumerable<T> GetItems<T>(Map map, Rectangle2D bounds) where T : Item =>
|
||||
Map.PooledEnumerable<T>.Instantiate(map, bounds, SelectItems<T>);
|
||||
|
||||
public static Map.PooledEnumerable<BaseMulti> GetMultis(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<BaseMulti>.Instantiate(map, bounds, MultiSelector ?? SelectMultis);
|
||||
|
||||
public static Map.PooledEnumerable<StaticTile[]> GetMultiTiles(Map map, Rectangle2D bounds) =>
|
||||
Map.PooledEnumerable<StaticTile[]>.Instantiate(map, bounds, MultiTileSelector ?? SelectMultiTiles);
|
||||
|
||||
public static IEnumerable<Sector> EnumerateSectors(Map map, Rectangle2D bounds)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var x1 = bounds.Start.X;
|
||||
var y1 = bounds.Start.Y;
|
||||
var x2 = bounds.End.X;
|
||||
var y2 = bounds.End.Y;
|
||||
|
||||
if (!Bound(map, ref x1, ref y1, ref x2, ref y2, out var xSector, out var ySector))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
|
||||
while (NextSector(map, x1, y1, x2, y2, ref index, ref xSector, ref ySector, out var s))
|
||||
{
|
||||
yield return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Bound(
|
||||
Map map,
|
||||
ref int x1,
|
||||
ref int y1,
|
||||
ref int x2,
|
||||
ref int y2,
|
||||
out int xSector,
|
||||
out int ySector
|
||||
)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
map.Bound(x1, y1, out x1, out y1);
|
||||
map.Bound(x2 - 1, y2 - 1, out x2, out y2);
|
||||
|
||||
x1 >>= Map.SectorShift;
|
||||
y1 >>= Map.SectorShift;
|
||||
x2 >>= Map.SectorShift;
|
||||
y2 >>= Map.SectorShift;
|
||||
|
||||
xSector = x1;
|
||||
ySector = y1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool NextSector(
|
||||
Map map,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
ref int index,
|
||||
ref int xSector,
|
||||
ref int ySector,
|
||||
out Sector s
|
||||
)
|
||||
{
|
||||
if (map == null)
|
||||
{
|
||||
s = null;
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (map == Map.Internal)
|
||||
{
|
||||
s = map.InvalidSector;
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index++ > 0)
|
||||
{
|
||||
if (++ySector > y2)
|
||||
{
|
||||
ySector = y1;
|
||||
|
||||
if (++xSector > x2)
|
||||
{
|
||||
xSector = x1;
|
||||
|
||||
s = map.InvalidSector;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s = map.GetRealSector(xSector, ySector);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
||||
{
|
||||
public const int SectorSize = 16;
|
||||
|
|
@ -501,7 +226,6 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString() => Name;
|
||||
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
|
|
@ -598,8 +322,6 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Array.Sort(pool, 0, length, ZComparer.Default);
|
||||
}
|
||||
|
||||
|
|
@ -1429,8 +1151,6 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (contains)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -1510,11 +1230,9 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
continue;
|
||||
}
|
||||
|
||||
area.Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
area.Free();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1598,88 +1316,6 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
return loc;
|
||||
}
|
||||
|
||||
public class NullEnumerable<T> : IPooledEnumerable<T>
|
||||
{
|
||||
public static readonly NullEnumerable<T> Instance = new();
|
||||
|
||||
private readonly IEnumerable<T> m_Empty = Enumerable.Empty<T>();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => m_Empty.GetEnumerator();
|
||||
|
||||
public void Free()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PooledEnumerable<T> : IPooledEnumerable<T>, IDisposable
|
||||
{
|
||||
private static readonly Queue<PooledEnumerable<T>> _Buffer = new(0x400);
|
||||
|
||||
private bool m_IsDisposed;
|
||||
|
||||
private List<T> m_Pool = new(0x40);
|
||||
|
||||
public PooledEnumerable(IEnumerable<T> pool)
|
||||
{
|
||||
m_Pool.AddRange(pool);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_IsDisposed = true;
|
||||
|
||||
m_Pool.Clear();
|
||||
m_Pool.TrimExcess();
|
||||
m_Pool = null;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_Pool.GetEnumerator();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => m_Pool.GetEnumerator();
|
||||
|
||||
public void Free()
|
||||
{
|
||||
if (m_IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Pool.Clear();
|
||||
m_Pool.Capacity = Math.Max(m_Pool.Capacity, 0x100);
|
||||
|
||||
lock (((ICollection)_Buffer).SyncRoot)
|
||||
{
|
||||
_Buffer.Enqueue(this);
|
||||
}
|
||||
}
|
||||
#pragma warning disable CA1000 // Do not declare static members on generic types
|
||||
public static PooledEnumerable<T> Instantiate(
|
||||
Map map, Rectangle2D bounds, PooledEnumeration.Selector<T> selector
|
||||
)
|
||||
{
|
||||
PooledEnumerable<T> e = null;
|
||||
|
||||
lock (((ICollection)_Buffer).SyncRoot)
|
||||
{
|
||||
if (_Buffer.Count > 0)
|
||||
{
|
||||
e = _Buffer.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
var pool = PooledEnumeration.EnumerateSectors(map, bounds).SelectMany(s => selector(s, bounds));
|
||||
|
||||
if (e == null)
|
||||
{
|
||||
return new PooledEnumerable<T>(pool);
|
||||
}
|
||||
|
||||
e.m_Pool.AddRange(pool);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CA1000 // Do not declare static members on generic types
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Map Parse(string s) => Parse(s, null);
|
||||
|
|
@ -1775,4 +1411,212 @@ public sealed class Map : IComparable<Map>, ISpanFormattable, ISpanParsable<Map>
|
|||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public class RegionRect : IComparable<RegionRect>
|
||||
{
|
||||
private Rectangle3D m_Rect;
|
||||
|
||||
public RegionRect(Region region, Rectangle3D rect)
|
||||
{
|
||||
Region = region;
|
||||
m_Rect = rect;
|
||||
}
|
||||
|
||||
public Region Region { get; }
|
||||
|
||||
public Rectangle3D Rect => m_Rect;
|
||||
|
||||
public int CompareTo(RegionRect regRect) => regRect == null ? 1 : Region.CompareTo(regRect.Region);
|
||||
|
||||
public bool Contains(Point3D loc) => m_Rect.Contains(loc);
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
// TODO: Can we avoid this?
|
||||
private static readonly List<Mobile> m_DefaultMobileList = new();
|
||||
private static readonly List<Item> m_DefaultItemList = new();
|
||||
private static readonly List<NetState> m_DefaultClientList = new();
|
||||
private static readonly List<BaseMulti> m_DefaultMultiList = new();
|
||||
private static readonly List<RegionRect> m_DefaultRectList = new();
|
||||
private bool m_Active;
|
||||
private List<NetState> m_Clients;
|
||||
private List<Item> m_Items;
|
||||
private List<Mobile> m_Mobiles;
|
||||
private List<BaseMulti> m_Multis;
|
||||
private List<RegionRect> m_RegionRects;
|
||||
|
||||
public Sector(int x, int y, Map owner)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Owner = owner;
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
public List<RegionRect> RegionRects => m_RegionRects ?? m_DefaultRectList;
|
||||
|
||||
public List<BaseMulti> Multis => m_Multis ?? m_DefaultMultiList;
|
||||
|
||||
public List<Mobile> Mobiles => m_Mobiles ?? m_DefaultMobileList;
|
||||
|
||||
public List<Item> Items => m_Items ?? m_DefaultItemList;
|
||||
|
||||
public List<NetState> Clients => m_Clients ?? m_DefaultClientList;
|
||||
|
||||
public bool Active => m_Active && Owner != Map.Internal;
|
||||
|
||||
public Map Owner { get; }
|
||||
|
||||
public int X { get; }
|
||||
|
||||
public int Y { get; }
|
||||
|
||||
public void OnClientChange(NetState oldState, NetState newState)
|
||||
{
|
||||
Utility.Replace(ref m_Clients, oldState, newState);
|
||||
}
|
||||
|
||||
public void OnEnter(Item item)
|
||||
{
|
||||
Utility.Add(ref m_Items, item);
|
||||
}
|
||||
|
||||
public void OnLeave(Item item)
|
||||
{
|
||||
Utility.Remove(ref m_Items, item);
|
||||
}
|
||||
|
||||
public void OnEnter(Mobile mob)
|
||||
{
|
||||
Utility.Add(ref m_Mobiles, mob);
|
||||
|
||||
if (mob.NetState != null)
|
||||
{
|
||||
Utility.Add(ref m_Clients, mob.NetState);
|
||||
|
||||
Owner.ActivateSectors(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLeave(Mobile mob)
|
||||
{
|
||||
Utility.Remove(ref m_Mobiles, mob);
|
||||
|
||||
if (mob.NetState != null)
|
||||
{
|
||||
Utility.Remove(ref m_Clients, mob.NetState);
|
||||
|
||||
Owner.DeactivateSectors(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEnter(Region region, Rectangle3D rect)
|
||||
{
|
||||
Utility.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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_RegionRects.Count == 0)
|
||||
{
|
||||
m_RegionRects = null;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateMobileRegions();
|
||||
}
|
||||
|
||||
private void UpdateMobileRegions()
|
||||
{
|
||||
if (m_Mobiles != null)
|
||||
{
|
||||
using var queue = PooledRefQueue<Mobile>.Create(m_Mobiles.Count);
|
||||
foreach (var mob in m_Mobiles)
|
||||
{
|
||||
queue.Enqueue(mob);
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
queue.Dequeue().UpdateRegion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMultiEnter(BaseMulti multi)
|
||||
{
|
||||
Utility.Add(ref m_Multis, multi);
|
||||
}
|
||||
|
||||
public void OnMultiLeave(BaseMulti multi)
|
||||
{
|
||||
Utility.Remove(ref m_Multis, multi);
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (!Active)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
390
Projects/Server/Maps/PooledEnumeration.cs
Normal file
390
Projects/Server/Maps/PooledEnumeration.cs
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2023 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: PooledEnumeration.cs *
|
||||
* *
|
||||
* 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 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server;
|
||||
|
||||
public interface IPooledEnumerable<T> : IEnumerable<T>, IDisposable
|
||||
{
|
||||
}
|
||||
|
||||
public static class PooledEnumeration
|
||||
{
|
||||
public delegate IEnumerable<T> Selector<out T>(Map.Sector sector, Rectangle2D bounds);
|
||||
|
||||
static PooledEnumeration()
|
||||
{
|
||||
ClientSelector = SelectClients;
|
||||
EntitySelector = SelectEntities;
|
||||
MobileSelector = SelectMobiles<Mobile>;
|
||||
ItemSelector = SelectItems<Item>;
|
||||
MultiSelector = SelectMultis;
|
||||
MultiTileSelector = SelectMultiTiles;
|
||||
}
|
||||
|
||||
public static Selector<NetState> ClientSelector { get; set; }
|
||||
public static Selector<IEntity> EntitySelector { get; set; }
|
||||
public static Selector<Mobile> MobileSelector { get; set; }
|
||||
public static Selector<Item> ItemSelector { get; set; }
|
||||
public static Selector<BaseMulti> MultiSelector { get; set; }
|
||||
public static Selector<StaticTile[]> MultiTileSelector { get; set; }
|
||||
|
||||
public static IEnumerable<NetState> SelectClients(Map.Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var clients = new List<NetState>(s.Clients.Count);
|
||||
foreach (var client in s.Clients)
|
||||
{
|
||||
var m = client.Mobile;
|
||||
|
||||
if (m?.Deleted == false && bounds.Contains(m.Location))
|
||||
{
|
||||
clients.Add(client);
|
||||
}
|
||||
}
|
||||
|
||||
return clients;
|
||||
}
|
||||
|
||||
public static IEnumerable<IEntity> SelectEntities(Map.Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var entities = new List<IEntity>(s.Mobiles.Count + s.Items.Count);
|
||||
for (int i = s.Mobiles.Count - 1, j = s.Items.Count - 1; i >= 0 || j >= 0; --i, --j)
|
||||
{
|
||||
if (j >= 0)
|
||||
{
|
||||
Item item = s.Items[j];
|
||||
if (item is { Deleted: false, Parent: null } && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
Mobile mob = s.Mobiles[i];
|
||||
if (mob is { Deleted: false } && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectMobiles<T>(Map.Sector s, Rectangle2D bounds) where T : Mobile
|
||||
{
|
||||
var entities = new List<T>(s.Mobiles.Count);
|
||||
for (int i = s.Mobiles.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Mobiles[i] is T { Deleted: false } mob && bounds.Contains(mob.Location))
|
||||
{
|
||||
entities.Add(mob);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> SelectItems<T>(Map.Sector s, Rectangle2D bounds) where T : Item
|
||||
{
|
||||
var entities = new List<T>(s.Items.Count);
|
||||
for (int i = s.Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (s.Items[i] is T { Deleted: false, Parent: null } item && bounds.Contains(item.Location))
|
||||
{
|
||||
entities.Add(item);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<BaseMulti> SelectMultis(Map.Sector s, Rectangle2D bounds)
|
||||
{
|
||||
var entities = new List<BaseMulti>(s.Multis.Count);
|
||||
for (int i = s.Multis.Count - 1; i >= 0; --i)
|
||||
{
|
||||
BaseMulti multi = s.Multis[i];
|
||||
if (multi is { Deleted: false } && bounds.Contains(multi.Location))
|
||||
{
|
||||
entities.Add(multi);
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
public static IEnumerable<StaticTile[]> SelectMultiTiles(Map.Sector s, Rectangle2D bounds)
|
||||
{
|
||||
for (int l = s.Multis.Count - 1; l >= 0; --l)
|
||||
{
|
||||
BaseMulti o = s.Multis[l];
|
||||
if (o?.Deleted != false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MultiComponentList c = o.Components;
|
||||
|
||||
int x, y, xo, yo;
|
||||
StaticTile[] t, r;
|
||||
|
||||
for (x = bounds.Start.X; x < bounds.End.X; x++)
|
||||
{
|
||||
xo = x - (o.X + c.Min.X);
|
||||
|
||||
if (xo < 0 || xo >= c.Width)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (y = bounds.Start.Y; y < bounds.End.Y; y++)
|
||||
{
|
||||
yo = y - (o.Y + c.Min.Y);
|
||||
|
||||
if (yo < 0 || yo >= c.Height)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
t = c.Tiles[xo][yo];
|
||||
|
||||
if (t.Length <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
r = new StaticTile[t.Length];
|
||||
|
||||
for (var i = 0; i < t.Length; i++)
|
||||
{
|
||||
r[i] = t[i];
|
||||
r[i].Z += o.Z;
|
||||
}
|
||||
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PooledEnumerable<NetState> GetClients(Map map, Rectangle2D bounds) =>
|
||||
PooledEnumerable<NetState>.Instantiate(map, bounds, ClientSelector ?? SelectClients);
|
||||
|
||||
public static PooledEnumerable<IEntity> GetEntities(Map map, Rectangle2D bounds) =>
|
||||
PooledEnumerable<IEntity>.Instantiate(map, bounds, EntitySelector ?? SelectEntities);
|
||||
|
||||
public static PooledEnumerable<Mobile> GetMobiles(Map map, Rectangle2D bounds) =>
|
||||
GetMobiles<Mobile>(map, bounds);
|
||||
|
||||
public static PooledEnumerable<T> GetMobiles<T>(Map map, Rectangle2D bounds) where T : Mobile =>
|
||||
PooledEnumerable<T>.Instantiate(map, bounds, SelectMobiles<T>);
|
||||
|
||||
public static PooledEnumerable<T> GetItems<T>(Map map, Rectangle2D bounds) where T : Item =>
|
||||
PooledEnumerable<T>.Instantiate(map, bounds, SelectItems<T>);
|
||||
|
||||
public static PooledEnumerable<BaseMulti> GetMultis(Map map, Rectangle2D bounds) =>
|
||||
PooledEnumerable<BaseMulti>.Instantiate(map, bounds, MultiSelector ?? SelectMultis);
|
||||
|
||||
public static PooledEnumerable<StaticTile[]> GetMultiTiles(Map map, Rectangle2D bounds) =>
|
||||
PooledEnumerable<StaticTile[]>.Instantiate(map, bounds, MultiTileSelector ?? SelectMultiTiles);
|
||||
|
||||
public static IEnumerable<Map.Sector> EnumerateSectors(Map map, Rectangle2D bounds)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var x1 = bounds.Start.X;
|
||||
var y1 = bounds.Start.Y;
|
||||
var x2 = bounds.End.X;
|
||||
var y2 = bounds.End.Y;
|
||||
|
||||
if (!Bound(map, ref x1, ref y1, ref x2, ref y2, out var xSector, out var ySector))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
|
||||
while (NextSector(map, x1, y1, x2, y2, ref index, ref xSector, ref ySector, out var s))
|
||||
{
|
||||
yield return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Bound(
|
||||
Map map,
|
||||
ref int x1,
|
||||
ref int y1,
|
||||
ref int x2,
|
||||
ref int y2,
|
||||
out int xSector,
|
||||
out int ySector
|
||||
)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
map.Bound(x1, y1, out x1, out y1);
|
||||
map.Bound(x2 - 1, y2 - 1, out x2, out y2);
|
||||
|
||||
x1 >>= Map.SectorShift;
|
||||
y1 >>= Map.SectorShift;
|
||||
x2 >>= Map.SectorShift;
|
||||
y2 >>= Map.SectorShift;
|
||||
|
||||
xSector = x1;
|
||||
ySector = y1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool NextSector(
|
||||
Map map,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
ref int index,
|
||||
ref int xSector,
|
||||
ref int ySector,
|
||||
out Map.Sector s
|
||||
)
|
||||
{
|
||||
if (map == null)
|
||||
{
|
||||
s = null;
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (map == Map.Internal)
|
||||
{
|
||||
s = map.InvalidSector;
|
||||
xSector = ySector = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index++ > 0)
|
||||
{
|
||||
if (++ySector > y2)
|
||||
{
|
||||
ySector = y1;
|
||||
|
||||
if (++xSector > x2)
|
||||
{
|
||||
xSector = x1;
|
||||
|
||||
s = map.InvalidSector;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s = map.GetRealSector(xSector, ySector);
|
||||
return true;
|
||||
}
|
||||
|
||||
public class NullEnumerable<T> : IPooledEnumerable<T>
|
||||
{
|
||||
public static readonly NullEnumerable<T> Instance = new();
|
||||
|
||||
private readonly IEnumerable<T> m_Empty = Enumerable.Empty<T>();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_Empty.GetEnumerator();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => m_Empty.GetEnumerator();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PooledEnumerable<T> : IPooledEnumerable<T>
|
||||
{
|
||||
private static readonly Queue<PooledEnumerable<T>> _Buffer = new(0x400);
|
||||
|
||||
private bool m_IsDisposed;
|
||||
|
||||
private List<T> m_Pool = new(0x40);
|
||||
|
||||
public PooledEnumerable(IEnumerable<T> pool)
|
||||
{
|
||||
m_Pool.AddRange(pool);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_IsDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_IsDisposed = true;
|
||||
|
||||
m_Pool.Clear();
|
||||
m_Pool.Capacity = Math.Max(m_Pool.Capacity, 0x100);
|
||||
|
||||
lock (((ICollection)_Buffer).SyncRoot)
|
||||
{
|
||||
_Buffer.Enqueue(this);
|
||||
}
|
||||
}
|
||||
|
||||
~PooledEnumerable()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => m_Pool.GetEnumerator();
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => m_Pool.GetEnumerator();
|
||||
|
||||
|
||||
#pragma warning disable CA1000 // Do not declare static members on generic types
|
||||
public static PooledEnumerable<T> Instantiate(
|
||||
Map map, Rectangle2D bounds, PooledEnumeration.Selector<T> selector
|
||||
)
|
||||
{
|
||||
PooledEnumerable<T> e = null;
|
||||
|
||||
lock (((ICollection)_Buffer).SyncRoot)
|
||||
{
|
||||
if (_Buffer.Count > 0)
|
||||
{
|
||||
e = _Buffer.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
var pool = PooledEnumeration.EnumerateSectors(map, bounds).SelectMany(s => selector(s, bounds));
|
||||
|
||||
if (e == null)
|
||||
{
|
||||
return new PooledEnumerable<T>(pool);
|
||||
}
|
||||
|
||||
e.m_Pool.AddRange(pool);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2985,8 +2985,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
SendOPLPacketTo(state);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public ISpawner Spawner { get; set; }
|
||||
|
|
@ -4313,8 +4311,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
const int cacheLength = OutgoingMobilePackets.MobileMovingPacketCacheByteLength;
|
||||
const int width = OutgoingMobilePackets.MobileMovingPacketLength;
|
||||
|
||||
|
|
@ -4790,8 +4786,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
Region.OnDeath(this);
|
||||
|
|
@ -5092,8 +5086,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
ns.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
var fixLoc = item.Location;
|
||||
|
|
@ -5253,8 +5245,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
ns.Send(buffer);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual bool Drop(Item to, Point3D loc)
|
||||
|
|
@ -5585,8 +5575,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
object mutateContext = null;
|
||||
var mutatedText = text;
|
||||
SpeechEventArgs mutatedArgs = null;
|
||||
|
|
@ -5983,8 +5971,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
ns.SendDamage(Serial, amount);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void SendVisibleDamageSelective(Mobile from, int amount)
|
||||
|
|
@ -6745,8 +6731,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
state.Send(buffer);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
|
@ -6783,8 +6767,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void SendOPLPacketTo(NetState ns)
|
||||
|
|
@ -6837,8 +6819,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(removeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void ClearScreen()
|
||||
|
|
@ -6867,8 +6847,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -6949,8 +6927,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void UpdateRegion()
|
||||
|
|
@ -7086,8 +7062,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
SendOPLPacketTo(state);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void OnConnected()
|
||||
|
|
@ -7307,18 +7281,13 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
var ourState = m_NetState;
|
||||
|
||||
// Check to see if we are attached to a client
|
||||
if (ourState != null)
|
||||
{
|
||||
var eeable = map.GetObjectsInRange(newLocation, Core.GlobalMaxUpdateRange);
|
||||
|
||||
// We are attached to a client, so it's a bit more complex. We need to send new items and people to ourself, and ourself to other clients
|
||||
|
||||
foreach (var o in eeable)
|
||||
foreach (var o in map.GetObjectsInRange(newLocation, Core.GlobalMaxUpdateRange))
|
||||
{
|
||||
if (o is Item item)
|
||||
{
|
||||
|
|
@ -7381,8 +7350,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
m.SendOPLPacketTo(ourState);
|
||||
}
|
||||
}
|
||||
|
||||
eeable.Free();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -7411,8 +7378,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
SendOPLPacketTo(ns);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7494,8 +7459,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
SendOPLPacketTo(state);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public bool PlaceInBackpack(Item item) =>
|
||||
|
|
@ -8009,7 +7972,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable. Virtual event invoked when the sector this Mobile is in gets <see cref="Sector.Activate">activated</see>.
|
||||
/// Overridable. Virtual event invoked when the sector this Mobile is in gets <see cref="Map.Sector.Activate">activated</see>.
|
||||
/// </summary>
|
||||
public virtual void OnSectorActivate()
|
||||
{
|
||||
|
|
@ -8017,7 +7980,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
/// <summary>
|
||||
/// Overridable. Virtual event invoked when the sector this Mobile is in gets
|
||||
/// <see cref="Sector.Deactivate">deactivated</see>.
|
||||
/// <see cref="Map.Sector.Deactivate">deactivated</see>.
|
||||
/// </summary>
|
||||
public virtual void OnSectorDeactivate()
|
||||
{
|
||||
|
|
@ -8956,8 +8919,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void PublicOverheadMessage(MessageType type, int hue, int number, string args = "", bool noLineOfSight = true)
|
||||
|
|
@ -8987,8 +8948,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void PublicOverheadMessage(
|
||||
|
|
@ -9027,8 +8986,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void PrivateOverheadMessage(MessageType type, int hue, bool ascii, string text, NetState state)
|
||||
|
|
@ -9075,8 +9032,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void NonlocalOverheadMessage(MessageType type, int hue, bool ascii, string text)
|
||||
|
|
@ -9106,8 +9061,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
state.Send(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public void SendLocalizedMessage(int number, string args = "", int hue = 0x3B2) =>
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public class Region : IComparable<Region>, IValueLinkListNode<Region>
|
|||
|
||||
public Rectangle3D[] Area { get; }
|
||||
|
||||
public Sector[] Sectors { get; private set; }
|
||||
public Map.Sector[] Sectors { get; private set; }
|
||||
|
||||
public bool Dynamic { get; }
|
||||
|
||||
|
|
@ -346,7 +346,7 @@ public class Region : IComparable<Region>, IValueLinkListNode<Region>
|
|||
|
||||
Map.RegisterRegion(this);
|
||||
|
||||
var sectors = new List<Sector>();
|
||||
var sectors = new List<Map.Sector>();
|
||||
|
||||
for (var i = 0; i < Area.Length; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,215 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Collections;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server;
|
||||
|
||||
public class RegionRect : IComparable<RegionRect>
|
||||
{
|
||||
private Rectangle3D m_Rect;
|
||||
|
||||
public RegionRect(Region region, Rectangle3D rect)
|
||||
{
|
||||
Region = region;
|
||||
m_Rect = rect;
|
||||
}
|
||||
|
||||
public Region Region { get; }
|
||||
|
||||
public Rectangle3D Rect => m_Rect;
|
||||
|
||||
public int CompareTo(RegionRect regRect) => regRect == null ? 1 : Region.CompareTo(regRect.Region);
|
||||
|
||||
public bool Contains(Point3D loc) => m_Rect.Contains(loc);
|
||||
}
|
||||
|
||||
public class Sector
|
||||
{
|
||||
// TODO: Can we avoid this?
|
||||
private static readonly List<Mobile> m_DefaultMobileList = new();
|
||||
private static readonly List<Item> m_DefaultItemList = new();
|
||||
private static readonly List<NetState> m_DefaultClientList = new();
|
||||
private static readonly List<BaseMulti> m_DefaultMultiList = new();
|
||||
private static readonly List<RegionRect> m_DefaultRectList = new();
|
||||
private bool m_Active;
|
||||
private List<NetState> m_Clients;
|
||||
private List<Item> m_Items;
|
||||
private List<Mobile> m_Mobiles;
|
||||
private List<BaseMulti> m_Multis;
|
||||
private List<RegionRect> m_RegionRects;
|
||||
|
||||
public Sector(int x, int y, Map owner)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Owner = owner;
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
public List<RegionRect> RegionRects => m_RegionRects ?? m_DefaultRectList;
|
||||
|
||||
public List<BaseMulti> Multis => m_Multis ?? m_DefaultMultiList;
|
||||
|
||||
public List<Mobile> Mobiles => m_Mobiles ?? m_DefaultMobileList;
|
||||
|
||||
public List<Item> Items => m_Items ?? m_DefaultItemList;
|
||||
|
||||
public List<NetState> Clients => m_Clients ?? m_DefaultClientList;
|
||||
|
||||
public bool Active => m_Active && Owner != Map.Internal;
|
||||
|
||||
public Map Owner { get; }
|
||||
|
||||
public int X { get; }
|
||||
|
||||
public int Y { get; }
|
||||
|
||||
public void OnClientChange(NetState oldState, NetState newState)
|
||||
{
|
||||
Utility.Replace(ref m_Clients, oldState, newState);
|
||||
}
|
||||
|
||||
public void OnEnter(Item item)
|
||||
{
|
||||
Utility.Add(ref m_Items, item);
|
||||
}
|
||||
|
||||
public void OnLeave(Item item)
|
||||
{
|
||||
Utility.Remove(ref m_Items, item);
|
||||
}
|
||||
|
||||
public void OnEnter(Mobile mob)
|
||||
{
|
||||
Utility.Add(ref m_Mobiles, mob);
|
||||
|
||||
if (mob.NetState != null)
|
||||
{
|
||||
Utility.Add(ref m_Clients, mob.NetState);
|
||||
|
||||
Owner.ActivateSectors(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLeave(Mobile mob)
|
||||
{
|
||||
Utility.Remove(ref m_Mobiles, mob);
|
||||
|
||||
if (mob.NetState != null)
|
||||
{
|
||||
Utility.Remove(ref m_Clients, mob.NetState);
|
||||
|
||||
Owner.DeactivateSectors(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEnter(Region region, Rectangle3D rect)
|
||||
{
|
||||
Utility.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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_RegionRects.Count == 0)
|
||||
{
|
||||
m_RegionRects = null;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateMobileRegions();
|
||||
}
|
||||
|
||||
private void UpdateMobileRegions()
|
||||
{
|
||||
if (m_Mobiles != null)
|
||||
{
|
||||
using var queue = PooledRefQueue<Mobile>.Create(m_Mobiles.Count);
|
||||
foreach (var mob in m_Mobiles)
|
||||
{
|
||||
queue.Enqueue(mob);
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
queue.Dequeue().UpdateRegion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMultiEnter(BaseMulti multi)
|
||||
{
|
||||
Utility.Add(ref m_Multis, multi);
|
||||
}
|
||||
|
||||
public void OnMultiLeave(BaseMulti multi)
|
||||
{
|
||||
Utility.Remove(ref m_Multis, multi);
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
if (!Active)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -261,8 +261,6 @@ public class TileMatrix
|
|||
m_TilesList.AddRange(multiTiles);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (!any)
|
||||
{
|
||||
return tiles[x & 0x7][y & 0x7];
|
||||
|
|
|
|||
|
|
@ -997,6 +997,17 @@ public static class Utility
|
|||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Shuffle<T>(this PooledRefList<T> list)
|
||||
{
|
||||
var count = list.Count;
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var r = RandomMinMax(i, count - 1);
|
||||
(list[r], list[i]) = (list[i], list[r]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random sample from the source list.
|
||||
* Not meant for unbounded lists. Does not shuffle or modify source.
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ namespace Server.Commands.Generic
|
|||
objs.Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
ext.Filter(objs);
|
||||
|
||||
RunCommand(from, objs, command, args);
|
||||
|
|
|
|||
|
|
@ -1141,14 +1141,11 @@ namespace Server.Commands
|
|||
{
|
||||
if (item.Z == z && item.ItemID == itemID)
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (m_DeleteQueue.Count > 0)
|
||||
{
|
||||
m_DeleteQueue.Dequeue().Delete();
|
||||
|
|
@ -1211,8 +1208,6 @@ namespace Server.Commands
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
else if (item is MarkContainer markCont)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1137,14 +1137,11 @@ namespace Server.Commands
|
|||
{
|
||||
if (item.Z == z && item.ItemID == itemID)
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (m_DeleteQueue.Count > 0)
|
||||
{
|
||||
m_DeleteQueue.Dequeue()?.Delete();
|
||||
|
|
@ -1197,8 +1194,6 @@ namespace Server.Commands
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
else if (item is MarkContainer markCont)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,8 +132,6 @@ namespace Server.Commands
|
|||
item.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (m_ToDelete.Count > 0)
|
||||
{
|
||||
m_ToDelete.Dequeue().Delete();
|
||||
|
|
|
|||
|
|
@ -97,8 +97,6 @@ namespace Server.Commands
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
for (var i = 0; i < toDelete.Count; ++i)
|
||||
{
|
||||
toDelete[i].Delete();
|
||||
|
|
|
|||
|
|
@ -479,8 +479,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (empty)
|
||||
{
|
||||
HitObject(point, landTop, 0);
|
||||
|
|
@ -569,8 +567,6 @@ namespace Server.Engines.ConPVP
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
area.Free();
|
||||
if (i is BRGoal goal)
|
||||
{
|
||||
var oldLoc = new Point3D(GetWorldLocation());
|
||||
|
|
@ -591,8 +587,6 @@ namespace Server.Engines.ConPVP
|
|||
return;
|
||||
}
|
||||
|
||||
area.Free();
|
||||
|
||||
var clients = Map.GetClientsInBounds(rect);
|
||||
foreach (var ns in clients)
|
||||
{
|
||||
|
|
@ -622,16 +616,12 @@ namespace Server.Engines.ConPVP
|
|||
continue;
|
||||
}
|
||||
|
||||
clients.Free();
|
||||
|
||||
// TODO: probably need to change this a lot...
|
||||
DoCatch(m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
clients.Free();
|
||||
|
||||
m_PathIdx = pathCheckEnd;
|
||||
|
||||
if (m_PathIdx > 0 && m_PathIdx - 1 < m_Path.Count)
|
||||
|
|
@ -685,8 +675,6 @@ namespace Server.Engines.ConPVP
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Z = myZ;
|
||||
m_Flying = false;
|
||||
Visible = true;
|
||||
|
|
|
|||
|
|
@ -393,7 +393,6 @@ namespace Server.Engines.Craft
|
|||
{
|
||||
if (item.Z + 16 > item.Z && item.Z + 16 > item.Z && Find(item.ItemID, itemIDs))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,8 +65,6 @@ public class DefBlacksmithy : CraftSystem
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
for (var x = -range; (!anvil || !forge) && x <= range; ++x)
|
||||
{
|
||||
for (var y = -range; (!anvil || !forge) && y <= range; ++y)
|
||||
|
|
|
|||
|
|
@ -203,14 +203,11 @@ public partial class LeverPuzzleController : Item
|
|||
{
|
||||
if (item is LeverPuzzleController)
|
||||
{
|
||||
eable.Free();
|
||||
e.Mobile.SendMessage("Lamp room puzzle already exists: please delete the existing controller first ...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
e.Mobile.SendMessage("Generating Lamp Room puzzle...");
|
||||
|
||||
NetState.FlushAll();
|
||||
|
|
@ -533,8 +530,6 @@ public partial class LeverPuzzleController : Item
|
|||
|
||||
state.Send(buffer);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private void Deserialize(IGenericReader reader, int version)
|
||||
|
|
@ -620,7 +615,6 @@ public partial class LeverPuzzleController : Item
|
|||
var eable = m_IEntity.Map.GetMobilesInRange(m_IEntity.Location, 2);
|
||||
var mobiles = new List<Mobile>();
|
||||
mobiles.AddRange(eable);
|
||||
eable.Free();
|
||||
|
||||
for (var k = 0; k < mobiles.Count; k++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,8 +167,6 @@ namespace Server.Ethics
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (!found)
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -273,13 +273,10 @@ namespace Server.Factions
|
|||
|
||||
if (type.IsInstanceOfType(obj))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -292,13 +289,10 @@ namespace Server.Factions
|
|||
{
|
||||
if (types[i].IsInstanceOfType(obj))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,12 +83,9 @@ namespace Server.Factions
|
|||
{
|
||||
if (type.IsInstanceOfType(item))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
foreach (var mob in targets)
|
||||
{
|
||||
var damage = mob.Hits * 6 / 10;
|
||||
|
|
|
|||
|
|
@ -312,13 +312,10 @@ namespace Server.Engines.Harvest
|
|||
{
|
||||
if (i.StackWith(m, i, false))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
item.MoveToWorld(m.Location, map);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ namespace Server.Commands
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
@ -44,8 +42,6 @@ namespace Server.Commands
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +49,6 @@ namespace Server.Commands
|
|||
{
|
||||
var eable = Map.Felucca.GetItemsInBounds<T>(new Rectangle2D(x, y, 1, 1));
|
||||
var t = eable.FirstOrDefault(item => item.GetType() == srcItem.GetType());
|
||||
eable.Free();
|
||||
if (t != null)
|
||||
{
|
||||
srcItem.Delete();
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Server.Movement
|
|||
|
||||
private readonly List<Item>[] _pools = { new(), new(), new(), new() };
|
||||
|
||||
private readonly HashSet<Sector> _sectors = new();
|
||||
private readonly HashSet<Map.Sector> _sectors = new();
|
||||
|
||||
private MovementImpl()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -162,8 +162,6 @@ namespace Server.Engines.Spawners
|
|||
queue.Dequeue().Delete();
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
try
|
||||
{
|
||||
var spawner = type.CreateInstance<ISpawner>(json, options);
|
||||
|
|
|
|||
|
|
@ -380,8 +380,6 @@ public partial class CharacterStatue : Mobile, IRewardItem
|
|||
CharacterStatuePackets.CreateStatueAnimation(animPacket, Serial, 1, m_Animation, m_Frames);
|
||||
state.Send(animPacket);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private class DemolishEntry : ContextMenuEntry
|
||||
|
|
|
|||
|
|
@ -60,8 +60,6 @@ namespace Server.Engines.Events
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (spawncount > pumpkins)
|
||||
{
|
||||
new HalloweenPumpkin().MoveToWorld(Utility.RandomPointIn(rect, map), map);
|
||||
|
|
|
|||
|
|
@ -270,7 +270,6 @@ namespace Server.Items
|
|||
{
|
||||
var eable = map.GetItemsInRange<SHTeleporter>(p, 0);
|
||||
var teleporter = eable.FirstOrDefault(item => item.Z == p.Z);
|
||||
eable.Free();
|
||||
return teleporter;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,12 +136,9 @@ public partial class MarkContainer : LockableContainer
|
|||
{
|
||||
if (item.Z == p.Z)
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@ public partial class Firebomb : Item
|
|||
targets.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (targets.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ public partial class MorphItem : Item
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
ItemID = found ? _activeItemId : _inactiveItemId;
|
||||
|
||||
Visible = ItemID != 0x1;
|
||||
|
|
|
|||
|
|
@ -60,8 +60,6 @@ public partial class OilFlask : Item
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (!didStack)
|
||||
{
|
||||
emptyFlask.MoveToWorld(Location, Map);
|
||||
|
|
|
|||
|
|
@ -143,8 +143,6 @@ public partial class Campfire : Item
|
|||
pm.SendLocalizedMessage(500620); // You feel it would take a few moments to secure your camp.
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private void ClearEntries()
|
||||
|
|
|
|||
|
|
@ -167,8 +167,6 @@ public abstract partial class BaseExplosionPotion : BasePotion
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
var min = Scale(from, MinDamage);
|
||||
var max = Scale(from, MaxDamage);
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,6 @@ public partial class FireHorn : Item
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (targets.Count > 0)
|
||||
{
|
||||
var prov = from.Skills.Provocation.Fixed;
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (didEffect)
|
||||
{
|
||||
attacker.FixedEffect(0x3728, 10, 15);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Server.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Collections;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
|
|
@ -27,29 +27,25 @@ namespace Server.Items
|
|||
return;
|
||||
}
|
||||
|
||||
List<Mobile> targets = new List<Mobile>();
|
||||
IPooledEnumerable eable = defender.GetMobilesInRange(5);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
using var list = PooledRefList<Mobile>.Create();
|
||||
foreach (Mobile m in defender.GetMobilesInRange(5))
|
||||
{
|
||||
if (m != defender && m != attacker && SpellHelper.ValidIndirectTarget(attacker, m) && m?.Deleted == false &&
|
||||
m.Map == attacker.Map && m.Alive && attacker.CanSee(m) && attacker.CanBeHarmful(m) &&
|
||||
attacker.InRange(m, weapon.MaxRange) && attacker.InLOS(m))
|
||||
{
|
||||
targets.Add(m);
|
||||
list.Add(m);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
defender.BoltEffect(0);
|
||||
|
||||
var mobilesLeft = Math.Min(targets.Count, 2);
|
||||
while (mobilesLeft-- > 0)
|
||||
{
|
||||
var index = Utility.Random(targets.Count);
|
||||
var m = targets[index];
|
||||
targets.RemoveAt(index);
|
||||
var count = Math.Min(list.Count, 2);
|
||||
list.Shuffle();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var m = list[i];
|
||||
m.BoltEffect(0);
|
||||
AOS.Damage(m, attacker, Utility.RandomMinMax(29, 40), 0, 0, 0, 0, 100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,7 @@ public class MysticArc : WeaponAbility
|
|||
}
|
||||
|
||||
using var queue = PooledRefQueue<Mobile>.Create();
|
||||
IPooledEnumerable eable = attacker.GetMobilesInRange(weapon.MaxRange);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
foreach (Mobile m in attacker.GetMobilesInRange(weapon.MaxRange))
|
||||
{
|
||||
if (m == defender)
|
||||
{
|
||||
|
|
@ -45,8 +43,6 @@ public class MysticArc : WeaponAbility
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (queue.Count > 0)
|
||||
{
|
||||
_target = queue.PeekRandom();
|
||||
|
|
|
|||
|
|
@ -51,8 +51,6 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (queue.Count <= 0)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1729,8 +1729,6 @@ public abstract partial class BaseWeapon : Item, IWeapon, IFactionItem, ICraftab
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return inPack switch
|
||||
{
|
||||
>= 5 => 100,
|
||||
|
|
@ -1765,8 +1763,6 @@ public abstract partial class BaseWeapon : Item, IWeapon, IFactionItem, ICraftab
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
PlaySwingAnimation(attacker);
|
||||
|
|
@ -3587,8 +3583,6 @@ public abstract partial class BaseWeapon : Item, IWeapon, IFactionItem, ICraftab
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (queue.Count == 0)
|
||||
{
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2193,8 +2193,6 @@ public abstract class BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (destroyables > 0)
|
||||
{
|
||||
Effects.PlaySound(new Point3D(x, y, m_Mobile.Z), m_Mobile.Map, 0x3B3);
|
||||
|
|
@ -2764,8 +2762,6 @@ public abstract class BaseAI
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
m_Mobile.FocusMob = newFocusMob ?? enemySummonMob;
|
||||
return m_Mobile.FocusMob != null;
|
||||
}
|
||||
|
|
@ -2845,8 +2841,6 @@ public abstract class BaseAI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public virtual void Deactivate()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public abstract class AreaEffectMonsterAbility : MonsterAbility
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3649,8 +3649,6 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (toRummage == null)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -3813,7 +3811,6 @@ namespace Server.Mobiles
|
|||
queue.Enqueue(pet);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
|
|
@ -5360,7 +5357,6 @@ namespace Server.Mobiles
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,8 +84,6 @@ public partial class HordeMinionFamiliar : BaseFamiliar
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
var pickedUp = 3;
|
||||
|
||||
while (pickedUp > 0 && queue.Count > 0)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ public partial class ShadowWispFamiliar : BaseFamiliar
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -305,8 +305,6 @@ namespace Server.Mobiles
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,8 +124,6 @@ namespace Server.Mobiles
|
|||
orc.MoveToWorld(map.GetRandomNearbyLocation(target.Location), map);
|
||||
orc.Combatant = target;
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,8 +139,6 @@ namespace Server.Mobiles
|
|||
m.FixedParticles(0x376A, 9, 32, 5030, EffectLayer.Waist);
|
||||
m.PlaySound(0x202);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
base.OnThink();
|
||||
|
|
|
|||
|
|
@ -90,7 +90,6 @@ namespace Server.Mobiles
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (queue.Count == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ namespace Server.Mobiles
|
|||
var eable = Map.GetItemsInRange<StainedOoze>(p, 0);
|
||||
using var enumerator = eable.GetEnumerator();
|
||||
bool atLocation = enumerator.MoveNext();
|
||||
eable.Free();
|
||||
if (!atLocation)
|
||||
{
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ namespace Server.Mobiles
|
|||
var eable = Map.GetItemsInRange<StainedOoze>(p, 0);
|
||||
using var enumerator = eable.GetEnumerator();
|
||||
bool atLocation = enumerator.MoveNext();
|
||||
eable.Free();
|
||||
if (!atLocation)
|
||||
{
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -246,8 +246,6 @@ public partial class Meraktus : BaseChampion
|
|||
m.Animate(20, 7, 1, true, false, 0); // take hit
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private void MigrateFrom(V0Content content)
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ namespace Server.Mobiles
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
var amount = queue.Count - 6;
|
||||
if (amount > 0)
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ namespace Server.Mobiles
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
var amount = queue.Count - 6;
|
||||
if (amount > 0)
|
||||
|
|
|
|||
|
|
@ -179,8 +179,6 @@ namespace Server.Mobiles
|
|||
); // * The plague beast attempts to absorb the remains, but cannot! *
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
private void IncreaseHits(int hp)
|
||||
|
|
|
|||
|
|
@ -100,8 +100,6 @@ namespace Server.Mobiles
|
|||
Hits += bogling.Hits / 2;
|
||||
bogling.Delete();
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public override void OnGotMeleeAttack(Mobile attacker, int damage)
|
||||
|
|
|
|||
|
|
@ -141,8 +141,6 @@ namespace Server.Mobiles
|
|||
m.FixedParticles(0x36BD, 1, 10, 0x1F78, 0xA6, 0, (EffectLayer)255);
|
||||
m.ApplyPoison(this, Poison.Lethal);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -862,12 +862,9 @@ namespace Server.Mobiles
|
|||
{
|
||||
if (m.Z >= location.Z && m.Z < location.Z + 16 && (!m.Hidden || m.AccessLevel == AccessLevel.Player))
|
||||
{
|
||||
mobiles.Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mobiles.Free();
|
||||
}
|
||||
|
||||
var bi = item.GetBounce();
|
||||
|
|
|
|||
|
|
@ -148,14 +148,11 @@ public partial class Barracoon : BaseChampion
|
|||
rats++;
|
||||
if (rats >= 16)
|
||||
{
|
||||
eable.Free();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
PlaySound(0x3D);
|
||||
|
||||
rats = Utility.RandomMinMax(3, 6);
|
||||
|
|
|
|||
|
|
@ -539,7 +539,6 @@ public partial class Harrower : BaseCreature
|
|||
break;
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (toTeleport == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -154,8 +154,6 @@ public partial class HarrowerTentacles : BaseCreature
|
|||
|
||||
m.Damage(drain, m_Owner);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,8 +132,6 @@ public partial class Rikktor : BaseChampion
|
|||
m.Animate(20, 7, 1, true, false, 0); // take hit
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public override int GetAngerSound() => Utility.Random(0x2CE, 2);
|
||||
|
|
|
|||
|
|
@ -1277,8 +1277,6 @@ namespace Server.Mobiles
|
|||
m.OpenBackpack(from);
|
||||
}
|
||||
}
|
||||
|
||||
mobiles.Free();
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
|
|
|||
|
|
@ -1526,8 +1526,6 @@ namespace Server.Multis
|
|||
newComponents.Tiles[x][y].Length == 0 || Contains(item);
|
||||
}
|
||||
);
|
||||
|
||||
eable.Free();
|
||||
return canFit;
|
||||
}
|
||||
|
||||
|
|
@ -1905,7 +1903,7 @@ namespace Server.Multis
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Dispose()
|
||||
{
|
||||
_entities?.Free();
|
||||
_entities?.Dispose();
|
||||
_enumerator?.Dispose();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,13 +237,10 @@ namespace Server.Items
|
|||
{
|
||||
if (obj == this)
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -770,8 +770,6 @@ namespace Server.Multis
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public List<Mobile> AvailableVendorsFor(Mobile m) =>
|
||||
|
|
@ -1157,8 +1155,6 @@ namespace Server.Multis
|
|||
var eable = Map.GetItemsInBounds(rect);
|
||||
var list = eable.Where(item => item.Movable && IsInside(item)).ToList();
|
||||
|
||||
eable.Free();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -3661,7 +3657,6 @@ namespace Server.Multis
|
|||
map.GetItemsInBounds<Guildstone>(new Rectangle2D(X + mcl.Min.X, Y + mcl.Min.Y, mcl.Width, mcl.Height));
|
||||
|
||||
var item = eable.FirstOrDefault(Contains);
|
||||
eable.Free();
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ namespace Server.Multis
|
|||
}
|
||||
}
|
||||
|
||||
var _sectors = new List<Sector>();
|
||||
var _sectors = new List<Map.Sector>();
|
||||
var _houses = new List<BaseHouse>();
|
||||
|
||||
for (var i = 0; i < yard.Count; i++)
|
||||
|
|
|
|||
|
|
@ -156,8 +156,6 @@ public class GuardedRegion : BaseRegion
|
|||
var eable = focus.GetMobilesInRange<BaseGuard>(8);
|
||||
var useGuard = eable.FirstOrDefault(m => m.Focus == null);
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (useGuard == null)
|
||||
{
|
||||
m_GuardParams[0] = focus;
|
||||
|
|
@ -338,8 +336,6 @@ public class GuardedRegion : BaseRegion
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
public bool IsGuardCandidate(Mobile m) =>
|
||||
|
|
|
|||
|
|
@ -81,8 +81,6 @@ namespace Server.SkillHandlers
|
|||
}
|
||||
}
|
||||
|
||||
inRange.Free();
|
||||
|
||||
if (Faction.Find(src) != null)
|
||||
{
|
||||
var itemsInRange = src.Map.GetItemsInRange<BaseFactionTrap>(p, range);
|
||||
|
|
@ -103,8 +101,6 @@ namespace Server.SkillHandlers
|
|||
foundAnyone = true;
|
||||
}
|
||||
}
|
||||
|
||||
itemsInRange.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@ namespace Server.SkillHandlers
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
ok = !badCombat && m.CheckSkill(SkillName.Hiding, 0.0 - bonus, 100.0 - bonus);
|
||||
|
|
|
|||
|
|
@ -77,8 +77,6 @@ public static class Snooping
|
|||
ns.Mobile.SendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,6 @@ namespace Server.SkillHandlers
|
|||
break;
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
var min = 1 + (int)(Caster.Skills.SpiritSpeak.Value * 0.25);
|
||||
var max = min + 4;
|
||||
|
|
|
|||
|
|
@ -225,7 +225,6 @@ namespace Server.SkillHandlers
|
|||
list.Add(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
if (list.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ namespace Server.Spells.Chivalry
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
}
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ namespace Server.Spells.Chivalry
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Caster.PlaySound(0x244);
|
||||
Caster.FixedParticles(0x3709, 1, 30, 9965, 5, 7, EffectLayer.Waist);
|
||||
Caster.FixedParticles(0x376A, 1, 30, 9502, 5, 3, EffectLayer.Waist);
|
||||
|
|
|
|||
|
|
@ -262,8 +262,6 @@ namespace Server.Spells.Fifth
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var m = queue.Dequeue();
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ namespace Server.Spells.Fourth
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Effects.PlaySound(loc, Caster.Map, 0x299);
|
||||
|
||||
var cured = 0;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ namespace Server.Spells.Fourth
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
var party = Party.Get(Caster);
|
||||
|
|
|
|||
|
|
@ -47,9 +47,7 @@ namespace Server.Spells.Mysticism
|
|||
var casterParty = Party.Get(Caster);
|
||||
if (casterParty != null)
|
||||
{
|
||||
IPooledEnumerable eable = Caster.Map.GetMobilesInRange(m.Location, 2);
|
||||
|
||||
foreach (Mobile mob in eable)
|
||||
foreach (Mobile mob in Caster.Map.GetMobilesInRange(m.Location, 2))
|
||||
{
|
||||
if (mob == m)
|
||||
{
|
||||
|
|
@ -65,8 +63,6 @@ namespace Server.Spells.Mysticism
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
var primarySkill = GetBaseSkill(Caster);
|
||||
|
|
|
|||
|
|
@ -111,8 +111,6 @@ namespace Server.Spells.Necromancy
|
|||
pool.Enqueue(targ);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (pool.Count > 0)
|
||||
{
|
||||
var targ = pool.Dequeue();
|
||||
|
|
|
|||
|
|
@ -84,8 +84,6 @@ namespace Server.Spells.Necromancy
|
|||
pool.Enqueue(targ);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
Effects.PlaySound(Caster.Location, map, 0x1FB);
|
||||
Effects.PlaySound(Caster.Location, map, 0x10B);
|
||||
Effects.SendLocationParticles(
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ namespace Server.Spells.Seventh
|
|||
pool.Enqueue(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (pool.Count > 0)
|
||||
{
|
||||
double damage = Core.AOS
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@ namespace Server.Spells.Seventh
|
|||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
queue.Dequeue().Delete();
|
||||
|
|
|
|||
|
|
@ -60,8 +60,6 @@ namespace Server.Spells.Seventh
|
|||
queue.Enqueue(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
double damage = Core.AOS
|
||||
? GetNewAosDamage(51, 1, 5, playerVsPlayer)
|
||||
: Utility.Random(27, 22);
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ namespace Server.Spells.Sixth
|
|||
|
||||
HarmfulSpell(m);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,8 +53,6 @@ namespace Server.Spells.Sixth
|
|||
m.FixedParticles(0x375A, 9, 20, 5049, EffectLayer.Head);
|
||||
m.PlaySound(0x1FD);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,13 +103,10 @@ namespace Server.Spells.Spellweaving
|
|||
{
|
||||
if (item.Z + item.ItemData.CalcHeight == location.Z && IsValidTile(item.ItemID))
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -125,12 +122,9 @@ namespace Server.Spells.Spellweaving
|
|||
if (m != Caster && m is PlayerMobile && Caster.CanBeBeneficial(m, false) &&
|
||||
Math.Abs(spellWeaving - m.Skills.Spellweaving.Value) <= 20)
|
||||
{
|
||||
eable.Free();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -150,8 +144,6 @@ namespace Server.Spells.Spellweaving
|
|||
pool.Enqueue(m);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ namespace Server.Spells.Spellweaving
|
|||
new BuffInfo(BuffIcon.EssenceOfWind, 1075802, duration, m, $"{fcMalus}\t{ssiMalus}")
|
||||
);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ namespace Server.Spells.Spellweaving
|
|||
new BuffInfo(BuffIcon.Thunderstorm, 1075800, duration, m, GetCastRecoveryMalus(m))
|
||||
);
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
|
|
@ -106,8 +106,6 @@ namespace Server.Spells.Third
|
|||
item.OnMoveOver(m);
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue