From 9ea061fdb3048ba8554ce6ff30a9dcde9207d79d Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Sat, 29 Mar 2025 19:38:25 +0100 Subject: [PATCH] feat(webui): adding modular K-Drives and Amps --- .../custom/addModularEquipmentController.ts | 20 +++++ .../custom/getItemListsController.ts | 4 +- src/routes/custom.ts | 4 +- static/webui/index.html | 22 +++++- static/webui/script.js | 79 +++++++++++++++++++ 5 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/controllers/custom/addModularEquipmentController.ts diff --git a/src/controllers/custom/addModularEquipmentController.ts b/src/controllers/custom/addModularEquipmentController.ts new file mode 100644 index 00000000..39a12b24 --- /dev/null +++ b/src/controllers/custom/addModularEquipmentController.ts @@ -0,0 +1,20 @@ +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 inventory = await getInventory(accountId); + const category = modularWeaponTypes[request.ItemType]; + addEquipment(inventory, category, request.ItemType, request.ModularParts); + occupySlot(inventory, productCategoryToInventoryBin(category)!, 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..dc81ef07 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 = { @@ -79,7 +80,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({ 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..2183cdd6 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -299,6 +299,12 @@
+
+ + + + +
@@ -309,6 +315,13 @@
+
+ + + + + +
@@ -604,7 +617,6 @@ - @@ -613,6 +625,14 @@ + + + + + + + + diff --git a/static/webui/script.js b/static/webui/script.js index 8697414e..ec036756 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -233,6 +233,30 @@ 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" + ]; + 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 +646,61 @@ function doAcquireEquipment(category) { }); } +function doAcquireModularEquipment(category) { + let 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": + ItemType = "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon"; + requiredParts = ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"]; + 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(() => { + requiredParts.forEach(part => { + document.getElementById("acquire-type-" + category + "-" + part).value = ""; + }); + updateInventory(); + }); + }); + } +} + $("input[list]").on("input", function () { $(this).removeClass("is-invalid"); });