Refactor categoryConfigs; inventory slots

This commit is contained in:
Platinum 2023-02-15 23:16:48 +11:00
parent 46be556143
commit 948f63c111
3 changed files with 82 additions and 40 deletions

View File

@ -45,7 +45,8 @@
{
"description": "Backpacks",
"id": "5b5f6f6c86f774093f2ecf0b",
"forceCustomBackgroundColours": true
"forceCustomBackgroundColours": true,
"useSlotsBasedBackgroundColours": false
},
{
"description": "Facecovers",

View File

@ -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"
}
]
}

View File

@ -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() };