fix: Eliminates List allocations in various places. (#2158)

This commit is contained in:
Kamron Batman 2025-11-16 18:33:53 -08:00 committed by GitHub
parent 6f64cddd0b
commit 4836bff5eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 263 additions and 200 deletions

View file

@ -430,8 +430,8 @@ public partial class Container : Item
public virtual bool TryDropItems(Mobile from, bool sendFullMessage, params ReadOnlySpan<Item> droppedItems)
{
var dropItems = new List<Item>();
var stackItems = new List<ItemStackEntry>();
using var dropItems = PooledRefQueue<Item>.Create();
using var stackItems = PooledRefQueue<ItemStackEntry>.Create();
var extraItems = 0;
var extraWeight = 0;
@ -451,7 +451,7 @@ public partial class Container : Item
if (item is not Container && CheckHold(from, dropped, false, false, 0, extraWeight) &&
item.CanStackWith(dropped))
{
stackItems.Add(new ItemStackEntry(item, dropped));
stackItems.Enqueue(new ItemStackEntry(item, dropped));
extraWeight += (int)Math.Ceiling(item.Weight * (item.Amount + dropped.Amount)) -
item.PileWeight; // extra weight delta, do not need TotalWeight as we do not have hybrid stackable container types
stacked = true;
@ -461,7 +461,7 @@ public partial class Container : Item
if (!stacked && CheckHold(from, dropped, false, true, extraItems, extraWeight))
{
dropItems.Add(dropped);
dropItems.Enqueue(dropped);
extraItems++;
extraWeight += dropped.TotalWeight + dropped.PileWeight;
}
@ -469,14 +469,15 @@ public partial class Container : Item
if (dropItems.Count + stackItems.Count == droppedItems.Length) // All good
{
for (var i = 0; i < dropItems.Count; i++)
while (dropItems.Count > 0)
{
DropItem(dropItems[i]);
DropItem(dropItems.Dequeue());
}
for (var i = 0; i < stackItems.Count; i++)
while (stackItems.Count > 0)
{
stackItems[i].m_StackItem.StackWith(from, stackItems[i].m_DropItem, false);
var stackItem = stackItems.Dequeue();
stackItem.m_StackItem.StackWith(from, stackItem.m_DropItem, false);
}
return true;

View file

@ -547,10 +547,29 @@ public class Region : IComparable<Region>, IValueLinkListNode<Region>
public virtual bool AcceptsSpawnsFrom(Region region) =>
AllowSpawn() && (region == this || Parent?.AcceptsSpawnsFrom(region) == true);
public PooledRefList<Mobile> GetPlayersPooled()
{
var list = PooledRefList<Mobile>.Create();
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
foreach (var ns in sector.Clients)
{
var player = ns.Mobile;
if (player?.Deleted == false && player.Region.IsPartOf(this))
{
list.Add(ns.Mobile);
}
}
}
return list;
}
public List<Mobile> GetPlayers()
{
var list = new List<Mobile>();
List<Mobile> list = [];
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
@ -609,6 +628,25 @@ public class Region : IComparable<Region>, IValueLinkListNode<Region>
return list;
}
public PooledRefList<Mobile> GetMobilesPooled()
{
var list = PooledRefList<Mobile>.Create();
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
foreach (var mobile in sector.Mobiles)
{
if (mobile.Region.IsPartOf(this))
{
list.Add(mobile);
}
}
}
return list;
}
public int GetMobileCount()
{
var count = 0;
@ -649,6 +687,26 @@ public class Region : IComparable<Region>, IValueLinkListNode<Region>
return list;
}
public PooledRefList<Item> GetItemsPooled()
{
var list = PooledRefList<Item>.Create();
for (var i = 0; i < Sectors?.Length; i++)
{
var sector = Sectors[i];
foreach (var item in sector.Items)
{
if (Find(item.Location, item.Map).IsPartOf(this))
{
list.Add(item);
}
}
}
return list;
}
public int GetItemCount()
{
var count = 0;

View file

@ -16,7 +16,6 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Text;
using Server.Buffers;
using Server.Text;

View file

@ -850,40 +850,6 @@ public partial class Account : IAccount, IComparable<Account>
return true;
}
/// <summary>
/// Deserializes a list of string values from an xml element. Null values are not added to the list.
/// </summary>
/// <param name="node">The XmlElement from which to deserialize.</param>
/// <returns>String list. Value will never be null.</returns>
private static string[] LoadAccessCheck(XmlElement node)
{
string[] stringList;
var accessCheck = node["accessCheck"];
if (accessCheck != null)
{
var list = new List<string>();
foreach (XmlElement ip in accessCheck.GetElementsByTagName("ip"))
{
var text = Utility.GetText(ip, null);
if (text != null)
{
list.Add(text);
}
}
stringList = list.ToArray();
}
else
{
stringList = [];
}
return stringList;
}
/// <summary>
/// Deserializes a list of IPAddress values from an xml element.
/// </summary>

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Server.Collections;
using Server.Gumps;
using Server.Items;
using Server.Multis;
@ -112,7 +113,7 @@ namespace Server.Commands.Generic
if (okay)
{
var foundations = new List<HouseFoundation>();
using var foundations = PooledRefQueue<HouseFoundation>.Create();
flushToLog = list.Count > 20;
for (var i = 0; i < list.Count; ++i)
@ -127,7 +128,7 @@ namespace Server.Commands.Generic
if (!foundations.Contains(house))
{
foundations.Add(house);
foundations.Enqueue(house);
}
break;
@ -146,9 +147,9 @@ namespace Server.Commands.Generic
}
}
foreach (var house in foundations)
while (foundations.Count > 0)
{
house.Delta(ItemDelta.Update);
foundations.Dequeue().Delta(ItemDelta.Update);
}
}
else

