Replaced lists containing unique values with HashSets

Reworked Soft Insert id checks

Improved dogtag id lookup memory usage

Removed wave cleanup code
This commit is contained in:
Chomp
2025-02-17 19:05:47 +00:00
parent ea7b3919c0
commit 1ff8d2cbef
58 changed files with 228 additions and 246 deletions
@@ -32,7 +32,7 @@ public class ItemEventCallbacks(HttpResponseUtil _httpResponseUtil, ItemEventRou
}
// List of non-critical error codes, we return true if any error NOT included is passed in
var nonCriticalErrorCodes = new List<BackendErrorCodes>
var nonCriticalErrorCodes = new HashSet<BackendErrorCodes>
{
BackendErrorCodes.NotEnoughSpace
};
@@ -250,7 +250,7 @@ public class HideoutController(
// Dont inform client when upgraded area is hall of fame or equipment stand, BSG doesn't inform client this specifc upgrade has occurred
// will break client if sent
List<HideoutAreas> check = [HideoutAreas.PLACE_OF_FAME];
HashSet<HideoutAreas> check = [HideoutAreas.PLACE_OF_FAME];
if (!check.Contains(dbHideoutArea.Type ?? HideoutAreas.NOTSET))
{
AddContainerUpgradeToClientOutput(sessionID, dbHideoutArea.Type, dbHideoutArea, hideoutStage, output);
@@ -733,9 +733,8 @@ public class InsuranceController(
*/
public void InsureSoftInserts(Item itemWithSoftInserts, PmcData pmcData, InsureRequestData body)
{
var softInsertIds = _itemHelper.GetSoftInsertSlotIds();
var softInsertSlots = pmcData.Inventory.Items.Where(
item => item.ParentId == itemWithSoftInserts.Id && softInsertIds.Contains(item.SlotId.ToLower())
item => item.ParentId == itemWithSoftInserts.Id && _itemHelper.IsSoftInsertId(item.SlotId.ToLower())
);
foreach (var softInsertSlot in softInsertSlots)
@@ -261,7 +261,7 @@ public class InventoryController(
var foundInRaid = openedItem.Upd?.SpawnedInSession;
var rewards = new List<List<Item>>();
var unlockedWeaponCrates = new List<string>
var unlockedWeaponCrates = new HashSet<string>
{
ItemTpl.RANDOMLOOTCONTAINER_ARENA_WEAPONCRATE_VIOLET_OPEN,
ItemTpl.RANDOMLOOTCONTAINER_ARENA_WEAPONCRATE_BLUE_OPEN,
@@ -41,6 +41,18 @@ public class BotEquipmentModGenerator(
{
protected BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
protected HashSet<string> _modSightIds = ["mod_sight_front", "mod_sight_rear"];
protected HashSet<string> _scopeIds =
[
"mod_scope",
"mod_mount",
"mod_mount_000",
"mod_scope_000",
"mod_scope_001",
"mod_scope_002",
"mod_scope_003"
];
/// <summary>
/// Check mods are compatible and add to array
/// </summary>
@@ -152,7 +164,7 @@ public class BotEquipmentModGenerator(
// Choose random mod from pool and check its compatibility
string modTpl = null;
var found = false;
var exhaustableModPool = CreateExhaustableArray(modPoolToChooseFrom.ToList());
var exhaustableModPool = CreateExhaustableArray(modPoolToChooseFrom);
while (exhaustableModPool.HasValues())
{
modTpl = exhaustableModPool.GetRandomValue();
@@ -454,7 +466,7 @@ public class BotEquipmentModGenerator(
var randomisationSettings = _botHelper.GetBotRandomizationDetails(request.BotData.Level ?? 0, botEquipConfig);
// Iterate over mod pool and choose mods to attach
var sortedModKeys = SortModKeys(compatibleModsPool.Keys.ToList(), request.ParentTemplate.Id);
var sortedModKeys = SortModKeys(compatibleModsPool.Keys.ToHashSet(), request.ParentTemplate.Id);
foreach (var modSlot in sortedModKeys)
{
// Check weapon has slot for mod to fit in
@@ -707,7 +719,7 @@ public class BotEquipmentModGenerator(
public bool ShouldForceSubStockSlots(string modSlot, EquipmentFilters botEquipConfig, TemplateItem modToAddTemplate)
{
// Slots a weapon can store its stock in
string[] stockSlots = ["mod_stock", "mod_stock_000", "mod_stock_001", "mod_stock_akms"];
HashSet<string> stockSlots = ["mod_stock", "mod_stock_000", "mod_stock_001", "mod_stock_akms"];
// Can the stock hold child items
var hasSubSlots = modToAddTemplate.Properties.Slots?.Count > 0;
@@ -730,7 +742,7 @@ public class BotEquipmentModGenerator(
return true;
}
return ((string[]) ["mod_sight_front", "mod_sight_rear"]).Contains(modSlot);
return _modSightIds.Contains(modSlot);
}
/// <summary>
@@ -741,17 +753,7 @@ public class BotEquipmentModGenerator(
/// <returns>true if it can hold a scope</returns>
public bool ModSlotCanHoldScope(string modSlot, string modsParentId)
{
return ((string[])
[
"mod_scope",
"mod_mount",
"mod_mount_000",
"mod_scope_000",
"mod_scope_001",
"mod_scope_002",
"mod_scope_003"
]).Contains(modSlot.ToLower()) &&
modsParentId == BaseClasses.MOUNT;
return _scopeIds.Contains(modSlot.ToLower()) && modsParentId == BaseClasses.MOUNT;
}
/// <summary>
@@ -799,7 +801,7 @@ public class BotEquipmentModGenerator(
/// <param name="unsortedSlotKeys">Array of mod slot strings to sort</param>
/// <param name="itemTplWithKeysToSort">The Tpl of the item with mod keys being sorted</param>
/// <returns>Sorted array</returns>
public List<string> SortModKeys(List<string> unsortedSlotKeys, string itemTplWithKeysToSort)
public HashSet<string> SortModKeys(HashSet<string> unsortedSlotKeys, string itemTplWithKeysToSort)
{
// No need to sort with only 1 item in array
if (unsortedSlotKeys.Count <= 1)
@@ -809,7 +811,7 @@ public class BotEquipmentModGenerator(
var isMount = _itemHelper.IsOfBaseclass(itemTplWithKeysToSort, BaseClasses.MOUNT);
List<string> sortedKeys = [];
HashSet<string> sortedKeys = [];
var modRecieverKey = "mod_reciever";
var modMount001Key = "mod_mount_001";
var modGasBlockKey = "mod_gas_block";
@@ -899,7 +901,7 @@ public class BotEquipmentModGenerator(
}
}
sortedKeys.AddRange(unsortedSlotKeys);
sortedKeys.UnionWith(unsortedSlotKeys);
return sortedKeys;
}
@@ -1138,7 +1140,7 @@ public class BotEquipmentModGenerator(
}
// Filter mod pool to only items that appear in parents allowed list
preFilteredModPool = preFilteredModPool.Where(tpl => parentSlot.Props.Filters[0].Filter.Contains(tpl)).ToList();
preFilteredModPool = preFilteredModPool.Where(tpl => parentSlot.Props.Filters[0].Filter.Contains(tpl)).ToHashSet();
if (preFilteredModPool.Count == 0)
{
return new ChooseRandomCompatibleModResult
@@ -1158,10 +1160,10 @@ public class BotEquipmentModGenerator(
/// <param name="modSpawnType">How should the slot choice be handled - forced/normal etc</param>
/// <param name="weapon">Weapon mods at current time</param>
/// <returns>IChooseRandomCompatibleModResult</returns>
public ChooseRandomCompatibleModResult GetCompatibleModFromPool(List<string> modPool, ModSpawn? modSpawnType, List<Item> weapon)
public ChooseRandomCompatibleModResult GetCompatibleModFromPool(HashSet<string> modPool, ModSpawn? modSpawnType, List<Item> weapon)
{
// Create exhaustable pool to pick mod item from
var exhaustableModPool = CreateExhaustableArray(modPool.ToList());
var exhaustableModPool = CreateExhaustableArray(modPool);
// Create default response if no compatible item is found below
ChooseRandomCompatibleModResult chosenModResult = new()
@@ -1244,9 +1246,9 @@ public class BotEquipmentModGenerator(
return chosenModResult;
}
public ExhaustableArray<T> CreateExhaustableArray<T>(List<T> itemsToAddToArray)
public ExhaustableArray<T> CreateExhaustableArray<T>(ICollection<T> itemsToAddToArray)
{
return new ExhaustableArray<T>(itemsToAddToArray.ToList(), _randomUtil, _cloner);
return new ExhaustableArray<T>(itemsToAddToArray, _randomUtil, _cloner);
}
/// <summary>
@@ -1255,9 +1257,9 @@ public class BotEquipmentModGenerator(
/// <param name="modPool"></param>
/// <param name="tplBlacklist">Tpls that are incompatible and should not be used</param>
/// <returns>string array of compatible mod tpls with weapon</returns>
public List<string> GetFilteredModPool(HashSet<string> modPool, HashSet<string> tplBlacklist)
public HashSet<string> GetFilteredModPool(HashSet<string> modPool, HashSet<string> tplBlacklist)
{
return modPool.Where(tpl => !tplBlacklist.Contains(tpl)).ToList();
return modPool.Where(tpl => !tplBlacklist.Contains(tpl)).ToHashSet();
}
/// <summary>
@@ -1442,7 +1444,7 @@ public class BotEquipmentModGenerator(
/// e.g. mod_magazine / patron_in_weapon_000
/// </summary>
/// <returns>string array</returns>
public List<string> GetAmmoContainers()
public HashSet<string> GetAmmoContainers()
{
return ["mod_magazine", "patron_in_weapon", "patron_in_weapon_000", "patron_in_weapon_001", "cartridges"];
}
@@ -1781,7 +1783,7 @@ public class BotEquipmentModGenerator(
{
// Check to see if mount has a scope slot (only include primary slot, ignore the rest like the backup sight slots)
// Should only find 1 as there's currently no items with a mod_scope AND a mod_scope_000
List<string> filter = ["mod_scope", "mod_scope_000"];
HashSet<string> filter = ["mod_scope", "mod_scope_000"];
var scopeSlot = itemDetails.Properties.Slots.Where(
slot =>
filter.Contains(slot.Name)
@@ -1806,7 +1808,7 @@ public class BotEquipmentModGenerator(
}
// No mods added to return list after filtering has occurred, send back the original mod list
if (filteredScopesAndMods is null || filteredScopesAndMods.Count() == 0)
if (filteredScopesAndMods.Count == 0)
{
if (_logger.IsLogEnabled(LogLevel.Debug))
{
@@ -40,7 +40,7 @@ public class BotInventoryGenerator(
private readonly BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
// Slots handled individually inside `GenerateAndAddEquipmentToBot`
private readonly List<EquipmentSlots> _excludedEquipmentSlots =
private readonly HashSet<EquipmentSlots> _excludedEquipmentSlots =
[
EquipmentSlots.Pockets,
EquipmentSlots.FirstPrimaryWeapon,
@@ -449,7 +449,7 @@ public class BotInventoryGenerator(
/// <returns>true when item added</returns>
public bool GenerateEquipment(GenerateEquipmentProperties settings)
{
List<string> slotsToCheck = [EquipmentSlots.Pockets.ToString(), EquipmentSlots.SecuredContainer.ToString()];
HashSet<string> slotsToCheck = [EquipmentSlots.Pockets.ToString(), EquipmentSlots.SecuredContainer.ToString()];
double? spawnChance = slotsToCheck.Contains(settings.RootEquipmentSlot.ToString())
? 100
: settings.SpawnChances.EquipmentChances.GetValueOrDefault(settings.RootEquipmentSlot.ToString());
@@ -589,7 +589,7 @@ public class BotInventoryGenerator(
/// <param name="itemTpl">Item mod pool is being retrieved and filtered</param>
/// <param name="equipmentBlacklist">Blacklist to filter mod pool with</param>
/// <returns>Filtered pool of mods</returns>
public Dictionary<string, HashSet<string>> GetFilteredDynamicModsForItem(string itemTpl, Dictionary<string, List<string>> equipmentBlacklist)
public Dictionary<string, HashSet<string>> GetFilteredDynamicModsForItem(string itemTpl, Dictionary<string, HashSet<string>> equipmentBlacklist)
{
var modPool = _botEquipmentModPoolService.GetModsForGearSlot(itemTpl);
foreach (var modSlot in modPool)
@@ -368,9 +368,9 @@ public class BotLootGenerator(
/// </summary>
/// <param name="botInventory"></param>
/// <returns></returns>
private List<EquipmentSlots> GetAvailableContainersBotCanStoreItemsIn(BotBaseInventory botInventory)
private HashSet<EquipmentSlots> GetAvailableContainersBotCanStoreItemsIn(BotBaseInventory botInventory)
{
List<EquipmentSlots> result = [EquipmentSlots.Pockets];
HashSet<EquipmentSlots> result = [EquipmentSlots.Pockets];
if ((botInventory.Items ?? []).Any(item => item.SlotId == EquipmentSlots.TacticalVest.ToString()))
{
@@ -438,7 +438,7 @@ public class BotLootGenerator(
private void AddLootFromPool
(
Dictionary<string, double> pool,
List<EquipmentSlots> equipmentSlots,
HashSet<EquipmentSlots> equipmentSlots,
double totalItemCount,
BotBaseInventory inventoryToAddItemsTo,
string botRole,
@@ -200,9 +200,8 @@ public class BotWeaponGenerator(
}
// Add cartridge(s) to gun chamber(s)
if (weaponItemTemplate.Properties.Chambers?.Any() ??
(false &&
weaponItemTemplate.Properties.Chambers[0].Props.Filters[0].Filter.Contains(ammoTpl)))
if (weaponItemTemplate.Properties?.Chambers?.Count > 0 &&
weaponItemTemplate.Properties.Chambers[0].Props.Filters[0].Filter.Contains(ammoTpl))
{
// Guns have variety of possible Chamber ids, patron_in_weapon/patron_in_weapon_000/patron_in_weapon_001
var chamberSlotNames = weaponItemTemplate.Properties.Chambers.Select(chamberSlot => chamberSlot.Name);
@@ -500,7 +499,7 @@ public class BotWeaponGenerator(
{
var id = _hashUtil.Generate();
_botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
new List<EquipmentSlots>
new HashSet<EquipmentSlots>
{
EquipmentSlots.SecuredContainer
},
@@ -634,7 +633,7 @@ public class BotWeaponGenerator(
/// </summary>
/// <param name="weaponTemplate">Weapon db template to get cartridges for</param>
/// <returns>List of cartridge tpls</returns>
protected List<string>? GetCompatibleCartridgesFromWeaponTemplate(TemplateItem weaponTemplate)
protected HashSet<string>? GetCompatibleCartridgesFromWeaponTemplate(TemplateItem weaponTemplate)
{
var cartridges = weaponTemplate.Properties?.Chambers.FirstOrDefault()?.Props?.Filters?[0].Filter;
if (cartridges is not null)
@@ -645,7 +644,7 @@ public class BotWeaponGenerator(
// Fallback to the magazine if possible, e.g. for revolvers
// Grab the magazines template
var firstMagazine = weaponTemplate.Properties.Slots.FirstOrDefault(slot => slot.Name == "mod_magazine");
var magazineTemplate = _itemHelper.GetItem(firstMagazine.Props.Filters?[0].Filter[0]);
var magazineTemplate = _itemHelper.GetItem(firstMagazine.Props.Filters?[0].Filter.FirstOrDefault());
var magProperties = magazineTemplate.Value.Properties;
// Get the first slots array of cartridges
@@ -683,14 +682,11 @@ public class BotWeaponGenerator(
if (weaponTemplate.Properties.LinkedWeapon is not null)
{
var ammoInChamber = _itemHelper.GetItem(
weaponTemplate.Properties.Chambers[0].Props.Filters[0].Filter[0]
weaponTemplate.Properties.Chambers[0].Props.Filters[0].Filter.FirstOrDefault()
);
if (!ammoInChamber.Key)
{
return null;
}
return ammoInChamber.Value.Properties.Caliber;
return !ammoInChamber.Key
? null
: ammoInChamber.Value.Properties.Caliber;
}
return null;
@@ -227,7 +227,7 @@ public class FenceBaseAssortGenerator(
if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.AMMO_BOX))
{
// Get the cartridge tpl found inside ammo box
var cartridgeTplInBox = rootItemDb.Properties.StackSlots[0].Props.Filters[0].Filter[0];
var cartridgeTplInBox = rootItemDb.Properties.StackSlots[0].Props.Filters[0].Filter.FirstOrDefault();
// Look up cartridge tpl in db
var ammoItemDb = itemHelper.GetItem(cartridgeTplInBox);
@@ -823,7 +823,7 @@ public class LocationLootGenerator(
}
// Get an array of allowed IDs after above filtering has occured
var validItemIds = spawnPoint.Template.Items.Select(item => item.Id).ToList();
var validItemIds = spawnPoint.Template.Items.Select(item => item.Id).ToHashSet();
// Construct container to hold above filtered items, letting us pick an item for the spot
var itemArray = new ProbabilityObjectArray<string, double?>(_mathUtil, _cloner);
+1 -1
View File
@@ -219,7 +219,7 @@ public class LootGenerator(
/// <param name="blockSeasonalItemsOutOfSeason">Prevent seasonal items appearing outside their defined season</param>
/// <returns>results of filtering + blacklist used</returns>
protected ItemRewardPoolResults GetItemRewardPool(
List<string> itemTplBlacklist,
HashSet<string> itemTplBlacklist,
List<string> itemTypeWhitelist,
bool useRewardItemBlacklist,
bool allowBossItems,
@@ -139,7 +139,7 @@ public class PlayerScavGenerator(
/// <param name="scavData"></param>
/// <param name="containersToAddTo">Possible slotIds to add loot to</param>
protected void AddAdditionalLootToPlayerScavContainers(Dictionary<string, double> possibleItemsToAdd, BotBase scavData,
List<EquipmentSlots> containersToAddTo)
HashSet<EquipmentSlots> containersToAddTo)
{
foreach (var tpl in possibleItemsToAdd)
{
@@ -71,7 +71,7 @@ public class RagfairAssortGenerator(
var dbItemsClone = itemHelper.GetItems().Where(item => item.Type != "Node");
/** Store processed preset tpls so we dont add them when procesing non-preset items */
List<string> processedArmorItems = [];
HashSet<string> processedArmorItems = [];
var seasonalEventActive = seasonalEventService.SeasonalEventEnabled();
var seasonalItemTplBlacklist = seasonalEventService.GetInactiveSeasonalEventItems();
@@ -529,7 +529,7 @@ public class RagfairOfferGenerator(
// Latest first, to ensure we don't move later items off by 1 each time we remove an item below it
var indexesToRemove = offerItemPlatesToRemove.Select(plateItem => itemWithChildren.IndexOf(plateItem))
.ToList();
.ToHashSet();
foreach (var index in indexesToRemove.OrderByDescending(x => x))
{
itemWithChildren.RemoveAt(index);
@@ -556,7 +556,7 @@ public class RepeatableQuestGenerator(
var itemIdsWhitelisted = itemWhitelist
.Where(p => p.MinPlayerLevel <= pmcLevel)
.SelectMany(x => x.ItemIds)
.ToList(); //.Aggregate((a, p) => a.Concat(p.ItemIds), []);
.ToHashSet(); //.Aggregate((a, p) => a.Concat(p.ItemIds), []);
itemSelection = itemSelection.Where(
x =>
{
@@ -579,7 +579,7 @@ public class RepeatableQuestGenerator(
var itemIdsBlacklisted = itemBlacklist
.Where(p => p.MinPlayerLevel <= pmcLevel)
.SelectMany(x => x.ItemIds)
.ToList(); //.Aggregate(List<ItemsBlacklist> , (a, p) => a.Concat(p.ItemIds) );
.ToHashSet(); //.Aggregate(List<ItemsBlacklist> , (a, p) => a.Concat(p.ItemIds) );
itemSelection = itemSelection.Where(
x =>
+2 -2
View File
@@ -331,7 +331,7 @@ public class BotGeneratorHelper(
public ChooseRandomCompatibleModResult IsItemIncompatibleWithCurrentItems(List<Item> itemsEquipped, string tplToCheck, string equipmentSlot)
{
// Skip slots that have no incompatibilities
List<string> slotsToCheck = ["Scabbard", "Backpack", "SecureContainer", "Holster", "ArmBand"];
HashSet<string> slotsToCheck = ["Scabbard", "Backpack", "SecureContainer", "Holster", "ArmBand"];
if (slotsToCheck.Contains(equipmentSlot))
{
return new ChooseRandomCompatibleModResult
@@ -530,7 +530,7 @@ public class BotGeneratorHelper(
/// <param name="containersIdFull"></param>
/// <returns>ItemAddedResult result object</returns>
public ItemAddedResult AddItemWithChildrenToEquipmentSlot(
List<EquipmentSlots> equipmentSlots,
HashSet<EquipmentSlots> equipmentSlots,
string rootItemId,
string? rootItemTplId,
List<Item> itemWithChildren,
+3 -3
View File
@@ -19,7 +19,7 @@ public class BotHelper(
{
protected BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
protected PmcConfig _pmcConfig = _configServer.GetConfig<PmcConfig>();
protected List<string?> _pmcNames = ["usec", "bear", "pmc", "pmcbear", "pmcusec"];
protected HashSet<string?> _pmcNames = ["usec", "bear", "pmc", "pmcbear", "pmcusec"];
/// <summary>
/// Get a template object for the specified botRole from bots.types db
@@ -119,8 +119,8 @@ public class BotHelper(
/// <returns>True if role is PMC</returns>
public bool BotRoleIsPmc(string botRole)
{
List<string> ListToCheck = [_pmcConfig.UsecType.ToLower(), _pmcConfig.BearType.ToLower()];
return ListToCheck.Contains(
HashSet<string> listToCheck = [_pmcConfig.UsecType.ToLower(), _pmcConfig.BearType.ToLower()];
return listToCheck.Contains(
botRole.ToLower()
);
}
@@ -20,7 +20,7 @@ public class BotWeaponGeneratorHelper(
LocalisationService _localisationService
)
{
private readonly List<string> _magCheck = ["CylinderMagazine", "SpringDrivenCylinder"];
private readonly HashSet<string> _magCheck = ["CylinderMagazine", "SpringDrivenCylinder"];
/// <summary>
/// Get a randomized number of bullets for a specific magazine
@@ -35,7 +35,7 @@ public class BotWeaponGeneratorHelper(
double? chamberBulletCount = 0;
if (MagazineIsCylinderRelated(parentItem.Name))
{
var firstSlotAmmoTpl = magTemplate.Properties.Cartridges.FirstOrDefault()?.Props.Filters[0].Filter[0];
var firstSlotAmmoTpl = magTemplate.Properties.Cartridges.FirstOrDefault()?.Props.Filters[0].Filter.FirstOrDefault();
var ammoMaxStackSize = _itemHelper.GetItem(firstSlotAmmoTpl).Value?.Properties?.StackMaxSize ?? 1;
chamberBulletCount = ammoMaxStackSize == 1
? 1 // Rotating grenade launcher
@@ -110,7 +110,7 @@ public class BotWeaponGeneratorHelper(
string ammoTpl,
int cartridgeCount,
BotBaseInventory inventory,
List<EquipmentSlots> equipmentSlotsToAddTo
HashSet<EquipmentSlots> equipmentSlotsToAddTo
)
{
if (equipmentSlotsToAddTo is null)
@@ -12,7 +12,7 @@ public class HelloMessageHandler(
MailSendService _mailSendService,
RandomUtil _randomUtil) : IChatMessageHandler
{
protected List<string> _listOfMessages = ["hello", "hi", "sup", "yo", "hey", "bonjour"];
protected HashSet<string> _listOfGreetings = ["hello", "hi", "sup", "yo", "hey", "bonjour"];
public int GetPriority()
@@ -22,7 +22,7 @@ public class HelloMessageHandler(
public bool CanHandle(string message)
{
return _listOfMessages.Contains(message, StringComparer.OrdinalIgnoreCase);
return _listOfGreetings.Contains(message, StringComparer.OrdinalIgnoreCase);
}
public void Process(string sessionId, UserDialogInfo sptFriendUser, PmcData sender)
+1 -1
View File
@@ -210,7 +210,7 @@ public class HealthHelper(
protected void TransferPostRaidLimbEffectsToProfile(Dictionary<string, BodyPartHealth> postRaidBodyParts, PmcData profileData)
{
// Iterate over each body part
List<string> effectsToIgnore = ["Dehydration", "Exhaustion"];
HashSet<string> effectsToIgnore = ["Dehydration", "Exhaustion"];
foreach (var bodyPartId in postRaidBodyParts)
{
// Get effects on body part from profile
+2 -2
View File
@@ -38,7 +38,7 @@ public class HideoutHelper(
public const string BitcoinProductionId = "5d5c205bd582a50d042a3c0e";
public const string WaterCollector = "5d5589c1f934db045e6c5492";
public const int MaxSkillPoint = 5000;
protected List<string> _idCheck = [BitcoinFarm, CultistCircleCraftId];
protected HashSet<string> _idCheck = [BitcoinFarm, CultistCircleCraftId];
protected HideoutConfig hideoutConfig = _configServer.GetConfig<HideoutConfig>();
/// <summary>
@@ -1499,7 +1499,7 @@ public class HideoutHelper(
var wallBonuses = wallAreaDb.Stages.SelectMany(stage => stage.Value.Bonuses);
// Get all bonus Ids that the wall adds
List<string> bonusIdsToRemove = [];
HashSet<string> bonusIdsToRemove = [];
foreach (var bonus in wallBonuses)
{
bonusIdsToRemove.Add(bonus.Id);
+2 -2
View File
@@ -39,7 +39,7 @@ public class InventoryHelper(
)
{
// Item types to ignore inside `GetSizeByInventoryItemHash`
private readonly List<string> _itemBaseTypesToIgnore = [BaseClasses.BACKPACK, BaseClasses.SEARCHABLE_ITEM, BaseClasses.SIMPLE_CONTAINER];
private readonly HashSet<string> _itemBaseTypesToIgnore = [BaseClasses.BACKPACK, BaseClasses.SEARCHABLE_ITEM, BaseClasses.SIMPLE_CONTAINER];
protected InventoryConfig _inventoryConfig = _configServer.GetConfig<InventoryConfig>();
/// <summary>
@@ -1235,7 +1235,7 @@ public class InventoryHelper(
}
// Reset fast panel value if item was moved to a container other than pocket/rig (cant be used from fastpanel)
List<string> slots = ["pockets", "tacticalvest"];
HashSet<string> slots = ["pockets", "tacticalvest"];
var wasMovedToFastPanelAccessibleContainer = slots.Contains(
itemParent?.SlotId?.ToLower() ?? ""
);
+61 -50
View File
@@ -16,7 +16,6 @@ namespace Core.Helpers;
public class ItemHelper(
ISptLogger<ItemHelper> _logger,
HashUtil _hashUtil,
JsonUtil _jsonUtil,
RandomUtil _randomUtil,
MathUtil _mathUtil,
DatabaseService _databaseService,
@@ -28,7 +27,7 @@ public class ItemHelper(
ICloner _cloner
)
{
protected List<string> _defaultInvalidBaseTypes =
protected HashSet<string> _defaultInvalidBaseTypes =
[
BaseClasses.LOOT_CONTAINER,
BaseClasses.MOB_CONTAINER,
@@ -39,7 +38,7 @@ public class ItemHelper(
BaseClasses.POCKETS
];
protected List<string> _slotsAsStrings =
protected HashSet<string> _slotsAsStrings =
[
EquipmentSlots.Headwear.ToString(),
EquipmentSlots.Earpiece.ToString(),
@@ -57,6 +56,38 @@ public class ItemHelper(
EquipmentSlots.Scabbard.ToString()
];
protected HashSet<string> _dogTagTpls =
[
ItemTpl.BARTER_DOGTAG_BEAR,
ItemTpl.BARTER_DOGTAG_BEAR_EOD,
ItemTpl.BARTER_DOGTAG_BEAR_TUE,
ItemTpl.BARTER_DOGTAG_USEC,
ItemTpl.BARTER_DOGTAG_USEC_EOD,
ItemTpl.BARTER_DOGTAG_USEC_TUE,
ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_1,
ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_2,
ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_1,
ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_2
];
protected HashSet<string> _softInsertIds =
[
"groin",
"groin_back",
"soft_armor_back",
"soft_armor_front",
"soft_armor_left",
"soft_armor_right",
"shoulder_l",
"shoulder_r",
"collar",
"helmet_top",
"helmet_back",
"helmet_eyes",
"helmet_jaw",
"helmet_ears"
];
/**
* Does the provided pool of items contain the desired item
* @param itemPool Item collection to check
@@ -308,7 +339,7 @@ public class ItemHelper(
* @param tpl the template id / tpl
* @returns boolean; true for items that may be in player possession and not quest items
*/
public bool IsValidItem(string tpl, List<string> invalidBaseTypes = null)
public bool IsValidItem(string tpl, ICollection<string>? invalidBaseTypes = null)
{
var baseTypes = invalidBaseTypes ?? _defaultInvalidBaseTypes;
var itemDetails = GetItem(tpl);
@@ -403,8 +434,7 @@ public class ItemHelper(
}
// Check if item has slots that match soft insert name ids
var softInsertIds = GetSoftInsertSlotIds();
if (itemDbDetails.Value.Properties.Slots.Any(slot => softInsertIds.Contains(slot.Name.ToLower())))
if (itemDbDetails.Value.Properties.Slots.Any(slot => IsSoftInsertId(slot.Name.ToLower())))
{
return true;
}
@@ -414,32 +444,26 @@ public class ItemHelper(
// Get all soft insert slot ids
// @returns A List of soft insert ids (e.g. soft_armor_back, helmet_top)
public List<string> GetSoftInsertSlotIds()
public HashSet<string> GetSoftInsertSlotIds()
{
return
[
"groin",
"groin_back",
"soft_armor_back",
"soft_armor_front",
"soft_armor_left",
"soft_armor_right",
"shoulder_l",
"shoulder_r",
"collar",
"helmet_top",
"helmet_back",
"helmet_eyes",
"helmet_jaw",
"helmet_ears"
];
return _softInsertIds;
}
/// <summary>
/// Does the passed in slot id match a soft insert id
/// </summary>
/// <param name="slotId">Id to check</param>
/// <returns></returns>
public bool IsSoftInsertId(string slotId)
{
return _softInsertIds.Contains(slotId);
}
// Returns the items total price based on the handbook or as a fallback from the prices.json if the item is not
// found in the handbook. If the price can't be found at all return 0
// @param List<string> tpls item tpls to look up the price of
// @returns Total price in roubles
public double GetItemAndChildrenPrice(List<string> tpls)
public double GetItemAndChildrenPrice(IEnumerable<string> tpls)
{
// Run getItemPrice for each tpl in tpls array, return sum
return tpls.Aggregate(0, (total, tpl) => total + (int) GetItemPrice(tpl).GetValueOrDefault(0));
@@ -817,21 +841,7 @@ public class ItemHelper(
/// <returns>True if it is a dogtag.</returns>
public bool IsDogtag(string tpl)
{
List<string> dogTagTpls =
[
ItemTpl.BARTER_DOGTAG_BEAR,
ItemTpl.BARTER_DOGTAG_BEAR_EOD,
ItemTpl.BARTER_DOGTAG_BEAR_TUE,
ItemTpl.BARTER_DOGTAG_USEC,
ItemTpl.BARTER_DOGTAG_USEC_EOD,
ItemTpl.BARTER_DOGTAG_USEC_TUE,
ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_1,
ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_2,
ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_1,
ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_2
];
return dogTagTpls.Contains(tpl);
return _dogTagTpls.Contains(tpl);
}
/// <summary>
@@ -1332,7 +1342,7 @@ public class ItemHelper(
*/
public bool IsAttachmentAttached(Item item)
{
List<string> check = ["hideout", "main"];
HashSet<string> check = ["hideout", "main"];
return !(check.Contains(item.SlotId) || _slotsAsStrings.Contains(item.SlotId) || !int.TryParse(item.SlotId, out _));
}
@@ -1445,7 +1455,7 @@ public class ItemHelper(
public void AddCartridgesToAmmoBox(List<Item> ammoBox, TemplateItem ammoBoxDetails)
{
var ammoBoxMaxCartridgeCount = ammoBoxDetails.Properties.StackSlots[0].MaxCount;
var cartridgeTpl = ammoBoxDetails.Properties.StackSlots[0].Props.Filters[0].Filter[0];
var cartridgeTpl = ammoBoxDetails.Properties.StackSlots[0].Props.Filters[0].Filter.FirstOrDefault();
var cartridgeDetails = GetItem(cartridgeTpl);
var cartridgeMaxStackSize = cartridgeDetails.Value.Properties.StackMaxSize;
@@ -1496,7 +1506,7 @@ public class ItemHelper(
public void AddSingleStackCartridgesToAmmoBox(List<Item> ammoBox, TemplateItem ammoBoxDetails)
{
var ammoBoxMaxCartridgeCount = ammoBoxDetails.Properties?.StackSlots?[0].MaxCount ?? 0;
var cartridgeTpl = ammoBoxDetails.Properties?.StackSlots?[0].Props?.Filters?[0].Filter?[0];
var cartridgeTpl = ammoBoxDetails.Properties?.StackSlots?[0].Props?.Filters?[0].Filter?.FirstOrDefault();
ammoBox.Add(
CreateCartridges(
ammoBox[0].Id,
@@ -1684,7 +1694,7 @@ public class ItemHelper(
protected string? GetRandomValidCaliber(TemplateItem magTemplate)
{
var ammoTpls = magTemplate.Properties.Cartridges[0].Props.Filters[0].Filter;
List<string> calibers = ammoTpls
var calibers = ammoTpls
.Where(x => GetItem(x).Key)
.Select(x => GetItem(x).Value.Properties.Caliber)
.ToList();
@@ -1704,7 +1714,7 @@ public class ItemHelper(
string caliber,
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
string? fallbackCartridgeTpl = null,
List<string>? cartridgeWhitelist = null
ICollection<string>? cartridgeWhitelist = null
)
{
var ammos = staticAmmoDist.GetValueOrDefault(caliber, []);
@@ -1832,7 +1842,7 @@ public class ItemHelper(
)
{
var result = itemToAdd;
HashSet<string> incompatibleModTpls = new();
HashSet<string> incompatibleModTpls = [];
foreach (var slot in itemToAddTemplate.Properties.Slots)
{
// If only required mods is requested, skip non-essential
@@ -1856,7 +1866,7 @@ public class ItemHelper(
}
var itemPool = slot.Props.Filters[0].Filter ?? [];
if (itemPool.Count() == 0)
if (itemPool.Count == 0)
{
if (_logger.IsLogEnabled(LogLevel.Debug))
{
@@ -1896,7 +1906,8 @@ public class ItemHelper(
var modItemDbDetails = GetItem(modItemToAdd.Template).Value;
// Include conflicting items of newly added mod in pool to be used for next mod choice
modItemDbDetails.Properties.ConflictingItems.ForEach(item => incompatibleModTpls.Add(item));
incompatibleModTpls.UnionWith(modItemDbDetails.Properties.ConflictingItems);
}
return result;
@@ -1908,7 +1919,7 @@ public class ItemHelper(
/// <param name="possibleTpls">Tpls to randomly choose from</param>
/// <param name="incompatibleModTpls">Incompatible tpls to not allow</param>
/// <returns>Chosen tpl or undefined</returns>
public string GetCompatibleTplFromArray(List<string> possibleTpls, HashSet<string> incompatibleModTpls)
public string? GetCompatibleTplFromArray(HashSet<string> possibleTpls, HashSet<string> incompatibleModTpls)
{
if (!possibleTpls.Any())
{
@@ -1951,7 +1962,7 @@ public class ItemHelper(
// Get a list of slot names that hold removable plates
// Returns Array of slot ids (e.g. front_plate)
public List<string> GetRemovablePlateSlotIds()
public HashSet<string> GetRemovablePlateSlotIds()
{
return ["front_plate", "back_plate", "left_side_plate", "right_side_plate"];
}
+1 -1
View File
@@ -189,6 +189,6 @@ public class PresetHelper(
var tpls = defaultPreset is not null ? defaultPreset.Items.Select(item => item.Template) : [tpl];
// Get price of tpls
return _itemHelper.GetItemAndChildrenPrice(tpls.ToList());
return _itemHelper.GetItemAndChildrenPrice(tpls);
}
}
+1 -1
View File
@@ -199,7 +199,7 @@ public class ProfileHelper(
Version = _watermark.GetVersionTag(true),
Mods = new List<ModDetails>(),
ReceivedGifts = new List<ReceivedGift>(),
BlacklistedItemTemplates = new List<string>(),
BlacklistedItemTemplates = new HashSet<string>(),
FreeRepeatableRefreshUsedCount = new Dictionary<string, int>(),
Migrations = new Dictionary<string, long>(),
CultistRewards = new Dictionary<string, AcceptedCultistReward>(),
+3 -3
View File
@@ -38,7 +38,7 @@ public class QuestHelper(
ICloner _cloner
)
{
protected List<QuestStatusEnum> _newlyQuestCheck = [QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish];
protected HashSet<QuestStatusEnum> _newlyQuestCheck = [QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish];
protected QuestConfig _questConfig = _configServer.GetConfig<QuestConfig>();
/// <summary>
@@ -413,7 +413,7 @@ public class QuestHelper(
}
);
return GetQuestsWithOnlyLevelRequirementStartCondition(eligibleQuests.ToList());
return GetQuestsWithOnlyLevelRequirementStartCondition(eligibleQuests);
}
/**
@@ -674,7 +674,7 @@ public class QuestHelper(
* @param quests quests to process
* @returns quest list without conditions
*/
protected List<Quest> GetQuestsWithOnlyLevelRequirementStartCondition(List<Quest> quests)
protected List<Quest> GetQuestsWithOnlyLevelRequirementStartCondition(IEnumerable<Quest> quests)
{
return quests.Select(GetQuestWithOnlyLevelRequirementStartCondition).ToList();
}
+3 -3
View File
@@ -477,7 +477,7 @@ public class RagfairOfferHelper(
/// <returns>true if quest locked</returns>
public bool TraderOfferItemQuestLocked(RagfairOffer offer, Dictionary<string, TraderAssort> traderAssorts)
{
var itemIds = offer.Items.Select(x => x.Id).ToList();
var itemIds = offer.Items.Select(x => x.Id).ToHashSet();
//foreach (var item in offer.Items)
//{
// traderAssorts.TryGetValue(offer.User.Id, out var assorts);
@@ -574,9 +574,9 @@ public class RagfairOfferHelper(
return false;
}
protected List<string> GetLoyaltyLockedOffers(List<RagfairOffer> offers, PmcData pmcProfile)
protected HashSet<string> GetLoyaltyLockedOffers(List<RagfairOffer> offers, PmcData pmcProfile)
{
var loyaltyLockedOffers = new List<string>();
var loyaltyLockedOffers = new HashSet<string>();
foreach (var offer in offers.Where(offer => OfferIsFromTrader(offer)))
{
if (pmcProfile.TradersInfo.TryGetValue(offer.User.Id, out var traderDetails) &&
+1 -1
View File
@@ -131,7 +131,7 @@ public class TraderAssortHelper(
/// </summary>
/// <param name="assortToFilter">Trader assort to modify</param>
/// <param name="itemsTplsToRemove">Item TPLs the assort should not have</param>
protected void RemoveItemsFromAssort(TraderAssort assortToFilter, List<string> itemsTplsToRemove)
protected void RemoveItemsFromAssort(TraderAssort assortToFilter, HashSet<string> itemsTplsToRemove)
{
assortToFilter.Items = assortToFilter.Items.Where(
item =>
@@ -301,7 +301,7 @@ public record TaskConditionCounter
public record UnlockedInfo
{
[JsonPropertyName("unlockedProductionRecipe")]
public List<string>? UnlockedProductionRecipe
public HashSet<string>? UnlockedProductionRecipe
{
get;
set;
@@ -97,7 +97,7 @@ public record Reward
* Game editions whitelisted to get reward
*/
[JsonPropertyName("availableInGameEditions")]
public List<string>? AvailableInGameEditions
public HashSet<string>? AvailableInGameEditions
{
get;
set;
@@ -107,7 +107,7 @@ public record Reward
* Game editions blacklisted from getting reward
*/
[JsonPropertyName("notAvailableInGameEditions")]
public List<string>? NotAvailableInGameEditions
public HashSet<string>? NotAvailableInGameEditions
{
get;
set;
@@ -482,7 +482,7 @@ public record Props
}
[JsonPropertyName("ConflictingItems")]
public List<string>? ConflictingItems
public HashSet<string>? ConflictingItems
{
get;
set;
@@ -1509,7 +1509,7 @@ public record Props
}
[JsonPropertyName("weapFireType")]
public List<string>? WeapFireType
public HashSet<string>? WeapFireType
{
get;
set;
@@ -3604,7 +3604,7 @@ public record GridProps
public record GridFilter
{
[JsonPropertyName("Filter")]
public List<string>? Filter
public HashSet<string>? Filter
{
get;
set;
@@ -3755,7 +3755,7 @@ public record SlotFilter
}
[JsonPropertyName("Filter")]
public List<string>? Filter
public HashSet<string>? Filter
{
get;
set;
@@ -733,7 +733,7 @@ public record Spt
* item TPLs blacklisted from being sold on flea for this profile
*/
[JsonPropertyName("blacklistedItemTpls")]
public List<string>? BlacklistedItemTemplates
public HashSet<string>? BlacklistedItemTemplates
{
get;
set;
+1 -1
View File
@@ -7,7 +7,7 @@ public record Money
public const string DOLLARS = "5696686a4bdc2da3298b456a";
public const string GP = "5d235b4d86f7742e017bc88a";
public static List<string> GetMoneyTpls()
public static HashSet<string> GetMoneyTpls()
{
return [ROUBLES, EUROS, DOLLARS, GP];
}
@@ -82,7 +82,7 @@ public record GenerateEquipmentProperties
/// OPTIONAL - Do not generate mods for tpls in this array
/// </summary>
[JsonPropertyName("generateModsBlacklist")]
public List<string>? GenerateModsBlacklist
public HashSet<string>? GenerateModsBlacklist
{
get;
set;
@@ -160,7 +160,7 @@ public record BotConfig : BaseConfig
* Bot roles in this array will be given a dog tag on generation
*/
[JsonPropertyName("botRolesWithDogTags")]
public List<string> BotRolesWithDogTags
public HashSet<string> BotRolesWithDogTags
{
get;
set;
@@ -190,7 +190,7 @@ public record BotConfig : BaseConfig
* Tpls for low profile gas blocks
*/
[JsonPropertyName("lowProfileGasBlockTpls")]
public List<string> LowProfileGasBlockTpls
public HashSet<string> LowProfileGasBlockTpls
{
get;
set;
@@ -200,7 +200,7 @@ public record BotConfig : BaseConfig
* What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/
*/
[JsonPropertyName("disableLootOnBotTypes")]
public List<string> DisableLootOnBotTypes
public HashSet<string> DisableLootOnBotTypes
{
get;
set;
@@ -220,7 +220,7 @@ public record BotConfig : BaseConfig
* Bot roles that must have a unique name when generated vs other bots in raid
*/
[JsonPropertyName("botRolesThatMustHaveUniqueName")]
public List<string> BotRolesThatMustHaveUniqueName
public HashSet<string> BotRolesThatMustHaveUniqueName
{
get;
set;
@@ -702,7 +702,7 @@ public record EquipmentFilters
/// What additional slot ids should be seen as required when choosing a mod to add to a weapon
/// </summary>
[JsonPropertyName("weaponSlotIdsToMakeRequired")]
public List<string>? WeaponSlotIdsToMakeRequired
public HashSet<string>? WeaponSlotIdsToMakeRequired
{
get;
set;
@@ -929,7 +929,7 @@ public record EquipmentFilterDetails
/// Key: mod slot name e.g. mod_magazine, value: item tpls
/// </summary>
[JsonPropertyName("equipment")]
public Dictionary<string, List<string>>? Equipment
public Dictionary<string, HashSet<string>>? Equipment
{
get;
set;
@@ -939,7 +939,7 @@ public record EquipmentFilterDetails
/// Key: equipment slot name e.g. FirstPrimaryWeapon, value: item tpls
/// </summary>
[JsonPropertyName("gear")]
public Dictionary<EquipmentSlots, List<string>>? Gear
public Dictionary<EquipmentSlots, HashSet<string>>? Gear
{
get;
set;
@@ -949,7 +949,7 @@ public record EquipmentFilterDetails
/// Key: cartridge type e.g. Caliber23x75, value: item tpls
/// </summary>
[JsonPropertyName("cartridge")]
public Dictionary<string, List<string>>? Cartridge
public Dictionary<string, HashSet<string>>? Cartridge
{
get;
set;
@@ -335,7 +335,7 @@ public record ServerFeatures
* Keyed to profile type e.g. "Standard" or "SPT Developer"
*/
[JsonPropertyName("createNewProfileTypesBlacklist")]
public List<string> CreateNewProfileTypesBlacklist
public HashSet<string> CreateNewProfileTypesBlacklist
{
get;
set;
@@ -60,7 +60,7 @@ public record InventoryConfig : BaseConfig
* Container Tpls that should be deprioritised when choosing where to take money from for payments
*/
[JsonPropertyName("deprioritisedMoneyContainers")]
public List<string> DeprioritisedMoneyContainers
public HashSet<string> DeprioritisedMoneyContainers
{
get;
set;
@@ -51,7 +51,7 @@ public record LocationConfig : BaseConfig
/// Open zones to add to map
/// </summary>
[JsonPropertyName("openZones")]
public Dictionary<string, List<string>> OpenZones
public Dictionary<string, HashSet<string>> OpenZones
{
get;
set;
@@ -61,7 +61,7 @@ public record LocationConfig : BaseConfig
/// Key = map id, value = item tpls that should only have one forced loot spawn position
/// </summary>
[JsonPropertyName("forcedLootSingleSpawnById")]
public Dictionary<string, List<string>> ForcedLootSingleSpawnById
public Dictionary<string, HashSet<string>> ForcedLootSingleSpawnById
{
get;
set;
@@ -218,7 +218,7 @@ public record LocationConfig : BaseConfig
/// Containers to remove all children from when generating static/loose loot
/// </summary>
[JsonPropertyName("tplsToStripChildItemsFrom")]
public List<string> TplsToStripChildItemsFrom
public HashSet<string> TplsToStripChildItemsFrom
{
get;
set;
@@ -228,7 +228,7 @@ public record LocationConfig : BaseConfig
/// Map ids players cannot visit
/// </summary>
[JsonPropertyName("nonMaps")]
public List<string> NonMaps
public HashSet<string> NonMaps
{
get;
set;
@@ -370,7 +370,7 @@ public record SlotLootSettings
* Item Type whitelist
*/
[JsonPropertyName("whitelist")]
public List<string> Whitelist
public HashSet<string> Whitelist
{
get;
set;
@@ -380,7 +380,7 @@ public record SlotLootSettings
* Item tpl blacklist
*/
[JsonPropertyName("blacklist")]
public List<string> Blacklist
public HashSet<string> Blacklist
{
get;
set;
@@ -62,14 +62,14 @@ public record QuestConfig : BaseConfig
}
[JsonPropertyName("bearOnlyQuests")]
public List<string>? BearOnlyQuests
public HashSet<string>? BearOnlyQuests
{
get;
set;
}
[JsonPropertyName("usecOnlyQuests")]
public List<string>? UsecOnlyQuests
public HashSet<string>? UsecOnlyQuests
{
get;
set;
@@ -79,7 +79,7 @@ public record QuestConfig : BaseConfig
* Quests that the keyed game version do not see/access
*/
[JsonPropertyName("profileBlacklist")]
public Dictionary<string, List<string>>? ProfileBlacklist
public Dictionary<string, HashSet<string>>? ProfileBlacklist
{
get;
set;
@@ -89,7 +89,7 @@ public record QuestConfig : BaseConfig
* key=questid, gameversions that can see/access quest
*/
[JsonPropertyName("profileWhitelist")]
public Dictionary<string, List<string>>? ProfileWhitelist
public Dictionary<string, HashSet<string>>? ProfileWhitelist
{
get;
set;
@@ -266,7 +266,7 @@ public record RepeatableQuestConfig
* Item base types to block when generating rewards
*/
[JsonPropertyName("rewardBaseTypeBlacklist")]
public List<string>? RewardBaseTypeBlacklist
public HashSet<string>? RewardBaseTypeBlacklist
{
get;
set;
@@ -276,7 +276,7 @@ public record RepeatableQuestConfig
* Item tplIds to ignore when generating rewards
*/
[JsonPropertyName("rewardBlacklist")]
public List<string>? RewardBlacklist
public HashSet<string>? RewardBlacklist
{
get;
set;
@@ -228,7 +228,7 @@ public record Dynamic
[JsonPropertyName("ignoreQualityPriceVarianceBlacklist")]
/** Tpls that should not use the variable price system when their quality is < 100% (lower dura/uses = lower price) */
public List<string> IgnoreQualityPriceVarianceBlacklist
public HashSet<string> IgnoreQualityPriceVarianceBlacklist
{
get;
set;
@@ -306,7 +306,7 @@ public record Dynamic
[JsonPropertyName("showAsSingleStack")]
/** Item tpls that should be forced to sell as a single item */
public List<string> ShowAsSingleStack
public HashSet<string> ShowAsSingleStack
{
get;
set;
@@ -435,7 +435,7 @@ public record BarterDetails
* Item Tpls to never be turned into a barter
*/
[JsonPropertyName("itemTypeBlacklist")]
public List<string> ItemTypeBlacklist
public HashSet<string> ItemTypeBlacklist
{
get;
set;
@@ -578,7 +578,7 @@ public record RagfairBlacklist
/// Custom blacklist for item Tpls
/// </summary>
[JsonPropertyName("custom")]
public List<string> Custom
public HashSet<string> Custom
{
get;
set;
@@ -638,7 +638,7 @@ public record RagfairBlacklist
/// Custom category blacklist for parent Ids
/// </summary>
[JsonPropertyName("customItemCategoryList")]
public List<string> CustomItemCategoryList
public HashSet<string> CustomItemCategoryList
{
get;
set;
@@ -661,7 +661,7 @@ public record ArmorPlateBlacklistSettings
/// Item slots to NOT remove from items on flea
/// </summary>
[JsonPropertyName("ignoreSlots")]
public List<string> IgnoreSlots
public HashSet<string> IgnoreSlots
{
get;
set;
@@ -724,7 +724,7 @@ public record ArmorSettings
/// What slots are to be removed when removeRemovablePlateChance is true
/// </summary>
[JsonPropertyName("plateSlotIdToRemovePool")]
public List<string> PlateSlotIdToRemovePool
public HashSet<string>? PlateSlotIdToRemovePool
{
get;
set;
@@ -34,14 +34,14 @@ public record ScavCaseConfig : BaseConfig
}
[JsonPropertyName("rewardItemParentBlacklist")]
public List<string> RewardItemParentBlacklist
public HashSet<string> RewardItemParentBlacklist
{
get;
set;
}
[JsonPropertyName("rewardItemBlacklist")]
public List<string> RewardItemBlacklist
public HashSet<string> RewardItemBlacklist
{
get;
set;
@@ -250,7 +250,7 @@ public record FenceConfig
}
[JsonPropertyName("blacklist")]
public List<string> Blacklist
public HashSet<string> Blacklist
{
get;
set;
@@ -50,7 +50,7 @@ public record LootRequest
/// Item tpl blacklist to exclude
/// </summary>
[JsonPropertyName("itemBlacklist")]
public List<string>? ItemBlacklist
public HashSet<string>? ItemBlacklist
{
get;
set;
+2 -2
View File
@@ -171,7 +171,7 @@ public class AirdropService(
var itemsMatchingTypeBlacklist = _itemHelper.GetItems()
.Where(templateItem => !string.IsNullOrEmpty(templateItem.Parent))
.Where(templateItem => _itemHelper.IsOfBaseclasses(templateItem.Parent, itemTypeBlacklist))
.Select(templateItem => templateItem.Id);
.Select(templateItem => templateItem.Id).ToHashSet();
var itemBlacklist = new HashSet<string>();
itemBlacklist.UnionWith(lootSettingsByType.ItemBlacklist);
itemBlacklist.UnionWith(_itemFilterService.GetItemRewardBlacklist());
@@ -185,7 +185,7 @@ public class AirdropService(
ArmorPresetCount = lootSettingsByType.ArmorPresetCount,
ItemCount = lootSettingsByType.ItemCount,
WeaponCrateCount = lootSettingsByType.WeaponCrateCount,
ItemBlacklist = itemBlacklist.ToList(),
ItemBlacklist = itemBlacklist,
ItemTypeWhitelist = lootSettingsByType.ItemTypeWhitelist,
ItemLimits = lootSettingsByType.ItemLimits,
ItemStackLimits = lootSettingsByType.ItemStackLimits,
@@ -322,7 +322,7 @@ public class BotEquipmentFilterService
var botAmmo = baseBotNode.BotInventory.Ammo[ammoCaliberKvP.Key];
// Skip cartridge slot if blacklist doesn't exist / is empty
blacklist.Cartridge.TryGetValue(ammoCaliberKvP.Key, out List<string> cartridgeCaliberBlacklist);
blacklist.Cartridge.TryGetValue(ammoCaliberKvP.Key, out var cartridgeCaliberBlacklist);
if (cartridgeCaliberBlacklist is null || cartridgeCaliberBlacklist.Count == 0)
{
continue;
@@ -468,23 +468,6 @@ public class BotLootCacheService(
}
}
/// <summary>
/// Add unique items into combined pool
/// </summary>
/// <param name="poolToAddTo">Pool of items to add to</param>
/// <param name="itemsToAdd">items to add to combined pool if unique</param>
protected void AddUniqueItemsToPool(List<TemplateItem> poolToAddTo, List<TemplateItem> itemsToAdd)
{
if (poolToAddTo.Count() == 0)
{
poolToAddTo.AddRange(itemsToAdd);
return;
}
poolToAddTo.Concat(itemsToAdd);
poolToAddTo = poolToAddTo.Distinct().ToList();
}
protected void AddItemsToPool(Dictionary<string, double> poolToAddTo, Dictionary<string, double> poolOfItemsToAdd)
{
foreach (var tpl in poolOfItemsToAdd)
+1 -1
View File
@@ -44,7 +44,7 @@ public class BotNameService(
BotType botJsonTemplate,
BotGenerationDetails botGenerationDetails,
string botRole,
List<string>? uniqueRoles = null)
HashSet<string>? uniqueRoles = null)
{
var isPmc = botGenerationDetails.IsPmc;
+3 -3
View File
@@ -1376,7 +1376,7 @@ public class FenceService(
protected void RemoveRandomModsOfItem(List<Item> itemAndMods)
{
// Items to be removed from inventory
var toDelete = new List<string>();
var toDelete = new HashSet<string>();
// Find mods to remove from item that could've been scavenged by other players in-raid
foreach (var itemMod in itemAndMods)
@@ -1391,7 +1391,7 @@ public class FenceService(
}
// Remove item and its sub-items to prevent orphans
toDelete.AddRange(itemHelper.FindAndReturnChildrenByItems(itemAndMods, itemMod.Id));
toDelete.UnionWith(itemHelper.FindAndReturnChildrenByItems(itemAndMods, itemMod.Id));
}
}
@@ -1411,7 +1411,7 @@ public class FenceService(
* @param itemsBeingDeleted Current list of items on weapon being deleted
* @returns True if item will be removed
*/
protected bool PresetModItemWillBeRemoved(Item weaponMod, List<string> itemsBeingDeleted)
protected bool PresetModItemWillBeRemoved(Item weaponMod, HashSet<string> itemsBeingDeleted)
{
var slotIdsThatCanFail = traderConfig.Fence.PresetSlotsToRemoveChancePercent;
if (!slotIdsThatCanFail.TryGetValue(weaponMod.SlotId, out var removalChance) || removalChance == 0.0)
+11 -14
View File
@@ -27,10 +27,7 @@ public class ItemFilterService(
{
if (_itemBlacklistCache.Count == 0)
{
foreach (var item in _itemConfig.Blacklist)
{
_itemBlacklistCache.Add(item);
}
_itemBlacklistCache.UnionWith(_itemConfig.Blacklist);
}
return _itemBlacklistCache.Contains(tpl);
@@ -50,36 +47,36 @@ public class ItemFilterService(
* Get an array of items that should never be given as a reward to player
* @returns string array of item tpls
*/
public List<string> GetItemRewardBlacklist()
public HashSet<string> GetItemRewardBlacklist()
{
return _cloner.Clone(_itemConfig.RewardItemBlacklist).ToList();
return _cloner.Clone(_itemConfig.RewardItemBlacklist);
}
/**
* Get an array of item types that should never be given as a reward to player
* @returns string array of item base ids
*/
public List<string> GetItemRewardBaseTypeBlacklist()
public HashSet<string> GetItemRewardBaseTypeBlacklist()
{
return _cloner.Clone(_itemConfig.RewardItemTypeBlacklist).ToList();
return _cloner.Clone(_itemConfig.RewardItemTypeBlacklist);
}
/**
* Return every template id blacklisted in config/item.json
* @returns string array of blacklisted template ids
*/
public List<string> GetBlacklistedItems()
public HashSet<string> GetBlacklistedItems()
{
return _cloner.Clone(_itemConfig.Blacklist).ToList();
return _cloner.Clone(_itemConfig.Blacklist);
}
/**
* Return every template id blacklisted in config/item.json/lootableItemBlacklist
* @returns string array of blacklisted template ids
*/
public List<string> GetBlacklistedLootableItems()
public HashSet<string> GetBlacklistedLootableItems()
{
return _cloner.Clone(_itemConfig.LootableItemBlacklist).ToList();
return _cloner.Clone(_itemConfig.LootableItemBlacklist);
}
/**
@@ -96,9 +93,9 @@ public class ItemFilterService(
* Return boss items in config/item.json
* @returns string array of boss item template ids
*/
public List<string> GetBossItems()
public HashSet<string> GetBossItems()
{
return _cloner.Clone(_itemConfig.BossItems).ToList();
return _cloner.Clone(_itemConfig.BossItems).ToHashSet();
}
/**
@@ -221,7 +221,7 @@ public class LocationLifecycleService
// Find only scav extracts and overwrite existing exits with them
var scavExtracts = mapExtracts.Where(extract => extract.Side.ToLower() == "scav").ToList();
if (scavExtracts.Count() > 0)
if (scavExtracts.Count > 0)
// Scav extracts found, use them
{
locationData.Exits.AddRange(scavExtracts);
@@ -342,12 +342,6 @@ public class LocationLifecycleService
return locationBaseClone;
}
// If new spawn system is enabled, clear the spawn waves to prevent x2 spawns
if (locationBaseClone.NewSpawn is true)
{
locationBaseClone.Waves = [];
}
// Only requested base data, not loot
if (!generateLoot)
{
+2 -2
View File
@@ -28,8 +28,8 @@ public class MailSendService(
)
{
private const string _systemSenderId = "59e7125688a45068a6249071";
protected List<MessageType> _messageTypes = [MessageType.NPC_TRADER, MessageType.FLEAMARKET_MESSAGE];
protected List<string> _slotNames = ["hideout", "main"];
protected HashSet<MessageType> _messageTypes = [MessageType.NPC_TRADER, MessageType.FLEAMARKET_MESSAGE];
protected HashSet<string> _slotNames = ["hideout", "main"];
/**
* Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale
@@ -91,7 +91,7 @@ public class PmcChatResponseService(
}
// If killer wasn't a PMC, skip
var pmcTypes = new List<string>
var pmcTypes = new HashSet<string>
{
"pmcUSEC",
"pmcBEAR"
+1 -1
View File
@@ -126,7 +126,7 @@ public class PostDbLoadService(
private void RemoveNewBeginningRequirementFromPrestige()
{
var prestigeDb = _databaseService.GetTemplates().Prestige;
var newBeginningQuestId = new List<string>
var newBeginningQuestId = new HashSet<string>
{
"6761f28a022f60bb320f3e95",
"6761ff17cdc36bd66102e9d0"
@@ -103,7 +103,7 @@ public class RagfairLinkedItemService(
if (cylinderMod != null)
{
// Get the first cylinder filter tpl
var cylinderTpl = cylinderMod.Props?.Filters?[0].Filter?[0];
var cylinderTpl = cylinderMod.Props?.Filters?[0].Filter?.FirstOrDefault();
if (!string.IsNullOrEmpty(cylinderTpl))
{
// Get db data for cylinder tpl, add found slots info (camora_xxx) to linked items on revolver weapon
+2 -2
View File
@@ -594,7 +594,7 @@ public class RepairService(
// Skill < level 10 + repairing armor
if (
new List<SkillTypes>
new HashSet<SkillTypes>
{
SkillTypes.LightVests,
SkillTypes.HeavyVests
@@ -606,7 +606,7 @@ public class RepairService(
}
var skillSettings = globals.Configuration.SkillsSettings.GetAllPropsAsDict();
BuffSettings buffSettings = null;
BuffSettings? buffSettings = null;
switch (itemSkillType)
{
case SkillTypes.LightVests:
+15 -15
View File
@@ -26,7 +26,7 @@ public class SeasonalEventService(
{
private bool _christmasEventActive;
protected IReadOnlyList<string> _christmasEventItems =
protected HashSet<string> _christmasEventItems =
[
ItemTpl.ARMOR_6B13_M_ASSAULT_ARMOR_CHRISTMAS_EDITION,
ItemTpl.BACKPACK_SANTAS_BAG,
@@ -57,7 +57,7 @@ public class SeasonalEventService(
private List<SeasonalEvent> _currentlyActiveEvents = [];
private bool _halloweenEventActive;
protected IReadOnlyList<string> _halloweenEventItems =
protected HashSet<string> _halloweenEventItems =
[
ItemTpl.HEADWEAR_JACKOLANTERN_TACTICAL_PUMPKIN_HELMET,
ItemTpl.FACECOVER_FACELESS_MASK,
@@ -82,7 +82,7 @@ public class SeasonalEventService(
/// Get an array of christmas items found in bots inventories as loot
/// </summary>
/// <returns>array</returns>
public IEnumerable<string> GetChristmasEventItems()
public HashSet<string> GetChristmasEventItems()
{
return _christmasEventItems;
}
@@ -91,7 +91,7 @@ public class SeasonalEventService(
/// Get an array of halloween items found in bots inventories as loot
/// </summary>
/// <returns>array</returns>
public IEnumerable<string> GetHalloweenEventItems()
public HashSet<string> GetHalloweenEventItems()
{
return _halloweenEventItems;
}
@@ -131,17 +131,17 @@ public class SeasonalEventService(
/// or, if halloween and christmas are inactive, return both sets of items
/// </summary>
/// <returns>array of tpl strings</returns>
public List<string> GetInactiveSeasonalEventItems()
public HashSet<string> GetInactiveSeasonalEventItems()
{
var items = new List<string>();
var items = new HashSet<string>();
if (!ChristmasEventEnabled())
{
items.AddRange(_christmasEventItems);
items.UnionWith(_christmasEventItems);
}
if (!HalloweenEventEnabled())
{
items.AddRange(_halloweenEventItems);
items.UnionWith(_halloweenEventItems);
}
return items;
@@ -350,8 +350,8 @@ public class SeasonalEventService(
public void RemoveChristmasItemsFromBotInventory(BotTypeInventory botInventory, string botRole)
{
var christmasItems = GetChristmasEventItems();
List<EquipmentSlots> equipmentSlotsToFilter = [EquipmentSlots.FaceCover, EquipmentSlots.Headwear, EquipmentSlots.Backpack, EquipmentSlots.TacticalVest];
List<string> lootContainersToFilter = ["Backpack", "Pockets", "TacticalVest"];
HashSet<EquipmentSlots> equipmentSlotsToFilter = [EquipmentSlots.FaceCover, EquipmentSlots.Headwear, EquipmentSlots.Backpack, EquipmentSlots.TacticalVest];
HashSet<string> lootContainersToFilter = ["Backpack", "Pockets", "TacticalVest"];
// Remove christmas related equipment
foreach (var equipmentSlotKey in equipmentSlotsToFilter)
@@ -731,9 +731,9 @@ public class SeasonalEventService(
/// </summary>
/// <param name="locationInfections">Dict of locations with their infection percentage</param>
/// <returns>List of location ids</returns>
protected List<string> GetLocationsWithZombies(Dictionary<string, double> locationInfections)
protected HashSet<string> GetLocationsWithZombies(Dictionary<string, double> locationInfections)
{
var result = new List<string>();
var result = new HashSet<string>();
// Get only the locations with an infection above 0
var infectionKeys = locationInfections.Where(
@@ -743,7 +743,7 @@ public class SeasonalEventService(
// Convert the infected location id into its generic location id
foreach (var location in infectionKeys)
{
result.AddRange(GetLocationFromInfectedLocation(location.Key));
result.UnionWith(GetLocationFromInfectedLocation(location.Key));
}
return result;
@@ -794,7 +794,7 @@ public class SeasonalEventService(
/// </summary>
/// <param name="eventType">Seasonal event, e.g. HALLOWEEN/CHRISTMAS</param>
/// <param name="mapIdWhitelist">OPTIONAL - Maps to add bosses to</param>
protected void AddEventBossesToMaps(string eventType, List<string> mapIdWhitelist = null)
protected void AddEventBossesToMaps(string eventType, HashSet<string>? mapIdWhitelist = null)
{
if (!_seasonalEventConfig.EventBossSpawns.TryGetValue(eventType.ToLower(), out var botsToAddPerMap))
{
@@ -992,7 +992,7 @@ public class SeasonalEventService(
protected void EnableDancingTree()
{
var maps = _databaseService.GetLocations();
List<string> mapsToCheck = ["hideout", "base", "privatearea"];
HashSet<string> mapsToCheck = ["hideout", "base", "privatearea"];
foreach (var mapKvP in maps.GetDictionary())
{
// Skip maps that have no tree
+2 -2
View File
@@ -410,14 +410,14 @@ public class ItemTplGenerator(
private string GetAmmoBoxPrefix(TemplateItem item)
{
var ammoItem = item.Properties?.StackSlots?[0]?.Props?.Filters?[0]?.Filter?[0];
var ammoItem = item.Properties?.StackSlots?[0]?.Props?.Filters?[0]?.Filter?.FirstOrDefault();
return GetAmmoPrefix(items[ammoItem]);
}
private string GetMagazinePrefix(TemplateItem item)
{
var ammoItem = item.Properties?.Cartridges?[0]?.Props?.Filters?[0]?.Filter?[0];
var ammoItem = item.Properties?.Cartridges?[0]?.Props?.Filters?[0]?.Filter?.FirstOrDefault();
return GetAmmoPrefix(items[ammoItem]);
}