Fixed flea logic that prevented offers being listed for complex items (items /w children)

`GetItemsToListOnFleaFromInventory` would not keep the root item at index 0, client requires this

`FindAndReturnChildrenAsItems` now inserts root item at index 0
`CreateMultiOffer` now looks for root item by its id

Updated `CreateSingleOffer` to not choose first inventory item as root, search for it instead

Fixes #318
This commit is contained in:
Chomp
2025-06-04 17:30:26 +01:00
parent adf65f497c
commit 112afd3391
2 changed files with 34 additions and 30 deletions
@@ -555,13 +555,15 @@ public class RagfairController
SptProfile fullProfile, ItemEventRouterResponse output)
{
var pmcData = fullProfile.CharacterData.PmcData;
// var itemsToListCount = offerRequest.Items.Count; // Wasnt used to commented out for now // Does not count stack size, only items
// var itemsToListCount = offerRequest.Items.Count; // Wasn't used to commented out for now // Does not count stack size, only items
var firstOfferItemId = offerRequest.Items.First(); // What id chosen doesn't matter, it's a multi-offer so all items are the same
// multi-offers are all the same item,
// Get first item and its children and use as template
var firstListingAndChidren = _itemHelper.FindAndReturnChildrenAsItems(
var inventoryItems = _itemHelper.FindAndReturnChildrenAsItems(
pmcData.Inventory.Items,
offerRequest.Items[0]
firstOfferItemId // Choose first item as they're all the same item
);
// Find items to be listed on flea (+ children) from player inventory
@@ -571,19 +573,19 @@ public class RagfairController
_httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage);
}
// Total count of items summed using their stack counts
// Total count of items summed using their individual stack counts
var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(result.Items);
// When listing identical items on flea, condense separate items into one stack with a merged stack count
// e.g. 2 ammo items, stackObjectCount = 3 for each, will result in 1 stack of 6
firstListingAndChidren[0].Upd ??= new Upd();
firstListingAndChidren[0].Upd.StackObjectsCount = stackCountTotal;
// e.g. 2 ammo items each with stackObjectCount = 3, will result in 1 stack of 6
inventoryItems[0].Upd ??= new Upd();
inventoryItems[0].Upd.StackObjectsCount = stackCountTotal;
// Create flea object
var offer = CreatePlayerOffer(sessionID, offerRequest.Requirements, firstListingAndChidren, false);
var offer = CreatePlayerOffer(sessionID, offerRequest.Requirements, inventoryItems, false);
// This is the item that will be listed on flea, has merged stackObjectCount
var newRootOfferItem = offer.Items[0];
var rootOfferItem = offer.Items.First(x => x.Id == firstOfferItemId);
// Average offer price for single item (or whole weapon)
var averages =
@@ -593,10 +595,10 @@ public class RagfairController
TemplateId = offer.Items[0].Template
}
);
var averageOfferPrice = averages.Avg;
// Check for and apply item price modifer if it exists in config
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out var itemPriceModifer))
var averageOfferPrice = averages.Avg;
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(rootOfferItem.Template, out var itemPriceModifer))
{
averageOfferPrice *= itemPriceModifer;
}
@@ -625,7 +627,7 @@ public class RagfairController
{
var taxFeeChargeFailed = ChargePlayerTaxFee(
sessionID,
newRootOfferItem,
rootOfferItem,
pmcData,
playerListedPriceInRub,
(int) stackCountTotal,
@@ -665,7 +667,7 @@ public class RagfairController
SptProfile fullProfile, ItemEventRouterResponse output)
{
var pmcData = fullProfile.CharacterData.PmcData;
// var itemsToListCount = offerRequest.Items.Count; // Wasn't used so commented out for now // Does not count stack size, only items
// var itemsToListCount = offerRequest.Items.Count; // TODO: Wasn't used so commented out for now // Does not count stack size, only items
// multi-offers are all the same item,
// Get first item and its children and use as template
@@ -687,14 +689,13 @@ public class RagfairController
// When listing identical items on flea, condense separate items into one stack with a merged stack count
// e.g. 2 ammo items, stackObjectCount = 3 for each, will result in 1 stack of 6
firstListingAndChidren[0].Upd ??= new Upd();
firstListingAndChidren[0].Upd.StackObjectsCount = stackCountTotal;
// Create flea object
var offer = CreatePlayerOffer(sessionID, offerRequest.Requirements, firstListingAndChidren, true);
// This is the item that will be listed on flea, has merged stackObjectCount
var newRootOfferItem = offer.Items[0];
var newRootOfferItem = offer.Items[0]; // TODO: add logic like single/multi offers to find root item
// Single price for an item
var averages = GetItemMinAvgMaxFleaPriceValues(
@@ -778,24 +779,25 @@ public class RagfairController
// var itemsToListCount = offerRequest.Items.Count; // Wasn't used so commented out for now // Does not count stack size, only items
// Find items to be listed on flea from player inventory
var result = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items);
if (result.Items is null || !string.IsNullOrEmpty(result.ErrorMessage))
var inventoryItemsToSell = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items);
if (inventoryItemsToSell.Items is null || !string.IsNullOrEmpty(inventoryItemsToSell.ErrorMessage))
{
_httpResponseUtil.AppendErrorToOutput(output, result.ErrorMessage);
_httpResponseUtil.AppendErrorToOutput(output, inventoryItemsToSell.ErrorMessage);
}
// Total count of items summed using their stack counts
var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(result.Items);
var stackCountTotal = _ragfairOfferHelper.GetTotalStackCountSize(inventoryItemsToSell.Items);
// Checks are done, create the offer
// Checks are done, create offer
var playerListedPriceInRub = CalculateRequirementsPriceInRub(offerRequest.Requirements);
var offer = CreatePlayerOffer(
sessionID,
offerRequest.Requirements,
result.Items.First(),
inventoryItemsToSell.Items.First(), // Single offer, value will be collection with one array of items
false
);
var rootItem = offer.Items.First();
var offerRootItem = offer.Items.FirstOrDefault(x => x.Id == offerRequest.Items[0]);
// Get average of items quality+children
var qualityMultiplier = _itemHelper.GetItemQualityModifierForItems(offer.Items, true);
@@ -805,13 +807,13 @@ public class RagfairController
GetItemMinAvgMaxFleaPriceValues(
new GetMarketPriceRequestData
{
TemplateId = rootItem.Template
TemplateId = offerRootItem.Template
}
);
var averageOfferPriceSingleItem = averages.Avg;
// Check for and apply item price modifer if it exists in config
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(rootItem.Template, out var itemPriceModifer))
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(offerRootItem.Template, out var itemPriceModifer))
{
averageOfferPriceSingleItem *= itemPriceModifer;
}
@@ -832,7 +834,7 @@ public class RagfairController
{
var taxFeeChargeFailed = ChargePlayerTaxFee(
sessionID,
rootItem,
offerRootItem,
pmcData,
playerListedPriceInRub,
(int) stackCountTotal,
@@ -994,8 +996,8 @@ public class RagfairController
// Count how many items are being sold and multiply the requested amount accordingly
foreach (var itemId in itemIdsFromFleaOfferRequest)
{
var item = pmcData.Inventory?.Items?.FirstOrDefault(i => i.Id == itemId);
if (item is null)
var rootItem = pmcData.Inventory?.Items?.FirstOrDefault(i => i.Id == itemId);
if (rootItem is null)
{
errorMessage = _localisationService.GetText(
"ragfair-unable_to_find_item_in_inventory",
@@ -1013,7 +1015,8 @@ public class RagfairController
};
}
item = _itemHelper.FixItemStackCount(item);
_itemHelper.FixItemStackCount(rootItem);
itemsToReturn.Add(_itemHelper.FindAndReturnChildrenAsItems(pmcData.Inventory.Items, itemId));
}
@@ -804,13 +804,14 @@ public class ItemHelper(
public List<Item> FindAndReturnChildrenAsItems(IEnumerable<Item> items, string baseItemId, bool modsOnly = false)
{
// Use dictionary to make key lookup faster, convert to list before being returned
Dictionary<string, Item> result = [];
OrderedDictionary<string, Item> result = [];
foreach (var childItem in items)
{
// Include itself
if (string.Equals(childItem.Id, baseItemId, StringComparison.Ordinal))
{
result.Add(childItem.Id, childItem);
// Root item MUST be at 0 index for things like flea market offers
result.Insert(0, childItem.Id, childItem);
continue;
}