feat(webui): skins

Re #2361
This commit is contained in:
AMelonInsideLemon 2025-09-27 02:07:35 +02:00
parent f5c1b83598
commit 6fa80dab38
15 changed files with 208 additions and 45 deletions

View File

@ -11,7 +11,6 @@
"administratorNames": [],
"autoCreateAccount": true,
"skipTutorial": false,
"unlockAllSkins": false,
"fullyStockedVendors": false,
"skipClanKeyCrafting": false,
"spoofMasteryRank": -1,

View File

@ -334,16 +334,38 @@ export const getInventoryResponse = async (
});
}
if (config.unlockAllSkins) {
const ownedWeaponSkins = new Set<string>(inventoryResponse.WeaponSkins.map(x => x.ItemType));
for (const [uniqueName, meta] of Object.entries(ExportCustoms)) {
if (!meta.alwaysAvailable && !ownedWeaponSkins.has(uniqueName)) {
inventoryResponse.WeaponSkins.push({
ItemId: {
$oid: "ca70ca70ca70ca70" + catBreadHash(uniqueName).toString(16).padStart(8, "0")
},
ItemType: uniqueName
});
const skinLookupTable: Record<number, string> = {};
for (const key of Object.keys(ExportCustoms)) {
skinLookupTable[catBreadHash(key)] = key;
}
for (const key of equipmentKeys) {
if (key in inventoryResponse) {
for (const equipment of inventoryResponse[key]) {
for (const config of equipment.Configs) {
if (config.Skins) {
for (let i = 0; i < config.Skins.length; i++) {
const skinId: string = config.Skins[i];
if (skinId.substring(0, 16) === "ca70ca70ca70ca70") {
const skinItemType = skinLookupTable[parseInt(skinId.substring(16), 16)];
const inventoryItem = inventoryResponse.WeaponSkins.find(
x => x.ItemType == skinItemType
);
if (inventoryItem) {
config.Skins[i] = inventoryItem.ItemId.$oid;
} else {
config.Skins[i] = skinItemType;
if (!ExportCustoms[skinItemType].alwaysAvailable) {
logger.warn(
`Get ${skinItemType} or you may loose your appearance on ${equipment.ItemType}`
);
}
}
}
}
}
}
}
}
}

View File

@ -77,6 +77,9 @@ export const sellController: RequestHandler = async (req, res) => {
requiredFields.add("CrewShipSalvagedWeaponSkins");
}
}
if (payload.Items.WeaponSkins) {
requiredFields.add("WeaponSkins");
}
const inventory = await getInventory(accountId, Array.from(requiredFields).join(" "));
// Give currency
@ -302,6 +305,11 @@ export const sellController: RequestHandler = async (req, res) => {
addFusionTreasures(inventory, [parseFusionTreasure(sellItem.String, sellItem.Count * -1)]);
});
}
if (payload.Items.WeaponSkins) {
payload.Items.WeaponSkins.forEach(sellItem => {
inventory.WeaponSkins.pull({ _id: sellItem.String });
});
}
await inventory.save();
res.json({
@ -335,6 +343,7 @@ interface ISellRequest {
CrewShipWeapons?: ISellItem[];
CrewShipWeaponSkins?: ISellItem[];
FusionTreasures?: ISellItem[];
WeaponSkins?: ISellItem[];
};
SellPrice: number;
SellCurrency:

View File

@ -66,6 +66,7 @@ interface ItemLists {
VaultDecoRecipes: ListedItem[];
FlavourItems: ListedItem[];
ShipDecorations: ListedItem[];
WeaponSkins: ListedItem[];
//circuitGameModes: ListedItem[];
}
@ -107,7 +108,8 @@ const getItemListsController: RequestHandler = (req, response) => {
TechProjects: [],
VaultDecoRecipes: [],
FlavourItems: [],
ShipDecorations: []
ShipDecorations: [],
WeaponSkins: []
/*circuitGameModes: [
{
uniqueName: "Survival",
@ -298,10 +300,18 @@ const getItemListsController: RequestHandler = (req, response) => {
});
}
for (const [uniqueName, item] of Object.entries(ExportCustoms)) {
res.miscitems.push({
uniqueName: uniqueName,
name: getString(item.name, lang)
});
if (
item.productCategory == "WeaponSkins" &&
!uniqueName.startsWith("/Lotus/Types/Game/Lotus") && // Base Items
!uniqueName.endsWith("ProjectileSkin") && // UnrealTournament ProjectileSkins
!uniqueName.endsWith("Coat") // Frost Prime stuff
) {
res.WeaponSkins.push({
uniqueName: uniqueName,
name: getString(item.name, lang),
alwaysAvailable: item.alwaysAvailable
});
}
}
for (const [uniqueName, upgrade] of Object.entries(ExportUpgrades)) {

View File

@ -21,7 +21,6 @@ export interface IConfig {
administratorNames?: string[];
autoCreateAccount?: boolean;
skipTutorial?: boolean;
unlockAllSkins?: boolean;
fullyStockedVendors?: boolean;
skipClanKeyCrafting?: boolean;
spoofMasteryRank?: number;
@ -129,7 +128,8 @@ export const configRemovedOptionsKeys = [
"fastClanAscension",
"unlockAllFlavourItems",
"unlockAllShipDecorations",
"unlockAllDecoRecipes"
"unlockAllDecoRecipes",
"unlockAllSkins"
];
export const configPath = path.join(repoDir, args.configPath ?? "config.json");

View File

@ -139,22 +139,16 @@ export const handleInventoryItemConfigChange = async (
case "WeaponSkins": {
const itemEntries = equipment as IItemEntry;
for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) {
if (itemId.startsWith("ca70ca70ca70ca70")) {
logger.warn(
`unlockAllSkins does not work with favoriting items because you don't actually own it`
);
} else {
const inventoryItem = inventory.WeaponSkins.id(itemId);
if (!inventoryItem) {
logger.warn(`inventory item WeaponSkins not found with id ${itemId}`);
continue;
}
if ("Favorite" in itemConfigEntries) {
inventoryItem.Favorite = itemConfigEntries.Favorite;
}
if ("IsNew" in itemConfigEntries) {
inventoryItem.IsNew = itemConfigEntries.IsNew;
}
const inventoryItem = inventory.WeaponSkins.id(itemId);
if (!inventoryItem) {
logger.warn(`inventory item WeaponSkins not found with id ${itemId}`);
continue;
}
if ("Favorite" in itemConfigEntries) {
inventoryItem.Favorite = itemConfigEntries.Favorite;
}
if ("IsNew" in itemConfigEntries) {
inventoryItem.IsNew = itemConfigEntries.IsNew;
}
}
break;

View File

@ -526,6 +526,24 @@
</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="inventory_weaponSkins"></h5>
<div class="card-body d-flex flex-column">
<form class="input-group mb-3" onsubmit="doAcquireEquipment('WeaponSkins');return false;">
<input class="form-control" id="acquire-type-WeaponSkins" list="datalist-WeaponSkins" />
<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="WeaponSkins-list"></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<h5 class="card-header" data-loc="general_bulkActions"></h5>
<div class="card-body">
@ -538,6 +556,7 @@
<button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['SentinelWeapons']);" data-loc="inventory_bulkAddSentinelWeapons"></button>
<button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['FlavourItems']);" data-loc="inventory_bulkAddFlavourItems"></button>
<button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['ShipDecorations']);" data-loc="inventory_bulkAddShipDecorations"></button>
<button class="btn btn-primary" onclick="debounce(addMissingEquipment, ['WeaponSkins']);" data-loc="inventory_bulkAddWeaponSkins"></button>
<button class="btn btn-primary" onclick="debounce(addMissingEvolutionProgress);" data-loc="inventory_bulkAddEvolutionProgress"></button>
</div>
<div class="mb-2 d-flex flex-wrap gap-2">
@ -1093,10 +1112,6 @@
<input class="form-check-input" type="checkbox" id="skipTutorial" />
<label class="form-check-label" for="skipTutorial" data-loc="cheats_skipTutorial"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unlockAllSkins" />
<label class="form-check-label" for="unlockAllSkins" data-loc="cheats_unlockAllSkins"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="fullyStockedVendors" />
<label class="form-check-label" for="fullyStockedVendors" data-loc="cheats_fullyStockedVendors"></label>
@ -1503,6 +1518,7 @@
<datalist id="datalist-VaultDecoRecipes"></datalist>
<datalist id="datalist-FlavourItems"></datalist>
<datalist id="datalist-ShipDecorations"></datalist>
<datalist id="datalist-WeaponSkins"></datalist>
<datalist id="datalist-circuitGameModes">
<option>Survival</option>
<option>VoidFlood</option>

View File

@ -599,6 +599,46 @@ function fetchItemList() {
}
itemMap[item.uniqueName] = { ...item, type };
});
} else if (type == "WeaponSkins") {
let beardNumber = 1;
let cutNumber = 13;
let adultHeadNumber = 1;
let headNumber = 1;
items.forEach(item => {
if (item.name == "") {
if (item.uniqueName.includes("/Beards/")) {
item.name = loc("code_drifterBeardName")
.split("|INDEX|")
.join(beardNumber.toString().padStart(3, "0"));
beardNumber++;
} else if (item.uniqueName.includes("/Hair/")) {
item.name = loc("code_cutName")
.split("|INDEX|")
.join(cutNumber.toString().padStart(3, "0"));
cutNumber++;
if (cutNumber == 19) cutNumber = 21;
} else if (item.uniqueName.includes("/Heads/Adult")) {
item.name = loc("code_drifterFaceName")
.split("|INDEX|")
.join(adultHeadNumber.toString().padStart(3, "0"));
adultHeadNumber++;
} else if (item.uniqueName.includes("/Heads/")) {
item.name = loc("code_operatorFaceName")
.split("|INDEX|")
.join(headNumber.toString().padStart(3, "0"));
headNumber++;
} else {
item.name = item.uniqueName;
}
}
if (!item.alwaysAvailable) {
const option = document.createElement("option");
option.setAttribute("data-key", item.uniqueName);
option.value = item.name;
document.getElementById("datalist-" + type).appendChild(option);
}
itemMap[item.uniqueName] = { ...item, type };
});
} else {
const nameToItems = {};
items.forEach(item => {
@ -1103,6 +1143,44 @@ function updateInventory() {
document.getElementById("FlavourItems-list").appendChild(tr);
});
document.getElementById("WeaponSkins-list").innerHTML = "";
data.WeaponSkins.forEach(item => {
if (item.ItemId.$oid.startsWith("ca70ca70ca70ca70")) return;
const datalist = document.getElementById("datalist-WeaponSkins");
const optionToRemove = datalist.querySelector(`option[data-key="${item.ItemType}"]`);
if (optionToRemove) {
datalist.removeChild(optionToRemove);
}
const tr = document.createElement("tr");
{
const td = document.createElement("td");
const name = itemMap[item.ItemType]?.name?.trim();
td.textContent = name || item.ItemType;
tr.appendChild(td);
}
{
const td = document.createElement("td");
td.classList = "text-end text-nowrap";
{
const a = document.createElement("a");
a.href = "#";
a.onclick = function (event) {
event.preventDefault();
document.getElementById("WeaponSkins-list").removeChild(tr);
reAddToItemList(itemMap, "WeaponSkins", item.ItemType);
disposeOfGear("WeaponSkins", item.ItemId.$oid);
};
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);
}
tr.appendChild(td);
}
document.getElementById("WeaponSkins-list").appendChild(tr);
});
const datalistEvolutionProgress = document.querySelectorAll("#datalist-EvolutionProgress option");
const formEvolutionProgress = document.querySelector('form[onsubmit*="doAcquireEvolution()"]');

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `[UNTRANSLATED] Funded`,
code_replays: `[UNTRANSLATED] Replays`,
code_stalker: `Stalker`,
code_cutName: `Frisur: |INDEX|`,
code_drifterBeardName: `Drifter-Bart: |INDEX|`,
code_drifterFaceName: `Drifter-Gesicht: |INDEX|`,
code_operatorFaceName: `Operator-Gesicht: |INDEX|`,
code_succChange: `Erfolgreich geändert.`,
code_requiredInvigorationUpgrade: `[UNTRANSLATED] You must select both an offensive & utility upgrade.`,
login_description: `Melde dich mit deinem OpenWF-Account an (denselben Angaben wie im Spiel, wenn du dich mit diesem Server verbindest).`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `Booster`,
inventory_flavourItems: `<abbr title="Animationssets, Glyphen, Farbpaletten usw.">Sammlerstücke</abbr>`,
inventory_shipDecorations: `Schiffsdekorationen`,
inventory_weaponSkins: `Skins`,
inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`,
inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `[UNTRANSLATED] Add Missing Flavour Items`,
inventory_bulkAddShipDecorations: `[UNTRANSLATED] Add Missing Ship Decorations`,
inventory_bulkAddEvolutionProgress: `Fehlende Incarnon-Entwicklungsfortschritte hinzufügen`,
inventory_bulkAddWeaponSkins: `[UNTRANSLATED] Add Missing Skins`,
inventory_bulkRankUpSuits: `Alle Warframes auf Max. Rang`,
inventory_bulkRankUpWeapons: `Alle Waffen auf Max. Rang`,
inventory_bulkRankUpSpaceSuits: `Alle Archwings auf Max. Rang`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Void-Spuren nicht verbrauchen`,
cheats_dontSubtractConsumables: `Verbrauchsgegenstände (Ausrüstung) nicht verbrauchen`,
cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`,
cheats_unlockAllSkins: `Alle Skins freischalten`,
cheats_unlockAllCapturaScenes: `Alle Photora-Szenen freischalten`,
cheats_universalPolarityEverywhere: `Universelle Polarität überall`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Orokin Reaktor & Beschleuniger überall`,

View File

@ -74,6 +74,10 @@ dict = {
code_funded: `Funded`,
code_replays: `Replays`,
code_stalker: `Stalker`,
code_cutName: `Cut |INDEX|`,
code_drifterBeardName: `Drifter Beard |INDEX|`,
code_drifterFaceName: `Drifter Visage |INDEX|`,
code_operatorFaceName: `Operator Visage |INDEX|`,
code_succChange: `Successfully changed.`,
code_requiredInvigorationUpgrade: `You must select both an offensive & utility upgrade.`,
login_description: `Login using your OpenWF account credentials (same as in-game when connecting to this server).`,
@ -111,6 +115,7 @@ dict = {
inventory_boosters: `Boosters`,
inventory_flavourItems: `<abbr title="Animation Sets, Glyphs, Palettes, etc.">Flavour Items</abbr>`,
inventory_shipDecorations: `Ship Decorations`,
inventory_weaponSkins: `Skins`,
inventory_bulkAddSuits: `Add Missing Warframes`,
inventory_bulkAddWeapons: `Add Missing Weapons`,
inventory_bulkAddSpaceSuits: `Add Missing Archwings`,
@ -120,6 +125,7 @@ dict = {
inventory_bulkAddFlavourItems: `Add Missing Flavour Items`,
inventory_bulkAddShipDecorations: `Add Missing Ship Decorations`,
inventory_bulkAddEvolutionProgress: `Add Missing Incarnon Evolution Progress`,
inventory_bulkAddWeaponSkins: `Add Missing Skins`,
inventory_bulkRankUpSuits: `Max Rank All Warframes`,
inventory_bulkRankUpWeapons: `Max Rank All Weapons`,
inventory_bulkRankUpSpaceSuits: `Max Rank All Archwings`,
@ -208,7 +214,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Don't Subtract Void Traces`,
cheats_dontSubtractConsumables: `Don't Subtract Consumables`,
cheats_unlockAllShipFeatures: `Unlock All Ship Features`,
cheats_unlockAllSkins: `Unlock All Skins`,
cheats_unlockAllCapturaScenes: `Unlock All Captura Scenes`,
cheats_universalPolarityEverywhere: `Universal Polarity Everywhere`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Potatoes Everywhere`,

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `Financiado`,
code_replays: `Repeticiones`,
code_stalker: `Stalker`,
code_cutName: `[UNTRANSLATED] Cut |INDEX|`,
code_drifterBeardName: `Barba del Viajero: |INDEX|`,
code_drifterFaceName: `Rostro del Viajero |INDEX|`,
code_operatorFaceName: `Rostro del operador |INDEX|`,
code_succChange: `Cambiado correctamente`,
code_requiredInvigorationUpgrade: `Debes seleccionar una mejora ofensiva y una mejora de utilidad.`,
login_description: `Inicia sesión con las credenciales de tu cuenta OpenWF (las mismas que usas en el juego al conectarte a este servidor).`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `Potenciadores`,
inventory_flavourItems: `<abbr title="Conjuntos de animaciones, glifos, paletas, etc.">Ítems estéticos</abbr>`,
inventory_shipDecorations: `Decoraciones de nave`,
inventory_weaponSkins: `Diseños`,
inventory_bulkAddSuits: `Agregar Warframes faltantes`,
inventory_bulkAddWeapons: `Agregar armas faltantes`,
inventory_bulkAddSpaceSuits: `Agregar Archwings faltantes`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `Añadir items estéticos faltantes`,
inventory_bulkAddShipDecorations: `Añadir decoraciones de Nave Faltantes`,
inventory_bulkAddEvolutionProgress: `Completar el progreso de evolución Incarnon faltante`,
inventory_bulkAddWeaponSkins: `[UNTRANSLATED] Add Missing Skins`,
inventory_bulkRankUpSuits: `Maximizar rango de todos los Warframes`,
inventory_bulkRankUpWeapons: `Maximizar rango de todas las armas`,
inventory_bulkRankUpSpaceSuits: `Maximizar rango de todos los Archwings`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `No descontar vestigios del Vacío`,
cheats_dontSubtractConsumables: `No restar consumibles`,
cheats_unlockAllShipFeatures: `Desbloquear todas las funciones de nave`,
cheats_unlockAllSkins: `Desbloquear todas las skins`,
cheats_unlockAllCapturaScenes: `Desbloquear todas las escenas de Captura`,
cheats_universalPolarityEverywhere: `Polaridad universal en todas partes`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Patatas en todas partes`,

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `Complété`,
code_replays: `[UNTRANSLATED] Replays`,
code_stalker: `Stalker`,
code_cutName: `[UNTRANSLATED] Cut |INDEX|`,
code_drifterBeardName: `Barbe du Voyageur |INDEX|`,
code_drifterFaceName: `Visage du Voyageur |INDEX|`,
code_operatorFaceName: `Visage de l'Opérateur |INDEX|`,
code_succChange: `Changement effectué.`,
code_requiredInvigorationUpgrade: `[UNTRANSLATED] You must select both an offensive & utility upgrade.`,
login_description: `Connexion avec les informations de connexion OpenWF.`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `Boosters`,
inventory_flavourItems: `[UNTRANSLATED] <abbr title="Animation Sets, Glyphs, Palettes, etc.">Flavour Items</abbr>`,
inventory_shipDecorations: `Décorations du vaisseau`,
inventory_weaponSkins: `Aspects`,
inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
inventory_bulkAddWeapons: `Ajouter les armes manquantes`,
inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `[UNTRANSLATED] Add Missing Flavour Items`,
inventory_bulkAddShipDecorations: `[UNTRANSLATED] Add Missing Ship Decorations`,
inventory_bulkAddEvolutionProgress: `Ajouter les évolutions Incarnon manquantes`,
inventory_bulkAddWeaponSkins: `[UNTRANSLATED] Add Missing Skins`,
inventory_bulkRankUpSuits: `Toutes les Warframes au rang max`,
inventory_bulkRankUpWeapons: `Toutes les armes au rang max`,
inventory_bulkRankUpSpaceSuits: `Tous les Archwings au rang max`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Ne pas consommer de Void Traces`,
cheats_dontSubtractConsumables: `Ne pas retirer de consommables`,
cheats_unlockAllShipFeatures: `Débloquer tous les segments du vaisseau`,
cheats_unlockAllSkins: `Débloquer tous les skins`,
cheats_unlockAllCapturaScenes: `Débloquer toutes les scènes captura`,
cheats_universalPolarityEverywhere: `Polarités universelles partout`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Réacteurs et Catalyseurs partout`,

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `Профинансировано`,
code_replays: `Повторов`,
code_stalker: `Сталкер`,
code_cutName: `Причёска: |INDEX|`,
code_drifterBeardName: `Борода скитальца: |INDEX|`,
code_drifterFaceName: `Внешность скитальца: |INDEX|`,
code_operatorFaceName: `Внешность оператора: |INDEX|`,
code_succChange: `Успешно изменено.`,
code_requiredInvigorationUpgrade: `Вы должны выбрать как атакующее, так и вспомогательное улучшение.`,
login_description: `Войдите, используя учетные данные OpenWF (те же, что и в игре при подключении к этому серверу).`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `Бустеры`,
inventory_flavourItems: `<abbr title="Наборы анимаций, глифы, палитры и т. д.">Уникальные предметы</abbr>`,
inventory_shipDecorations: `Украшения корабля`,
inventory_weaponSkins: `Скины`,
inventory_bulkAddSuits: `Добавить отсутствующие Варфреймы`,
inventory_bulkAddWeapons: `Добавить отсутствующее оружие`,
inventory_bulkAddSpaceSuits: `Добавить отсутствующие Арчвинги`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `Добавить отсутствующие уникальные предметы`,
inventory_bulkAddShipDecorations: `Добавить отсутствующие украшения корабля`,
inventory_bulkAddEvolutionProgress: `Добавить отсутствующий прогресс эволюции Инкарнонов`,
inventory_bulkAddWeaponSkins: `Добавить отсутствующие скины`,
inventory_bulkRankUpSuits: `Макс. ранг всех Варфреймов`,
inventory_bulkRankUpWeapons: `Макс. ранг всего оружия`,
inventory_bulkRankUpSpaceSuits: `Макс. ранг всех Арчвингов`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Не вычитать количество Отголосков Бездны`,
cheats_dontSubtractConsumables: `Не вычитать количество расходников`,
cheats_unlockAllShipFeatures: `Разблокировать все функции корабля`,
cheats_unlockAllSkins: `Разблокировать все скины`,
cheats_unlockAllCapturaScenes: `Разблокировать все сцены Каптуры`,
cheats_universalPolarityEverywhere: `Универсальная полярность везде`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Реакторы/Катализаторы орокин везде`,

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `Профінансовано`,
code_replays: `Повтори`,
code_stalker: `Сталкер`,
code_cutName: `Зачіска: |INDEX|`,
code_drifterBeardName: `Борода мандрівника: |INDEX|`,
code_drifterFaceName: `Зовнішність мандрівника: |INDEX|`,
code_operatorFaceName: `Зовнішність оператора: |INDEX|`,
code_succChange: `Успішно змінено.`,
code_requiredInvigorationUpgrade: `Ви повинні вибрати як атакуюче, так і допоміжне вдосконалення.`,
login_description: `Увійдіть, використовуючи облікові дані OpenWF (ті ж, що й у грі при підключенні до цього серверу).`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `Посилення`,
inventory_flavourItems: `<abbr title="Набори анімацій, гліфи, палітри і т. д.">Унікальні предмети</abbr>`,
inventory_shipDecorations: `Прикраси судна`,
inventory_weaponSkins: `Вигляди`,
inventory_bulkAddSuits: `Додати відсутні Ворфрейми`,
inventory_bulkAddWeapons: `Додати відсутню зброю`,
inventory_bulkAddSpaceSuits: `Додати відсутні Арквінґи`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `Додати відсутні унікальні предмети`,
inventory_bulkAddShipDecorations: `Додати відсутні оздоби корабля`,
inventory_bulkAddEvolutionProgress: `Додати відсутній прогрес еволюції Інкарнонів`,
inventory_bulkAddWeaponSkins: `[UNTRANSLATED] Add Missing Skins`,
inventory_bulkRankUpSuits: `Макс. рівень всіх Ворфреймів`,
inventory_bulkRankUpWeapons: `Макс. рівень всієї зброї`,
inventory_bulkRankUpSpaceSuits: `Макс. рівень всіх Арквінґів`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `Не вираховувати кількість Відлуння`,
cheats_dontSubtractConsumables: `Не вираховувати кількість витратних матеріалів`,
cheats_unlockAllShipFeatures: `Розблокувати всі функції судна`,
cheats_unlockAllSkins: `Розблокувати всі скіни`,
cheats_unlockAllCapturaScenes: `Розблокувати всі сцени Світлописця`,
cheats_universalPolarityEverywhere: `Будь-яка полярність скрізь`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Орокінські Реактори/Каталізатори скрізь`,

View File

@ -75,6 +75,10 @@ dict = {
code_funded: `[UNTRANSLATED] Funded`,
code_replays: `[UNTRANSLATED] Replays`,
code_stalker: `追猎者`,
code_cutName: `[UNTRANSLATED] Cut |INDEX|`,
code_drifterBeardName: `漂泊者胡须 |INDEX|`,
code_drifterFaceName: `漂泊者面部 |INDEX|`,
code_operatorFaceName: `指挥官面部 |INDEX|`,
code_succChange: `更改成功`,
code_requiredInvigorationUpgrade: `[UNTRANSLATED] You must select both an offensive & utility upgrade.`,
login_description: `使用您的 OpenWF 账户凭证登录(与游戏内连接本服务器时使用的昵称相同)`,
@ -112,6 +116,7 @@ dict = {
inventory_boosters: `加成器`,
inventory_flavourItems: `<abbr title="动作表情、浮印、调色板等">装饰物品</abbr>`,
inventory_shipDecorations: `飞船装饰`,
inventory_weaponSkins: `外观`,
inventory_bulkAddSuits: `添加缺失战甲`,
inventory_bulkAddWeapons: `添加缺失武器`,
inventory_bulkAddSpaceSuits: `添加缺失载具`,
@ -121,6 +126,7 @@ dict = {
inventory_bulkAddFlavourItems: `[UNTRANSLATED] Add Missing Flavour Items`,
inventory_bulkAddShipDecorations: `[UNTRANSLATED] Add Missing Ship Decorations`,
inventory_bulkAddEvolutionProgress: `添加缺失的灵化之源进度`,
inventory_bulkAddWeaponSkins: `[UNTRANSLATED] Add Missing Skins`,
inventory_bulkRankUpSuits: `所有战甲升满级`,
inventory_bulkRankUpWeapons: `所有武器升满级`,
inventory_bulkRankUpSpaceSuits: `所有载具升满级`,
@ -209,7 +215,6 @@ dict = {
cheats_dontSubtractVoidTraces: `虚空光体无消耗`,
cheats_dontSubtractConsumables: `消耗物品使用时无损耗`,
cheats_unlockAllShipFeatures: `解锁所有飞船功能`,
cheats_unlockAllSkins: `解锁所有外观`,
cheats_unlockAllCapturaScenes: `解锁所有Captura场景`,
cheats_universalPolarityEverywhere: `全局万用极性`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `全物品自带Orokin反应堆`,