diff --git a/categories.json b/categories.json index c7a971e..bbd3f2c 100644 --- a/categories.json +++ b/categories.json @@ -45,7 +45,8 @@ { "description": "Backpacks", "id": "5b5f6f6c86f774093f2ecf0b", - "forceCustomBackgroundColours": true + "forceCustomBackgroundColours": true, + "useSlotsBasedBackgroundColours": false }, { "description": "Facecovers", diff --git a/config.json b/config.json index c3f18e5..1268f5e 100644 --- a/config.json +++ b/config.json @@ -75,5 +75,37 @@ "maxValue": 100000000, "colour": "violet" } + ], + "inventorySlotBackgroundColours": [ + { + "minValue": 0, + "maxValue": 12, + "colour": "orange" + }, + { + "minValue": 13, + "maxValue": 19, + "colour": "red" + }, + { + "minValue": 20, + "maxValue": 29, + "colour": "yellow" + }, + { + "minValue": 30, + "maxValue": 34, + "colour": "green" + }, + { + "minValue": 35, + "maxValue": 39, + "colour": "blue" + }, + { + "minValue": 40, + "maxValue": 999, + "colour": "purple" + } ] } \ No newline at end of file diff --git a/src/mod.ts b/src/mod.ts index c546b32..711ffb2 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -28,6 +28,7 @@ import { Money } from "@spt-aki/models/enums/Money"; import config from "../config.json"; import categoryConfig from "../categories.json"; +import { Props } from "@spt-aki/models/eft/common/tables/ITemplateItem"; class EyesOfATraderMod implements IPostDBLoadMod { private logger: ILogger; @@ -36,9 +37,7 @@ class EyesOfATraderMod implements IPostDBLoadMod { private modName = "[Eyes of a Trader]"; // We want to cache all (sub)categories of the Handbook that we have enabled our mod for otherwise we'll recursively search thousands of times. - private enabledCategories: Category[] = []; - private enabledCategoriesWithoutCustomBackground: Category[] = []; - private enabledCategoriesWithForcedCustomBackground: Category[] = []; + private enabledCategories: CategoryConfig[] = []; public postDBLoad(container: DependencyContainer): void { this.container = container; @@ -67,7 +66,10 @@ class EyesOfATraderMod implements IPostDBLoadMod { const itemProps = item._props; const isValidItem = itemProps.Name && itemProps.Name !== "Dog tag" && !itemProps.QuestItem; - if (this.isCategoryEnabled(handbookItem) && isValidItem) { + // If a categoryConfig exists for this handbook item, it means we want to display prices for this item! + const categoryConfig = this.enabledCategories.find(category => category.id === handbookItem.ParentId); + + if (categoryConfig && isValidItem) { const pricing = new Pricing( this.getApproxTraderPrice(handbookItems, itemId), this.getApproxFleaPrice(itemId), @@ -76,17 +78,18 @@ class EyesOfATraderMod implements IPostDBLoadMod { pricingMap.set(itemId, pricing); - const forceCustomBackground = this.enabledCategoriesWithForcedCustomBackground.some(category => category.Id === handbookItem.ParentId); - // Display custom background colours if forced via category configs or // Disable custom background colours if disabled globally or per category. if ( - forceCustomBackground || + categoryConfig.forceCustomBackgroundColours || config.useCustomBackgroundColours && - !this.enabledCategoriesWithoutCustomBackground.some(category => category.Id === handbookItem.ParentId) + !categoryConfig.disableCustomBackgroundColours ) { - const customColour = this.getCustomBackgroundColour(pricing); - if (customColour && (forceCustomBackground || config.updateVioletItemBackground || itemProps.BackgroundColor !== "violet")) { + const customColour = categoryConfig.useSlotsBasedBackgroundColours + ? this.getCustomBackgroundColourBasedOnInventorySlots(itemProps) + : this.getCustomBackgroundColourBasedOnPrice(pricing); + + if (customColour && (categoryConfig.forceCustomBackgroundColours || config.updateVioletItemBackground || itemProps.BackgroundColor !== "violet")) { itemProps.BackgroundColor = customColour; } } @@ -100,45 +103,30 @@ class EyesOfATraderMod implements IPostDBLoadMod { private cacheEnabledCategories(handbookCategories: Category[]): void { if (this.enabledCategories.length === 0) { - categoryConfig.enabledCategories.forEach(categoryConfig => { + categoryConfig.enabledCategories.forEach((categoryConfig: CategoryConfig) => { // We gotta add the parent categories first - const handbookCategory = handbookCategories.find(category => category.Id === categoryConfig.id); + this.enabledCategories.push(categoryConfig); - if (categoryConfig.disableCustomBackgroundColours) { - this.enabledCategoriesWithoutCustomBackground.push(handbookCategory); - } - - // Some categories like backpacks are all purple but we generally don't want to change existing purple ones, except for these forced categories. - if (categoryConfig.forceCustomBackgroundColours) { - this.enabledCategoriesWithForcedCustomBackground.push(handbookCategory); - } - - this.enabledCategories.push(handbookCategory) - - this.addSubCategoriesRecursively(handbookCategories, categoryConfig.id, categoryConfig.disableCustomBackgroundColours, categoryConfig.forceCustomBackgroundColours) + this.addSubCategoriesRecursively(handbookCategories, categoryConfig) }); } } - private addSubCategoriesRecursively(allCategories: Category[], categoryId: string, disableCustomBackground = false, forceCustomBackground = false): void { - const subCategories = allCategories.filter(category => category.ParentId === categoryId); + private addSubCategoriesRecursively(allCategories: Category[], categoryConfig: CategoryConfig): void { + const subCategories = allCategories.filter(category => category.ParentId === categoryConfig.id); if (subCategories.length) { - if (disableCustomBackground) { - this.enabledCategoriesWithoutCustomBackground = this.enabledCategoriesWithoutCustomBackground.concat(subCategories); - } - if (forceCustomBackground) { - this.enabledCategoriesWithForcedCustomBackground = this.enabledCategoriesWithForcedCustomBackground.concat(subCategories); - } - this.enabledCategories = this.enabledCategories.concat(subCategories); + const subCategoryConfigs = subCategories.map((subCategory): CategoryConfig => ({ + id: subCategory.Id, + disableCustomBackgroundColours: categoryConfig.disableCustomBackgroundColours, + forceCustomBackgroundColours: categoryConfig.forceCustomBackgroundColours, + useSlotsBasedBackgroundColours: categoryConfig.useSlotsBasedBackgroundColours + })); + this.enabledCategories = this.enabledCategories.concat(subCategoryConfigs); - subCategories.forEach(category => this.addSubCategoriesRecursively(allCategories, category.Id, disableCustomBackground)); + subCategoryConfigs.forEach(categoryConfig => this.addSubCategoriesRecursively(allCategories, categoryConfig)); } } - private isCategoryEnabled(handbookItem: HandbookItem): boolean { - return this.enabledCategories.some(category => category.Id === handbookItem.ParentId); - } - private getApproxTraderPrice(handbookItems: HandbookItem[], itemId: string): number { const fullPrice = handbookItems.find(item => item.Id === itemId)?.Price; if (!fullPrice) { @@ -158,7 +146,20 @@ class EyesOfATraderMod implements IPostDBLoadMod { return dynamicPrice * config.fleaPriceMultiplier; } - private getCustomBackgroundColour({ perSlotTraderPrice, perSlotFleaPrice, traderPrice, fleaPrice }: Pricing): string { + private getCustomBackgroundColourBasedOnInventorySlots({ Grids }: Props): string { + const totalSlots = Grids.reduce((totalSlots, grid) => { + const horizontal = grid._props.cellsH; + const vertical = grid._props.cellsV; + const slots = horizontal * vertical; + + return totalSlots += slots; + }, 0); + + const colourConfig = config.inventorySlotBackgroundColours.find(({ minValue, maxValue }) => totalSlots >= minValue && totalSlots <= maxValue); + return colourConfig?.colour; + } + + private getCustomBackgroundColourBasedOnPrice({ perSlotTraderPrice, perSlotFleaPrice, traderPrice, fleaPrice }: Pricing): string { const { usePerSlotPricingForBackgrounds, useFleaPricesForBackground, fleaValueBackgroundColours, traderValueBackgroundColours, autoUseFleaPricing } = config; const overrideWithFleaPrice = autoUseFleaPricing.enabled && (perSlotFleaPrice / perSlotTraderPrice) > autoUseFleaPricing.fleaToTraderValueThresholdRatio; const useFleaPrices = useFleaPricesForBackground || overrideWithFleaPrice; @@ -215,4 +216,12 @@ class Pricing { } } +interface CategoryConfig { + id: string; + description?: string; + disableCustomBackgroundColours?: boolean; + forceCustomBackgroundColours?: boolean; + useSlotsBasedBackgroundColours?: boolean; +} + module.exports = { mod: new EyesOfATraderMod() };