XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat(webui): Valence Bonus (#2348)

Closes #1181 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2348 Reviewed-by: Sainan <sainan@calamity.inc> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

d1c860c6
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

11 个文件 +298 -78
Added src/controllers/custom/updateFingerprintController.ts +39 -0
@@ -0,0 +1,39 @@
1 import { getInventory } from "@/src/services/inventoryService";
2 import { WeaponTypeInternal } from "@/src/services/itemDataService";
3 import { getAccountIdForRequest } from "@/src/services/loginService";
4 import { RequestHandler } from "express";
5
6 export const updateFingerprintController: RequestHandler = async (req, res) => {
7 const accountId = await getAccountIdForRequest(req);
8 const request = req.body as IUpdateFingerPrintRequest;
9 const inventory = await getInventory(accountId, request.category);
10 const item = inventory[request.category].id(request.oid);
11 if (item) {
12 if (request.action == "set" && request.upgradeFingerprint.buffs[0].Tag) {
13 const newUpgradeFingerprint = request.upgradeFingerprint;
14 if (!newUpgradeFingerprint.compact) newUpgradeFingerprint.compact = item.ItemType;
15
16 item.UpgradeType = request.upgradeType;
17 item.UpgradeFingerprint = JSON.stringify(newUpgradeFingerprint);
18 } else if (request.action == "remove") {
19 item.UpgradeFingerprint = undefined;
20 item.UpgradeType = undefined;
21 }
22 await inventory.save();
23 }
24 res.end();
25 };
26
27 interface IUpdateFingerPrintRequest {
28 category: WeaponTypeInternal;
29 oid: string;
30 action: "set" | "remove";
31 upgradeType: string;
32 upgradeFingerprint: {
33 compact?: string;
34 buffs: {
35 Tag: string;
36 Value: number;
37 }[];
38 };
39 }
Modified src/routes/custom.ts +2 -0
@@ -24,6 +24,7 @@ import { importController } from "@/src/controllers/custom/importController";
24 24 import { manageQuestsController } from "@/src/controllers/custom/manageQuestsController";
25 25 import { setEvolutionProgressController } from "@/src/controllers/custom/setEvolutionProgressController";
26 26 import { setBoosterController } from "@/src/controllers/custom/setBoosterController";
27 import { updateFingerprintController } from "@/src/controllers/custom/updateFingerprintController";
27 28
28 29 import { getConfigController, setConfigController } from "@/src/controllers/custom/configController";
29 30
@@ -53,6 +54,7 @@ customRouter.post("/import", importController);
53 54 customRouter.post("/manageQuests", manageQuestsController);
54 55 customRouter.post("/setEvolutionProgress", setEvolutionProgressController);
55 56 customRouter.post("/setBooster", setBoosterController);
57 customRouter.post("/updateFingerprint", updateFingerprintController);
56 58
57 59 customRouter.post("/getConfig", getConfigController);
58 60 customRouter.post("/setConfig", setConfigController);
Modified src/routes/webui.ts +1 -1
@@ -24,7 +24,7 @@ webuiRouter.use("/webui", (req, res, next) => {
24 24 webuiRouter.get("/webui/inventory", (_req, res) => {
25 25 res.sendFile(path.join(baseDir, "static/webui/index.html"));
26 26 });
27 webuiRouter.get(/webui\/powersuit\/(.+)/, (_req, res) => {
27 webuiRouter.get("/webui/detailedView", (_req, res) => {
28 28 res.sendFile(path.join(baseDir, "static/webui/index.html"));
29 29 });
30 30 webuiRouter.get("/webui/mods", (_req, res) => {
Modified static/webui/index.html +17 -5
@@ -456,15 +456,15 @@
456 456 </div>
457 457 </div>
458 458 </div>
459 <div id="powersuit-route" data-route="~ /webui/powersuit/(.+)" data-title="Inventory | OpenWF WebUI">
459 <div id="detailedView-route" data-route="/webui/detailedView" data-title="Inventory | OpenWF WebUI">
460 460 <h3 class="mb-0"></h3>
461 461 <p class="text-body-secondary"></p>
462 <div class="card">
463 <h5 class="card-header" data-loc="powersuit_archonShardsLabel"></h5>
462 <div id="archonShards-card" class="card mb-3 d-none">
463 <h5 class="card-header" data-loc="detailedView_archonShardsLabel"></h5>
464 464 <div class="card-body">
465 465 <p>
466 <span data-loc="powersuit_archonShardsDescription"></span>
467 <span data-loc="powersuit_archonShardsDescription2"></span>
466 <span data-loc="detailedView_archonShardsDescription"></span>
467 <span data-loc="detailedView_archonShardsDescription2"></span>
468 468 </p>
469 469 <form class="input-group mb-3" onsubmit="doPushArchonCrystalUpgrade();return false;">
470 470 <input type="number" id="archon-crystal-add-count" min="1" max="10000" value="1" class="form-control" style="max-width:100px" />
@@ -477,6 +477,18 @@
477 477 </table>
478 478 </div>
479 479 </div>
480 <div id="valenceBonus-card" class="card mb-3 d-none">
481 <h5 class="card-header" data-loc="detailedView_valenceBonusLabel"></h5>
482 <div class="card-body">
483 <p data-loc="detailedView_valenceBonusDescription"></p>
484 <form class="input-group mb-3" onsubmit="handleValenceBonusChange(event)">
485 <select class="form-control" id="valenceBonus-innateDamage"></select>
486 <input type="number" id="valenceBonus-procent" min="25" max="60" step="0.1" class="form-control" style="max-width:100px" />
487 <button class="btn btn-primary" type="submit" value="set" data-loc="general_setButton"></button>
488 <button class="btn btn-danger" type="submit" value="remove" data-loc="general_removeButton"></button>
489 </form>
490 </div>
491 </div>
480 492 </div>
481 493 <div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
482 494 <p class="mb-3" data-loc="general_inventoryUpdateNote"></p>
Modified static/webui/script.js +131 -54
@@ -284,6 +284,8 @@ function fetchItemList() {
284 284 document.getElementById("changeSyndicate").innerHTML = "";
285 285 document.getElementById("changeSyndicate").appendChild(syndicateNone);
286 286
287 document.getElementById("valenceBonus-innateDamage").innerHTML = "";
288
287 289 // prettier-ignore
288 290 data.archonCrystalUpgrades = {
289 291 "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibrium": loc("upgrade_Equilibrium").split("|VAL|").join("20"),
@@ -366,6 +368,16 @@ function fetchItemList() {
366 368 };
367 369 window.archonCrystalUpgrades = data.archonCrystalUpgrades;
368 370
371 data.innateDamages = {
372 InnateElectricityDamage: loc("damageType_Electricity"),
373 InnateFreezeDamage: loc("damageType_Freeze"),
374 InnateHeatDamage: loc("damageType_Fire"),
375 InnateImpactDamage: loc("damageType_Impact"),
376 InnateMagDamage: loc("damageType_Magnetic"),
377 InnateRadDamage: loc("damageType_Radiation"),
378 InnateToxinDamage: loc("damageType_Poison")
379 };
380
369 381 // Add mods mising in data sources
370 382 data.mods.push({
371 383 uniqueName: "/Lotus/Upgrades/Mods/Fusers/LegendaryModFuser",
@@ -450,6 +462,13 @@ function fetchItemList() {
450 462 option.value = name;
451 463 document.getElementById("datalist-" + type).appendChild(option);
452 464 });
465 } else if (type == "innateDamages") {
466 Object.entries(items).forEach(([uniqueName, name]) => {
467 const option = document.createElement("option");
468 option.value = uniqueName;
469 option.textContent = name;
470 document.getElementById("valenceBonus-innateDamage").appendChild(option);
471 });
453 472 } else if (type == "uniqueLevelCaps") {
454 473 uniqueLevelCaps = items;
455 474 } else if (type == "Syndicates") {
@@ -659,6 +678,12 @@ function updateInventory() {
659 678 }
660 679 }
661 680
681 if (["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category)) {
682 const a = document.createElement("a");
683 a.href = "/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid;
684 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
685 td.appendChild(a);
686 }
662 687 if (item.XP < maxXP || anyExaltedMissingXP) {
663 688 const a = document.createElement("a");
664 689 a.href = "#";
@@ -721,13 +746,6 @@ function updateInventory() {
721 746 a.title = loc("code_unmature");
722 747 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M256 64A64 64 0 1 0 128 64a64 64 0 1 0 128 0zM152.9 169.3c-23.7-8.4-44.5-24.3-58.8-45.8L74.6 94.2C64.8 79.5 45 75.6 30.2 85.4s-18.7 29.7-8.9 44.4L40.9 159c18.1 27.1 42.8 48.4 71.1 62.4L112 480c0 17.7 14.3 32 32 32s32-14.3 32-32l0-96 32 0 0 96c0 17.7 14.3 32 32 32s32-14.3 32-32l0-258.4c29.1-14.2 54.4-36.2 72.7-64.2l18.2-27.9c9.6-14.8 5.4-34.6-9.4-44.3s-34.6-5.5-44.3 9.4L291 122.4c-21.8 33.4-58.9 53.6-98.8 53.6c-12.6 0-24.9-2-36.6-5.8c-.9-.3-1.8-.7-2.7-.9z"/></svg>`;
723 748 }
724
725 td.appendChild(a);
726 }
727 if (category == "Suits") {
728 const a = document.createElement("a");
729 a.href = "/webui/powersuit/" + item.ItemId.$oid;
730 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
731 749 td.appendChild(a);
732 750 }
733 751 {
@@ -1126,53 +1144,73 @@ function updateInventory() {
1126 1144 }
1127 1145 });
1128 1146
1129 // Populate powersuit route
1130 if (single.getCurrentPath().substr(0, 17) == "/webui/powersuit/") {
1131 const oid = single.getCurrentPath().substr(17);
1132 const item = data.Suits.find(x => x.ItemId.$oid == oid);
1147 // Populate detailedView route
1148 if (single.getCurrentPath().substr(0, 19) == "/webui/detailedView") {
1149 const urlParams = new URLSearchParams(window.location.search);
1150 const oid = urlParams.get("itemId");
1151 const category = urlParams.get("productCategory");
1152 const item = data[category].find(x => x.ItemId.$oid == oid);
1153
1133 1154 if (item) {
1134 1155 if (item.ItemName) {
1135 $("#powersuit-route h3").text(item.ItemName);
1136 $("#powersuit-route .text-body-secondary").text(itemMap[item.ItemType]?.name ?? item.ItemType);
1156 $("#detailedView-route h3").text(item.ItemName);
1157 $("#detailedView-route .text-body-secondary").text(
1158 itemMap[item.ItemType]?.name ?? item.ItemType
1159 );
1137 1160 } else {
1138 $("#powersuit-route h3").text(itemMap[item.ItemType]?.name ?? item.ItemType);
1139 $("#powersuit-route .text-body-secondary").text("");
1161 $("#detailedView-route h3").text(itemMap[item.ItemType]?.name ?? item.ItemType);
1162 $("#detailedView-route .text-body-secondary").text("");
1140 1163 }
1141 1164
1142 const uniqueUpgrades = {};
1143 (item.ArchonCrystalUpgrades ?? []).forEach(upgrade => {
1144 if (upgrade && upgrade.UpgradeType) {
1145 uniqueUpgrades[upgrade.UpgradeType] ??= 0;
1146 uniqueUpgrades[upgrade.UpgradeType] += 1;
1147 }
1148 });
1165 if (category == "Suits") {
1166 document.getElementById("archonShards-card").classList.remove("d-none");
1149 1167
1150 document.getElementById("crystals-list").innerHTML = "";
1151 Object.entries(uniqueUpgrades).forEach(([upgradeType, count]) => {
1152 const tr = document.createElement("tr");
1153 {
1154 const td = document.createElement("td");
1155 td.textContent = count + "x " + (archonCrystalUpgrades[upgradeType] ?? upgradeType);
1156 tr.appendChild(td);
1157 }
1158 {
1159 const td = document.createElement("td");
1160 td.classList = "text-end text-nowrap";
1168 const uniqueUpgrades = {};
1169 (item.ArchonCrystalUpgrades ?? []).forEach(upgrade => {
1170 if (upgrade && upgrade.UpgradeType) {
1171 uniqueUpgrades[upgrade.UpgradeType] ??= 0;
1172 uniqueUpgrades[upgrade.UpgradeType] += 1;
1173 }
1174 });
1175
1176 document.getElementById("crystals-list").innerHTML = "";
1177 Object.entries(uniqueUpgrades).forEach(([upgradeType, count]) => {
1178 const tr = document.createElement("tr");
1161 1179 {
1162 const a = document.createElement("a");
1163 a.href = "#";
1164 a.onclick = function (event) {
1165 event.preventDefault();
1166 doPopArchonCrystalUpgrade(upgradeType);
1167 };
1168 a.title = loc("code_remove");
1169 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
1170 td.appendChild(a);
1180 const td = document.createElement("td");
1181 td.textContent = count + "x " + (archonCrystalUpgrades[upgradeType] ?? upgradeType);
1182 tr.appendChild(td);
1171 1183 }
1172 tr.appendChild(td);
1184 {
1185 const td = document.createElement("td");
1186 td.classList = "text-end text-nowrap";
1187 {
1188 const a = document.createElement("a");
1189 a.href = "#";
1190 a.onclick = function (event) {
1191 event.preventDefault();
1192 doPopArchonCrystalUpgrade(upgradeType);
1193 };
1194 a.title = loc("code_remove");
1195 a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
1196 td.appendChild(a);
1197 }
1198 tr.appendChild(td);
1199 }
1200 document.getElementById("crystals-list").appendChild(tr);
1201 });
1202 } else if (["LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category)) {
1203 document.getElementById("valenceBonus-card").classList.remove("d-none");
1204 document.getElementById("valenceBonus-innateDamage").value = "";
1205 document.getElementById("valenceBonus-procent").value = 25;
1206
1207 if (item.UpgradeFingerprint) {
1208 const buff = JSON.parse(item.UpgradeFingerprint).buffs[0];
1209 const buffValue = fromUpdradeFingerPrintVaule(buff.Value, 0.25);
1210 document.getElementById("valenceBonus-innateDamage").value = buff.Tag ?? "";
1211 document.getElementById("valenceBonus-procent").value = Math.round(buffValue * 1000) / 10;
1173 1212 }
1174 document.getElementById("crystals-list").appendChild(tr);
1175 });
1213 }
1176 1214 } else {
1177 1215 single.loadRoute("/webui/inventory");
1178 1216 }
@@ -2110,16 +2148,19 @@ function doAddMissingMaxRankMods() {
2110 2148 });
2111 2149 }
2112 2150
2113 // Powersuit Route
2151 // DetailedView Route
2114 2152
2115 single.getRoute("#powersuit-route").on("beforeload", function () {
2153 single.getRoute("#detailedView-route").on("beforeload", function () {
2116 2154 this.element.querySelector("h3").textContent = "Loading...";
2155 document.getElementById("archonShards-card").classList.add("d-none");
2156 document.getElementById("valenceBonus-card").classList.add("d-none");
2117 2157 if (window.didInitialInventoryUpdate) {
2118 2158 updateInventory();
2119 2159 }
2120 2160 });
2121 2161
2122 2162 function doPushArchonCrystalUpgrade() {
2163 const urlParams = new URLSearchParams(window.location.search);
2123 2164 const uniqueName = getKey(document.querySelector("[list='datalist-archonCrystalUpgrades']"));
2124 2165 if (!uniqueName) {
2125 2166 $("[list='datalist-archonCrystalUpgrades']").addClass("is-invalid").focus();
@@ -2130,7 +2171,7 @@ function doPushArchonCrystalUpgrade() {
2130 2171 "/custom/pushArchonCrystalUpgrade?" +
2131 2172 window.authz +
2132 2173 "&oid=" +
2133 single.getCurrentPath().substr(17) +
2174 urlParams.get("itemId") +
2134 2175 "&type=" +
2135 2176 uniqueName +
2136 2177 "&count=" +
@@ -2143,14 +2184,10 @@ function doPushArchonCrystalUpgrade() {
2143 2184 }
2144 2185
2145 2186 function doPopArchonCrystalUpgrade(type) {
2187 const urlParams = new URLSearchParams(window.location.search);
2146 2188 revalidateAuthz().then(() => {
2147 2189 $.get(
2148 "/custom/popArchonCrystalUpgrade?" +
2149 window.authz +
2150 "&oid=" +
2151 single.getCurrentPath().substr(17) +
2152 "&type=" +
2153 type
2190 "/custom/popArchonCrystalUpgrade?" + window.authz + "&oid=" + urlParams.get("itemId") + "&type=" + type
2154 2191 ).done(function () {
2155 2192 updateInventory();
2156 2193 });
@@ -2661,3 +2698,43 @@ document.querySelectorAll(".tags-input").forEach(input => {
2661 2698 };
2662 2699 input.oninput();
2663 2700 });
2701
2702 function fromUpdradeFingerPrintVaule(raw, min) {
2703 const range = 0.6 - min;
2704 return min + (raw * range) / 0x3fffffff;
2705 }
2706
2707 function toUpdradeFingerPrintVaule(value, min) {
2708 const range = 0.6 - min;
2709 return Math.trunc(((value - min) * 0x3fffffff) / range);
2710 }
2711
2712 function handleValenceBonusChange(event) {
2713 event.preventDefault();
2714 const urlParams = new URLSearchParams(window.location.search);
2715 const action = event.submitter.value;
2716 const Tag = document.getElementById("valenceBonus-innateDamage").value;
2717 const Value = toUpdradeFingerPrintVaule(document.getElementById("valenceBonus-procent").value / 100, 0.25);
2718 revalidateAuthz().then(() => {
2719 $.post({
2720 url: "/custom/updateFingerprint?" + window.authz,
2721 contentType: "application/json",
2722 data: JSON.stringify({
2723 category: urlParams.get("productCategory"),
2724 oid: urlParams.get("itemId"),
2725 action,
2726 upgradeType: "/Lotus/Weapons/Grineer/KuvaLich/Upgrades/InnateDamageRandomMod",
2727 upgradeFingerprint: {
2728 buffs: [
2729 {
2730 Tag,
2731 Value
2732 }
2733 ]
2734 }
2735 })
2736 }).done(function () {
2737 updateInventory();
2738 });
2739 });
2740 }
Modified static/webui/translations/de.js +18 -3
@@ -2,7 +2,10 @@
2 2 dict = {
3 3 general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
4 4 general_addButton: `Hinzufügen`,
5 general_setButton: `[UNTRANSLATED] Set`,
6 general_removeButton: `[UNTRANSLATED] Remove`,
5 7 general_bulkActions: `Massenaktionen`,
8
6 9 code_loginFail: `[UNTRANSLATED] Login failed. Double-check the email and password.`,
7 10 code_regFail: `[UNTRANSLATED] Registration failed. Account already exists?`,
8 11 code_changeNameConfirm: `In welchen Namen möchtest du deinen Account umbenennen?`,
@@ -112,9 +115,13 @@ dict = {
112 115 currency_FusionPoints: `Endo`,
113 116 currency_PrimeTokens: `Reines Aya`,
114 117 currency_owned: `Du hast |COUNT|.`,
115 powersuit_archonShardsLabel: `Archon-Scherben-Slots`,
116 powersuit_archonShardsDescription: `Du kannst diese unbegrenzten Slots nutzen, um eine Vielzahl von Verbesserungen anzuwenden.`,
117 powersuit_archonShardsDescription2: `Hinweis: Jede Archon-Scherbe benötigt beim Laden etwas Zeit, um angewendet zu werden.`,
118
119 detailedView_archonShardsLabel: `Archon-Scherben-Slots`,
120 detailedView_archonShardsDescription: `Du kannst diese unbegrenzten Slots nutzen, um eine Vielzahl von Verbesserungen anzuwenden.`,
121 detailedView_archonShardsDescription2: `Hinweis: Jede Archon-Scherbe benötigt beim Laden etwas Zeit, um angewendet zu werden.`,
122 detailedView_valenceBonusLabel: `Valenz-Bonus`,
123 detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
124
118 125 mods_addRiven: `Riven hinzufügen`,
119 126 mods_fingerprint: `Fingerabdruck`,
120 127 mods_fingerprintHelp: `Benötigst du Hilfe mit dem Fingerabdruck?`,
@@ -291,6 +298,14 @@ dict = {
291 298 upgrade_SwiftExecute: `[UNTRANSLATED] Speed of Mercy Kills increased by 50%`,
292 299 upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after hacking`,
293 300
301 damageType_Electricity: `Elektrizität`,
302 damageType_Fire: `Hitze`,
303 damageType_Freeze: `Kälte`,
304 damageType_Impact: `Einschlag`,
305 damageType_Magnetic: `Magnetismus`,
306 damageType_Poison: `Gift`,
307 damageType_Radiation: `Strahlung`,
308
294 309 theme_dark: `[UNTRANSLATED] Dark Theme`,
295 310 theme_light: `[UNTRANSLATED] Light Theme`,
296 311
Modified static/webui/translations/en.js +18 -3
@@ -1,7 +1,10 @@
1 1 dict = {
2 2 general_inventoryUpdateNote: `Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
3 3 general_addButton: `Add`,
4 general_setButton: `Set`,
5 general_removeButton: `Remove`,
4 6 general_bulkActions: `Bulk Actions`,
7
5 8 code_loginFail: `Login failed. Double-check the email and password.`,
6 9 code_regFail: `Registration failed. Account already exists?`,
7 10 code_changeNameConfirm: `What would you like to change your account name to?`,
@@ -111,9 +114,13 @@ dict = {
111 114 currency_FusionPoints: `Endo`,
112 115 currency_PrimeTokens: `Regal Aya`,
113 116 currency_owned: `You have |COUNT|.`,
114 powersuit_archonShardsLabel: `Archon Shard Slots`,
115 powersuit_archonShardsDescription: `You can use these unlimited slots to apply a wide range of upgrades.`,
116 powersuit_archonShardsDescription2: `Note that each archon shard takes some time to be applied when loading in.`,
117
118 detailedView_archonShardsLabel: `Archon Shard Slots`,
119 detailedView_archonShardsDescription: `You can use these unlimited slots to apply a wide range of upgrades.`,
120 detailedView_archonShardsDescription2: `Note that each archon shard takes some time to be applied when loading in.`,
121 detailedView_valenceBonusLabel: `Valence Bonus`,
122 detailedView_valenceBonusDescription: `You can set or remove the Valence Bonus from your weapon.`,
123
117 124 mods_addRiven: `Add Riven`,
118 125 mods_fingerprint: `Fingerprint`,
119 126 mods_fingerprintHelp: `Need help with the fingerprint?`,
@@ -290,6 +297,14 @@ dict = {
290 297 upgrade_SwiftExecute: `Speed of Mercy Kills increased by 50%`,
291 298 upgrade_OnHackInvis: `Invisible for 15 seconds after hacking`,
292 299
300 damageType_Electricity: `Electricity`,
301 damageType_Fire: `Heat`,
302 damageType_Freeze: `Cold`,
303 damageType_Impact: `Impact`,
304 damageType_Magnetic: `Magnetic`,
305 damageType_Poison: `Toxin`,
306 damageType_Radiation: `Radiation`,
307
293 308 theme_dark: `Dark Theme`,
294 309 theme_light: `Light Theme`,
295 310
Modified static/webui/translations/es.js +18 -3
@@ -2,7 +2,10 @@
2 2 dict = {
3 3 general_inventoryUpdateNote: `Para ver los cambios en el juego, necesitas volver a sincronizar tu inventario, por ejemplo, usando el comando /sync del bootstrapper, visitando un dojo o repetidor, o volviendo a iniciar sesión.`,
4 4 general_addButton: `Agregar`,
5 general_setButton: `[UNTRANSLATED] Set`,
6 general_removeButton: `[UNTRANSLATED] Remove`,
5 7 general_bulkActions: `Acciones masivas`,
8
6 9 code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`,
7 10 code_regFail: `Error al registrar la cuenta. ¿Ya existe una cuenta con este correo?`,
8 11 code_changeNameConfirm: `¿Qué nombre te gustaría ponerle a tu cuenta?`,
@@ -112,9 +115,13 @@ dict = {
112 115 currency_FusionPoints: `Endo`,
113 116 currency_PrimeTokens: `Aya Real`,
114 117 currency_owned: `Tienes |COUNT|.`,
115 powersuit_archonShardsLabel: `Ranuras de Fragmento de Archón`,
116 powersuit_archonShardsDescription: `Puedes usar estas ranuras ilimitadas para aplicar una amplia variedad de mejoras`,
117 powersuit_archonShardsDescription2: `Ten en cuenta que cada fragmento de archón tarda un poco en aplicarse al cargar`,
118
119 detailedView_archonShardsLabel: `Ranuras de Fragmento de Archón`,
120 detailedView_archonShardsDescription: `Puedes usar estas ranuras ilimitadas para aplicar una amplia variedad de mejoras`,
121 detailedView_archonShardsDescription2: `Ten en cuenta que cada fragmento de archón tarda un poco en aplicarse al cargar`,
122 detailedView_valenceBonusLabel: `Bônus de Valência`,
123 detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
124
118 125 mods_addRiven: `Agregar Agrietado`,
119 126 mods_fingerprint: `Huella digital`,
120 127 mods_fingerprintHelp: `¿Necesitas ayuda con la huella digital?`,
@@ -291,6 +298,14 @@ dict = {
291 298 upgrade_SwiftExecute: `Velocidad de ejecuciones aumentada en un 50%`,
292 299 upgrade_OnHackInvis: `Invisible durante 15 segundos después de hackear`,
293 300
301 damageType_Electricity: `Eletricidade`,
302 damageType_Fire: `Ígneo`,
303 damageType_Freeze: `Glacial`,
304 damageType_Impact: `Colisivo`,
305 damageType_Magnetic: `Magnético`,
306 damageType_Poison: `Tóxico`,
307 damageType_Radiation: `Radioativo`,
308
294 309 theme_dark: `[UNTRANSLATED] Dark Theme`,
295 310 theme_light: `[UNTRANSLATED] Light Theme`,
296 311
Modified static/webui/translations/fr.js +18 -3
@@ -2,7 +2,10 @@
2 2 dict = {
3 3 general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
4 4 general_addButton: `Ajouter`,
5 general_setButton: `[UNTRANSLATED] Set`,
6 general_removeButton: `[UNTRANSLATED] Remove`,
5 7 general_bulkActions: `Action groupée`,
8
6 9 code_loginFail: `Connexion échouée. Vérifiez le mot de passe.`,
7 10 code_regFail: `Enregistrement impossible. Compte existant?`,
8 11 code_changeNameConfirm: `Nouveau nom du compte :`,
@@ -112,9 +115,13 @@ dict = {
112 115 currency_FusionPoints: `Endo`,
113 116 currency_PrimeTokens: `Aya Raffiné`,
114 117 currency_owned: `|COUNT| possédés.`,
115 powersuit_archonShardsLabel: `Emplacements de fragments d'Archonte`,
116 powersuit_archonShardsDescription: `Slots illimités pour appliquer plusieurs améliorations`,
117 powersuit_archonShardsDescription2: `Un délai sera présent entre l'application des éclats et le chargement en jeu.`,
118
119 detailedView_archonShardsLabel: `Emplacements de fragments d'Archonte`,
120 detailedView_archonShardsDescription: `Slots illimités pour appliquer plusieurs améliorations`,
121 detailedView_archonShardsDescription2: `Un délai sera présent entre l'application des éclats et le chargement en jeu.`,
122 detailedView_valenceBonusLabel: `Bonus de Valence`,
123 detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
124
118 125 mods_addRiven: `Ajouter un riven`,
119 126 mods_fingerprint: `Empreinte`,
120 127 mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`,
@@ -291,6 +298,14 @@ dict = {
291 298 upgrade_SwiftExecute: `Vitesse des miséricordes augmentée de 50%`,
292 299 upgrade_OnHackInvis: `Invisible pendant 15 secondes après un piratage`,
293 300
301 damageType_Electricity: `Électrique`,
302 damageType_Fire: `Feu`,
303 damageType_Freeze: `Glace`,
304 damageType_Impact: `Impact`,
305 damageType_Magnetic: `Magnétique`,
306 damageType_Poison: `Poison`,
307 damageType_Radiation: `Radiations`,
308
294 309 theme_dark: `[UNTRANSLATED] Dark Theme`,
295 310 theme_light: `[UNTRANSLATED] Light Theme`,
296 311
Modified static/webui/translations/ru.js +18 -3
@@ -2,7 +2,10 @@
2 2 dict = {
3 3 general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command, visiting a dojo/relay, or relogging.`,
4 4 general_addButton: `Добавить`,
5 general_setButton: `Установить`,
6 general_removeButton: `Удалить`,
5 7 general_bulkActions: `Массовые действия`,
8
6 9 code_loginFail: `[UNTRANSLATED] Login failed. Double-check the email and password.`,
7 10 code_regFail: `[UNTRANSLATED] Registration failed. Account already exists?`,
8 11 code_changeNameConfirm: `Какое имя вы хотите установить для своей учетной записи?`,
@@ -112,9 +115,13 @@ dict = {
112 115 currency_FusionPoints: `Эндо`,
113 116 currency_PrimeTokens: `Королевские Айя`,
114 117 currency_owned: `У тебя |COUNT|.`,
115 powersuit_archonShardsLabel: `Ячейки осколков архонта`,
116 powersuit_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`,
117 powersuit_archonShardsDescription2: `Обратите внимание: каждый фрагмент архонта применяется с задержкой при загрузке.`,
118
119 detailedView_archonShardsLabel: `Ячейки осколков архонта`,
120 detailedView_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`,
121 detailedView_archonShardsDescription2: `Обратите внимание: каждый фрагмент архонта применяется с задержкой при загрузке.`,
122 detailedView_valenceBonusLabel: `Бонус Валентности`,
123 detailedView_valenceBonusDescription: `Вы можете установить или убрать бонус валентности с вашего оружия.`,
124
118 125 mods_addRiven: `Добавить Мод Разлома`,
119 126 mods_fingerprint: `Отпечаток`,
120 127 mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
@@ -291,6 +298,14 @@ dict = {
291 298 upgrade_SwiftExecute: `[UNTRANSLATED] Speed of Mercy Kills increased by 50%`,
292 299 upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after hacking`,
293 300
301 damageType_Electricity: `Электричество`,
302 damageType_Fire: `Огонь`,
303 damageType_Freeze: `Холод`,
304 damageType_Impact: `Удар`,
305 damageType_Magnetic: `Магнит`,
306 damageType_Poison: `Токсин`,
307 damageType_Radiation: `Радиация`,
308
294 309 theme_dark: `[UNTRANSLATED] Dark Theme`,
295 310 theme_light: `[UNTRANSLATED] Light Theme`,
296 311
Modified static/webui/translations/zh.js +18 -3
@@ -2,7 +2,10 @@
2 2 dict = {
3 3 general_inventoryUpdateNote: `注意:要在游戏中查看更改,您需要重新同步库存,例如使用引导程序的 /sync 命令、访问道场 / 中继站或重新登录`,
4 4 general_addButton: `添加`,
5 general_setButton: `[UNTRANSLATED] Set`,
6 general_removeButton: `[UNTRANSLATED] Remove`,
5 7 general_bulkActions: `批量操作`,
8
6 9 code_loginFail: `登录失败。请检查邮箱和密码。`,
7 10 code_regFail: `注册失败。账号已存在。`,
8 11 code_changeNameConfirm: `您想将账户名称更改为什么?`,
@@ -112,9 +115,13 @@ dict = {
112 115 currency_FusionPoints: `内融核心`,
113 116 currency_PrimeTokens: `御品阿耶`,
114 117 currency_owned: `当前拥有 |COUNT|。`,
115 powersuit_archonShardsLabel: `执刑官源力石槽位`,
116 powersuit_archonShardsDescription: `您可以使用这些无限插槽应用各种强化效果`,
117 powersuit_archonShardsDescription2: `请注意, 在加载时, 每个执政官源力石都需要一定的时间来生效。`,
118
119 detailedView_archonShardsLabel: `执刑官源力石槽位`,
120 detailedView_archonShardsDescription: `您可以使用这些无限插槽应用各种强化效果`,
121 detailedView_archonShardsDescription2: `请注意, 在加载时, 每个执政官源力石都需要一定的时间来生效。`,
122 detailedView_valenceBonusLabel: `效价加成`,
123 detailedView_valenceBonusDescription: `[UNTRANSLATED] You can set or remove the Valence Bonus from your weapon.`,
124
118 125 mods_addRiven: `添加裂罅MOD`,
119 126 mods_fingerprint: `印记`,
120 127 mods_fingerprintHelp: `需要印记相关的帮助?`,
@@ -291,6 +298,14 @@ dict = {
291 298 upgrade_SwiftExecute: `怜悯之击速度提升50%`,
292 299 upgrade_OnHackInvis: `入侵后隐身15秒`,
293 300
301 damageType_Electricity: `电击`,
302 damageType_Fire: `火焰`,
303 damageType_Freeze: `冰冻`,
304 damageType_Impact: `冲击`,
305 damageType_Magnetic: `磁力`,
306 damageType_Poison: `毒素`,
307 damageType_Radiation: `辐射`,
308
294 309 theme_dark: `[UNTRANSLATED] Dark Theme`,
295 310 theme_light: `[UNTRANSLATED] Light Theme`,
296 311