diff --git a/config.json.example b/config.json.example index e8c32ed1..c464ad1a 100644 --- a/config.json.example +++ b/config.json.example @@ -19,6 +19,7 @@ "infiniteEndo": false, "infiniteRegalAya": false, "infiniteHelminthMaterials": false, + "claimingBlueprintRefundsIngredients": false, "dontSubtractConsumables": false, "unlockAllShipFeatures": false, "unlockAllShipDecorations": false, diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index 173c7221..e519d170 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -17,8 +17,11 @@ import { } from "@/src/services/inventoryService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; +import { InventorySlot, IPendingRecipeDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; import { toOid2 } from "@/src/helpers/inventoryHelpers"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { IRecipe } from "warframe-public-export-plus"; +import { config } from "@/src/services/configService"; interface IClaimCompletedRecipeRequest { RecipeIds: IOid[]; @@ -46,34 +49,8 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = } if (req.query.cancel) { - const inventoryChanges: IInventoryChanges = { - ...updateCurrency(inventory, recipe.buildPrice * -1, false) - }; - - const equipmentIngredients = new Set(); - for (const category of ["LongGuns", "Pistols", "Melee"] as const) { - if (pendingRecipe[category]) { - pendingRecipe[category].forEach(item => { - const index = inventory[category].push(item) - 1; - inventoryChanges[category] ??= []; - inventoryChanges[category].push(inventory[category][index].toJSON()); - equipmentIngredients.add(item.ItemType); - - occupySlot(inventory, InventorySlot.WEAPONS, false); - inventoryChanges.WeaponBin ??= { Slots: 0 }; - inventoryChanges.WeaponBin.Slots -= 1; - }); - } - } - for (const ingredient of recipe.ingredients) { - if (!equipmentIngredients.has(ingredient.ItemType)) { - combineInventoryChanges( - inventoryChanges, - await addItem(inventory, ingredient.ItemType, ingredient.ItemCount) - ); - } - } - + const inventoryChanges: IInventoryChanges = {}; + await refundRecipeIngredients(inventory, inventoryChanges, recipe, pendingRecipe); await inventory.save(); res.json(inventoryChanges); // Not a bug: In the specific case of cancelling a recipe, InventoryChanges are expected to be the root. } else { @@ -141,7 +118,43 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) = )) }; } + if (config.claimingBlueprintRefundsIngredients) { + await refundRecipeIngredients(inventory, InventoryChanges, recipe, pendingRecipe); + } await inventory.save(); res.json({ InventoryChanges, BrandedSuits }); } }; + +const refundRecipeIngredients = async ( + inventory: TInventoryDatabaseDocument, + inventoryChanges: IInventoryChanges, + recipe: IRecipe, + pendingRecipe: IPendingRecipeDatabase +): Promise => { + updateCurrency(inventory, recipe.buildPrice * -1, false, inventoryChanges); + + const equipmentIngredients = new Set(); + for (const category of ["LongGuns", "Pistols", "Melee"] as const) { + if (pendingRecipe[category]) { + pendingRecipe[category].forEach(item => { + const index = inventory[category].push(item) - 1; + inventoryChanges[category] ??= []; + inventoryChanges[category].push(inventory[category][index].toJSON()); + equipmentIngredients.add(item.ItemType); + + occupySlot(inventory, InventorySlot.WEAPONS, false); + inventoryChanges.WeaponBin ??= { Slots: 0 }; + inventoryChanges.WeaponBin.Slots -= 1; + }); + } + } + for (const ingredient of recipe.ingredients) { + if (!equipmentIngredients.has(ingredient.ItemType)) { + combineInventoryChanges( + inventoryChanges, + await addItem(inventory, ingredient.ItemType, ingredient.ItemCount) + ); + } + } +}; diff --git a/src/services/configService.ts b/src/services/configService.ts index 26a5008d..8d3206ef 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -24,6 +24,7 @@ interface IConfig { infiniteEndo?: boolean; infiniteRegalAya?: boolean; infiniteHelminthMaterials?: boolean; + claimingBlueprintRefundsIngredients?: boolean; dontSubtractConsumables?: boolean; unlockAllShipFeatures?: boolean; unlockAllShipDecorations?: boolean; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index dd3b229b..cfb3ca16 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -1113,24 +1113,29 @@ const isCurrencyTracked = (usePremium: boolean): boolean => { export const updateCurrency = ( inventory: TInventoryDatabaseDocument, price: number, - usePremium: boolean + usePremium: boolean, + inventoryChanges: IInventoryChanges = {} ): IInventoryChanges => { - const currencyChanges: IInventoryChanges = {}; if (price != 0 && isCurrencyTracked(usePremium)) { if (usePremium) { if (inventory.PremiumCreditsFree > 0) { - currencyChanges.PremiumCreditsFree = Math.min(price, inventory.PremiumCreditsFree) * -1; - inventory.PremiumCreditsFree += currencyChanges.PremiumCreditsFree; + const premiumCreditsFreeDelta = Math.min(price, inventory.PremiumCreditsFree) * -1; + inventoryChanges.PremiumCreditsFree ??= 0; + inventoryChanges.PremiumCreditsFree += premiumCreditsFreeDelta; + inventory.PremiumCreditsFree += premiumCreditsFreeDelta; } - currencyChanges.PremiumCredits = -price; - inventory.PremiumCredits += currencyChanges.PremiumCredits; + inventoryChanges.PremiumCredits ??= 0; + inventoryChanges.PremiumCredits -= price; + inventory.PremiumCredits -= price; + logger.debug(`currency changes `, { PremiumCredits: -price }); } else { - currencyChanges.RegularCredits = -price; - inventory.RegularCredits += currencyChanges.RegularCredits; + inventoryChanges.RegularCredits ??= 0; + inventoryChanges.RegularCredits -= price; + inventory.RegularCredits -= price; + logger.debug(`currency changes `, { RegularCredits: -price }); } - logger.debug(`currency changes `, currencyChanges); } - return currencyChanges; + return inventoryChanges; }; export const addFusionPoints = (inventory: TInventoryDatabaseDocument, add: number): number => { diff --git a/static/webui/index.html b/static/webui/index.html index 2297c8e6..71937337 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -590,6 +590,10 @@ +
+ + +
diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 54f2e147..0edbf98f 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -131,6 +131,7 @@ dict = { cheats_infiniteEndo: `Unendlich Endo`, cheats_infiniteRegalAya: `Unendlich Reines Aya`, cheats_infiniteHelminthMaterials: `Unendlich Helminth-Materialien`, + cheats_claimingBlueprintRefundsIngredients: `[UNTRANSLATED] Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `Verbrauchsgegenstände (Ausrüstung) nicht verbrauchen`, cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`, cheats_unlockAllShipDecorations: `Alle Schiffsdekorationen freischalten`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index da0d5a0d..9dfeb21a 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -130,6 +130,7 @@ dict = { cheats_infiniteEndo: `Infinite Endo`, cheats_infiniteRegalAya: `Infinite Regal Aya`, cheats_infiniteHelminthMaterials: `Infinite Helminth Materials`, + cheats_claimingBlueprintRefundsIngredients: `Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `Don't Subtract Consumables`, cheats_unlockAllShipFeatures: `Unlock All Ship Features`, cheats_unlockAllShipDecorations: `Unlock All Ship Decorations`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index 3caa2b83..8251a1c9 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -131,6 +131,7 @@ dict = { cheats_infiniteEndo: `Endo infinito`, cheats_infiniteRegalAya: `Aya Real infinita`, cheats_infiniteHelminthMaterials: `Materiales Helminto infinitos`, + cheats_claimingBlueprintRefundsIngredients: `[UNTRANSLATED] Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `No restar consumibles`, cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`, cheats_unlockAllShipDecorations: `Desbloquear todas las decoraciones de nave`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 9f35699d..9253bfff 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -131,6 +131,7 @@ dict = { cheats_infiniteEndo: `Endo infini`, cheats_infiniteRegalAya: `Aya Raffiné infini`, cheats_infiniteHelminthMaterials: `Ressources d'Helminth infinies`, + cheats_claimingBlueprintRefundsIngredients: `[UNTRANSLATED] Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`, cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`, cheats_unlockAllShipDecorations: `Débloquer toutes les décorations du vaisseau`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 3861d7ff..a2bb6354 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -131,6 +131,7 @@ dict = { cheats_infiniteEndo: `Бесконечное эндо`, cheats_infiniteRegalAya: `Бесконечная Королевская Айя`, cheats_infiniteHelminthMaterials: `Бесконечные Выделения Гельминта`, + cheats_claimingBlueprintRefundsIngredients: `[UNTRANSLATED] Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `Не уменьшать количество расходников`, cheats_unlockAllShipFeatures: `Разблокировать все функции корабля`, cheats_unlockAllShipDecorations: `Разблокировать все украшения корабля`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index dacba31e..a242891a 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -131,6 +131,7 @@ dict = { cheats_infiniteEndo: `无限内融核心`, cheats_infiniteRegalAya: `无限御品阿耶`, cheats_infiniteHelminthMaterials: `无限Helminth材料`, + cheats_claimingBlueprintRefundsIngredients: `[UNTRANSLATED] Claiming Blueprint Refunds Ingredients`, cheats_dontSubtractConsumables: `[UNTRANSLATED] Don't Subtract Consumables`, cheats_unlockAllShipFeatures: `解锁所有飞船功能`, cheats_unlockAllShipDecorations: `解锁所有飞船装饰`,