fix: Eliminates List allocations in various places. (#2158)
This commit is contained in:
parent
6f64cddd0b
commit
4836bff5eb
23 changed files with 263 additions and 200 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using Server.Buffers;
|
||||
using Server.Text;
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Items;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue