Improve fence price calculation code. Prices now take into account removed item mods + mod durability

This commit is contained in:
Dev 2024-02-06 20:44:40 +00:00
parent f48ad01b38
commit 1101927768
5 changed files with 57 additions and 66 deletions

View File

@ -392,7 +392,7 @@ export class RagfairController
const rootItem = offer.items[0];
// Get average of items quality+children
const qualityMultiplier = this.ragfairHelper.getItemQualityModifierForOfferItems(offer.items);
const qualityMultiplier = this.itemHelper.getItemQualityModifierForOfferItems(offer.items);
const averageOfferPrice = this.ragfairPriceService.getFleaPriceForOfferItems(offer.items)
* rootItem.upd.StackObjectsCount * qualityMultiplier;
const itemStackCount = (offerRequest.sellInOnePiece) ? 1 : rootItem.upd.StackObjectsCount;

View File

@ -124,12 +124,12 @@ export class FenceBaseAssortGenerator
}
// Construct preset + mods
const presetAndMods: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(defaultPreset._items));
const itemAndChildren: Item[] = this.itemHelper.replaceIDs(null, this.jsonUtil.clone(defaultPreset._items));
// Find root item and add some properties to it
for (let i = 0; i < presetAndMods.length; i++)
for (let i = 0; i < itemAndChildren.length; i++)
{
const mod = presetAndMods[i];
const mod = itemAndChildren[i];
// Build root Item info
if (!("parentId" in mod))
@ -147,19 +147,19 @@ export class FenceBaseAssortGenerator
}
// Add constructed preset to assorts
baseFenceAssort.items.push(...presetAndMods);
baseFenceAssort.items.push(...itemAndChildren);
// Calculate preset price
const price = this.getHandbookItemPriceWithChildren(presetAndMods);
// Calculate preset price (root item + child items)
const price = this.handbookHelper.getTemplatePriceForItems(itemAndChildren);
// Multiply weapon+mods rouble price by multipler in config
baseFenceAssort.barter_scheme[presetAndMods[0]._id] = [[]];
baseFenceAssort.barter_scheme[presetAndMods[0]._id][0][0] = {
// Multiply weapon+mods rouble price by quality modifier
baseFenceAssort.barter_scheme[itemAndChildren[0]._id] = [[]];
baseFenceAssort.barter_scheme[itemAndChildren[0]._id][0][0] = {
_tpl: Money.ROUBLES,
count: Math.round(price) * this.traderConfig.fence.presetPriceMult,
count: Math.round(price * this.itemHelper.getItemQualityModifierForOfferItems(itemAndChildren)),
};
baseFenceAssort.loyal_level_items[presetAndMods[0]._id] = 1;
baseFenceAssort.loyal_level_items[itemAndChildren[0]._id] = 1;
}
}
@ -240,22 +240,6 @@ export class FenceBaseAssortGenerator
}
}
/**
* Calculate and return the price of an item and its child mods
* @param itemWithChildren Item + mods to calcualte price of
* @returns price
*/
protected getHandbookItemPriceWithChildren(itemWithChildren: Item[]): number
{
let price = 0;
for (const item of itemWithChildren)
{
price += this.handbookHelper.getTemplatePrice(item._tpl);
}
return price;
}
/**
* Check if item is valid for being added to fence assorts
* @param item Item to check

View File

@ -289,6 +289,22 @@ export class ItemHelper
return itemDetails[0];
}
/**
* Calcualte the average quality of an item and its children
* @param items An offers item to process
* @returns % quality modifer between 0 and 1
*/
public getItemQualityModifierForOfferItems(items: Item[]): number
{
let qualityModifier = 1;
for (const item of items)
{
qualityModifier += this.getItemQualityModifier(item);
}
return Math.min(qualityModifier / items.length, 1);
}
/**
* get normalized value (0-1) based on item condition
* @param item

View File

@ -199,20 +199,4 @@ export class RagfairHelper
return "₽";
}
}
/**
* Calcualte the average quality of an item and its children
* @param offerItems An offers item to process
* @returns % quality modifer between 0 and 1
*/
public getItemQualityModifierForOfferItems(offerItems: Item[]): number
{
let qualityModifier = 1;
for (const item of offerItems)
{
qualityModifier += this.itemHelper.getItemQualityModifier(item);
}
return Math.min(qualityModifier / offerItems.length, 1);
}
}

View File

