feat(webui): Vault MiscItems and ShipDecorations

Closes #2874 #2875
This commit is contained in:
AMelonInsideLemon 2025-10-11 14:13:12 +02:00
parent 02f0935710
commit 1252f41264
13 changed files with 233 additions and 117 deletions

View File

@ -1,36 +0,0 @@
import { getAccountIdForRequest } from "../../services/loginService.ts";
import { getInventory } from "../../services/inventoryService.ts";
import type { RequestHandler } from "express";
import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
import { GuildPermission } from "../../types/guildTypes.ts";
import type { ITypeCount } from "../../types/commonTypes.ts";
export const addVaultDecoRecipeController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const requests = req.body as ITypeCount[];
const inventory = await getInventory(accountId, "GuildId");
const guild = await getGuildForRequestEx(req, inventory);
if (!(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) {
res.status(400).send("-1").end();
return;
}
guild.VaultDecoRecipes ??= [];
for (const request of requests) {
const index = guild.VaultDecoRecipes.findIndex(x => x.ItemType === request.ItemType);
if (index == -1) {
guild.VaultDecoRecipes.push({
ItemType: request.ItemType,
ItemCount: request.ItemCount
});
} else {
guild.VaultDecoRecipes[index].ItemCount += request.ItemCount;
if (guild.VaultDecoRecipes[index].ItemCount < 1) {
guild.VaultDecoRecipes.splice(index, 1);
}
}
}
await guild.save();
res.end();
};

View File

@ -0,0 +1,43 @@
import { getAccountIdForRequest } from "../../services/loginService.ts";
import { getInventory } from "../../services/inventoryService.ts";
import type { RequestHandler } from "express";
import { getGuildForRequestEx, hasGuildPermission } from "../../services/guildService.ts";
import { GuildPermission } from "../../types/guildTypes.ts";
import type { ITypeCount } from "../../types/commonTypes.ts";
export const addVaultTypeCountController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req);
const { vaultType, items } = req.body as {
vaultType: keyof typeof vaultConfig;
items: ITypeCount[];
};
const inventory = await getInventory(accountId, "GuildId");
const guild = await getGuildForRequestEx(req, inventory);
if (!(await hasGuildPermission(guild, accountId, vaultConfig[vaultType]))) {
res.status(400).send("-1").end();
return;
}
guild[vaultType] ??= [];
for (const item of items) {
const index = guild[vaultType].findIndex(x => x.ItemType === item.ItemType);
if (index === -1) {
guild[vaultType].push({
ItemType: item.ItemType,
ItemCount: item.ItemCount
});
} else {
guild[vaultType][index].ItemCount += item.ItemCount;
if (guild[vaultType][index].ItemCount < 1) {
guild[vaultType].splice(index, 1);
}
}
}
await guild.save();
res.end();
};
const vaultConfig = {
VaultShipDecorations: GuildPermission.Treasurer,
VaultMiscItems: GuildPermission.Treasurer,
VaultDecoRecipes: GuildPermission.Architect
} as const;

View File

