diff --git a/Libraries/Core/Controllers/LocationController.cs b/Libraries/Core/Controllers/LocationController.cs
index 0c2708ec..4b8a0342 100644
--- a/Libraries/Core/Controllers/LocationController.cs
+++ b/Libraries/Core/Controllers/LocationController.cs
@@ -61,13 +61,7 @@ public class LocationController(
///
public GetAirdropLootResponse? GetAirDropLoot(GetAirdropLootRequest? request)
{
- if (request is null)
- {
- // client sometimes requests this after a raid has ended, just return null
- return null;
- }
-
- if (request.ContainerId is not null)
+ if (request?.ContainerId is not null)
{
return _airdropService.GenerateCustomAirdropLoot(request);
}
diff --git a/Libraries/Core/Generators/BotWeaponGenerator.cs b/Libraries/Core/Generators/BotWeaponGenerator.cs
index 7a625bda..7746a9dd 100644
--- a/Libraries/Core/Generators/BotWeaponGenerator.cs
+++ b/Libraries/Core/Generators/BotWeaponGenerator.cs
@@ -33,7 +33,7 @@ public class BotWeaponGenerator(
IEnumerable inventoryMagGenComponents
)
{
- protected List _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents);
+ protected IEnumerable _inventoryMagGenComponents = MagGenSetUp(inventoryMagGenComponents);
protected BotConfig _botConfig = _configServer.GetConfig();
protected PmcConfig _pmcConfig = _configServer.GetConfig();
protected RepairConfig _repairConfig = _configServer.GetConfig();
@@ -42,13 +42,8 @@ public class BotWeaponGenerator(
private static List MagGenSetUp(IEnumerable components)
{
var inventoryMagGens = components.ToList();
- inventoryMagGens.ToList()
- .Sort(
- (a, b) =>
- a.GetPriority() -
- b.GetPriority()
- );
- return inventoryMagGens.ToList();
+ inventoryMagGens.Sort((a, b) => a.GetPriority() - b.GetPriority());
+ return inventoryMagGens;
}
///
@@ -398,7 +393,7 @@ public class BotWeaponGenerator(
return;
}
-
+ var isInternalMag = magTemplate.Properties.ReloadMagType == "InternalMagazine";
var ammoTemplate = _itemHelper.GetItem(generatedWeaponResult.ChosenAmmoTemplate).Value;
if (ammoTemplate is null)
{
@@ -722,7 +717,6 @@ public class BotWeaponGenerator(
/// Weapon items list to amend
/// Magazine item details we're adding cartridges to
/// Cartridge to put into the magazine
- /// How many cartridges should go into the magazine
/// Magazines db template
protected void AddOrUpdateMagazinesChildWithAmmo(List- weaponWithMods, Item magazine, string chosenAmmoTpl, TemplateItem magazineTemplate)
{
@@ -736,8 +730,7 @@ public class BotWeaponGenerator(
}
// Create array with just magazine
- List
- magazineWithCartridges = new();
- magazineWithCartridges.AddRange(magazine);
+ List
- magazineWithCartridges = [magazine];
// Add full cartridge child items to above array
_itemHelper.FillMagazineWithCartridge(magazineWithCartridges, magazineTemplate, chosenAmmoTpl, 1);
diff --git a/Libraries/Core/Generators/LootGenerator.cs b/Libraries/Core/Generators/LootGenerator.cs
index a9af4b6a..3e29b8da 100644
--- a/Libraries/Core/Generators/LootGenerator.cs
+++ b/Libraries/Core/Generators/LootGenerator.cs
@@ -21,8 +21,10 @@ public class LootGenerator(
ItemHelper _itemHelper,
PresetHelper _presetHelper,
DatabaseService _databaseService,
- ItemFilterService _itemFilterService
-
+ ItemFilterService _itemFilterService,
+ LocalisationService _localisationService,
+ WeightedRandomHelper _weightedRandomHelper,
+ RagfairLinkedItemService _ragfairLinkedItemService
)
{
@@ -278,8 +280,8 @@ public class LootGenerator(
{
var randomItem = _randomUtil.GetArrayValue(items);
- var itemLimitCount = itemTypeCounts[randomItem.Parent];
- if (itemLimitCount is not null && itemLimitCount.Current > itemLimitCount.Max) {
+ var itemLimitCount = itemTypeCounts.TryGetValue(randomItem.Parent, out var randomItemLimitCount);
+ if (!itemLimitCount && randomItemLimitCount?.Current > randomItemLimitCount?.Max) {
return false;
}
@@ -291,7 +293,7 @@ public class LootGenerator(
var newLootItem = new Item {
Id = _hashUtil.Generate(),
Template = randomItem.Id,
- Upd = {
+ Upd = new Upd {
StackObjectsCount = 1,
SpawnedInSession = true,
},
@@ -305,9 +307,9 @@ public class LootGenerator(
newLootItem.Template = randomItem.Id;
result.Add(newLootItem);
- if (itemLimitCount is not null) {
+ if (randomItemLimitCount is not null) {
// Increment item count as it's in limit array
- itemLimitCount.Current++;
+ randomItemLimitCount.Current++;
}
// Item added okay
@@ -322,7 +324,15 @@ public class LootGenerator(
/// stack count
protected int GetRandomisedStackCount(TemplateItem item, LootRequest options)
{
- throw new NotImplementedException();
+ var min = item.Properties.StackMinRandom;
+ var max = item.Properties.StackMaxSize;
+
+ if (options.ItemStackLimits.TryGetValue(item.Id, out var itemLimits)) {
+ min = itemLimits.Min;
+ max = (int?)itemLimits.Max;
+ }
+
+ return _randomUtil.GetInt((int)(min ?? 1), max ?? 1);
}
///
@@ -338,7 +348,61 @@ public class LootGenerator(
HashSet itemBlacklist,
List
- result)
{
- throw new NotImplementedException();
+ // Choose random preset and get details from item db using encyclopedia value (encyclopedia === tplId)
+ var chosenPreset = _randomUtil.GetArrayValue(presetPool);
+ if (chosenPreset is null ) {
+ _logger.Warning("Unable to find random preset in given presets, skipping");
+
+ return false;
+ }
+
+ // No `_encyclopedia` property, not possible to reliably get root item tpl
+ if (chosenPreset.Encyclopedia is null) {
+ _logger.Debug("$Preset with id: {chosenPreset?.Id} lacks encyclopedia property, skipping");
+
+ return false;
+ }
+
+ // Get preset root item db details via its `_encyclopedia` property
+ var itemDbDetails = _itemHelper.GetItem(chosenPreset.Encyclopedia);
+ if (!itemDbDetails.Key) {
+ _logger.Debug($"$Unable to find preset with tpl: {chosenPreset.Encyclopedia}, skipping");
+
+ return false;
+ }
+
+ // Skip preset if root item is blacklisted
+ if (itemBlacklist.Contains(chosenPreset.Items[0].Template)) {
+ return false;
+ }
+
+ // Some custom mod items lack a parent property
+ if (itemDbDetails.Value.Parent is null) {
+ _logger.Error(_localisationService.GetText("loot-item_missing_parentid", itemDbDetails.Value?.Name));
+
+ return false;
+ }
+
+ // Check chosen preset hasn't exceeded spawn limit
+ var hasItemLimitCount = itemTypeCounts.TryGetValue(itemDbDetails.Value.Parent, out var itemLimitCount);
+ if (!hasItemLimitCount && itemLimitCount?.Current > itemLimitCount?.Max) {
+ return false;
+ }
+
+ var presetAndMods = _itemHelper.ReplaceIDs(chosenPreset.Items);
+ _itemHelper.RemapRootItemId(presetAndMods);
+ // Add chosen preset tpl to result array
+ foreach (var item in presetAndMods) {
+ result.Add(item);
+ }
+
+ if (itemLimitCount is not null) {
+ // Increment item count as item has been chosen and its inside itemLimitCount dictionary
+ itemLimitCount.Current++;
+ }
+
+ // Item added okay
+ return true;
}
///
@@ -348,7 +412,52 @@ public class LootGenerator(
/// List of items with children lists
public List
> GetSealedWeaponCaseLoot(SealedAirdropContainerSettings containerSettings)
{
- throw new NotImplementedException();
+ List> itemsToReturn = [];
+
+ // Choose a weapon to give to the player (weighted)
+ var chosenWeaponTpl = _weightedRandomHelper.GetWeightedValue(
+ containerSettings.WeaponRewardWeight
+ );
+
+ // Get itemDb details of weapon
+ var weaponDetailsDb = _itemHelper.GetItem(chosenWeaponTpl);
+ if (!weaponDetailsDb.Key) {
+ _logger.Error(
+ _localisationService.GetText("loot-non_item_picked_as_sealed_weapon_crate_reward", chosenWeaponTpl)
+ );
+
+ return itemsToReturn;
+ }
+
+ // Get weapon preset - default or choose a random one from globals.json preset pool
+ var chosenWeaponPreset = containerSettings.DefaultPresetsOnly
+ ? _presetHelper.GetDefaultPreset(chosenWeaponTpl)
+ : _randomUtil.GetArrayValue(_presetHelper.GetPresets(chosenWeaponTpl));
+
+ // No default preset found for weapon, choose a random one
+ if (chosenWeaponPreset is null) {
+ _logger.Warning(
+ _localisationService.GetText("loot-default_preset_not_found_using_random", chosenWeaponTpl)
+ );
+ chosenWeaponPreset = _randomUtil.GetArrayValue(_presetHelper.GetPresets(chosenWeaponTpl));
+ }
+
+ // Clean up Ids to ensure they're all unique and prevent collisions
+ var presetAndMods = _itemHelper.ReplaceIDs(chosenWeaponPreset.Items);
+ _itemHelper.RemapRootItemId(presetAndMods);
+
+ // Add preset to return object
+ itemsToReturn.Add(presetAndMods);
+
+ // Get a random collection of weapon mods related to chosen weawpon and add them to result array
+ var linkedItemsToWeapon = _ragfairLinkedItemService.GetLinkedDbItems(chosenWeaponTpl);
+ itemsToReturn.AddRange(GetSealedContainerWeaponModRewards(containerSettings, linkedItemsToWeapon, chosenWeaponPreset)
+ );
+
+ // Handle non-weapon mod reward types
+ itemsToReturn.AddRange((GetSealedContainerNonWeaponModRewards(containerSettings, weaponDetailsDb.Value)));
+
+ return itemsToReturn;
}
///
@@ -360,7 +469,69 @@ public class LootGenerator(
protected List> GetSealedContainerNonWeaponModRewards(SealedAirdropContainerSettings containerSettings,
TemplateItem weaponDetailsDb)
{
- throw new NotImplementedException();
+ List> rewards = [];
+
+ foreach (var (rewardKey,settings) in containerSettings.RewardTypeLimits) {
+ var rewardCount = _randomUtil.GetDouble(settings.Min.Value, settings.Max.Value);
+
+ if (rewardCount == 0) {
+ continue;
+ }
+
+ // Edge case - ammo boxes
+ if (rewardKey == BaseClasses.AMMO_BOX) {
+ // Get ammoboxes from db
+ var ammoBoxesDetails = containerSettings.AmmoBoxWhitelist.Select((tpl) => {
+ var itemDetails = _itemHelper.GetItem(tpl);
+ return itemDetails.Value;
+ });
+
+ // Need to find boxes that matches weapons caliber
+ var weaponCaliber = weaponDetailsDb.Properties.AmmoCaliber;
+ var ammoBoxesMatchingCaliber = ammoBoxesDetails.Where((x) =>
+ x.Properties.AmmoCaliber == weaponCaliber);
+ if (!ammoBoxesMatchingCaliber.Any()) {
+ _logger.Debug($"No ammo box with caliber {weaponCaliber} found, skipping");
+
+ continue;
+ }
+
+ for (var index = 0; index < rewardCount; index++) {
+ var chosenAmmoBox = _randomUtil.GetArrayValue(ammoBoxesMatchingCaliber);
+ var ammoBoxReward = new List- { new() { Id = _hashUtil.Generate(), Template = chosenAmmoBox.Id } };
+ _itemHelper.AddCartridgesToAmmoBox(ammoBoxReward, chosenAmmoBox);
+ rewards.Add(ammoBoxReward);
+ }
+
+ continue;
+ }
+
+ // Get all items of the desired type + not quest items + not globally blacklisted
+ var rewardItemPool = _databaseService.GetItems().Values.Where(
+ (item) =>
+ item.Parent == rewardKey &&
+ item.Type.ToLower() == "item" &&
+ _itemFilterService.IsItemBlacklisted(item.Id) &&
+ !(containerSettings.AllowBossItems || _itemFilterService.IsBossItem(item.Id)) &&
+ item.Properties.QuestItem is null
+ );
+
+ if (rewardItemPool.Count() == 0) {
+ _logger.Debug($"No items with base type of {rewardKey} found, skipping");
+
+ continue;
+ }
+
+ for (var index = 0; index < rewardCount; index++) {
+ // Choose a random item from pool
+ var chosenRewardItem = _randomUtil.GetArrayValue(rewardItemPool);
+ var rewardItem = new List
- { new() { Id = _hashUtil.Generate(), Template = chosenRewardItem.Id } };
+
+ rewards.Add(rewardItem);
+ }
+ }
+
+ return rewards;
}
///
@@ -373,7 +544,37 @@ public class LootGenerator(
protected List
> GetSealedContainerWeaponModRewards(SealedAirdropContainerSettings containerSettings, List linkedItemsToWeapon,
Preset chosenWeaponPreset)
{
- throw new NotImplementedException();
+ List> modRewards = [];
+
+ foreach (var (rewardKey,settings) in containerSettings.WeaponModRewardLimits) {
+ var rewardCount = _randomUtil.GetDouble(settings.Min.Value, settings.Max.Value);
+
+ // Nothing to add, skip reward type
+ if (rewardCount == 0) {
+ continue;
+ }
+
+ // Get items that fulfil reward type criteria from items that fit on gun
+ var relatedItems = linkedItemsToWeapon?.Where(
+ (item) => item?.Parent == rewardKey && !_itemFilterService.IsItemBlacklisted(item.Id)
+ );
+ if (relatedItems is null || relatedItems.Count() == 0) {
+ _logger.Debug(
+ $"No items found to fulfil reward type: {rewardKey} for weapon: {chosenWeaponPreset.Name}, skipping type"
+ );
+ continue;
+ }
+
+ // Find a random item of the desired type and add as reward
+ for (var index = 0; index < rewardCount; index++) {
+ var chosenItem = _randomUtil.DrawRandomFromList(relatedItems.ToList());
+ var reward = new List- { new Item() { Id = _hashUtil.Generate(), Template = chosenItem[0].Id } };
+
+ modRewards.Add(reward);
+ }
+ }
+
+ return modRewards;
}
///
diff --git a/Libraries/Core/Models/Spt/Config/ItemConfig.cs b/Libraries/Core/Models/Spt/Config/ItemConfig.cs
index 2c962201..e57d2418 100644
--- a/Libraries/Core/Models/Spt/Config/ItemConfig.cs
+++ b/Libraries/Core/Models/Spt/Config/ItemConfig.cs
@@ -1,4 +1,4 @@
-using System.Text.Json.Serialization;
+using System.Text.Json.Serialization;
using Core.Models.Eft.Common;
namespace Core.Models.Spt.Config;
@@ -10,23 +10,23 @@ public record ItemConfig : BaseConfig
/** Items that should be globally blacklisted */
[JsonPropertyName("blacklist")]
- public List Blacklist { get; set; }
+ public HashSet Blacklist { get; set; }
/** Items that should not be lootable from any location */
[JsonPropertyName("lootableItemBlacklist")]
- public List LootableItemBlacklist { get; set; }
+ public HashSet LootableItemBlacklist { get; set; }
/** items that should not be given as rewards */
[JsonPropertyName("rewardItemBlacklist")]
- public List RewardItemBlacklist { get; set; }
+ public HashSet RewardItemBlacklist { get; set; }
/** Item base types that should not be given as rewards */
[JsonPropertyName("rewardItemTypeBlacklist")]
- public List RewardItemTypeBlacklist { get; set; }
+ public HashSet RewardItemTypeBlacklist { get; set; }
/** Items that can only be found on bosses */
[JsonPropertyName("bossItems")]
- public List BossItems { get; set; }
+ public HashSet BossItems { get; set; }
[JsonPropertyName("handbookPriceOverride")]
public Dictionary HandbookPriceOverride { get; set; }
diff --git a/Libraries/Core/Services/AirdropService.cs b/Libraries/Core/Services/AirdropService.cs
index 8abe2d67..1683d61b 100644
--- a/Libraries/Core/Services/AirdropService.cs
+++ b/Libraries/Core/Services/AirdropService.cs
@@ -51,7 +51,7 @@ public class AirdropService(
_logger.Debug($"Chose: {airdropType} for airdrop loot");
// Common/weapon/etc
- var airdropConfig = GetAirdropLootConfigByType((AirdropTypeEnum)airdropType);
+ var airdropConfig = GetAirdropLootConfigByType(airdropType);
// generate loot to put into airdrop crate
var crateLoot = airdropConfig.UseForcedLoot.GetValueOrDefault(false)
@@ -138,7 +138,7 @@ public class AirdropService(
///
/// Type of airdrop to get settings for
/// LootRequest
- protected AirdropLootRequest GetAirdropLootConfigByType(AirdropTypeEnum airdropType)
+ protected AirdropLootRequest GetAirdropLootConfigByType(SptAirdropTypeEnum? airdropType)
{
var lootSettingsByType = _airdropConfig.Loot[airdropType.ToString()];
if (lootSettingsByType is null) {
@@ -146,6 +146,7 @@ public class AirdropService(
_localisationService.GetText("location-unable_to_find_airdrop_drop_config_of_type", airdropType)
);
+ // TODO: Get Radar airdrop to work. Atm Radar will default to common supply drop (mixed)
// Default to common
lootSettingsByType = _airdropConfig.Loot[AirdropTypeEnum.Common.ToString()];
}
@@ -153,8 +154,9 @@ public class AirdropService(
// Get all items that match the blacklisted types and fold into item blacklist
var itemTypeBlacklist = _itemFilterService.GetItemRewardBaseTypeBlacklist();
var itemsMatchingTypeBlacklist = _itemHelper.GetItems()
- .Where((templateItem) => _itemHelper.IsOfBaseclasses(templateItem.Parent, itemTypeBlacklist))
- .Select((templateItem) => templateItem.Id);
+ .Where(templateItem => !string.IsNullOrEmpty(templateItem.Parent))
+ .Where(templateItem => _itemHelper.IsOfBaseclasses(templateItem.Parent, itemTypeBlacklist))
+ .Select(templateItem => templateItem.Id);
var itemBlacklist = new HashSet();
itemBlacklist.UnionWith(lootSettingsByType.ItemBlacklist);
itemBlacklist.UnionWith(_itemFilterService.GetItemRewardBlacklist());
diff --git a/Libraries/Core/Services/ItemBaseClassService.cs b/Libraries/Core/Services/ItemBaseClassService.cs
index a8b2e3f6..b26f66b6 100644
--- a/Libraries/Core/Services/ItemBaseClassService.cs
+++ b/Libraries/Core/Services/ItemBaseClassService.cs
@@ -68,7 +68,7 @@ public class ItemBaseClassService(
HydrateItemBaseClassCache();
}
- if (itemTpl is null)
+ if (string.IsNullOrEmpty(itemTpl))
{
_logger.Warning("Unable to check itemTpl base class as value passed is null");
diff --git a/Libraries/Core/Services/ItemFilterService.cs b/Libraries/Core/Services/ItemFilterService.cs
index affd997e..6ad30f38 100644
--- a/Libraries/Core/Services/ItemFilterService.cs
+++ b/Libraries/Core/Services/ItemFilterService.cs
@@ -10,14 +10,13 @@ namespace Core.Services;
public class ItemFilterService(
ISptLogger _logger,
ICloner _cloner,
- DatabaseServer _databaseServer,
ConfigServer _configServer
)
{
protected ItemConfig _itemConfig = _configServer.GetConfig();
- protected HashSet? _lootableItemBlacklistCache = new HashSet();
- protected HashSet? _itemBlacklistCache = new HashSet();
+ protected HashSet? _lootableItemBlacklistCache = [];
+ protected HashSet? _itemBlacklistCache = [];
/**
* Check if the provided template id is blacklisted in config/item.json/blacklist
@@ -26,7 +25,14 @@ public class ItemFilterService(
*/
public bool ItemBlacklisted(string tpl)
{
- throw new NotImplementedException();
+ if (_itemBlacklistCache.Count == 0)
+ {
+ foreach (var item in _itemConfig.Blacklist) {
+ _itemBlacklistCache.Add(item);
+ }
+ }
+
+ return _itemBlacklistCache.Contains(tpl);
}
/**
@@ -36,7 +42,14 @@ public class ItemFilterService(
*/
public bool LootableItemBlacklisted(string tpl)
{
- throw new NotImplementedException();
+ if (_lootableItemBlacklistCache.Count == 0)
+ {
+ foreach (var item in _itemConfig.LootableItemBlacklist) {
+ _itemBlacklistCache.Add(item);
+ }
+ }
+
+ return _lootableItemBlacklistCache.Contains(tpl);
}
/**
@@ -46,7 +59,7 @@ public class ItemFilterService(
*/
public bool ItemRewardBlacklisted(string tpl)
{
- throw new NotImplementedException();
+ return _itemConfig.RewardItemBlacklist.Contains(tpl);
}
/**
@@ -55,7 +68,7 @@ public class ItemFilterService(
*/
public List GetItemRewardBlacklist()
{
- throw new NotImplementedException();
+ return _cloner.Clone(_itemConfig.RewardItemBlacklist).ToList();
}
/**
@@ -64,7 +77,7 @@ public class ItemFilterService(
*/
public List GetItemRewardBaseTypeBlacklist()
{
- throw new NotImplementedException();
+ return _cloner.Clone(_itemConfig.RewardItemTypeBlacklist).ToList();
}
/**
@@ -73,7 +86,7 @@ public class ItemFilterService(
*/
public List GetBlacklistedItems()
{
- return _cloner.Clone(_itemConfig.Blacklist);
+ return _cloner.Clone(_itemConfig.Blacklist).ToList();
}
/**
@@ -82,7 +95,7 @@ public class ItemFilterService(
*/
public List GetBlacklistedLootableItems()
{
- throw new NotImplementedException();
+ return _cloner.Clone(_itemConfig.LootableItemBlacklist).ToList();
}
/**
@@ -92,7 +105,7 @@ public class ItemFilterService(
*/
public bool BossItem(string tpl)
{
- throw new NotImplementedException();
+ return _itemConfig.BossItems.Contains(tpl);
}
/**
@@ -101,7 +114,8 @@ public class ItemFilterService(
*/
public List GetBossItems()
{
- throw new NotImplementedException();
+
+ return _cloner.Clone(_itemConfig.BossItems).ToList();
}
/**
diff --git a/Libraries/Core/Services/LocationLifecycleService.cs b/Libraries/Core/Services/LocationLifecycleService.cs
index 08567b7d..9830ae08 100644
--- a/Libraries/Core/Services/LocationLifecycleService.cs
+++ b/Libraries/Core/Services/LocationLifecycleService.cs
@@ -485,6 +485,11 @@ public class LocationLifecycleService
*/
protected void HandleCarExtract(string extractName, PmcData pmcData, string sessionId)
{
+ pmcData.CarExtractCounts?.TryAdd(extractName, 0);
+
+ // Increment extract count value
+ pmcData.CarExtractCounts[extractName] += 1;
+
var newFenceStanding = GetFenceStandingAfterExtract(
pmcData,
_inRaidConfig.CarExtractBaseStandingGain,
@@ -513,10 +518,14 @@ public class LocationLifecycleService
*/
protected void HandleCoopExtract(string sessionId, PmcData pmcData, string extractName)
{
+ pmcData.CoopExtractCounts?.TryAdd(extractName, 0);
+
+ pmcData.CoopExtractCounts[extractName] += 1;
+
var newFenceStanding = GetFenceStandingAfterExtract(
pmcData,
- _inRaidConfig.CarExtractBaseStandingGain,
- pmcData.CarExtractCounts[extractName]);
+ _inRaidConfig.CoopExtractBaseStandingGain,
+ pmcData.CoopExtractCounts[extractName]);
var fenceId = Traders.FENCE;
pmcData.TradersInfo[fenceId].Standing = newFenceStanding;
@@ -525,8 +534,6 @@ public class LocationLifecycleService
_traderHelper.LevelUp(fenceId, pmcData);
pmcData.TradersInfo[fenceId].LoyaltyLevel = Math.Max((int)pmcData.TradersInfo[fenceId].LoyaltyLevel, 1);
- _logger.Debug($"Car extract: {extractName} used, total times taken: {pmcData.CarExtractCounts[extractName]}");
-
// Copy updated fence rep values into scav profile to ensure consistency
var scavData = _profileHelper.GetScavProfile(sessionId);
scavData.TradersInfo[fenceId].Standing = pmcData.TradersInfo[fenceId].Standing;
diff --git a/Libraries/Core/Services/RagfairPriceService.cs b/Libraries/Core/Services/RagfairPriceService.cs
index 7b35d94d..266c6e7e 100644
--- a/Libraries/Core/Services/RagfairPriceService.cs
+++ b/Libraries/Core/Services/RagfairPriceService.cs
@@ -34,12 +34,13 @@ public class RagfairPriceService(
///
public async Task OnLoadAsync()
{
- throw new NotImplementedException();
+ RefreshStaticPrices();
+ RefreshDynamicPrices();
}
public string GetRoute()
{
- throw new NotImplementedException();
+ return "RagfairPriceService";
}
///
@@ -58,7 +59,7 @@ public class RagfairPriceService(
///
public void RefreshDynamicPrices()
{
- throw new NotImplementedException();
+ // TODO: remove as redundant?
}
///
@@ -95,7 +96,13 @@ public class RagfairPriceService(
/// Rouble price
public double GetFleaPriceForOfferItems(List- offerItems)
{
- throw new NotImplementedException();
+ // Preset weapons take the direct prices.json value, otherwise they're massivly inflated
+ if (_itemHelper.IsOfBaseclass(offerItems[0].Template, BaseClasses.WEAPON))
+ {
+ return GetFleaPriceForItem(offerItems[0].Template);
+ }
+
+ return offerItems.Sum(item => GetFleaPriceForItem(item.Template));
}
///