@ -83,6 +83,7 @@ export class FenceService
{
if (this.traderConfig.fence.regenerateAssortsOnRefresh)
{
// Using base assorts made earlier, do some alterations and store in this.fenceAssort
this.generateFenceAssorts();
}
@ -382,16 +383,16 @@ export class FenceService
// Reset refresh time now assorts are being generated
this.incrementPartialRefreshTime();
const assorts = this.createFenceAssortSkeleton();
const discountAssorts = this.createFenceAssortSkeleton();
// Create basic fence assort
const assorts = this.createFenceAssortSkeleton();
this.createAssorts(this.traderConfig.fence.assortSize, assorts, 1);
// Store in this.fenceAssort
this.setFenceAssort(assorts);
// Create level 2 assorts accessible at rep level 6
const discountAssorts = this.createFenceAssortSkeleton();
this.createAssorts(this.traderConfig.fence.discountOptions.assortSize, discountAssorts, 2);
// store in fenceAssort class properties
this.setFenceAssort(assorts);
// Store in this.fenceDiscountAssort
this.setFenceDiscountAssort(discountAssorts);
}
@ -416,10 +417,10 @@ export class FenceService
*/
protected createAssorts(assortCount: number, assorts: ITraderAssort, loyaltyLevel: number): void
{
const baseFenceAssort = this.databaseServer.getTables().traders[Traders.FENCE].assort;
const baseFenceAssortClone = this.jsonUtil.clone(this.databaseServer.getTables().traders[Traders.FENCE].assort);
const itemTypeCounts = this.initItemLimitCounter(this.traderConfig.fence.itemTypeLimits);
this.addItemAssorts(assortCount, assorts, baseFenceAssort, itemTypeCounts, loyaltyLevel);
this.addItemAssorts(assortCount, assorts, baseFenceAssortClone, itemTypeCounts, loyaltyLevel);
// Add presets
const weaponPresetCount = this.randomUtil.getInt(
@ -430,7 +431,7 @@ export class FenceService
this.traderConfig.fence.equipmentPresetMinMax.min,
this.traderConfig.fence.equipmentPresetMinMax.max,
);
this.addPresetsToAssort(weaponPresetCount, equipmentPresetCount, assorts, baseFenceAssort, loyaltyLevel);
this.addPresetsToAssort(weaponPresetCount, equipmentPresetCount, assorts, baseFenceAssortClone, loyaltyLevel);
}
protected addItemAssorts(
@ -555,16 +556,15 @@ export class FenceService
// Check chosen item is below price cap
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
const itemPrice = this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
* this.itemHelper.getItemQualityModifierForOfferItems(presetWithChildrenClone);
if (priceLimitRouble)
{
if (this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone) > priceLimitRouble)
if (itemPrice > priceLimitRouble)
{
// Too expensive, try again
this.logger.warning(
`Blocked ${rootItemDb._name}, price: ${
this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
} limit: ${priceLimitRouble}`,
);
this.logger.warning(`Blocked ${rootItemDb._name}, price: ${itemPrice} limit: ${priceLimitRouble}`);
continue;
}
}
@ -578,8 +578,12 @@ export class FenceService
assorts.items.push(...presetWithChildrenClone);
// Set assort price
// Must be careful to use correct id as the item has had its IDs regenerated
assorts.barter_scheme[presetWithChildrenClone[0]._id] = baseFenceAssort.barter_scheme[randomPresetRoot._id];
assorts.barter_scheme[presetWithChildrenClone[0]._id] = [[{
_tpl: "5449016a4bdc2d6f028b456f",
count: itemPrice,
}]];
assorts.loyal_level_items[presetWithChildrenClone[0]._id] = loyaltyLevel;
weaponPresetsAddedCount++;
@ -613,16 +617,16 @@ export class FenceService
// Check chosen item is below price cap
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
const itemPrice = this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
* this.itemHelper.getItemQualityModifierForOfferItems(presetWithChildrenClone);
if (priceLimitRouble)
{
if (this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone) > priceLimitRouble)
// Get new price with random mods now removed
if (itemPrice > priceLimitRouble)
{
// Too expensive, try again
this.logger.warning(
`Blocked ${rootItemDb._name}, price: ${
this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
} limit: ${priceLimitRouble}`,
);
this.logger.warning(`Blocked ${rootItemDb._name}, price: ${itemPrice} limit: ${priceLimitRouble}`);
continue;
}
}
@ -637,7 +641,10 @@ export class FenceService
assorts.items.push(...presetWithChildrenClone);
// Must be careful to use correct id as the item has had its IDs regenerated
assorts.barter_scheme[presetWithChildrenClone[0]._id] = baseFenceAssort.barter_scheme[randomPresetRoot._id];
assorts.barter_scheme[presetWithChildrenClone[0]._id] = [[{
_tpl: "5449016a4bdc2d6f028b456f",
count: itemPrice,
}]];
assorts.loyal_level_items[presetWithChildrenClone[0]._id] = loyaltyLevel;
equipmentPresetsAddedCount++;