forked from OpenWF/SpaceNinjaServer
Compare commits
8 Commits
654652b889
...
d0127f609c
| Author | SHA1 | Date | |
|---|---|---|---|
| d0127f609c | |||
| 2b054d1728 | |||
| 5ac73528a0 | |||
| 678ad0c4a1 | |||
| 4bdb759463 | |||
| 71be8a2868 | |||
| f3072e84c9 | |||
| b2749765a3 |
@ -20,6 +20,7 @@ SpaceNinjaServer requires a `config.json`. To set it up, you can copy the [confi
|
||||
- `worldState.vallisOverride` can be set to `warm` or `cold` to lock the temperature on Orb Vallis.
|
||||
- `worldState.duviriOverride` can be set to `joy`, `anger`, `envy`, `sorrow`, or `fear` to lock the Duviri spiral.
|
||||
- `worldState.nightwaveOverride` will lock the nightwave season, assuming the client is new enough for it. Valid values:
|
||||
- `RadioLegionIntermission14Syndicate` for Nora's Mix: Dreams of the Dead
|
||||
- `RadioLegionIntermission13Syndicate` for Nora's Mix Vol. 9
|
||||
- `RadioLegionIntermission12Syndicate` for Nora's Mix Vol. 8
|
||||
- `RadioLegionIntermission11Syndicate` for Nora's Mix Vol. 7
|
||||
|
||||
@ -41,8 +41,7 @@ function run(changedFile) {
|
||||
}
|
||||
|
||||
const thisbuildproc = spawn(
|
||||
process.versions.bun ? "bun" : "npm",
|
||||
["run", cangoraw ? "verify" : "build:dev"],
|
||||
[process.versions.bun ? "bun" : "npm", "run", cangoraw ? "verify" : "build:dev"].join(" "),
|
||||
spawnopts
|
||||
);
|
||||
const thisbuildstart = Date.now();
|
||||
@ -55,8 +54,13 @@ function run(changedFile) {
|
||||
if (code === 0) {
|
||||
console.log(`${cangoraw ? "Verified" : "Built"} in ${Date.now() - thisbuildstart} ms`);
|
||||
runproc = spawn(
|
||||
process.versions.bun ? "bun" : "npm",
|
||||
["run", cangoraw ? (process.versions.bun ? "raw:bun" : "raw") : "start", "--", ...args],
|
||||
[
|
||||
process.versions.bun ? "bun" : "npm",
|
||||
"run",
|
||||
cangoraw ? (process.versions.bun ? "raw:bun" : "raw") : "start",
|
||||
"--",
|
||||
...args
|
||||
].join(" "),
|
||||
spawnopts
|
||||
);
|
||||
runproc.on("exit", () => {
|
||||
|
||||
@ -17,7 +17,7 @@ const app = express();
|
||||
|
||||
app.use((req, _res, next) => {
|
||||
// 38.5.0 introduced "ezip" for encrypted body blobs and "e" for request verification only (encrypted body blobs with no application data).
|
||||
// The bootstrapper decrypts it for us but having an unsupported Content-Encoding here would still be an issue for Express, so removing it.
|
||||
// The client patch is expected to decrypt it for us but having an unsupported Content-Encoding here would still be an issue for Express, so removing it.
|
||||
if (req.headers["content-encoding"] == "ezip" || req.headers["content-encoding"] == "e") {
|
||||
req.headers["content-encoding"] = undefined;
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import type { RequestHandler } from "express";
|
||||
import { parseString } from "../../helpers/general.ts";
|
||||
import { getJSONfromString } from "../../helpers/stringHelpers.ts";
|
||||
import { getInventory } from "../../services/inventoryService.ts";
|
||||
import { giveKeyChainItem } from "../../services/questService.ts";
|
||||
import type { IKeyChainRequest } from "../../types/requestTypes.ts";
|
||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
||||
|
||||
export const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => {
|
||||
const accountId = parseString(req.query.accountId);
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const keyChainInfo = getJSONfromString<IKeyChainRequest>((req.body as string).toString());
|
||||
|
||||
const inventory = await getInventory(accountId);
|
||||
|
||||
17
src/controllers/api/reverseQuestProgressController.ts
Normal file
17
src/controllers/api/reverseQuestProgressController.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import type { RequestHandler } from "express";
|
||||
import { getAccountIdForRequest } from "../../services/loginService.ts";
|
||||
import { resetQuestKeyToStage } from "../../services/questService.ts";
|
||||
import { getInventory } from "../../services/inventoryService.ts";
|
||||
import { getJSONfromString } from "../../helpers/stringHelpers.ts";
|
||||
import type { IKeyChainRequest } from "../../types/requestTypes.ts";
|
||||
|
||||
export const reverseQuestProgressController: RequestHandler = async (req, res) => {
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const keyChainInfo = getJSONfromString<IKeyChainRequest>((req.body as string).toString());
|
||||
|
||||
const inventory = await getInventory(accountId);
|
||||
resetQuestKeyToStage(inventory, keyChainInfo);
|
||||
await inventory.save();
|
||||
|
||||
res.end();
|
||||
};
|
||||
@ -120,6 +120,7 @@ import { rerollRandomModController } from "../controllers/api/rerollRandomModCon
|
||||
import { researchMushroomController } from "../controllers/api/researchMushroomController.ts";
|
||||
import { resetQuestProgressController } from "../controllers/api/resetQuestProgressController.ts";
|
||||
import { retrievePetFromStasisController } from "../controllers/api/retrievePetFromStasisController.ts";
|
||||
import { reverseQuestProgressController } from "../controllers/api/reverseQuestProgressController.ts";
|
||||
import { saveDialogueController } from "../controllers/api/saveDialogueController.ts";
|
||||
import { saveLoadoutController } from "../controllers/api/saveLoadoutController.ts";
|
||||
import { saveSettingsController } from "../controllers/api/saveSettingsController.ts";
|
||||
@ -323,6 +324,7 @@ apiRouter.post("/renamePet.php", renamePetController);
|
||||
apiRouter.post("/rerollRandomMod.php", rerollRandomModController);
|
||||
apiRouter.post("/researchMushroom.php", researchMushroomController);
|
||||
apiRouter.post("/retrievePetFromStasis.php", retrievePetFromStasisController);
|
||||
apiRouter.post("/reverseQuestProgress.php", reverseQuestProgressController);
|
||||
apiRouter.post("/saveDialogue.php", saveDialogueController);
|
||||
apiRouter.post("/saveLoadout.php", saveLoadoutController);
|
||||
apiRouter.post("/saveSettings.php", saveSettingsController);
|
||||
|
||||
@ -41,8 +41,8 @@ export const createAccount = async (accountData: IDatabaseAccountRequiredFields)
|
||||
await account.save();
|
||||
const loadoutId = await createLoadout(account._id);
|
||||
const shipId = await createShip(account._id);
|
||||
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
||||
await createPersonalRooms(account._id, shipId);
|
||||
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
||||
await createStats(account._id.toString());
|
||||
return account.toJSON();
|
||||
} catch (error) {
|
||||
@ -64,17 +64,6 @@ export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Typ
|
||||
personalRoomsOwnerId: accountId,
|
||||
activeShipId: shipId
|
||||
});
|
||||
if (config.skipTutorial) {
|
||||
// unlocked during Vor's Prize and The Teacher quests
|
||||
const defaultFeatures = [
|
||||
"/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem",
|
||||
"/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem",
|
||||
"/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem",
|
||||
"/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem",
|
||||
"/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem"
|
||||
];
|
||||
personalRooms.Ship.Features.push(...defaultFeatures);
|
||||
}
|
||||
await personalRooms.save();
|
||||
};
|
||||
|
||||
|
||||
@ -2031,7 +2031,7 @@ function getRandomMissionDrops(
|
||||
.replace("SteelPath", "Steel")
|
||||
.replace(
|
||||
"/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob",
|
||||
"Lotus/Types/Game/MissionDecks/NokkoColonyRewards/NokkoColonyRewards"
|
||||
"/Lotus/Types/Game/MissionDecks/NokkoColonyRewards/NokkoColonyRewards"
|
||||
),
|
||||
masteryReq: 0,
|
||||
minEnemyLevel: 30,
|
||||
|
||||
@ -2,16 +2,25 @@ import type { IKeyChainRequest } from "../types/requestTypes.ts";
|
||||
import { isEmptyObject } from "../helpers/general.ts";
|
||||
import type { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel.ts";
|
||||
import { createMessage } from "./inboxService.ts";
|
||||
import { addItem, addItems, addKeyChainItems, setupKahlSyndicate } from "./inventoryService.ts";
|
||||
import {
|
||||
addEquipment,
|
||||
addItem,
|
||||
addItems,
|
||||
addKeyChainItems,
|
||||
addPowerSuit,
|
||||
setupKahlSyndicate
|
||||
} from "./inventoryService.ts";
|
||||
import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "./itemDataService.ts";
|
||||
import type { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "../types/inventoryTypes/inventoryTypes.ts";
|
||||
import { logger } from "../utils/logger.ts";
|
||||
import { ExportKeys } from "warframe-public-export-plus";
|
||||
import { ExportKeys, ExportRecipes } from "warframe-public-export-plus";
|
||||
import { addFixedLevelRewards } from "./missionInventoryUpdateService.ts";
|
||||
import type { IInventoryChanges } from "../types/purchaseTypes.ts";
|
||||
import questCompletionItems from "../../static/fixed_responses/questCompletionRewards.json" with { type: "json" };
|
||||
import type { ITypeCount } from "../types/commonTypes.ts";
|
||||
import { addString } from "../helpers/stringHelpers.ts";
|
||||
import { unlockShipFeature } from "./personalRoomsService.ts";
|
||||
import { EquipmentFeatures } from "../types/equipmentTypes.ts";
|
||||
|
||||
export interface IUpdateQuestRequest {
|
||||
QuestKeys: IQuestKeyClient[];
|
||||
@ -92,6 +101,30 @@ export const updateQuestStage = (
|
||||
}
|
||||
};
|
||||
|
||||
export const resetQuestKeyToStage = (
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
{ KeyChain, ChainStage }: IKeyChainRequest
|
||||
): void => {
|
||||
const quest = inventory.QuestKeys.find(quest => quest.ItemType === KeyChain);
|
||||
|
||||
if (!quest) {
|
||||
throw new Error(`Quest ${KeyChain} not found in QuestKeys`);
|
||||
}
|
||||
|
||||
quest.Progress ??= [];
|
||||
|
||||
quest.Progress.splice(1 + ChainStage); // remove stages past the target
|
||||
|
||||
const questStage = quest.Progress[ChainStage];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (questStage) {
|
||||
const run = quest.Progress[0].c;
|
||||
if (run >= 0) {
|
||||
questStage.c = run - 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const addQuestKey = (
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
questKey: IQuestKeyDatabase
|
||||
@ -169,6 +202,7 @@ export const completeQuest = async (
|
||||
stage.c = run;
|
||||
await giveKeyChainStageTriggered(inventory, { KeyChain: questKey, ChainStage: i }, sendMessages);
|
||||
await giveKeyChainMissionReward(inventory, { KeyChain: questKey, ChainStage: i });
|
||||
await installShipFeatures(inventory, { KeyChain: questKey, ChainStage: i });
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,6 +339,9 @@ const handleQuestCompletion = async (
|
||||
logger.debug(`quest completion items`, questCompletionItems);
|
||||
if (questCompletionItems) {
|
||||
await addItems(inventory, questCompletionItems, inventoryChanges);
|
||||
for (const item of questCompletionItems) {
|
||||
await removeRequiredItems(inventory, item.ItemType);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -354,7 +391,12 @@ export const giveKeyChainMessage = async (
|
||||
await createMessage(inventory.accountOwnerId, [keyChainMessage]);
|
||||
} else {
|
||||
if (keyChainMessage.countedAtt?.length) await addItems(inventory, keyChainMessage.countedAtt);
|
||||
if (keyChainMessage.att?.length) await addItems(inventory, keyChainMessage.att);
|
||||
if (keyChainMessage.att?.length) {
|
||||
await addItems(inventory, keyChainMessage.att);
|
||||
for (const reward of keyChainMessage.att) {
|
||||
await removeRequiredItems(inventory, reward);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateQuestStage(inventory, keyChainInfo, { m: true });
|
||||
@ -379,6 +421,7 @@ export const giveKeyChainMissionReward = async (
|
||||
|
||||
for (const reward of missionRewards) {
|
||||
await addItem(inventory, fromStoreItem(reward.StoreItem), reward.ItemCount);
|
||||
await removeRequiredItems(inventory, fromStoreItem(reward.StoreItem));
|
||||
}
|
||||
|
||||
updateQuestStage(inventory, keyChainInfo, { c: run });
|
||||
@ -392,6 +435,7 @@ export const giveKeyChainMissionReward = async (
|
||||
await addItem(inventory, fromStoreItem(reward.itemType), reward.amount);
|
||||
} else {
|
||||
await addItem(inventory, fromStoreItem(reward.itemType));
|
||||
await removeRequiredItems(inventory, fromStoreItem(reward.itemType));
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,3 +464,337 @@ export const giveKeyChainStageTriggered = async (
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const installShipFeatures = async (
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
keyChainInfo: IKeyChainRequest
|
||||
): Promise<void> => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
const chainStages = ExportKeys[keyChainInfo.KeyChain]?.chainStages;
|
||||
const questKey = inventory.QuestKeys.find(qk => qk.ItemType === keyChainInfo.KeyChain);
|
||||
if (chainStages && questKey) {
|
||||
if (keyChainInfo.ChainStage - 1 >= 0) {
|
||||
const prevStage = chainStages[keyChainInfo.ChainStage - 1];
|
||||
for (const item of prevStage.itemsToGiveWhenTriggered) {
|
||||
if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
|
||||
logger.debug(`installing ship feature ${fromStoreItem(item)}`);
|
||||
await unlockShipFeature(inventory, fromStoreItem(item));
|
||||
}
|
||||
}
|
||||
if (prevStage.key) {
|
||||
const fixedLevelRewards = getLevelKeyRewards(prevStage.key);
|
||||
if (fixedLevelRewards.levelKeyRewards?.items) {
|
||||
for (const item of fixedLevelRewards.levelKeyRewards.items) {
|
||||
if (item.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")) {
|
||||
logger.debug(`installing ship feature ${fromStoreItem(item)}`);
|
||||
await unlockShipFeature(inventory, fromStoreItem(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fixedLevelRewards.levelKeyRewards2) {
|
||||
for (const item of fixedLevelRewards.levelKeyRewards2) {
|
||||
if (
|
||||
item.rewardType == "RT_STORE_ITEM" &&
|
||||
item.itemType.startsWith("/Lotus/StoreItems/Types/Items/ShipFeatureItems/")
|
||||
) {
|
||||
logger.debug(`installing ship feature ${fromStoreItem(item.itemType)}`);
|
||||
await unlockShipFeature(inventory, fromStoreItem(item.itemType));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const removeRequiredItems = async (inventory: TInventoryDatabaseDocument, typeName: string): Promise<void> => {
|
||||
switch (typeName) {
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianHelmetBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboHelmetKeyBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianSystemsBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboSystemsKeyBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/MagicianChassisBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Keys/LimboQuest/LimboChassisKeyBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/BrawlerBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Recipes/Components/InfestedIrradiatedBaitBallBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
await addItem(inventory, recipe.resultType, -1, false, undefined, undefined, true);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Game/CrewShip/RailJack/DefaultHarness": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
||||
await addItems(inventory, [
|
||||
{
|
||||
ItemType:
|
||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingWingsBlueprint",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType:
|
||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingChassisBlueprint",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType:
|
||||
"/Lotus/Types/Recipes/ArchwingRecipes/StandardArchwing/StandardArchwingSystemsBlueprint",
|
||||
ItemCount: -1
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Keys/ModQuest/ModQuestKeyChain": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Recipes/Components/VorBoltRemoverBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/ChromaBlueprint": {
|
||||
await addItems(inventory, [
|
||||
{
|
||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconABlueprint",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconBBlueprint",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType: "/Lotus/Types/Recipes/WarframeRecipes/ChromaBeaconCBlueprint",
|
||||
ItemCount: -1
|
||||
}
|
||||
]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/OctaviaBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Keys/BardQuest/BardQuestSequencerBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, -1);
|
||||
await addItems(inventory, [
|
||||
{
|
||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartA",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartB",
|
||||
ItemCount: -1
|
||||
},
|
||||
{
|
||||
ItemType: "/Lotus/Types/Keys/BardQuest/BardQuestSequencerPartC",
|
||||
ItemCount: -1
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Game/CrewShip/Ships/RailJack": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Recipes/Railjack/RailjackCephalonBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
||||
await unlockShipFeature(inventory, recipe.resultType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Items/ShipDecos/MummyQuestVessel": {
|
||||
const gearItem = inventory.Consumables.find(
|
||||
i => i.ItemType == "/Lotus/Types/Keys/MummyQuest/MummyArtifact01GearItem"
|
||||
);
|
||||
if (gearItem && gearItem.ItemCount > 0) {
|
||||
await addItem(inventory, gearItem.ItemType, gearItem.ItemCount * -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Types/Recipes/WarframeRecipes/ConcreteFrameBlueprint": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Gameplay/EntratiLab/Quest/GargoyleRecipeItem"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
await addItem(inventory, recipe.resultType);
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "/Lotus/Upgrades/Skins/Umbra/UmbraAltHelmet": {
|
||||
const recipeItem = inventory.Recipes.find(
|
||||
i => i.ItemType == "/Lotus/Types/Recipes/WarframeRecipes/ExcaliburUmbraBlueprint"
|
||||
);
|
||||
if (recipeItem && recipeItem.ItemCount > 0) {
|
||||
const recipe = ExportRecipes[recipeItem.ItemType];
|
||||
if (!inventory.MiscItems.find(i => i.ItemType == recipe.resultType)) {
|
||||
const umbraModA = (
|
||||
await addItem(
|
||||
inventory,
|
||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModA",
|
||||
1,
|
||||
false,
|
||||
undefined,
|
||||
`{"lvl":5}`
|
||||
)
|
||||
).Upgrades![0];
|
||||
const umbraModB = (
|
||||
await addItem(
|
||||
inventory,
|
||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModB",
|
||||
1,
|
||||
false,
|
||||
undefined,
|
||||
`{"lvl":5}`
|
||||
)
|
||||
).Upgrades![0];
|
||||
const umbraModC = (
|
||||
await addItem(
|
||||
inventory,
|
||||
"/Lotus/Upgrades/Mods/Sets/Umbra/WarframeUmbraModC",
|
||||
1,
|
||||
false,
|
||||
undefined,
|
||||
`{"lvl":5}`
|
||||
)
|
||||
).Upgrades![0];
|
||||
const sacrificeModA = (
|
||||
await addItem(
|
||||
inventory,
|
||||
"/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModA",
|
||||
1,
|
||||
false,
|
||||
undefined,
|
||||
`{"lvl":5}`
|
||||
)
|
||||
).Upgrades![0];
|
||||
const sacrificeModB = (
|
||||
await addItem(
|
||||
inventory,
|
||||
"/Lotus/Upgrades/Mods/Sets/Sacrifice/MeleeSacrificeModB",
|
||||
1,
|
||||
false,
|
||||
undefined,
|
||||
`{"lvl":5}`
|
||||
)
|
||||
).Upgrades![0];
|
||||
|
||||
await addPowerSuit(inventory, "/Lotus/Powersuits/Excalibur/ExcaliburUmbra", {
|
||||
Configs: [
|
||||
{
|
||||
Upgrades: [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
umbraModA.ItemId.$oid,
|
||||
umbraModB.ItemId.$oid,
|
||||
umbraModC.ItemId.$oid
|
||||
]
|
||||
}
|
||||
],
|
||||
XP: 900_000,
|
||||
Features: EquipmentFeatures.DOUBLE_CAPACITY
|
||||
});
|
||||
inventory.XPInfo.push({
|
||||
ItemType: "/Lotus/Powersuits/Excalibur/ExcaliburUmbra",
|
||||
XP: 900_000
|
||||
});
|
||||
|
||||
addEquipment(inventory, "Melee", "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana", {
|
||||
Configs: [
|
||||
{
|
||||
Upgrades: ["", "", "", "", "", "", sacrificeModA.ItemId.$oid, sacrificeModB.ItemId.$oid]
|
||||
}
|
||||
],
|
||||
XP: 450_000,
|
||||
Features: EquipmentFeatures.DOUBLE_CAPACITY
|
||||
});
|
||||
inventory.XPInfo.push({
|
||||
ItemType: "/Lotus/Weapons/Tenno/Melee/Swords/UmbraKatana/UmbraKatana",
|
||||
XP: 450_000
|
||||
});
|
||||
if (recipe.consumeOnUse) await addItem(inventory, recipeItem.ItemType, recipeItem.ItemCount * -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@ -3777,7 +3777,10 @@ export const getNightwaveSyndicateTag = (buildLabel: string | undefined): string
|
||||
valid_values: Object.keys(nightwaveTagToSeason)
|
||||
});
|
||||
}
|
||||
if (!buildLabel || version_compare(buildLabel, "2025.05.20.10.18") >= 0) {
|
||||
if (!buildLabel || version_compare(buildLabel, "2025.10.14.16.10") >= 0) {
|
||||
return "RadioLegionIntermission14Syndicate";
|
||||
}
|
||||
if (version_compare(buildLabel, "2025.05.20.10.18") >= 0) {
|
||||
return "RadioLegionIntermission13Syndicate";
|
||||
}
|
||||
if (version_compare(buildLabel, "2025.02.05.11.19") >= 0) {
|
||||
@ -3787,6 +3790,7 @@ export const getNightwaveSyndicateTag = (buildLabel: string | undefined): string
|
||||
};
|
||||
|
||||
const nightwaveTagToSeason: Record<string, number> = {
|
||||
RadioLegionIntermission14Syndicate: 16, // Nora's Mix: Dreams of the Dead
|
||||
RadioLegionIntermission13Syndicate: 15, // Nora's Mix Vol. 9
|
||||
RadioLegionIntermission12Syndicate: 14, // Nora's Mix Vol. 8
|
||||
RadioLegionIntermission11Syndicate: 13, // Nora's Mix Vol. 7
|
||||
|
||||
@ -1474,6 +1474,7 @@
|
||||
<label class="form-label" for="worldState.nightwaveOverride" data-loc="worldState_nightwaveOverride"></label>
|
||||
<select class="form-control" id="worldState.nightwaveOverride" data-default="">
|
||||
<option value="" data-loc="disabled"></option>
|
||||
<option value="RadioLegionIntermission14Syndicate" data-loc="worldState_RadioLegionIntermission14Syndicate"></option>
|
||||
<option value="RadioLegionIntermission13Syndicate" data-loc="worldState_RadioLegionIntermission13Syndicate"></option>
|
||||
<option value="RadioLegionIntermission12Syndicate" data-loc="worldState_RadioLegionIntermission12Syndicate"></option>
|
||||
<option value="RadioLegionIntermission11Syndicate" data-loc="worldState_RadioLegionIntermission11Syndicate"></option>
|
||||
|
||||
@ -1542,14 +1542,17 @@ function updateInventory() {
|
||||
|
||||
if (item) {
|
||||
document.getElementById("detailedView-loading").classList.add("d-none");
|
||||
|
||||
const itemName = itemMap[item.ItemType]?.name ?? item.ItemType;
|
||||
if (item.ItemName) {
|
||||
$("#detailedView-title").text(item.ItemName);
|
||||
$("#detailedView-route .text-body-secondary").text(
|
||||
itemMap[item.ItemType]?.name ?? item.ItemType
|
||||
);
|
||||
const pipeIndex = item.ItemName.indexOf("|");
|
||||
if (pipeIndex != -1) {
|
||||
$("#detailedView-title").text(item.ItemName.substr(1 + pipeIndex) + " " + itemName);
|
||||
} else {
|
||||
$("#detailedView-title").text(item.ItemName);
|
||||
$("#detailedView-route .text-body-secondary").text(itemName);
|
||||
}
|
||||
} else {
|
||||
$("#detailedView-title").text(itemMap[item.ItemType]?.name ?? item.ItemType);
|
||||
$("#detailedView-title").text(itemName);
|
||||
}
|
||||
|
||||
if (category == "Suits") {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// German translation by Animan8000
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Hinweis: Um Änderungen im Spiel zu sehen, musst du dein Inventar neu synchronisieren, z. B. mit dem /sync Befehl des Bootstrappers im Spielchat, durch Besuch eines Dojo/Relais oder durch erneutes Einloggen.`,
|
||||
general_inventoryUpdateNote: `Hinweis: Um Änderungen im Spiel zu sehen, musst du dein Inventar neu synchronisieren, z. B. durch Besuch eines Dojo/Relais oder durch erneutes Anmelden.`,
|
||||
general_inventoryUpdateNoteGameWs: `Hinweis: Möglicherweise musst du ein Menü neu öffnen, damit die Änderungen sichtbar werden.`,
|
||||
general_addButton: `Hinzufügen`,
|
||||
general_setButton: `Festlegen`,
|
||||
@ -51,7 +51,7 @@ dict = {
|
||||
code_focusUnlocked: `|COUNT| neue Fokus-Schulen freigeschaltet! Ein Inventar-Update wird benötigt, damit die Änderungen im Spiel sichtbar werden.`,
|
||||
code_addModsConfirm: `Bist du sicher, dass du |COUNT| Mods zu deinem Account hinzufügen möchtest?`,
|
||||
code_succImport: `Erfolgreich importiert.`,
|
||||
code_succRelog: `Fertig. Bitte beachte, dass du dich neu einloggen musst, um Änderungen im Spiel zu sehen.`,
|
||||
code_succRelog: `Fertig. Bitte beachte, dass du dich neu anmelden musst, um Änderungen im Spiel zu sehen.`,
|
||||
code_nothingToDo: `Fertig. Es gab nichts zu tun.`,
|
||||
code_gild: `Veredeln`,
|
||||
code_moa: `Moa`,
|
||||
@ -135,7 +135,7 @@ dict = {
|
||||
inventory_bulkRankUpSentinelWeapons: `Alle Wächter-Waffen auf Max. Rang`,
|
||||
inventory_bulkRankUpEvolutionProgress: `Alle Incarnon-Entwicklungsfortschritte auf Max. Rang`,
|
||||
inventory_maxPlexus: `Plexus auf Max. Rang`,
|
||||
inventory_removeIsNew: `[UNTRANSLATED] Remove New Equipment Exclamation Icon`,
|
||||
inventory_removeIsNew: `Entferne Ausrufezeichen bei neuem Equipment`,
|
||||
|
||||
quests_list: `Quests`,
|
||||
quests_completeAll: `Alle Quests abschließen`,
|
||||
@ -200,9 +200,9 @@ dict = {
|
||||
cheats_skipTutorial: `Tutorial überspringen`,
|
||||
cheats_skipAllDialogue: `Alle Dialoge überspringen`,
|
||||
cheats_unlockAllScans: `Alle Scans freischalten`,
|
||||
cheats_unlockSuccRelog: `Erfolgreich. Bitte beachte, dass du dich neu einloggen musst, damit der Client dies aktualisiert.`,
|
||||
cheats_unlockSuccRelog: `Erfolgreich. Bitte beachte, dass du dich neu anmelden musst, damit der Client dies aktualisiert.`,
|
||||
cheats_unlockAllMissions: `Alle Missionen freischalten`,
|
||||
cheats_unlockAllMissions_ok: `Erfolgreich. Bitte beachte, dass du ein Dojo/Relais besuchen oder dich neu einloggen musst, damit die Sternenkarte aktualisiert wird.`,
|
||||
cheats_unlockAllMissions_ok: `Erfolgreich. Bitte beachte, dass du ein Dojo/Relais besuchen oder dich neu anmelden musst, damit die Sternenkarte aktualisiert wird.`,
|
||||
cheats_infiniteCredits: `Unendlich Credits`,
|
||||
cheats_infinitePlatinum: `Unendlich Platinum`,
|
||||
cheats_infiniteEndo: `Unendlich Endo`,
|
||||
@ -214,7 +214,7 @@ dict = {
|
||||
cheats_dontSubtractPurchaseItemCost: `Gegenstände beim Kauf nicht verbrauchen`,
|
||||
cheats_dontSubtractPurchaseStandingCost: `Ansehen beim Kauf nicht verbrauchen`,
|
||||
cheats_dontSubtractVoidTraces: `Void-Spuren nicht verbrauchen`,
|
||||
cheats_dontSubtractConsumables: `Verbrauchsgegenstände (Ausrüstung) nicht verbrauchen`,
|
||||
cheats_dontSubtractConsumables: `Verbrauchsgüter (Ausrüstung) nicht verbrauchen`,
|
||||
cheats_unlockAllShipFeatures: `Alle Schiffs-Funktionen freischalten`,
|
||||
cheats_unlockAllSkins: `Alle Skins freischalten`,
|
||||
cheats_unlockAllCapturaScenes: `Alle Photora-Szenen freischalten`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Baro hat volles Inventar`,
|
||||
cheats_syndicateMissionsRepeatable: `Syndikat-Missionen wiederholbar`,
|
||||
cheats_unlockAllProfitTakerStages: `Alle Profiteintreiber-Phasen freischalten`,
|
||||
cheats_unlockSuccInventory: `Erfolgreich. Bitte beachte, dass du dein Inventar neu synchronisieren musst, z. B. mit dem /sync Befehl des Bootstrappers im Spielchat, durch Besuch eines Dojo/Relais oder durch erneutes Einloggen.`,
|
||||
cheats_unlockSuccInventory: `Erfolgreich. Bitte beachte, dass du dein Inventar neu synchronisieren musst, z. B. durch Besuch eines Dojo/Relais oder durch erneutes Anmelden.`,
|
||||
cheats_instantFinishRivenChallenge: `Riven-Mod Herausforderung sofort abschließen`,
|
||||
cheats_instantResourceExtractorDrones: `Sofortige Ressourcen-Extraktor-Drohnen`,
|
||||
cheats_noResourceExtractorDronesDamage: `Kein Schaden für Ressourcen-Extraktor-Drohnen`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `Trauer`,
|
||||
worldState_fear: `Angst`,
|
||||
worldState_nightwaveOverride: `Nightwave-Überschreibung`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `Noras Mix: Träume der Toten`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Noras Mix - Vol. 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Noras Mix - Vol. 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Noras Mix - Vol. 7`,
|
||||
@ -385,10 +386,10 @@ dict = {
|
||||
upgrade_AvatarAbilityRange: `+7.5% Fähigkeitsreichweite`,
|
||||
upgrade_AvatarAbilityEfficiency: `+5% Fähigkeitseffizienz`,
|
||||
upgrade_AvatarEnergyRegen: `+0.5 Energieregeneration pro Sekunde`,
|
||||
upgrade_AvatarEnemyRadar: `+5m Feindradar`,
|
||||
upgrade_AvatarEnemyRadar: `+5m Gegnerradar`,
|
||||
upgrade_AvatarLootRadar: `+7m Beuteradar`,
|
||||
upgrade_WeaponAmmoMax: `+15% Max. Munition`,
|
||||
upgrade_EnemyArmorReductionAura: `-3% Rüstung bei Feinden`,
|
||||
upgrade_EnemyArmorReductionAura: `-3% Rüstung für Gegner`,
|
||||
upgrade_OnExecutionAmmo: `+100% Magazinfüllung für Primär- und Sekundärwaffen bei Gnadenstoß`,
|
||||
upgrade_OnExecutionHealthDrop: `+100% Gesundheitskugel Chance bei Gnadenstoß`,
|
||||
upgrade_OnExecutionEnergyDrop: `+50% Energiekugel Chance bei Gnadenstoß`,
|
||||
@ -398,7 +399,7 @@ dict = {
|
||||
upgrade_OnExecutionParkourSpeed: `+60% Parkourgeschwindigkeit für 15s nach Gnadenstoß`,
|
||||
upgrade_AvatarTimeLimitIncrease: `+8s extra Zeit beim Hacken`,
|
||||
upgrade_ElectrifyOnHack: `Setze beim Hacken Gegner innerhalb von 20m unter Strom`,
|
||||
upgrade_OnExecutionTerrify: `+50% Chance bei Gnadenstoß, dass Feinde innerhalb von 15m vor Furcht für 8s kauern`,
|
||||
upgrade_OnExecutionTerrify: `+50% Chance bei Gnadenstoß, dass Gegner innerhalb von 15m vor Furcht für 8s kauern`,
|
||||
upgrade_OnHackLockers: `Schließe nach dem Hacken 5 Spinde innerhalb von 20m auf`,
|
||||
upgrade_OnExecutionBlind: `Blende bei einem Gnadenstoß Gegner innerhalb von 18m`,
|
||||
upgrade_OnExecutionDrainPower: `Nächste Fähigkeit erhält +50% Fähigkeitsstärke nach Gnadenstoß`,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Note: To see changes in-game, you need to resync your inventory, e.g. using the bootstrapper's /sync command in game chat, visiting a dojo/relay, or relogging.`,
|
||||
general_inventoryUpdateNote: `Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `Note: You may need to reopen any menu you are on for changes to be reflected.`,
|
||||
general_addButton: `Add`,
|
||||
general_setButton: `Set`,
|
||||
@ -233,7 +233,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Baro Fully Stocked`,
|
||||
cheats_syndicateMissionsRepeatable: `Syndicate Missions Repeatable`,
|
||||
cheats_unlockAllProfitTakerStages: `Unlock All Profit Taker Stages`,
|
||||
cheats_unlockSuccInventory: `Success. Please note that you'll need to resync your inventory, e.g. using the bootstrapper's /sync command in game chat, visiting a dojo/relay, or relogging.`,
|
||||
cheats_unlockSuccInventory: `Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `Instant Finish Riven Challenge`,
|
||||
cheats_instantResourceExtractorDrones: `Instant Resource Extractor Drones`,
|
||||
cheats_noResourceExtractorDronesDamage: `No Resource Extractor Drones Damage`,
|
||||
@ -323,6 +323,7 @@ dict = {
|
||||
worldState_sorrow: `Sorrow`,
|
||||
worldState_fear: `Fear`,
|
||||
worldState_nightwaveOverride: `Nightwave Override`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Nora's Mix Vol. 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Nora's Mix Vol. 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Nora's Mix Vol. 7`,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Spanish translation by hxedcl, Slayer55555
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Para ver los cambios en el juego, necesitas volver a sincronizar tu inventario, por ejemplo, usando el comando /sync del bootstrapper, visitando un dojo o repetidor, o volviendo a iniciar sesión.`,
|
||||
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `Nota: Puede que necesites reabrir cualquier menú en el que te encuentres para que los cambios se reflejen.`,
|
||||
general_addButton: `Agregar`,
|
||||
general_setButton: `Establecer`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Baro con stock completo`,
|
||||
cheats_syndicateMissionsRepeatable: `Misiones de sindicato rejugables`,
|
||||
cheats_unlockAllProfitTakerStages: `Desbloquea todas las etapas del Roba-ganancias`,
|
||||
cheats_unlockSuccInventory: `Éxito. Ten en cuenta que deberás volver a sincronizar tu inventario. Para hacerlo, puedes usar el comando /sync en el Bootstrapper, visitar un dojo o repetidor, o volver a iniciar sesión.`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `Terminar desafío de agrietado inmediatamente`,
|
||||
cheats_instantResourceExtractorDrones: `Drones de extracción de recursos instantáneos`,
|
||||
cheats_noResourceExtractorDronesDamage: `Sin daño a los drones extractores de recursos`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `Tristeza`,
|
||||
worldState_fear: `Miedo`,
|
||||
worldState_nightwaveOverride: `Volúmen de Onda Nocturna`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `[UNTRANSLATED] Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Mix de Nora Vol. 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Mix de Nora Vol. 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Mix de Nora Vol. 7`,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// French translation by Vitruvio
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Note : Pour voir les changements en jeu, l'inventaire doit être actualisé. Cela se fait en tapant /sync dans le tchat, en visitant un dojo/relais ou en se reconnectant.`,
|
||||
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `Note : Rouvrir un menu est nécessaire pour voir les changements.`,
|
||||
general_addButton: `Ajouter`,
|
||||
general_setButton: `Définir`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Stock de Baro au max`,
|
||||
cheats_syndicateMissionsRepeatable: `Mission syndicat répétables`,
|
||||
cheats_unlockAllProfitTakerStages: `Débloquer toutes les étapes du Preneur de Profit`,
|
||||
cheats_unlockSuccInventory: `Succès. Une resynchronisation est nécessaire en tapant "/sync" dans le tchat, en visitant un relais ou en se reconnectant.`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `Débloquer le challenge Riven instantanément`,
|
||||
cheats_instantResourceExtractorDrones: `Ressources de drones d'extraction instantannées`,
|
||||
cheats_noResourceExtractorDronesDamage: `Aucun dégâts aux drones d'extraction de resources`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `hagrin`,
|
||||
worldState_fear: `Peur`,
|
||||
worldState_nightwaveOverride: `Saison d'Ondes Nocturnes`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `[UNTRANSLATED] Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Mix de Nora Vol. 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Mix de Nora Vol. 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Mix de Nora Vol. 7`,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Russian translation by AMelonInsideLemon, LoseFace
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Примечание: Чтобы увидеть изменения в игре, вам нужно повторно синхронизировать свой инвентарь, например, используя команду загрузчика /sync в чате игры, посетив Додзё/Реле или перезагрузив игру.`,
|
||||
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `Примечание: для того, чтобы изменения вступили в силу, может потребоваться повторно открыть меню, в котором вы находитесь.`,
|
||||
general_addButton: `Добавить`,
|
||||
general_setButton: `Установить`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Баро полностью укомплектован`,
|
||||
cheats_syndicateMissionsRepeatable: `Повторять миссии синдиката`,
|
||||
cheats_unlockAllProfitTakerStages: `Разблокировать все этапы Сферы извлечения прибыли`,
|
||||
cheats_unlockSuccInventory: `Успех. Обратите внимание, что вам необходимо будет повторно синхронизировать свой инвентарь, например, с помощью команды загрузчика /sync в чате игры, посетив Додзё/Реле или повторно войдя в игру.`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `Мгновенное завершение испытания мода Разлома`,
|
||||
cheats_instantResourceExtractorDrones: `Мгновенно добывающие Дроны-сборщики`,
|
||||
cheats_noResourceExtractorDronesDamage: `Без урона по Дронам-сборщикам`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `Печаль`,
|
||||
worldState_fear: `Страх`,
|
||||
worldState_nightwaveOverride: `Сезон Ночной волны`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `[UNTRANSLATED] Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Микс Норы, Диск 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Микс Норы, Диск 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Микс Норы, Диск 7`,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Ukrainian translation by LoseFace
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `Пам'ятка: Щоб побачити зміни в грі, вам потрібно повторно синхронізувати своє спорядження, наприклад, використовуючи команду завантажувача /sync у чаті гри, відвідавши Доджьо/Реле або перезавантаживши гру.`,
|
||||
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `Примітка: для відображення змін може знадобитися повторно відкрити меню, в якому ви перебуваєте.`,
|
||||
general_addButton: `Добавити`,
|
||||
general_setButton: `Встановити`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `Баро повністю укомплектований`,
|
||||
cheats_syndicateMissionsRepeatable: `Повторювати місії синдиката`,
|
||||
cheats_unlockAllProfitTakerStages: `Розблокувати всі етапи Привласнювачки`,
|
||||
cheats_unlockSuccInventory: `Успішно. Зверніть увагу, що вам потрібно буде повторно синхронізувати своє спорядження, наприклад, за допомогою команди завантажувача /sync у чаті гри, відвідавши Доджьо/Реле або повторно увійшовши в гру.`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `Миттєве завершення випробування модифікатора Розколу`,
|
||||
cheats_instantResourceExtractorDrones: `Миттєво добуваючі Дрони-видобувачі`,
|
||||
cheats_noResourceExtractorDronesDamage: `Без шкоди по Дронам-видобувачам`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `Журба`,
|
||||
worldState_fear: `Страх`,
|
||||
worldState_nightwaveOverride: `Сезон Нічної хвилі`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `[UNTRANSLATED] Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `Вибірка Нори 9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `Вибірка Нори 8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `Вибірка Нори 7`,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Chinese translation by meb154, bishan178, nyaoouo, qianlishun, CrazyZhang, Corvus, qingchun
|
||||
dict = {
|
||||
general_inventoryUpdateNote: `注意: 要在游戏中查看更改,您需要重新同步库存,例如使用客户端的 /sync 命令,访问道场/中继站或重新登录.`,
|
||||
general_inventoryUpdateNote: `[UNTRANSLATED] Note: To see changes in-game, you need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
general_inventoryUpdateNoteGameWs: `[UNTRANSLATED] Note: You may need to reopen any menu you are on for changes to be reflected.`,
|
||||
general_addButton: `添加`,
|
||||
general_setButton: `设置`,
|
||||
@ -234,7 +234,7 @@ dict = {
|
||||
cheats_baroFullyStocked: `虚空商人贩卖所有商品`,
|
||||
cheats_syndicateMissionsRepeatable: `集团任务可重复完成`,
|
||||
cheats_unlockAllProfitTakerStages: `解锁利润收割者圆蛛所有阶段`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. using the bootstrapper's /sync command in game chat, visiting a dojo/relay, or relogging.`,
|
||||
cheats_unlockSuccInventory: `[UNTRANSLATED] Success. Please note that you'll need to resync your inventory, e.g. by visiting a dojo/relay or relogging.`,
|
||||
cheats_instantFinishRivenChallenge: `立即完成裂罅挑战`,
|
||||
cheats_instantResourceExtractorDrones: `资源无人机即时完成`,
|
||||
cheats_noResourceExtractorDronesDamage: `资源无人机不会损毁`,
|
||||
@ -324,6 +324,7 @@ dict = {
|
||||
worldState_sorrow: `悲伤`,
|
||||
worldState_fear: `恐惧`,
|
||||
worldState_nightwaveOverride: `午夜电波系列`,
|
||||
worldState_RadioLegionIntermission14Syndicate: `[UNTRANSLATED] Nora's Mix: Dreams of the Dead`,
|
||||
worldState_RadioLegionIntermission13Syndicate: `诺拉的混选VOL.9`,
|
||||
worldState_RadioLegionIntermission12Syndicate: `诺拉的混选VOL.8`,
|
||||
worldState_RadioLegionIntermission11Syndicate: `诺拉的混选VOL.7`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user