diff --git a/Dockerfile b/Dockerfile index f265957f..8913def2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,8 +10,6 @@ ENV APP_SKIP_TUTORIAL=true ENV APP_SKIP_ALL_DIALOGUE=true ENV APP_UNLOCK_ALL_SCANS=true ENV APP_UNLOCK_ALL_MISSIONS=true -ENV APP_UNLOCK_ALL_QUESTS=true -ENV APP_COMPLETE_ALL_QUESTS=true ENV APP_INFINITE_RESOURCES=true ENV APP_UNLOCK_ALL_SHIP_FEATURES=true ENV APP_UNLOCK_ALL_SHIP_DECORATIONS=true diff --git a/src/controllers/custom/getItemListsController.ts b/src/controllers/custom/getItemListsController.ts index d84d4aea..7d60f896 100644 --- a/src/controllers/custom/getItemListsController.ts +++ b/src/controllers/custom/getItemListsController.ts @@ -5,6 +5,7 @@ import { ExportAvionics, ExportDrones, ExportGear, + ExportKeys, ExportMisc, ExportRailjackWeapons, ExportRecipes, @@ -26,6 +27,7 @@ interface ListedItem { exalted?: string[]; badReason?: "starter" | "frivolous" | "notraw"; partType?: string; + chainLength?: number; } const relicQualitySuffixes: Record = { @@ -52,6 +54,7 @@ const getItemListsController: RequestHandler = (req, response) => { res.miscitems = []; res.Syndicates = []; res.OperatorAmps = []; + res.QuestKeys = []; for (const [uniqueName, item] of Object.entries(ExportWarframes)) { res[item.productCategory].push({ uniqueName, @@ -208,6 +211,15 @@ const getItemListsController: RequestHandler = (req, response) => { name: getString(syndicate.name, lang) }); } + for (const [uniqueName, key] of Object.entries(ExportKeys)) { + if (key.chainStages) { + res.QuestKeys.push({ + uniqueName, + name: getString(key.name || "", lang), + chainLength: key.chainStages.length + }); + } + } response.json({ archonCrystalUpgrades, diff --git a/src/controllers/custom/manageQuestsController.ts b/src/controllers/custom/manageQuestsController.ts index 2234ec00..49ae004c 100644 --- a/src/controllers/custom/manageQuestsController.ts +++ b/src/controllers/custom/manageQuestsController.ts @@ -1,7 +1,11 @@ -import { addString } from "@/src/controllers/api/inventoryController"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { addQuestKey, completeQuest, IUpdateQuestRequest, updateQuestKey } from "@/src/services/questService"; +import { + addQuestKey, + completeQuest, + giveKeyChainMissionReward, + giveKeyChainStageTriggered +} from "@/src/services/questService"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; import { ExportKeys } from "warframe-public-export-plus"; @@ -9,13 +13,17 @@ import { ExportKeys } from "warframe-public-export-plus"; export const manageQuestsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const operation = req.query.operation as - | "unlockAll" | "completeAll" - | "ResetAll" - | "completeAllUnlocked" - | "updateKey" - | "giveAll"; - const questKeyUpdate = req.body as IUpdateQuestRequest["QuestKeys"]; + | "resetAll" + | "giveAll" + | "completeKey" + | "deleteKey" + | "resetKey" + | "prevStage" + | "nextStage" + | "setInactive"; + + const questItemType = req.query.itemType as string; const allQuestKeys: string[] = []; for (const [k, v] of Object.entries(ExportKeys)) { @@ -26,47 +34,15 @@ export const manageQuestsController: RequestHandler = async (req, res) => { const inventory = await getInventory(accountId); switch (operation) { - case "updateKey": { - //TODO: if this is intended to be used, one needs to add a updateQuestKeyMultiple, the game does never intend to do it, so it errors for multiple keys. - await updateQuestKey(inventory, questKeyUpdate); - break; - } - case "unlockAll": { - for (const questKey of allQuestKeys) { - addQuestKey(inventory, { ItemType: questKey, Completed: false, unlock: true, Progress: [] }); - } - break; - } case "completeAll": { - logger.info("completing all quests.."); - for (const questKey of allQuestKeys) { - try { - await completeQuest(inventory, questKey); - } catch (error) { - if (error instanceof Error) { - logger.error( - `Something went wrong completing quest ${questKey}, probably could not add some item` - ); - logger.error(error.message); - } - } - - //Skip "Watch The Maker" - if (questKey === "/Lotus/Types/Keys/NewWarIntroQuest/NewWarIntroKeyChain") { - addString( - inventory.NodeIntrosCompleted, - "/Lotus/Levels/Cinematics/NewWarIntro/NewWarStageTwo.level" - ); - } - - if (questKey === "/Lotus/Types/Keys/ArchwingQuest/ArchwingQuestKeyChain") { - inventory.ArchwingEnabled = true; + if (allQuestKeys.includes(questItemType)) { + for (const questKey of inventory.QuestKeys) { + await completeQuest(inventory, questKey.ItemType); } } break; } - case "ResetAll": { - logger.info("resetting all quests.."); + case "resetAll": { for (const questKey of inventory.QuestKeys) { questKey.Completed = false; questKey.Progress = []; @@ -75,40 +51,113 @@ export const manageQuestsController: RequestHandler = async (req, res) => { inventory.ActiveQuest = ""; break; } - case "completeAllUnlocked": { - logger.info("completing all unlocked quests.."); - for (const questKey of inventory.QuestKeys) { - try { + case "giveAll": { + allQuestKeys.forEach(questKey => addQuestKey(inventory, { ItemType: questKey })); + break; + } + case "deleteKey": { + if (allQuestKeys.includes(questItemType)) { + const questKey = inventory.QuestKeys.find(key => key.ItemType === questItemType); + if (!questKey) { + logger.error(`Quest key not found in inventory: ${questItemType}`); + break; + } + + inventory.QuestKeys.pull({ ItemType: questItemType }); + } + break; + } + case "completeKey": { + if (allQuestKeys.includes(questItemType)) { + const questKey = inventory.QuestKeys.find(key => key.ItemType === questItemType); + if (!questKey) { + logger.error(`Quest key not found in inventory: ${questItemType}`); + break; + } + + await completeQuest(inventory, questItemType); + } + break; + } + case "resetKey": { + if (allQuestKeys.includes(questItemType)) { + const questKey = inventory.QuestKeys.find(key => key.ItemType === questItemType); + if (!questKey) { + logger.error(`Quest key not found in inventory: ${questItemType}`); + break; + } + + questKey.Completed = false; + questKey.Progress = []; + questKey.CompletionDate = undefined; + } + break; + } + case "prevStage": { + if (allQuestKeys.includes(questItemType)) { + const questKey = inventory.QuestKeys.find(key => key.ItemType === questItemType); + if (!questKey) { + logger.error(`Quest key not found in inventory: ${questItemType}`); + break; + } + if (!questKey.Progress) break; + + if (questKey.Completed) { + questKey.Completed = false; + questKey.CompletionDate = undefined; + } + questKey.Progress.pop(); + const stage = questKey.Progress.length - 1; + if (stage > 0) { + await giveKeyChainStageTriggered(inventory, { + KeyChain: questKey.ItemType, + ChainStage: stage + }); + } + } + break; + } + case "nextStage": { + if (allQuestKeys.includes(questItemType)) { + const questKey = inventory.QuestKeys.find(key => key.ItemType === questItemType); + const questManifest = ExportKeys[questItemType]; + if (!questKey) { + logger.error(`Quest key not found in inventory: ${questItemType}`); + break; + } + if (!questKey.Progress) break; + + const currentStage = questKey.Progress.length; + if (currentStage + 1 == questManifest.chainStages?.length) { + logger.debug(`Trying to complete last stage with nextStage, calling completeQuest instead`); await completeQuest(inventory, questKey.ItemType); - } catch (error) { - if (error instanceof Error) { - logger.error( - `Something went wrong completing quest ${questKey.ItemType}, probably could not add some item` - ); - logger.error(error.message); + } else { + const progress = { + c: questManifest.chainStages![currentStage].key ? -1 : 0, + i: false, + m: false, + b: [] + }; + questKey.Progress.push(progress); + + await giveKeyChainStageTriggered(inventory, { + KeyChain: questKey.ItemType, + ChainStage: currentStage + }); + + if (currentStage > 0) { + await giveKeyChainMissionReward(inventory, { + KeyChain: questKey.ItemType, + ChainStage: currentStage - 1 + }); } } - - //Skip "Watch The Maker" - if (questKey.ItemType === "/Lotus/Types/Keys/NewWarIntroQuest/NewWarIntroKeyChain") { - addString( - inventory.NodeIntrosCompleted, - "/Lotus/Levels/Cinematics/NewWarIntro/NewWarStageTwo.level" - ); - } - - if (questKey.ItemType === "/Lotus/Types/Keys/ArchwingQuest/ArchwingQuestKeyChain") { - inventory.ArchwingEnabled = true; - } } break; } - case "giveAll": { - for (const questKey of allQuestKeys) { - addQuestKey(inventory, { ItemType: questKey }); - } + case "setInactive": + inventory.ActiveQuest = ""; break; - } } await inventory.save(); diff --git a/src/routes/webui.ts b/src/routes/webui.ts index 2cfa14da..02224903 100644 --- a/src/routes/webui.ts +++ b/src/routes/webui.ts @@ -30,6 +30,9 @@ webuiRouter.get("/webui/mods", (_req, res) => { webuiRouter.get("/webui/settings", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); +webuiRouter.get("/webui/quests", (_req, res) => { + res.sendFile(path.join(rootDir, "static/webui/index.html")); +}); webuiRouter.get("/webui/cheats", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); diff --git a/src/services/questService.ts b/src/services/questService.ts index a8a20629..7b82b304 100644 --- a/src/services/questService.ts +++ b/src/services/questService.ts @@ -130,73 +130,56 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest throw new Error(`Quest ${questKey} does not contain chain stages`); } - const chainStageTotal = ExportKeys[questKey].chainStages?.length ?? 0; + const chainStageTotal = chainStages.length; const existingQuestKey = inventory.QuestKeys.find(qk => qk.ItemType === questKey); + const startingStage = Math.max((existingQuestKey?.Progress?.length ?? 0) - 1, 0); + if (existingQuestKey?.Completed) { return; } - const Progress = Array(chainStageTotal).fill({ - c: 0, - i: false, - m: false, - b: [] - } satisfies IQuestStage); - - const completedQuestKey: IQuestKeyDatabase = { - ItemType: questKey, - Completed: true, - unlock: true, - Progress: Progress, - CompletionDate: new Date() - }; - - //overwrite current quest progress, might lead to multiple quest item rewards if (existingQuestKey) { - existingQuestKey.overwrite(completedQuestKey); - //Object.assign(existingQuestKey, completedQuestKey); + existingQuestKey.Progress = existingQuestKey.Progress ?? []; + + const existingProgressLength = existingQuestKey.Progress.length; + + if (existingProgressLength < chainStageTotal) { + const missingProgress: IQuestStage[] = Array.from( + { length: chainStageTotal - existingProgressLength }, + () => + ({ + c: 0, + i: false, + m: false, + b: [] + }) as IQuestStage + ); + + existingQuestKey.Progress.push(...missingProgress); + existingQuestKey.CompletionDate = new Date(); + existingQuestKey.Completed = true; + } } else { + const completedQuestKey: IQuestKeyDatabase = { + ItemType: questKey, + Completed: true, + unlock: true, + Progress: Array(chainStageTotal).fill({ + c: 0, + i: false, + m: false, + b: [] + } satisfies IQuestStage), + CompletionDate: new Date() + }; addQuestKey(inventory, completedQuestKey); } - for (let i = 0; i < chainStageTotal; i++) { - if (chainStages[i].itemsToGiveWhenTriggered.length > 0) { - await giveKeyChainItem(inventory, { KeyChain: questKey, ChainStage: i }); - } + for (let i = startingStage; i < chainStageTotal; i++) { + await giveKeyChainStageTriggered(inventory, { KeyChain: questKey, ChainStage: i }); - if (chainStages[i].messageToSendWhenTriggered) { - await giveKeyChainMessage(inventory, inventory.accountOwnerId, { - KeyChain: questKey, - ChainStage: i - }); - } - - const missionName = chainStages[i].key; - if (missionName) { - const fixedLevelRewards = getLevelKeyRewards(missionName); - //logger.debug(`fixedLevelRewards`, fixedLevelRewards); - if (fixedLevelRewards.levelKeyRewards) { - const missionRewards: { StoreItem: string; ItemCount: number }[] = []; - addFixedLevelRewards(fixedLevelRewards.levelKeyRewards, inventory, missionRewards); - - for (const reward of missionRewards) { - await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount); - } - } else if (fixedLevelRewards.levelKeyRewards2) { - for (const reward of fixedLevelRewards.levelKeyRewards2) { - if (reward.rewardType == "RT_CREDITS") { - inventory.RegularCredits += reward.amount; - continue; - } - if (reward.rewardType == "RT_RESOURCE") { - await addItem(inventory, fromStoreItem(reward.itemType), reward.amount); - } else { - await addItem(inventory, fromStoreItem(reward.itemType)); - } - } - } - } + await giveKeyChainMissionReward(inventory, { KeyChain: questKey, ChainStage: i }); } const questCompletionItems = getQuestCompletionItems(questKey); @@ -205,7 +188,7 @@ export const completeQuest = async (inventory: TInventoryDatabaseDocument, quest await addItems(inventory, questCompletionItems); } - inventory.ActiveQuest = ""; + if (inventory.ActiveQuest == questKey) inventory.ActiveQuest = ""; if (questKey == "/Lotus/Types/Keys/NewWarQuest/NewWarQuestKeyChain") { setupKahlSyndicate(inventory); @@ -247,3 +230,60 @@ export const giveKeyChainMessage = async ( updateQuestStage(inventory, keyChainInfo, { m: true }); }; + +export const giveKeyChainMissionReward = async ( + inventory: TInventoryDatabaseDocument, + keyChainInfo: IKeyChainRequest +): Promise => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages; + + if (chainStages) { + const missionName = chainStages[keyChainInfo.ChainStage].key; + if (missionName) { + const fixedLevelRewards = getLevelKeyRewards(missionName); + if (fixedLevelRewards.levelKeyRewards) { + const missionRewards: { StoreItem: string; ItemCount: number }[] = []; + addFixedLevelRewards(fixedLevelRewards.levelKeyRewards, inventory, missionRewards); + + for (const reward of missionRewards) { + await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount); + } + + updateQuestStage(inventory, keyChainInfo, { c: 0 }); + } else if (fixedLevelRewards.levelKeyRewards2) { + for (const reward of fixedLevelRewards.levelKeyRewards2) { + if (reward.rewardType == "RT_CREDITS") { + inventory.RegularCredits += reward.amount; + continue; + } + if (reward.rewardType == "RT_RESOURCE") { + await addItem(inventory, fromStoreItem(reward.itemType), reward.amount); + } else { + await addItem(inventory, fromStoreItem(reward.itemType)); + } + } + + updateQuestStage(inventory, keyChainInfo, { c: 0 }); + } + } + } +}; + +export const giveKeyChainStageTriggered = async ( + inventory: TInventoryDatabaseDocument, + keyChainInfo: IKeyChainRequest +): Promise => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages; + + if (chainStages) { + if (chainStages[keyChainInfo.ChainStage].itemsToGiveWhenTriggered.length > 0) { + await giveKeyChainItem(inventory, keyChainInfo); + } + + if (chainStages[keyChainInfo.ChainStage].messageToSendWhenTriggered) { + await giveKeyChainMessage(inventory, inventory.accountOwnerId, keyChainInfo); + } + } +}; diff --git a/static/webui/index.html b/static/webui/index.html index aefb1f11..74ea23d6 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -61,6 +61,9 @@ + @@ -470,22 +473,31 @@
-
-
-
- - -
+
+
+
+
+
+
+ + +
+ + +
+
+
-
-
-
-
-
- - - - +
+
+
+
+
+ + + +
+
@@ -633,14 +645,6 @@
-
-
- - - - - -
@@ -666,6 +670,7 @@ + diff --git a/static/webui/script.js b/static/webui/script.js index c5239833..849062b2 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -489,6 +489,132 @@ function updateInventory() { }); }); + // Populate quests route + document.getElementById("QuestKeys-list").innerHTML = ""; + data.QuestKeys.forEach(item => { + const tr = document.createElement("tr"); + tr.setAttribute("data-item-type", item.ItemType); + const stage = item.Progress?.length ?? 0; + + const datalist = document.getElementById("datalist-QuestKeys"); + const optionToRemove = datalist.querySelector(`option[data-key="${item.ItemType}"]`); + if (optionToRemove) { + datalist.removeChild(optionToRemove); + } + + { + const td = document.createElement("td"); + td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; + if (!item.Completed) { + td.textContent += + " | " + loc("code_stage") + ": [" + stage + "/" + itemMap[item.ItemType].chainLength + "]"; + } else { + td.textContent += " | " + loc("code_completed"); + } + + if (data.ActiveQuest == item.ItemType) td.textContent += " | " + loc("code_active"); + tr.appendChild(td); + } + { + const td = document.createElement("td"); + td.classList = "text-end text-nowrap"; + if (data.ActiveQuest == item.ItemType && !item.Completed) { + console.log(data.ActiveQuest); + + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + doQuestUpdate("setInactive", item.ItemType); + }; + a.title = loc("code_setInactive"); + a.innerHTML = ``; + td.appendChild(a); + } + if (stage > 0) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + doQuestUpdate("resetKey", item.ItemType); + }; + a.title = loc("code_reset"); + a.innerHTML = ``; + td.appendChild(a); + } + if (itemMap[item.ItemType].chainLength > stage && !item.Completed) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + doQuestUpdate("completeKey", item.ItemType); + }; + a.title = loc("code_complete"); + a.innerHTML = ``; + td.appendChild(a); + } + if (stage > 0 && itemMap[item.ItemType].chainLength > 1) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + doQuestUpdate("prevStage", item.ItemType); + }; + a.title = loc("code_prevStage"); + a.innerHTML = ``; + td.appendChild(a); + } + if ( + itemMap[item.ItemType].chainLength > stage && + !item.Completed && + itemMap[item.ItemType].chainLength > 1 + ) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + doQuestUpdate("nextStage", item.ItemType); + }; + a.title = loc("code_nextStage"); + a.innerHTML = ``; + td.appendChild(a); + } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + const option = document.createElement("option"); + option.setAttribute("data-key", item.ItemType); + option.value = itemMap[item.ItemType]?.name ?? item.ItemType; + document.getElementById("datalist-QuestKeys").appendChild(option); + doQuestUpdate("deleteKey", item.ItemType); + }; + a.title = loc("code_remove"); + a.innerHTML = ``; + td.appendChild(a); + } + tr.appendChild(td); + } + document.getElementById("QuestKeys-list").appendChild(tr); + }); + + const datalistQuestKeys = document.querySelectorAll("#datalist-QuestKeys option"); + const form = document.querySelector("form[onsubmit*=\"doAcquireEquipment('QuestKeys')\"]"); + const giveAllQuestButton = document.querySelector("button[onclick*=\"doBulkQuestUpdate('giveAll')\"]"); + + if (datalistQuestKeys.length === 0) { + form.classList.add("disabled"); + form.querySelector("input").disabled = true; + form.querySelector("button").disabled = true; + giveAllQuestButton.disabled = true; + } else { + form.classList.remove("disabled"); + form.querySelector("input").disabled = false; + form.querySelector("button").disabled = false; + giveAllQuestButton.disabled = false; + } + // Populate mods route document.getElementById("riven-list").innerHTML = ""; document.getElementById("mods-list").innerHTML = ""; @@ -1397,7 +1523,16 @@ function doAddCurrency(currency) { }); } -function doQuestUpdate(operation) { +function doQuestUpdate(operation, itemType) { + $.post({ + url: "/custom/manageQuests?" + window.authz + "&operation=" + operation + "&itemType=" + itemType, + contentType: "application/json" + }).then(function () { + updateInventory(); + }); +} + +function doBulkQuestUpdate(operation) { $.post({ url: "/custom/manageQuests?" + window.authz + "&operation=" + operation, contentType: "application/json" diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 87d56833..f04d2780 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -45,6 +45,14 @@ dict = { code_zanukaA: `Jagdhund: Dorma`, code_zanukaB: `Jagdhund: Bhaira`, code_zanukaC: `Jagdhund: Hec`, + code_stage: `[UNTRANSLATED] Stage`, + code_complete: `[UNTRANSLATED] Complete`, + code_nextStage: `[UNTRANSLATED] Next stage`, + code_prevStage: `[UNTRANSLATED] Previous stage`, + code_reset: `[UNTRANSLATED] Reset`, + code_setInactive: `[UNTRANSLATED] Make the quest inactive`, + code_completed: `[UNTRANSLATED] Completed`, + code_active: `[UNTRANSLATED] Active`, login_description: `Melde dich mit deinem OpenWF-Account an (denselben Angaben wie im Spiel, wenn du dich mit diesem Server verbindest).`, login_emailLabel: `E-Mail-Adresse`, login_passwordLabel: `Passwort`, @@ -84,6 +92,11 @@ dict = { inventory_bulkRankUpSentinels: `Alle Wächter auf Max. Rang`, inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`, + quests_list: `Quests`, + quests_completeAll: `Alle Quests abschließen`, + quests_resetAll: `Alle Quests zurücksetzen`, + quests_giveAll: `Alle Quests erhalten`, + currency_RegularCredits: `Credits`, currency_PremiumCredits: `Platinum`, currency_FusionPoints: `Endo`, @@ -135,12 +148,6 @@ dict = { cheats_changeSupportedSyndicate: `Unterstütztes Syndikat`, cheats_changeButton: `Ändern`, cheats_none: `Keines`, - cheats_quests: `Quests`, - cheats_quests_unlockAll: `Alle Quests freischalten`, - cheats_quests_completeAll: `Alle Quests abschließen`, - cheats_quests_completeAllUnlocked: `Alle freigeschalteten Quests abschließen`, - cheats_quests_resetAll: `Alle Quests zurücksetzen`, - cheats_quests_giveAll: `Alle Quests erhalten`, import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, werden in deinem Account überschrieben.`, import_submit: `Absenden`, prettier_sucks_ass: `` diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index 6a465fc2..ba1e406c 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -44,6 +44,14 @@ dict = { code_zanukaA: `Dorma Hound`, code_zanukaB: `Bhaira Hound`, code_zanukaC: `Hec Hound`, + code_stage: `Stage`, + code_complete: `Complete`, + code_nextStage: `Next stage`, + code_prevStage: `Previous stage`, + code_reset: `Reset`, + code_setInactive: `Make the quest inactive`, + code_completed: `Completed`, + code_active: `Active`, login_description: `Login using your OpenWF account credentials (same as in-game when connecting to this server).`, login_emailLabel: `Email address`, login_passwordLabel: `Password`, @@ -83,6 +91,11 @@ dict = { inventory_bulkRankUpSentinels: `Max Rank All Sentinels`, inventory_bulkRankUpSentinelWeapons: `Max Rank All Sentinel Weapons`, + quests_list: `Quests`, + quests_completeAll: `Complete All Quests`, + quests_resetAll: `Reset All Quests`, + quests_giveAll: `Give All Quests`, + currency_RegularCredits: `Credits`, currency_PremiumCredits: `Platinum`, currency_FusionPoints: `Endo`, @@ -134,12 +147,6 @@ dict = { cheats_changeSupportedSyndicate: `Supported syndicate`, cheats_changeButton: `Change`, cheats_none: `None`, - cheats_quests: `Quests`, - cheats_quests_unlockAll: `Unlock All Quests`, - cheats_quests_completeAll: `Complete All Quests`, - cheats_quests_completeAllUnlocked: `Complete All Unlocked Quests`, - cheats_quests_resetAll: `Reset All Quests`, - cheats_quests_giveAll: `Give All Quests`, import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer will be overwritten in your account.`, import_submit: `Submit`, prettier_sucks_ass: `` diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 09cf069c..9e307117 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -45,6 +45,14 @@ dict = { code_zanukaA: `Molosse Dorma`, code_zanukaB: `Molosse Bhaira`, code_zanukaC: `Molosse Hec`, + code_stage: `[UNTRANSLATED] Stage`, + code_complete: `[UNTRANSLATED] Complete`, + code_nextStage: `[UNTRANSLATED] Next stage`, + code_prevStage: `[UNTRANSLATED] Previous stage`, + code_reset: `[UNTRANSLATED] Reset`, + code_setInactive: `[UNTRANSLATED] Make the quest inactive`, + code_completed: `[UNTRANSLATED] Completed`, + code_active: `[UNTRANSLATED] Active`, login_description: `Connexion avec les informations de connexion OpenWF.`, login_emailLabel: `Email`, login_passwordLabel: `Mot de passe`, @@ -84,6 +92,11 @@ dict = { inventory_bulkRankUpSentinels: `Toutes les Sentinelles rang max`, inventory_bulkRankUpSentinelWeapons: `Toutes les armes de Sentinelles rang max`, + quests_list: `Quêtes`, + quests_completeAll: `Compléter toutes les quêtes`, + quests_resetAll: `Réinitialiser toutes les quêtes`, + quests_giveAll: `Obtenir toutes les quêtes`, + currency_RegularCredits: `Crédits`, currency_PremiumCredits: `Platinum`, currency_FusionPoints: `Endo`, @@ -135,12 +148,6 @@ dict = { cheats_changeSupportedSyndicate: `Allégeance`, cheats_changeButton: `Changer`, cheats_none: `Aucun`, - cheats_quests: `Quêtes`, - cheats_quests_unlockAll: `Débloquer toutes les quêtes`, - cheats_quests_completeAll: `Compléter toutes les quêtes`, - cheats_quests_completeAllUnlocked: `Compléter toutes les quêtes déverrouillées`, - cheats_quests_resetAll: `Réinitialiser toutes les quêtes`, - cheats_quests_giveAll: `Obtenir toutes les quêtes`, import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire écraseront celles présentes dans la base de données.`, import_submit: `Soumettre`, prettier_sucks_ass: `` diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index a10f72e4..294b526e 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -45,6 +45,14 @@ dict = { code_zanukaA: `Гончая: Дорма`, code_zanukaB: `Гончая: Бхайра`, code_zanukaC: `Гончая: Хек`, + code_stage: `Этап`, + code_complete: `Завершить`, + code_nextStage: `Cледующий этап`, + code_prevStage: `Предыдущий этап`, + code_reset: `Сбросить`, + code_setInactive: `Сделать квест неактивным`, + code_completed: `Завершено`, + code_active: `Активный`, login_description: `Войдите, используя учетные данные OpenWF (те же, что и в игре при подключении к этому серверу).`, login_emailLabel: `Адрес электронной почты`, login_passwordLabel: `Пароль`, @@ -84,6 +92,11 @@ dict = { inventory_bulkRankUpSentinels: `Максимальный ранг всех стражей`, inventory_bulkRankUpSentinelWeapons: `Максимальный ранг всего оружия стражей`, + quests_list: `Квесты`, + quests_completeAll: `Завершить все квесты`, + quests_resetAll: `Сбросить прогресс всех квестов`, + quests_giveAll: `Выдать все квесты`, + currency_RegularCredits: `Кредиты`, currency_PremiumCredits: `Платина`, currency_FusionPoints: `Эндо`, @@ -135,12 +148,6 @@ dict = { cheats_changeSupportedSyndicate: `Поддерживаемый синдикат`, cheats_changeButton: `Изменить`, cheats_none: `Отсутствует`, - cheats_quests: `Квесты`, - cheats_quests_unlockAll: `Разблокировать все квесты`, - cheats_quests_completeAll: `Завершить все квесты`, - cheats_quests_completeAllUnlocked: `Завершить все разблокированые квесты`, - cheats_quests_resetAll: `Сбросить прогресс всех квестов`, - cheats_quests_giveAll: `Выдать все квесты`, import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля будут перезаписаны в вашем аккаунте.`, import_submit: `Отправить`, prettier_sucks_ass: `` diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index a99c30d1..5ec64622 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -45,6 +45,14 @@ dict = { code_zanukaA: `铎玛猎犬`, code_zanukaB: `拜拉猎犬`, code_zanukaC: `骸克猎犬`, + code_stage: `[UNTRANSLATED] Stage`, + code_complete: `[UNTRANSLATED] Complete`, + code_nextStage: `[UNTRANSLATED] Next stage`, + code_prevStage: `[UNTRANSLATED] Previous stage`, + code_reset: `[UNTRANSLATED] Reset`, + code_setInactive: `[UNTRANSLATED] Make the quest inactive`, + code_completed: `[UNTRANSLATED] Completed`, + code_active: `[UNTRANSLATED] Active`, login_description: `使用您的 OpenWF 账户凭证登录(与游戏内连接本服务器时使用的昵称相同)。`, login_emailLabel: `电子邮箱`, login_passwordLabel: `密码`, @@ -84,6 +92,11 @@ dict = { inventory_bulkRankUpSentinels: `所有守护升满级`, inventory_bulkRankUpSentinelWeapons: `所有守护武器升满级`, + quests_list: `任务`, + quests_completeAll: `完成所有任务`, + quests_resetAll: `重置所有任务`, + quests_giveAll: `授予所有任务`, + currency_RegularCredits: `现金`, currency_PremiumCredits: `白金`, currency_FusionPoints: `内融核心`, @@ -135,12 +148,6 @@ dict = { cheats_changeSupportedSyndicate: `支持的集团`, cheats_changeButton: `更改`, cheats_none: `无`, - cheats_quests: `任务`, - cheats_quests_unlockAll: `解锁所有任务`, - cheats_quests_completeAll: `完成所有任务`, - cheats_quests_completeAllUnlocked: `完成所有已解锁任务`, - cheats_quests_resetAll: `重置所有任务`, - cheats_quests_giveAll: `授予所有任务`, import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段将被覆盖到您的账户中。`, import_submit: `提交`, prettier_sucks_ass: ``