merge upstream
This commit is contained in:
commit
eeb3e687cd
@ -26,7 +26,7 @@ app.use((req, _res, next) => {
|
|||||||
|
|
||||||
app.use(bodyParser.raw());
|
app.use(bodyParser.raw());
|
||||||
app.use(express.json({ limit: "4mb" }));
|
app.use(express.json({ limit: "4mb" }));
|
||||||
app.use(bodyParser.text());
|
app.use(bodyParser.text({ limit: "4mb" }));
|
||||||
app.use(requestLogger);
|
app.use(requestLogger);
|
||||||
|
|
||||||
app.use("/api", apiRouter);
|
app.use("/api", apiRouter);
|
||||||
|
@ -14,7 +14,12 @@ import {
|
|||||||
ExportVirtuals
|
ExportVirtuals
|
||||||
} from "warframe-public-export-plus";
|
} from "warframe-public-export-plus";
|
||||||
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
|
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
|
||||||
import { addMiscItems, allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
|
import {
|
||||||
|
addMiscItems,
|
||||||
|
allDailyAffiliationKeys,
|
||||||
|
cleanupInventory,
|
||||||
|
createLibraryDailyTask
|
||||||
|
} from "@/src/services/inventoryService";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
import { catBreadHash } from "@/src/helpers/stringHelpers";
|
import { catBreadHash } from "@/src/helpers/stringHelpers";
|
||||||
|
|
||||||
@ -79,6 +84,8 @@ export const inventoryController: RequestHandler = async (request, response) =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanupInventory(inventory);
|
||||||
|
|
||||||
inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
|
inventory.NextRefill = new Date((Math.trunc(Date.now() / 86400000) + 1) * 86400000);
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
}
|
}
|
||||||
|
@ -12,22 +12,17 @@ export const saveDialogueController: RequestHandler = async (req, res) => {
|
|||||||
const request = JSON.parse(String(req.body)) as SaveDialogueRequest;
|
const request = JSON.parse(String(req.body)) as SaveDialogueRequest;
|
||||||
if ("YearIteration" in request) {
|
if ("YearIteration" in request) {
|
||||||
const inventory = await getInventory(accountId, "DialogueHistory");
|
const inventory = await getInventory(accountId, "DialogueHistory");
|
||||||
if (inventory.DialogueHistory) {
|
inventory.DialogueHistory ??= {};
|
||||||
inventory.DialogueHistory.YearIteration = request.YearIteration;
|
inventory.DialogueHistory.YearIteration = request.YearIteration;
|
||||||
} else {
|
|
||||||
inventory.DialogueHistory = { YearIteration: request.YearIteration };
|
|
||||||
}
|
|
||||||
await inventory.save();
|
await inventory.save();
|
||||||
res.end();
|
res.end();
|
||||||
} else {
|
} else {
|
||||||
const inventory = await getInventory(accountId);
|
const inventory = await getInventory(accountId);
|
||||||
if (!inventory.DialogueHistory) {
|
|
||||||
throw new Error("bad inventory state");
|
|
||||||
}
|
|
||||||
const inventoryChanges: IInventoryChanges = {};
|
const inventoryChanges: IInventoryChanges = {};
|
||||||
const tomorrowAt0Utc = config.noKimCooldowns
|
const tomorrowAt0Utc = config.noKimCooldowns
|
||||||
? Date.now()
|
? Date.now()
|
||||||
: (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000;
|
: (Math.trunc(Date.now() / 86400_000) + 1) * 86400_000;
|
||||||
|
inventory.DialogueHistory ??= {};
|
||||||
inventory.DialogueHistory.Dialogues ??= [];
|
inventory.DialogueHistory.Dialogues ??= [];
|
||||||
const dialogue = getDialogue(inventory, request.DialogueName);
|
const dialogue = getDialogue(inventory, request.DialogueName);
|
||||||
dialogue.Rank = request.Rank;
|
dialogue.Rank = request.Rank;
|
||||||
|
@ -29,6 +29,7 @@ interface ListedItem {
|
|||||||
badReason?: "starter" | "frivolous" | "notraw";
|
badReason?: "starter" | "frivolous" | "notraw";
|
||||||
partType?: string;
|
partType?: string;
|
||||||
chainLength?: number;
|
chainLength?: number;
|
||||||
|
parazon?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const relicQualitySuffixes: Record<TRelicQuality, string> = {
|
const relicQualitySuffixes: Record<TRelicQuality, string> = {
|
||||||
@ -68,7 +69,8 @@ const getItemListsController: RequestHandler = (req, response) => {
|
|||||||
if (item.productCategory != "SpecialItems") {
|
if (item.productCategory != "SpecialItems") {
|
||||||
res[item.productCategory].push({
|
res[item.productCategory].push({
|
||||||
uniqueName,
|
uniqueName,
|
||||||
name: getString(item.name, lang)
|
name: getString(item.name, lang),
|
||||||
|
exalted: item.exalted
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,6 +198,9 @@ const getItemListsController: RequestHandler = (req, response) => {
|
|||||||
} else if (upgrade.upgradeEntries) {
|
} else if (upgrade.upgradeEntries) {
|
||||||
mod.badReason = "notraw";
|
mod.badReason = "notraw";
|
||||||
}
|
}
|
||||||
|
if (upgrade.type == "PARAZON") {
|
||||||
|
mod.parazon = true;
|
||||||
|
}
|
||||||
res.mods.push(mod);
|
res.mods.push(mod);
|
||||||
}
|
}
|
||||||
for (const [uniqueName, upgrade] of Object.entries(ExportAvionics)) {
|
for (const [uniqueName, upgrade] of Object.entries(ExportAvionics)) {
|
||||||
|
@ -909,7 +909,7 @@ dialogueSchema.set("toJSON", {
|
|||||||
|
|
||||||
const dialogueHistorySchema = new Schema<IDialogueHistoryDatabase>(
|
const dialogueHistorySchema = new Schema<IDialogueHistoryDatabase>(
|
||||||
{
|
{
|
||||||
YearIteration: { type: Number, required: true },
|
YearIteration: Number,
|
||||||
Resets: Number,
|
Resets: Number,
|
||||||
Dialogues: { type: [dialogueSchema], required: false }
|
Dialogues: { type: [dialogueSchema], required: false }
|
||||||
},
|
},
|
||||||
|
@ -37,6 +37,7 @@ import {
|
|||||||
} from "../types/inventoryTypes/inventoryTypes";
|
} from "../types/inventoryTypes/inventoryTypes";
|
||||||
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
|
||||||
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes";
|
import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes";
|
||||||
|
import { slotNames } from "../types/purchaseTypes";
|
||||||
|
|
||||||
const convertDate = (value: IMongoDate): Date => {
|
const convertDate = (value: IMongoDate): Date => {
|
||||||
return new Date(parseInt(value.$date.$numberLong));
|
return new Date(parseInt(value.$date.$numberLong));
|
||||||
@ -212,20 +213,7 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial<
|
|||||||
replaceArray<IOperatorConfigDatabase>(db[key], client[key].map(convertOperatorConfig));
|
replaceArray<IOperatorConfigDatabase>(db[key], client[key].map(convertOperatorConfig));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const key of [
|
for (const key of slotNames) {
|
||||||
"SuitBin",
|
|
||||||
"WeaponBin",
|
|
||||||
"SentinelBin",
|
|
||||||
"SpaceSuitBin",
|
|
||||||
"SpaceWeaponBin",
|
|
||||||
"PvpBonusLoadoutBin",
|
|
||||||
"PveBonusLoadoutBin",
|
|
||||||
"RandomModBin",
|
|
||||||
"MechBin",
|
|
||||||
"CrewMemberBin",
|
|
||||||
"OperatorAmpBin",
|
|
||||||
"CrewShipSalvageBin"
|
|
||||||
] as const) {
|
|
||||||
if (client[key] !== undefined) {
|
if (client[key] !== undefined) {
|
||||||
replaceSlots(db[key], client[key]);
|
replaceSlots(db[key], client[key]);
|
||||||
}
|
}
|
||||||
|
@ -87,9 +87,7 @@ export const createInventory = async (
|
|||||||
const inventory = new Inventory({
|
const inventory = new Inventory({
|
||||||
accountOwnerId: accountOwnerId,
|
accountOwnerId: accountOwnerId,
|
||||||
LoadOutPresets: defaultItemReferences.loadOutPresetId,
|
LoadOutPresets: defaultItemReferences.loadOutPresetId,
|
||||||
Ships: [defaultItemReferences.ship],
|
Ships: [defaultItemReferences.ship]
|
||||||
PlayedParkourTutorial: config.skipTutorial,
|
|
||||||
ReceivedStartingGear: config.skipTutorial
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
inventory.LibraryAvailableDailyTaskInfo = createLibraryDailyTask();
|
||||||
@ -102,6 +100,7 @@ export const createInventory = async (
|
|||||||
await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords");
|
await addItem(inventory, "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords");
|
||||||
|
|
||||||
if (config.skipTutorial) {
|
if (config.skipTutorial) {
|
||||||
|
inventory.PlayedParkourTutorial = true;
|
||||||
await addStartingGear(inventory);
|
await addStartingGear(inventory);
|
||||||
await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
|
await completeQuest(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
|
||||||
|
|
||||||
@ -1769,3 +1768,23 @@ export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void
|
|||||||
Tag: "KahlSyndicate"
|
Tag: "KahlSyndicate"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void => {
|
||||||
|
let index = inventory.MiscItems.findIndex(x => x.ItemType == "");
|
||||||
|
if (index != -1) {
|
||||||
|
inventory.MiscItems.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
index = inventory.Affiliations.findIndex(x => x.Tag == "KahlSyndicate");
|
||||||
|
if (index != -1 && !inventory.Affiliations[index].WeeklyMissions) {
|
||||||
|
logger.debug(`KahlSyndicate seems broken, removing it and setting up again`);
|
||||||
|
inventory.Affiliations.splice(index, 1);
|
||||||
|
setupKahlSyndicate(inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LibrarySyndicate = inventory.Affiliations.find(x => x.Tag == "LibrarySyndicate");
|
||||||
|
if (LibrarySyndicate && LibrarySyndicate.FreeFavorsEarned) {
|
||||||
|
logger.debug(`removing FreeFavorsEarned from LibrarySyndicate`);
|
||||||
|
LibrarySyndicate.FreeFavorsEarned = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -55,6 +55,7 @@ import { Loadout } from "../models/inventoryModels/loadoutModel";
|
|||||||
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes";
|
||||||
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
import { getLiteSortie, getWorldState, idToWeek } from "./worldStateService";
|
||||||
import { config } from "./configService";
|
import { config } from "./configService";
|
||||||
|
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
|
||||||
|
|
||||||
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
|
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
|
||||||
// For Spy missions, e.g. 3 vaults cracked = A, B, C
|
// For Spy missions, e.g. 3 vaults cracked = A, B, C
|
||||||
@ -331,35 +332,36 @@ export const addMissionInventoryUpdates = async (
|
|||||||
case "LibraryScans":
|
case "LibraryScans":
|
||||||
value.forEach(scan => {
|
value.forEach(scan => {
|
||||||
let synthesisIgnored = true;
|
let synthesisIgnored = true;
|
||||||
if (
|
if (inventory.LibraryPersonalTarget) {
|
||||||
inventory.LibraryPersonalTarget &&
|
const taskAvatar = libraryPersonalTargetToAvatar[inventory.LibraryPersonalTarget];
|
||||||
libraryPersonalTargetToAvatar[inventory.LibraryPersonalTarget] == scan.EnemyType
|
const taskAvatars = libraryDailyTasks.find(x => x.indexOf(taskAvatar) != -1)!;
|
||||||
) {
|
if (taskAvatars.indexOf(scan.EnemyType) != -1) {
|
||||||
let progress = inventory.LibraryPersonalProgress.find(
|
let progress = inventory.LibraryPersonalProgress.find(
|
||||||
x => x.TargetType == inventory.LibraryPersonalTarget
|
x => x.TargetType == inventory.LibraryPersonalTarget
|
||||||
);
|
);
|
||||||
if (!progress) {
|
if (!progress) {
|
||||||
progress =
|
progress =
|
||||||
inventory.LibraryPersonalProgress[
|
inventory.LibraryPersonalProgress[
|
||||||
inventory.LibraryPersonalProgress.push({
|
inventory.LibraryPersonalProgress.push({
|
||||||
TargetType: inventory.LibraryPersonalTarget,
|
TargetType: inventory.LibraryPersonalTarget,
|
||||||
Scans: 0,
|
Scans: 0,
|
||||||
Completed: false
|
Completed: false
|
||||||
}) - 1
|
}) - 1
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
progress.Scans += scan.Count;
|
||||||
|
if (
|
||||||
|
progress.Scans >=
|
||||||
|
(inventory.LibraryPersonalTarget ==
|
||||||
|
"/Lotus/Types/Game/Library/Targets/DragonframeQuestTarget"
|
||||||
|
? 3
|
||||||
|
: 10)
|
||||||
|
) {
|
||||||
|
progress.Completed = true;
|
||||||
|
}
|
||||||
|
logger.debug(`synthesis of ${scan.EnemyType} added to personal target progress`);
|
||||||
|
synthesisIgnored = false;
|
||||||
}
|
}
|
||||||
progress.Scans += scan.Count;
|
|
||||||
if (
|
|
||||||
progress.Scans >=
|
|
||||||
(inventory.LibraryPersonalTarget ==
|
|
||||||
"/Lotus/Types/Game/Library/Targets/DragonframeQuestTarget"
|
|
||||||
? 3
|
|
||||||
: 10)
|
|
||||||
) {
|
|
||||||
progress.Completed = true;
|
|
||||||
}
|
|
||||||
logger.debug(`synthesis of ${scan.EnemyType} added to personal target progress`);
|
|
||||||
synthesisIgnored = false;
|
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
inventory.LibraryActiveDailyTaskInfo &&
|
inventory.LibraryActiveDailyTaskInfo &&
|
||||||
|
@ -4,14 +4,7 @@ import { unixTimesInMs } from "@/src/constants/timeConstants";
|
|||||||
import { config } from "@/src/services/configService";
|
import { config } from "@/src/services/configService";
|
||||||
import { CRng } from "@/src/services/rngService";
|
import { CRng } from "@/src/services/rngService";
|
||||||
import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
|
import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
|
||||||
import {
|
import { ICalendarDay, ICalendarSeason, ILiteSortie, ISeasonChallenge, IWorldState } from "../types/worldStateTypes";
|
||||||
ICalendarDay,
|
|
||||||
ICalendarSeason,
|
|
||||||
ILiteSortie,
|
|
||||||
ISeasonChallenge,
|
|
||||||
ISortie,
|
|
||||||
IWorldState
|
|
||||||
} from "../types/worldStateTypes";
|
|
||||||
|
|
||||||
const sortieBosses = [
|
const sortieBosses = [
|
||||||
"SORTIE_BOSS_HYENA",
|
"SORTIE_BOSS_HYENA",
|
||||||
@ -174,7 +167,47 @@ const getSortieTime = (day: number): number => {
|
|||||||
return dayStart + (isDst ? 16 : 17) * 3600000;
|
return dayStart + (isDst ? 16 : 17) * 3600000;
|
||||||
};
|
};
|
||||||
|
|
||||||
const pushSortieIfRelevant = (out: ISortie[], day: number): void => {
|
const pushSyndicateMissions = (
|
||||||
|
worldState: IWorldState,
|
||||||
|
day: number,
|
||||||
|
seed: number,
|
||||||
|
idSuffix: string,
|
||||||
|
syndicateTag: string
|
||||||
|
): void => {
|
||||||
|
const nodeOptions: string[] = [];
|
||||||
|
for (const [key, value] of Object.entries(ExportRegions)) {
|
||||||
|
if (
|
||||||
|
value.name.indexOf("Archwing") == -1 && // no archwing
|
||||||
|
value.systemIndex != 23 && // no 1999 stuff
|
||||||
|
value.missionIndex != 10 && // Exclude MT_PVP (for relays)
|
||||||
|
value.missionIndex != 23 && // no junctions
|
||||||
|
value.missionIndex <= 28 // no railjack or some such
|
||||||
|
) {
|
||||||
|
nodeOptions.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rng = new CRng(seed);
|
||||||
|
const nodes: string[] = [];
|
||||||
|
for (let i = 0; i != 6; ++i) {
|
||||||
|
const index = rng.randomInt(0, nodeOptions.length - 1);
|
||||||
|
nodes.push(nodeOptions[index]);
|
||||||
|
nodeOptions.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayStart = getSortieTime(day);
|
||||||
|
const dayEnd = getSortieTime(day + 1);
|
||||||
|
worldState.SyndicateMissions.push({
|
||||||
|
_id: { $oid: Math.trunc(dayStart / 1000).toString(16) + idSuffix },
|
||||||
|
Activation: { $date: { $numberLong: dayStart.toString() } },
|
||||||
|
Expiry: { $date: { $numberLong: dayEnd.toString() } },
|
||||||
|
Tag: syndicateTag,
|
||||||
|
Seed: seed,
|
||||||
|
Nodes: nodes
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const pushSortieIfRelevant = (worldState: IWorldState, day: number): void => {
|
||||||
const dayStart = getSortieTime(day);
|
const dayStart = getSortieTime(day);
|
||||||
if (!isBeforeNextExpectedWorldStateRefresh(dayStart)) {
|
if (!isBeforeNextExpectedWorldStateRefresh(dayStart)) {
|
||||||
return;
|
return;
|
||||||
@ -231,7 +264,9 @@ const pushSortieIfRelevant = (out: ISortie[], day: number): void => {
|
|||||||
value.name.indexOf("Archwing") == -1 &&
|
value.name.indexOf("Archwing") == -1 &&
|
||||||
value.missionIndex != 0 && // Exclude MT_ASSASSINATION
|
value.missionIndex != 0 && // Exclude MT_ASSASSINATION
|
||||||
value.missionIndex != 5 && // Exclude MT_CAPTURE
|
value.missionIndex != 5 && // Exclude MT_CAPTURE
|
||||||
|
value.missionIndex != 10 && // Exclude MT_PVP (for relays)
|
||||||
value.missionIndex != 21 && // Exclude MT_PURIFY
|
value.missionIndex != 21 && // Exclude MT_PURIFY
|
||||||
|
value.missionIndex != 22 && // Exclude MT_ARENA
|
||||||
value.missionIndex != 23 && // Exclude MT_JUNCTION
|
value.missionIndex != 23 && // Exclude MT_JUNCTION
|
||||||
value.missionIndex <= 28
|
value.missionIndex <= 28
|
||||||
) {
|
) {
|
||||||
@ -291,7 +326,7 @@ const pushSortieIfRelevant = (out: ISortie[], day: number): void => {
|
|||||||
missionTypes.add(missionType);
|
missionTypes.add(missionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push({
|
worldState.Sorties.push({
|
||||||
_id: { $oid: Math.trunc(dayStart / 1000).toString(16) + "d4d932c97c0a3acd" },
|
_id: { $oid: Math.trunc(dayStart / 1000).toString(16) + "d4d932c97c0a3acd" },
|
||||||
Activation: { $date: { $numberLong: dayStart.toString() } },
|
Activation: { $date: { $numberLong: dayStart.toString() } },
|
||||||
Expiry: { $date: { $numberLong: dayEnd.toString() } },
|
Expiry: { $date: { $numberLong: dayEnd.toString() } },
|
||||||
@ -300,6 +335,13 @@ const pushSortieIfRelevant = (out: ISortie[], day: number): void => {
|
|||||||
Boss: boss,
|
Boss: boss,
|
||||||
Variants: selectedNodes
|
Variants: selectedNodes
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48049", "ArbitersSyndicate");
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804a", "CephalonSudaSyndicate");
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4804e", "NewLokaSyndicate");
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48050", "PerrinSyndicate");
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa4805e", "RedVeilSyndicate");
|
||||||
|
pushSyndicateMissions(worldState, day, rng.randomInt(0, 0xffff), "ba6f84724fa48061", "SteelMeridianSyndicate");
|
||||||
};
|
};
|
||||||
|
|
||||||
const dailyChallenges = Object.keys(ExportNightwave.challenges).filter(x =>
|
const dailyChallenges = Object.keys(ExportNightwave.challenges).filter(x =>
|
||||||
@ -952,9 +994,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sortie cycling every day
|
// Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
|
||||||
pushSortieIfRelevant(worldState.Sorties, day - 1);
|
pushSortieIfRelevant(worldState, day - 1);
|
||||||
pushSortieIfRelevant(worldState.Sorties, day);
|
pushSortieIfRelevant(worldState, day);
|
||||||
|
|
||||||
// Archon Hunt cycling every week
|
// Archon Hunt cycling every week
|
||||||
worldState.LiteSorties.push(getLiteSortie(week));
|
worldState.LiteSorties.push(getLiteSortie(week));
|
||||||
|
@ -1130,13 +1130,13 @@ export interface IEndlessXpProgress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IDialogueHistoryClient {
|
export interface IDialogueHistoryClient {
|
||||||
YearIteration: number;
|
YearIteration?: number;
|
||||||
Resets?: number; // added in 38.5.0
|
Resets?: number; // added in 38.5.0
|
||||||
Dialogues?: IDialogueClient[];
|
Dialogues?: IDialogueClient[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDialogueHistoryDatabase {
|
export interface IDialogueHistoryDatabase {
|
||||||
YearIteration: number;
|
YearIteration?: number;
|
||||||
Resets?: number;
|
Resets?: number;
|
||||||
Dialogues?: IDialogueDatabase[];
|
Dialogues?: IDialogueDatabase[];
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,7 @@ export const slotNames = [
|
|||||||
"WeaponBin",
|
"WeaponBin",
|
||||||
"MechBin",
|
"MechBin",
|
||||||
"PveBonusLoadoutBin",
|
"PveBonusLoadoutBin",
|
||||||
|
"PvpBonusLoadoutBin",
|
||||||
"SentinelBin",
|
"SentinelBin",
|
||||||
"SpaceSuitBin",
|
"SpaceSuitBin",
|
||||||
"SpaceWeaponBin",
|
"SpaceWeaponBin",
|
||||||
|
@ -63,22 +63,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"SyndicateMissions": [
|
"SyndicateMissions": [
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa48049" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "ArbitersSyndicate",
|
|
||||||
"Seed": 24491,
|
|
||||||
"Nodes": ["SolNode223", "SolNode89", "SolNode146", "SolNode212", "SolNode167", "SolNode48", "SolNode78"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa4804a" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "CephalonSudaSyndicate",
|
|
||||||
"Seed": 12770,
|
|
||||||
"Nodes": ["SolNode36", "SolNode59", "SettlementNode12", "SolNode61", "SolNode12", "SolNode138", "SolNode72"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa4804c" },
|
"_id": { "$oid": "663a4fc5ba6f84724fa4804c" },
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
||||||
@ -103,14 +87,6 @@
|
|||||||
"Seed": 50102,
|
"Seed": 50102,
|
||||||
"Nodes": []
|
"Nodes": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa4804e" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "NewLokaSyndicate",
|
|
||||||
"Seed": 16064,
|
|
||||||
"Nodes": ["SolNode101", "SolNode224", "SolNode205", "SettlementNode2", "SolNode171", "SolNode188", "SolNode75"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa4804f" },
|
"_id": { "$oid": "663a4fc5ba6f84724fa4804f" },
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
||||||
@ -119,14 +95,6 @@
|
|||||||
"Seed": 77721,
|
"Seed": 77721,
|
||||||
"Nodes": []
|
"Nodes": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa48050" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "PerrinSyndicate",
|
|
||||||
"Seed": 9940,
|
|
||||||
"Nodes": ["SolNode39", "SolNode14", "SolNode203", "SolNode100", "SolNode130", "SolNode64", "SettlementNode15"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa48052" },
|
"_id": { "$oid": "663a4fc5ba6f84724fa48052" },
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
||||||
@ -255,14 +223,6 @@
|
|||||||
"Seed": 67257,
|
"Seed": 67257,
|
||||||
"Nodes": []
|
"Nodes": []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa4805e" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "RedVeilSyndicate",
|
|
||||||
"Seed": 46649,
|
|
||||||
"Nodes": ["SolNode226", "SolNode79", "SolNode216", "SettlementNode11", "SolNode56", "SolNode41", "SolNode23"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa48060" },
|
"_id": { "$oid": "663a4fc5ba6f84724fa48060" },
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
||||||
@ -270,14 +230,6 @@
|
|||||||
"Tag": "VoxSyndicate",
|
"Tag": "VoxSyndicate",
|
||||||
"Seed": 77972,
|
"Seed": 77972,
|
||||||
"Nodes": []
|
"Nodes": []
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a4fc5ba6f84724fa48061" },
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715097541439" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"Tag": "SteelMeridianSyndicate",
|
|
||||||
"Seed": 42366,
|
|
||||||
"Nodes": ["SolNode27", "SolNode107", "SolNode214", "SettlementNode1", "SolNode177", "SolNode141", "SolNode408"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ActiveMissions": [
|
"ActiveMissions": [
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
<input class="form-control" type="password" id="password" required />
|
<input class="form-control" type="password" id="password" required />
|
||||||
<br />
|
<br />
|
||||||
<button class="btn btn-primary" type="submit" data-loc="login_loginButton"></button>
|
<button class="btn btn-primary" type="submit" data-loc="login_loginButton"></button>
|
||||||
|
<button class="btn btn-secondary" type="submit" onclick="registerSubmit = true;" data-loc="login_registerButton"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
|
<div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
|
||||||
@ -490,8 +491,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
<h5 class="card-header" data-loc="general_bulkActions"></h5>
|
<h5 class="card-header" data-loc="general_bulkActions"></h5>
|
||||||
<div class="card-body">
|
<div class="card-body d-flex flex-wrap gap-2">
|
||||||
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_bulkAddMods"></button>
|
<button class="btn btn-primary" onclick="doAddAllMods();" data-loc="mods_bulkAddMods"></button>
|
||||||
|
<button class="btn btn-danger" onclick="doRemoveUnrankedMods();" data-loc="mods_removeUnranked"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
|
let loginOrRegisterPending = false;
|
||||||
|
window.registerSubmit = false;
|
||||||
|
|
||||||
function doLogin() {
|
function doLogin() {
|
||||||
|
if (loginOrRegisterPending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loginOrRegisterPending = true;
|
||||||
localStorage.setItem("email", $("#email").val());
|
localStorage.setItem("email", $("#email").val());
|
||||||
localStorage.setItem("password", $("#password").val());
|
localStorage.setItem("password", $("#password").val());
|
||||||
$("#email, #password").val("");
|
|
||||||
loginFromLocalStorage();
|
loginFromLocalStorage();
|
||||||
|
registerSubmit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loginFromLocalStorage() {
|
function loginFromLocalStorage() {
|
||||||
@ -37,12 +44,15 @@ function doLoginRequest(succ_cb, fail_cb) {
|
|||||||
s: "W0RFXVN0ZXZlIGxpa2VzIGJpZyBidXR0cw==", // signature of some kind
|
s: "W0RFXVN0ZXZlIGxpa2VzIGJpZyBidXR0cw==", // signature of some kind
|
||||||
lang: "en",
|
lang: "en",
|
||||||
date: 1501230947855458660, // ???
|
date: 1501230947855458660, // ???
|
||||||
ClientType: "webui",
|
ClientType: registerSubmit ? "" : "webui",
|
||||||
PS: "W0RFXVN0ZXZlIGxpa2VzIGJpZyBidXR0cw==" // anti-cheat data
|
PS: "W0RFXVN0ZXZlIGxpa2VzIGJpZyBidXR0cw==" // anti-cheat data
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
req.done(succ_cb);
|
req.done(succ_cb);
|
||||||
req.fail(fail_cb);
|
req.fail(fail_cb);
|
||||||
|
req.always(() => {
|
||||||
|
loginOrRegisterPending = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function revalidateAuthz(succ_cb) {
|
function revalidateAuthz(succ_cb) {
|
||||||
@ -436,17 +446,35 @@ function updateInventory() {
|
|||||||
category != "SpaceSuits" &&
|
category != "SpaceSuits" &&
|
||||||
category != "Sentinels" &&
|
category != "Sentinels" &&
|
||||||
category != "Hoverboards" &&
|
category != "Hoverboards" &&
|
||||||
category != "MechSuits"
|
category != "MechSuits" &&
|
||||||
|
category != "MoaPets" &&
|
||||||
|
category != "KubrowPets"
|
||||||
) {
|
) {
|
||||||
maxXP /= 2;
|
maxXP /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.XP < maxXP) {
|
let anyExaltedMissingXP = false;
|
||||||
|
if (item.XP >= maxXP && "exalted" in itemMap[item.ItemType]) {
|
||||||
|
for (const exaltedType of itemMap[item.ItemType].exalted) {
|
||||||
|
const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType);
|
||||||
|
if (exaltedItem) {
|
||||||
|
const exaltedCap = itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000;
|
||||||
|
if (exaltedItem.XP < exaltedCap) {
|
||||||
|
anyExaltedMissingXP = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.XP < maxXP || anyExaltedMissingXP) {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.href = "#";
|
a.href = "#";
|
||||||
a.onclick = function (event) {
|
a.onclick = function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
addGearExp(category, item.ItemId.$oid, maxXP - item.XP);
|
if (item.XP < maxXP) {
|
||||||
|
addGearExp(category, item.ItemId.$oid, maxXP - item.XP);
|
||||||
|
}
|
||||||
if ("exalted" in itemMap[item.ItemType]) {
|
if ("exalted" in itemMap[item.ItemType]) {
|
||||||
for (const exaltedType of itemMap[item.ItemType].exalted) {
|
for (const exaltedType of itemMap[item.ItemType].exalted) {
|
||||||
const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType);
|
const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType);
|
||||||
@ -786,7 +814,7 @@ function updateInventory() {
|
|||||||
{
|
{
|
||||||
const td = document.createElement("td");
|
const td = document.createElement("td");
|
||||||
td.classList = "text-end text-nowrap";
|
td.classList = "text-end text-nowrap";
|
||||||
{
|
if (maxRank != 0) {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.href = "#";
|
a.href = "#";
|
||||||
a.onclick = function (event) {
|
a.onclick = function (event) {
|
||||||
@ -1594,6 +1622,31 @@ function doAddAllMods() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doRemoveUnrankedMods() {
|
||||||
|
revalidateAuthz(() => {
|
||||||
|
const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
|
||||||
|
req.done(inventory => {
|
||||||
|
window.itemListPromise.then(itemMap => {
|
||||||
|
$.post({
|
||||||
|
url: "/api/sell.php?" + window.authz,
|
||||||
|
contentType: "text/plain",
|
||||||
|
data: JSON.stringify({
|
||||||
|
SellCurrency: "SC_RegularCredits",
|
||||||
|
SellPrice: 0,
|
||||||
|
Items: {
|
||||||
|
Upgrades: inventory.RawUpgrades.filter(
|
||||||
|
x => !itemMap[x.ItemType]?.parazon && x.ItemCount > 0
|
||||||
|
).map(x => ({ String: x.ItemType, Count: x.ItemCount }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).done(function () {
|
||||||
|
updateInventory();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Powersuit Route
|
// Powersuit Route
|
||||||
|
|
||||||
single.getRoute("#powersuit-route").on("beforeload", function () {
|
single.getRoute("#powersuit-route").on("beforeload", function () {
|
||||||
|
@ -54,12 +54,13 @@ dict = {
|
|||||||
code_completed: `Abgeschlossen`,
|
code_completed: `Abgeschlossen`,
|
||||||
code_active: `Aktiv`,
|
code_active: `Aktiv`,
|
||||||
code_pigment: `Pigment`,
|
code_pigment: `Pigment`,
|
||||||
code_mature: `[UNTRANSLATED] Mature for combat`,
|
code_mature: `Für den Kampf auswachsen lassen`,
|
||||||
code_unmature: `[UNTRANSLATED] Regress genetic aging`,
|
code_unmature: `Genetisches Altern zurücksetzen`,
|
||||||
login_description: `Melde dich mit deinem OpenWF-Account an (denselben Angaben wie im Spiel, wenn du dich mit diesem Server verbindest).`,
|
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_emailLabel: `E-Mail-Adresse`,
|
||||||
login_passwordLabel: `Passwort`,
|
login_passwordLabel: `Passwort`,
|
||||||
login_loginButton: `Anmelden`,
|
login_loginButton: `Anmelden`,
|
||||||
|
login_registerButton: `[UNTRANSLATED] Register`,
|
||||||
navbar_logout: `Abmelden`,
|
navbar_logout: `Abmelden`,
|
||||||
navbar_renameAccount: `Account umbenennen`,
|
navbar_renameAccount: `Account umbenennen`,
|
||||||
navbar_deleteAccount: `Account löschen`,
|
navbar_deleteAccount: `Account löschen`,
|
||||||
@ -82,7 +83,7 @@ dict = {
|
|||||||
inventory_operatorAmps: `Verstärker`,
|
inventory_operatorAmps: `Verstärker`,
|
||||||
inventory_hoverboards: `K-Drives`,
|
inventory_hoverboards: `K-Drives`,
|
||||||
inventory_moaPets: `Moa`,
|
inventory_moaPets: `Moa`,
|
||||||
inventory_kubrowPets: `[UNTRANSLATED] Beasts`,
|
inventory_kubrowPets: `Bestien`,
|
||||||
inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
|
inventory_bulkAddSuits: `Fehlende Warframes hinzufügen`,
|
||||||
inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`,
|
inventory_bulkAddWeapons: `Fehlende Waffen hinzufügen`,
|
||||||
inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`,
|
inventory_bulkAddSpaceSuits: `Fehlende Archwings hinzufügen`,
|
||||||
@ -115,6 +116,7 @@ dict = {
|
|||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Fehlende Mods hinzufügen`,
|
mods_bulkAddMods: `Fehlende Mods hinzufügen`,
|
||||||
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `Du musst Administrator sein, um diese Funktion nutzen zu können. Um Administrator zu werden, füge <code>|DISPLAYNAME|</code> zu <code>administratorNames</code> in der config.json hinzu.`,
|
cheats_administratorRequirement: `Du musst Administrator sein, um diese Funktion nutzen zu können. Um Administrator zu werden, füge <code>|DISPLAYNAME|</code> zu <code>administratorNames</code> in der config.json hinzu.`,
|
||||||
cheats_server: `Server`,
|
cheats_server: `Server`,
|
||||||
cheats_skipTutorial: `Tutorial überspringen`,
|
cheats_skipTutorial: `Tutorial überspringen`,
|
||||||
|
@ -59,6 +59,7 @@ dict = {
|
|||||||
login_emailLabel: `Email address`,
|
login_emailLabel: `Email address`,
|
||||||
login_passwordLabel: `Password`,
|
login_passwordLabel: `Password`,
|
||||||
login_loginButton: `Login`,
|
login_loginButton: `Login`,
|
||||||
|
login_registerButton: `Register`,
|
||||||
navbar_logout: `Logout`,
|
navbar_logout: `Logout`,
|
||||||
navbar_renameAccount: `Rename Account`,
|
navbar_renameAccount: `Rename Account`,
|
||||||
navbar_deleteAccount: `Delete Account`,
|
navbar_deleteAccount: `Delete Account`,
|
||||||
@ -114,6 +115,7 @@ dict = {
|
|||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Add Missing Mods`,
|
mods_bulkAddMods: `Add Missing Mods`,
|
||||||
|
mods_removeUnranked: `Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `You must be an administrator to use this feature. To become an administrator, add <code>|DISPLAYNAME|</code> to <code>administratorNames</code> in the config.json.`,
|
cheats_administratorRequirement: `You must be an administrator to use this feature. To become an administrator, add <code>|DISPLAYNAME|</code> to <code>administratorNames</code> in the config.json.`,
|
||||||
cheats_server: `Server`,
|
cheats_server: `Server`,
|
||||||
cheats_skipTutorial: `Skip Tutorial`,
|
cheats_skipTutorial: `Skip Tutorial`,
|
||||||
|
@ -60,6 +60,7 @@ dict = {
|
|||||||
login_emailLabel: `Dirección de correo electrónico`,
|
login_emailLabel: `Dirección de correo electrónico`,
|
||||||
login_passwordLabel: `Contraseña`,
|
login_passwordLabel: `Contraseña`,
|
||||||
login_loginButton: `Iniciar sesión`,
|
login_loginButton: `Iniciar sesión`,
|
||||||
|
login_registerButton: `[UNTRANSLATED] Register`,
|
||||||
navbar_logout: `Cerrar sesión`,
|
navbar_logout: `Cerrar sesión`,
|
||||||
navbar_renameAccount: `Renombrar cuenta`,
|
navbar_renameAccount: `Renombrar cuenta`,
|
||||||
navbar_deleteAccount: `Eliminar cuenta`,
|
navbar_deleteAccount: `Eliminar cuenta`,
|
||||||
@ -115,6 +116,7 @@ dict = {
|
|||||||
mods_rivens: `Agrietados`,
|
mods_rivens: `Agrietados`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Agregar mods faltantes`,
|
mods_bulkAddMods: `Agregar mods faltantes`,
|
||||||
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `Debes ser administrador para usar esta función. Para convertirte en administrador, agrega <code>|DISPLAYNAME|</code> a <code>administratorNames</code> en el archivo config.json.`,
|
cheats_administratorRequirement: `Debes ser administrador para usar esta función. Para convertirte en administrador, agrega <code>|DISPLAYNAME|</code> a <code>administratorNames</code> en el archivo config.json.`,
|
||||||
cheats_server: `Servidor`,
|
cheats_server: `Servidor`,
|
||||||
cheats_skipTutorial: `Omitir tutorial`,
|
cheats_skipTutorial: `Omitir tutorial`,
|
||||||
|
@ -25,10 +25,10 @@ dict = {
|
|||||||
code_renamePrompt: `Nouveau nom :`,
|
code_renamePrompt: `Nouveau nom :`,
|
||||||
code_remove: `Retirer`,
|
code_remove: `Retirer`,
|
||||||
code_addItemsConfirm: `Ajouter |COUNT| items à l'inventaire ?`,
|
code_addItemsConfirm: `Ajouter |COUNT| items à l'inventaire ?`,
|
||||||
code_succRankUp: `[UNTRANSLATED] Successfully ranked up.`,
|
code_succRankUp: `Montée de niveau effectuée.`,
|
||||||
code_noEquipmentToRankUp: `No equipment to rank up.`,
|
code_noEquipmentToRankUp: `Aucun équipement à monter de niveau.`,
|
||||||
code_succAdded: `Ajouté.`,
|
code_succAdded: `Ajouté.`,
|
||||||
code_succRemoved: `[UNTRANSLATED] Successfully removed.`,
|
code_succRemoved: `Retiré.`,
|
||||||
code_buffsNumber: `Nombre de buffs`,
|
code_buffsNumber: `Nombre de buffs`,
|
||||||
code_cursesNumber: `Nombre de débuffs`,
|
code_cursesNumber: `Nombre de débuffs`,
|
||||||
code_rerollsNumber: `Nombre de rerolls`,
|
code_rerollsNumber: `Nombre de rerolls`,
|
||||||
@ -45,21 +45,22 @@ dict = {
|
|||||||
code_zanukaA: `Molosse Dorma`,
|
code_zanukaA: `Molosse Dorma`,
|
||||||
code_zanukaB: `Molosse Bhaira`,
|
code_zanukaB: `Molosse Bhaira`,
|
||||||
code_zanukaC: `Molosse Hec`,
|
code_zanukaC: `Molosse Hec`,
|
||||||
code_stage: `[UNTRANSLATED] Stage`,
|
code_stage: `Étape`,
|
||||||
code_complete: `[UNTRANSLATED] Complete`,
|
code_complete: `Compléter`,
|
||||||
code_nextStage: `[UNTRANSLATED] Next stage`,
|
code_nextStage: `Étape suivante`,
|
||||||
code_prevStage: `[UNTRANSLATED] Previous stage`,
|
code_prevStage: `Étape précédente`,
|
||||||
code_reset: `[UNTRANSLATED] Reset`,
|
code_reset: `Réinitialiser`,
|
||||||
code_setInactive: `[UNTRANSLATED] Make the quest inactive`,
|
code_setInactive: `Rendre la quête inactive`,
|
||||||
code_completed: `[UNTRANSLATED] Completed`,
|
code_completed: `Complétée`,
|
||||||
code_active: `[UNTRANSLATED] Active`,
|
code_active: `Active`,
|
||||||
code_pigment: `Pigment`,
|
code_pigment: `Pigment`,
|
||||||
code_mature: `[UNTRANSLATED] Mature for combat`,
|
code_mature: `Maturer pour le combat`,
|
||||||
code_unmature: `[UNTRANSLATED] Regress genetic aging`,
|
code_unmature: `Régrésser l'âge génétique`,
|
||||||
login_description: `Connexion avec les informations de connexion OpenWF.`,
|
login_description: `Connexion avec les informations de connexion OpenWF.`,
|
||||||
login_emailLabel: `Email`,
|
login_emailLabel: `Email`,
|
||||||
login_passwordLabel: `Mot de passe`,
|
login_passwordLabel: `Mot de passe`,
|
||||||
login_loginButton: `Connexion`,
|
login_loginButton: `Connexion`,
|
||||||
|
login_registerButton: `[UNTRANSLATED] Register`,
|
||||||
navbar_logout: `Déconnexion`,
|
navbar_logout: `Déconnexion`,
|
||||||
navbar_renameAccount: `Renommer le compte`,
|
navbar_renameAccount: `Renommer le compte`,
|
||||||
navbar_deleteAccount: `Supprimer le compte`,
|
navbar_deleteAccount: `Supprimer le compte`,
|
||||||
@ -82,7 +83,7 @@ dict = {
|
|||||||
inventory_operatorAmps: `Amplificateurs`,
|
inventory_operatorAmps: `Amplificateurs`,
|
||||||
inventory_hoverboards: `K-Drives`,
|
inventory_hoverboards: `K-Drives`,
|
||||||
inventory_moaPets: `Moa`,
|
inventory_moaPets: `Moa`,
|
||||||
inventory_kubrowPets: `[UNTRANSLATED] Beasts`,
|
inventory_kubrowPets: `Bêtes`,
|
||||||
inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
|
inventory_bulkAddSuits: `Ajouter les Warframes manquantes`,
|
||||||
inventory_bulkAddWeapons: `Ajouter les armes manquantes`,
|
inventory_bulkAddWeapons: `Ajouter les armes manquantes`,
|
||||||
inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`,
|
inventory_bulkAddSpaceSuits: `Ajouter les Archwings manquants`,
|
||||||
@ -107,14 +108,15 @@ dict = {
|
|||||||
currency_PrimeTokens: `Aya Raffiné`,
|
currency_PrimeTokens: `Aya Raffiné`,
|
||||||
currency_owned: `|COUNT| possédés.`,
|
currency_owned: `|COUNT| possédés.`,
|
||||||
powersuit_archonShardsLabel: `Emplacements de fragments d'Archonte`,
|
powersuit_archonShardsLabel: `Emplacements de fragments d'Archonte`,
|
||||||
powersuit_archonShardsDescription: `Slots illimités pour appliquer plusieurs améliorations.`,
|
powersuit_archonShardsDescription: `Slots illimités pour appliquer plusieurs améliorations`,
|
||||||
powersuit_archonShardsDescription2: `[UNTRANSLATED] Note that each archon shard takes some time to be applied when loading in.`,
|
powersuit_archonShardsDescription2: `Un délai sera présent entre l'application des éclats et le chargement en jeu.`,
|
||||||
mods_addRiven: `Ajouter un riven`,
|
mods_addRiven: `Ajouter un riven`,
|
||||||
mods_fingerprint: `Empreinte`,
|
mods_fingerprint: `Empreinte`,
|
||||||
mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`,
|
mods_fingerprintHelp: `Besoin d'aide pour l'empreinte ?`,
|
||||||
mods_rivens: `Rivens`,
|
mods_rivens: `Rivens`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `Ajouter les mods manquants`,
|
mods_bulkAddMods: `Ajouter les mods manquants`,
|
||||||
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `Rôle d'administrateur requis pour cette fonctionnalité. Ajoutez <code>|DISPLAYNAME|</code> à la ligne <code>administratorNames</code> dans le fichier config.json.`,
|
cheats_administratorRequirement: `Rôle d'administrateur requis pour cette fonctionnalité. Ajoutez <code>|DISPLAYNAME|</code> à la ligne <code>administratorNames</code> dans le fichier config.json.`,
|
||||||
cheats_server: `Serveur`,
|
cheats_server: `Serveur`,
|
||||||
cheats_skipTutorial: `Passer le tutoriel`,
|
cheats_skipTutorial: `Passer le tutoriel`,
|
||||||
@ -131,32 +133,32 @@ dict = {
|
|||||||
cheats_unlockAllFlavourItems: `Débloquer tous les <abbr title=\"Animations, Glyphes, Palettes, etc.\">Flavor Items</abbr>`,
|
cheats_unlockAllFlavourItems: `Débloquer tous les <abbr title=\"Animations, Glyphes, Palettes, etc.\">Flavor Items</abbr>`,
|
||||||
cheats_unlockAllSkins: `Débloquer tous les skins`,
|
cheats_unlockAllSkins: `Débloquer tous les skins`,
|
||||||
cheats_unlockAllCapturaScenes: `Débloquer toutes les scènes captura`,
|
cheats_unlockAllCapturaScenes: `Débloquer toutes les scènes captura`,
|
||||||
cheats_unlockAllDecoRecipes: `[UNTRANSLATED] Unlock All Dojo Deco Recipes`,
|
cheats_unlockAllDecoRecipes: `Débloquer toutes les recherches dojo`,
|
||||||
cheats_universalPolarityEverywhere: `Polarités universelles partout`,
|
cheats_universalPolarityEverywhere: `Polarités universelles partout`,
|
||||||
cheats_unlockDoubleCapacityPotatoesEverywhere: `Réacteurs et Catalyseurs partout`,
|
cheats_unlockDoubleCapacityPotatoesEverywhere: `Réacteurs et Catalyseurs partout`,
|
||||||
cheats_unlockExilusEverywhere: `Adaptateurs Exilus partout`,
|
cheats_unlockExilusEverywhere: `Adaptateurs Exilus partout`,
|
||||||
cheats_unlockArcanesEverywhere: `Adaptateur d'Arcanes partout`,
|
cheats_unlockArcanesEverywhere: `Adaptateur d'Arcanes partout`,
|
||||||
cheats_noDailyStandingLimits: `Pas de limite de réputation journalière`,
|
cheats_noDailyStandingLimits: `Aucune limite de réputation journalière`,
|
||||||
cheats_noDailyFocusLimit: `[UNTRANSLATED] No Daily Focus Limits`,
|
cheats_noDailyFocusLimit: `Aucune limite journalière de focus`,
|
||||||
cheats_noArgonCrystalDecay: `[UNTRANSLATED] No Argon Crystal Decay`,
|
cheats_noArgonCrystalDecay: `Aucune désintégration des Cristaux d'Argon`,
|
||||||
cheats_noMasteryRankUpCooldown: `[UNTRANSLATED] No Mastery Rank Up Cooldown`,
|
cheats_noMasteryRankUpCooldown: `Aucune attente pour la montée de rang de maîtrise`,
|
||||||
cheats_noVendorPurchaseLimits: `[UNTRANSLATED] No Vendor Purchase Limits`,
|
cheats_noVendorPurchaseLimits: `Aucune limite d'achat chez les PNJ`,
|
||||||
cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
|
cheats_noDeathMarks: `Aucune marque d'assassin`,
|
||||||
cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
|
cheats_noKimCooldowns: `Aucun cooldown sur le KIM`,
|
||||||
cheats_instantResourceExtractorDrones: `Ressources de drone d'extraction instantannées`,
|
cheats_instantResourceExtractorDrones: `Ressources de drones d'extraction instantannées`,
|
||||||
cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
|
cheats_noResourceExtractorDronesDamage: `Aucun dégâts aux drones d'extraction de resources`,
|
||||||
cheats_noDojoRoomBuildStage: `No Dojo Room Build Stage`,
|
cheats_noDojoRoomBuildStage: `Aucune attente (construction des salles)`,
|
||||||
cheats_noDojoDecoBuildStage: `[UNTRANSLATED] No Dojo Deco Build Stage`,
|
cheats_noDojoDecoBuildStage: `Aucune attente (construction des décorations)`,
|
||||||
cheats_fastDojoRoomDestruction: `[UNTRANSLATED] Fast Dojo Room Destruction`,
|
cheats_fastDojoRoomDestruction: `Destruction de salle instantanée (Dojo)`,
|
||||||
cheats_noDojoResearchCosts: `Aucun coût de recherche (Dojo)`,
|
cheats_noDojoResearchCosts: `Aucun coût de recherche (Dojo)`,
|
||||||
cheats_noDojoResearchTime: `Aucun temps de recherche (Dojo)`,
|
cheats_noDojoResearchTime: `Aucun temps de recherche (Dojo)`,
|
||||||
cheats_fastClanAscension: `[UNTRANSLATED] Fast Clan Ascension`,
|
cheats_fastClanAscension: `Ascension de clan rapide`,
|
||||||
cheats_spoofMasteryRank: `Spoofed Mastery Rank (-1 to disable)`,
|
cheats_spoofMasteryRank: `Rang de maîtrise personnalisé (-1 pour désactiver)`,
|
||||||
cheats_saveSettings: `Sauvegarder les paramètres`,
|
cheats_saveSettings: `Sauvegarder les paramètres`,
|
||||||
cheats_account: `Compte`,
|
cheats_account: `Compte`,
|
||||||
cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`,
|
cheats_unlockAllFocusSchools: `Débloquer toutes les écoles de focus`,
|
||||||
cheats_helminthUnlockAll: `Helminth niveau max`,
|
cheats_helminthUnlockAll: `Helminth niveau max`,
|
||||||
cheats_intrinsicsUnlockAll: `[UNTRANSLATED] Max Rank All Intrinsics`,
|
cheats_intrinsicsUnlockAll: `Inhérences niveau max`,
|
||||||
cheats_changeSupportedSyndicate: `Allégeance`,
|
cheats_changeSupportedSyndicate: `Allégeance`,
|
||||||
cheats_changeButton: `Changer`,
|
cheats_changeButton: `Changer`,
|
||||||
cheats_none: `Aucun`,
|
cheats_none: `Aucun`,
|
||||||
|
@ -60,6 +60,7 @@ dict = {
|
|||||||
login_emailLabel: `Адрес электронной почты`,
|
login_emailLabel: `Адрес электронной почты`,
|
||||||
login_passwordLabel: `Пароль`,
|
login_passwordLabel: `Пароль`,
|
||||||
login_loginButton: `Войти`,
|
login_loginButton: `Войти`,
|
||||||
|
login_registerButton: `[UNTRANSLATED] Register`,
|
||||||
navbar_logout: `Выйти`,
|
navbar_logout: `Выйти`,
|
||||||
navbar_renameAccount: `Переименовать аккаунт`,
|
navbar_renameAccount: `Переименовать аккаунт`,
|
||||||
navbar_deleteAccount: `Удалить аккаунт`,
|
navbar_deleteAccount: `Удалить аккаунт`,
|
||||||
@ -108,13 +109,14 @@ dict = {
|
|||||||
currency_owned: `У тебя |COUNT|.`,
|
currency_owned: `У тебя |COUNT|.`,
|
||||||
powersuit_archonShardsLabel: `Ячейки осколков архонта`,
|
powersuit_archonShardsLabel: `Ячейки осколков архонта`,
|
||||||
powersuit_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`,
|
powersuit_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`,
|
||||||
powersuit_archonShardsDescription2: `[UNTRANSLATED] Note that each archon shard takes some time to be applied when loading in.`,
|
powersuit_archonShardsDescription2: `Обратите внимание: каждый фрагмент архонта применяется с задержкой при загрузке.`,
|
||||||
mods_addRiven: `Добавить Мод Разлома`,
|
mods_addRiven: `Добавить Мод Разлома`,
|
||||||
mods_fingerprint: `Отпечаток`,
|
mods_fingerprint: `Отпечаток`,
|
||||||
mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
|
mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
|
||||||
mods_rivens: `Моды Разлома`,
|
mods_rivens: `Моды Разлома`,
|
||||||
mods_mods: `Моды`,
|
mods_mods: `Моды`,
|
||||||
mods_bulkAddMods: `Добавить отсутствующие моды`,
|
mods_bulkAddMods: `Добавить отсутствующие моды`,
|
||||||
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `Вы должны быть администратором для использования этой функции. Чтобы стать администратором, добавьте <code>\"|DISPLAYNAME|\"</code> в <code>administratorNames</code> в config.json.`,
|
cheats_administratorRequirement: `Вы должны быть администратором для использования этой функции. Чтобы стать администратором, добавьте <code>\"|DISPLAYNAME|\"</code> в <code>administratorNames</code> в config.json.`,
|
||||||
cheats_server: `Сервер`,
|
cheats_server: `Сервер`,
|
||||||
cheats_skipTutorial: `Пропустить обучение`,
|
cheats_skipTutorial: `Пропустить обучение`,
|
||||||
@ -136,15 +138,15 @@ dict = {
|
|||||||
cheats_unlockDoubleCapacityPotatoesEverywhere: `Катализаторы везде`,
|
cheats_unlockDoubleCapacityPotatoesEverywhere: `Катализаторы везде`,
|
||||||
cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`,
|
cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`,
|
||||||
cheats_unlockArcanesEverywhere: `Адаптеры для мистификаторов везде`,
|
cheats_unlockArcanesEverywhere: `Адаптеры для мистификаторов везде`,
|
||||||
cheats_noDailyStandingLimits: `Без ежедневных ограничений репутации`,
|
cheats_noDailyStandingLimits: `Без ежедневных лимитов репутации`,
|
||||||
cheats_noDailyFocusLimit: `[UNTRANSLATED] No Daily Focus Limits`,
|
cheats_noDailyFocusLimit: `Без ежедневных лимитов фокуса`,
|
||||||
cheats_noArgonCrystalDecay: `Без распада аргоновых кристаллов`,
|
cheats_noArgonCrystalDecay: `Без распада аргоновых кристаллов`,
|
||||||
cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`,
|
cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`,
|
||||||
cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
|
cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у вендоров`,
|
||||||
cheats_noDeathMarks: `[UNTRANSLATED] No Death Marks`,
|
cheats_noDeathMarks: `Без меток сметри`,
|
||||||
cheats_noKimCooldowns: `[UNTRANSLATED] No KIM Cooldowns`,
|
cheats_noKimCooldowns: `Чаты KIM без кулдауна`,
|
||||||
cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`,
|
cheats_instantResourceExtractorDrones: `Мгновенные Экстракторы Ресурсов`,
|
||||||
cheats_noResourceExtractorDronesDamage: `[UNTRANSLATED] No Resource Extractor Drones Damage`,
|
cheats_noResourceExtractorDronesDamage: `Без урона по дронам-сборщикам`,
|
||||||
cheats_noDojoRoomBuildStage: `Мгновенное Строительтво Комнат Додзё`,
|
cheats_noDojoRoomBuildStage: `Мгновенное Строительтво Комнат Додзё`,
|
||||||
cheats_noDojoDecoBuildStage: `Мгновенное Строительтво Декораций Додзё`,
|
cheats_noDojoDecoBuildStage: `Мгновенное Строительтво Декораций Додзё`,
|
||||||
cheats_fastDojoRoomDestruction: `Мгновенные Уничтожение Комнат Додзё`,
|
cheats_fastDojoRoomDestruction: `Мгновенные Уничтожение Комнат Додзё`,
|
||||||
|
@ -60,6 +60,7 @@ dict = {
|
|||||||
login_emailLabel: `电子邮箱`,
|
login_emailLabel: `电子邮箱`,
|
||||||
login_passwordLabel: `密码`,
|
login_passwordLabel: `密码`,
|
||||||
login_loginButton: `登录`,
|
login_loginButton: `登录`,
|
||||||
|
login_registerButton: `[UNTRANSLATED] Register`,
|
||||||
navbar_logout: `退出登录`,
|
navbar_logout: `退出登录`,
|
||||||
navbar_renameAccount: `重命名账户`,
|
navbar_renameAccount: `重命名账户`,
|
||||||
navbar_deleteAccount: `删除账户`,
|
navbar_deleteAccount: `删除账户`,
|
||||||
@ -115,6 +116,7 @@ dict = {
|
|||||||
mods_rivens: `裂罅MOD`,
|
mods_rivens: `裂罅MOD`,
|
||||||
mods_mods: `Mods`,
|
mods_mods: `Mods`,
|
||||||
mods_bulkAddMods: `添加缺失MOD`,
|
mods_bulkAddMods: `添加缺失MOD`,
|
||||||
|
mods_removeUnranked: `[UNTRANSLATED] Remove Unranked Mods`,
|
||||||
cheats_administratorRequirement: `您必须是管理员才能使用此功能。要成为管理员,请将 <code>|DISPLAYNAME|</code> 添加到 config.json 的 <code>administratorNames</code> 中。`,
|
cheats_administratorRequirement: `您必须是管理员才能使用此功能。要成为管理员,请将 <code>|DISPLAYNAME|</code> 添加到 config.json 的 <code>administratorNames</code> 中。`,
|
||||||
cheats_server: `服务器`,
|
cheats_server: `服务器`,
|
||||||
cheats_skipTutorial: `跳过教程`,
|
cheats_skipTutorial: `跳过教程`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user