Ienumerable changes

This commit is contained in:
Chomp
2025-07-23 13:06:48 +01:00
parent 839e154adc
commit 1320f7d0ab
27 changed files with 176 additions and 158 deletions
@@ -379,7 +379,7 @@ public class RagfairController(
var offers = ragfairOfferService.GetOffersOfType(getPriceRequest.TemplateId);
// Offers exist for item, get averages of what's listed
if (offers?.Count > 0)
if (offers.Any())
{
// These get calculated while iterating through the list below
var minMax = new MinMax<double>(int.MaxValue, 0);
@@ -412,7 +412,7 @@ public class RagfairController(
}
protected double GetAveragePriceFromOffers(
List<RagfairOffer> offers,
IEnumerable<RagfairOffer> offers,
MinMax<double> minMax,
bool ignoreTraderOffers
)
@@ -197,7 +197,8 @@ public class BotEquipmentModGenerator(
);
switch (plateSlotFilteringOutcome.Result)
{
case Result.UNKNOWN_FAILURE or Result.NO_DEFAULT_FILTER:
case Result.UNKNOWN_FAILURE
or Result.NO_DEFAULT_FILTER:
if (logger.IsLogEnabled(LogLevel.Debug))
{
logger.Debug(
@@ -692,6 +693,7 @@ public class BotEquipmentModGenerator(
// Force spawn chance to be 100% to ensure it gets added
if (
modSlot == "mod_handguard"
&& modToAddTemplate.Properties?.Slots is not null
&& modToAddTemplate.Properties.Slots.Any(slot => slot.Name == "mod_handguard")
&& !request.Weapon.Any(item => item.SlotId == "mod_launcher")
)
@@ -772,6 +774,7 @@ public class BotEquipmentModGenerator(
if (
isRandomisableSlot
&& !containsModInPool
&& modToAddTemplate.Properties?.Slots is not null
&& modToAddTemplate.Properties.Slots.Any()
)
{
@@ -835,7 +838,13 @@ public class BotEquipmentModGenerator(
/// <returns>True it lacks cartridges/chamber slots</returns>
protected bool ItemLacksSlotsCartridgesAndChambers(TemplateItem item)
{
return item.Properties.Slots?.Count == 0
if (item.Properties is null)
{
return true;
}
return item.Properties.Slots is null
|| !item.Properties.Slots.Any()
&& item.Properties.Cartridges?.Count == 0
&& item.Properties.Chambers?.Count == 0;
}
@@ -854,7 +863,9 @@ public class BotEquipmentModGenerator(
)
{
// Can the stock hold child items
var hasSubSlots = modToAddTemplate.Properties.Slots?.Count > 0;
var hasSubSlots =
modToAddTemplate.Properties?.Slots is not null
&& modToAddTemplate.Properties.Slots.Any();
return (_stockSlots.Contains(modSlot) && hasSubSlots)
|| botEquipConfig.ForceStock.GetValueOrDefault(false);
@@ -1280,8 +1291,8 @@ public class BotEquipmentModGenerator(
var desiredMagazineTpls = modPool.Where(magTpl =>
{
var magazineDb = itemHelper.GetItem(magTpl).Value;
return magazineDb.Properties is not null
&& magazineDb.Properties.Cartridges.FirstOrDefault().MaxCount
return magazineDb.Properties?.Cartridges is not null
&& magazineDb.Properties.Cartridges.FirstOrDefault()?.MaxCount
>= minMagSizeFromSettings;
});
@@ -1546,7 +1557,7 @@ public class BotEquipmentModGenerator(
// Mod isn't in existing pool, only add if it has no children and exists inside parent filter
if (
(parentSlotCompatibleItems?.Contains(matchingModFromPreset.Template) ?? false)
&& itemHelper.GetItem(matchingModFromPreset.Template).Value.Properties.Slots?.Count == 0
&& !itemHelper.GetItem(matchingModFromPreset.Template).Value.Properties.Slots.Any()
)
{
// Chosen mod has no conflicts + no children + is in parent compat list
@@ -2070,22 +2081,23 @@ public class BotEquipmentModGenerator(
// Filter items that are not directly scopes OR mounts that do not hold the type of scope we allow for this weapon type
HashSet<MongoId> filteredScopesAndMods = [];
foreach (var item in scopes)
foreach (var scopeTpl in scopes)
{
// Mods is a scope, check base class is allowed
if (itemHelper.IsOfBaseclasses(item, whitelistedSightTypes))
if (itemHelper.IsOfBaseclasses(scopeTpl, whitelistedSightTypes))
{
// Add mod to allowed list
filteredScopesAndMods.Add(item);
filteredScopesAndMods.Add(scopeTpl);
continue;
}
// Edge case, what if item is a mount for a scope and not directly a scope?
// Check item is mount + has child items
var itemDetails = itemHelper.GetItem(item).Value;
var itemDetails = itemHelper.GetItem(scopeTpl).Value;
if (
itemHelper.IsOfBaseclass(item, BaseClasses.MOUNT)
itemDetails?.Properties?.Slots is not null
&& itemDetails.Properties.Slots.Any()
&& itemHelper.IsOfBaseclass(scopeTpl, BaseClasses.MOUNT)
)
{
// Check to see if mount has a scope slot (only include primary slot, ignore the rest like the backup sight slots)
@@ -2107,7 +2119,7 @@ public class BotEquipmentModGenerator(
)
// Add mod to allowed list
{
filteredScopesAndMods.Add(item);
filteredScopesAndMods.Add(scopeTpl);
}
}
}
@@ -615,7 +615,11 @@ public class BotInventoryGenerator(
settings.GenerateModsBlacklist != null
&& settings.GenerateModsBlacklist.Contains(pickedItemDb.Id);
// Does item have slots for sub-mods to be inserted into
if (pickedItemDb.Properties?.Slots?.Count > 0 && !itemIsOnGenerateModBlacklist)
if (
pickedItemDb.Properties?.Slots is not null
&& pickedItemDb.Properties.Slots.Any()
&& !itemIsOnGenerateModBlacklist
)
{
var childItemsToAdd = botEquipmentModGenerator.GenerateModsForEquipment(
[item],
@@ -285,7 +285,7 @@ public class BotLootGenerator(
var itemPriceLimits = GetSingleItemLootPriceLimits(botLevel, isPmc);
// Backpack - generate loot if they have one
if (containersBotHasAvailable.Contains(EquipmentSlots.Backpack))
if (containersBotHasAvailable.Contains(EquipmentSlots.Backpack) && backpackLootCount > 0)
{
// Add randomly generated weapon to PMC backpacks
if (isPmc && randomUtil.GetChance100(_pmcConfig.LooseWeaponInBackpackChancePercent))
@@ -506,9 +506,7 @@ public class BotLootGenerator(
)
{
// Loot pool has items
var poolSize = pool.Count;
if (poolSize <= 0)
if (pool.Count <= 0)
{
return;
}
@@ -905,9 +905,9 @@ public class BotWeaponGenerator(
/// <param name="weaponMods">Weapon with children.</param>
/// <param name="ubglMod">Underbarrrel grenade launcher item.</param>
/// <param name="ubglAmmoTpl">Grenade ammo template.</param>
protected void FillUbgl(IEnumerable<Item> weaponMods, Item ubglMod, MongoId ubglAmmoTpl)
protected void FillUbgl(List<Item> weaponMods, Item ubglMod, MongoId ubglAmmoTpl)
{
weaponMods.Append(
weaponMods.Add(
new Item
{
Id = new MongoId(),
@@ -77,7 +77,7 @@ public class FenceBaseAssortGenerator(
// Only allow rigs with no slots (carrier rigs)
if (
itemHelper.IsOfBaseclass(itemId, BaseClasses.VEST)
&& (rootItemDb.Properties?.Slots?.Count ?? 0) > 0
&& (rootItemDb.Properties?.Slots is not null && rootItemDb.Properties.Slots.Any())
)
{
continue;
@@ -271,7 +271,8 @@ public class FenceBaseAssortGenerator(
protected void AddChildrenToArmorModSlots(List<Item> armor, TemplateItem itemDbDetails)
{
// Armor has no mods, make no additions
var hasMods = itemDbDetails.Properties.Slots.Count > 0;
var hasMods =
itemDbDetails.Properties?.Slots is not null && itemDbDetails.Properties.Slots.Any();
if (!hasMods)
{
return;
@@ -171,7 +171,7 @@ public class LocationLootGenerator(
// Find all 100% spawn containers
var staticLootDist = mapData.StaticLoot;
var guaranteedContainers = GetGuaranteedContainers(allStaticContainersOnMapClone);
staticContainerCount += guaranteedContainers.Count;
staticContainerCount += guaranteedContainers.Count();
// Add loot to guaranteed containers and add to result
foreach (
@@ -188,12 +188,12 @@ public class LocationLootGenerator(
{
result.Add(containerWithLoot.Template);
staticLootItemCount += containerWithLoot.Template.Items.Count;
staticLootItemCount += containerWithLoot.Template.Items.Count();
}
if (_logger.IsLogEnabled(LogLevel.Debug))
{
_logger.Debug($"Added {guaranteedContainers.Count} guaranteed containers");
_logger.Debug($"Added {guaranteedContainers.Count()} guaranteed containers");
}
// Randomisation is turned off for location / globally
@@ -202,7 +202,7 @@ public class LocationLootGenerator(
if (_logger.IsLogEnabled(LogLevel.Debug))
{
_logger.Debug(
$"Container randomisation disabled, Adding: {staticRandomisableContainersOnMap.Count} containers to: {locationId}"
$"Container randomisation disabled, Adding: {staticRandomisableContainersOnMap.Count()} containers to: {locationId}"
);
}
@@ -217,7 +217,7 @@ public class LocationLootGenerator(
);
result.Add(containerWithLoot.Template);
staticLootItemCount += containerWithLoot.Template.Items.Count;
staticLootItemCount += containerWithLoot.Template.Items.Count();
}
_logger.Success($"A total of {staticLootItemCount} static items spawned");
@@ -320,7 +320,7 @@ public class LocationLootGenerator(
result.Add(containerWithLoot.Template);
staticContainerCount++;
staticLootItemCount += containerWithLoot.Template.Items.Count;
staticLootItemCount += containerWithLoot.Template.Items.Count();
}
}
@@ -346,19 +346,17 @@ public class LocationLootGenerator(
/// </summary>
/// <param name="staticContainers"></param>
/// <returns>StaticContainerData array</returns>
protected List<StaticContainerData> GetRandomisableContainersOnMap(
List<StaticContainerData> staticContainers
protected IEnumerable<StaticContainerData> GetRandomisableContainersOnMap(
IEnumerable<StaticContainerData> staticContainers
)
{
return staticContainers
.Where(staticContainer =>
return staticContainers.Where(staticContainer =>
staticContainer.Probability != 1
&& !staticContainer.Template.IsAlwaysSpawn.GetValueOrDefault(false)
&& !_locationConfig.ContainerRandomisationSettings.ContainerTypesToNotRandomise.Contains(
staticContainer.Template.Items.FirstOrDefault().Template
)
)
.ToList();
);
}
/// <summary>
@@ -366,19 +364,17 @@ public class LocationLootGenerator(
/// </summary>
/// <param name="staticContainersOnMap"></param>
/// <returns>IStaticContainerData array</returns>
protected List<StaticContainerData> GetGuaranteedContainers(
List<StaticContainerData> staticContainersOnMap
protected IEnumerable<StaticContainerData> GetGuaranteedContainers(
IEnumerable<StaticContainerData> staticContainersOnMap
)
{
return staticContainersOnMap
.Where(staticContainer =>
return staticContainersOnMap.Where(staticContainer =>
staticContainer.Probability == 1
|| staticContainer.Template.IsAlwaysSpawn.GetValueOrDefault(false)
|| _locationConfig.ContainerRandomisationSettings.ContainerTypesToNotRandomise.Contains(
staticContainer.Template.Items.FirstOrDefault().Template
)
)
.ToList();
);
}
/// <summary>
@@ -395,7 +391,7 @@ public class LocationLootGenerator(
{
var chosenContainerIds = new List<string>();
var containerIds = containerData.ContainerIdsWithProbability.Keys.ToList();
var containerIds = containerData.ContainerIdsWithProbability.Keys;
if (containerData.ChosenCount > containerIds.Count)
{
if (_logger.IsLogEnabled(LogLevel.Debug))
@@ -405,7 +401,7 @@ public class LocationLootGenerator(
);
}
return containerIds;
return containerIds.ToList();
}
// Create probability array with all possible container ids in this group and their relative probability of spawning
@@ -429,7 +425,7 @@ public class LocationLootGenerator(
/// <returns>dictionary keyed by groupId</returns>
protected Dictionary<string, ContainerGroupCount> GetGroupIdToContainerMappings(
StaticContainer staticContainerGroupData,
List<StaticContainerData> staticContainersOnMap
IEnumerable<StaticContainerData> staticContainersOnMap
)
{
// Create dictionary of all group ids and choose a count of containers the map will spawn of that group
@@ -532,7 +528,7 @@ public class LocationLootGenerator(
/// <returns>StaticContainerData</returns>
protected StaticContainerData AddLootToContainer(
StaticContainerData staticContainer,
List<StaticForced>? staticForced,
IEnumerable<StaticForced>? staticForced,
Dictionary<string, StaticLootDetails> staticLootDist,
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
string locationName
@@ -639,9 +635,8 @@ public class LocationLootGenerator(
};
// Add loot to container before returning
containerClone.Template.Items.AddRange(
items.Select(item => item.ToLootItem()).ToList() // Convert into correct output type first
);
var itemsToAdd = items.Select(item => item.ToLootItem()); // Convert into correct output type first
containerClone.Template.Items = containerClone.Template.Items.Union(itemsToAdd);
}
return containerClone;
@@ -776,16 +771,12 @@ public class LocationLootGenerator(
// Remove christmas items from loot data
if (!_seasonalEventService.ChristmasEventEnabled())
{
dynamicLootDist.Spawnpoints = dynamicLootDist
.Spawnpoints.Where(point =>
dynamicLootDist.Spawnpoints = dynamicLootDist.Spawnpoints.Where(point =>
!point.Template.Id.StartsWith("christmas", StringComparison.OrdinalIgnoreCase)
)
.ToList();
dynamicLootDist.SpawnpointsForced = dynamicLootDist
.SpawnpointsForced.Where(point =>
);
dynamicLootDist.SpawnpointsForced = dynamicLootDist.SpawnpointsForced.Where(point =>
!point.Template.Id.StartsWith("christmas", StringComparison.OrdinalIgnoreCase)
)
.ToList();
);
}
// Build the list of forced loot from both `SpawnpointsForced` and any point marked `IsAlwaysSpawn`
@@ -929,7 +920,7 @@ public class LocationLootGenerator(
}
// Spawn point has no items after filtering, skip
if (spawnPoint.Template.Items is null || spawnPoint.Template.Items.Count == 0)
if (spawnPoint.Template.Items is null || !spawnPoint.Template.Items.Any())
{
if (_logger.IsLogEnabled(LogLevel.Debug))
{
@@ -1031,7 +1022,7 @@ public class LocationLootGenerator(
/// <param name="staticAmmoDist"></param>
/// <returns>Collection of spawn points with forced loot in them</returns>
protected List<SpawnpointTemplate> GetForcedDynamicLoot(
List<Spawnpoint> forcedSpawnPoints,
IEnumerable<Spawnpoint> forcedSpawnPoints,
string locationName,
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist
)
@@ -1105,7 +1096,7 @@ public class LocationLootGenerator(
/// <returns> ContainerItem object </returns>
protected ContainerItem CreateDynamicLootItem(
SptLootItem chosenItem,
List<SptLootItem> lootItems,
IEnumerable<SptLootItem> lootItems,
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist
)
{
@@ -1282,17 +1273,20 @@ public class LocationLootGenerator(
var defaultPreset = _presetHelper.GetDefaultPreset(chosenTpl);
if (defaultPreset is not null)
{
var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList();
var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs();
presetAndModsClone.RemapRootItemId();
// Use original items parentId otherwise item doesn't get added to container correctly
presetAndModsClone.FirstOrDefault().ParentId = rootItem.ParentId;
items = presetAndModsClone;
items = presetAndModsClone.ToList();
}
else
{
// We make base item in calling method, no need to do it here
if ((armorDbTemplate.Properties.Slots?.Count ?? 0) > 0)
if (
armorDbTemplate.Properties?.Slots is not null
&& armorDbTemplate.Properties.Slots.Any()
)
{
items = _itemHelper.AddChildSlotItems(
items,
@@ -343,9 +343,9 @@ public class RagfairOfferGenerator(
/// Create multiple offers for items by using a unique list of items we've generated previously
/// </summary>
/// <param name="expiredOffers"> Optional, expired offers to regenerate </param>
public void GenerateDynamicOffers(List<List<Item>>? expiredOffers = null)
public void GenerateDynamicOffers(IEnumerable<List<Item>>? expiredOffers = null)
{
var replacingExpiredOffers = (expiredOffers?.Count ?? 0) > 0;
var replacingExpiredOffers = expiredOffers is not null && expiredOffers.Any();
var stopwatch = Stopwatch.StartNew();
// get assort items from param if they exist, otherwise grab freshly generated assorts
@@ -356,7 +356,7 @@ public class RagfairOfferGenerator(
if (logger.IsLogEnabled(LogLevel.Debug) && stopwatch.ElapsedMilliseconds > 0)
{
logger.Debug(
$"Took {stopwatch.ElapsedMilliseconds}ms to GetRagfairAssorts - {assortItemsToProcess.Count} items"
$"Took {stopwatch.ElapsedMilliseconds}ms to GetRagfairAssorts - {assortItemsToProcess.Count()} items"
);
}
@@ -209,11 +209,14 @@ public class ExplorationQuestGenerator(
/// <param name="locationKey">Map id (e.g. factory4_day)</param>
/// <param name="playerGroup">Pmc/Scav</param>
/// <returns>List of Exit objects</returns>
protected List<Exit>? GetLocationExitsForSide(string locationKey, PlayerGroup playerGroup)
protected IEnumerable<Exit>? GetLocationExitsForSide(
string locationKey,
PlayerGroup playerGroup
)
{
var mapExtracts = databaseService.GetLocation(locationKey.ToLowerInvariant())?.AllExtracts;
return mapExtracts?.Where(exit => exit.Side == Enum.GetName(playerGroup)).ToList();
return mapExtracts?.Where(exit => exit.Side == Enum.GetName(playerGroup));
}
/// <summary>
@@ -308,18 +311,16 @@ public class ExplorationQuestGenerator(
}
// Only get exits that have a greater than 0% chance to spawn
var exitPool = mapExits.Where(exit => exit.Chance > 0).ToList();
var exitPool = mapExits.Where(exit => exit.Chance > 0);
// Exclude exits with a requirement to leave (e.g. car extracts)
var possibleExits = exitPool
.Where(exit =>
var possibleExits = exitPool.Where(exit =>
repeatableConfig.QuestConfig.Exploration.SpecificExits.PassageRequirementWhitelist.Contains(
"PassageRequirement"
)
)
.ToList();
);
if (possibleExits.Count == 0)
if (!possibleExits.Any())
{
logger.Error(
localisationService.GetText(
@@ -332,7 +333,7 @@ public class ExplorationQuestGenerator(
}
// Choose one of the exits we filtered above
var chosenExit = randomUtil.DrawRandomFromList(possibleExits)[0];
var chosenExit = randomUtil.DrawRandomFromList(possibleExits.ToList())[0];
// Create a quest condition to leave raid via chosen exit
var exitCondition = GenerateQuestConditionCounter(chosenExit);
@@ -596,7 +596,7 @@ public class BotGeneratorHelper(
continue;
}
if (itemDbDetails?.Properties?.Grids?.Count == 0)
if (itemDbDetails?.Properties?.Grids is null || !itemDbDetails.Properties.Grids.Any())
// Container has no slots to hold items
{
continue;
@@ -611,15 +611,11 @@ public class BotGeneratorHelper(
// Iterate over each grid in the container and look for a big enough space for the item to be placed in
var currentGridCount = 1;
var totalSlotGridCount = itemDbDetails?.Properties?.Grids?.Count;
var totalSlotGridCount = itemDbDetails?.Properties?.Grids?.Count();
foreach (var slotGrid in itemDbDetails?.Properties?.Grids ?? [])
{
// Grid is empty, skip or item size is bigger than grid
if (
slotGrid.Props?.CellsH == 0
|| slotGrid.Props?.CellsV == 0
|| itemWidth * itemHeight > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH
)
if (IsGridSmallerThanItem(slotGrid, itemWidth, itemHeight))
{
continue;
}
@@ -711,6 +707,13 @@ public class BotGeneratorHelper(
return ItemAddedResult.NO_SPACE;
}
protected static bool IsGridSmallerThanItem(Grid slotGrid, int itemWidth, int itemHeight)
{
return slotGrid.Props?.CellsH == 0
|| slotGrid.Props?.CellsV == 0
|| itemWidth * itemHeight > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH;
}
/// <summary>
/// Take a list of items and check if they need children + add them
/// </summary>
@@ -44,7 +44,7 @@ public class BotWeaponGeneratorHelper(
chamberBulletCount =
ammoMaxStackSize == 1
? 1 // Rotating grenade launcher
: magTemplate.Properties.Slots.Count; // Shotguns/revolvers. We count the number of camoras as the _max_count of the magazine is 0
: magTemplate.Properties.Slots.Count(); // Shotguns/revolvers. We count the number of camoras as the _max_count of the magazine is 0
}
else if (parentItem.Id == BaseClasses.UBGL)
{
@@ -369,7 +369,8 @@ public class ItemHelper(
{
var itemTemplate = GetItem(itemTpl);
return itemTemplate.Value.Properties.Slots.Any(slot =>
return itemTemplate.Value?.Properties?.Slots is not null
&& itemTemplate.Value.Properties.Slots.Any(slot =>
_removablePlateSlotIds.Contains(slot.Name.ToLowerInvariant())
);
}
@@ -543,7 +544,7 @@ public class ItemHelper(
{
if (databaseService.GetItems().TryGetValue(itemTpl, out var item))
{
return item?.Properties?.Slots?.Count > 0;
return item.Properties?.Slots is not null && item.Properties.Slots.Any();
}
return false;
@@ -1534,7 +1535,7 @@ public class ItemHelper(
magTemplate.Id,
BaseClasses.SPRING_DRIVEN_CYLINDER
)
? magProps?.Slots?.Count // Edge case for rotating grenade launcher magazine
? magProps?.Slots?.Count() // Edge case for rotating grenade launcher magazine
: magProps?.Cartridges?.FirstOrDefault()?.MaxCount;
if (magazineCartridgeMaxCount is null)
@@ -2001,8 +2002,8 @@ public class ItemHelper(
var containerTemplate = GetItem(containerTpl).Value;
// Get height/width
var height = containerTemplate.Properties.Grids[0].Props.CellsV;
var width = containerTemplate.Properties.Grids[0].Props.CellsH;
var height = containerTemplate.Properties.Grids.First().Props.CellsV;
var width = containerTemplate.Properties.Grids.First().Props.CellsH;
return GetBlankContainerMap(width.Value, height.Value);
}
@@ -225,7 +225,7 @@ public class RagfairOfferHelper(
PmcData pmcData
)
{
var offersMap = new Dictionary<string, List<RagfairOffer>>();
var offersMap = new Dictionary<MongoId, List<RagfairOffer>>();
var offersToReturn = new List<RagfairOffer>();
var playerIsFleaBanned = pmcData.PlayerIsFleaBanned(timeUtil.GetTimeStamp());
var tieredFlea = _ragfairConfig.TieredFlea;
@@ -720,7 +720,7 @@ public record PveSettings
[JsonExtensionData]
public Dictionary<string, object>? ExtensionData { get; set; }
public List<string> AvailableVersions { get; set; }
public IEnumerable<string> AvailableVersions { get; set; }
public bool ModeEnabled { get; set; }
}
@@ -730,7 +730,7 @@ public record CoopSettings
[JsonExtensionData]
public Dictionary<string, object>? ExtensionData { get; set; }
public List<string> AvailableVersions { get; set; }
public IEnumerable<string> AvailableVersions { get; set; }
}
public record RunddansSettings
@@ -739,7 +739,7 @@ public record RunddansSettings
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("accessKeys")]
public List<string> AccessKeys { get; set; }
public IEnumerable<string> AccessKeys { get; set; }
[JsonPropertyName("active")]
public bool Active { get; set; }
@@ -751,7 +751,7 @@ public record RunddansSettings
public double ApplyFrozenEverySec { get; set; }
[JsonPropertyName("consumables")]
public List<string> Consumables { get; set; }
public IEnumerable<string> Consumables { get; set; }
[JsonPropertyName("drunkImmunitySec")]
public double DrunkImmunitySec { get; set; }
@@ -772,13 +772,13 @@ public record RunddansSettings
public double KnifeCritChanceToBreak { get; set; }
[JsonPropertyName("locations")]
public List<string> Locations { get; set; }
public IEnumerable<string> Locations { get; set; }
[JsonPropertyName("multitoolRepairSec")]
public double MultitoolRepairSec { get; set; }
[JsonPropertyName("nonExitsLocations")]
public List<string> NonExitsLocations { get; set; }
public IEnumerable<string> NonExitsLocations { get; set; }
[JsonPropertyName("rainForFrozen")]
public double RainForFrozen { get; set; }
@@ -790,7 +790,7 @@ public record RunddansSettings
public XY SecToBreak { get; set; }
[JsonPropertyName("sleighLocations")]
public List<string> SleighLocations { get; set; }
public IEnumerable<string> SleighLocations { get; set; }
}
public record SeasonActivity
@@ -1627,7 +1627,7 @@ public record CustomizationVoice
public string Voice { get; set; }
[JsonPropertyName("side")]
public List<string> Side { get; set; }
public IEnumerable<string> Side { get; set; }
[JsonPropertyName("isNotRandom")]
public bool IsNotRandom { get; set; }
@@ -2310,7 +2310,7 @@ public record Buff
[JsonPropertyName("SkillName")]
public string SkillName { get; set; }
public List<string> AppliesTo { get; set; }
public IEnumerable<string> AppliesTo { get; set; }
}
public record Tremor
@@ -3287,7 +3287,7 @@ public record BTRSettings
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("LocationsWithBTR")]
public List<string> LocationsWithBTR { get; set; }
public IEnumerable<string> LocationsWithBTR { get; set; }
[JsonPropertyName("BasePriceTaxi")]
public double BasePriceTaxi { get; set; }
@@ -3422,7 +3422,7 @@ public record PathConfig
public string ExitPoint { get; set; }
[JsonPropertyName("pathPoints")]
public List<string> PathPoints { get; set; }
public IEnumerable<string> PathPoints { get; set; }
[JsonPropertyName("once")]
public bool Once { get; set; }
@@ -3434,7 +3434,7 @@ public record PathConfig
public double CircleCount { get; set; }
[JsonPropertyName("skinType")]
public List<string> SkinType { get; set; }
public IEnumerable<string> SkinType { get; set; }
}
public record SquadSettings
@@ -4927,10 +4927,10 @@ public record RepairStrategy
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("BuffTypes")]
public List<string> BuffTypes { get; set; }
public IEnumerable<string> BuffTypes { get; set; }
[JsonPropertyName("Filter")]
public List<string> Filter { get; set; }
public IEnumerable<string> Filter { get; set; }
}
public record BotPreset
@@ -46,7 +46,7 @@ public record Location
/// All possible map extracts
/// </summary>
[JsonPropertyName("allExtracts")]
public Exit[] AllExtracts { get; set; }
public IEnumerable<Exit> AllExtracts { get; set; }
}
public record StaticContainer
@@ -133,10 +133,10 @@ public record StaticContainerDetails
public List<SpawnpointTemplate> StaticWeapons { get; set; }
[JsonPropertyName("staticContainers")]
public List<StaticContainerData> StaticContainers { get; set; }
public IEnumerable<StaticContainerData> StaticContainers { get; set; }
[JsonPropertyName("staticForced")]
public List<StaticForced> StaticForced { get; set; }
public IEnumerable<StaticForced> StaticForced { get; set; }
}
public record StaticForced
@@ -12,10 +12,10 @@ public record LooseLoot
public SpawnpointCount? SpawnpointCount { get; set; }
[JsonPropertyName("spawnpointsForced")]
public List<Spawnpoint>? SpawnpointsForced { get; set; }
public IEnumerable<Spawnpoint>? SpawnpointsForced { get; set; }
[JsonPropertyName("spawnpoints")]
public List<Spawnpoint>? Spawnpoints { get; set; }
public IEnumerable<Spawnpoint>? Spawnpoints { get; set; }
}
public record SpawnpointCount
@@ -65,7 +65,7 @@ public record SpawnpointTemplate
public bool? IsGroupPosition { get; set; }
[JsonPropertyName("GroupPositions")]
public List<GroupPosition>? GroupPositions { get; set; }
public IEnumerable<GroupPosition>? GroupPositions { get; set; }
[JsonPropertyName("Root")]
public string? Root
@@ -75,7 +75,7 @@ public record SpawnpointTemplate
}
[JsonPropertyName("Items")]
public List<SptLootItem>? Items { get; set; }
public IEnumerable<SptLootItem>? Items { get; set; }
}
public record SptLootItem : Item
@@ -123,7 +123,7 @@ public record Spawnpoint
public SpawnpointTemplate? Template { get; set; }
[JsonPropertyName("itemDistribution")]
public List<LooseLootItemDistribution>? ItemDistribution { get; set; }
public IEnumerable<LooseLootItemDistribution>? ItemDistribution { get; set; }
}
public record LooseLootItemDistribution
@@ -199,7 +199,7 @@ public record LockableComponent
[JsonExtensionData]
public Dictionary<string, object>? ExtensionData { get; set; }
public List<string>? KeyIds { get; set; }
public IEnumerable<string>? KeyIds { get; set; }
public bool? Locked { get; set; }
public LockableKeyComponent? KeyComponent { get; set; }
}
@@ -327,10 +327,10 @@ public record UpdSight
public Dictionary<string, object>? ExtensionData { get; set; }
[JsonPropertyName("ScopesCurrentCalibPointIndexes")]
public List<int>? ScopesCurrentCalibPointIndexes { get; set; }
public IEnumerable<int>? ScopesCurrentCalibPointIndexes { get; set; }
[JsonPropertyName("ScopesSelectedModes")]
public List<int>? ScopesSelectedModes { get; set; }
public IEnumerable<int>? ScopesSelectedModes { get; set; }
[JsonPropertyName("SelectedScope")]
public int? SelectedScope { get; set; }
@@ -353,10 +353,10 @@ public record Props
public bool? DogTagQualities { get; set; }
[JsonPropertyName("Grids")]
public List<Grid>? Grids { get; set; }
public IEnumerable<Grid>? Grids { get; set; }
[JsonPropertyName("Slots")]
public List<Slot>? Slots { get; set; }
public IEnumerable<Slot>? Slots { get; set; }
[JsonPropertyName("CanPutIntoDuringTheRaid")]
public bool? CanPutIntoDuringTheRaid { get; set; }
@@ -89,8 +89,8 @@ public class BotEquipmentModPoolService(
continue;
}
// Skip item without slots
if (item.Properties.Slots is null || item.Properties.Slots.Count == 0)
// No slots
if (item.Properties?.Slots is null || !item.Properties.Slots.Any())
{
continue;
}
@@ -120,7 +120,9 @@ public class BotEquipmentModPoolService(
}
var subItemDetails = itemHelper.GetItem(itemToAddTpl).Value;
var hasSubItemsToAdd = (subItemDetails?.Properties?.Slots?.Count ?? 0) > 0;
var hasSubItemsToAdd =
subItemDetails.Properties?.Slots is not null
&& subItemDetails.Properties.Slots.Any();
// Item has Slots + pool doesn't have value
if (hasSubItemsToAdd && !pool.ContainsKey(subItemDetails.Id))
@@ -221,7 +223,7 @@ public class BotEquipmentModPoolService(
// Get item from db
var itemDb = itemHelper.GetItem(itemTpl).Value;
if (itemDb.Properties.Slots is not null)
if (itemDb.Properties?.Slots is not null)
// Loop over slots flagged as 'required'
{
foreach (
@@ -122,7 +122,7 @@ public class BotWeaponModLimitService(
// Mount has one slot and it is for a mod_scope
if (
modLimits.Scope.Count >= modLimits.ScopeMax
&& modTemplate.Properties.Slots?.Count == 1
&& modTemplate.Properties?.Slots?.Count() == 1
&& itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
&& !itemHelper.IsOfBaseclass(modsParent.Id, BaseClasses.MOUNT)
&& modTemplate.Properties.Slots.Any(slot => slot.Name == "mod_scope")
@@ -149,7 +149,7 @@ public class BotWeaponModLimitService(
// Mod is a mount that can hold only flashlights ad limit is reached (don't want to add empty mounts if limit is reached)
if (
modLimits.Scope.Count >= modLimits.ScopeMax
&& modTemplate.Properties.Slots?.Count == 1
&& modTemplate.Properties?.Slots?.Count() == 1
&& itemHelper.IsOfBaseclass(modTemplate.Id, BaseClasses.MOUNT)
&& modTemplate.Properties.Slots.Any(slot => slot.Name == "mod_flashlight")
)
@@ -951,7 +951,8 @@ public class FenceService(
rootItemBeingAdded.Template,
[BaseClasses.ARMORED_EQUIPMENT, BaseClasses.SEARCHABLE_ITEM]
)
&& (itemDbDetails.Properties.Slots?.Count ?? 0) > 0;
&& itemDbDetails?.Properties?.Slots is not null
&& itemDbDetails.Properties.Slots.Any();
// Only one match and it's not medical or armored gear
if (matchingItems.Count == 1 && !(isMedical || isGearAndHasSlots))
@@ -288,7 +288,7 @@ public class CustomItemService(
protected void AddToWeaponShelf(string newItemId)
{
// Ids for wall stashes in db
List<string> wallStashIds =
List<MongoId> wallStashIds =
[
ItemTpl.HIDEOUTAREACONTAINER_WEAPONSTAND_STASH_1,
ItemTpl.HIDEOUTAREACONTAINER_WEAPONSTAND_STASH_2,
@@ -299,7 +299,7 @@ public class CustomItemService(
var wall = itemHelper.GetItem(wallId);
if (wall.Key)
{
wall.Value.Properties.Grids[0].Props.Filters[0].Filter.Add(newItemId);
wall.Value.Properties.Grids.First().Props.Filters[0].Filter.Add(newItemId);
}
}
}
@@ -391,10 +391,13 @@ public class PostDbLoadService(
if (existingLootPosition is not null)
{
existingLootPosition.Template.Items.AddRange(
existingLootPosition.Template.Items =
existingLootPosition.Template.Items.Union(
positionToAdd.Template.Items
);
existingLootPosition.ItemDistribution.AddRange(
existingLootPosition.ItemDistribution =
existingLootPosition.ItemDistribution.Union(
positionToAdd.ItemDistribution
);
@@ -402,7 +405,7 @@ public class PostDbLoadService(
}
// New position, add entire object
looselootData.Spawnpoints.Add(positionToAdd);
looselootData.Spawnpoints = looselootData.Spawnpoints.Append(positionToAdd);
}
return looselootData;
@@ -153,7 +153,7 @@ public class RagfairLinkedItemService(
var result = new HashSet<MongoId>();
var slots = item.Properties?.Slots;
if (slots is null || slots.Count == 0)
if (slots is null || !slots.Any())
{
// No slots, skip
return result;
@@ -49,7 +49,7 @@ public class RagfairOfferService(
return ragfairOfferHolder.GetOfferById(offerId);
}
public List<RagfairOffer>? GetOffersOfType(MongoId templateId)
public IEnumerable<RagfairOffer>? GetOffersOfType(MongoId templateId)
{
return ragfairOfferHolder.GetOffersByTemplate(templateId);
}
@@ -68,7 +68,7 @@ public class RagfairOfferHolder(
/// </summary>
/// <param name="templateId">Tpl to get offers for</param>
/// <returns>RagfairOffer list</returns>
public List<RagfairOffer>? GetOffersByTemplate(MongoId templateId)
public IEnumerable<RagfairOffer>? GetOffersByTemplate(MongoId templateId)
{
// Get the offerIds we want to return
if (!_offersByTemplate.TryGetValue(templateId, out var offerIds))
@@ -76,7 +76,7 @@ public class RagfairOfferHolder(
return null;
}
var result = _offersById.Where(x => offerIds.Contains(x.Key)).Select(x => x.Value).ToList();
var result = _offersById.Where(x => offerIds.Contains(x.Key)).Select(x => x.Value);
return result;
}
@@ -86,7 +86,7 @@ public class RagfairOfferHolder(
/// </summary>
/// <param name="traderId">Id of trader to get offers for</param>
/// <returns>RagfairOffer list</returns>
public List<RagfairOffer> GetOffersByTrader(MongoId traderId)
public IEnumerable<RagfairOffer> GetOffersByTrader(MongoId traderId)
{
if (!_offersByTrader.TryGetValue(traderId, out var offerIds))
{
@@ -95,8 +95,7 @@ public class RagfairOfferHolder(
return offerIds
.Select(offerId => _offersById.GetValueOrDefault(offerId))
.Where(offer => offer != null)
.ToList();
.Where(offer => offer != null);
}
/// <summary>
@@ -117,7 +116,7 @@ public class RagfairOfferHolder(
/// Add a collection of offers to ragfair
/// </summary>
/// <param name="offers">Offers to add</param>
public void AddOffers(List<RagfairOffer> offers)
public void AddOffers(IEnumerable<RagfairOffer> offers)
{
foreach (var offer in offers)
{
@@ -326,7 +325,7 @@ public class RagfairOfferHolder(
/// Get an array of arrays of expired offer items + children
/// </summary>
/// <returns>Expired offer assorts</returns>
public List<List<Item>> GetExpiredOfferItems()
public IEnumerable<List<Item>> GetExpiredOfferItems()
{
lock (_expiredOfferIdsLock)
{
@@ -1,7 +1,6 @@
using MongoIdTplGenerator.Utils;
using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -498,7 +497,7 @@ public class ItemTplMongoIdGenerator(
// Add grid size for lootable containers
if (itemHelper.IsOfBaseclass(item.Id, BaseClasses.LOOT_CONTAINER))
{
return $"{item.Properties.Grids[0]?.Props.CellsH}X{item.Properties.Grids[0]?.Props.CellsV}";
return $"{item.Properties.Grids.First()?.Props.CellsH}X{item.Properties.Grids.First()?.Props.CellsV}";
}
// Add ammo caliber to conflicting weapons