返回提交历史
Added
src/controllers/custom/addModularEquipmentController.ts
+21
-0
Modified
src/controllers/custom/getItemListsController.ts
+6
-2
Modified
src/routes/custom.ts
+3
-1
Modified
static/webui/index.html
+34
-2
Modified
static/webui/script.js
+129
-5
Modified
static/webui/translations/de.js
+0
-1
Modified
static/webui/translations/en.js
+0
-1
Modified
static/webui/translations/fr.js
+0
-1
Modified
static/webui/translations/ru.js
+0
-1
Modified
static/webui/translations/zh.js
+0
-1
XFEstudio/SpaceNinjaServer
feat(webui): adding modular K-Drives, Amps and Zaw (#1374)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1374 Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
4cb883da
代码差异
10 个文件
+193
-15
@@ -0,0 +1,21 @@
1
import { getAccountIdForRequest } from "@/src/services/loginService";
2
import { getInventory, addEquipment, occupySlot, productCategoryToInventoryBin } from "@/src/services/inventoryService";
3
import { RequestHandler } from "express";
4
import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper";
5
6
export const addModularEquipmentController: RequestHandler = async (req, res) => {
7
const accountId = await getAccountIdForRequest(req);
8
const request = req.body as IAddModularEquipmentRequest;
9
const category = modularWeaponTypes[request.ItemType];
10
const inventoryBin = productCategoryToInventoryBin(category)!;
11
const inventory = await getInventory(accountId, `${category} ${inventoryBin}`);
12
addEquipment(inventory, category, request.ItemType, request.ModularParts);
13
occupySlot(inventory, inventoryBin, true);
14
await inventory.save();
15
res.end();
16
};
17
18
interface IAddModularEquipmentRequest {
19
ItemType: string;
20
ModularParts: string[];
21
}
@@ -25,6 +25,7 @@ interface ListedItem {
25
25
fusionLimit?: number;
26
26
exalted?: string[];
27
27
badReason?: "starter" | "frivolous" | "notraw";
28
partType?: string;
28
29
}
29
30
30
31
const relicQualitySuffixes: Record<TRelicQuality, string> = {
@@ -50,6 +51,7 @@ const getItemListsController: RequestHandler = (req, response) => {
50
51
res.MechSuits = [];
51
52
res.miscitems = [];
52
53
res.Syndicates = [];
54
res.OperatorAmps = [];
53
55
for (const [uniqueName, item] of Object.entries(ExportWarframes)) {
54
56
res[item.productCategory].push({
55
57
uniqueName,
@@ -79,7 +81,8 @@ const getItemListsController: RequestHandler = (req, response) => {
79
81
) {
80
82
res.ModularParts.push({
81
83
uniqueName,
82
name: getString(item.name, lang)
84
name: getString(item.name, lang),
85
partType: item.partType
83
86
});
84
87
if (uniqueName.split("/")[5] != "SentTrainingAmplifier") {
85
88
res.miscitems.push({
@@ -94,7 +97,8 @@ const getItemListsController: RequestHandler = (req, response) => {
94
97
item.productCategory == "Melee" ||
95
98
item.productCategory == "SpaceGuns" ||
96
99
item.productCategory == "SpaceMelee" ||
97
item.productCategory == "SentinelWeapons"
100
item.productCategory == "SentinelWeapons" ||
101
item.productCategory == "OperatorAmps"
98
102
) {
99
103
res[item.productCategory].push({
100
104
uniqueName,
@@ -13,8 +13,9 @@ import { unlockAllIntrinsicsController } from "@/src/controllers/custom/unlockAl
13
13
14
14
import { createAccountController } from "@/src/controllers/custom/createAccountController";
15
15
import { createMessageController } from "@/src/controllers/custom/createMessageController";
16
import { addCurrencyController } from "../controllers/custom/addCurrencyController";
16
import { addCurrencyController } from "@/src/controllers/custom/addCurrencyController";
17
17
import { addItemsController } from "@/src/controllers/custom/addItemsController";
18
import { addModularEquipmentController } from "@/src/controllers/custom/addModularEquipmentController";
18
19
import { addXpController } from "@/src/controllers/custom/addXpController";
19
20
import { importController } from "@/src/controllers/custom/importController";
20
21
@@ -39,6 +40,7 @@ customRouter.post("/createAccount", createAccountController);
39
40
customRouter.post("/createMessage", createMessageController);
40
41
customRouter.post("/addCurrency", addCurrencyController);
41
42
customRouter.post("/addItems", addItemsController);
43
customRouter.post("/addModularEquipment", addModularEquipmentController);
42
44
customRouter.post("/addXp", addXpController);
43
45
customRouter.post("/import", importController);
44
46
customRouter.post("/manageQuests", manageQuestsController);
@@ -193,10 +193,15 @@
193
193
<div class="card mb-3" style="height: 400px;">
194
194
<h5 class="card-header" data-loc="inventory_melee"></h5>
195
195
<div class="card-body overflow-auto">
196
<form class="input-group mb-3" onsubmit="doAcquireEquipment('Melee');return false;">
196
<form class="input-group mb-3" onsubmit="handleModularSelection('Melee');return false;">
197
197
<input class="form-control" id="acquire-type-Melee" list="datalist-Melee" />
198
198
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
199
199
</form>
200
<form class="input-group mb-3" id="modular-Melee" style="display: none;">
201
<input class="form-control" id="acquire-type-Melee-BLADE" list="datalist-ModularParts-BLADE" />
202
<input class="form-control" id="acquire-type-Melee-HILT" list="datalist-ModularParts-HILT" />
203
<input class="form-control" id="acquire-type-Melee-HILT_WEIGHT" list="datalist-ModularParts-HILT_WEIGHT" />
204
</form>
200
205
<table class="table table-hover w-100">
201
206
<tbody id="Melee-list"></tbody>
202
207
</table>
@@ -299,6 +304,15 @@
299
304
<div class="card mb-3" style="height: 400px;">
300
305
<h5 class="card-header" data-loc="inventory_operatorAmps"></h5>
301
306
<div class="card-body overflow-auto">
307
<form class="input-group mb-3" onsubmit="handleModularSelection('OperatorAmps');return false;">
308
<input class="form-control" id="acquire-type-OperatorAmps" list="datalist-OperatorAmps" />
309
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
310
</form>
311
<form class="input-group mb-3" id="modular-OperatorAmps" style="display: none;">
312
<input class="form-control" id="acquire-type-OperatorAmps-AMP_OCULUS" list="datalist-ModularParts-AMP_OCULUS" />
313
<input class="form-control" id="acquire-type-OperatorAmps-AMP_CORE" list="datalist-ModularParts-AMP_CORE" />
314
<input class="form-control" id="acquire-type-OperatorAmps-AMP_BRACE" list="datalist-ModularParts-AMP_BRACE" />
315
</form>
302
316
<table class="table table-hover w-100">
303
317
<tbody id="OperatorAmps-list"></tbody>
304
318
</table>
@@ -309,6 +323,13 @@
309
323
<div class="card mb-3" style="height: 400px;">
310
324
<h5 class="card-header" data-loc="inventory_hoverboards"></h5>
311
325
<div class="card-body overflow-auto">
326
<form class="input-group mb-3" onsubmit="doAcquireModularEquipment('HoverBoards');return false;">
327
<input class="form-control" id="acquire-type-HoverBoards-HB_DECK" list="datalist-ModularParts-HB_DECK" />
328
<input class="form-control" id="acquire-type-HoverBoards-HB_ENGINE" list="datalist-ModularParts-HB_ENGINE" />
329
<input class="form-control" id="acquire-type-HoverBoards-HB_FRONT" list="datalist-ModularParts-HB_FRONT" />
330
<input class="form-control" id="acquire-type-HoverBoards-HB_JET" list="datalist-ModularParts-HB_JET" />
331
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
332
</form>
312
333
<table class="table table-hover w-100">
313
334
<tbody id="Hoverboards-list"></tbody>
314
335
</table>
@@ -604,7 +625,6 @@
604
625
<datalist id="datalist-SpaceMelee"></datalist>
605
626
<datalist id="datalist-SentinelWeapons"></datalist>
606
627
<datalist id="datalist-Sentinels"></datalist>
607
<datalist id="datalist-ModularParts"></datalist>
608
628
<datalist id="datalist-MechSuits"></datalist>
609
629
<datalist id="datalist-Syndicates"></datalist>
610
630
<datalist id="datalist-miscitems"></datalist>
@@ -613,6 +633,18 @@
613
633
<option data-key="/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod" value="Traumatic Peculiar"></option>
614
634
</datalist>
615
635
<datalist id="datalist-archonCrystalUpgrades"></datalist>
636
<datalist id="datalist-OperatorAmps"></datalist>
637
<datalist id="datalist-ModularParts"></datalist>
638
<datalist id="datalist-ModularParts-HB_DECK"></datalist>
639
<datalist id="datalist-ModularParts-HB_ENGINE"></datalist>
640
<datalist id="datalist-ModularParts-HB_FRONT"></datalist>
641
<datalist id="datalist-ModularParts-HB_JET"></datalist>
642
<datalist id="datalist-ModularParts-AMP_OCULUS"></datalist>
643
<datalist id="datalist-ModularParts-AMP_CORE"></datalist>
644
<datalist id="datalist-ModularParts-AMP_BRACE"></datalist>
645
<datalist id="datalist-ModularParts-BLADE"></datalist>
646
<datalist id="datalist-ModularParts-HILT"></datalist>
647
<datalist id="datalist-ModularParts-HILT_WEIGHT"></datalist>
616
648
<script src="/webui/libs/jquery-3.6.0.min.js"></script>
617
649
<script src="/webui/libs/whirlpool-js.min.js"></script>
618
650
<script src="/webui/libs/single.js"></script>
@@ -185,6 +185,16 @@ function fetchItemList() {
185
185
name: loc("code_traumaticPeculiar")
186
186
});
187
187
188
// Add modular weapons
189
data.OperatorAmps.push({
190
uniqueName: "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
191
name: loc("code_amp")
192
});
193
data.Melee.push({
194
uniqueName: "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon",
195
name: loc("code_zaw")
196
});
197
188
198
const itemMap = {
189
199
// Generics for rivens
190
200
"/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: loc("code_archgun") },
@@ -201,14 +211,9 @@ function fetchItemList() {
201
211
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": { name: loc("code_kitgun") },
202
212
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": { name: loc("code_kitgun") },
203
213
"/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": { name: loc("code_kitgun") },
204
"/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": { name: loc("code_zaw") },
205
214
"/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/OperatorTrainingAmpWeapon": {
206
215
name: loc("code_moteAmp")
207
216
},
208
"/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": { name: loc("code_amp") },
209
"/Lotus/Weapons/Operator/Pistols/DrifterPistol/DrifterPistolPlayerWeapon": {
210
name: loc("code_sirocco")
211
},
212
217
"/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": { name: loc("code_kDrive") }
213
218
};
214
219
for (const [type, items] of Object.entries(data)) {
@@ -233,6 +238,33 @@ function fetchItemList() {
233
238
if (type == "Syndicates" && item.uniqueName.startsWith("RadioLegion")) {
234
239
item.name += " (" + item.uniqueName + ")";
235
240
}
241
if (type == "ModularParts") {
242
const supportedModularParts = [
243
"LWPT_HB_DECK",
244
"LWPT_HB_ENGINE",
245
"LWPT_HB_FRONT",
246
"LWPT_HB_JET",
247
"LWPT_AMP_OCULUS",
248
"LWPT_AMP_CORE",
249
"LWPT_AMP_BRACE",
250
"LWPT_BLADE",
251
"LWPT_HILT",
252
"LWPT_HILT_WEIGHT"
253
];
254
if (supportedModularParts.includes(item.partType)) {
255
const option = document.createElement("option");
256
option.setAttribute("data-key", item.uniqueName);
257
option.value = item.name;
258
document
259
.getElementById("datalist-" + type + "-" + item.partType.slice(5))
260
.appendChild(option);
261
} else {
262
const option = document.createElement("option");
263
option.setAttribute("data-key", item.uniqueName);
264
option.value = item.name;
265
document.getElementById("datalist-" + type).appendChild(option);
266
}
267
}
236
268
if (item.badReason != "notraw") {
237
269
const option = document.createElement("option");
238
270
option.setAttribute("data-key", item.uniqueName);
@@ -622,6 +654,67 @@ function doAcquireEquipment(category) {
622
654
});
623
655
}
624
656
657
function doAcquireModularEquipment(category, ItemType) {
658
let requiredParts;
659
let ModularParts = [];
660
switch (category) {
661
case "HoverBoards":
662
ItemType = "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit";
663
requiredParts = ["HB_DECK", "HB_ENGINE", "HB_FRONT", "HB_JET"];
664
break;
665
case "OperatorAmps":
666
requiredParts = ["AMP_OCULUS", "AMP_CORE", "AMP_BRACE"];
667
break;
668
case "Melee":
669
requiredParts = ["BLADE", "HILT", "HILT_WEIGHT"];
670
break;
671
}
672
requiredParts.forEach(part => {
673
const partName = getKey(document.getElementById("acquire-type-" + category + "-" + part));
674
if (partName) {
675
ModularParts.push(partName);
676
}
677
});
678
if (ModularParts.length != requiredParts.length) {
679
let isFirstPart = true;
680
requiredParts.forEach(part => {
681
const partSelector = document.getElementById("acquire-type-" + category + "-" + part);
682
if (!getKey(partSelector)) {
683
if (isFirstPart) {
684
isFirstPart = false;
685
$("#acquire-type-" + category + "-" + part)
686
.addClass("is-invalid")
687
.focus();
688
} else {
689
$("#acquire-type-" + category + "-" + part).addClass("is-invalid");
690
}
691
}
692
});
693
} else {
694
revalidateAuthz(() => {
695
const req = $.post({
696
url: "/custom/addModularEquipment?" + window.authz,
697
contentType: "application/json",
698
data: JSON.stringify({
699
ItemType,
700
ModularParts
701
})
702
});
703
req.done(() => {
704
const mainInput = document.getElementById("acquire-type-" + category);
705
if (mainInput) {
706
mainInput.value = "";
707
document.getElementById("modular-" + category).style.display = "none";
708
}
709
requiredParts.forEach(part => {
710
document.getElementById("acquire-type-" + category + "-" + part).value = "";
711
});
712
updateInventory();
713
});
714
});
715
}
716
}
717
625
718
$("input[list]").on("input", function () {
626
719
$(this).removeClass("is-invalid");
627
720
});
@@ -1220,3 +1313,34 @@ function toast(text) {
1220
1313
toast.appendChild(div);
1221
1314
new bootstrap.Toast(document.querySelector(".toast-container").appendChild(toast)).show();
1222
1315
}
1316
1317
function handleModularSelection(category) {
1318
const modularWeapons = [
1319
"/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
1320
"/Lotus/Weapons/Ostron/Melee/LotusModularWeapon"
1321
];
1322
const itemType = getKey(document.getElementById("acquire-type-" + category));
1323
1324
if (modularWeapons.includes(itemType)) {
1325
doAcquireModularEquipment(category, itemType);
1326
} else {
1327
doAcquireEquipment(category);
1328
}
1329
}
1330
{
1331
const modularWeapons = [
1332
"/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon",
1333
"/Lotus/Weapons/Ostron/Melee/LotusModularWeapon"
1334
];
1335
const supportedModularInventoryCategory = ["OperatorAmps", "Melee"];
1336
supportedModularInventoryCategory.forEach(inventoryCategory => {
1337
document.getElementById("acquire-type-" + inventoryCategory).addEventListener("input", function () {
1338
const modularFields = document.getElementById("modular-" + inventoryCategory);
1339
if (modularWeapons.includes(getKey(this))) {
1340
modularFields.style.display = "";
1341
} else {
1342
modularFields.style.display = "none";
1343
}
1344
});
1345
});
1346
}
@@ -15,7 +15,6 @@ dict = {
15
15
code_zaw: `Zaw`,
16
16
code_moteAmp: `Anfangsverstärker`,
17
17
code_amp: `Verstärker`,
18
code_sirocco: `Sirocco`,
19
18
code_kDrive: `K-Drive`,
20
19
code_legendaryCore: `Legendärer Kern`,
21
20
code_traumaticPeculiar: `Kuriose Mod: Traumatisch`,
@@ -14,7 +14,6 @@ dict = {
14
14
code_zaw: `Zaw`,
15
15
code_moteAmp: `Mote Amp`,
16
16
code_amp: `Amp`,
17
code_sirocco: `Sirocco`,
18
17
code_kDrive: `K-Drive`,
19
18
code_legendaryCore: `Legendary Core`,
20
19
code_traumaticPeculiar: `Traumatic Peculiar`,
@@ -15,7 +15,6 @@ dict = {
15
15
code_zaw: `Zaw`,
16
16
code_moteAmp: `Amplificateur Faible`,
17
17
code_amp: `Amplificateur`,
18
code_sirocco: `Sirocco`,
19
18
code_kDrive: `K-Drive`,
20
19
code_legendaryCore: `Coeur Légendaire`,
21
20
code_traumaticPeculiar: `Traumatisme Atypique`,
@@ -15,7 +15,6 @@ dict = {
15
15
code_zaw: `Зо`,
16
16
code_moteAmp: `Пылинка`,
17
17
code_amp: `Усилитель`,
18
code_sirocco: `Сирокко`,
19
18
code_kDrive: `К-Драйв`,
20
19
code_legendaryCore: `Легендарное ядро`,
21
20
code_traumaticPeculiar: `Травмирующая Странность`,
@@ -15,7 +15,6 @@ dict = {
15
15
code_zaw: `自制近战`,
16
16
code_moteAmp: `微尘增幅器`,
17
17
code_amp: `增幅器`,
18
code_sirocco: `赤风`,
19
18
code_kDrive: `K式悬浮板`,
20
19
code_legendaryCore: `传奇核心`,
21
20
code_traumaticPeculiar: `创伤怪奇`,