diff --git a/project/src/controllers/RagfairController.ts b/project/src/controllers/RagfairController.ts index 4d6ea76d..478eb3bd 100644 --- a/project/src/controllers/RagfairController.ts +++ b/project/src/controllers/RagfairController.ts @@ -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; diff --git a/project/src/generators/FenceBaseAssortGenerator.ts b/project/src/generators/FenceBaseAssortGenerator.ts index b9b5d073..f6c55883 100644 --- a/project/src/generators/FenceBaseAssortGenerator.ts +++ b/project/src/generators/FenceBaseAssortGenerator.ts @@ -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 diff --git a/project/src/helpers/ItemHelper.ts b/project/src/helpers/ItemHelper.ts index 096bdf46..6fb0985e 100644 --- a/project/src/helpers/ItemHelper.ts +++ b/project/src/helpers/ItemHelper.ts @@ -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 diff --git a/project/src/helpers/RagfairHelper.ts b/project/src/helpers/RagfairHelper.ts index 3facc586..b35f0e4b 100644 --- a/project/src/helpers/RagfairHelper.ts +++ b/project/src/helpers/RagfairHelper.ts @@ -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); - } } diff --git a/project/src/services/FenceService.ts b/project/src/services/FenceService.ts index 1318fced..da9a4d27 100644 --- a/project/src/services/FenceService.ts +++ b/project/src/services/FenceService.ts @@ -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++;