@ -38,6 +38,7 @@ interface ListedItem {
parazon?: boolean;
alwaysAvailable?: boolean;
maxLevelCap?: number;
eligibleForVault?: boolean;
}
interface ItemLists {
@ -141,6 +142,12 @@ const getItemListsController: RequestHandler = (req, response) => {
}
]*/
};
const eligibleForVault = new Set<string>([
...Object.values(ExportDojoRecipes.research).flatMap(r => r.ingredients.map(i => i.ItemType)),
...Object.values(ExportDojoRecipes.fabrications).flatMap(f => f.ingredients.map(i => i.ItemType)),
...Object.values(ExportDojoRecipes.rooms).flatMap(r => r.ingredients.map(i => i.ItemType)),
...Object.values(ExportDojoRecipes.decos).flatMap(d => d.ingredients.map(i => i.ItemType))
]);
for (const [uniqueName, item] of Object.entries(ExportWarframes)) {
res[item.productCategory].push({
uniqueName,
@ -246,7 +253,8 @@ const getItemListsController: RequestHandler = (req, response) => {
res.miscitems.push({
uniqueName: uniqueName,
name: name,
subtype: "Resource"
subtype: "Resource",
...(eligibleForVault.has(uniqueName) && { eligibleForVault: true })
});
}
}

View File

@ -34,7 +34,7 @@ import {
fundTechProjectController,
removeTechProjectController
} from "../controllers/custom/techProjectController.ts";
import { addVaultDecoRecipeController } from "../controllers/custom/addVaultDecoRecipeController.ts";
import { addVaultTypeCountController } from "../controllers/custom/addVaultTypeCountController.ts";
import { addXpController } from "../controllers/custom/addXpController.ts";
import { importController } from "../controllers/custom/importController.ts";
import { manageQuestsController } from "../controllers/custom/manageQuestsController.ts";
@ -81,7 +81,7 @@ customRouter.post("/addCurrency", addCurrencyController);
customRouter.post("/addItems", addItemsController);
customRouter.post("/addTechProject", addTechProjectController);
customRouter.post("/removeTechProject", removeTechProjectController);
customRouter.post("/addVaultDecoRecipe", addVaultDecoRecipeController);
customRouter.post("/addVaultTypeCount", addVaultTypeCountController);
customRouter.post("/fundTechProject", fundTechProjectController);
customRouter.post("/completeTechProject", completeTechProjectsController);
customRouter.post("/addXp", addXpController);

View File

@ -624,7 +624,7 @@
<div class="card" style="height: 400px;">
<h5 class="card-header" data-loc="guildView_vaultDecoRecipes"></h5>
<div class="card-body d-flex flex-column">
<form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultDecoRecipe();return false;">
<form id="vaultDecoRecipes-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultDecoRecipes');return false;">
<input class="form-control" id="acquire-type-VaultDecoRecipes" list="datalist-VaultDecoRecipes" />
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
</form>
@ -637,6 +637,42 @@
</div>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-lg-6">
<div class="card" style="height: 400px;">
<h5 class="card-header" data-loc="guildView_vaultMiscItems"></h5>
<div class="card-body d-flex flex-column">
<form id="vaultMiscItems-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultMiscItems');return false;">
<input class="form-control" id="VaultMiscItems-count" type="number" value="1" />
<input class="form-control w-50" id="acquire-type-VaultMiscItems" list="datalist-VaultMiscItems" />
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
</form>
<div class="overflow-auto">
<table class="table table-hover w-100">
<tbody id="VaultMiscItems-list"></tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card" style="height: 400px;">
<h5 class="card-header" data-loc="guildView_vaultShipDecorations"></h5>
<div class="card-body d-flex flex-column">
<form id="vaultShipDecorations-form" class="input-group mb-3 d-none" onsubmit="addVaultItem('VaultShipDecorations');return false;">
<input class="form-control" id="VaultShipDecorations-count" type="number" value="1" />
<input class="form-control w-50" id="acquire-type-VaultShipDecorations" list="datalist-ShipDecorations" />
<button class="btn btn-primary" type="submit" data-loc="general_addButton"></button>
</form>
<div class="overflow-auto">
<table class="table table-hover w-100">
<tbody id="VaultShipDecorations-list"></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-lg-6">
<div class="card" style="height: 400px;">
@ -666,7 +702,8 @@
<div class="card-body" id="guild-actions">
<div class="mb-2 d-flex flex-wrap gap-2">
<button class="btn btn-primary" onclick="debounce(addMissingTechProjects);" data-loc="guildView_bulkAddTechProjects"></button>
<button class="btn btn-primary" onclick="debounce(addMissingVaultDecoRecipes);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
<button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultDecoRecipes']);" data-loc="guildView_bulkAddVaultDecoRecipes"></button>
<button class="btn btn-primary" onclick="debounce(addMissingVaultItems, ['VaultShipDecorations']);" data-loc="guildView_bulkAddVaultShipDecorations"></button>
</div>
<div class="mb-2 d-flex flex-wrap gap-2">
<button class="btn btn-success" onclick="debounce(fundAllTechProjects);" data-loc="guildView_bulkFundTechProjects"></button>
@ -1548,6 +1585,7 @@
<datalist id="datalist-FlavourItems"></datalist>
<datalist id="datalist-ShipDecorations"></datalist>
<datalist id="datalist-WeaponSkins"></datalist>
<datalist id="datalist-VaultMiscItems"></datalist>
<datalist id="datalist-circuitGameModes">
<option>Survival</option>
<option>VoidFlood</option>

View File

@ -711,6 +711,10 @@ function fetchItemList() {
option.value += " (" + item.subtype + ")";
}
document.getElementById("datalist-" + type).appendChild(option);
if (item.eligibleForVault) {
const vaultOption = option.cloneNode(true);
document.getElementById("datalist-VaultMiscItems").appendChild(vaultOption);
}
} else {
//console.log(`Not adding ${item.uniqueName} to datalist for ${type} due to duplicate display name: ${item.name}`);
}
@ -1802,6 +1806,8 @@ function updateInventory() {
document.getElementById("VaultRegularCredits-owned").classList.remove("mb-0");
document.getElementById("vaultPremiumCredits-form").classList.remove("d-none");
document.getElementById("VaultPremiumCredits-owned").classList.remove("mb-0");
document.getElementById("vaultMiscItems-form").classList.remove("d-none");
document.getElementById("vaultShipDecorations-form").classList.remove("d-none");
}
if (userGuildMember.Rank <= 1) {
document.querySelectorAll("#guild-actions button").forEach(btn => {
@ -1892,42 +1898,55 @@ function updateInventory() {
document.getElementById("TechProjects-list").appendChild(tr);
});
document.getElementById("VaultDecoRecipes-list").innerHTML = "";
guildData.VaultDecoRecipes ??= [];
guildData.VaultDecoRecipes.forEach(item => {
const datalist = document.getElementById("datalist-VaultDecoRecipes");
const optionToRemove = datalist.querySelector(`option[data-key="${item.ItemType}"]`);
if (optionToRemove) {
datalist.removeChild(optionToRemove);
}
const tr = document.createElement("tr");
tr.setAttribute("data-item-type", item.ItemType);
{
const td = document.createElement("td");
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
tr.appendChild(td);
}
{
const td = document.createElement("td");
td.classList = "text-end text-nowrap";
if (userGuildMember && userGuildMember.Rank <= 1) {
const a = document.createElement("a");
a.href = "#";
a.onclick = function (event) {
event.preventDefault();
reAddToItemList(itemMap, "VaultDecoRecipes", item.ItemType);
removeVaultDecoRecipe(item.ItemType);
};
a.title = loc("code_remove");
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>`;
td.appendChild(a);
["VaultDecoRecipes", "VaultMiscItems", "VaultShipDecorations"].forEach(vaultKey => {
document.getElementById(vaultKey + "-list").innerHTML = "";
(guildData[vaultKey] ??= []).forEach(item => {
if (vaultKey == "VaultDecoRecipes") {
const datalist = document.getElementById("datalist-VaultDecoRecipes");
const optionToRemove = datalist.querySelector(
`option[data-key="${item.ItemType}"]`
);
if (optionToRemove) {
datalist.removeChild(optionToRemove);
}
}
tr.appendChild(td);
}
const tr = document.createElement("tr");
tr.setAttribute("data-item-type", item.ItemType);
{
const td = document.createElement("td");
td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
if (item.ItemCount > 1) {
td.innerHTML += ` <span title='${loc("code_count")}'>🗍 ${parseInt(item.ItemCount)}</span>`;
}
tr.appendChild(td);
}
{
const td = document.createElement("td");
td.classList = "text-end text-nowrap";
const canRemove =
vaultKey === "VaultDecoRecipes"
? userGuildMember && userGuildMember.Rank <= 1
: userGuildPermissions && userGuildPermissions & 64;
if (canRemove) {
const a = document.createElement("a");
a.href = "#";
a.title = loc("code_remove");
a.onclick = e => {
e.preventDefault();
if (vaultKey == "VaultDecoRecipes") {
reAddToItemList(itemMap, vaultKey, item.ItemType);
}
removeVaultItem(vaultKey, item.ItemType, item.ItemCount * -1);
};
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>`;
td.appendChild(a);
}
tr.appendChild(td);
}
document.getElementById("VaultDecoRecipes-list").appendChild(tr);
document.getElementById(vaultKey + "-list").appendChild(tr);
});
});
document.getElementById("Members-list").innerHTML = "";
@ -2346,41 +2365,52 @@ function addMissingEquipment(categories) {
}
}
function addVaultDecoRecipe() {
const uniqueName = getKey(document.getElementById("acquire-type-VaultDecoRecipes"));
if (!uniqueName) {
$("#acquire-type-VaultDecoRecipes").addClass("is-invalid").focus();
function addVaultItem(vaultType) {
const ItemType = getKey(document.getElementById(`acquire-type-${vaultType}`));
if (!ItemType) {
$(`#acquire-type-${vaultType}`).addClass("is-invalid").focus();
return;
}
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
contentType: "application/json",
data: JSON.stringify([
{
ItemType: uniqueName,
ItemCount: 1
}
])
const ItemCount = ["VaultMiscItems", "VaultShipDecorations"].includes(vaultType)
? parseInt($(`#${vaultType}-count`).val())
: 1;
if (ItemCount != 0) {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
contentType: "application/json",
data: JSON.stringify({
vaultType,
items: [
{
ItemType,
ItemCount
}
]
})
});
req.done(() => {
document.getElementById(`acquire-type-${vaultType}`).value = "";
updateInventory();
});
});
req.done(() => {
document.getElementById("acquire-type-VaultDecoRecipes").value = "";
updateInventory();
});
});
}
}
function removeVaultDecoRecipe(uniqueName) {
function removeVaultItem(vaultType, ItemType, ItemCount) {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
url: "/custom/addVaultTypeCount?" + window.authz + "&guildId=" + window.guildId,
contentType: "application/json",
data: JSON.stringify([
{
ItemType: uniqueName,
ItemCount: -1
}
])
data: JSON.stringify({
vaultType,
items: [
{
ItemType,
ItemCount
}
]
})
});
req.done(() => {
updateInventory();
@ -2462,13 +2492,16 @@ function fundGuildTechProject(uniqueName) {
});
}
function dispatchAddVaultDecoRecipesBatch(requests) {
function dispatchAddVaultItemsBatch(requests, vaultType) {
return new Promise(resolve => {
revalidateAuthz().then(() => {
const req = $.post({
url: "/custom/addVaultDecoRecipe?" + window.authz + "&guildId=" + window.guildId,
url: "/custom/addVaultItems?" + window.authz + "&guildId=" + window.guildId,
contentType: "application/json",
data: JSON.stringify(requests)
data: JSON.stringify({
vaultType,
items: requests
})
});
req.done(() => {
updateInventory();
@ -2478,20 +2511,23 @@ function dispatchAddVaultDecoRecipesBatch(requests) {
});
}
function addMissingVaultDecoRecipes() {
function addMissingVaultItems(vaultType) {
const requests = [];
document.querySelectorAll("#datalist-VaultDecoRecipes" + " option").forEach(elm => {
if (!document.querySelector("#VaultDecoRecipes-list [data-item-type='" + elm.getAttribute("data-key") + "']")) {
requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount: 1 });
document.querySelectorAll(`#datalist-${vaultType} option`).forEach(elm => {
const datalist = vaultType === "VaultShipDecorations" ? "ShipDecorations" : vaultType;
if (!document.querySelector(`#${datalist}-list [data-item-type='${elm.getAttribute("data-key")}']`)) {
let ItemCount = 1;
if (category == "VaultShipDecorations") ItemCount = 999999;
requests.push({ ItemType: elm.getAttribute("data-key"), ItemCount });
}
});
if (
requests.length != 0 &&
window.confirm(loc("code_addDecoRecipesConfirm").split("|COUNT|").join(requests.length))
window.confirm(loc("code_addVaultItemsRecipesConfirm").split("|COUNT|").join(requests.length))
) {
return dispatchAddVaultDecoRecipesBatch(requests);
return dispatchAddVaultItemsBatch(requests, vaultType);
}
}
@ -3445,6 +3481,12 @@ single.getRoute("#guild-route").on("beforeload", function () {
document.getElementById("VaultDecoRecipes-list").innerHTML = "";
document.getElementById("vaultDecoRecipes-form").classList.add("d-none");
document.getElementById("acquire-type-VaultDecoRecipes").value = "";
document.getElementById("VaultMiscItems-list").innerHTML = "";
document.getElementById("vaultMiscItems-form").classList.add("d-none");
document.getElementById("acquire-type-VaultMiscItems").value = "";
document.getElementById("VaultShipDecorations-list").innerHTML = "";
document.getElementById("vaultShipDecorations-form").classList.add("d-none");
document.getElementById("acquire-type-VaultShipDecorations").value = "";
document.getElementById("Alliance-list").innerHTML = "";
document.getElementById("guildView-alliance").textContent = "";
document.getElementById("Members-list").innerHTML = "";

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `Entfernen`,
code_addItemsConfirm: `Bist du sicher, dass du |COUNT| Gegenstände zu deinem Account hinzufügen möchtest?`,
code_addTechProjectsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| research to your clan?`,
code_addDecoRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| deco recipes to your clan?`,
code_addVaultItemsRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `Erfolgreich aufgestiegen.`,
code_noEquipmentToRankUp: `Keine Ausstattung zum Rangaufstieg verfügbar.`,
code_succAdded: `Erfolgreich hinzugefügt.`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
guildView_techProjects: `Forschung`,
guildView_vaultDecoRecipes: `[UNTRANSLATED] Dojo Deco Recipes`,
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
guildView_alliance: `Allianz`,
guildView_members: `Mitglieder`,
guildView_pending: `Ausstehend`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `[UNTRANSLATED] |COUNT| in Vault.`,
guildView_bulkAddTechProjects: `[UNTRANSLATED] Add Missing Research`,
guildView_bulkAddVaultDecoRecipes: `[UNTRANSLATED] Add Missing Dojo Deco Recipes`,
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `[UNTRANSLATED] Fund All Research`,
guildView_bulkCompleteTechProjects: `[UNTRANSLATED] Complete All Research`,
guildView_promote: `Befördern`,

View File

@ -32,7 +32,7 @@ dict = {
code_remove: `Remove`,
code_addItemsConfirm: `Are you sure you want to add |COUNT| items to your account?`,
code_addTechProjectsConfirm: `Are you sure you want to add |COUNT| research to your clan?`,
code_addDecoRecipesConfirm: `Are you sure you want to add |COUNT| deco recipes to your clan?`,
code_addVaultItemsRecipesConfirm: `Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `Successfully ranked up.`,
code_noEquipmentToRankUp: `No equipment to rank up.`,
code_succAdded: `Successfully added.`,
@ -418,6 +418,8 @@ dict = {
guildView_cheats: `Clan Cheats`,
guildView_techProjects: `Research`,
guildView_vaultDecoRecipes: `Dojo Deco Recipes`,
guildView_vaultMiscItems: `Resources in Vault`,
guildView_vaultShipDecorations: `Decorations in Vault`,
guildView_alliance: `Alliance`,
guildView_members: `Members`,
guildView_pending: `Pending`,
@ -440,6 +442,7 @@ dict = {
guildView_currency_owned: `|COUNT| in Vault.`,
guildView_bulkAddTechProjects: `Add Missing Research`,
guildView_bulkAddVaultDecoRecipes: `Add Missing Dojo Deco Recipes`,
guildView_bulkAddVaultShipDecorations: `Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `Fund All Research`,
guildView_bulkCompleteTechProjects: `Complete All Research`,
guildView_promote: `Promote`,

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `Quitar`,
code_addItemsConfirm: `¿Estás seguro de que deseas agregar |COUNT| objetos a tu cuenta?`,
code_addTechProjectsConfirm: `¿Estás seguro de que quieres añadir |COUNT| proyectos de investigación a tu clan?`,
code_addDecoRecipesConfirm: `¿Estás seguro de que quieres añadir |COUNT| planos de decoración a tu clan?`,
code_addVaultItemsRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `Ascenso exitoso.`,
code_noEquipmentToRankUp: `No hay equipo para ascender.`,
code_succAdded: `Agregado exitosamente.`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `Trucos de Clan`,
guildView_techProjects: `Investigación`,
guildView_vaultDecoRecipes: `Planos de Decoración de Dojo`,
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
guildView_alliance: `Alianza`,
guildView_members: `Miembros`,
guildView_pending: `Pendiente`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `|COUNT| en la Bóveda.`,
guildView_bulkAddTechProjects: `Añadir proyectos de Investigación Faltantes`,
guildView_bulkAddVaultDecoRecipes: `Añadir planos de Decoración de Dojo Faltantes`,
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `Financiar toda la Investigación`,
guildView_bulkCompleteTechProjects: `Completar toda la Investigación`,
guildView_promote: `Promover`,

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `Retirer`,
code_addItemsConfirm: `Ajouter |COUNT| items à l'inventaire ?`,
code_addTechProjectsConfirm: `Ajouter |COUNT| recherches au clan ?`,
code_addDecoRecipesConfirm: `Ajouter |COUNT| décorations au clan ?`,
code_addVaultItemsRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `Montée de niveau effectuée.`,
code_noEquipmentToRankUp: `Aucun équipement à monter de niveau.`,
code_succAdded: `Ajouté.`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
guildView_techProjects: `Recherche`,
guildView_vaultDecoRecipes: `Schémas de décorations de dojo`,
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
guildView_alliance: `Alliance`,
guildView_members: `Members`,
guildView_pending: `En Attente`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `|COUNT| dans le coffre.`,
guildView_bulkAddTechProjects: `Ajouter les recherches manquantes`,
guildView_bulkAddVaultDecoRecipes: `Ajouter les schémas de décorations de dojo manquantes`,
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `Financer toutes les recherches`,
guildView_bulkCompleteTechProjects: `Compléter toutes les recherches`,
guildView_promote: `Promouvoir`,

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `Удалить`,
code_addItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов на ваш аккаунт?`,
code_addTechProjectsConfirm: `Вы уверены, что хотите добавить |COUNT| исследований в свой клан?`,
code_addDecoRecipesConfirm: `Вы уверены, что хотите добавить |COUNT| рецептов декораций в свой клан?`,
code_addVaultItemsRecipesConfirm: `Вы уверены, что хотите добавить |COUNT| предметов в хранилище своего клана?`,
code_succRankUp: `Ранг успешно повышен.`,
code_noEquipmentToRankUp: `Нет снаряжения для повышения ранга.`,
code_succAdded: `Успешно добавлено.`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `Читы Клана`,
guildView_techProjects: `Исследовения`,
guildView_vaultDecoRecipes: `Рецепты декораций Додзё`,
guildView_vaultMiscItems: `Ресурсы в Хранилище`,
guildView_vaultShipDecorations: `Укращения в Хранилище`,
guildView_alliance: `Альянс`,
guildView_members: `Товарищи`,
guildView_pending: `Ожидание`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `В хранилище |COUNT|.`,
guildView_bulkAddTechProjects: `Добавить отсутствующие исследования`,
guildView_bulkAddVaultDecoRecipes: `Добавить отсутствующие рецепты декораций Дoдзё`,
guildView_bulkAddVaultShipDecorations: `Добавить отсутствующие укращения в Хранилище`,
guildView_bulkFundTechProjects: `Профинансировать все исследования`,
guildView_bulkCompleteTechProjects: `Завершить все исследования`,
guildView_promote: `Повысить`,

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `Видалити`,
code_addItemsConfirm: `Ви впевнені, що хочете додати |COUNT| предметів на ваш обліковий запис?`,
code_addTechProjectsConfirm: `Ви впевнені, що хочете додати |COUNT| досліджень до свого клану?`,
code_addDecoRecipesConfirm: `Ви впевнені, що хочете додати |COUNT| рецептів оздоблень до свого клану?`,
code_addVaultItemsRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `Рівень успішно підвищено`,
code_noEquipmentToRankUp: `Немає спорядження для підвищення рівня.`,
code_succAdded: `Успішно додано.`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `Кланові чити`,
guildView_techProjects: `Дослідження`,
guildView_vaultDecoRecipes: `Рецепти оздоблень Доджьо`,
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
guildView_alliance: `Альянс`,
guildView_members: `Учасники`,
guildView_pending: `Очікування`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `В сховищі |COUNT|.`,
guildView_bulkAddTechProjects: `Додати відсутні дослідження`,
guildView_bulkAddVaultDecoRecipes: `Додати відсутні рецепти оздоблень Доджьо`,
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `Фінансувати всі дослідження`,
guildView_bulkCompleteTechProjects: `Завершити всі дослідження`,
guildView_promote: `Підвищити звання`,

View File

@ -33,7 +33,7 @@ dict = {
code_remove: `移除`,
code_addItemsConfirm: `确定要向您的账户添加 |COUNT| 件物品吗?`,
code_addTechProjectsConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| research to your clan?`,
code_addDecoRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| deco recipes to your clan?`,
code_addVaultItemsRecipesConfirm: `[UNTRANSLATED] Are you sure you want to add |COUNT| items to your clan vault?`,
code_succRankUp: `等级已提升`,
code_noEquipmentToRankUp: `没有可升级的装备`,
code_succAdded: `添加成功`,
@ -419,6 +419,8 @@ dict = {
guildView_cheats: `[UNTRANSLATED] Clan Cheats`,
guildView_techProjects: `研究`,
guildView_vaultDecoRecipes: `[UNTRANSLATED] Dojo Deco Recipes`,
guildView_vaultMiscItems: `[UNTRANSLATED] Resources in Vault`,
guildView_vaultShipDecorations: `[UNTRANSLATED] Decorations in Vault`,
guildView_alliance: `联盟`,
guildView_members: `成员`,
guildView_pending: `待处理`,
@ -441,6 +443,7 @@ dict = {
guildView_currency_owned: `[UNTRANSLATED] |COUNT| in Vault.`,
guildView_bulkAddTechProjects: `[UNTRANSLATED] Add Missing Research`,
guildView_bulkAddVaultDecoRecipes: `[UNTRANSLATED] Add Missing Dojo Deco Recipes`,
guildView_bulkAddVaultShipDecorations: `[UNTRANSLATED] Add Missing Decorations in Vault`,
guildView_bulkFundTechProjects: `[UNTRANSLATED] Fund All Research`,
guildView_bulkCompleteTechProjects: `[UNTRANSLATED] Complete All Research`,
guildView_promote: `升级`,