From d033c2bc12dc89b65302d8ccf704a95ded867314 Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:18:41 -0700 Subject: [PATCH] feat(webui): MoaPets support (#1402) Translations were taken from the game Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1402 Reviewed-by: Sainan Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> --- .../custom/addModularEquipmentController.ts | 65 ++++++++++++++- src/helpers/modularWeaponHelper.ts | 1 + static/webui/index.html | 37 +++++++++ static/webui/script.js | 80 ++++++++++++++++--- static/webui/translations/de.js | 6 ++ static/webui/translations/en.js | 6 ++ static/webui/translations/fr.js | 6 ++ static/webui/translations/ru.js | 6 ++ static/webui/translations/zh.js | 6 ++ 9 files changed, 201 insertions(+), 12 deletions(-) diff --git a/src/controllers/custom/addModularEquipmentController.ts b/src/controllers/custom/addModularEquipmentController.ts index ea51e2d3..f1f6cd17 100644 --- a/src/controllers/custom/addModularEquipmentController.ts +++ b/src/controllers/custom/addModularEquipmentController.ts @@ -1,15 +1,26 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; -import { getInventory, addEquipment, occupySlot, productCategoryToInventoryBin } from "@/src/services/inventoryService"; +import { + getInventory, + addEquipment, + occupySlot, + productCategoryToInventoryBin, + applyDefaultUpgrades +} from "@/src/services/inventoryService"; import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper"; +import { getDefaultUpgrades } from "@/src/services/itemDataService"; +import { IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ExportWeapons } from "warframe-public-export-plus"; import { RequestHandler } from "express"; export const addModularEquipmentController: RequestHandler = async (req, res) => { + const requiredFields = new Set(); 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}`); + requiredFields.add(category); + requiredFields.add(inventoryBin); + request.ModularParts.forEach(part => { if (ExportWeapons[part].gunType) { if (category == "LongGuns") { @@ -25,9 +36,57 @@ export const addModularEquipmentController: RequestHandler = async (req, res) => GT_BEAM: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam" }[ExportWeapons[part].gunType]; } + } else if (request.ItemType == "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit") { + if (part.includes("ZanukaPetPartHead")) { + request.ItemType = { + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadA": + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadB": + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadC": + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit" + }[part]!; + } } }); - addEquipment(inventory, category, request.ItemType, request.ModularParts); + const defaultUpgrades = getDefaultUpgrades(request.ModularParts); + if (defaultUpgrades) { + requiredFields.add("RawUpgrades"); + } + const defaultWeaponsMap: Record = { + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit": [ + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetMeleeWeaponIP" + ], + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit": [ + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetMeleeWeaponIS" + ], + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit": [ + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetMeleeWeaponPS" + ] + }; + const defaultWeapons = defaultWeaponsMap[request.ItemType]; + if (defaultWeapons) { + for (const defaultWeapon of defaultWeapons) { + const category = ExportWeapons[defaultWeapon].productCategory; + requiredFields.add(category); + requiredFields.add(productCategoryToInventoryBin(category)); + } + } + + const inventory = await getInventory(accountId, Array.from(requiredFields).join(" ")); + if (defaultWeapons) { + for (const defaultWeapon of defaultWeapons) { + const category = ExportWeapons[defaultWeapon].productCategory; + addEquipment(inventory, category, defaultWeapon); + occupySlot(inventory, productCategoryToInventoryBin(category)!, true); + } + } + + const defaultOverwrites: Partial = { + Configs: applyDefaultUpgrades(inventory, defaultUpgrades) + }; + + addEquipment(inventory, category, request.ItemType, request.ModularParts, undefined, defaultOverwrites); occupySlot(inventory, inventoryBin, true); await inventory.save(); res.end(); diff --git a/src/helpers/modularWeaponHelper.ts b/src/helpers/modularWeaponHelper.ts index cf0e9b19..5651f373 100644 --- a/src/helpers/modularWeaponHelper.ts +++ b/src/helpers/modularWeaponHelper.ts @@ -13,6 +13,7 @@ export const modularWeaponTypes: Record = { "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": "OperatorAmps", "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": "Hoverboards", "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit": "MoaPets", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit": "MoaPets", "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit": "MoaPets", "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit": "MoaPets", "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit": "MoaPets", diff --git a/static/webui/index.html b/static/webui/index.html index f5df02df..aefb1f11 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -294,6 +294,34 @@ +
+
+
+
+
+ + +
+ + + + +
+
+
+
+ +
@@ -637,6 +665,7 @@ + @@ -659,6 +688,14 @@ + + + + + + + + diff --git a/static/webui/script.js b/static/webui/script.js index 73783972..9538c218 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -202,6 +202,15 @@ function fetchItemList() { uniqueName: "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary", name: loc("code_kitgun") }); + data.MoaPets ??= []; + data.MoaPets.push({ + uniqueName: "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit", + name: loc("code_moa") + }); + data.MoaPets.push({ + uniqueName: "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit", + name: loc("code_zanuka") + }); const itemMap = { // Generics for rivens @@ -220,7 +229,16 @@ function fetchItemList() { "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/OperatorTrainingAmpWeapon": { name: loc("code_moteAmp") }, - "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": { name: loc("code_kDrive") } + "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": { name: loc("code_kDrive") }, + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit": { + name: loc("code_zanukaA") + }, + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit": { + name: loc("code_zanukaB") + }, + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit": { + name: loc("code_zanukaC") + } }; for (const [type, items] of Object.entries(data)) { if (type == "archonCrystalUpgrades") { @@ -259,7 +277,15 @@ function fetchItemList() { "LWPT_GUN_PRIMARY_HANDLE", "LWPT_GUN_SECONDARY_HANDLE", "LWPT_GUN_BARREL", - "LWPT_GUN_CLIP" + "LWPT_GUN_CLIP", + "LWPT_MOA_ENGINE", + "LWPT_MOA_PAYLOAD", + "LWPT_MOA_HEAD", + "LWPT_MOA_LEG", + "LWPT_ZANUKA_BODY", + "LWPT_ZANUKA_HEAD", + "LWPT_ZANUKA_LEG", + "LWPT_ZANUKA_TAIL" ]; if (supportedModularParts.includes(item.partType)) { const option = document.createElement("option"); @@ -269,6 +295,7 @@ function fetchItemList() { .getElementById("datalist-" + type + "-" + item.partType.slice(5)) .appendChild(option); } else { + console.log(item.partType); const option = document.createElement("option"); option.setAttribute("data-key", item.uniqueName); option.value = item.name; @@ -308,7 +335,11 @@ function updateInventory() { "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun", "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon", "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", - "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit" + "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit", + "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetAPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetBPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetCPowerSuit" ]; // Populate inventory route @@ -330,7 +361,8 @@ function updateInventory() { "SentinelWeapons", "Hoverboards", "OperatorAmps", - "MechSuits" + "MechSuits", + "MoaPets" ].forEach(category => { document.getElementById(category + "-list").innerHTML = ""; data[category].forEach(item => { @@ -709,6 +741,13 @@ function doAcquireModularEquipment(category, ItemType) { case "Pistols": requiredParts = ["GUN_BARREL", "GUN_SECONDARY_HANDLE", "GUN_CLIP"]; break; + case "MoaPets": + if (ItemType == "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit") { + requiredParts = ["MOA_ENGINE", "MOA_PAYLOAD", "MOA_HEAD", "MOA_LEG"]; + } else { + requiredParts = ["ZANUKA_BODY", "ZANUKA_HEAD", "ZANUKA_LEG", "ZANUKA_TAIL"]; + } + break; } requiredParts.forEach(part => { const partName = getKey(document.getElementById("acquire-type-" + category + "-" + part)); @@ -1375,7 +1414,9 @@ function handleModularSelection(category) { "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon", "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary", - "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary" + "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary", + "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit" ]; const itemType = getKey(document.getElementById("acquire-type-" + category)); @@ -1390,16 +1431,37 @@ function handleModularSelection(category) { "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon", "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon", "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary", - "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary" + "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary", + "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit", + "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit" ]; - const supportedModularInventoryCategory = ["OperatorAmps", "Melee", "LongGuns", "Pistols"]; + const supportedModularInventoryCategory = ["OperatorAmps", "Melee", "LongGuns", "Pistols", "MoaPets"]; 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 = ""; + const modularFieldsZanuka = + inventoryCategory === "MoaPets" + ? document.getElementById("modular-" + inventoryCategory + "-Zanuka") + : null; + const key = getKey(this); + + if (modularWeapons.includes(key)) { + if (key === "/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetPowerSuit" && modularFieldsZanuka) { + modularFields.style.display = "none"; + modularFieldsZanuka.style.display = ""; + } else if (key === "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit") { + modularFields.style.display = ""; + if (modularFieldsZanuka) { + modularFieldsZanuka.style.display = "none"; + } + } else { + modularFields.style.display = ""; + } } else { modularFields.style.display = "none"; + if (modularFieldsZanuka) { + modularFieldsZanuka.style.display = "none"; + } } }); }); diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 89684cea..87d56833 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -40,6 +40,11 @@ dict = { code_addModsConfirm: `Bist du sicher, dass du |COUNT| Mods zu deinem Account hinzufügen möchtest?`, code_succImport: `Erfolgreich importiert.`, code_gild: `Veredeln`, + code_moa: `Moa`, + code_zanuka: `Jagdhund`, + code_zanukaA: `Jagdhund: Dorma`, + code_zanukaB: `Jagdhund: Bhaira`, + code_zanukaC: `Jagdhund: Hec`, login_description: `Melde dich mit deinem OpenWF-Account an (denselben Angaben wie im Spiel, wenn du dich mit diesem Server verbindest).`, login_emailLabel: `E-Mail-Adresse`, login_passwordLabel: `Passwort`, @@ -65,6 +70,7 @@ dict = { inventory_sentinelWeapons: `Wächter-Waffen`, inventory_operatorAmps: `Verstärker`, inventory_hoverboards: `K-Drives`, + inventory_moaPets: `Moa`, inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`, inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`, inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 251c9ccc..6a465fc2 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -39,6 +39,11 @@ dict = { code_addModsConfirm: `Are you sure you want to add |COUNT| mods to your account?`, code_succImport: `Successfully imported.`, code_gild: `Gild`, + code_moa: `Moa`, + code_zanuka: `Hound`, + code_zanukaA: `Dorma Hound`, + code_zanukaB: `Bhaira Hound`, + code_zanukaC: `Hec Hound`, login_description: `Login using your OpenWF account credentials (same as in-game when connecting to this server).`, login_emailLabel: `Email address`, login_passwordLabel: `Password`, @@ -64,6 +69,7 @@ dict = { inventory_sentinelWeapons: `Sentinel Weapons`, inventory_operatorAmps: `Amps`, inventory_hoverboards: `K-Drives`, + inventory_moaPets: `Moa`, inventory_bulkAddSuits: `Add Missing Warframes`, inventory_bulkAddWeapons: `Add Missing Weapons`, inventory_bulkAddSpaceSuits: `Add Missing Archwings`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index b9bff424..a9aafae2 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -40,6 +40,11 @@ dict = { code_addModsConfirm: `Ajouter |COUNT| mods à l'inventaire ?`, code_succImport: `Importé.`, code_gild: `[UNTRANSLATED] Gild`, + code_moa: `Moa`, + code_zanuka: `Molosse`, + code_zanukaA: `Molosse Dorma`, + code_zanukaB: `Molosse Bhaira`, + code_zanukaC: `Molosse Hec`, login_description: `Connexion avec les informations de connexion OpenWF.`, login_emailLabel: `Email`, login_passwordLabel: `Mot de passe`, @@ -65,6 +70,7 @@ dict = { inventory_sentinelWeapons: `Armes de sentinelles`, inventory_operatorAmps: `Amplificateurs`, inventory_hoverboards: `K-Drives`, + inventory_moaPets: `Moa`, inventory_bulkAddSuits: `Ajouter les Warframes manquantes`, inventory_bulkAddWeapons: `Ajouter les armes manquantes`, inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index 3fd2575f..a10f72e4 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -40,6 +40,11 @@ dict = { code_addModsConfirm: `Вы уверены, что хотите добавить |COUNT| модов на ваш аккаунт?`, code_succImport: `Успешно импортировано.`, code_gild: `Улучшить`, + code_moa: `МОА`, + code_zanuka: `Гончая`, + code_zanukaA: `Гончая: Дорма`, + code_zanukaB: `Гончая: Бхайра`, + code_zanukaC: `Гончая: Хек`, login_description: `Войдите, используя учетные данные OpenWF (те же, что и в игре при подключении к этому серверу).`, login_emailLabel: `Адрес электронной почты`, login_passwordLabel: `Пароль`, @@ -65,6 +70,7 @@ dict = { inventory_sentinelWeapons: `Оружие стражей`, inventory_operatorAmps: `Усилители`, inventory_hoverboards: `К-Драйвы`, + inventory_moaPets: `МОА`, inventory_bulkAddSuits: `Добавить отсутствующие варфреймы`, inventory_bulkAddWeapons: `Добавить отсутствующее оружие`, inventory_bulkAddSpaceSuits: `Добавить отсутствующие арчвинги`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index cf23e042..b28de1cc 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -40,6 +40,11 @@ dict = { code_addModsConfirm: `确定要向账户添加 |COUNT| 张MOD吗?`, code_succImport: `导入成功。`, code_gild: `[UNTRANSLATED] Gild`, + code_moa: `恐鸟`, + code_zanuka: `猎犬`, + code_zanukaA: `铎玛猎犬`, + code_zanukaB: `拜拉猎犬`, + code_zanukaC: `骸克猎犬`, login_description: `使用您的 OpenWF 账户凭证登录(与游戏内连接本服务器时使用的昵称相同)。`, login_emailLabel: `电子邮箱`, login_passwordLabel: `密码`, @@ -65,6 +70,7 @@ dict = { inventory_sentinelWeapons: `守护武器`, inventory_operatorAmps: `增幅器`, inventory_hoverboards: `K式悬浮板`, + inventory_moaPets: `恐鸟`, inventory_bulkAddSuits: `添加缺失战甲`, inventory_bulkAddWeapons: `添加缺失武器`, inventory_bulkAddSpaceSuits: `添加缺失Archwing`,