Improve fence price calculation code. Prices now take into account removed item mods + mod durability
This commit is contained in:
parent
f48ad01b38
commit
1101927768
@ -392,7 +392,7 @@ export class RagfairController
|
|||||||
const rootItem = offer.items[0];
|
const rootItem = offer.items[0];
|
||||||
|
|
||||||
// Get average of items quality+children
|
// 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)
|
const averageOfferPrice = this.ragfairPriceService.getFleaPriceForOfferItems(offer.items)
|
||||||
* rootItem.upd.StackObjectsCount * qualityMultiplier;
|
* rootItem.upd.StackObjectsCount * qualityMultiplier;
|
||||||
const itemStackCount = (offerRequest.sellInOnePiece) ? 1 : rootItem.upd.StackObjectsCount;
|
const itemStackCount = (offerRequest.sellInOnePiece) ? 1 : rootItem.upd.StackObjectsCount;
|
||||||
|
@ -124,12 +124,12 @@ export class FenceBaseAssortGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct preset + mods
|
// 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
|
// 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
|
// Build root Item info
|
||||||
if (!("parentId" in mod))
|
if (!("parentId" in mod))
|
||||||
@ -147,19 +147,19 @@ export class FenceBaseAssortGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add constructed preset to assorts
|
// Add constructed preset to assorts
|
||||||
baseFenceAssort.items.push(...presetAndMods);
|
baseFenceAssort.items.push(...itemAndChildren);
|
||||||
|
|
||||||
// Calculate preset price
|
// Calculate preset price (root item + child items)
|
||||||
const price = this.getHandbookItemPriceWithChildren(presetAndMods);
|
const price = this.handbookHelper.getTemplatePriceForItems(itemAndChildren);
|
||||||
|
|
||||||
// Multiply weapon+mods rouble price by multipler in config
|
// Multiply weapon+mods rouble price by quality modifier
|
||||||
baseFenceAssort.barter_scheme[presetAndMods[0]._id] = [[]];
|
baseFenceAssort.barter_scheme[itemAndChildren[0]._id] = [[]];
|
||||||
baseFenceAssort.barter_scheme[presetAndMods[0]._id][0][0] = {
|
baseFenceAssort.barter_scheme[itemAndChildren[0]._id][0][0] = {
|
||||||
_tpl: Money.ROUBLES,
|
_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
|
* Check if item is valid for being added to fence assorts
|
||||||
* @param item Item to check
|
* @param item Item to check
|
||||||
|
@ -289,6 +289,22 @@ export class ItemHelper
|
|||||||
return itemDetails[0];
|
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
|
* get normalized value (0-1) based on item condition
|
||||||
* @param item
|
* @param item
|
||||||
|
@ -199,20 +199,4 @@ export class RagfairHelper
|
|||||||
return "₽";
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,7 @@ export class FenceService
|
|||||||
{
|
{
|
||||||
if (this.traderConfig.fence.regenerateAssortsOnRefresh)
|
if (this.traderConfig.fence.regenerateAssortsOnRefresh)
|
||||||
{
|
{
|
||||||
|
// Using base assorts made earlier, do some alterations and store in this.fenceAssort
|
||||||
this.generateFenceAssorts();
|
this.generateFenceAssorts();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,16 +383,16 @@ export class FenceService
|
|||||||
// Reset refresh time now assorts are being generated
|
// Reset refresh time now assorts are being generated
|
||||||
this.incrementPartialRefreshTime();
|
this.incrementPartialRefreshTime();
|
||||||
|
|
||||||
const assorts = this.createFenceAssortSkeleton();
|
|
||||||
const discountAssorts = this.createFenceAssortSkeleton();
|
|
||||||
// Create basic fence assort
|
// Create basic fence assort
|
||||||
|
const assorts = this.createFenceAssortSkeleton();
|
||||||
this.createAssorts(this.traderConfig.fence.assortSize, assorts, 1);
|
this.createAssorts(this.traderConfig.fence.assortSize, assorts, 1);
|
||||||
|
// Store in this.fenceAssort
|
||||||
|
this.setFenceAssort(assorts);
|
||||||
|
|
||||||
// Create level 2 assorts accessible at rep level 6
|
// Create level 2 assorts accessible at rep level 6
|
||||||
|
const discountAssorts = this.createFenceAssortSkeleton();
|
||||||
this.createAssorts(this.traderConfig.fence.discountOptions.assortSize, discountAssorts, 2);
|
this.createAssorts(this.traderConfig.fence.discountOptions.assortSize, discountAssorts, 2);
|
||||||
|
// Store in this.fenceDiscountAssort
|
||||||
// store in fenceAssort class properties
|
|
||||||
this.setFenceAssort(assorts);
|
|
||||||
this.setFenceDiscountAssort(discountAssorts);
|
this.setFenceDiscountAssort(discountAssorts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,10 +417,10 @@ export class FenceService
|
|||||||
*/
|
*/
|
||||||
protected createAssorts(assortCount: number, assorts: ITraderAssort, loyaltyLevel: number): void
|
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);
|
const itemTypeCounts = this.initItemLimitCounter(this.traderConfig.fence.itemTypeLimits);
|
||||||
|
|
||||||
this.addItemAssorts(assortCount, assorts, baseFenceAssort, itemTypeCounts, loyaltyLevel);
|
this.addItemAssorts(assortCount, assorts, baseFenceAssortClone, itemTypeCounts, loyaltyLevel);
|
||||||
|
|
||||||
// Add presets
|
// Add presets
|
||||||
const weaponPresetCount = this.randomUtil.getInt(
|
const weaponPresetCount = this.randomUtil.getInt(
|
||||||
@ -430,7 +431,7 @@ export class FenceService
|
|||||||
this.traderConfig.fence.equipmentPresetMinMax.min,
|
this.traderConfig.fence.equipmentPresetMinMax.min,
|
||||||
this.traderConfig.fence.equipmentPresetMinMax.max,
|
this.traderConfig.fence.equipmentPresetMinMax.max,
|
||||||
);
|
);
|
||||||
this.addPresetsToAssort(weaponPresetCount, equipmentPresetCount, assorts, baseFenceAssort, loyaltyLevel);
|
this.addPresetsToAssort(weaponPresetCount, equipmentPresetCount, assorts, baseFenceAssortClone, loyaltyLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected addItemAssorts(
|
protected addItemAssorts(
|
||||||
@ -555,16 +556,15 @@ export class FenceService
|
|||||||
|
|
||||||
// Check chosen item is below price cap
|
// Check chosen item is below price cap
|
||||||
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
|
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
|
||||||
|
const itemPrice = this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
|
||||||
|
* this.itemHelper.getItemQualityModifierForOfferItems(presetWithChildrenClone);
|
||||||
if (priceLimitRouble)
|
if (priceLimitRouble)
|
||||||
{
|
{
|
||||||
if (this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone) > priceLimitRouble)
|
if (itemPrice > priceLimitRouble)
|
||||||
{
|
{
|
||||||
// Too expensive, try again
|
// Too expensive, try again
|
||||||
this.logger.warning(
|
this.logger.warning(`Blocked ${rootItemDb._name}, price: ${itemPrice} limit: ${priceLimitRouble}`);
|
||||||
`Blocked ${rootItemDb._name}, price: ${
|
|
||||||
this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
|
|
||||||
} limit: ${priceLimitRouble}`,
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,8 +578,12 @@ export class FenceService
|
|||||||
|
|
||||||
assorts.items.push(...presetWithChildrenClone);
|
assorts.items.push(...presetWithChildrenClone);
|
||||||
|
|
||||||
|
// Set assort price
|
||||||
// Must be careful to use correct id as the item has had its IDs regenerated
|
// 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;
|
assorts.loyal_level_items[presetWithChildrenClone[0]._id] = loyaltyLevel;
|
||||||
|
|
||||||
weaponPresetsAddedCount++;
|
weaponPresetsAddedCount++;
|
||||||
@ -613,16 +617,16 @@ export class FenceService
|
|||||||
|
|
||||||
// Check chosen item is below price cap
|
// Check chosen item is below price cap
|
||||||
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
|
const priceLimitRouble = this.traderConfig.fence.itemCategoryRoublePriceLimit[rootItemDb._parent];
|
||||||
|
const itemPrice = this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
|
||||||
|
* this.itemHelper.getItemQualityModifierForOfferItems(presetWithChildrenClone);
|
||||||
if (priceLimitRouble)
|
if (priceLimitRouble)
|
||||||
{
|
{
|
||||||
if (this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone) > priceLimitRouble)
|
// Get new price with random mods now removed
|
||||||
|
if (itemPrice > priceLimitRouble)
|
||||||
{
|
{
|
||||||
// Too expensive, try again
|
// Too expensive, try again
|
||||||
this.logger.warning(
|
this.logger.warning(`Blocked ${rootItemDb._name}, price: ${itemPrice} limit: ${priceLimitRouble}`);
|
||||||
`Blocked ${rootItemDb._name}, price: ${
|
|
||||||
this.handbookHelper.getTemplatePriceForItems(presetWithChildrenClone)
|
|
||||||
} limit: ${priceLimitRouble}`,
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,7 +641,10 @@ export class FenceService
|
|||||||
assorts.items.push(...presetWithChildrenClone);
|
assorts.items.push(...presetWithChildrenClone);
|
||||||
|
|
||||||
// Must be careful to use correct id as the item has had its IDs regenerated
|
// 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;
|
assorts.loyal_level_items[presetWithChildrenClone[0]._id] = loyaltyLevel;
|
||||||
|
|
||||||
equipmentPresetsAddedCount++;
|
equipmentPresetsAddedCount++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user