返回提交历史
Deleted
src/controllers/custom/addVaultDecoRecipeController.ts
+0
-36
Added
src/controllers/custom/addVaultTypeCountController.ts
+43
-0
Modified
src/controllers/custom/getItemListsController.ts
+9
-1
Modified
src/routes/custom.ts
+2
-2
Modified
static/webui/index.html
+40
-2
Modified
static/webui/script.js
+111
-69
Modified
static/webui/translations/de.js
+4
-1
Modified
static/webui/translations/en.js
+4
-1
Modified
static/webui/translations/es.js
+4
-1
Modified
static/webui/translations/fr.js
+4
-1
Modified
static/webui/translations/ru.js
+4
-1
Modified
static/webui/translations/uk.js
+4
-1
Modified
static/webui/translations/zh.js
+4
-1
XFEstudio/XFESpaceNinjaServer
feat(webui): Vault MiscItems and ShipDecorations (#2889)
Closes #2874 Closes #2875 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2889 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
c1c14b20
代码差异
13 个文件
+233
-117
@@ -1,36 +0,0 @@
1
import { getAccountIdForRequest } from "../../services/loginService.ts";
2
import { getInventory } from "../../services/inventoryService.ts";
3
import type { RequestHandler } from "express";
4
import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
5
import { GuildPermission } from "../../types/guildTypes.ts";
6
import type { ITypeCount } from "../../types/commonTypes.ts";
7
8
export const addVaultDecoRecipeController: RequestHandler = async (req, res) => {
9
const accountId = await getAccountIdForRequest(req);
10
const requests = req.body as ITypeCount[];
11
const inventory = await getInventory(accountId, "GuildId");
12
const guild = await getGuildForRequestEx(req, inventory);
13
if (!(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) {
14
res.status(400).send("-1").end();
15
return;
16
}
17
guild.VaultDecoRecipes ??= [];
18
for (const request of requests) {
19
const index = guild.VaultDecoRecipes.findIndex(x => x.ItemType === request.ItemType);
20
21
if (index == -1) {
22
guild.VaultDecoRecipes.push({
23
ItemType: request.ItemType,
24
ItemCount: request.ItemCount
25
});
26
} else {
27
guild.VaultDecoRecipes[index].ItemCount += request.ItemCount;
28
29
if (guild.VaultDecoRecipes[index].ItemCount < 1) {
30
guild.VaultDecoRecipes.splice(index, 1);
31
}
32
}
33
}
34
await guild.save();
35
res.end();
36
};
@@ -0,0 +1,43 @@
1
import { getAccountIdForRequest } from "../../services/loginService.ts";
2
import { getInventory } from "../../services/inventoryService.ts";
3
import type { RequestHandler } from "express";
4
import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
5
import { GuildPermission } from "../../types/guildTypes.ts";
6
import type { ITypeCount } from "../../types/commonTypes.ts";
7
8
export const addVaultTypeCountController: RequestHandler = async (req, res) => {
9
const accountId = await getAccountIdForRequest(req);
10
const { vaultType, items } = req.body as {
11
vaultType: keyof typeof vaultConfig;
12
items: ITypeCount[];
13
};
14
const inventory = await getInventory(accountId, "GuildId");
15
const guild = await getGuildForRequestEx(req, inventory);
16
if (!(await hasGuildPermission(guild, accountId, vaultConfig[vaultType]))) {
17
res.status(400).send("-1").end();
18
return;
19
}
20
guild[vaultType] ??= [];
21
for (const item of items) {
22
const index = guild[vaultType].findIndex(x => x.ItemType === item.ItemType);
23
if (index === -1) {
24
guild[vaultType].push({
25
ItemType: item.ItemType,
26
ItemCount: item.ItemCount
27
});
28
} else {
29
guild[vaultType][index].ItemCount += item.ItemCount;
30
if (guild[vaultType][index].ItemCount < 1) {
31
guild[vaultType].splice(index, 1);
32
}
33
}
34
}
35
36
await guild.save();
37
res.end();
38
};
39
const vaultConfig = {
40
VaultShipDecorations: GuildPermission.Treasurer,
41
VaultMiscItems: GuildPermission.Treasurer,
42
VaultDecoRecipes: GuildPermission.Architect
43
} as const;
@@ -38,6 +38,7 @@ interface ListedItem {
38
38
parazon?: boolean;
39
39
alwaysAvailable?: boolean;
40
40
maxLevelCap?: number;
41
eligibleForVault?: boolean;
41
42
}
42
43
43
44
interface ItemLists {
@@ -141,6 +142,12 @@ const getItemListsController: RequestHandler = (req, response) => {
141
142
}
142
143
]*/
143
144
};
145
const eligibleForVault = new Set<string>([
146
...Object.values(ExportDojoRecipes.research).flatMap(r => r.ingredients.map(i => i.ItemType)),
147
...Object.values(ExportDojoRecipes.fabrications).flatMap(f => f.ingredients.map(i => i.ItemType)),
148
...Object.values(ExportDojoRecipes.rooms).flatMap(r => r.ingredients.map(i => i.ItemType)),
149
...Object.values(ExportDojoRecipes.decos).flatMap(d => d.ingredients.map(i => i.ItemType))
150
]);
144
151
for (const [uniqueName, item] of Object.entries(ExportWarframes)) {
145
152
res[item.productCategory].push({
146
153
uniqueName,
@@ -246,7 +253,8 @@ const getItemListsController: RequestHandler = (req, response) => {
246
253
res.miscitems.push({
247
254
uniqueName: uniqueName,
248
255
name: name,
249
subtype: "Resource"
256
subtype: "Resource",
257
...(eligibleForVault.has(uniqueName) && { eligibleForVault: true })
250
258
});
251
259
}
252
260
}
@@ -34,7 +34,7 @@ import {
34
34
fundTechProjectController,
35
35
removeTechProjectController
36
36
} from "../controllers/custom/techProjectController.ts";
37
import { addVaultDecoRecipeController } from "../controllers/custom/addVaultDecoRecipeController.ts";
37
import { addVaultTypeCountController } from "../controllers/custom/addVaultTypeCountController.ts";
38
38
import { addXpController } from "../controllers/custom/addXpController.ts";
39
39
import { importController } from "../controllers/custom/importController.ts";
40
40
import { manageQuestsController } from "../controllers/custom/manageQuestsController.ts";
@@ -81,7 +81,7 @@ customRouter.post("/addCurrency", addCurrencyController);
81
81
customRouter.post("/addItems", addItemsController);
82
82
customRouter.post("/addTechProject", addTechProjectController);
83
83
customRouter.post("/removeTechProject", removeTechProjectController);
84
customRouter.post("/addVaultDecoRecipe", addVaultDecoRecipeController);
84
customRouter.post("/addVaultTypeCount", addVaultTypeCountController);
85
85
customRouter.post("/fundTechProject", fundTechProjectController);
86
86
customRouter.post("/completeTechProject", completeTechProjectsController);
87
87
customRouter.post("/addXp", addXpController);
@@ -624,7 +624,7 @@
624
624
<div class="card" style="height: 400px;">
625
625
<h5 class="card-header" data-loc="guildView_vaultDecoRecipes"></h5>
626
626
<div class="card-body d-flex flex-column">
627
<form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultDecoRecipe();return false;">
627
<form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultDecoRecipes');return false;">
628
628
<input class="form-control" id="acquire-type-VaultDecoRecipes" list="datalist-VaultDecoRecipes" />
629
629
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
630
630
</form>
@@ -637,6 +637,42 @@
637
637
</div>
638
638
</div>
639
639
</div>
640
<div class="row g-3 mb-3">
641
<div class="col-lg-6">
642
<div class="card" style="height: 400px;">
643
<h5 class="card-header" data-loc="guildView_vaultMiscItems"></h5>
644
<div class="card-body d-flex flex-column">
645
<form id="vaultMiscItems-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultMiscItems');return false;">
646
<input class="form-control" id="VaultMiscItems-count" type="number" value="1" />
647
<input class="form-control w-50" id="acquire-type-VaultMiscItems" list="datalist-VaultMiscItems" />
648
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
649
</form>
650
<div class="overflow-auto">
651
<table class="table table-hover w-100">
652
<tbody id="VaultMiscItems-list"></tbody>
653
</table>
654
</div>
655
</div>
656
</div>
657
</div>
658
<div class="col-lg-6">
659
<div class="card" style="height: 400px;">
660
<h5 class="card-header" data-loc="guildView_vaultShipDecorations"></h5>
661
<div class="card-body d-flex flex-column">
662
<form id="vaultShipDecorations-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultShipDecorations');return false;">
663
<input class="form-control" id="VaultShipDecorations-count" type="number" value="1" />
664
<input class="form-control w-50" id="acquire-type-VaultShipDecorations" list="datalist-ShipDecorations" />
665
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
666
</form>
667
<div class="overflow-auto">
668
<table class="table table-hover w-100">
669
<tbody id="VaultShipDecorations-list"></tbody>
670
</table>
671
</div>
672
</div>
673
</div>
674
</div>
675
</div>
640
676
<div class="row g-3 mb-3">
641
677
<div class="col-lg-6">
642
678
<div class="card" style="height: 400px;">
@@ -666,7 +702,8 @@
666
702
<div class="card-body" id="guild-actions">
667
703
<div class="mb-2 d-flex flex-wrap gap-2">
668
704
<button class="btn btn-primary" onclick="debounce(addMissingTechProjects);" data-loc="guildView_bulkAddTechProjects"></button>
669
<button class="btn btn-primary" onclick="debounce(addMissingVaultDecoRecipes);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
705
<button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultDecoRecipes']);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
706
<button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultShipDecorations']);" data-loc="guildView_bulkAddVaultShipDecorations"></button>
670
707
</div>
671
708
<div class="mb-2 d-flex flex-wrap gap-2">
672
709
<button class="btn btn-success" onclick="debounce(fundAllTechProjects);" data-loc="guildView_bulkFundTechProjects"></button>
@@ -1552,6 +1589,7 @@
1552
1589
<datalist id="datalist-FlavourItems"></datalist>
1553
1590
<datalist id="datalist-ShipDecorations"></datalist>
1554
1591
<datalist id="datalist-WeaponSkins"></datalist>
1592
<datalist id="datalist-VaultMiscItems"></datalist>
1555
1593
<datalist id="datalist-circuitGameModes">
1556
1594
<option>Survival</option>
1557
1595
<option>VoidFlood</option>
@@ -711,6 +711,10 @@ function fetchItemList() {
711
711
option.value += " (" + item.subtype + ")";
712
712
}
713
713
document.getElementById("datalist-" + type).appendChild(option);
714
if (item.eligibleForVault) {
715
const vaultOption = option.cloneNode(true);
716
document.getElementById("datalist-VaultMiscItems").appendChild(vaultOption);
717
}
714
718
} else {
715
719
//console.log(`Not adding ${item.uniqueName} to datalist for ${type} due to duplicate display name: ${item.name}`);
716
720
}
@@ -1802,6 +1806,8 @@ function updateInventory() {
1802
1806
document.getElementById("VaultRegularCredits-owned").classList.remove("mb-0");
1803
1807
document.getElementById("vaultPremiumCredits-form").classList.remove("d-none");
1804
1808
document.getElementById("VaultPremiumCredits-owned").classList.remove("mb-0");
1809
document.getElementById("vaultMiscItems-form").classList.remove("d-none");
1810
document.getElementById("vaultShipDecorations-form").classList.remove("d-none");
1805
1811
}
1806
1812
if (userGuildMember.Rank <= 1) {
1807
1813
document.querySelectorAll("#guild-actions button").forEach(btn => {
@@ -1892,42 +1898,55 @@ function updateInventory() {
1892
1898
document.getElementById("TechProjects-list").appendChild(tr);
1893
1899
});
1894
1900
1895
document.getElementById("VaultDecoRecipes-list").innerHTML = "";
1896
guildData.VaultDecoRecipes ??= [];
1897
guildData.VaultDecoRecipes.forEach(item => {
1898
const datalist = document.getElementById("datalist-VaultDecoRecipes");
1899
const optionToRemove = datalist.querySelector(`option[data-key="${item.ItemType}"]`);
1900
if (optionToRemove) {
1901
datalist.removeChild(optionToRemove);
1902
}
1903
const tr = document.createElement("tr");
1904
tr.setAttribute("data-item-type", item.ItemType);
1905
{
1906
const td = document.createElement("td");
1907
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
1908
tr.appendChild(td);
1909
}
1910
{
1911
const td = document.createElement("td");
1912
td.classList = "text-end text-nowrap";
1913
1914
if (userGuildMember && userGuildMember.Rank <= 1) {
1915
const a = document.createElement("a");
1916
a.href = "#";
1917
a.onclick = function (event) {
1918
event.preventDefault();
1919
reAddToItemList(itemMap, "VaultDecoRecipes", item.ItemType);
1920
removeVaultDecoRecipe(item.ItemType);
1921
};
1922
a.title = loc("code_remove");
1923
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>`;
1924
td.appendChild(a);
1901
["VaultDecoRecipes", "VaultMiscItems", "VaultShipDecorations"].forEach(vaultKey => {
1902
document.getElementById(vaultKey + "-list").innerHTML = "";
1903
(guildData[vaultKey] ??= []).forEach(item => {
1904
if (vaultKey == "VaultDecoRecipes") {
1905
const datalist = document.getElementById("datalist-VaultDecoRecipes");
1906
const optionToRemove = datalist.querySelector(
1907
`option[data-key="${item.ItemType}"]`
1908
);
1909
if (optionToRemove) {
1910
datalist.removeChild(optionToRemove);
1911
}
1925
1912
}
1926
1913
1927
tr.appendChild(td);
1928
}
1914
const tr = document.createElement("tr");
1915
tr.setAttribute("data-item-type", item.ItemType);
1916
{
1917
const td = document.createElement("td");
1918
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
1919
if (item.ItemCount > 1) {
1920
td.innerHTML += ` <span title='${loc("code_count")}'>🗍 ${parseInt(item.ItemCount)}</span>`;
1921
}
1922
tr.appendChild(td);
1923
}
1924
{
1925
const td = document.createElement("td");
1926
td.classList = "text-end text-nowrap";
1927
const canRemove =
1928
vaultKey === "VaultDecoRecipes"
1929
? userGuildMember && userGuildMember.Rank <= 1
1930
: userGuildPermissions && userGuildPermissions & 64;
1931
if (canRemove) {
1932
const a = document.createElement("a");
1933
a.href = "#";
1934
a.title = loc("code_remove");
1935
a.onclick = e => {
1936
e.preventDefault();
1937
if (vaultKey == "VaultDecoRecipes") {
1938
reAddToItemList(itemMap, vaultKey, item.ItemType);
1939
}
1940
removeVaultItem(vaultKey, item.ItemType, item.ItemCount * -1);
1941
};
1942
a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><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>`;
1943
td.appendChild(a);
1944
}
1945
tr.appendChild(td);
1946
}
1929
1947
1930
document.getElementById("VaultDecoRecipes-list").appendChild(tr);
1948
document.getElementById(vaultKey + "-list").appendChild(tr);
1949
});
1931
1950
});
1932
1951
1933
1952
document.getElementById("Members-list").innerHTML = "";
@@ -2346,41 +2365,52 @@ function addMissingEquipment(categories) {
2346
2365
}
2347
2366
}
2348
2367
2349
function addVaultDecoRecipe() {
2350
const uniqueName = getKey(document.getElementById("acquire-type-VaultDecoRecipes"));
2351
if (!uniqueName) {
2352
$("#acquire-type-VaultDecoRecipes").addClass("is-invalid").focus();
2368
function addVaultItem(vaultType) {
2369
const ItemType = getKey(document.getElementById(`acquire-type-${vaultType}`));
2370
if (!ItemType) {
2371
$(`#acquire-type-${vaultType}`).addClass("is-invalid").focus();
2353
2372
return;
2354
2373
}
2355
revalidateAuthz().then(() => {
2356
const req = $.post({
2357
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2358
contentType: "application/json",
2359
data: JSON.stringify([
2360
{
2361
ItemType: uniqueName,
2362
ItemCount: 1
2363
}
2364
])
2365
});
2366
req.done(() => {
2367
document.getElementById("acquire-type-VaultDecoRecipes").value = "";
2368
updateInventory();
2374
const ItemCount = ["VaultMiscItems", "VaultShipDecorations"].includes(vaultType)
2375
? parseInt($(`#${vaultType}-count`).val())
2376
: 1;
2377
if (ItemCount != 0) {
2378
revalidateAuthz().then(() => {
2379
const req = $.post({
2380
url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
2381
contentType: "application/json",
2382
data: JSON.stringify({
2383
vaultType,
2384
items: [
2385
{
2386
ItemType,
2387
ItemCount
2388
}
2389
]
2390
})
2391
});
2392
req.done(() => {
2393
document.getElementById(`acquire-type-${vaultType}`).value = "";
2394
updateInventory();
2395
});
2369
2396
});
2370
});
2397
}
2371
2398
}
2372
2399
2373
function removeVaultDecoRecipe(uniqueName) {
2400
function removeVaultItem(vaultType, ItemType, ItemCount) {
2374
2401
revalidateAuthz().then(() => {
2375
2402
const req = $.post({
2376
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2403
url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
2377
2404
contentType: "application/json",
2378
data: JSON.stringify([
2379
{
2380
ItemType: uniqueName,
2381
ItemCount: -1
2382
}
2383
])
2405
data: JSON.stringify({
2406
vaultType,
2407
items: [
2408
{
2409
ItemType,
2410
ItemCount
2411
}
2412
]
2413
})
2384
2414
});
2385
2415
req.done(() => {
2386
2416
updateInventory();
@@ -2462,13 +2492,16 @@ function fundGuildTechProject(uniqueName) {
2462
2492
});
2463
2493
}
2464
2494
2465
function dispatchAddVaultDecoRecipesBatch(requests) {
2495
function dispatchAddVaultItemsBatch(requests, vaultType) {
2466
2496
return new Promise(resolve => {
2467
2497
revalidateAuthz().then(() => {
2468
2498
const req = $.post({
2469
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
2499
url: "/custom/addVaultItems?" + window.authz + "&guildId=" + window.guildId,
2470
2500
contentType: "application/json",
2471
data: JSON.stringify(requests)
2501
data: JSON.stringify({
2502
vaultType,
2503
items: requests
2504
})
2472
2505
});
2473
2506
req.done(() => {
2474
2507
updateInventory();
@@ -2478,20 +2511,23 @@ function dispatchAddVaultDecoRecipesBatch(requests) {
2478
2511
});
2479
2512
}
2480
2513
2481
function addMissingVaultDecoRecipes() {
2514
function addMissingVaultItems(vaultType) {
2482
2515
const requests = [];
2483
2516
2484
document.querySelectorAll("#datalist-VaultDecoRecipes" + " option").forEach(elm => {
2485
if (!document.querySelector("#VaultDecoRecipes-list [data-item-type='" + elm.getAttribute("data-key") + "']")) {
2486
requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount: 1 });
2517
document.querySelectorAll(`#datalist-${vaultType} option`).forEach(elm => {
2518
const datalist = vaultType === "VaultShipDecorations" ? "ShipDecorations" : vaultType;
2519
if (!document.querySelector(`#${datalist}-list [data-item-type='${elm.getAttribute("data-key")}']`)) {
2520
let ItemCount = 1;
2521
if (category == "VaultShipDecorations") ItemCount = 999999;
2522
requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount });
2487
2523
}
2488
2524
});
2489
2525
2490
2526
if (
2491
2527
requests.length != 0 &&
2492
window.confirm(loc("code_addDecoRecipesConfirm").split("|COUNT|").join(requests.length))
2528
window.confirm(loc("code_addVaultItemsConfirm").split("|COUNT|").join(requests.length))
2493
2529
) {
2494
return dispatchAddVaultDecoRecipesBatch(requests);
2530
return dispatchAddVaultItemsBatch(requests, vaultType);
2495
2531
}
2496
2532
}
2497
2533
@@ -3445,6 +3481,12 @@ single.getRoute("#guild-route").on("beforeload", function () {
3445
3481
document.getElementById("VaultDecoRecipes-list").innerHTML = "";
3446
3482
document.getElementById("vaultDecoRecipes-form").classList.add("d-none");
3447
3483
document.getElementById("acquire-type-VaultDecoRecipes").value = "";
3484
document.getElementById("VaultMiscItems-list").innerHTML = "";
3485
document.getElementById("vaultMiscItems-form").classList.add("d-none");
3486
document.getElementById("acquire-type-VaultMiscItems").value = "";
3487
document.getElementById("VaultShipDecorations-list").innerHTML = "";
3488
document.getElementById("vaultShipDecorations-form").classList.add("d-none");
3489
document.getElementById("acquire-type-VaultShipDecorations").value = "";
3448
3490
document.getElementById("Alliance-list").innerHTML = "";
3449
3491
document.getElementById("guildView-alliance").textContent = "";
3450
3492
document.getElementById("Members-list").innerHTML = "";
@@ -33,7 +33,7 @@ dict = {
33
33
code_remove: `Entfernen`,
34
34
code_addItemsConfirm: `Bist du sicher, dass du |COUNT| Gegenstände zu deinem Account hinzufügen möchtest?`,
35
35
code_addTechProjectsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| research to your clan?`,
36
code_addDecoRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| deco recipes to your clan?`,
36
code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37
37
code_succRankUp: `Erfolgreich aufgestiegen.`,
38
38
code_noEquipmentToRankUp: `Keine Ausstattung zum Rangaufstieg verfügbar.`,
39
39
code_succAdded: `Erfolgreich hinzugefügt.`,
@@ -419,6 +419,8 @@ dict = {
419
419
guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
420
420
guildView_techProjects: `Forschung`,
421
421
guildView_vaultDecoRecipes: `[UNTRANSLATED] Dojo Deco Recipes`,
422
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422
424
guildView_alliance: `Allianz`,
423
425
guildView_members: `Mitglieder`,
424
426
guildView_pending: `Ausstehend`,
@@ -441,6 +443,7 @@ dict = {
441
443
guildView_currency_owned: `[UNTRANSLATED] |COUNT| in Vault.`,
442
444
guildView_bulkAddTechProjects: `[UNTRANSLATED] Add Missing Research`,
443
445
guildView_bulkAddVaultDecoRecipes: `[UNTRANSLATED] Add Missing Dojo Deco Recipes`,
446
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444
447
guildView_bulkFundTechProjects: `[UNTRANSLATED] Fund All Research`,
445
448
guildView_bulkCompleteTechProjects: `[UNTRANSLATED] Complete All Research`,
446
449
guildView_promote: `Befördern`,
@@ -32,7 +32,7 @@ dict = {
32
32
code_remove: `Remove`,
33
33
code_addItemsConfirm: `Are you sure you want to add |COUNT| items to your account?`,
34
34
code_addTechProjectsConfirm: `Are you sure you want to add |COUNT| research to your clan?`,
35
code_addDecoRecipesConfirm: `Are you sure you want to add |COUNT| deco recipes to your clan?`,
35
code_addVaultItemsConfirm: `Are you sure you want to add |COUNT| items to your clan vault?`,
36
36
code_succRankUp: `Successfully ranked up.`,
37
37
code_noEquipmentToRankUp: `No equipment to rank up.`,
38
38
code_succAdded: `Successfully added.`,
@@ -418,6 +418,8 @@ dict = {
418
418
guildView_cheats: `Clan Cheats`,
419
419
guildView_techProjects: `Research`,
420
420
guildView_vaultDecoRecipes: `Dojo Deco Recipes`,
421
guildView_vaultMiscItems: `Resources in Vault`,
422
guildView_vaultShipDecorations: `Decorations in Vault`,
421
423
guildView_alliance: `Alliance`,
422
424
guildView_members: `Members`,
423
425
guildView_pending: `Pending`,
@@ -440,6 +442,7 @@ dict = {
440
442
guildView_currency_owned: `|COUNT| in Vault.`,
441
443
guildView_bulkAddTechProjects: `Add Missing Research`,
442
444
guildView_bulkAddVaultDecoRecipes: `Add Missing Dojo Deco Recipes`,
445
guildView_bulkAddVaultShipDecorations: `Add Missing Decorations in Vault`,
443
446
guildView_bulkFundTechProjects: `Fund All Research`,
444
447
guildView_bulkCompleteTechProjects: `Complete All Research`,
445
448
guildView_promote: `Promote`,
@@ -33,7 +33,7 @@ dict = {
33
33
code_remove: `Quitar`,
34
34
code_addItemsConfirm: `¿Estás seguro de que deseas agregar |COUNT| objetos a tu cuenta?`,
35
35
code_addTechProjectsConfirm: `¿Estás seguro de que quieres añadir |COUNT| proyectos de investigación a tu clan?`,
36
code_addDecoRecipesConfirm: `¿Estás seguro de que quieres añadir |COUNT| planos de decoración a tu clan?`,
36
code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37
37
code_succRankUp: `Ascenso exitoso.`,
38
38
code_noEquipmentToRankUp: `No hay equipo para ascender.`,
39
39
code_succAdded: `Agregado exitosamente.`,
@@ -419,6 +419,8 @@ dict = {
419
419
guildView_cheats: `Trucos de Clan`,
420
420
guildView_techProjects: `Investigación`,
421
421
guildView_vaultDecoRecipes: `Planos de Decoración de Dojo`,
422
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422
424
guildView_alliance: `Alianza`,
423
425
guildView_members: `Miembros`,
424
426
guildView_pending: `Pendiente`,
@@ -441,6 +443,7 @@ dict = {
441
443
guildView_currency_owned: `|COUNT| en la Bóveda.`,
442
444
guildView_bulkAddTechProjects: `Añadir proyectos de Investigación Faltantes`,
443
445
guildView_bulkAddVaultDecoRecipes: `Añadir planos de Decoración de Dojo Faltantes`,
446
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444
447
guildView_bulkFundTechProjects: `Financiar toda la Investigación`,
445
448
guildView_bulkCompleteTechProjects: `Completar toda la Investigación`,
446
449
guildView_promote: `Promover`,
@@ -33,7 +33,7 @@ dict = {
33
33
code_remove: `Retirer`,
34
34
code_addItemsConfirm: `Ajouter |COUNT| items à l'inventaire ?`,
35
35
code_addTechProjectsConfirm: `Ajouter |COUNT| recherches au clan ?`,
36
code_addDecoRecipesConfirm: `Ajouter |COUNT| décorations au clan ?`,
36
code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37
37
code_succRankUp: `Montée de niveau effectuée.`,
38
38
code_noEquipmentToRankUp: `Aucun équipement à monter de niveau.`,
39
39
code_succAdded: `Ajouté.`,
@@ -419,6 +419,8 @@ dict = {
419
419
guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
420
420
guildView_techProjects: `Recherche`,
421
421
guildView_vaultDecoRecipes: `Schémas de décorations de dojo`,
422
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422
424
guildView_alliance: `Alliance`,
423
425
guildView_members: `Members`,
424
426
guildView_pending: `En Attente`,
@@ -441,6 +443,7 @@ dict = {
441
443
guildView_currency_owned: `|COUNT| dans le coffre.`,
442
444
guildView_bulkAddTechProjects: `Ajouter les recherches manquantes`,
443
445
guildView_bulkAddVaultDecoRecipes: `Ajouter les schémas de décorations de dojo manquantes`,
446
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444
447
guildView_bulkFundTechProjects: `Financer toutes les recherches`,
445
448
guildView_bulkCompleteTechProjects: `Compléter toutes les recherches`,
446
449
guildView_promote: `Promouvoir`,
@@ -33,7 +33,7 @@ dict = {
33
33
code_remove: `Удалить`,
34
34
code_addItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов на ваш аккаунт?`,
35
35
code_addTechProjectsConfirm: `Вы уверены, что хотите добавить |COUNT| исследований в свой клан?`,
36
code_addDecoRecipesConfirm: `Вы уверены, что хотите добавить |COUNT| рецептов декораций в свой клан?`,
36
code_addVaultItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов в хранилище своего клана?`,
37
37
code_succRankUp: `Ранг успешно повышен.`,
38
38
code_noEquipmentToRankUp: `Нет снаряжения для повышения ранга.`,
39
39
code_succAdded: `Успешно добавлено.`,
@@ -419,6 +419,8 @@ dict = {
419
419
guildView_cheats: `Читы Клана`,
420
420
guildView_techProjects: `Исследовения`,
421
421
guildView_vaultDecoRecipes: `Рецепты декораций Додзё`,
422
guildView_vaultMiscItems: `Ресурсы в Хранилище`,
423
guildView_vaultShipDecorations: `Укращения в Хранилище`,
422
424
guildView_alliance: `Альянс`,
423
425
guildView_members: `Товарищи`,
424
426
guildView_pending: `Ожидание`,
@@ -441,6 +443,7 @@ dict = {
441
443
guildView_currency_owned: `В хранилище |COUNT|.`,
442
444
guildView_bulkAddTechProjects: `Добавить отсутствующие исследования`,
443
445
guildView_bulkAddVaultDecoRecipes: `Добавить отсутствующие рецепты декораций Дoдзё`,
446
guildView_bulkAddVaultShipDecorations: `Добавить отсутствующие укращения в Хранилище`,
444
447
guildView_bulkFundTechProjects: `Профинансировать все исследования`,
445
448
guildView_bulkCompleteTechProjects: `Завершить все исследования`,
446
449
guildView_promote: `Повысить`,
@@ -33,7 +33,7 @@ dict = {
33
33
code_remove: `Видалити`,
34
34
code_addItemsConfirm: `Ви впевнені, що хочете додати |COUNT| предметів на ваш обліковий запис?`,
35
35
code_addTechProjectsConfirm: `Ви впевнені, що хочете додати |COUNT| досліджень до свого клану?`,
36
code_addDecoRecipesConfirm: `Ви впевнені, що хочете додати |COUNT| рецептів оздоблень до свого клану?`,
36
code_addVaultItemsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
37
37
code_succRankUp: `Рівень успішно підвищено`,
38
38
code_noEquipmentToRankUp: `Немає спорядження для підвищення рівня.`,
39
39
code_succAdded: `Успішно додано.`,
@@ -419,6 +419,8 @@ dict = {
419
419
guildView_cheats: `Кланові чити`,
420
420
guildView_techProjects: `Дослідження`,
421
421
guildView_vaultDecoRecipes: `Рецепти оздоблень Доджьо`,
422
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
423
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
422
424
guildView_alliance: `Альянс`,
423
425
guildView_members: `Учасники`,
424
426
guildView_pending: `Очікування`,
@@ -441,6 +443,7 @@ dict = {
441
443
guildView_currency_owned: `В сховищі |COUNT|.`,
442
444
guildView_bulkAddTechProjects: `Додати відсутні дослідження`,
443
445
guildView_bulkAddVaultDecoRecipes: `Додати відсутні рецепти оздоблень Доджьо`,
446
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
444
447
guildView_bulkFundTechProjects: `Фінансувати всі дослідження`,
445
448
guildView_bulkCompleteTechProjects: `Завершити всі дослідження`,
446
449
guildView_promote: `Підвищити звання`,