Use jsonc
This commit is contained in:
parent
9acf51b0b0
commit
4bb8616e27
@ -2,7 +2,7 @@
|
||||
"baselineBulletId": "59e6906286f7746c9f75e847",
|
||||
"baselineBulletPrice": 1000,
|
||||
"bulletDamageMultiplierRedutionFactor": 0.7,
|
||||
"enableDebug": false,
|
||||
"enableDebug": true,
|
||||
"excludedCategories": ["5b5f78b786f77447ed5636af", "5b47574386f77428ca22b33c"],
|
||||
"useTraderPriceForOffersIfHigher": true,
|
||||
"handbookPriceMultiplier": 3
|
@ -18,6 +18,7 @@
|
||||
"fs-extra": "11.1.0",
|
||||
"glob": "8.0.3",
|
||||
"tsyringe": "4.7.0",
|
||||
"typescript": "4.9.4"
|
||||
"typescript": "4.9.4",
|
||||
"jsonc": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,6 @@
|
||||
import { Category } from "@spt-aki/models/eft/common/tables/IHandbookBase";
|
||||
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
|
||||
|
||||
import config from "../config.json";
|
||||
import advancedConfig from "../advancedConfig.json";
|
||||
|
||||
// There are so many child categories of attachments, this will return all categories using recursion so I don't have to type each ID.
|
||||
export function getAttachmentCategoryIds(handbookCategories: Category[]): string[] {
|
||||
const weaponPartsAndModsId = "5b5f71a686f77447ed5636ab";
|
||||
@ -45,29 +42,4 @@ export function isBulletOrShotgunShell(item: ITemplateItem): boolean {
|
||||
const props = item._props;
|
||||
|
||||
return props.ammoType === "bullet" || props.ammoType === "buckshot";
|
||||
}
|
||||
|
||||
export function getUpdatedAmmoPrice(item: ITemplateItem, baselineBullet: ITemplateItem): number {
|
||||
const baselinePen = baselineBullet._props.PenetrationPower;
|
||||
const baselineDamage = baselineBullet._props.Damage;
|
||||
|
||||
const basePenetrationMultiplier = item._props.PenetrationPower / baselinePen;
|
||||
const baseDamageMultiplier = item._props.Damage / baselineDamage;
|
||||
|
||||
let penetrationMultiplier: number;
|
||||
if (basePenetrationMultiplier > 1) {
|
||||
// A good gradient to make higher power rounds more expensive
|
||||
penetrationMultiplier = 7 * basePenetrationMultiplier - 6;
|
||||
} else {
|
||||
// Due to maths above, its really easy to go < 1. The baseline ammo is mid tier with a reasonable 1000 rouble each. Ammo weaker than this tend to be pretty crap so we'll make it much cheaper
|
||||
const newMultiplier = basePenetrationMultiplier * 0.7;
|
||||
penetrationMultiplier = newMultiplier < 0.1 ? 0.1 : newMultiplier;
|
||||
}
|
||||
|
||||
// Reduces the effect of the damage multiplier so high DMG rounds aren't super expensive.
|
||||
// Eg. let baseDamageMultiplier = 2 & bulletDamageMultiplierRedutionFactor = 0.7. Instead of a 2x price when a bullet is 2x damage, we instead get:
|
||||
// 2 + (1 - 2) * 0.7 = 2 - 0.7 = 1.3x the price.
|
||||
const damageMultiplier = baseDamageMultiplier + (1 - baseDamageMultiplier) * advancedConfig.bulletDamageMultiplierRedutionFactor;
|
||||
|
||||
return advancedConfig.baselineBulletPrice * penetrationMultiplier * damageMultiplier * config.blacklistedAmmoAdditionalPriceMultiplier;
|
||||
}
|
68
src/mod.ts
68
src/mod.ts
@ -16,6 +16,8 @@
|
||||
// along with spt-the-blacklist. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { DependencyContainer } from "tsyringe";
|
||||
import { jsonc } from "jsonc";
|
||||
import path from "path";
|
||||
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
import { IPostDBLoadModAsync } from "@spt-aki/models/external/IPostDBLoadModAsync";
|
||||
@ -26,9 +28,7 @@ import { IRagfairConfig } from "@spt-aki/models/spt/config/IRagfairConfig";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { HandbookItem } from "@spt-aki/models/eft/common/tables/IHandbookBase";
|
||||
|
||||
import config from "../config.json";
|
||||
import advancedConfig from "../advancedConfig.json";
|
||||
import { getAttachmentCategoryIds, getUpdatedAmmoPrice, isBulletOrShotgunShell } from "./helpers";
|
||||
import { getAttachmentCategoryIds, isBulletOrShotgunShell } from "./helpers";
|
||||
|
||||
class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
private logger: ILogger;
|
||||
@ -46,9 +46,14 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
private nonBlacklistedItemsUpdatedCount = 0;
|
||||
private ammoPricesUpdatedCount = 0;
|
||||
|
||||
private config;
|
||||
private advancedConfig;
|
||||
|
||||
public async postDBLoadAsync(container: DependencyContainer) {
|
||||
this.logger = container.resolve<ILogger>("WinstonLogger");
|
||||
|
||||
this.config = await jsonc.read(path.resolve(__dirname, "../config.jsonc"));
|
||||
this.advancedConfig = await jsonc.read(path.resolve(__dirname, "../advancedConfig.jsonc"));
|
||||
|
||||
const databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
|
||||
const tables = databaseServer.getTables();
|
||||
const configServer = container.resolve<ConfigServer>("ConfigServer");
|
||||
@ -58,12 +63,12 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
const handbookItems = tables.templates.handbook.Items;
|
||||
const prices = tables.templates.prices;
|
||||
|
||||
ragfairConfig.dynamic.blacklist.enableBsgList = !config.disableBsgBlacklist;
|
||||
ragfairConfig.dynamic.useTraderPriceForOffersIfHigher = advancedConfig.useTraderPriceForOffersIfHigher != null ? advancedConfig.useTraderPriceForOffersIfHigher : true;
|
||||
this.baselineBullet = itemTable[this.advancedConfig.baselineBulletId];
|
||||
|
||||
this.baselineBullet = itemTable[advancedConfig.baselineBulletId];
|
||||
ragfairConfig.dynamic.blacklist.enableBsgList = !this.config.disableBsgBlacklist;
|
||||
ragfairConfig.dynamic.useTraderPriceForOffersIfHigher = this.advancedConfig.useTraderPriceForOffersIfHigher != null ? this.advancedConfig.useTraderPriceForOffersIfHigher : true;
|
||||
|
||||
if (config.limitMaxPriceOfAttachments) {
|
||||
if (this.config.limitMaxPriceOfAttachments) {
|
||||
this.attachmentCategoryIds = getAttachmentCategoryIds(tables.templates.handbook.Categories);
|
||||
}
|
||||
|
||||
@ -77,7 +82,7 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.limitMaxPriceOfAttachments && this.attachmentCategoryIds.includes(handbookItem.ParentId)) {
|
||||
if (this.config.limitMaxPriceOfAttachments && this.attachmentCategoryIds.includes(handbookItem.ParentId)) {
|
||||
this.updateAttachmentPrice(handbookItem, item, prices);
|
||||
}
|
||||
|
||||
@ -89,7 +94,7 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
|
||||
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)) {
|
||||
if (this.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;
|
||||
@ -109,16 +114,16 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
});
|
||||
|
||||
this.logger.success(`${this.modName}: Success! Found ${this.blacklistedItemsUpdatedCount} blacklisted & ${this.nonBlacklistedItemsUpdatedCount} non-blacklisted items to update.`);
|
||||
if (config.limitMaxPriceOfAttachments) {
|
||||
if (this.config.limitMaxPriceOfAttachments) {
|
||||
this.logger.success(`${this.modName}: config.limitMaxPriceOfAttachments is enabled! Updated ${this.attachmentPriceLimitedCount} flea prices of attachments.`);
|
||||
}
|
||||
if (config.useBalancedPricingForAllAmmo) {
|
||||
if (this.config.useBalancedPricingForAllAmmo) {
|
||||
this.logger.success(`${this.modName}: config.useBalancedPricingForAllAmmo is enabled! Updated ${this.ammoPricesUpdatedCount} ammo prices.`);
|
||||
}
|
||||
}
|
||||
|
||||
private updateItemUsingCustomItemConfig(item: ITemplateItem , prices: Record<string, number>, originalPrice: number, ragfairConfig: IRagfairConfig): boolean {
|
||||
const customItemConfig = config.customItemConfigs.find(conf => conf.itemId === item._id);
|
||||
const customItemConfig = this.config.customItemConfigs.find(conf => conf.itemId === item._id);
|
||||
|
||||
if (!customItemConfig) {
|
||||
return false;
|
||||
@ -153,7 +158,7 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
private updateAttachmentPrice(handbookItem: HandbookItem, item: ITemplateItem, prices: Record<string, number>) {
|
||||
const handbookPrice = handbookItem.Price;
|
||||
const existingFleaPrice = prices[item._id];
|
||||
const maxFleaPrice = handbookPrice * config.maxFleaPriceOfAttachmentsToHandbookPrice;
|
||||
const maxFleaPrice = handbookPrice * this.config.maxFleaPriceOfAttachmentsToHandbookPrice;
|
||||
|
||||
if (existingFleaPrice > maxFleaPrice) {
|
||||
prices[item._id] = maxFleaPrice;
|
||||
@ -168,11 +173,11 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
const itemProps = item._props;
|
||||
|
||||
// We don't care about this standard ammo item if we haven't enabled useBalancedPricingForAllAmmo
|
||||
if (itemProps.CanSellOnRagfair && !config.useBalancedPricingForAllAmmo) {
|
||||
if (itemProps.CanSellOnRagfair && !this.config.useBalancedPricingForAllAmmo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newPrice = getUpdatedAmmoPrice(item, this.baselineBullet);
|
||||
const newPrice = this.getUpdatedAmmoPrice(item);
|
||||
prices[item._id] = newPrice;
|
||||
|
||||
if (!itemProps.CanSellOnRagfair) {
|
||||
@ -184,19 +189,44 @@ class TheBlacklistMod implements IPostDBLoadModAsync {
|
||||
this.ammoPricesUpdatedCount++;
|
||||
}
|
||||
|
||||
private getUpdatedAmmoPrice(item: ITemplateItem): number {
|
||||
const baselinePen = this.baselineBullet._props.PenetrationPower;
|
||||
const baselineDamage = this.baselineBullet._props.Damage;
|
||||
|
||||
const basePenetrationMultiplier = item._props.PenetrationPower / baselinePen;
|
||||
const baseDamageMultiplier = item._props.Damage / baselineDamage;
|
||||
|
||||
let penetrationMultiplier: number;
|
||||
if (basePenetrationMultiplier > 1) {
|
||||
// A good gradient to make higher power rounds more expensive
|
||||
penetrationMultiplier = 7 * basePenetrationMultiplier - 6;
|
||||
} else {
|
||||
// Due to maths above, its really easy to go < 1. The baseline ammo is mid tier with a reasonable 1000 rouble each. Ammo weaker than this tend to be pretty crap so we'll make it much cheaper
|
||||
const newMultiplier = basePenetrationMultiplier * 0.7;
|
||||
penetrationMultiplier = newMultiplier < 0.1 ? 0.1 : newMultiplier;
|
||||
}
|
||||
|
||||
// Reduces the effect of the damage multiplier so high DMG rounds aren't super expensive.
|
||||
// Eg. let baseDamageMultiplier = 2 & bulletDamageMultiplierRedutionFactor = 0.7. Instead of a 2x price when a bullet is 2x damage, we instead get:
|
||||
// 2 + (1 - 2) * 0.7 = 2 - 0.7 = 1.3x the price.
|
||||
const damageMultiplier = baseDamageMultiplier + (1 - baseDamageMultiplier) * this.advancedConfig.bulletDamageMultiplierRedutionFactor;
|
||||
|
||||
return this.advancedConfig.baselineBulletPrice * penetrationMultiplier * damageMultiplier * this.config.blacklistedAmmoAdditionalPriceMultiplier;
|
||||
}
|
||||
|
||||
private getUpdatedPrice(handbookItem: HandbookItem, item: ITemplateItem, prices: Record<string, number>): number | undefined {
|
||||
// If a flea price doesn't exist for an item, we can multiply its handbook price which usually exists.
|
||||
if (prices[item._id] == null) {
|
||||
const handbookPrice = handbookItem.Price;
|
||||
|
||||
return handbookPrice * advancedConfig.handbookPriceMultiplier;
|
||||
return handbookPrice * this.advancedConfig.handbookPriceMultiplier;
|
||||
}
|
||||
|
||||
return prices[item._id] * config.blacklistedItemPriceMultiplier;
|
||||
return prices[item._id] * this.config.blacklistedItemPriceMultiplier;
|
||||
}
|
||||
|
||||
private debug(message: string) {
|
||||
if (advancedConfig.enableDebug) {
|
||||
if (this.advancedConfig.enableDebug) {
|
||||
this.logger.debug(`${this.modName}: ${message}`);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user