fix: Changes Map.Sector.Items to link list. (#1547)

### Summary

Eliminates `IPooledEnumerable<T>` and `eable.Free()` from `Map` for items. This drastically simplifies code that iterates in range, for example:

```cs
foreach (var item in m.GetItemsInRange(5))
{
}
```
The code above no longer requires an eable and calling `Free()`.
This commit is contained in:
Kamron Batman 2023-10-16 20:51:02 -07:00 • committed by GitHub
parent 1330c4a830
commit 24858f3989
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 577 additions and 419 deletions

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Toolkit.HighPerformance;
using Server.Collections;
using Server.Engines.Quests.Haven;
using Server.Engines.Quests.Necro;
using Server.Engines.Spawners;
@ -78,8 +79,6 @@ namespace Server.Commands
private static readonly Type typeofCannon = typeof(Cannon);
private static readonly Type typeofSerpentPillar = typeof(SerpentPillar);
private static readonly Queue<Item> m_DeleteQueue = new();
private static readonly string[] m_EmptyParams = Array.Empty<string>();
private List<DecorationEntry> m_Entries;
private int m_ItemID;
@ -1037,16 +1036,17 @@ namespace Server.Commands
private static bool FindItem(int x, int y, int z, Map map, Item srcItem)
{
var itemID = srcItem.ItemID;
var lt = srcItem.Light;
var srcName = srcItem.ItemData.Name;
var type = srcItem.GetType();
var res = false;
IPooledEnumerable<Item> eable;
using var queue = PooledRefQueue<Item>.Create();
if (srcItem is BaseDoor)
foreach (var item in map.GetItemsInRange(new Point3D(x, y, z), 1))
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 1);
foreach (var item in eable)
if (srcItem is BaseDoor)
{
if (!(item is BaseDoor))
{
@ -1079,18 +1079,10 @@ namespace Server.Commands
}
else if ((item.Z - z).Abs() < 8)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
}
}
else if (TileData.ItemTable[itemID & TileData.MaxItemValue].LightSource)
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
var lt = srcItem.Light;
var srcName = srcItem.ItemData.Name;
foreach (var item in eable)
else if (TileData.ItemTable[itemID & TileData.MaxItemValue].LightSource)
{
if (item.Z == z)
{
@ -1098,7 +1090,7 @@ namespace Server.Commands
{
if (item.Light != lt)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
else
{
@ -1107,24 +1099,17 @@ namespace Server.Commands
}
else if (item.ItemData.LightSource && item.ItemData.Name == srcName)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
}
}
}
else if (srcItem is Teleporter or FillableContainer or BaseBook)
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
var type = srcItem.GetType();
foreach (var item in eable)
else if (srcItem is Teleporter or FillableContainer or BaseBook)
{
if (item.Z == z && item.ItemID == itemID)
{
if (item.GetType() != type)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
else
{
@ -1132,12 +1117,7 @@ namespace Server.Commands
}
}
}
}
else
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
foreach (var item in eable)
else
{
if (item.Z == z && item.ItemID == itemID)
{
@ -1146,9 +1126,9 @@ namespace Server.Commands
}
}
while (m_DeleteQueue.Count > 0)
while (queue.Count > 0)
{
m_DeleteQueue.Dequeue().Delete();
queue.Dequeue().Delete();
}
return res;
@ -1196,7 +1176,6 @@ namespace Server.Commands
if (item is BaseDoor door)
{
var eable = maps[j].GetItemsInRange<BaseDoor>(loc, 1);
var itemType = door.GetType();
foreach (var link in eable)

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Toolkit.HighPerformance;
using Server.Collections;
using Server.Engines.Quests.Haven;
using Server.Engines.Quests.Necro;
using Server.Engines.Spawners;
@ -74,8 +75,6 @@ namespace Server.Commands
private static readonly Type typeofCannon = typeof(Cannon);
private static readonly Type typeofSerpentPillar = typeof(SerpentPillar);
private static readonly Queue<Item> m_DeleteQueue = new();
private static readonly string[] m_EmptyParams = Array.Empty<string>();
private List<DecorationEntryMag> m_Entries;
private int m_ItemID;
@ -1033,16 +1032,16 @@ namespace Server.Commands
private static bool FindItem(int x, int y, int z, Map map, Item srcItem)
{
var itemID = srcItem.ItemID;
var lt = srcItem.Light;
var srcName = srcItem.ItemData.Name;
var type = srcItem.GetType();
var res = false;
IPooledEnumerable<Item> eable;
if (srcItem is BaseDoor)
using var queue = PooledRefQueue<Item>.Create();
foreach (var item in map.GetItemsInRange(new Point3D(x, y, z), 1))
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 1);
foreach (var item in eable)
if (srcItem is BaseDoor)
{
if (!(item is BaseDoor))
{
@ -1075,18 +1074,10 @@ namespace Server.Commands
}
else if ((item.Z - z).Abs() < 8)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
}
}
else if (TileData.ItemTable[itemID & TileData.MaxItemValue].LightSource)
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
var lt = srcItem.Light;
var srcName = srcItem.ItemData.Name;
foreach (var item in eable)
else if (TileData.ItemTable[itemID & TileData.MaxItemValue].LightSource)
{
if (item.Z == z)
{
@ -1094,7 +1085,7 @@ namespace Server.Commands
{
if (item.Light != lt)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
else
{
@ -1103,24 +1094,17 @@ namespace Server.Commands
}
else if (item.ItemData.LightSource && item.ItemData.Name == srcName)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
}
}
}
else if (srcItem is Teleporter or FillableContainer or BaseBook)
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
var type = srcItem.GetType();
foreach (var item in eable)
else if (srcItem is Teleporter or FillableContainer or BaseBook)
{
if (item.Z == z && item.ItemID == itemID)
{
if (item.GetType() != type)
{
m_DeleteQueue.Enqueue(item);
queue.Enqueue(item);
}
else
{
@ -1128,12 +1112,7 @@ namespace Server.Commands
}
}
}
}
else
{
eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
foreach (var item in eable)
else
{
if (item.Z == z && item.ItemID == itemID)
{
@ -1142,9 +1121,9 @@ namespace Server.Commands
}
}
while (m_DeleteQueue.Count > 0)
while (queue.Count > 0)
{
m_DeleteQueue.Dequeue()?.Delete();
queue.Dequeue()?.Delete();
}
return res;
@ -1181,11 +1160,9 @@ namespace Server.Commands
if (item is BaseDoor door)
{
var eable = maps[j].GetItemsInRange<BaseDoor>(loc, 1);
var itemType = door.GetType();
foreach (var link in eable)
foreach (var link in maps[j].GetItemsInRange<BaseDoor>(loc, 1))
{
if (link != item && link.Z == door.Z && link.GetType() == itemType)
{

View file

@ -121,17 +121,16 @@ namespace Server.Commands
public static int DeleteTeleporters(WorldLocation worldLocation)
{
var eable = worldLocation.Map.GetItemsInRange<Teleporter>(worldLocation, 0);
var count = 0;
foreach (var item in eable)
foreach (var item in worldLocation.Map.GetItemsInRange<Teleporter>(worldLocation, 0))
{
if (!(item is KeywordTeleporter or SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z))
if (item is not (KeywordTeleporter or SkillTeleporter) && IsWithinZ(item.Z - worldLocation.Z))
{
count++;
item.Delete();
}
}
return count;
}