From cdb55ef7d56833f2ca3e5bc113db9d8720346322 Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 22 Feb 2024 14:02:32 +0000 Subject: [PATCH] Weight PMC look by price, higher price = smaller weight --- project/src/generators/PMCLootGenerator.ts | 102 ++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/project/src/generators/PMCLootGenerator.ts b/project/src/generators/PMCLootGenerator.ts index e2f863d5..9c8564b8 100644 --- a/project/src/generators/PMCLootGenerator.ts +++ b/project/src/generators/PMCLootGenerator.ts @@ -7,6 +7,7 @@ import { IPmcConfig } from "@spt-aki/models/spt/config/IPmcConfig"; import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { ItemFilterService } from "@spt-aki/services/ItemFilterService"; +import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService"; import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService"; /** @@ -26,6 +27,7 @@ export class PMCLootGenerator @inject("DatabaseServer") protected databaseServer: DatabaseServer, @inject("ConfigServer") protected configServer: ConfigServer, @inject("ItemFilterService") protected itemFilterService: ItemFilterService, + @inject("RagfairPriceService") protected ragfairPriceService: RagfairPriceService, @inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService, ) { @@ -68,6 +70,21 @@ export class PMCLootGenerator { this.pocketLootPool[itemToAdd._id] = 1; } + + for (const itemToAdd of itemsToAdd) + { + this.pocketLootPool[itemToAdd._id] = 1; + } + + const highestPrice = Math.max(...Object.values(this.backpackLootPool)); + for (const key of Object.keys(this.pocketLootPool)) + { + // Invert price so cheapest has a larger weight + // Times by highest price so most expensive item has weight of 1 + this.pocketLootPool[key] = Math.round((1 / this.pocketLootPool[key]) * highestPrice); + } + + this.reduceWeightValues(this.pocketLootPool); } return this.pocketLootPool; @@ -108,6 +125,16 @@ export class PMCLootGenerator { this.vestLootPool[itemToAdd._id] = 1; } + + const highestPrice = Math.max(...Object.values(this.backpackLootPool)); + for (const key of Object.keys(this.vestLootPool)) + { + // Invert price so cheapest has a larger weight + // Times by highest price so most expensive item has weight of 1 + this.vestLootPool[key] = Math.round((1 / this.vestLootPool[key]) * highestPrice); + } + + this.reduceWeightValues(this.vestLootPool); } return this.vestLootPool; @@ -155,10 +182,83 @@ export class PMCLootGenerator for (const itemToAdd of itemsToAdd) { - this.backpackLootPool[itemToAdd._id] = 1; + // Set price of item as its weight + const price = this.ragfairPriceService.getFleaPriceForItem(itemToAdd._id); + this.backpackLootPool[itemToAdd._id] = price; } + + const highestPrice = Math.max(...Object.values(this.backpackLootPool)); + for (const key of Object.keys(this.backpackLootPool)) + { + // Invert price so cheapest has a larger weight + // Times by highest price so most expensive item has weight of 1 + this.backpackLootPool[key] = Math.round((1 / this.backpackLootPool[key]) * highestPrice); + } + + this.reduceWeightValues(this.backpackLootPool); } return this.backpackLootPool; } + + /** + * Find the greated common divisor of all weights and use it on the passed in dictionary + * @param weightedDict + */ + protected reduceWeightValues(weightedDict: Record): void + { + // No values, nothing to reduce + if (Object.keys(weightedDict).length === 0) + { + return; + } + + // Only one value, set to 1 and exit + if (Object.keys(weightedDict).length === 1) + { + const key = Object.keys(weightedDict)[0]; + weightedDict[key] = 1; + return; + } + + const weights = Object.values(weightedDict).slice(); + const commonDivisor = this.commonDivisor(weights); + + // No point in dividing by 1 + if (commonDivisor === 1) + { + return; + } + + for (const key in weightedDict) + { + if (Object.hasOwn(weightedDict, key)) + { + weightedDict[key] /= commonDivisor; + } + } + } + + protected commonDivisor(numbers: number[]): number + { + let result = numbers[0]; + for (let i = 1; i < numbers.length; i++) + { + result = this.gcd(result, numbers[i]); + } + + return result; + } + + protected gcd(a: number, b: number): number + { + while (b !== 0) + { + const temp = b; + b = a % b; + a = temp; + } + + return a; + } }