Converted RemoveFiRStatusFromItemsInContainer into extension method
Improved performance of method by using breadth-first search to find children instead of loop Wrote tests for method
This commit is contained in:
@@ -416,5 +416,37 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
|
||||
return new InventoryItemHash { ByItemId = inventoryItems.ToDictionary(item => item.Id), ByParentId = byParentId };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove spawned in session (FiR) status from items inside a container
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="containerSlotId">Container slot id to find items for and remove FiR from e.g. "Backpack"</param>
|
||||
public static void RemoveFiRStatusFromItemsInContainer(this PmcData pmcData, string containerSlotId)
|
||||
{
|
||||
var container = pmcData?.Inventory?.Items?.FirstOrDefault(item => item.SlotId == containerSlotId);
|
||||
if (container is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var parentItemLookup = pmcData.Inventory.Items.ToLookup(item => item.ParentId);
|
||||
var parentIdsToSearch = new Queue<string>();
|
||||
parentIdsToSearch.Enqueue(container.Id);
|
||||
|
||||
while (parentIdsToSearch.Count > 0)
|
||||
{
|
||||
var currentParentId = parentIdsToSearch.Dequeue();
|
||||
foreach (var childItem in parentItemLookup[currentParentId])
|
||||
{
|
||||
if (childItem.Upd?.SpawnedInSession != null && childItem.Upd.SpawnedInSession.Value)
|
||||
{
|
||||
childItem.Upd.SpawnedInSession = false;
|
||||
}
|
||||
|
||||
parentIdsToSearch.Enqueue(childItem.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,34 +144,6 @@ public class InRaidHelper(InventoryHelper inventoryHelper, ConfigServer configSe
|
||||
pmcData.Inventory.FastPanel = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove FiR status from designated container.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="secureContainerSlotId">Container slot id to find items for and remove FiR from</param>
|
||||
public void RemoveFiRStatusFromItemsInContainer(MongoId sessionId, PmcData pmcData, string secureContainerSlotId)
|
||||
{
|
||||
if (!pmcData.Inventory.Items.Any(item => item.SlotId == secureContainerSlotId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Item> itemsInsideContainer = [];
|
||||
foreach (var inventoryItem in pmcData.Inventory.Items.Where(item => item.Upd is not null && item.SlotId != "hideout"))
|
||||
{
|
||||
if (inventoryItem.ItemIsInsideContainer(secureContainerSlotId, pmcData.Inventory.Items))
|
||||
{
|
||||
itemsInsideContainer.Add(inventoryItem);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in itemsInsideContainer.Where(item => item.Upd?.SpawnedInSession ?? false))
|
||||
{
|
||||
item.Upd.SpawnedInSession = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of items from a profile that will be lost on death.
|
||||
/// </summary>
|
||||
|
||||
@@ -777,7 +777,7 @@ public class LocationLifecycleService(
|
||||
|
||||
inRaidHelper.DeleteInventory(serverPmcProfile, sessionId);
|
||||
|
||||
inRaidHelper.RemoveFiRStatusFromItemsInContainer(sessionId, serverPmcProfile, "SecuredContainer");
|
||||
serverPmcProfile.RemoveFiRStatusFromItemsInContainer("SecuredContainer");
|
||||
}
|
||||
|
||||
// Must occur AFTER killer messages have been sent
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using NUnit.Framework;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
|
||||
namespace UnitTests.Tests.Extensions;
|
||||
@@ -139,4 +140,156 @@ public class ItemTests
|
||||
Assert.AreEqual(result[0].Id, rootItem.Id);
|
||||
Assert.AreEqual(result.Count, 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveFiRStatusFromItemsInContainer_twoItemsInBackpack()
|
||||
{
|
||||
var profile = new PmcData() { Inventory = new BotBaseInventory() { Items = [] } };
|
||||
profile.Inventory.Equipment = new MongoId();
|
||||
|
||||
// Add backpack
|
||||
var backpackId = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = backpackId,
|
||||
Template = ItemTpl.BACKPACK_HAZARD_4_PILLBOX_BACKPACK_BLACK,
|
||||
ParentId = profile.Inventory.Equipment,
|
||||
SlotId = "Backpack",
|
||||
}
|
||||
);
|
||||
|
||||
// Add ifak to first slot in backpack
|
||||
var item1Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item1Id,
|
||||
Template = ItemTpl.MEDKIT_AFAK_TACTICAL_INDIVIDUAL_FIRST_AID_KIT,
|
||||
ParentId = backpackId,
|
||||
SlotId = "main",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
Location = new ItemLocation
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
R = ItemRotation.Horizontal,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// Add wrench to first slot of ifak
|
||||
var item2Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item2Id,
|
||||
Template = ItemTpl.BARTER_WRENCH,
|
||||
ParentId = backpackId,
|
||||
SlotId = "main",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
Location = new ItemLocation
|
||||
{
|
||||
X = 1,
|
||||
Y = 0,
|
||||
R = ItemRotation.Horizontal,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// Add armband to armband slot as root
|
||||
var item3Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item3Id,
|
||||
Template = ItemTpl.ARMBAND_RED,
|
||||
ParentId = profile.Inventory.Equipment,
|
||||
SlotId = "Armband",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
}
|
||||
);
|
||||
|
||||
profile.RemoveFiRStatusFromItemsInContainer("Backpack");
|
||||
|
||||
Assert.AreEqual(false, profile.Inventory.Items.FirstOrDefault(item => item.Id == item1Id).Upd.SpawnedInSession);
|
||||
Assert.AreEqual(false, profile.Inventory.Items.FirstOrDefault(item => item.Id == item2Id).Upd.SpawnedInSession);
|
||||
Assert.AreEqual(true, profile.Inventory.Items.FirstOrDefault(item => item.Id == item3Id).Upd.SpawnedInSession);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveFiRStatusFromItemsInContainer_oneItemWithChildInBackpack()
|
||||
{
|
||||
var profile = new PmcData { Inventory = new BotBaseInventory { Items = [] } };
|
||||
profile.Inventory.Equipment = new MongoId();
|
||||
|
||||
// Add backpack
|
||||
var backpackId = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = backpackId,
|
||||
Template = ItemTpl.BACKPACK_HAZARD_4_PILLBOX_BACKPACK_BLACK,
|
||||
ParentId = profile.Inventory.Equipment,
|
||||
SlotId = "Backpack",
|
||||
}
|
||||
);
|
||||
|
||||
// Add ifak to first slot in backpack
|
||||
var item1Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item1Id,
|
||||
Template = ItemTpl.MEDKIT_AFAK_TACTICAL_INDIVIDUAL_FIRST_AID_KIT,
|
||||
ParentId = backpackId,
|
||||
SlotId = "main",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
Location = new ItemLocation
|
||||
{
|
||||
X = 0,
|
||||
Y = 0,
|
||||
R = ItemRotation.Horizontal,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// Add wrench to first slot of ifak as child
|
||||
var item2Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item2Id,
|
||||
Template = ItemTpl.BARTER_WRENCH,
|
||||
ParentId = item1Id,
|
||||
SlotId = "main",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
Location = new ItemLocation
|
||||
{
|
||||
X = 1,
|
||||
Y = 0,
|
||||
R = ItemRotation.Horizontal,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// Add armband to armband slot as root
|
||||
var item3Id = new MongoId();
|
||||
profile.Inventory.Items.Add(
|
||||
new Item
|
||||
{
|
||||
Id = item3Id,
|
||||
Template = ItemTpl.ARMBAND_RED,
|
||||
ParentId = profile.Inventory.Equipment,
|
||||
SlotId = "Armband",
|
||||
Upd = new Upd { SpawnedInSession = true },
|
||||
}
|
||||
);
|
||||
|
||||
profile.RemoveFiRStatusFromItemsInContainer("Backpack");
|
||||
|
||||
Assert.AreEqual(false, profile.Inventory.Items.FirstOrDefault(item => item.Id == item1Id).Upd.SpawnedInSession);
|
||||
Assert.AreEqual(false, profile.Inventory.Items.FirstOrDefault(item => item.Id == item2Id).Upd.SpawnedInSession);
|
||||
Assert.AreEqual(true, profile.Inventory.Items.FirstOrDefault(item => item.Id == item3Id).Upd.SpawnedInSession);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user