Convert TemplateItem to MongoId (#436)
* Convert TemplateItem to MongoId * Push new extensions * Handle null mongoid's being passed to regex * Handle null strings, fixes item events * Updated loot generation to work with new property `composedKey` Fixed typo in `SlotId` * Fix missing method after merge * Remove duplicately named MongoIDExtensions? * Fixed location loot generation to handle impending loot json changes * Updated location JSONs with new properties (excluding lighthouse loose loot) * Fixed build issue with ItemTplGenerator * use correct handing for new mongo ids * Added helper method to improve readability --------- Co-authored-by: Chomp <dev@dev.sp-tarkov.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Generators;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Inventory;
|
||||
@@ -300,7 +301,7 @@ public class InventoryController(
|
||||
/// <param name="itemTpls">Inspected item tpls</param>
|
||||
/// <param name="fullProfile">Profile to add xp to</param>
|
||||
protected void FlagItemsAsInspectedAndRewardXp(
|
||||
IEnumerable<string> itemTpls,
|
||||
IEnumerable<MongoId> itemTpls,
|
||||
SptProfile fullProfile
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
|
||||
namespace SPTarkov.Server.Core.Extensions
|
||||
@@ -320,5 +321,26 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
|
||||
return result.Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an Item to SptLootItem
|
||||
/// </summary>
|
||||
/// <param name="item">Item to convert</param>
|
||||
/// <returns>Converted SptLootItem</returns>
|
||||
public static SptLootItem ToLootItem(this Item item)
|
||||
{
|
||||
return new SptLootItem
|
||||
{
|
||||
ComposedKey = null,
|
||||
Id = item.Id,
|
||||
Template = item.Template,
|
||||
Upd = item.Upd,
|
||||
ParentId = item.ParentId,
|
||||
SlotId = item.SlotId,
|
||||
Location = item.Location,
|
||||
Desc = item.Desc,
|
||||
ExtensionData = item.ExtensionData,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -2,8 +2,14 @@
|
||||
|
||||
namespace SPTarkov.Server.Core.Extensions
|
||||
{
|
||||
public static class MongoIDExtensions
|
||||
public static class MongoIdExtensions
|
||||
{
|
||||
//Temporary, but necessary
|
||||
public static IEnumerable<MongoId> ToMongoIds(this IEnumerable<string> source)
|
||||
{
|
||||
return source.Select(s => (MongoId)s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="MongoId"/> is a valid 24-character hexadecimal string,
|
||||
/// which is the standard format for MongoDB ObjectIds.
|
||||
@@ -1,21 +1,22 @@
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
|
||||
namespace SPTarkov.Server.Core.Extensions
|
||||
{
|
||||
public static class TemplateItemExtensions
|
||||
{
|
||||
public static IEnumerable<TemplateItem> OfClass(
|
||||
this Dictionary<string, TemplateItem> templates,
|
||||
params string[] baseClasses
|
||||
this Dictionary<MongoId, TemplateItem> templates,
|
||||
params MongoId[] baseClasses
|
||||
)
|
||||
{
|
||||
return templates.Where(x => baseClasses.Contains(x.Value.Parent)).Select(x => x.Value);
|
||||
}
|
||||
|
||||
public static IEnumerable<TemplateItem> OfClass(
|
||||
this Dictionary<string, TemplateItem> templates,
|
||||
this Dictionary<MongoId, TemplateItem> templates,
|
||||
Func<TemplateItem, bool> pred,
|
||||
params string[] baseClasses
|
||||
params MongoId[] baseClasses
|
||||
)
|
||||
{
|
||||
return templates
|
||||
|
||||
@@ -301,7 +301,7 @@ public class BotEquipmentModGenerator(
|
||||
public FilterPlateModsForSlotByLevelResult FilterPlateModsForSlotByLevel(
|
||||
GenerateEquipmentProperties settings,
|
||||
string modSlot,
|
||||
HashSet<string> existingPlateTplPool,
|
||||
HashSet<MongoId> existingPlateTplPool,
|
||||
TemplateItem armorItem
|
||||
)
|
||||
{
|
||||
@@ -1282,9 +1282,9 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="modSpawnRequest">Request data</param>
|
||||
/// <param name="modPool">Pool of magazine tpls to filter</param>
|
||||
/// <returns>Filtered pool of magazine tpls</returns>
|
||||
public IEnumerable<string> GetFilteredMagazinePoolByCapacity(
|
||||
public IEnumerable<MongoId> GetFilteredMagazinePoolByCapacity(
|
||||
ModToSpawnRequest modSpawnRequest,
|
||||
HashSet<string> modPool
|
||||
HashSet<MongoId> modPool
|
||||
)
|
||||
{
|
||||
var weaponTpl = modSpawnRequest.Weapon.FirstOrDefault().Template;
|
||||
@@ -1325,7 +1325,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <returns>Chosen weapon details</returns>
|
||||
public ChooseRandomCompatibleModResult GetCompatibleWeaponModTplForSlotFromPool(
|
||||
ModToSpawnRequest request,
|
||||
HashSet<string> modPool,
|
||||
HashSet<MongoId> modPool,
|
||||
Slot parentSlot,
|
||||
ModSpawn? choiceTypeEnum,
|
||||
List<Item> weapon,
|
||||
@@ -1369,7 +1369,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="weapon">Weapon mods at current time</param>
|
||||
/// <returns>IChooseRandomCompatibleModResult</returns>
|
||||
public ChooseRandomCompatibleModResult GetCompatibleModFromPool(
|
||||
HashSet<string> modPool,
|
||||
HashSet<MongoId> modPool,
|
||||
ModSpawn? modSpawnType,
|
||||
List<Item> weapon
|
||||
)
|
||||
@@ -1469,7 +1469,10 @@ 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 HashSet<string> GetFilteredModPool(HashSet<string> modPool, HashSet<string> tplBlacklist)
|
||||
public HashSet<MongoId> GetFilteredModPool(
|
||||
HashSet<MongoId> modPool,
|
||||
HashSet<MongoId> tplBlacklist
|
||||
)
|
||||
{
|
||||
return modPool.Where(tpl => !tplBlacklist.Contains(tpl)).ToHashSet();
|
||||
}
|
||||
@@ -1483,7 +1486,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="weaponTemplate">Mods root parent (weapon/equipment)</param>
|
||||
/// <returns>Array of mod tpls</returns>
|
||||
public HashSet<string>? GetModPoolForSlot(
|
||||
public HashSet<MongoId>? GetModPoolForSlot(
|
||||
ModToSpawnRequest request,
|
||||
TemplateItem weaponTemplate
|
||||
)
|
||||
@@ -1518,7 +1521,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="weaponTemplate"></param>
|
||||
/// <returns>Hashset of mods keyed by slot</returns>
|
||||
public HashSet<string> GetModPoolForDefaultSlot(
|
||||
public HashSet<MongoId> GetModPoolForDefaultSlot(
|
||||
ModToSpawnRequest request,
|
||||
TemplateItem weaponTemplate
|
||||
)
|
||||
@@ -1821,7 +1824,7 @@ public class BotEquipmentModGenerator(
|
||||
public void AddCompatibleModsForProvidedMod(
|
||||
string desiredSlotName,
|
||||
TemplateItem modTemplate,
|
||||
IDictionary<string, Dictionary<string, HashSet<string>>> modPool,
|
||||
IDictionary<string, Dictionary<string, HashSet<MongoId>>> modPool,
|
||||
EquipmentFilterDetails botEquipBlacklist
|
||||
)
|
||||
{
|
||||
@@ -1853,7 +1856,7 @@ public class BotEquipmentModGenerator(
|
||||
);
|
||||
}
|
||||
|
||||
modPool.TryAdd(modTemplate.Id, new Dictionary<string, HashSet<string>>());
|
||||
modPool.TryAdd(modTemplate.Id, new Dictionary<string, HashSet<MongoId>>());
|
||||
|
||||
modPool[modTemplate.Id][desiredSlotObject.Name] = supportedSubModsSet;
|
||||
}
|
||||
@@ -1865,7 +1868,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="modSlot">Slot item should fit in</param>
|
||||
/// <param name="botEquipBlacklist">Equipment that should not be picked</param>
|
||||
/// <returns>Array of compatible items for that slot</returns>
|
||||
public HashSet<string> GetDynamicModPool(
|
||||
public HashSet<MongoId> GetDynamicModPool(
|
||||
string parentItemId,
|
||||
string modSlot,
|
||||
EquipmentFilterDetails botEquipBlacklist
|
||||
@@ -1905,8 +1908,8 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="botEquipBlacklist">Equipment blacklist details for bot level range</param>
|
||||
/// <param name="modSlot">Mod slot mods belong to</param>
|
||||
/// <returns>New set of tpls not in blacklist(s)</returns>
|
||||
public HashSet<string> FilterModsByBlacklist(
|
||||
HashSet<string> modTplPool,
|
||||
public HashSet<MongoId> FilterModsByBlacklist(
|
||||
HashSet<MongoId> modTplPool,
|
||||
EquipmentFilterDetails? botEquipBlacklist,
|
||||
string modSlot
|
||||
)
|
||||
@@ -1947,7 +1950,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="cylinderMagTemplate">The CylinderMagazine's template</param>
|
||||
public void FillCamora(
|
||||
List<Item> items,
|
||||
Dictionary<string, Dictionary<string, HashSet<string>>> modPool,
|
||||
Dictionary<string, Dictionary<string, HashSet<MongoId>>> modPool,
|
||||
string cylinderMagParentId,
|
||||
TemplateItem cylinderMagTemplate
|
||||
)
|
||||
@@ -1965,7 +1968,7 @@ public class BotEquipmentModGenerator(
|
||||
);
|
||||
|
||||
// Attempt to generate camora slots for item
|
||||
modPool[cylinderMagTemplate.Id] = new Dictionary<string, HashSet<string>>();
|
||||
modPool[cylinderMagTemplate.Id] = new Dictionary<string, HashSet<MongoId>>();
|
||||
foreach (var camora in camoraSlots)
|
||||
{
|
||||
modPool[cylinderMagTemplate.Id][camora.Name] = camora.Props.Filters?[
|
||||
@@ -1976,7 +1979,7 @@ public class BotEquipmentModGenerator(
|
||||
itemModPool = modPool[cylinderMagTemplate.Id];
|
||||
}
|
||||
|
||||
ExhaustableArray<string>? exhaustableModPool = null;
|
||||
ExhaustableArray<MongoId>? exhaustableModPool = null;
|
||||
var modSlot = "cartridges";
|
||||
const string camoraFirstSlot = "camora_000";
|
||||
if (itemModPool.TryGetValue(modSlot, out var value))
|
||||
@@ -2046,7 +2049,7 @@ public class BotEquipmentModGenerator(
|
||||
/// </summary>
|
||||
/// <param name="camorasWithShells">Dictionary of camoras we want to merge into one array</param>
|
||||
/// <returns>String array of shells for multiple camora sources</returns>
|
||||
public HashSet<string> MergeCamoraPools(Dictionary<string, HashSet<string>> camorasWithShells)
|
||||
public HashSet<MongoId> MergeCamoraPools(Dictionary<string, HashSet<MongoId>> camorasWithShells)
|
||||
{
|
||||
return camorasWithShells.SelectMany(shellKvP => shellKvP.Value).Distinct().ToHashSet();
|
||||
}
|
||||
@@ -2060,9 +2063,9 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="scopes">Full scope pool</param>
|
||||
/// <param name="botWeaponSightWhitelist">Whitelist of scope types by weapon base type</param>
|
||||
/// <returns>Array of scope tpls that have been filtered to just ones allowed for that weapon type</returns>
|
||||
public HashSet<string> FilterSightsByWeaponType(
|
||||
public HashSet<MongoId> FilterSightsByWeaponType(
|
||||
Item weapon,
|
||||
HashSet<string> scopes,
|
||||
HashSet<MongoId> scopes,
|
||||
Dictionary<string, List<string>> botWeaponSightWhitelist
|
||||
)
|
||||
{
|
||||
@@ -2087,7 +2090,7 @@ 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<string> filteredScopesAndMods = [];
|
||||
HashSet<MongoId> filteredScopesAndMods = [];
|
||||
foreach (var item in scopes)
|
||||
{
|
||||
// Mods is a scope, check base class is allowed
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Frozen;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Match;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -645,9 +646,9 @@ 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(
|
||||
public Dictionary<string, HashSet<MongoId>> GetFilteredDynamicModsForItem(
|
||||
string itemTpl,
|
||||
Dictionary<string, HashSet<string>> equipmentBlacklist
|
||||
Dictionary<string, HashSet<MongoId>> equipmentBlacklist
|
||||
)
|
||||
{
|
||||
var modPool = _botEquipmentModPoolService.GetModsForGearSlot(itemTpl);
|
||||
|
||||
@@ -2,6 +2,7 @@ using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Generators.WeaponGen;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -753,7 +754,9 @@ public class BotWeaponGenerator(
|
||||
/// </summary>
|
||||
/// <param name="weaponTemplate">Weapon db template to get cartridges for</param>
|
||||
/// <returns>List of cartridge tpls</returns>
|
||||
protected HashSet<string> GetCompatibleCartridgesFromWeaponTemplate(TemplateItem weaponTemplate)
|
||||
protected HashSet<MongoId> GetCompatibleCartridgesFromWeaponTemplate(
|
||||
TemplateItem weaponTemplate
|
||||
)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(weaponTemplate);
|
||||
|
||||
@@ -775,7 +778,7 @@ public class BotWeaponGenerator(
|
||||
/// <param name="weaponTemplate">Weapon db template to get magazine cartridges for</param>
|
||||
/// <returns>Hashset of cartridge tpls</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when weaponTemplate is null.</exception>
|
||||
protected HashSet<string> GetCompatibleCartridgesFromMagazineTemplate(
|
||||
protected HashSet<MongoId> GetCompatibleCartridgesFromMagazineTemplate(
|
||||
TemplateItem weaponTemplate
|
||||
)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace SPTarkov.Server.Core.Generators;
|
||||
public class LocationLootGenerator(
|
||||
ISptLogger<LocationLootGenerator> _logger,
|
||||
RandomUtil _randomUtil,
|
||||
MathUtil _mathUtil,
|
||||
HashUtil _hashUtil,
|
||||
ItemHelper _itemHelper,
|
||||
DatabaseService _databaseService,
|
||||
@@ -198,15 +197,12 @@ public class LocationLootGenerator(
|
||||
}
|
||||
|
||||
// Randomisation is turned off for location / globally
|
||||
if (
|
||||
!_locationConfig.ContainerRandomisationSettings.Enabled
|
||||
|| !_locationConfig.ContainerRandomisationSettings.Maps.ContainsKey(locationId)
|
||||
)
|
||||
if (!LocationRandomisationEnabled(locationId))
|
||||
{
|
||||
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}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -339,6 +335,12 @@ public class LocationLootGenerator(
|
||||
return result;
|
||||
}
|
||||
|
||||
protected bool LocationRandomisationEnabled(string locationId)
|
||||
{
|
||||
return _locationConfig.ContainerRandomisationSettings.Enabled
|
||||
&& _locationConfig.ContainerRandomisationSettings.Maps.ContainsKey(locationId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get containers with a non-100% chance to spawn OR are NOT on the container type randomistion blacklist
|
||||
/// </summary>
|
||||
@@ -639,7 +641,9 @@ public class LocationLootGenerator(
|
||||
};
|
||||
|
||||
// Add loot to container before returning
|
||||
containerClone.Template.Items.AddRange(items);
|
||||
containerClone.Template.Items.AddRange(
|
||||
items.Select(item => item.ToLootItem()).ToList() // Convert into correct output type first
|
||||
);
|
||||
}
|
||||
|
||||
return containerClone;
|
||||
@@ -975,10 +979,21 @@ public class LocationLootGenerator(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Draw a random item from spawn points possible items
|
||||
// Draw a random item from the spawn points possible items
|
||||
var chosenComposedKey = itemArray.Draw().FirstOrDefault();
|
||||
var chosenItem = spawnPoint.Template.Items.FirstOrDefault(item =>
|
||||
item.ComposedKey == chosenComposedKey
|
||||
);
|
||||
if (chosenItem is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
$"Unable to find item with composed key: {chosenComposedKey}, skipping spawn point: {spawnPoint.LocationId} "
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
var createItemResult = CreateDynamicLootItem(
|
||||
chosenComposedKey,
|
||||
chosenItem,
|
||||
spawnPoint.Template.Items,
|
||||
staticAmmoDist
|
||||
);
|
||||
@@ -996,8 +1011,11 @@ public class LocationLootGenerator(
|
||||
// Root id can change when generating a weapon, ensure ids match
|
||||
spawnPoint.Template.Root = createItemResult.Items.FirstOrDefault().Id;
|
||||
|
||||
// Convert the processed items into the correct output type
|
||||
var convertedItems = createItemResult.Items.Select(item => item.ToLootItem()).ToList();
|
||||
|
||||
// Overwrite entire pool with chosen item
|
||||
spawnPoint.Template.Items = createItemResult.Items;
|
||||
spawnPoint.Template.Items = convertedItems;
|
||||
|
||||
loot.Add(spawnPoint.Template);
|
||||
}
|
||||
@@ -1039,15 +1057,22 @@ public class LocationLootGenerator(
|
||||
continue;
|
||||
}
|
||||
|
||||
var chosenItem = forcedLootLocation.Template.Items.FirstOrDefault(item =>
|
||||
item.Id == rootItem.Id
|
||||
);
|
||||
var createItemResult = CreateDynamicLootItem(
|
||||
rootItem.Id,
|
||||
chosenItem,
|
||||
forcedLootLocation.Template.Items,
|
||||
staticAmmoDist
|
||||
);
|
||||
|
||||
// Update root ID with the above dynamically generated ID
|
||||
forcedLootLocation.Template.Root = createItemResult.Items.FirstOrDefault().Id;
|
||||
forcedLootLocation.Template.Items = createItemResult.Items;
|
||||
|
||||
// Convert the processed items into the correct output type
|
||||
var convertedItems = createItemResult.Items.Select(item => item.ToLootItem()).ToList();
|
||||
|
||||
forcedLootLocation.Template.Items = convertedItems;
|
||||
|
||||
// Push forced location into array as long as it doesn't exist already
|
||||
var existingLocation = result.Any(spawnPoint =>
|
||||
@@ -1074,28 +1099,20 @@ public class LocationLootGenerator(
|
||||
/// <summary>
|
||||
/// Create array of item (with child items) and return
|
||||
/// </summary>
|
||||
/// <param name="chosenComposedKey"> Key we want to look up items for </param>
|
||||
/// <param name="items"> Location loot Template </param>
|
||||
/// <param name="chosenItem"> Item we want to spawn in the position </param>
|
||||
/// <param name="lootItems"> Location loot Template </param>
|
||||
/// <param name="staticAmmoDist"> Ammo distributions </param>
|
||||
/// <returns> ContainerItem object </returns>
|
||||
protected ContainerItem CreateDynamicLootItem(
|
||||
string? chosenComposedKey,
|
||||
List<Item> items,
|
||||
SptLootItem chosenItem,
|
||||
List<SptLootItem> lootItems,
|
||||
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist
|
||||
)
|
||||
{
|
||||
var chosenItem = items.FirstOrDefault(item => item.Id == chosenComposedKey);
|
||||
MongoId chosenTpl = chosenItem?.Template ?? MongoId.Empty();
|
||||
var chosenTpl = chosenItem.Template;
|
||||
|
||||
if (chosenTpl == null)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Item for tpl {chosenComposedKey} was not found in the spawn point"
|
||||
);
|
||||
}
|
||||
|
||||
var itemTemplate = _itemHelper.GetItem(chosenTpl).Value;
|
||||
if (itemTemplate is null)
|
||||
var itemDbTemplate = _itemHelper.GetItem(chosenTpl).Value;
|
||||
if (itemDbTemplate is null)
|
||||
{
|
||||
_logger.Error($"Item tpl: {chosenTpl} cannot be found in database");
|
||||
}
|
||||
@@ -1107,11 +1124,11 @@ public class LocationLootGenerator(
|
||||
if (_itemHelper.IsOfBaseclasses(chosenTpl, [BaseClasses.MONEY, BaseClasses.AMMO]))
|
||||
{
|
||||
var stackCount =
|
||||
itemTemplate.Properties.StackMaxSize == 1
|
||||
itemDbTemplate.Properties.StackMaxSize == 1
|
||||
? 1
|
||||
: _randomUtil.GetInt(
|
||||
itemTemplate.Properties.StackMinRandom.Value,
|
||||
itemTemplate.Properties.StackMaxRandom.Value
|
||||
itemDbTemplate.Properties.StackMinRandom.Value,
|
||||
itemDbTemplate.Properties.StackMaxRandom.Value
|
||||
);
|
||||
|
||||
itemWithMods.Add(
|
||||
@@ -1126,21 +1143,21 @@ public class LocationLootGenerator(
|
||||
else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.AMMO_BOX))
|
||||
{
|
||||
// Fill with cartridges
|
||||
List<Item> ammoBoxItem = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }];
|
||||
_itemHelper.AddCartridgesToAmmoBox(ammoBoxItem, itemTemplate);
|
||||
List<Item> ammoBoxItem = [new() { Id = new MongoId(), Template = chosenTpl }];
|
||||
_itemHelper.AddCartridgesToAmmoBox(ammoBoxItem, itemDbTemplate);
|
||||
itemWithMods.AddRange(ammoBoxItem);
|
||||
}
|
||||
else if (_itemHelper.IsOfBaseclass(chosenTpl, BaseClasses.MAGAZINE))
|
||||
{
|
||||
// Create array with just magazine
|
||||
List<Item> magazineItem = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }];
|
||||
List<Item> magazineItem = [new() { Id = new MongoId(), Template = chosenTpl }];
|
||||
|
||||
if (_randomUtil.GetChance100(_locationConfig.StaticMagazineLootHasAmmoChancePercent))
|
||||
// Add randomised amount of cartridges
|
||||
{
|
||||
_itemHelper.FillMagazineWithRandomCartridge(
|
||||
magazineItem,
|
||||
itemTemplate, // Magazine template
|
||||
itemDbTemplate, // Magazine template
|
||||
staticAmmoDist,
|
||||
null,
|
||||
_locationConfig.MinFillLooseMagazinePercent / 100d
|
||||
@@ -1153,7 +1170,7 @@ public class LocationLootGenerator(
|
||||
{
|
||||
// Also used by armors to get child mods
|
||||
// Get item + children and add into array we return
|
||||
var itemWithChildren = items.FindAndReturnChildrenAsItems(chosenItem.Id);
|
||||
var itemWithChildren = lootItems.FindAndReturnChildrenAsItems(chosenItem.Id);
|
||||
|
||||
// Ensure all IDs are unique
|
||||
itemWithChildren = _itemHelper.ReplaceIDs(_cloner.Clone(itemWithChildren));
|
||||
@@ -1195,7 +1212,7 @@ public class LocationLootGenerator(
|
||||
|
||||
var width = itemTemplate.Properties.Width;
|
||||
var height = itemTemplate.Properties.Height;
|
||||
List<Item> items = [new() { Id = _hashUtil.Generate(), Template = chosenTpl }];
|
||||
List<Item> items = [new() { Id = new MongoId(), Template = chosenTpl }];
|
||||
var rootItem = items.FirstOrDefault();
|
||||
|
||||
// Use passed in parentId as override for new item
|
||||
|
||||
@@ -241,15 +241,15 @@ 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(
|
||||
HashSet<string> itemTplBlacklist,
|
||||
List<string> itemTypeWhitelist,
|
||||
HashSet<MongoId> itemTplBlacklist,
|
||||
List<MongoId> itemTypeWhitelist,
|
||||
bool useRewardItemBlacklist,
|
||||
bool allowBossItems,
|
||||
bool blockSeasonalItemsOutOfSeason
|
||||
)
|
||||
{
|
||||
var itemsDb = _databaseService.GetItems().Values;
|
||||
var itemBlacklist = new HashSet<string>();
|
||||
var itemBlacklist = new HashSet<MongoId>();
|
||||
itemBlacklist.UnionWith([.. _itemFilterService.GetBlacklistedItems(), .. itemTplBlacklist]);
|
||||
|
||||
if (useRewardItemBlacklist)
|
||||
@@ -321,9 +321,9 @@ public class LootGenerator(
|
||||
/// </summary>
|
||||
/// <param name="limits">limits as defined in config</param>
|
||||
/// <returns>record, key: item tplId, value: current/max item count allowed</returns>
|
||||
protected Dictionary<string, ItemLimit> InitItemLimitCounter(Dictionary<string, int> limits)
|
||||
protected Dictionary<MongoId, ItemLimit> InitItemLimitCounter(Dictionary<MongoId, int> limits)
|
||||
{
|
||||
var itemTypeCounts = new Dictionary<string, ItemLimit>();
|
||||
var itemTypeCounts = new Dictionary<MongoId, ItemLimit>();
|
||||
foreach (var itemTypeId in limits)
|
||||
{
|
||||
itemTypeCounts[itemTypeId.Key] = new ItemLimit
|
||||
@@ -346,7 +346,7 @@ public class LootGenerator(
|
||||
/// <returns>true if item was valid and added to pool</returns>
|
||||
protected bool FindAndAddRandomItemToLoot(
|
||||
List<TemplateItem> items,
|
||||
Dictionary<string, ItemLimit> itemTypeCounts,
|
||||
Dictionary<MongoId, ItemLimit> itemTypeCounts,
|
||||
LootRequest options,
|
||||
List<List<Item>> result
|
||||
)
|
||||
@@ -424,8 +424,8 @@ public class LootGenerator(
|
||||
/// <returns>true if preset was valid and added to pool</returns>
|
||||
protected bool FindAndAddRandomPresetToLoot(
|
||||
List<Preset> presetPool,
|
||||
Dictionary<string, ItemLimit> itemTypeCounts,
|
||||
HashSet<string> itemBlacklist,
|
||||
Dictionary<MongoId, ItemLimit> itemTypeCounts,
|
||||
HashSet<MongoId> itemBlacklist,
|
||||
List<List<Item>> result
|
||||
)
|
||||
{
|
||||
@@ -807,7 +807,7 @@ public class LootGenerator(
|
||||
{
|
||||
public List<TemplateItem> ItemPool { get; set; }
|
||||
|
||||
public HashSet<string> Blacklist { get; set; }
|
||||
public HashSet<MongoId> Blacklist { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -138,8 +139,8 @@ public class PMCLootGenerator(
|
||||
/// <returns>Dictionary of items and weights inversely tied to the items price</returns>
|
||||
protected Dictionary<string, double> GenerateLootPool(
|
||||
string pmcRole,
|
||||
HashSet<string> allowedItemTypeWhitelist,
|
||||
HashSet<string> itemTplAndParentBlacklist,
|
||||
HashSet<MongoId> allowedItemTypeWhitelist,
|
||||
HashSet<MongoId> itemTplAndParentBlacklist,
|
||||
Func<TemplateItem, bool>? genericItemCheck
|
||||
)
|
||||
{
|
||||
@@ -188,9 +189,9 @@ public class PMCLootGenerator(
|
||||
/// Get a generic all-container blacklist
|
||||
/// </summary>
|
||||
/// <returns>Hashset of blacklisted items</returns>
|
||||
protected HashSet<string> GetContainerLootBlacklist()
|
||||
protected HashSet<MongoId> GetContainerLootBlacklist()
|
||||
{
|
||||
var blacklist = new HashSet<string>();
|
||||
var blacklist = new HashSet<MongoId>();
|
||||
blacklist.UnionWith(_pmcConfig.PocketLoot.Blacklist);
|
||||
blacklist.UnionWith(_pmcConfig.GlobalLootBlacklist);
|
||||
blacklist.UnionWith(itemFilterService.GetBlacklistedItems());
|
||||
|
||||
@@ -835,7 +835,8 @@ public class RagfairOfferGenerator(
|
||||
|
||||
// Add hits to visor
|
||||
var visorMod = itemWithMods.FirstOrDefault(item =>
|
||||
item.ParentId == BaseClasses.ARMORED_EQUIPMENT && item.SlotId == "mod_equipment_000"
|
||||
item.ParentId == BaseClasses.ARMORED_EQUIPMENT.ToString()
|
||||
&& item.SlotId == "mod_equipment_000"
|
||||
);
|
||||
if (randomUtil.GetChance100(25) && visorMod != null)
|
||||
{
|
||||
|
||||
+10
-9
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -134,9 +135,9 @@ public class CompletionQuestGenerator(
|
||||
/// <param name="completionConfig">Completion quest type config</param>
|
||||
/// <param name="itemTplBlacklist">Item tpls to not add to pool</param>
|
||||
/// <returns>Set of item tpls</returns>
|
||||
protected HashSet<string> GetItemsToRetrievePool(
|
||||
protected HashSet<MongoId> GetItemsToRetrievePool(
|
||||
Completion completionConfig,
|
||||
HashSet<string> itemTplBlacklist
|
||||
HashSet<MongoId> itemTplBlacklist
|
||||
)
|
||||
{
|
||||
// Get seasonal items that should not be added to pool as seasonal event is not active
|
||||
@@ -178,11 +179,11 @@ public class CompletionQuestGenerator(
|
||||
/// <param name="roublesConfig">Roubles config</param>
|
||||
/// <param name="itemsToRetrievePool">Item pool</param>
|
||||
/// <returns>Filtered items and roubles budget</returns>
|
||||
protected (HashSet<string>, double) GetItemsWithinBudget(
|
||||
protected (HashSet<MongoId>, double) GetItemsWithinBudget(
|
||||
int pmcLevel,
|
||||
List<double> levelsConfig,
|
||||
List<double> roublesConfig,
|
||||
HashSet<string> itemsToRetrievePool
|
||||
HashSet<MongoId> itemsToRetrievePool
|
||||
)
|
||||
{
|
||||
// Be fair, don't value the items be more expensive than the reward
|
||||
@@ -208,8 +209,8 @@ public class CompletionQuestGenerator(
|
||||
/// <param name="itemSelection">Item selection to filter</param>
|
||||
/// <param name="pmcLevel">Level of pmc</param>
|
||||
/// <returns>Filtered selection, or original if null or empty</returns>
|
||||
protected HashSet<string> GetWhitelistedItemSelection(
|
||||
HashSet<string> itemSelection,
|
||||
protected HashSet<MongoId> GetWhitelistedItemSelection(
|
||||
HashSet<MongoId> itemSelection,
|
||||
int pmcLevel
|
||||
)
|
||||
{
|
||||
@@ -251,8 +252,8 @@ public class CompletionQuestGenerator(
|
||||
/// <param name="itemSelection">Item selection to filter</param>
|
||||
/// <param name="pmcLevel">Level of pmc</param>
|
||||
/// <returns>Filtered selection, or original if null or empty</returns>
|
||||
protected HashSet<string> GetBlacklistedItemSelection(
|
||||
HashSet<string> itemSelection,
|
||||
protected HashSet<MongoId> GetBlacklistedItemSelection(
|
||||
HashSet<MongoId> itemSelection,
|
||||
int pmcLevel
|
||||
)
|
||||
{
|
||||
@@ -296,7 +297,7 @@ public class CompletionQuestGenerator(
|
||||
RepeatableQuest quest,
|
||||
Completion completionConfig,
|
||||
RepeatableQuestConfig repeatableConfig,
|
||||
List<string> itemSelection,
|
||||
List<MongoId> itemSelection,
|
||||
double roublesBudget
|
||||
)
|
||||
{
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -818,8 +819,8 @@ public class RepeatableQuestRewardGenerator(
|
||||
/// <returns> True if item is valid reward </returns>
|
||||
public bool IsValidRewardItem(
|
||||
string tpl,
|
||||
HashSet<string> itemTplBlacklist,
|
||||
HashSet<string> itemTypeBlacklist,
|
||||
HashSet<MongoId> itemTplBlacklist,
|
||||
HashSet<MongoId> itemTypeBlacklist,
|
||||
List<string>? itemBaseWhitelist = null
|
||||
)
|
||||
{
|
||||
|
||||
@@ -496,12 +496,20 @@ public class ScavCaseRewardGenerator(
|
||||
/// <returns>value to set stack count to</returns>
|
||||
protected int GetRandomAmountRewardForScavCase(TemplateItem itemToCalculate, string rarity)
|
||||
{
|
||||
return itemToCalculate.Parent switch
|
||||
var parentId = itemToCalculate.Parent;
|
||||
|
||||
if (parentId == BaseClasses.AMMO)
|
||||
{
|
||||
BaseClasses.AMMO => GetRandomisedAmmoRewardStackSize(itemToCalculate),
|
||||
BaseClasses.MONEY => GetRandomisedMoneyRewardStackSize(itemToCalculate, rarity),
|
||||
_ => 1,
|
||||
};
|
||||
return GetRandomisedAmmoRewardStackSize(itemToCalculate);
|
||||
}
|
||||
else if (parentId == BaseClasses.MONEY)
|
||||
{
|
||||
return GetRandomisedMoneyRewardStackSize(itemToCalculate, rarity);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -525,26 +533,40 @@ public class ScavCaseRewardGenerator(
|
||||
/// <returns>value to set stack count to</returns>
|
||||
protected int GetRandomisedMoneyRewardStackSize(TemplateItem itemToCalculate, string rarity)
|
||||
{
|
||||
return itemToCalculate.Id switch
|
||||
var id = itemToCalculate.Id;
|
||||
|
||||
if (id == Money.ROUBLES)
|
||||
{
|
||||
Money.ROUBLES => _randomUtil.GetInt(
|
||||
return _randomUtil.GetInt(
|
||||
_scavCaseConfig.MoneyRewards.RubCount.GetByJsonProp<MinMax<int>>(rarity).Min,
|
||||
_scavCaseConfig.MoneyRewards.RubCount.GetByJsonProp<MinMax<int>>(rarity).Max
|
||||
),
|
||||
Money.EUROS => _randomUtil.GetInt(
|
||||
);
|
||||
}
|
||||
else if (id == Money.EUROS)
|
||||
{
|
||||
return _randomUtil.GetInt(
|
||||
_scavCaseConfig.MoneyRewards.EurCount.GetByJsonProp<MinMax<int>>(rarity).Min,
|
||||
_scavCaseConfig.MoneyRewards.EurCount.GetByJsonProp<MinMax<int>>(rarity).Max
|
||||
),
|
||||
Money.DOLLARS => _randomUtil.GetInt(
|
||||
);
|
||||
}
|
||||
else if (id == Money.DOLLARS)
|
||||
{
|
||||
return _randomUtil.GetInt(
|
||||
_scavCaseConfig.MoneyRewards.UsdCount.GetByJsonProp<MinMax<int>>(rarity).Min,
|
||||
_scavCaseConfig.MoneyRewards.UsdCount.GetByJsonProp<MinMax<int>>(rarity).Max
|
||||
),
|
||||
Money.GP => _randomUtil.GetInt(
|
||||
);
|
||||
}
|
||||
else if (id == Money.GP)
|
||||
{
|
||||
return _randomUtil.GetInt(
|
||||
_scavCaseConfig.MoneyRewards.GpCount.GetByJsonProp<MinMax<int>>(rarity).Min,
|
||||
_scavCaseConfig.MoneyRewards.GpCount.GetByJsonProp<MinMax<int>>(rarity).Max
|
||||
),
|
||||
_ => 1,
|
||||
};
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ using System.Text.RegularExpressions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers.Dialog.Commando.SptCommands;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Dialog;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
@@ -207,7 +208,7 @@ public class GiveSptCommand(
|
||||
localizedGlobal ??= GetGlobalsLocale(locale ?? "en");
|
||||
// If item is an item name, we need to search using that item name and the locale which one we want otherwise
|
||||
// item is just the tplId.
|
||||
var tplId = isItemName
|
||||
MongoId tplId = isItemName
|
||||
? _itemHelper
|
||||
.GetItems()
|
||||
.Where(IsItemAllowed)
|
||||
|
||||
@@ -48,10 +48,7 @@ public class HandbookHelper(
|
||||
}
|
||||
|
||||
itemToUpdate.Price = priceOverride.Price;
|
||||
if (priceOverride.ParentId is not null)
|
||||
{
|
||||
itemToUpdate.ParentId = priceOverride.ParentId;
|
||||
}
|
||||
itemToUpdate.ParentId = priceOverride.ParentId;
|
||||
}
|
||||
|
||||
var handbookDbClone = _cloner.Clone(handbook);
|
||||
|
||||
@@ -1679,7 +1679,7 @@ public class ItemHelper(
|
||||
string caliber,
|
||||
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
|
||||
string? fallbackCartridgeTpl = null,
|
||||
ICollection<string>? cartridgeWhitelist = null
|
||||
ICollection<MongoId>? cartridgeWhitelist = null
|
||||
)
|
||||
{
|
||||
var ammos = staticAmmoDist.GetValueOrDefault(caliber, []);
|
||||
@@ -1766,7 +1766,7 @@ public class ItemHelper(
|
||||
/// </summary>
|
||||
/// <param name="desiredBaseType">Item base type wanted</param>
|
||||
/// <returns>Array of tpls</returns>
|
||||
public List<string> GetItemTplsOfBaseType(string desiredBaseType)
|
||||
public List<MongoId> GetItemTplsOfBaseType(string desiredBaseType)
|
||||
{
|
||||
return _databaseService
|
||||
.GetItems()
|
||||
@@ -1791,7 +1791,7 @@ public class ItemHelper(
|
||||
)
|
||||
{
|
||||
var result = itemToAdd;
|
||||
HashSet<string> incompatibleModTpls = [];
|
||||
HashSet<MongoId> incompatibleModTpls = [];
|
||||
foreach (var slot in itemToAddTemplate.Properties.Slots)
|
||||
{
|
||||
// If only required mods is requested, skip non-essential
|
||||
@@ -1867,8 +1867,8 @@ public class ItemHelper(
|
||||
/// <param name="incompatibleModTpls">Incompatible tpls to not allow</param>
|
||||
/// <returns>Chosen tpl or undefined</returns>
|
||||
public string? GetCompatibleTplFromArray(
|
||||
HashSet<string> possibleTpls,
|
||||
HashSet<string> incompatibleModTpls
|
||||
HashSet<MongoId> possibleTpls,
|
||||
HashSet<MongoId> incompatibleModTpls
|
||||
)
|
||||
{
|
||||
if (!possibleTpls.Any())
|
||||
@@ -2062,7 +2062,7 @@ public class ItemHelper(
|
||||
return currentItem.Id;
|
||||
}
|
||||
|
||||
if (currentItem.Parent is null)
|
||||
if (currentItem.Parent.IsEmpty())
|
||||
// No parent, reached root
|
||||
{
|
||||
return currentItem.Id;
|
||||
|
||||
@@ -30,18 +30,25 @@ public class RagfairHelper(
|
||||
/// <returns>Currency tag, e.g. RUB</returns>
|
||||
public string GetCurrencyTag(string currencyTpl)
|
||||
{
|
||||
switch (currencyTpl)
|
||||
if (currencyTpl == Money.EUROS)
|
||||
{
|
||||
case Money.EUROS:
|
||||
return "EUR";
|
||||
case Money.DOLLARS:
|
||||
return "USD";
|
||||
case Money.ROUBLES:
|
||||
return "RUB";
|
||||
case Money.GP:
|
||||
return "GP";
|
||||
default:
|
||||
return "";
|
||||
return "EUR";
|
||||
}
|
||||
else if (currencyTpl == Money.DOLLARS)
|
||||
{
|
||||
return "USD";
|
||||
}
|
||||
else if (currencyTpl == Money.ROUBLES)
|
||||
{
|
||||
return "RUB";
|
||||
}
|
||||
else if (currencyTpl == Money.GP)
|
||||
{
|
||||
return "GP";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,11 +197,8 @@ public class RagfairHelper(
|
||||
*/
|
||||
public string GetCurrencySymbol(string currencyTpl)
|
||||
{
|
||||
return currencyTpl switch
|
||||
{
|
||||
Money.EUROS => "€",
|
||||
Money.DOLLARS => "$",
|
||||
_ => "₽",
|
||||
};
|
||||
return currencyTpl == Money.EUROS ? "€"
|
||||
: currencyTpl == Money.DOLLARS ? "$"
|
||||
: "₽";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,13 @@ public readonly partial struct MongoId : IEquatable<MongoId>
|
||||
|
||||
public MongoId(string id)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(id) || id.Length != 24)
|
||||
// This is temporary, otherwise item buying is broken as when LINQ searches for string id's it's possible null is passed
|
||||
if (id == null)
|
||||
{
|
||||
id = string.Empty;
|
||||
}
|
||||
|
||||
if (id.Length != 24)
|
||||
{
|
||||
// TODO: Items.json root item has an empty parentId property
|
||||
Console.WriteLine($"Critical MongoId error: Incorrect length. id: {id}");
|
||||
@@ -125,7 +131,7 @@ public readonly partial struct MongoId : IEquatable<MongoId>
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
if (_stringId == "000000000000000000000000")
|
||||
if (_stringId == "000000000000000000000000" || string.IsNullOrEmpty(_stringId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,13 @@ public record SpawnpointTemplate
|
||||
}
|
||||
|
||||
[JsonPropertyName("Items")]
|
||||
public List<Item>? Items { get; set; }
|
||||
public List<SptLootItem>? Items { get; set; }
|
||||
}
|
||||
|
||||
public record SptLootItem : Item
|
||||
{
|
||||
[JsonPropertyName("composedKey")]
|
||||
public string? ComposedKey { get; set; }
|
||||
}
|
||||
|
||||
public record GroupPosition
|
||||
|
||||
@@ -4,5 +4,8 @@ global using GlobalAmmo = System.Collections.Generic.Dictionary<
|
||||
>;
|
||||
global using GlobalMods = System.Collections.Generic.Dictionary<
|
||||
string,
|
||||
System.Collections.Generic.Dictionary<string, System.Collections.Generic.HashSet<string>>
|
||||
System.Collections.Generic.Dictionary<
|
||||
string,
|
||||
System.Collections.Generic.HashSet<SPTarkov.Server.Core.Models.Common.MongoId>
|
||||
>
|
||||
>;
|
||||
|
||||
@@ -12,11 +12,11 @@ public record Item
|
||||
|
||||
private string? _parentId;
|
||||
|
||||
private string? _SlotId;
|
||||
private string? _slotId;
|
||||
|
||||
// MongoId
|
||||
[JsonPropertyName("_id")]
|
||||
public required MongoId Id { get; set; }
|
||||
public virtual required MongoId Id { get; set; }
|
||||
|
||||
[JsonPropertyName("_tpl")]
|
||||
// MongoId
|
||||
@@ -32,8 +32,8 @@ public record Item
|
||||
[JsonPropertyName("slotId")]
|
||||
public string? SlotId
|
||||
{
|
||||
get { return _SlotId; }
|
||||
set { _SlotId = value == null ? null : string.Intern(value); }
|
||||
get { return _slotId; }
|
||||
set { _slotId = value == null ? null : string.Intern(value); }
|
||||
}
|
||||
|
||||
[JsonPropertyName("location")]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Constants;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Utils.Json.Converters;
|
||||
|
||||
@@ -12,8 +13,6 @@ public record TemplateItem
|
||||
|
||||
private Dictionary<string, bool>? _blocks;
|
||||
|
||||
private string? _id;
|
||||
|
||||
private string? _name;
|
||||
|
||||
private string? _parent;
|
||||
@@ -23,11 +22,7 @@ public record TemplateItem
|
||||
private string? _type;
|
||||
|
||||
[JsonPropertyName("_id")]
|
||||
public string? Id
|
||||
{
|
||||
get { return _id; }
|
||||
set { _id = string.Intern(value); }
|
||||
}
|
||||
public MongoId Id { get; set; }
|
||||
|
||||
[JsonPropertyName("_name")]
|
||||
public string? Name
|
||||
@@ -37,11 +32,7 @@ public record TemplateItem
|
||||
}
|
||||
|
||||
[JsonPropertyName("_parent")]
|
||||
public string? Parent
|
||||
{
|
||||
get { return _parent; }
|
||||
set { _parent = string.Intern(value); }
|
||||
}
|
||||
public MongoId Parent { get; set; }
|
||||
|
||||
[JsonPropertyName("_type")]
|
||||
public string? Type
|
||||
@@ -309,7 +300,7 @@ public record Props
|
||||
public bool? CanRequireOnRagfair { get; set; }
|
||||
|
||||
[JsonPropertyName("ConflictingItems")]
|
||||
public HashSet<string>? ConflictingItems { get; set; }
|
||||
public HashSet<MongoId>? ConflictingItems { get; set; }
|
||||
|
||||
[JsonPropertyName("Unlootable")]
|
||||
public bool? Unlootable { get; set; }
|
||||
@@ -1235,7 +1226,7 @@ public record Props
|
||||
|
||||
// Confirmed on client - MongoId
|
||||
[JsonPropertyName("TargetItemFilter")]
|
||||
public List<string>? TargetItemFilter { get; set; }
|
||||
public List<MongoId>? TargetItemFilter { get; set; }
|
||||
|
||||
[JsonPropertyName("RepairQuality")]
|
||||
public double? RepairQuality { get; set; }
|
||||
@@ -1815,7 +1806,7 @@ public record SlotFilter
|
||||
public List<string>? ArmorPlateColliders { get; set; }
|
||||
|
||||
[JsonPropertyName("Filter")]
|
||||
public HashSet<string>? Filter { get; set; }
|
||||
public HashSet<MongoId>? Filter { get; set; }
|
||||
|
||||
[JsonPropertyName("AnimationIndex")]
|
||||
public double? AnimationIndex { get; set; }
|
||||
|
||||
@@ -276,7 +276,7 @@ public record BarterScheme
|
||||
public double? Count { get; set; }
|
||||
|
||||
[JsonPropertyName("_tpl")]
|
||||
public string? Template { get; set; }
|
||||
public MongoId Template { get; set; }
|
||||
|
||||
[JsonPropertyName("onlyFunctional")]
|
||||
public bool? OnlyFunctional { get; set; }
|
||||
|
||||
@@ -1,115 +1,117 @@
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Enums;
|
||||
|
||||
public static class BaseClasses
|
||||
{
|
||||
public const string WEAPON = "5422acb9af1c889c16000029";
|
||||
public const string UBGL = "55818b014bdc2ddc698b456b";
|
||||
public const string ARMOR = "5448e54d4bdc2dcc718b4568";
|
||||
public const string ARMORED_EQUIPMENT = "57bef4c42459772e8d35a53b";
|
||||
public const string REPAIR_KITS = "616eb7aea207f41933308f46";
|
||||
public const string HEADWEAR = "5a341c4086f77401f2541505";
|
||||
public const string FACECOVER = "5a341c4686f77469e155819e";
|
||||
public const string VEST = "5448e5284bdc2dcb718b4567";
|
||||
public const string BACKPACK = "5448e53e4bdc2d60728b4567";
|
||||
public const string COMPOUND = "566162e44bdc2d3f298b4573";
|
||||
public const string VISORS = "5448e5724bdc2ddf718b4568";
|
||||
public const string FOOD = "5448e8d04bdc2ddf718b4569";
|
||||
public const string GAS_BLOCK = "56ea9461d2720b67698b456f";
|
||||
public const string RAIL_COVER = "55818b1d4bdc2d5b648b4572";
|
||||
public const string DRINK = "5448e8d64bdc2dce718b4568";
|
||||
public const string BARTER_ITEM = "5448eb774bdc2d0a728b4567";
|
||||
public const string INFO = "5448ecbe4bdc2d60728b4568";
|
||||
public const string MEDKIT = "5448f39d4bdc2d0a728b4568";
|
||||
public const string DRUGS = "5448f3a14bdc2d27728b4569";
|
||||
public const string STIMULATOR = "5448f3a64bdc2d60728b456a";
|
||||
public const string MEDICAL = "5448f3ac4bdc2dce718b4569";
|
||||
public const string MEDICAL_SUPPLIES = "57864c8c245977548867e7f1";
|
||||
public const string MOD = "5448fe124bdc2da5018b4567";
|
||||
public const string FUNCTIONAL_MOD = "550aa4154bdc2dd8348b456b";
|
||||
public const string FUEL = "5d650c3e815116009f6201d2";
|
||||
public const string GEAR_MOD = "55802f3e4bdc2de7118b4584";
|
||||
public const string STOCK = "55818a594bdc2db9688b456a";
|
||||
public const string FOREGRIP = "55818af64bdc2d5b648b4570";
|
||||
public const string MASTER_MOD = "55802f4a4bdc2ddb688b4569";
|
||||
public const string MOUNT = "55818b224bdc2dde698b456f";
|
||||
public const string MUZZLE = "5448fe394bdc2d0d028b456c";
|
||||
public const string SIGHTS = "5448fe7a4bdc2d6f028b456b";
|
||||
public const string MEDS = "543be5664bdc2dd4348b4569";
|
||||
public const string MAP = "567849dd4bdc2d150f8b456e";
|
||||
public const string MONEY = "543be5dd4bdc2deb348b4569";
|
||||
public const string NIGHTVISION = "5a2c3a9486f774688b05e574";
|
||||
public const string THERMAL_VISION = "5d21f59b6dbe99052b54ef83";
|
||||
public const string KEY = "543be5e94bdc2df1348b4568";
|
||||
public const string KEY_MECHANICAL = "5c99f98d86f7745c314214b3";
|
||||
public const string KEYCARD = "5c164d2286f774194c5e69fa";
|
||||
public const string EQUIPMENT = "543be5f84bdc2dd4348b456a";
|
||||
public const string THROW_WEAPON = "543be6564bdc2df4348b4568";
|
||||
public const string FOOD_DRINK = "543be6674bdc2df1348b4569";
|
||||
public const string PISTOL = "5447b5cf4bdc2d65278b4567";
|
||||
public const string REVOLVER = "617f1ef5e8b54b0998387733";
|
||||
public const string SMG = "5447b5e04bdc2d62278b4567";
|
||||
public const string ASSAULT_RIFLE = "5447b5f14bdc2d61278b4567";
|
||||
public const string ASSAULT_CARBINE = "5447b5fc4bdc2d87278b4567";
|
||||
public const string SHOTGUN = "5447b6094bdc2dc3278b4567";
|
||||
public const string MARKSMAN_RIFLE = "5447b6194bdc2d67278b4567";
|
||||
public const string SNIPER_RIFLE = "5447b6254bdc2dc3278b4568";
|
||||
public const string MACHINE_GUN = "5447bed64bdc2d97278b4568";
|
||||
public const string GRENADE_LAUNCHER = "5447bedf4bdc2d87278b4568";
|
||||
public const string SPECIAL_WEAPON = "5447bee84bdc2dc3278b4569";
|
||||
public const string SPEC_ITEM = "5447e0e74bdc2d3c308b4567";
|
||||
public const string SPRING_DRIVEN_CYLINDER = "627a137bf21bc425b06ab944";
|
||||
public const string KNIFE = "5447e1d04bdc2dff2f8b4567";
|
||||
public const string AMMO = "5485a8684bdc2da71d8b4567";
|
||||
public const string AMMO_BOX = "543be5cb4bdc2deb348b4568";
|
||||
public const string LOOT_CONTAINER = "566965d44bdc2d814c8b4571";
|
||||
public const string MOB_CONTAINER = "5448bf274bdc2dfc2f8b456a";
|
||||
public const string SEARCHABLE_ITEM = "566168634bdc2d144c8b456c";
|
||||
public const string STASH = "566abbb64bdc2d144c8b457d";
|
||||
public const string SORTING_TABLE = "6050cac987d3f925bf016837";
|
||||
public const string LOCKABLE_CONTAINER = "5671435f4bdc2d96058b4569";
|
||||
public const string SIMPLE_CONTAINER = "5795f317245977243854e041";
|
||||
public const string INVENTORY = "55d720f24bdc2d88028b456d";
|
||||
public const string STATIONARY_CONTAINER = "567583764bdc2d98058b456e";
|
||||
public const string POCKETS = "557596e64bdc2dc2118b4571";
|
||||
public const string ARMBAND = "5b3f15d486f77432d0509248";
|
||||
public const string JEWELRY = "57864a3d24597754843f8721";
|
||||
public const string ELECTRONICS = "57864a66245977548f04a81f";
|
||||
public const string BUILDING_MATERIAL = "57864ada245977548638de91";
|
||||
public const string TOOL = "57864bb7245977548b3b66c2";
|
||||
public const string HOUSEHOLD_GOODS = "57864c322459775490116fbf";
|
||||
public const string LUBRICANT = "57864e4c24597754843f8723";
|
||||
public const string BATTERY = "57864ee62459775490116fc1";
|
||||
public const string ASSAULT_SCOPE = "55818add4bdc2d5b648b456f";
|
||||
public const string TACTICAL_COMBO = "55818b164bdc2ddc698b456c";
|
||||
public const string FLASHLIGHT = "55818b084bdc2d5b648b4571";
|
||||
public const string MAGAZINE = "5448bc234bdc2d3c308b4569";
|
||||
public const string LIGHT_LASER_DESIGNATOR = "55818b0e4bdc2dde698b456e";
|
||||
public const string FLASH_HIDER = "550aa4bf4bdc2dd6348b456b";
|
||||
public const string COLLIMATOR = "55818ad54bdc2ddc698b4569";
|
||||
public const string IRON_SIGHT = "55818ac54bdc2d5b648b456e";
|
||||
public const string COMPACT_COLLIMATOR = "55818acf4bdc2dde698b456b";
|
||||
public const string COMPENSATOR = "550aa4af4bdc2dd4348b456e";
|
||||
public const string OPTIC_SCOPE = "55818ae44bdc2dde698b456c";
|
||||
public const string SPECIAL_SCOPE = "55818aeb4bdc2ddc698b456a";
|
||||
public const string OTHER = "590c745b86f7743cc433c5f2";
|
||||
public const string SILENCER = "550aa4cd4bdc2dd8348b456c";
|
||||
public const string PORTABLE_RANGE_FINDER = "61605ddea09d851a0a0c1bbc";
|
||||
public const string ITEM = "54009119af1c881c07000029";
|
||||
public const string CYLINDER_MAGAZINE = "610720f290b75a49ff2e5e25";
|
||||
public const string AUXILIARY_MOD = "5a74651486f7744e73386dd1";
|
||||
public const string BIPOD = "55818afb4bdc2dde698b456d";
|
||||
public const string HEADPHONES = "5645bcb74bdc2ded0b8b4578";
|
||||
public const string RANDOM_LOOT_CONTAINER = "62f109593b54472778797866";
|
||||
public const string STACKABLE_ITEM = "5661632d4bdc2d903d8b456b";
|
||||
public const string BUILT_IN_INSERTS = "65649eb40bf0ed77b8044453";
|
||||
public const string ARMOR_PLATE = "644120aa86ffbe10ee032b6f";
|
||||
public const string CULTIST_AMULET = "64b69b0c8f3be32ed22682f8";
|
||||
public const string RADIO_TRANSMITTER = "62e9103049c018f425059f38";
|
||||
public const string HANDGUARD = "55818a104bdc2db9688b4569";
|
||||
public const string PISTOL_GRIP = "55818a684bdc2ddd698b456d";
|
||||
public const string RECEIVER = "55818a304bdc2db5418b457d";
|
||||
public const string BARREL = "555ef6e44bdc2de9068b457e";
|
||||
public const string CHARGING_HANDLE = "55818a6f4bdc2db9688b456b";
|
||||
public const string COMB_MUZZLE_DEVICE = "550aa4dd4bdc2dc9348b4569 ";
|
||||
public const string HIDEOUT_AREA_CONTAINER = "63da6da4784a55176c018dba";
|
||||
public static readonly MongoId WEAPON = new MongoId("5422acb9af1c889c16000029");
|
||||
public static readonly MongoId UBGL = new MongoId("55818b014bdc2ddc698b456b");
|
||||
public static readonly MongoId ARMOR = new MongoId("5448e54d4bdc2dcc718b4568");
|
||||
public static readonly MongoId ARMORED_EQUIPMENT = new MongoId("57bef4c42459772e8d35a53b");
|
||||
public static readonly MongoId REPAIR_KITS = new MongoId("616eb7aea207f41933308f46");
|
||||
public static readonly MongoId HEADWEAR = new MongoId("5a341c4086f77401f2541505");
|
||||
public static readonly MongoId FACECOVER = new MongoId("5a341c4686f77469e155819e");
|
||||
public static readonly MongoId VEST = new MongoId("5448e5284bdc2dcb718b4567");
|
||||
public static readonly MongoId BACKPACK = new MongoId("5448e53e4bdc2d60728b4567");
|
||||
public static readonly MongoId COMPOUND = new MongoId("566162e44bdc2d3f298b4573");
|
||||
public static readonly MongoId VISORS = new MongoId("5448e5724bdc2ddf718b4568");
|
||||
public static readonly MongoId FOOD = new MongoId("5448e8d04bdc2ddf718b4569");
|
||||
public static readonly MongoId GAS_BLOCK = new MongoId("56ea9461d2720b67698b456f");
|
||||
public static readonly MongoId RAIL_COVER = new MongoId("55818b1d4bdc2d5b648b4572");
|
||||
public static readonly MongoId DRINK = new MongoId("5448e8d64bdc2dce718b4568");
|
||||
public static readonly MongoId BARTER_ITEM = new MongoId("5448eb774bdc2d0a728b4567");
|
||||
public static readonly MongoId INFO = new MongoId("5448ecbe4bdc2d60728b4568");
|
||||
public static readonly MongoId MEDKIT = new MongoId("5448f39d4bdc2d0a728b4568");
|
||||
public static readonly MongoId DRUGS = new MongoId("5448f3a14bdc2d27728b4569");
|
||||
public static readonly MongoId STIMULATOR = new MongoId("5448f3a64bdc2d60728b456a");
|
||||
public static readonly MongoId MEDICAL = new MongoId("5448f3ac4bdc2dce718b4569");
|
||||
public static readonly MongoId MEDICAL_SUPPLIES = new MongoId("57864c8c245977548867e7f1");
|
||||
public static readonly MongoId MOD = new MongoId("5448fe124bdc2da5018b4567");
|
||||
public static readonly MongoId FUNCTIONAL_MOD = new MongoId("550aa4154bdc2dd8348b456b");
|
||||
public static readonly MongoId FUEL = new MongoId("5d650c3e815116009f6201d2");
|
||||
public static readonly MongoId GEAR_MOD = new MongoId("55802f3e4bdc2de7118b4584");
|
||||
public static readonly MongoId STOCK = new MongoId("55818a594bdc2db9688b456a");
|
||||
public static readonly MongoId FOREGRIP = new MongoId("55818af64bdc2d5b648b4570");
|
||||
public static readonly MongoId MASTER_MOD = new MongoId("55802f4a4bdc2ddb688b4569");
|
||||
public static readonly MongoId MOUNT = new MongoId("55818b224bdc2dde698b456f");
|
||||
public static readonly MongoId MUZZLE = new MongoId("5448fe394bdc2d0d028b456c");
|
||||
public static readonly MongoId SIGHTS = new MongoId("5448fe7a4bdc2d6f028b456b");
|
||||
public static readonly MongoId MEDS = new MongoId("543be5664bdc2dd4348b4569");
|
||||
public static readonly MongoId MAP = new MongoId("567849dd4bdc2d150f8b456e");
|
||||
public static readonly MongoId MONEY = new MongoId("543be5dd4bdc2deb348b4569");
|
||||
public static readonly MongoId NIGHTVISION = new MongoId("5a2c3a9486f774688b05e574");
|
||||
public static readonly MongoId THERMAL_VISION = new MongoId("5d21f59b6dbe99052b54ef83");
|
||||
public static readonly MongoId KEY = new MongoId("543be5e94bdc2df1348b4568");
|
||||
public static readonly MongoId KEY_MECHANICAL = new MongoId("5c99f98d86f7745c314214b3");
|
||||
public static readonly MongoId KEYCARD = new MongoId("5c164d2286f774194c5e69fa");
|
||||
public static readonly MongoId EQUIPMENT = new MongoId("543be5f84bdc2dd4348b456a");
|
||||
public static readonly MongoId THROW_WEAPON = new MongoId("543be6564bdc2df4348b4568");
|
||||
public static readonly MongoId FOOD_DRINK = new MongoId("543be6674bdc2df1348b4569");
|
||||
public static readonly MongoId PISTOL = new MongoId("5447b5cf4bdc2d65278b4567");
|
||||
public static readonly MongoId REVOLVER = new MongoId("617f1ef5e8b54b0998387733");
|
||||
public static readonly MongoId SMG = new MongoId("5447b5e04bdc2d62278b4567");
|
||||
public static readonly MongoId ASSAULT_RIFLE = new MongoId("5447b5f14bdc2d61278b4567");
|
||||
public static readonly MongoId ASSAULT_CARBINE = new MongoId("5447b5fc4bdc2d87278b4567");
|
||||
public static readonly MongoId SHOTGUN = new MongoId("5447b6094bdc2dc3278b4567");
|
||||
public static readonly MongoId MARKSMAN_RIFLE = new MongoId("5447b6194bdc2d67278b4567");
|
||||
public static readonly MongoId SNIPER_RIFLE = new MongoId("5447b6254bdc2dc3278b4568");
|
||||
public static readonly MongoId MACHINE_GUN = new MongoId("5447bed64bdc2d97278b4568");
|
||||
public static readonly MongoId GRENADE_LAUNCHER = new MongoId("5447bedf4bdc2d87278b4568");
|
||||
public static readonly MongoId SPECIAL_WEAPON = new MongoId("5447bee84bdc2dc3278b4569");
|
||||
public static readonly MongoId SPEC_ITEM = new MongoId("5447e0e74bdc2d3c308b4567");
|
||||
public static readonly MongoId SPRING_DRIVEN_CYLINDER = new MongoId("627a137bf21bc425b06ab944");
|
||||
public static readonly MongoId KNIFE = new MongoId("5447e1d04bdc2dff2f8b4567");
|
||||
public static readonly MongoId AMMO = new MongoId("5485a8684bdc2da71d8b4567");
|
||||
public static readonly MongoId AMMO_BOX = new MongoId("543be5cb4bdc2deb348b4568");
|
||||
public static readonly MongoId LOOT_CONTAINER = new MongoId("566965d44bdc2d814c8b4571");
|
||||
public static readonly MongoId MOB_CONTAINER = new MongoId("5448bf274bdc2dfc2f8b456a");
|
||||
public static readonly MongoId SEARCHABLE_ITEM = new MongoId("566168634bdc2d144c8b456c");
|
||||
public static readonly MongoId STASH = new MongoId("566abbb64bdc2d144c8b457d");
|
||||
public static readonly MongoId SORTING_TABLE = new MongoId("6050cac987d3f925bf016837");
|
||||
public static readonly MongoId LOCKABLE_CONTAINER = new MongoId("5671435f4bdc2d96058b4569");
|
||||
public static readonly MongoId SIMPLE_CONTAINER = new MongoId("5795f317245977243854e041");
|
||||
public static readonly MongoId INVENTORY = new MongoId("55d720f24bdc2d88028b456d");
|
||||
public static readonly MongoId STATIONARY_CONTAINER = new MongoId("567583764bdc2d98058b456e");
|
||||
public static readonly MongoId POCKETS = new MongoId("557596e64bdc2dc2118b4571");
|
||||
public static readonly MongoId ARMBAND = new MongoId("5b3f15d486f77432d0509248");
|
||||
public static readonly MongoId JEWELRY = new MongoId("57864a3d24597754843f8721");
|
||||
public static readonly MongoId ELECTRONICS = new MongoId("57864a66245977548f04a81f");
|
||||
public static readonly MongoId BUILDING_MATERIAL = new MongoId("57864ada245977548638de91");
|
||||
public static readonly MongoId TOOL = new MongoId("57864bb7245977548b3b66c2");
|
||||
public static readonly MongoId HOUSEHOLD_GOODS = new MongoId("57864c322459775490116fbf");
|
||||
public static readonly MongoId LUBRICANT = new MongoId("57864e4c24597754843f8723");
|
||||
public static readonly MongoId BATTERY = new MongoId("57864ee62459775490116fc1");
|
||||
public static readonly MongoId ASSAULT_SCOPE = new MongoId("55818add4bdc2d5b648b456f");
|
||||
public static readonly MongoId TACTICAL_COMBO = new MongoId("55818b164bdc2ddc698b456c");
|
||||
public static readonly MongoId FLASHLIGHT = new MongoId("55818b084bdc2d5b648b4571");
|
||||
public static readonly MongoId MAGAZINE = new MongoId("5448bc234bdc2d3c308b4569");
|
||||
public static readonly MongoId LIGHT_LASER_DESIGNATOR = new MongoId("55818b0e4bdc2dde698b456e");
|
||||
public static readonly MongoId FLASH_HIDER = new MongoId("550aa4bf4bdc2dd6348b456b");
|
||||
public static readonly MongoId COLLIMATOR = new MongoId("55818ad54bdc2ddc698b4569");
|
||||
public static readonly MongoId IRON_SIGHT = new MongoId("55818ac54bdc2d5b648b456e");
|
||||
public static readonly MongoId COMPACT_COLLIMATOR = new MongoId("55818acf4bdc2dde698b456b");
|
||||
public static readonly MongoId COMPENSATOR = new MongoId("550aa4af4bdc2dd4348b456e");
|
||||
public static readonly MongoId OPTIC_SCOPE = new MongoId("55818ae44bdc2dde698b456c");
|
||||
public static readonly MongoId SPECIAL_SCOPE = new MongoId("55818aeb4bdc2ddc698b456a");
|
||||
public static readonly MongoId OTHER = new MongoId("590c745b86f7743cc433c5f2");
|
||||
public static readonly MongoId SILENCER = new MongoId("550aa4cd4bdc2dd8348b456c");
|
||||
public static readonly MongoId PORTABLE_RANGE_FINDER = new MongoId("61605ddea09d851a0a0c1bbc");
|
||||
public static readonly MongoId ITEM = new MongoId("54009119af1c881c07000029");
|
||||
public static readonly MongoId CYLINDER_MAGAZINE = new MongoId("610720f290b75a49ff2e5e25");
|
||||
public static readonly MongoId AUXILIARY_MOD = new MongoId("5a74651486f7744e73386dd1");
|
||||
public static readonly MongoId BIPOD = new MongoId("55818afb4bdc2dde698b456d");
|
||||
public static readonly MongoId HEADPHONES = new MongoId("5645bcb74bdc2ded0b8b4578");
|
||||
public static readonly MongoId RANDOM_LOOT_CONTAINER = new MongoId("62f109593b54472778797866");
|
||||
public static readonly MongoId STACKABLE_ITEM = new MongoId("5661632d4bdc2d903d8b456b");
|
||||
public static readonly MongoId BUILT_IN_INSERTS = new MongoId("65649eb40bf0ed77b8044453");
|
||||
public static readonly MongoId ARMOR_PLATE = new MongoId("644120aa86ffbe10ee032b6f");
|
||||
public static readonly MongoId CULTIST_AMULET = new MongoId("64b69b0c8f3be32ed22682f8");
|
||||
public static readonly MongoId RADIO_TRANSMITTER = new MongoId("62e9103049c018f425059f38");
|
||||
public static readonly MongoId HANDGUARD = new MongoId("55818a104bdc2db9688b4569");
|
||||
public static readonly MongoId PISTOL_GRIP = new MongoId("55818a684bdc2ddd698b456d");
|
||||
public static readonly MongoId RECEIVER = new MongoId("55818a304bdc2db5418b457d");
|
||||
public static readonly MongoId BARREL = new MongoId("555ef6e44bdc2de9068b457e");
|
||||
public static readonly MongoId CHARGING_HANDLE = new MongoId("55818a6f4bdc2db9688b456b");
|
||||
public static readonly MongoId COMB_MUZZLE_DEVICE = new MongoId("550aa4dd4bdc2dc9348b4569");
|
||||
public static readonly MongoId HIDEOUT_AREA_CONTAINER = new MongoId("63da6da4784a55176c018dba");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Enums;
|
||||
|
||||
@@ -7,10 +8,10 @@ public record Money
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, object>? ExtensionData { get; set; }
|
||||
|
||||
public const string ROUBLES = "5449016a4bdc2d6f028b456f";
|
||||
public const string EUROS = "569668774bdc2da2298b4568";
|
||||
public const string DOLLARS = "5696686a4bdc2da3298b456a";
|
||||
public const string GP = "5d235b4d86f7742e017bc88a";
|
||||
public static readonly MongoId ROUBLES = new MongoId("5449016a4bdc2d6f028b456f");
|
||||
public static readonly MongoId EUROS = new MongoId("569668774bdc2da2298b4568");
|
||||
public static readonly MongoId DOLLARS = new MongoId("5696686a4bdc2da3298b456a");
|
||||
public static readonly MongoId GP = new MongoId("5d235b4d86f7742e017bc88a");
|
||||
|
||||
public static HashSet<string> GetMoneyTpls()
|
||||
{
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Spt.Bots;
|
||||
|
||||
@@ -11,7 +12,7 @@ public record FilterPlateModsForSlotByLevelResult
|
||||
public Result? Result { get; set; }
|
||||
|
||||
[JsonPropertyName("plateModTpls")]
|
||||
public HashSet<string>? PlateModTemplates { get; set; }
|
||||
public HashSet<MongoId>? PlateModTemplates { get; set; }
|
||||
}
|
||||
|
||||
public enum Result
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Spt.Bots;
|
||||
@@ -66,7 +67,7 @@ public record GenerateWeaponRequest
|
||||
/// Array of item tpls the weapon does not support
|
||||
/// </summary>
|
||||
[JsonPropertyName("conflictingItemTpls")]
|
||||
public HashSet<string>? ConflictingItemTpls { get; set; }
|
||||
public HashSet<MongoId>? ConflictingItemTpls { get; set; }
|
||||
}
|
||||
|
||||
public record BotData
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -41,7 +42,7 @@ public record ModToSpawnRequest
|
||||
/// Pool of items to pick from
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemModPool")]
|
||||
public Dictionary<string, HashSet<string>>? ItemModPool { get; set; }
|
||||
public Dictionary<string, HashSet<MongoId>>? ItemModPool { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List with only weapon tpl in it, ready for mods to be added
|
||||
@@ -77,7 +78,7 @@ public record ModToSpawnRequest
|
||||
/// List of item tpls the weapon does not support
|
||||
/// </summary>
|
||||
[JsonPropertyName("conflictingItemTpls")]
|
||||
public HashSet<string>? ConflictingItemTpls { get; set; }
|
||||
public HashSet<MongoId>? ConflictingItemTpls { get; set; }
|
||||
|
||||
[JsonPropertyName("botData")]
|
||||
public BotData? BotData { get; set; }
|
||||
|
||||
@@ -62,25 +62,25 @@ public record AirdropLoot
|
||||
/// Items to never allow - tpls
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemBlacklist")]
|
||||
public required List<string> ItemBlacklist { get; set; }
|
||||
public required List<MongoId> ItemBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item type (parentId) to allow inside crate
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemTypeWhitelist")]
|
||||
public required List<string> ItemTypeWhitelist { get; set; }
|
||||
public required List<MongoId> ItemTypeWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item type/ item tpls to limit count of inside crate - key: item base type: value: max count
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemLimits")]
|
||||
public required Dictionary<string, int> ItemLimits { get; set; }
|
||||
public required Dictionary<MongoId, int> ItemLimits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items to limit stack size of key: item tpl value: min/max stack size
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemStackLimits")]
|
||||
public required Dictionary<string, MinMax<int>> ItemStackLimits { get; set; }
|
||||
public required Dictionary<MongoId, MinMax<int>> ItemStackLimits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Armor levels to allow inside crate e.g. [4,5,6]
|
||||
|
||||
@@ -553,19 +553,19 @@ public record EquipmentFilterDetails
|
||||
/// Key: mod slot name e.g. mod_magazine, value: item tpls
|
||||
/// </summary>
|
||||
[JsonPropertyName("equipment")]
|
||||
public Dictionary<string, HashSet<string>>? Equipment { get; set; }
|
||||
public Dictionary<string, HashSet<MongoId>>? Equipment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key: equipment slot name e.g. FirstPrimaryWeapon, value: item tpls
|
||||
/// </summary>
|
||||
[JsonPropertyName("gear")]
|
||||
public Dictionary<EquipmentSlots, HashSet<string>>? Gear { get; set; }
|
||||
public Dictionary<EquipmentSlots, HashSet<MongoId>>? Gear { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key: cartridge type e.g. Caliber23x75, value: item tpls
|
||||
/// </summary>
|
||||
[JsonPropertyName("cartridge")]
|
||||
public Dictionary<string, HashSet<string>>? Cartridge { get; set; }
|
||||
public Dictionary<string, HashSet<MongoId>>? Cartridge { get; set; }
|
||||
}
|
||||
|
||||
public record WeightingAdjustmentDetails
|
||||
|
||||
@@ -133,7 +133,7 @@ public record CultistCircleSettings
|
||||
/// Item tpls to exclude from the reward pool
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardItemBlacklist")]
|
||||
public required List<string> RewardItemBlacklist { get; set; }
|
||||
public required List<MongoId> RewardItemBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item tpls to include in the reward pool
|
||||
@@ -142,7 +142,7 @@ public record CultistCircleSettings
|
||||
public required List<string> AdditionalRewardItemPool { get; set; }
|
||||
|
||||
[JsonPropertyName("currencyRewards")]
|
||||
public required Dictionary<string, MinMax<int>> CurrencyRewards { get; set; }
|
||||
public required Dictionary<MongoId, MinMax<int>> CurrencyRewards { get; set; }
|
||||
}
|
||||
|
||||
public record CraftTimeThreshold : MinMax<int>
|
||||
|
||||
@@ -57,7 +57,7 @@ public record RewardDetails
|
||||
public Dictionary<string, double>? RewardTplPool { get; set; }
|
||||
|
||||
[JsonPropertyName("rewardTypePool")]
|
||||
public List<string>? RewardTypePool { get; set; }
|
||||
public List<MongoId>? RewardTypePool { get; set; }
|
||||
}
|
||||
|
||||
public record SealedAirdropContainerSettings
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Spt.Config;
|
||||
@@ -12,34 +13,34 @@ public record ItemConfig : BaseConfig
|
||||
/// Items that should be globally blacklisted
|
||||
/// </summary>
|
||||
[JsonPropertyName("blacklist")]
|
||||
public required HashSet<string> Blacklist { get; set; }
|
||||
public required HashSet<MongoId> Blacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items that should not be lootable from any location
|
||||
/// </summary>
|
||||
[JsonPropertyName("lootableItemBlacklist")]
|
||||
public required HashSet<string> LootableItemBlacklist { get; set; }
|
||||
public required HashSet<MongoId> LootableItemBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// items that should not be given as rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardItemBlacklist")]
|
||||
public required HashSet<string> RewardItemBlacklist { get; set; }
|
||||
public required HashSet<MongoId> RewardItemBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item base types that should not be given as rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardItemTypeBlacklist")]
|
||||
public required HashSet<string> RewardItemTypeBlacklist { get; set; }
|
||||
public required HashSet<MongoId> RewardItemTypeBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items that can only be found on bosses
|
||||
/// </summary>
|
||||
[JsonPropertyName("bossItems")]
|
||||
public required HashSet<string> BossItems { get; set; }
|
||||
public required HashSet<MongoId> BossItems { get; set; }
|
||||
|
||||
[JsonPropertyName("handbookPriceOverride")]
|
||||
public required Dictionary<string, HandbookPriceOverride> HandbookPriceOverride { get; set; }
|
||||
public required Dictionary<MongoId, HandbookPriceOverride> HandbookPriceOverride { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Presets to add to the globals.json `ItemPresets` dictionary on server start
|
||||
@@ -63,5 +64,5 @@ public record HandbookPriceOverride
|
||||
/// NOT parentId from items.json, but handbook.json
|
||||
/// </summary>
|
||||
[JsonPropertyName("parentId")]
|
||||
public string? ParentId { get; set; } = string.Empty;
|
||||
public MongoId ParentId { get; set; } = MongoId.Empty();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public record PmcConfig : BaseConfig
|
||||
public required SlotLootSettings BackpackLoot { get; set; }
|
||||
|
||||
[JsonPropertyName("globalLootBlacklist")]
|
||||
public required List<string> GlobalLootBlacklist { get; set; }
|
||||
public required List<MongoId> GlobalLootBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use difficulty defined in config/bot.json/difficulty instead of chosen difficulty dropdown value
|
||||
@@ -206,13 +206,13 @@ public record SlotLootSettings
|
||||
/// Item Type whitelist
|
||||
/// </summary>
|
||||
[JsonPropertyName("whitelist")]
|
||||
public HashSet<string> Whitelist { get; set; } = [];
|
||||
public HashSet<MongoId> Whitelist { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Item tpl blacklist
|
||||
/// </summary>
|
||||
[JsonPropertyName("blacklist")]
|
||||
public HashSet<string> Blacklist { get; set; } = [];
|
||||
public HashSet<MongoId> Blacklist { get; set; } = [];
|
||||
}
|
||||
|
||||
public record MinMaxLootValue : MinMax<int>
|
||||
|
||||
@@ -206,13 +206,13 @@ public record RepeatableQuestConfig
|
||||
/// Item base types to block when generating rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardBaseTypeBlacklist")]
|
||||
public required HashSet<string> RewardBaseTypeBlacklist { get; set; }
|
||||
public required HashSet<MongoId> RewardBaseTypeBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item tplIds to ignore when generating rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardBlacklist")]
|
||||
public required HashSet<string> RewardBlacklist { get; set; }
|
||||
public required HashSet<MongoId> RewardBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum stack size that an ammo reward should be generated with
|
||||
@@ -476,7 +476,7 @@ public record Completion : BaseQuestConfig
|
||||
/// Blacklisted item types to not collect
|
||||
/// </summary>
|
||||
[JsonPropertyName("requiredItemTypeBlacklist")]
|
||||
public HashSet<string>? RequiredItemTypeBlacklist { get; set; }
|
||||
public HashSet<MongoId>? RequiredItemTypeBlacklist { get; set; }
|
||||
}
|
||||
|
||||
public record Pickup : BaseQuestConfig
|
||||
|
||||
@@ -37,22 +37,22 @@ public record LootRequest
|
||||
/// Item tpl blacklist to exclude
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemBlacklist")]
|
||||
public HashSet<string>? ItemBlacklist { get; set; }
|
||||
public HashSet<MongoId>? ItemBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item tpl whitelist to pick from
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemTypeWhitelist")]
|
||||
public List<string>? ItemTypeWhitelist { get; set; }
|
||||
public List<MongoId>? ItemTypeWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// key: item base type: value: max count
|
||||
/// </summary>
|
||||
[JsonPropertyName("itemLimits")]
|
||||
public Dictionary<string, int>? ItemLimits { get; set; }
|
||||
public Dictionary<MongoId, int>? ItemLimits { get; set; }
|
||||
|
||||
[JsonPropertyName("itemStackLimits")]
|
||||
public Dictionary<string, MinMax<int>>? ItemStackLimits { get; set; }
|
||||
public Dictionary<MongoId, MinMax<int>>? ItemStackLimits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allowed armor plate levels 2/3/4/5/6 for armor generated
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
|
||||
@@ -16,7 +17,7 @@ public record Templates
|
||||
public List<CustomisationStorage>? CustomisationStorage { get; set; }
|
||||
|
||||
[JsonPropertyName("items")]
|
||||
public Dictionary<string, TemplateItem>? Items { get; set; }
|
||||
public Dictionary<MongoId, TemplateItem>? Items { get; set; }
|
||||
|
||||
[JsonPropertyName("prestige")]
|
||||
public Prestige? Prestige { get; set; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Generators;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Location;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -255,7 +256,7 @@ public class AirdropService(
|
||||
)
|
||||
.Select(templateItem => templateItem.Id)
|
||||
.ToHashSet();
|
||||
var itemBlacklist = new HashSet<string>();
|
||||
var itemBlacklist = new HashSet<MongoId>();
|
||||
itemBlacklist.UnionWith(lootSettingsByType.ItemBlacklist);
|
||||
itemBlacklist.UnionWith(_itemFilterService.GetItemRewardBlacklist());
|
||||
itemBlacklist.UnionWith(_itemFilterService.GetBossItems());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
@@ -19,11 +20,11 @@ public class BotEquipmentModPoolService(
|
||||
|
||||
private ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
>? _gearModPool;
|
||||
protected ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
> GearModPool
|
||||
{
|
||||
get
|
||||
@@ -37,11 +38,11 @@ public class BotEquipmentModPoolService(
|
||||
|
||||
private ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
>? _weaponModPool;
|
||||
protected ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
> WeaponModPool
|
||||
{
|
||||
get
|
||||
@@ -60,7 +61,7 @@ public class BotEquipmentModPoolService(
|
||||
/// <param name="poolType"> Mod pool to choose from e.g. "weapon" for weaponModPool </param>
|
||||
protected ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
> GeneratePool(IEnumerable<TemplateItem>? inputItems, string poolType)
|
||||
{
|
||||
if (inputItems is null || !inputItems.Any())
|
||||
@@ -73,7 +74,7 @@ public class BotEquipmentModPoolService(
|
||||
}
|
||||
|
||||
var pool =
|
||||
new ConcurrentDictionary<string, ConcurrentDictionary<string, HashSet<string>>>();
|
||||
new ConcurrentDictionary<string, ConcurrentDictionary<string, HashSet<MongoId>>>();
|
||||
foreach (var item in inputItems)
|
||||
{
|
||||
if (item.Properties is null)
|
||||
@@ -95,7 +96,7 @@ public class BotEquipmentModPoolService(
|
||||
}
|
||||
|
||||
// Add base item (weapon/armor) to pool
|
||||
pool.TryAdd(item.Id, new ConcurrentDictionary<string, HashSet<string>>());
|
||||
pool.TryAdd(item.Id, new ConcurrentDictionary<string, HashSet<MongoId>>());
|
||||
|
||||
// Iterate over each items mod slots e.g. mod_muzzle
|
||||
foreach (var slot in item.Properties.Slots)
|
||||
@@ -134,7 +135,7 @@ public class BotEquipmentModPoolService(
|
||||
return pool;
|
||||
}
|
||||
|
||||
private bool SetContainsTpl(HashSet<string> itemSet, string tpl)
|
||||
private bool SetContainsTpl(HashSet<MongoId> itemSet, string tpl)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
@@ -142,7 +143,7 @@ public class BotEquipmentModPoolService(
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddTplToSet(HashSet<string> itemSet, string itemToAddTpl)
|
||||
private bool AddTplToSet(HashSet<MongoId> itemSet, string itemToAddTpl)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
@@ -151,7 +152,7 @@ public class BotEquipmentModPoolService(
|
||||
}
|
||||
|
||||
private bool InitSetInDict(
|
||||
ConcurrentDictionary<string, HashSet<string>> dictionary,
|
||||
ConcurrentDictionary<string, HashSet<MongoId>> dictionary,
|
||||
string slotName
|
||||
)
|
||||
{
|
||||
@@ -175,7 +176,7 @@ public class BotEquipmentModPoolService(
|
||||
/// <param name="itemTpl"> Item to look up </param>
|
||||
/// <param name="slotName"> Slot to get compatible mods for </param>
|
||||
/// <returns> Hashset of tpls that fit the slot </returns>
|
||||
public HashSet<string> GetCompatibleModsForWeaponSlot(string itemTpl, string slotName)
|
||||
public HashSet<MongoId> GetCompatibleModsForWeaponSlot(string itemTpl, string slotName)
|
||||
{
|
||||
if (WeaponModPool.TryGetValue(itemTpl, out var value))
|
||||
{
|
||||
@@ -194,7 +195,7 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
/// <param name="itemTpl"> Items tpl to look up mods for </param>
|
||||
/// <returns> Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value </returns>
|
||||
public ConcurrentDictionary<string, HashSet<string>> GetModsForGearSlot(string itemTpl)
|
||||
public ConcurrentDictionary<string, HashSet<MongoId>> GetModsForGearSlot(string itemTpl)
|
||||
{
|
||||
return GearModPool.TryGetValue(itemTpl, out var value) ? value : [];
|
||||
}
|
||||
@@ -204,7 +205,7 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
/// <param name="itemTpl"> Weapons tpl to look up mods for </param>
|
||||
/// <returns> Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value </returns>
|
||||
public ConcurrentDictionary<string, HashSet<string>> GetModsForWeaponSlot(string itemTpl)
|
||||
public ConcurrentDictionary<string, HashSet<MongoId>> GetModsForWeaponSlot(string itemTpl)
|
||||
{
|
||||
return WeaponModPool.TryGetValue(itemTpl, out var value) ? value : [];
|
||||
}
|
||||
@@ -214,9 +215,9 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
/// <param name="itemTpl"> Weapons tpl to look up mods for </param>
|
||||
/// <returns> Dictionary of mods (keys are mod slot names) with array of compatible mod tpls as value </returns>
|
||||
public Dictionary<string, HashSet<string>>? GetRequiredModsForWeaponSlot(string itemTpl)
|
||||
public Dictionary<string, HashSet<MongoId>>? GetRequiredModsForWeaponSlot(string itemTpl)
|
||||
{
|
||||
var result = new Dictionary<string, HashSet<string>>();
|
||||
var result = new Dictionary<string, HashSet<MongoId>>();
|
||||
|
||||
// Get item from db
|
||||
var itemDb = itemHelper.GetItem(itemTpl).Value;
|
||||
@@ -248,7 +249,7 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
protected ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
> GenerateWeaponPool()
|
||||
{
|
||||
var weaponsAndMods = databaseService
|
||||
@@ -267,7 +268,7 @@ public class BotEquipmentModPoolService(
|
||||
/// </summary>
|
||||
protected ConcurrentDictionary<
|
||||
string,
|
||||
ConcurrentDictionary<string, HashSet<string>>
|
||||
ConcurrentDictionary<string, HashSet<MongoId>>
|
||||
> GenerateGearPool()
|
||||
{
|
||||
var gearAndMods = databaseService
|
||||
|
||||
@@ -711,7 +711,7 @@ public class CircleOfCultistService(
|
||||
.Select(templateItem => templateItem.Key);
|
||||
|
||||
// Create set of unique values to ignore
|
||||
var itemRewardBlacklist = new HashSet<string>();
|
||||
var itemRewardBlacklist = new HashSet<MongoId>();
|
||||
itemRewardBlacklist.UnionWith(_seasonalEventService.GetInactiveSeasonalEventItems());
|
||||
itemRewardBlacklist.UnionWith(_itemFilterService.GetItemRewardBlacklist());
|
||||
itemRewardBlacklist.UnionWith(_itemFilterService.GetBlacklistedItems());
|
||||
@@ -785,7 +785,7 @@ public class CircleOfCultistService(
|
||||
/// <param name="rewardPool">Pool to add items to</param>
|
||||
protected void AddTaskItemRequirementsToRewardPool(
|
||||
PmcData pmcData,
|
||||
HashSet<string> itemRewardBlacklist,
|
||||
HashSet<MongoId> itemRewardBlacklist,
|
||||
HashSet<string> rewardPool
|
||||
)
|
||||
{
|
||||
@@ -826,7 +826,7 @@ public class CircleOfCultistService(
|
||||
protected void AddHideoutUpgradeRequirementsToRewardPool(
|
||||
Hideout hideoutDbData,
|
||||
PmcData pmcData,
|
||||
HashSet<string> itemRewardBlacklist,
|
||||
HashSet<MongoId> itemRewardBlacklist,
|
||||
HashSet<string> rewardPool
|
||||
)
|
||||
{
|
||||
@@ -900,7 +900,7 @@ public class CircleOfCultistService(
|
||||
/// <returns>Set of item tpls</returns>
|
||||
protected HashSet<string> GenerateRandomisedItemsAndAddToRewardPool(
|
||||
HashSet<string> rewardPool,
|
||||
HashSet<string> itemRewardBlacklist,
|
||||
HashSet<MongoId> itemRewardBlacklist,
|
||||
bool itemsShouldBeHighValue
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics;
|
||||
using SPTarkov.Common.Extensions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Spt.Bots;
|
||||
@@ -263,7 +264,7 @@ public class DatabaseService(
|
||||
}
|
||||
|
||||
/// <returns> assets/database/templates/items.json </returns>
|
||||
public Dictionary<string, TemplateItem> GetItems()
|
||||
public Dictionary<MongoId, TemplateItem> GetItems()
|
||||
{
|
||||
if (_databaseServer.GetTables().Templates?.Items == null)
|
||||
{
|
||||
@@ -423,6 +424,20 @@ public class DatabaseService(
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ValidateTable<T>(Dictionary<MongoId, T> table, string tableType)
|
||||
{
|
||||
foreach (var keyValuePair in table)
|
||||
{
|
||||
if (!_hashUtil.IsValidMongoId(keyValuePair.Key))
|
||||
{
|
||||
_logger.Error($"Invalid {tableType} ID: '{keyValuePair.Key}'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the database is valid
|
||||
/// </summary>
|
||||
|
||||
@@ -1552,10 +1552,11 @@ public class FenceService(
|
||||
|
||||
// Randomise armor durability
|
||||
if (
|
||||
itemDetails.Parent
|
||||
is BaseClasses.ARMORED_EQUIPMENT
|
||||
or BaseClasses.FACECOVER
|
||||
or BaseClasses.ARMOR_PLATE
|
||||
(
|
||||
itemDetails.Parent == BaseClasses.ARMORED_EQUIPMENT
|
||||
|| itemDetails.Parent == BaseClasses.FACECOVER
|
||||
|| itemDetails.Parent == BaseClasses.ARMOR_PLATE
|
||||
)
|
||||
&& itemDetails.Properties.MaxDurability.GetValueOrDefault(0) > 0
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
using SPTarkov.Server.Core.Servers;
|
||||
@@ -16,10 +17,10 @@ public class ItemFilterService(
|
||||
ConfigServer _configServer
|
||||
)
|
||||
{
|
||||
protected readonly HashSet<string>? _itemBlacklistCache = [];
|
||||
protected readonly HashSet<MongoId>? _itemBlacklistCache = [];
|
||||
protected readonly ItemConfig _itemConfig = _configServer.GetConfig<ItemConfig>();
|
||||
|
||||
protected readonly HashSet<string>? _lootableItemBlacklistCache = [];
|
||||
protected readonly HashSet<MongoId>? _lootableItemBlacklistCache = [];
|
||||
|
||||
/// <summary>
|
||||
/// Check if the provided template id is blacklisted in config/item.json/blacklist
|
||||
@@ -50,7 +51,7 @@ public class ItemFilterService(
|
||||
/// Get an HashSet of items that should never be given as a reward to player
|
||||
/// </summary>
|
||||
/// <returns> HashSet of item tpls </returns>
|
||||
public HashSet<string> GetItemRewardBlacklist()
|
||||
public HashSet<MongoId> GetItemRewardBlacklist()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.RewardItemBlacklist);
|
||||
}
|
||||
@@ -59,7 +60,7 @@ public class ItemFilterService(
|
||||
/// Get an HashSet of item types that should never be given as a reward to player
|
||||
/// </summary>
|
||||
/// <returns> HashSet of item base ids </returns>
|
||||
public HashSet<string> GetItemRewardBaseTypeBlacklist()
|
||||
public HashSet<MongoId> GetItemRewardBaseTypeBlacklist()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.RewardItemTypeBlacklist);
|
||||
}
|
||||
@@ -68,7 +69,7 @@ public class ItemFilterService(
|
||||
/// Return every template id blacklisted in config/item.json
|
||||
/// </summary>
|
||||
/// <returns> HashSet of blacklisted template ids </returns>
|
||||
public HashSet<string> GetBlacklistedItems()
|
||||
public HashSet<MongoId> GetBlacklistedItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.Blacklist);
|
||||
}
|
||||
@@ -77,7 +78,7 @@ public class ItemFilterService(
|
||||
/// Return every template id blacklisted in config/item.json/lootableItemBlacklist
|
||||
/// </summary>
|
||||
/// <returns> HashSet of blacklisted template ids </returns>
|
||||
public HashSet<string> GetBlacklistedLootableItems()
|
||||
public HashSet<MongoId> GetBlacklistedLootableItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.LootableItemBlacklist);
|
||||
}
|
||||
@@ -96,7 +97,7 @@ public class ItemFilterService(
|
||||
/// Return boss items in config/item.json
|
||||
/// </summary>
|
||||
/// <returns> HashSet of boss item template ids </returns>
|
||||
public HashSet<string> GetBossItems()
|
||||
public HashSet<MongoId> GetBossItems()
|
||||
{
|
||||
return _cloner.Clone(_itemConfig.BossItems).ToHashSet();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Reflection;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Mod;
|
||||
@@ -320,7 +321,7 @@ public class CustomItemService(
|
||||
return;
|
||||
}
|
||||
|
||||
var baseWeaponModObject = new Dictionary<string, HashSet<string>?>();
|
||||
var baseWeaponModObject = new Dictionary<string, HashSet<MongoId>?>();
|
||||
|
||||
// Get all slots weapon has and create a dictionary of them with possible mods that slot into each
|
||||
var weaponSlots = weapon.Value.Properties.Slots;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Text.RegularExpressions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Hideout;
|
||||
@@ -862,7 +863,7 @@ public class ProfileFixerService(
|
||||
protected bool ShouldRemoveWeaponEquipmentBuild(
|
||||
string buildType,
|
||||
UserBuild build,
|
||||
Dictionary<string, TemplateItem> itemsDb
|
||||
Dictionary<MongoId, TemplateItem> itemsDb
|
||||
)
|
||||
{
|
||||
if (buildType == "weapon")
|
||||
@@ -931,7 +932,7 @@ public class ProfileFixerService(
|
||||
/// <returns> True if the build should be removed from the build list, false otherwise </returns>
|
||||
protected bool ShouldRemoveMagazineBuild(
|
||||
MagazineBuild magazineBuild,
|
||||
Dictionary<string, TemplateItem> itemsDb
|
||||
Dictionary<MongoId, TemplateItem> itemsDb
|
||||
)
|
||||
{
|
||||
foreach (var item in magazineBuild.Items)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
@@ -13,9 +14,9 @@ public class RagfairLinkedItemService(
|
||||
ISptLogger<RagfairLinkedItemService> logger
|
||||
)
|
||||
{
|
||||
protected readonly Dictionary<string, HashSet<string>> linkedItemsCache = new();
|
||||
protected readonly Dictionary<string, HashSet<MongoId>> linkedItemsCache = new();
|
||||
|
||||
public HashSet<string> GetLinkedItems(string linkedSearchId)
|
||||
public HashSet<MongoId> GetLinkedItems(string linkedSearchId)
|
||||
{
|
||||
if (!linkedItemsCache.TryGetValue(linkedSearchId, out var set))
|
||||
{
|
||||
@@ -60,7 +61,7 @@ public class RagfairLinkedItemService(
|
||||
/// </summary>
|
||||
protected void BuildLinkedItemTable()
|
||||
{
|
||||
var linkedItems = new Dictionary<string, HashSet<string>>();
|
||||
var linkedItems = new Dictionary<string, HashSet<MongoId>>();
|
||||
|
||||
foreach (var item in databaseService.GetItems().Values)
|
||||
{
|
||||
@@ -117,7 +118,7 @@ public class RagfairLinkedItemService(
|
||||
/// <param name="itemLinkedSet"> Set to add to </param>
|
||||
protected void AddRevolverCylinderAmmoToLinkedItems(
|
||||
TemplateItem cylinder,
|
||||
HashSet<string> itemLinkedSet
|
||||
HashSet<MongoId> itemLinkedSet
|
||||
)
|
||||
{
|
||||
var cylinderMod = cylinder.Properties.Slots?.FirstOrDefault(x => x.Name == "mod_magazine");
|
||||
@@ -144,9 +145,9 @@ public class RagfairLinkedItemService(
|
||||
/// </summary>
|
||||
/// <param name="item">Db item to get tpls from</param>
|
||||
/// <returns>Set of tpls</returns>
|
||||
protected HashSet<string> GetSlotFilters(TemplateItem item)
|
||||
protected HashSet<MongoId> GetSlotFilters(TemplateItem item)
|
||||
{
|
||||
var result = new HashSet<string>();
|
||||
var result = new HashSet<MongoId>();
|
||||
|
||||
var slots = item.Properties?.Slots;
|
||||
if (slots is null || slots.Count == 0)
|
||||
@@ -172,9 +173,9 @@ public class RagfairLinkedItemService(
|
||||
return result;
|
||||
}
|
||||
|
||||
protected HashSet<string> GetChamberFilters(TemplateItem item)
|
||||
protected HashSet<MongoId> GetChamberFilters(TemplateItem item)
|
||||
{
|
||||
var result = new HashSet<string>();
|
||||
var result = new HashSet<MongoId>();
|
||||
|
||||
var chambers = item.Properties?.Chambers;
|
||||
if (chambers is null || chambers.Count == 0)
|
||||
@@ -198,9 +199,9 @@ public class RagfairLinkedItemService(
|
||||
return result;
|
||||
}
|
||||
|
||||
protected HashSet<string> GetCartridgeFilters(TemplateItem item)
|
||||
protected HashSet<MongoId> GetCartridgeFilters(TemplateItem item)
|
||||
{
|
||||
var result = new HashSet<string>();
|
||||
var result = new HashSet<MongoId>();
|
||||
|
||||
var cartridges = item.Properties?.Cartridges;
|
||||
if (cartridges is null || cartridges.Count == 0)
|
||||
|
||||
@@ -2,6 +2,7 @@ using SPTarkov.Common.Extensions;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
@@ -151,17 +152,17 @@ public class SeasonalEventService(
|
||||
/// or, if halloween and christmas are inactive, return both sets of items
|
||||
/// </summary>
|
||||
/// <returns>array of tpl strings</returns>
|
||||
public HashSet<string> GetInactiveSeasonalEventItems()
|
||||
public HashSet<MongoId> GetInactiveSeasonalEventItems()
|
||||
{
|
||||
var items = new HashSet<string>();
|
||||
var items = new HashSet<MongoId>();
|
||||
if (!ChristmasEventEnabled())
|
||||
{
|
||||
items.UnionWith(_christmasEventItems);
|
||||
items.UnionWith(_christmasEventItems.ToMongoIds());
|
||||
}
|
||||
|
||||
if (!HalloweenEventEnabled())
|
||||
{
|
||||
items.UnionWith(_halloweenEventItems);
|
||||
items.UnionWith(_halloweenEventItems.ToMongoIds());
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
@@ -144,14 +144,14 @@ public class ProbabilityObjectArray<K, V> : List<ProbabilityObject<K, V>>
|
||||
return this.Min(x => x.RelativeProbability.Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw random element of the ProbabilityObject N times to return an array of N keys.
|
||||
* Drawing can be with or without replacement
|
||||
* @param count The number of times we want to draw
|
||||
* @param removeAfterDraw Draw with or without replacement from the input dict (true = dont remove after drawing)
|
||||
* @param lockList list keys which shall be replaced even if drawing without replacement
|
||||
* @returns Array consisting of N random keys for this ProbabilityObjectArray
|
||||
*/
|
||||
/// <summary>
|
||||
/// Draw random element of the ProbabilityObject N times to return an array of N keys.
|
||||
/// Drawing can be with or without replacement
|
||||
/// </summary>
|
||||
/// <param name="drawCount">The number of times we want to draw</param>
|
||||
/// <param name="removeAfterDraw">Draw with or without replacement from the input dict (true = don't remove after drawing)</param>
|
||||
/// <param name="neverRemoveWhitelist">List of keys which shall be replaced even if drawing without replacement</param>
|
||||
/// <returns>Collection consisting of N random keys for this ProbabilityObjectArray</returns>
|
||||
public List<K> Draw(
|
||||
int drawCount = 1,
|
||||
bool removeAfterDraw = true,
|
||||
|
||||
@@ -3,6 +3,7 @@ using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Callbacks;
|
||||
using SPTarkov.Server.Core.DI;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
@@ -26,7 +27,7 @@ public class ItemTplGenerator(
|
||||
private readonly HashSet<string> collidedEnumKeys = [];
|
||||
private string _enumDir;
|
||||
private IDictionary<string, string> _itemOverrides;
|
||||
private Dictionary<string, TemplateItem> _items;
|
||||
private Dictionary<MongoId, TemplateItem> _items;
|
||||
|
||||
public async Task Run()
|
||||
{
|
||||
@@ -420,20 +421,16 @@ public class ItemTplGenerator(
|
||||
|
||||
private string GetAmmoBoxPrefix(TemplateItem item)
|
||||
{
|
||||
var ammoItem = item.Properties?.StackSlots?[0]?.Props?.Filters?[
|
||||
0
|
||||
]?.Filter?.FirstOrDefault();
|
||||
var ammoTpl = item.Properties?.StackSlots?[0]?.Props?.Filters?[0]?.Filter?.FirstOrDefault();
|
||||
|
||||
return GetAmmoPrefix(_items[ammoItem]);
|
||||
return GetAmmoPrefix(_items[ammoTpl.Value]);
|
||||
}
|
||||
|
||||
private string GetMagazinePrefix(TemplateItem item)
|
||||
{
|
||||
var ammoItem = item.Properties?.Cartridges?[0]?.Props?.Filters?[
|
||||
0
|
||||
]?.Filter?.FirstOrDefault();
|
||||
var ammoTpl = item.Properties?.Cartridges?[0]?.Props?.Filters?[0]?.Filter?.FirstOrDefault();
|
||||
|
||||
return GetAmmoPrefix(_items[ammoItem]);
|
||||
return GetAmmoPrefix(_items[ammoTpl.Value]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user