View file

@ -33,8 +33,10 @@ namespace Server.Commands.Generic
if (mobiles)
{
foreach (var mob in reg.GetMobiles())
using var mobileList = reg.GetMobilesPooled();
for (var i = 0; i < mobileList.Count; i++)
{
var mob = mobileList[i];
if (BaseCommand.IsAccessible(from, mob) && ext.IsValid(mob))
{
list.Add(mob);
@ -44,7 +46,8 @@ namespace Server.Commands.Generic
if (items)
{
foreach (var item in reg.GetItems())
using var itemList = reg.GetItemsPooled();
foreach (var item in itemList)
{
if (BaseCommand.IsAccessible(from, item) && ext.IsValid(item))
{

View file

@ -1364,6 +1364,8 @@ public class ChampionSpawnRegion : BaseRegion
global = Math.Max(global, 1 + Spawn.Level); //This is a guesstimate. TODO: Verify & get exact values // OSI testing: at 2 red skulls, light = 0x3 ; 1 red = 0x3.; 3 = 8; 9 = 0xD 8 = 0xD 12 = 0x12 10 = 0xD
}
private static readonly HashSet<IPAddress> _addresses = [];
public override void OnEnter(Mobile m)
{
if (!m.Player || m.AccessLevel != AccessLevel.Player || Spawn.Active)
@ -1371,8 +1373,6 @@ public class ChampionSpawnRegion : BaseRegion
return;
}
Region parent = Parent ?? this;
if (Spawn.ReadyToActivate)
{
Spawn.Start();
@ -1384,27 +1384,29 @@ public class ChampionSpawnRegion : BaseRegion
return;
}
List<Mobile> players = parent.GetPlayers();
List<IPAddress> addresses = new List<IPAddress>();
using var players = (Parent ?? this).GetPlayersPooled();
for (var i = 0; i < players.Count; i++)
{
if (players[i].AccessLevel == AccessLevel.Player && players[i].NetState != null &&
!addresses.Contains(players[i].NetState.Address) && !((PlayerMobile)players[i]).Young)
var player = players[i];
if (player.AccessLevel == AccessLevel.Player && player.NetState != null && !((PlayerMobile)player).Young)
{
addresses.Add(players[i].NetState.Address);
_addresses.Add(player.NetState.Address);
}
}
if (addresses.Count >= 15)
if (_addresses.Count >= 15)
{
foreach (Mobile player in players)
for (var i = 0; i < players.Count; i++)
{
player.SendMessage(0x20, Spawn.BroadcastMessage);
players[i].SendMessage(0x20, Spawn.BroadcastMessage);
}
Spawn.ActivatedByProximity = true;
Spawn.BeginRestart(TimeSpan.FromMinutes(5.0));
}
_addresses.Clear();
}
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)

View file

@ -14,7 +14,7 @@
*************************************************************************/
using System;
using System.Collections.Generic;
using Server.Collections;
using Server.Logging;
namespace Server.Engines.CannedEvil;
@ -67,18 +67,18 @@ public static class ChampionGenerator
*/
//We assume that all champion spawns are generated here.
List<ChampionSpawn> spawns = [];
using var spawns = PooledRefQueue<IEntity>.Create();
foreach (Item item in World.Items.Values)
{
if (item is ChampionSpawn spawn)
{
spawns.Add(spawn);
spawns.Enqueue(spawn);
}
}
for (int i = spawns.Count - 1; i >= 0; i--)
while (spawns.Count > 0)
{
spawns[i].Delete();
spawns.Dequeue().Delete();
}
Process(DungeonLocations);

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using Server.Collections;
using Server.Items;
using Server.Mobiles;
@ -272,18 +272,23 @@ namespace Server.Engines.Doom
FacialHairHue = 0x482
};
var items = new List<Item>(dealer.Items);
using var toDelete = PooledRefQueue<Item>.Create();
for (var i = 0; i < items.Count; ++i)
for (var i = 0; i < dealer.Items.Count; ++i)
{
var item = items[i];
var item = dealer.Items[i];
if (item.Layer is not Layer.ShopBuy and not Layer.ShopResale and not Layer.ShopSell)
{
item.Delete();
toDelete.Enqueue(item);
}
}
while (toDelete.Count > 0)
{
toDelete.Dequeue().Delete();
}
dealer.AddItem(new FloppyHat(1));
dealer.AddItem(new Robe(1));
dealer.AddItem(new LanternOfSouls());

View file

@ -667,12 +667,13 @@ public partial class LeverPuzzleController : Item
protected override void OnTick()
{
ticks++;
var mobiles = m_Controller._lampRoom.GetMobiles();
using var mobiles = m_Controller._lampRoom.GetMobilesPooled();
if (ticks >= 71 || m_Controller._lampRoom.GetPlayerCount() == 0)
{
foreach (var mobile in mobiles)
for (var i = 0; i < mobiles.Count; i++)
{
var mobile = mobiles[i];
if (mobile?.Deleted == false && !mobile.IsDeadBondedPet)
{
mobile.Kill();
@ -689,33 +690,36 @@ public partial class LeverPuzzleController : Item
level++;
}
foreach (var mobile in mobiles)
for (var i = 0; i < mobiles.Count; i++)
{
if (IsValidDamagable(mobile))
var mobile = mobiles[i];
if (!IsValidDamagable(mobile))
{
if (ticks % 2 == 0 && level == 5)
continue;
}
if (ticks % 2 == 0 && level == 5)
{
if (mobile.Player)
{
if (mobile.Player)
mobile.Say(1062092);
if (AniSafe(mobile))
{
mobile.Say(1062092);
if (AniSafe(mobile))
{
mobile.Animate(32, 5, 1, true, false, 0);
}
mobile.Animate(32, 5, 1, true, false, 0);
}
DoDamage(mobile, 15, 20, true);
}
if (Utility.Random((int)(level & ~0xfffffffc), 3) == 3)
{
mobile.ApplyPoison(mobile, PA2[level]);
}
DoDamage(mobile, 15, 20, true);
}
if (ticks % 12 == 0 && level > 0 && mobile.Player)
{
mobile.SendLocalizedMessage(PA[level][0], null, PA[level][1]);
}
if (Utility.Random((int)(level & ~0xfffffffc), 3) == 3)
{
mobile.ApplyPoison(mobile, PA2[level]);
}
if (ticks % 12 == 0 && level > 0 && mobile.Player)
{
mobile.SendLocalizedMessage(PA[level][0], null, PA[level][1]);
}
}

View file

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using Server.Collections;
using Server.Factions.AI;
using Server.Items;
using Server.Mobiles;
@ -692,41 +692,42 @@ namespace Server.Factions
var dexMod = GetStatMod(m_Guard, StatType.Dex);
var intMod = GetStatMod(m_Guard, StatType.Int);
var types = new List<Type>();
using var spellTypes = PooledRefQueue<Type>.Create();
if (strMod <= 0)
{
types.Add(typeof(StrengthSpell));
spellTypes.Enqueue(typeof(StrengthSpell));
}
if (dexMod <= 0 && IsAllowed(GuardAI.Melee))
{
types.Add(typeof(AgilitySpell));
spellTypes.Enqueue(typeof(AgilitySpell));
}
if (intMod <= 0 && IsAllowed(GuardAI.Magic))
{
types.Add(typeof(CunningSpell));
spellTypes.Enqueue(typeof(CunningSpell));
}
if (IsAllowed(GuardAI.Bless))
{
if (types.Count > 1)
if (spellTypes.Count > 1)
{
spell = new BlessSpell(m_Guard);
}
else if (types.Count == 1)
else if (spellTypes.Count == 1)
{
spell = types[0].CreateInstance<Spell>(m_Guard, null);
spell = spellTypes.Dequeue().CreateInstance<Spell>(m_Guard, null);
}
}
else if (types.Count > 0)
else if (spellTypes.Count > 0)
{
if (types[0] == typeof(StrengthSpell))
var spellType = spellTypes.Dequeue();
if (spellType == typeof(StrengthSpell))
{
UseItemByType(typeof(BaseStrengthPotion));
}
else if (types[0] == typeof(AgilitySpell))
else if (spellType == typeof(AgilitySpell))
{
UseItemByType(typeof(BaseAgilityPotion));
}
@ -746,30 +747,30 @@ namespace Server.Factions
var dexMod = GetStatMod(combatant, StatType.Dex);
var intMod = GetStatMod(combatant, StatType.Int);
var types = new List<Type>();
using var spellTypes = PooledRefQueue<Type>.Create();
if (strMod >= 0)
{
types.Add(typeof(WeakenSpell));
spellTypes.Enqueue(typeof(WeakenSpell));
}
if (dexMod >= 0 && IsAllowed(GuardAI.Melee))
{
types.Add(typeof(ClumsySpell));
spellTypes.Enqueue(typeof(ClumsySpell));
}
if (intMod >= 0 && IsAllowed(GuardAI.Magic))
{
types.Add(typeof(FeeblemindSpell));
spellTypes.Enqueue(typeof(FeeblemindSpell));
}
if (types.Count > 1)
if (spellTypes.Count > 1)
{
spell = new CurseSpell(m_Guard);
}
else if (types.Count == 1)
else if (spellTypes.Count == 1)
{
spell = types[0].CreateInstance<Spell>(m_Guard, null);
spell = spellTypes.Dequeue().CreateInstance<Spell>(m_Guard, null);
}
}
}

View file

@ -118,8 +118,7 @@ public abstract partial class DoneQuestCollector : BaseCreature, IRaceChanger
}
else
{
var conversation = new List<TextDefinition>();
conversation.AddRange(Incomplete);
List<TextDefinition> conversation = [..Incomplete];
var context = MLQuestSystem.GetContext(pm);

View file

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using Server.Collections;
using Server.Gumps;
using Server.Items;
using Server.Logging;
@ -46,7 +46,7 @@ namespace Server.Engines.MLQuests.Objectives
return;
}
var delivery = new List<Item>();
using var delivery = PooledRefQueue<Item>.Create();
for (var i = 0; i < Amount; ++i)
{
@ -54,7 +54,7 @@ namespace Server.Engines.MLQuests.Objectives
if (item != null)
{
delivery.Add(item);
delivery.Enqueue(item);
if (item.Stackable && Amount > 1)
{
@ -64,9 +64,9 @@ namespace Server.Engines.MLQuests.Objectives
}
}
foreach (var item in delivery)
while (delivery.Count > 0)
{
pack.DropItem(item); // Confirmed: on OSI items are added even if your pack is full
pack.DropItem(delivery.Dequeue()); // Confirmed: on OSI items are added even if your pack is full
}
}

View file

@ -870,7 +870,7 @@ namespace Server.Gumps
}
var items = house.GetItems();
var mobiles = house.GetMobiles();
using var mobiles = house.GetMobilesPooled();
newHouse.MoveToWorld(
new Point3D(
@ -1216,7 +1216,7 @@ namespace Server.Gumps
);
var r = m_House.Region;
var list = r.GetMobiles();
using var list = r.GetMobilesPooled();
for (var i = 0; i < list.Count; ++i)
{
@ -1258,7 +1258,7 @@ namespace Server.Gumps
}
var r = m_House.Region;
var list = r.GetMobiles();
using var list = r.GetMobilesPooled();
for (var i = 0; i < list.Count; ++i)
{

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
@ -141,11 +140,14 @@ namespace Server.Items
{
get
{
var lines = new List<string>();
foreach (var bpi in Pages)
using var lines = PooledRefQueue<string>.Create(256);
for (var i = 0; i < Pages.Length; i++)
{
lines.AddRange(bpi.Lines);
var bpi = Pages[i];
for (var j = 0; j < bpi.Lines.Length; j++)
{
lines.Enqueue(bpi.Lines[j]);
}
}
return lines.ToArray();

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.Targeting;
namespace Server.Items
@ -22,7 +22,7 @@ namespace Server.Items
PostedHue = Poster.Hue;
Lines = lines;
var list = new List<BulletinEquip>();
using var list = PooledRefQueue<BulletinEquip>.Create(poster.Items.Count);
for (var i = 0; i < poster.Items.Count; ++i)
{
@ -30,7 +30,7 @@ namespace Server.Items
if (item.Layer >= Layer.OneHanded && item.Layer <= Layer.Mount)
{
list.Add(new BulletinEquip(item.ItemID, item.Hue));
list.Enqueue(new BulletinEquip(item.ItemID, item.Hue));
}
}

View file

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.Multis;
namespace Server.Items;
@ -102,15 +102,15 @@ public partial class StrongBox : BaseContainer, IChoppable
public Container ConvertToStandardContainer()
{
var metalBox = new MetalBox();
var subItems = new List<Item>(Items);
using var subItems = PooledRefList<Item>.Create(Items.Count);
subItems.AddRange(Items);
foreach (var subItem in subItems)
for (var i = 0; i < subItems.Count; i++)
{
metalBox.AddItem(subItem);
metalBox.AddItem(subItems[i]);
}
Delete();
return metalBox;
}
}

View file

@ -824,25 +824,28 @@ public partial class Corpse : Container, ICarvable
}
var pack = from.Backpack;
using var items = PooledRefList<Item>.Create(128);
if (RestoreEquip != null && pack != null)
{
var packItems = new List<Item>(pack.Items); // Only items in the top-level pack are re-equipped
items.AddRange(pack.Items);
for (var i = 0; i < packItems.Count; i++)
// Only items in the top-level pack are re-equipped
for (var i = 0; i < items.Count; i++)
{
var packItem = packItems[i];
var packItem = items[i];
if (RestoreEquip.Contains(packItem) && packItem.Movable)
{
from.EquipItem(packItem);
}
}
items.Clear();
}
var items = new List<Item>(Items);
var didntFit = false;
items.AddRange(Items);
for (var i = 0; !didntFit && i < items.Count; ++i)
{

View file

@ -1,4 +1,3 @@
using System;
using ModernUO.Serialization;
namespace Server.Items;

View file

@ -986,67 +986,71 @@ namespace Server.Mobiles
from.TargetLocked = false;
}
public static void EquipMacro(Mobile m, List<Serial> list)
public static void EquipMacro(Mobile m, ref PooledRefList<Serial> list)
{
if (m is PlayerMobile { Alive: true } pm && pm.Backpack != null)
if (m is not PlayerMobile { Alive: true } pm || pm.Backpack == null)
{
var pack = pm.Backpack;
return;
}
foreach (var serial in list)
var pack = pm.Backpack;
foreach (var serial in list)
{
Item item = null;
foreach (var i in pack.Items)
{
Item item = null;
foreach (var i in pack.Items)
if (i.Serial == serial)
{
if (i.Serial == serial)
{
item = i;
break;
}
item = i;
break;
}
}
if (item == null)
if (item == null)
{
continue;
}
var toMove = pm.FindItemOnLayer(item.Layer);
if (toMove != null)
{
// pack.DropItem(toMove);
toMove.Internalize();
if (!pm.EquipItem(item))
{
continue;
}
var toMove = pm.FindItemOnLayer(item.Layer);
if (toMove != null)
{
// pack.DropItem(toMove);
toMove.Internalize();
if (!pm.EquipItem(item))
{
pm.EquipItem(toMove);
}
else
{
pack.DropItem(toMove);
}
pm.EquipItem(toMove);
}
else
{
pm.EquipItem(item);
pack.DropItem(toMove);
}
}
else
{
pm.EquipItem(item);
}
}
}
public static void UnequipMacro(Mobile m, List<Layer> layers)
public static void UnequipMacro(Mobile m, ref PooledRefList<Layer> layers)
{
if (m is PlayerMobile { Alive: true } pm && pm.Backpack != null)
if (m is not PlayerMobile { Alive: true } pm || pm.Backpack == null)
{
var pack = pm.Backpack;
var eq = m.Items;
return;
}
for (var i = eq.Count - 1; i >= 0; i--)
var pack = pm.Backpack;
var eq = m.Items;
for (var i = eq.Count - 1; i >= 0; i--)
{
var item = eq[i];
if (layers.Contains(item.Layer))
{
var item = eq[i];
if (layers.Contains(item.Layer))
{
pack.TryDropItem(pm, item, false);
}
pack.TryDropItem(pm, item, false);
}
}
}
@ -1547,13 +1551,17 @@ namespace Server.Mobiles
// Eject all from house
from.RevealingAction();
foreach (var item in context.Foundation.GetItems())
var list = context.Foundation.GetItems();
for (var i = 0; i < list.Count; i++)
{
var item = list[i];
item.Location = context.Foundation.BanLocation;
}
foreach (var mobile in context.Foundation.GetMobiles())
using var mobiles = context.Foundation.GetMobilesPooled();
for (var i = 0; i < mobiles.Count; i++)
{
var mobile = mobiles[i];
mobile.Location = context.Foundation.BanLocation;
}

View file

@ -1235,24 +1235,24 @@ namespace Server.Multis
return list;
}
public List<Mobile> GetMobiles()
public PooledRefList<Mobile> GetMobilesPooled()
{
if (Map == null || Map == Map.Internal)
{
return new List<Mobile>();
return PooledRefList<Mobile>.Create(0);
}
var list = new List<Mobile>();
foreach (var mobile in Region.GetMobiles())
var mobileList = Region.GetMobilesPooled();
for (var i = mobileList.Count - 1; i >= 0; i--)
{
if (IsInside(mobile))
var mobile = mobileList[i];
if (!IsInside(mobile))
{
list.Add(mobile);
mobileList.Remove(mobile);
}
}
return list;
return mobileList;
}
public virtual bool CheckAosLockdowns(int need) => GetAosCurLockdowns() + need <= GetAosMaxLockdowns();

View file

@ -901,8 +901,10 @@ namespace Server.Multis
item.Location = BanLocation;
}
foreach (var mobile in GetMobiles())
using var mobiles = GetMobilesPooled();
for (var i = 0; i < mobiles.Count; i++)
{
var mobile = mobiles[i];
if (mobile != m)
{
mobile.Location = BanLocation;
@ -1294,13 +1296,18 @@ namespace Server.Multis
// Eject all from house
from.RevealingAction();
foreach (var item in GetItems())
var items = GetItems();
for (var i = 0; i < items.Count; i++)
{
var item = items[i];
item.Location = BanLocation;
}
foreach (var mobile in GetMobiles())
using var mobiles = GetMobilesPooled();
var list = GetMobilesPooled();
for (var i = 0; i < list.Count; i++)
{
var mobile = list[i];
mobile.Location = BanLocation;
}
@ -1760,13 +1767,17 @@ namespace Server.Multis
// Eject all from house
from.RevealingAction();
foreach (var item in context.Foundation.GetItems())
var list = context.Foundation.GetItems();
for (var i = 0; i < list.Count; i++)
{
var item = list[i];
item.Location = context.Foundation.BanLocation;
}
foreach (var mobile in context.Foundation.GetMobiles())
using var mobiles = context.Foundation.GetMobilesPooled();
for (var i = 0; i < mobiles.Count; i++)
{
var mobile = mobiles[i];
mobile.Location = context.Foundation.BanLocation;
}

View file

@ -14,8 +14,8 @@
*************************************************************************/
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using Server.Collections;
using Server.Items;
using Server.Mobiles;
@ -112,24 +112,25 @@ public static class IncomingItemPackets
public static void EquipMacro(NetState state, SpanReader reader)
{
int count = reader.ReadByte();
var serialList = new List<Serial>(count);
var serialList = PooledRefList<Serial>.Create(count);
for (var i = 0; i < count; ++i)
{
serialList.Add((Serial)reader.ReadUInt32());
}
PlayerMobile.EquipMacro(state.Mobile, serialList);
PlayerMobile.EquipMacro(state.Mobile, ref serialList);
serialList.Dispose();
}
public static void UnequipMacro(NetState state, SpanReader reader)
{
int count = reader.ReadByte();
var layers = new List<Layer>(count);
var layers = PooledRefList<Layer>.Create(count);
for (var i = 0; i < count; ++i)
{
layers.Add((Layer)reader.ReadUInt16());
}
PlayerMobile.UnequipMacro(state.Mobile, layers);
PlayerMobile.UnequipMacro(state.Mobile, ref layers);
}
}