diff --git a/advancedConfig.json b/advancedConfig.json index 9136252..04a3f5b 100644 --- a/advancedConfig.json +++ b/advancedConfig.json @@ -4,5 +4,9 @@ "bulletDamageMultiplierRedutionFactor": 0.7, "baselineArmourId": "5c0e655586f774045612eeb2", "baselineArmourWeight": 10, - "enableDebug": true + "baselineArmourPrice": 200000, + "pricePerArmourClassStep": 100000, + "armourWeightMultiplierReductionFactor": 0.7, + "enableDebug": false, + "excludedCategories": ["5b5f78b786f77447ed5636af", "5b47574386f77428ca22b33c"] } \ No newline at end of file diff --git a/config.json b/config.json index 591fc81..dbf7ace 100644 --- a/config.json +++ b/config.json @@ -8,7 +8,7 @@ { "itemIdHint": "Just a human friendly description that isn't used in code to help you remember. This item is the .338 AP round", "itemId": "5fc382a9d724d907e2077dab", - "priceMultiplier": 1 + "priceMultiplier": 1.3 }, { "itemIdHint": "MK-18 .338 rifle", @@ -19,6 +19,16 @@ "itemIdHint": "AXMC .338 rifle. This gun has no flea price by default. We can use the price override to avoid any issues", "itemId": "627e14b21713922ded6f2c15", "fleaPriceOverride": 300000 + }, + { + "itemIdHint": "RSASS 7.62 rifle. 300k+ default seems too high for me", + "itemId": "5a367e5dc4a282000e49738f", + "fleaPriceOverride": 150000 + }, + { + "itemIdHint": "Thicc Items Case", + "itemId": "5c0a840b86f7742ffa4f2482", + "fleaPriceOverride": 12000000 } ] } \ No newline at end of file diff --git a/src/mod.ts b/src/mod.ts index a28ee68..9f8aeec 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -77,15 +77,20 @@ class TheBlacklistMod implements IPostDBLoadMod { // We found a custom price override to use. That's all we care about for this item. Move on to the next item. if (customItemConfig?.fleaPriceOverride) { prices[item._id] = customItemConfig.fleaPriceOverride; - this.debug(`Updated ${item._id} - ${item._name} flea price from ${originalPrice} to ${prices[item._id]} (price override).`); - blacklistedItemsCount++; return; } const itemProps = item._props; if (!itemProps.CanSellOnRagfair) { + // Some blacklisted items are hard to balance or just shouldn't be allowed so we will keep them blacklisted. + if (advancedConfig.excludedCategories.some(category => category === handbookItem.ParentId)) { + ragfairConfig.dynamic.blacklist.custom.push(item._id); + this.debug(`Blacklisted item ${item._id} - ${item._name} because we are excluding handbook category ${handbookItem.ParentId}.`); + return; + } + itemProps.CanSellOnRagfair = config.disableBsgBlacklist; prices[item._id] = this.getUpdatedPrice(item, prices); @@ -119,7 +124,7 @@ class TheBlacklistMod implements IPostDBLoadMod { if (item._props.ammoType === "bullet") { newPrice = this.getUpdatedAmmoPrice(item); } else if (Number(item._props.armorClass) > 0 && item._props.armorZone?.some(zone => zone === "Chest")) { - newPrice = this.getUpdatedArmourPrice(item, prices); + newPrice = this.getUpdatedArmourPrice(item); } // Avoids NaN. Also we shouldn't have any prices of 0. @@ -142,18 +147,20 @@ class TheBlacklistMod implements IPostDBLoadMod { return advancedConfig.baselineBulletPrice * penetrationMultiplier * damageMultiplier * config.blacklistedAmmoAdditionalPriceMultiplier; } - // Armour price balancing is tricky. The default prices for some armours like the Zabralo is too high imo. - // Updated prices are based on a Trooper armour (default) as well as the armour class and its weight. - private getUpdatedArmourPrice(item: ITemplateItem, prices: Record) { - const baselineArmourRating = Number(this.baselineArmour._props.armorClass); - const baselineArmourPrice = prices[this.baselineArmour._id]; + // Some default armour prices are too high like the Zabralo so I want a more balanced way to calculate the price. + private getUpdatedArmourPrice(item: ITemplateItem) { + const baselineArmourClass = Number(this.baselineArmour._props.armorClass); - const itemArmourRatingMultiplier = Number(item._props.armorClass) / baselineArmourRating; - const itemArmourWeightMultiplier = advancedConfig.baselineArmourWeight / item._props.Weight; - // Hard to balance this figure so will just leave it out. - // const partialItemCost = prices[item._id] * (advancedConfig.percentageOfInitialArmourPriceToAdd / 100) + // Instead of doing a simple multiplier by dividing the two armour classes, this will give us a much bigger price range for different tiered armours. + const armourClassCost = (Number(item._props.armorClass) - baselineArmourClass) * advancedConfig.pricePerArmourClassStep; + const baseArmourWeightMultiplier = advancedConfig.baselineArmourWeight / item._props.Weight; - return baselineArmourPrice * itemArmourRatingMultiplier * itemArmourWeightMultiplier * config.blacklistedArmourAdditionalPriceMultiplier; + // Reduces the effect of the weight multiplier so some lighter armour aren't super expensive. + // Eg. let baseArmourWeightMultiplier = 2 & armourWeightMultiplierReductionFactor = 0.7. Instead of a 2x price when an armour is half as light as the baseline, we instead get: + // 2 + (1 - 2) * 0.7 = 2 - 0.7 = 1.3x the price. + const armourWeightMultiplier = baseArmourWeightMultiplier + (1 - baseArmourWeightMultiplier) * advancedConfig.armourWeightMultiplierReductionFactor; + + return (advancedConfig.baselineArmourPrice + armourClassCost) * armourWeightMultiplier * config.blacklistedArmourAdditionalPriceMultiplier; } private debug(message: string) {