diff --git a/src/controllers/custom/addModularEquipmentController.ts b/src/controllers/custom/addModularEquipmentController.ts new file mode 100644 index 00000000..5e09902b --- /dev/null +++ b/src/controllers/custom/addModularEquipmentController.ts @@ -0,0 +1,21 @@ +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory, addEquipment, occupySlot, productCategoryToInventoryBin } from "@/src/services/inventoryService"; +import { RequestHandler } from "express"; +import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper"; + +export const addModularEquipmentController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const request = req.body as IAddModularEquipmentRequest; + const category = modularWeaponTypes[request.ItemType]; + const inventoryBin = productCategoryToInventoryBin(category)!; + const inventory = await getInventory(accountId, `${category} ${inventoryBin}`); + addEquipment(inventory, category, request.ItemType, request.ModularParts); + occupySlot(inventory, inventoryBin, true); + await inventory.save(); + res.end(); +}; + +interface IAddModularEquipmentRequest { + ItemType: string; + ModularParts: string[]; +} diff --git a/src/controllers/custom/getItemListsController.ts b/src/controllers/custom/getItemListsController.ts index accbac1c..196f59ca 100644 --- a/src/controllers/custom/getItemListsController.ts +++ b/src/controllers/custom/getItemListsController.ts @@ -25,6 +25,7 @@ interface ListedItem { fusionLimit?: number; exalted?: string[]; badReason?: "starter" | "frivolous" | "notraw"; + partType?: string; } const relicQualitySuffixes: Record = { @@ -50,6 +51,7 @@ const getItemListsController: RequestHandler = (req, response) => { res.MechSuits = []; res.miscitems = []; res.Syndicates = []; + res.OperatorAmps = []; for (const [uniqueName, item] of Object.entries(ExportWarframes)) { res[item.productCategory].push({ uniqueName, @@ -79,7 +81,8 @@ const getItemListsController: RequestHandler = (req, response) => { ) { res.ModularParts.push({ uniqueName, - name: getString(item.name, lang) + name: getString(item.name, lang), + partType: item.partType }); if (uniqueName.split("/")[5] != "SentTrainingAmplifier") { res.miscitems.push({ @@ -94,7 +97,8 @@ const getItemListsController: RequestHandler = (req, response) => { item.productCategory == "Melee" || item.productCategory == "SpaceGuns" || item.productCategory == "SpaceMelee" || - item.productCategory == "SentinelWeapons" + item.productCategory == "SentinelWeapons" || + item.productCategory == "OperatorAmps" ) { res[item.productCategory].push({ uniqueName, diff --git a/src/routes/custom.ts b/src/routes/custom.ts index 20f19a59..16359226 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -13,8 +13,9 @@ import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAl import { createAccountController } from "@/src/controllers/custom/createAccountController"; import { createMessageController } from "@/src/controllers/custom/createMessageController"; -import { addCurrencyController } from "../controllers/custom/addCurrencyController"; +import { addCurrencyController } from "@/src/controllers/custom/addCurrencyController"; import { addItemsController } from "@/src/controllers/custom/addItemsController"; +import { addModularEquipmentController } from "@/src/controllers/custom/addModularEquipmentController"; import { addXpController } from "@/src/controllers/custom/addXpController"; import { importController } from "@/src/controllers/custom/importController"; @@ -39,6 +40,7 @@ customRouter.post("/createAccount", createAccountController); customRouter.post("/createMessage", createMessageController); customRouter.post("/addCurrency", addCurrencyController); customRouter.post("/addItems", addItemsController); +customRouter.post("/addModularEquipment", addModularEquipmentController); customRouter.post("/addXp", addXpController); customRouter.post("/import", importController); customRouter.post("/manageQuests", manageQuestsController); diff --git a/static/webui/index.html b/static/webui/index.html index f88820e9..dcb2539c 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -193,10 +193,15 @@
-
+
+
@@ -299,6 +304,15 @@
+
+ + +
+
@@ -309,6 +323,13 @@
+
+ + + + + +
@@ -604,7 +625,6 @@ - @@ -613,6 +633,18 @@ + + + + + + + + + + + + diff --git a/static/webui/script.js b/static/webui/script.js index 8697414e..4e9119fc 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -185,6 +185,16 @@ function fetchItemList() { name: loc("code_traumaticPeculiar") }); + // Add modular weapons + data.OperatorAmps.push({ + uniqueName: "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", + name: loc("code_amp") + }); + data.Melee.push({ + uniqueName: "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon", + name: loc("code_zaw") + }); + const itemMap = { // Generics for rivens "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: loc("code_archgun") }, @@ -201,14 +211,9 @@ function fetchItemList() { "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": { name: loc("code_kitgun") }, "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": { name: loc("code_kitgun") }, "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": { name: loc("code_kitgun") }, - "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": { name: loc("code_zaw") }, "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/OperatorTrainingAmpWeapon": { name: loc("code_moteAmp") }, - "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": { name: loc("code_amp") }, - "/Lotus/Weapons/Operator/Pistols/DrifterPistol/DrifterPistolPlayerWeapon": { - name: loc("code_sirocco") - }, "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": { name: loc("code_kDrive") } }; for (const [type, items] of Object.entries(data)) { @@ -233,6 +238,33 @@ function fetchItemList() { if (type == "Syndicates" && item.uniqueName.startsWith("RadioLegion")) { item.name += " (" + item.uniqueName + ")"; } + if (type == "ModularParts") { + const supportedModularParts = [ + "LWPT_HB_DECK", + "LWPT_HB_ENGINE", + "LWPT_HB_FRONT", + "LWPT_HB_JET", + "LWPT_AMP_OCULUS", + "LWPT_AMP_CORE", + "LWPT_AMP_BRACE", + "LWPT_BLADE", + "LWPT_HILT", + "LWPT_HILT_WEIGHT" + ]; + if (supportedModularParts.includes(item.partType)) { + const option = document.createElement("option"); + option.setAttribute("data-key", item.uniqueName); + option.value = item.name; + document + .getElementById("datalist-" + type + "-" + item.partType.slice(5)) + .appendChild(option); + } else { + const option = document.createElement("option"); + option.setAttribute("data-key", item.uniqueName); + option.value = item.name; + document.getElementById("datalist-" + type).appendChild(option); + } + } if (item.badReason != "notraw") { const option = document.createElement("option"); option.setAttribute("data-key", item.uniqueName); @@ -622,6 +654,67 @@ function doAcquireEquipment(category) { }); } +function doAcquireModularEquipment(category, ItemType) { + let requiredParts; + let ModularParts = []; + switch (category) { + case "HoverBoards": + ItemType = "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit"; + requiredParts = ["HB_DECK", "HB_ENGINE", "HB_FRONT", "HB_JET"]; + break; + case "OperatorAmps": + requiredParts = ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"]; + break; + case "Melee": + requiredParts = ["BLADE", "HILT", "HILT_WEIGHT"]; + break; + } + requiredParts.forEach(part => { + const partName = getKey(document.getElementById("acquire-type-" + category + "-" + part)); + if (partName) { + ModularParts.push(partName); + } + }); + if (ModularParts.length != requiredParts.length) { + let isFirstPart = true; + requiredParts.forEach(part => { + const partSelector = document.getElementById("acquire-type-" + category + "-" + part); + if (!getKey(partSelector)) { + if (isFirstPart) { + isFirstPart = false; + $("#acquire-type-" + category + "-" + part) + .addClass("is-invalid") + .focus(); + } else { + $("#acquire-type-" + category + "-" + part).addClass("is-invalid"); + } + } + }); + } else { + revalidateAuthz(() => { + const req = $.post({ + url: "/custom/addModularEquipment?" + window.authz, + contentType: "application/json", + data: JSON.stringify({ + ItemType, + ModularParts + }) + }); + req.done(() => { + const mainInput = document.getElementById("acquire-type-" + category); + if (mainInput) { + mainInput.value = ""; + document.getElementById("modular-" + category).style.display = "none"; + } + requiredParts.forEach(part => { + document.getElementById("acquire-type-" + category + "-" + part).value = ""; + }); + updateInventory(); + }); + }); + } +} + $("input[list]").on("input", function () { $(this).removeClass("is-invalid"); }); @@ -1220,3 +1313,34 @@ function toast(text) { toast.appendChild(div); new bootstrap.Toast(document.querySelector(".toast-container").appendChild(toast)).show(); } + +function handleModularSelection(category) { + const modularWeapons = [ + "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", + "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon" + ]; + const itemType = getKey(document.getElementById("acquire-type-" + category)); + + if (modularWeapons.includes(itemType)) { + doAcquireModularEquipment(category, itemType); + } else { + doAcquireEquipment(category); + } +} +{ + const modularWeapons = [ + "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", + "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon" + ]; + const supportedModularInventoryCategory = ["OperatorAmps", "Melee"]; + supportedModularInventoryCategory.forEach(inventoryCategory => { + document.getElementById("acquire-type-" + inventoryCategory).addEventListener("input", function () { + const modularFields = document.getElementById("modular-" + inventoryCategory); + if (modularWeapons.includes(getKey(this))) { + modularFields.style.display = ""; + } else { + modularFields.style.display = "none"; + } + }); + }); +} diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 4aa6d562..09040ddb 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -15,7 +15,6 @@ dict = { code_zaw: `Zaw`, code_moteAmp: `Anfangsverstärker`, code_amp: `Verstärker`, - code_sirocco: `Sirocco`, code_kDrive: `K-Drive`, code_legendaryCore: `Legendärer Kern`, code_traumaticPeculiar: `Kuriose Mod: Traumatisch`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index ee197c9e..750468db 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -14,7 +14,6 @@ dict = { code_zaw: `Zaw`, code_moteAmp: `Mote Amp`, code_amp: `Amp`, - code_sirocco: `Sirocco`, code_kDrive: `K-Drive`, code_legendaryCore: `Legendary Core`, code_traumaticPeculiar: `Traumatic Peculiar`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index c51695bd..c1d8830d 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -15,7 +15,6 @@ dict = { code_zaw: `Zaw`, code_moteAmp: `Amplificateur Faible`, code_amp: `Amplificateur`, - code_sirocco: `Sirocco`, code_kDrive: `K-Drive`, code_legendaryCore: `Coeur Légendaire`, code_traumaticPeculiar: `Traumatisme Atypique`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 5af34072..7fda4ed1 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -15,7 +15,6 @@ dict = { code_zaw: `Зо`, code_moteAmp: `Пылинка`, code_amp: `Усилитель`, - code_sirocco: `Сирокко`, code_kDrive: `К-Драйв`, code_legendaryCore: `Легендарное ядро`, code_traumaticPeculiar: `Травмирующая Странность`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index dbcf45d0..de64de75 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -15,7 +15,6 @@ dict = { code_zaw: `自制近战`, code_moteAmp: `微尘增幅器`, code_amp: `增幅器`, - code_sirocco: `赤风`, code_kDrive: `K式悬浮板`, code_legendaryCore: `传奇核心`, code_traumaticPeculiar: `创伤怪奇`,