Compare commits

...

19 Commits

Author SHA1 Message Date
956ba38b7d fix(webui): handle name already being taken at rename (#2659)
Closes #2643

Reviewed-on: OpenWF/SpaceNinjaServer#2659
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-17 13:12:40 -07:00
660c3f3ddf fix(webui): differentiate between nonce invalidation & forced logout (#2658)
Closes #2642

Reviewed-on: OpenWF/SpaceNinjaServer#2658
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-17 13:12:29 -07:00
024b806af1 feat(webui): display Favorite items first (#2656)
Closes #2653

Reviewed-on: OpenWF/SpaceNinjaServer#2656
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-17 13:12:06 -07:00
b885d7766c feat: warframe anniversary goals (#2640)
Also adds `useAnniversaryTagForOldGoals` to display old Goals in GUI
Re #1103

Reviewed-on: OpenWF/SpaceNinjaServer#2640
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-17 13:11:55 -07:00
d0743654dd feat: orphix venom (#2637)
Without rotation on last mission
Re #1103
Thanks to https://wiki.warframe.com/w/World_State/Example

Reviewed-on: OpenWF/SpaceNinjaServer#2637
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-16 09:52:58 -07:00
cddd2cdd2b chore: fix inconsistencies with getGuildEventScoreController (#2641)
bring it more in line with the rest of the codebase

Reviewed-on: OpenWF/SpaceNinjaServer#2641
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-16 09:52:36 -07:00
62a6042c9c fix(webui): save ProgressOverride value (#2638)
Reviewed-on: OpenWF/SpaceNinjaServer#2638
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-16 05:42:09 -07:00
e8d4d84d6e chore(webui): update uk (#2639)
Reviewed-on: OpenWF/SpaceNinjaServer#2639
Co-authored-by: LoseFace <loseface@noreply.localhost>
Co-committed-by: LoseFace <loseface@noreply.localhost>
2025-08-16 05:41:12 -07:00
62881aaa36 feat: articula customizations (#2636)
Reviewed-on: OpenWF/SpaceNinjaServer#2636
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-16 05:40:16 -07:00
df316e3a7a feat: conclave challenges rotation (#2635)
Re #1192

Reviewed-on: OpenWF/SpaceNinjaServer#2635
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-16 05:39:23 -07:00
264e9cfc98 fix: use flat rush cost at <50% progress (#2634)
otherwise the cost would be increased instead of decreased

Reviewed-on: OpenWF/SpaceNinjaServer#2634
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-16 05:39:00 -07:00
5d5554a80e feat: h-09 apex turret sumdali reward (#2633)
Closes #2630

Reviewed-on: OpenWF/SpaceNinjaServer#2633
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-16 05:38:48 -07:00
da14a4081b chore: put reward year into goal _id (#2626)
Closes #2623

Reviewed-on: OpenWF/SpaceNinjaServer#2626
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-15 21:02:15 -07:00
b0b68f474a feat: getShip import (#2627)
Re #2592
Unsure about import note, is it okay that we leave the API path?

Reviewed-on: OpenWF/SpaceNinjaServer#2627
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-15 15:13:34 -07:00
ab214df1a8 chore(webui): update ru & uk (#2632)
Updated and improved some translations

Reviewed-on: OpenWF/SpaceNinjaServer#2632
Co-authored-by: LoseFace <loseface@noreply.localhost>
Co-committed-by: LoseFace <loseface@noreply.localhost>
2025-08-15 14:57:04 -07:00
9f8105d7f1 fix: extractor drone reward amounts (#2629)
Fixes #2628

Reviewed-on: OpenWF/SpaceNinjaServer#2629
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: VampireKitten <dynamightkobold@gmail.com>
Co-committed-by: VampireKitten <dynamightkobold@gmail.com>
2025-08-15 14:56:39 -07:00
c47a29ec96 chore: note 2025-08-15 18:15:10 +02:00
6d727c50f4 chore: handle addItem of GhoulFragmentRewards (#2625)
Closes #2624

Reviewed-on: OpenWF/SpaceNinjaServer#2625
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
2025-08-15 08:15:51 -07:00
bf04755c36 feat: belly of the beast / eight claw (#2621)
Re #1103

Reviewed-on: OpenWF/SpaceNinjaServer#2621
Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com>
Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
2025-08-15 08:14:36 -07:00
48 changed files with 2257 additions and 724 deletions

View File

@ -59,7 +59,8 @@
"nightwaveStandingMultiplier": 1, "nightwaveStandingMultiplier": 1,
"unfaithfulBugFixes": { "unfaithfulBugFixes": {
"ignore1999LastRegionPlayed": false, "ignore1999LastRegionPlayed": false,
"fixXtraCheeseTimer": false "fixXtraCheeseTimer": false,
"useAnniversaryTagForOldGoals": true
}, },
"worldState": { "worldState": {
"creditBoost": false, "creditBoost": false,
@ -67,8 +68,10 @@
"resourceBoost": false, "resourceBoost": false,
"tennoLiveRelay": false, "tennoLiveRelay": false,
"wolfHunt": false, "wolfHunt": false,
"orphixVenom": false,
"longShadow": false, "longShadow": false,
"hallowedFlame": false, "hallowedFlame": false,
"anniversary": null,
"hallowedNightmares": false, "hallowedNightmares": false,
"hallowedNightmaresRewardsOverride": 0, "hallowedNightmaresRewardsOverride": 0,
"proxyRebellion": false, "proxyRebellion": false,
@ -79,6 +82,10 @@
"starDaysOverride": null, "starDaysOverride": null,
"dogDaysOverride": null, "dogDaysOverride": null,
"dogDaysRewardsOverride": null, "dogDaysRewardsOverride": null,
"bellyOfTheBeast": false,
"bellyOfTheBeastProgressOverride": 0,
"eightClaw": false,
"eightClawProgressOverride": 0,
"eidolonOverride": "", "eidolonOverride": "",
"vallisOverride": "", "vallisOverride": "",
"duviriOverride": "", "duviriOverride": "",

8
package-lock.json generated
View File

@ -23,7 +23,7 @@
"ncp": "^2.0.0", "ncp": "^2.0.0",
"typescript": "^5.5", "typescript": "^5.5",
"undici": "^7.10.0", "undici": "^7.10.0",
"warframe-public-export-plus": "^0.5.80", "warframe-public-export-plus": "^0.5.81",
"warframe-riven-info": "^0.1.2", "warframe-riven-info": "^0.1.2",
"winston": "^3.17.0", "winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0", "winston-daily-rotate-file": "^5.0.0",
@ -5507,9 +5507,9 @@
} }
}, },
"node_modules/warframe-public-export-plus": { "node_modules/warframe-public-export-plus": {
"version": "0.5.80", "version": "0.5.81",
"resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.80.tgz", "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.81.tgz",
"integrity": "sha512-K5f1Ws3szVdnO0tBcxlNdhXoGHIw09cjHel7spKPGL7aF/vmEkbBGRmYQFvs8n5cGo+v+3qIDMre54Ghb3t0Iw==" "integrity": "sha512-kh3e21XThVDSwdC3TJsMsXZnlZ4B/21HdeJkKcjuTygpCd842EPEKS3lRZl3mpXFOmdha744vAW1XEyHfiLofg=="
}, },
"node_modules/warframe-riven-info": { "node_modules/warframe-riven-info": {
"version": "0.1.2", "version": "0.1.2",

View File

@ -40,7 +40,7 @@
"ncp": "^2.0.0", "ncp": "^2.0.0",
"typescript": "^5.5", "typescript": "^5.5",
"undici": "^7.10.0", "undici": "^7.10.0",
"warframe-public-export-plus": "^0.5.80", "warframe-public-export-plus": "^0.5.81",
"warframe-riven-info": "^0.1.2", "warframe-riven-info": "^0.1.2",
"winston": "^3.17.0", "winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0", "winston-daily-rotate-file": "^5.0.0",

View File

@ -102,7 +102,10 @@ export const claimCompletedRecipeController: RequestHandler = async (req, res) =
const secondsElapsed = Math.trunc(Date.now() / 1000) - start; const secondsElapsed = Math.trunc(Date.now() / 1000) - start;
const progress = secondsElapsed / recipe.buildTime; const progress = secondsElapsed / recipe.buildTime;
logger.debug(`rushing recipe at ${Math.trunc(progress * 100)}% completion`); logger.debug(`rushing recipe at ${Math.trunc(progress * 100)}% completion`);
const cost = Math.round(recipe.skipBuildTimePrice * (1 - (progress - 0.5))); const cost =
progress > 0.5
? Math.round(recipe.skipBuildTimePrice * (1 - (progress - 0.5)))
: recipe.skipBuildTimePrice;
InventoryChanges = { InventoryChanges = {
...InventoryChanges, ...InventoryChanges,
...updateCurrency(inventory, cost, true) ...updateCurrency(inventory, cost, true)

View File

@ -72,7 +72,7 @@ export const dronesController: RequestHandler = async (req, res) => {
); );
} }
} else { } else {
drone.ResourceCount = 1; drone.ResourceCount = droneMeta.binCapacity * droneMeta.capacityMultipliers[resource.Rarity];
} }
await inventory.save(); await inventory.save();
res.json({}); res.json({});

View File

@ -0,0 +1,26 @@
import { RequestHandler } from "express";
import { getAccountForRequest } from "@/src/services/loginService";
import { getInventory } from "@/src/services/inventoryService";
import { Guild } from "@/src/models/guildModel";
export const getGuildEventScoreController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req);
const inventory = await getInventory(account._id.toString(), "GuildId");
const guild = await Guild.findById(inventory.GuildId);
const goalId = req.query.goalId as string;
if (guild && guild.GoalProgress && goalId) {
const goal = guild.GoalProgress.find(x => x.goalId.toString() == goalId);
if (goal) {
res.json({
Tier: guild.Tier,
GoalProgress: {
Count: goal.Count,
Tag: goal.Tag,
_id: { $oid: goal.goalId }
}
});
return;
}
}
res.json({});
};

View File

@ -12,7 +12,7 @@ export const hubBlessingController: RequestHandler = async (req, res) => {
if (req.query.mode == "send") { if (req.query.mode == "send") {
const inventory = await getInventory(accountId, "BlessingCooldown Boosters"); const inventory = await getInventory(accountId, "BlessingCooldown Boosters");
inventory.BlessingCooldown = new Date(Date.now() + 86400000); inventory.BlessingCooldown = new Date(Date.now() + 86400000);
addBooster(boosterType, 3 * 3600, inventory); addBooster(boosterType, 3 * 3600, inventory); // unfaithful, but current HUB server does not handle broadcasting, so this way users can bless themselves.
await inventory.save(); await inventory.save();
let token = ""; let token = "";

View File

@ -88,8 +88,7 @@ export const loginController: RequestHandler = async (request, response) => {
account.LastLogin = new Date(); account.LastLogin = new Date();
await account.save(); await account.save();
// Tell WebUI its nonce has been invalidated sendWsBroadcastTo(account._id.toString(), { nonce_updated: true });
sendWsBroadcastTo(account._id.toString(), { logged_out: true });
response.json(createLoginResponse(myAddress, myUrlBase, account.toJSON(), buildLabel)); response.json(createLoginResponse(myAddress, myUrlBase, account.toJSON(), buildLabel));
}; };

View File

@ -21,8 +21,7 @@ export const logoutController: RequestHandler = async (req, res) => {
} }
); );
if (stat.modifiedCount) { if (stat.modifiedCount) {
// Tell WebUI its nonce has been invalidated sendWsBroadcastTo(req.query.accountId as string, { nonce_updated: true });
sendWsBroadcastTo(req.query.accountId as string, { logged_out: true });
} }
res.writeHead(200, { res.writeHead(200, {

View File

@ -1,23 +1,19 @@
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/personalRoomsTypes"; import { ISetPlacedDecoInfoRequest } from "@/src/types/personalRoomsTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService"; import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService";
export const setPlacedDecoInfoController: RequestHandler = async (req, res) => { export const setPlacedDecoInfoController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const payload = JSON.parse(req.body as string) as ISetPlacedDecoInfoRequest; const payload = JSON.parse(req.body as string) as ISetPlacedDecoInfoRequest;
//console.log(JSON.stringify(payload, null, 2));
await handleSetPlacedDecoInfo(accountId, payload); await handleSetPlacedDecoInfo(accountId, payload);
res.json({ res.json({
DecoId: payload.DecoId, ...payload,
IsPicture: true, IsPicture: !!payload.PictureFrameInfo
PictureFrameInfo: payload.PictureFrameInfo,
BootLocation: payload.BootLocation
} satisfies ISetPlacedDecoInfoResponse); } satisfies ISetPlacedDecoInfoResponse);
}; };
interface ISetPlacedDecoInfoResponse { interface ISetPlacedDecoInfoResponse extends ISetPlacedDecoInfoRequest {
DecoId: string;
IsPicture: boolean; IsPicture: boolean;
PictureFrameInfo?: IPictureFrameInfo;
BootLocation?: string;
} }

View File

@ -1,8 +1,10 @@
import { importInventory, importLoadOutPresets } from "@/src/services/importService"; import { importInventory, importLoadOutPresets, importPersonalRooms } from "@/src/services/importService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
import { getLoadout } from "@/src/services/loadoutService"; import { getLoadout } from "@/src/services/loadoutService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { getPersonalRooms } from "@/src/services/personalRoomsService";
import { IInventoryClient } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryClient } from "@/src/types/inventoryTypes/inventoryTypes";
import { IGetShipResponse } from "@/src/types/personalRoomsTypes";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
export const importController: RequestHandler = async (req, res) => { export const importController: RequestHandler = async (req, res) => {
@ -13,15 +15,21 @@ export const importController: RequestHandler = async (req, res) => {
importInventory(inventory, request.inventory); importInventory(inventory, request.inventory);
await inventory.save(); await inventory.save();
if (request.inventory.LoadOutPresets) { if ("LoadOutPresets" in request.inventory && request.inventory.LoadOutPresets) {
const loadout = await getLoadout(accountId); const loadout = await getLoadout(accountId);
importLoadOutPresets(loadout, request.inventory.LoadOutPresets); importLoadOutPresets(loadout, request.inventory.LoadOutPresets);
await loadout.save(); await loadout.save();
} }
if ("Ship" in request.inventory || "Apartment" in request.inventory || "TailorShop" in request.inventory) {
const personalRooms = await getPersonalRooms(accountId);
importPersonalRooms(personalRooms, request.inventory);
await personalRooms.save();
}
res.end(); res.end();
}; };
interface IImportRequest { interface IImportRequest {
inventory: Partial<IInventoryClient>; inventory: Partial<IInventoryClient> | Partial<IGetShipResponse>;
} }

View File

@ -19,6 +19,8 @@ import {
import { Document, Model, model, Schema, Types } from "mongoose"; import { Document, Model, model, Schema, Types } from "mongoose";
import { fusionTreasuresSchema, typeCountSchema } from "@/src/models/inventoryModels/inventoryModel"; import { fusionTreasuresSchema, typeCountSchema } from "@/src/models/inventoryModels/inventoryModel";
import { pictureFrameInfoSchema } from "@/src/models/personalRoomsModel"; import { pictureFrameInfoSchema } from "@/src/models/personalRoomsModel";
import { IGoalProgressClient, IGoalProgressDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
import { toOid } from "@/src/helpers/inventoryHelpers";
const dojoDecoSchema = new Schema<IDojoDecoDatabase>({ const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
Type: String, Type: String,
@ -174,6 +176,28 @@ const guildLogEntryNumberSchema = new Schema<IGuildLogEntryNumber>(
{ _id: false } { _id: false }
); );
const goalProgressSchema = new Schema<IGoalProgressDatabase>(
{
Count: Number,
Tag: String,
goalId: Types.ObjectId
},
{ _id: false }
);
goalProgressSchema.set("toJSON", {
virtuals: true,
transform(_doc, obj: Record<string, any>) {
const db = obj as IGoalProgressDatabase;
const client = obj as IGoalProgressClient;
client._id = toOid(db.goalId);
delete obj.goalId;
delete obj.__v;
}
});
const guildSchema = new Schema<IGuildDatabase>( const guildSchema = new Schema<IGuildDatabase>(
{ {
Name: { type: String, required: true, unique: true }, Name: { type: String, required: true, unique: true },
@ -206,7 +230,8 @@ const guildSchema = new Schema<IGuildDatabase>(
RoomChanges: { type: [guildLogRoomChangeSchema], default: undefined }, RoomChanges: { type: [guildLogRoomChangeSchema], default: undefined },
TechChanges: { type: [guildLogEntryContributableSchema], default: undefined }, TechChanges: { type: [guildLogEntryContributableSchema], default: undefined },
RosterActivity: { type: [guildLogEntryRosterSchema], default: undefined }, RosterActivity: { type: [guildLogEntryRosterSchema], default: undefined },
ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined } ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined },
GoalProgress: { type: [goalProgressSchema], default: undefined }
}, },
{ id: false } { id: false }
); );

View File

@ -85,8 +85,8 @@ import {
IAccolades, IAccolades,
IHubNpcCustomization, IHubNpcCustomization,
IEndlessXpReward, IEndlessXpReward,
IPersonalGoalProgressDatabase, IGoalProgressDatabase,
IPersonalGoalProgressClient, IGoalProgressClient,
IKubrowPetPrintClient, IKubrowPetPrintClient,
IKubrowPetPrintDatabase IKubrowPetPrintDatabase
} from "@/src/types/inventoryTypes/inventoryTypes"; } from "@/src/types/inventoryTypes/inventoryTypes";
@ -445,7 +445,7 @@ const discoveredMarkerSchema = new Schema<IDiscoveredMarker>(
{ _id: false } { _id: false }
); );
const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>( const personalGoalProgressSchema = new Schema<IGoalProgressDatabase>(
{ {
Best: Number, Best: Number,
Count: Number, Count: Number,
@ -458,8 +458,8 @@ const personalGoalProgressSchema = new Schema<IPersonalGoalProgressDatabase>(
personalGoalProgressSchema.set("toJSON", { personalGoalProgressSchema.set("toJSON", {
virtuals: true, virtuals: true,
transform(_doc, obj: Record<string, any>) { transform(_doc, obj: Record<string, any>) {
const db = obj as IPersonalGoalProgressDatabase; const db = obj as IGoalProgressDatabase;
const client = obj as IPersonalGoalProgressClient; const client = obj as IGoalProgressClient;
client._id = toOid(db.goalId); client._id = toOid(db.goalId);

View File

@ -25,7 +25,7 @@ export const EquipmentSelectionSchema = new Schema<IEquipmentSelection>(
} }
); );
const loadoutConfigSchema = new Schema<ILoadoutConfigDatabase>( export const loadoutConfigSchema = new Schema<ILoadoutConfigDatabase>(
{ {
FocusSchool: String, FocusSchool: String,
PresetIcon: String, PresetIcon: String,

View File

@ -8,7 +8,7 @@ const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
displayName: { type: String, required: true }, displayName: { type: String, required: true },
score: { type: Number, required: true }, score: { type: Number, required: true },
guildId: Schema.Types.ObjectId, guildId: Schema.Types.ObjectId,
expiry: { type: Date, required: true }, expiry: Date,
guildTier: Number guildTier: Number
}, },
{ id: false } { id: false }

View File

@ -1,6 +1,7 @@
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
import { import {
IApartmentDatabase, IApartmentDatabase,
ICustomizationInfoDatabase,
IFavouriteLoadoutDatabase, IFavouriteLoadoutDatabase,
IGardeningDatabase, IGardeningDatabase,
IOrbiterClient, IOrbiterClient,
@ -11,12 +12,13 @@ import {
IPlantClient, IPlantClient,
IPlantDatabase, IPlantDatabase,
IPlanterDatabase, IPlanterDatabase,
IRoom, IRoomDatabase,
ITailorShopDatabase, ITailorShopDatabase,
PersonalRoomsModelType PersonalRoomsModelType
} from "@/src/types/personalRoomsTypes"; } from "@/src/types/personalRoomsTypes";
import { Schema, Types, model } from "mongoose"; import { Schema, Types, model } from "mongoose";
import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel"; import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel";
import { loadoutConfigSchema } from "@/src/models/inventoryModels/loadoutModel";
export const pictureFrameInfoSchema = new Schema<IPictureFrameInfo>( export const pictureFrameInfoSchema = new Schema<IPictureFrameInfo>(
{ {
@ -34,7 +36,20 @@ export const pictureFrameInfoSchema = new Schema<IPictureFrameInfo>(
TextColorB: Number, TextColorB: Number,
TextOrientation: Number TextOrientation: Number
}, },
{ id: false, _id: false } { _id: false }
);
export const customizationInfoSchema = new Schema<ICustomizationInfoDatabase>(
{
Anim: String,
AnimPose: Number,
LoadOutPreset: loadoutConfigSchema,
VehiclePreset: loadoutConfigSchema,
EquippedWeapon: String,
AvatarType: String,
LoadOutType: String
},
{ _id: false }
); );
const placedDecosSchema = new Schema<IPlacedDecosDatabase>( const placedDecosSchema = new Schema<IPlacedDecosDatabase>(
@ -44,7 +59,9 @@ const placedDecosSchema = new Schema<IPlacedDecosDatabase>(
Rot: [Number], Rot: [Number],
Scale: Number, Scale: Number,
Sockets: Number, Sockets: Number,
PictureFrameInfo: { type: pictureFrameInfoSchema, default: undefined } PictureFrameInfo: { type: pictureFrameInfoSchema, default: undefined },
CustomizationInfo: { type: customizationInfoSchema, default: undefined },
AnimPoseItem: String
}, },
{ id: false } { id: false }
); );
@ -60,7 +77,7 @@ placedDecosSchema.set("toJSON", {
} }
}); });
const roomSchema = new Schema<IRoom>( const roomSchema = new Schema<IRoomDatabase>(
{ {
Name: String, Name: String,
MaxCapacity: Number, MaxCapacity: Number,

View File

@ -97,7 +97,19 @@ const statsSchema = new Schema<IStatsDatabase>({
SentinelGameScore: Number, SentinelGameScore: Number,
CaliberChicksScore: Number, CaliberChicksScore: Number,
OlliesCrashCourseScore: Number, OlliesCrashCourseScore: Number,
DojoObstacleScore: Number DojoObstacleScore: Number,
Halloween16: Number,
AmalgamEventScoreMax: Number,
Halloween19ScoreMax: Number,
FlotillaEventScore: Number,
FlotillaSpaceBadgesTier1: Number,
FlotillaSpaceBadgesTier2: Number,
FlotillaSpaceBadgesTier3: Number,
FlotillaGroundBadgesTier1: Number,
FlotillaGroundBadgesTier2: Number,
FlotillaGroundBadgesTier3: Number,
MechSurvivalScoreMax: Number
}); });
statsSchema.set("toJSON", { statsSchema.set("toJSON", {

View File

@ -62,6 +62,7 @@ import { getFriendsController } from "@/src/controllers/api/getFriendsController
import { getGuildContributionsController } from "@/src/controllers/api/getGuildContributionsController"; import { getGuildContributionsController } from "@/src/controllers/api/getGuildContributionsController";
import { getGuildController } from "@/src/controllers/api/getGuildController"; import { getGuildController } from "@/src/controllers/api/getGuildController";
import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController"; import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoController";
import { getGuildEventScoreController } from "@/src/controllers/api/getGuildEventScoreController";
import { getGuildLogController } from "@/src/controllers/api/getGuildLogController"; import { getGuildLogController } from "@/src/controllers/api/getGuildLogController";
import { getIgnoredUsersController } from "@/src/controllers/api/getIgnoredUsersController"; import { getIgnoredUsersController } from "@/src/controllers/api/getIgnoredUsersController";
import { getNewRewardSeedController } from "@/src/controllers/api/getNewRewardSeedController"; import { getNewRewardSeedController } from "@/src/controllers/api/getNewRewardSeedController";
@ -192,6 +193,7 @@ apiRouter.get("/getFriends.php", getFriendsController);
apiRouter.get("/getGuild.php", getGuildController); apiRouter.get("/getGuild.php", getGuildController);
apiRouter.get("/getGuildContributions.php", getGuildContributionsController); apiRouter.get("/getGuildContributions.php", getGuildContributionsController);
apiRouter.get("/getGuildDojo.php", getGuildDojoController); apiRouter.get("/getGuildDojo.php", getGuildDojoController);
apiRouter.get("/getGuildEventScore.php", getGuildEventScoreController);
apiRouter.get("/getGuildLog.php", getGuildLogController); apiRouter.get("/getGuildLog.php", getGuildLogController);
apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController); apiRouter.get("/getIgnoredUsers.php", getIgnoredUsersController);
apiRouter.get("/getMessages.php", inboxController); // unsure if this is correct, but needed for U17 apiRouter.get("/getMessages.php", inboxController); // unsure if this is correct, but needed for U17

View File

@ -8,5 +8,6 @@ const statsRouter = express.Router();
statsRouter.get("/view.php", viewController); statsRouter.get("/view.php", viewController);
statsRouter.post("/upload.php", uploadController); statsRouter.post("/upload.php", uploadController);
statsRouter.post("/leaderboardWeekly.php", leaderboardController); statsRouter.post("/leaderboardWeekly.php", leaderboardController);
statsRouter.post("/leaderboardArchived.php", leaderboardController);
export { statsRouter }; export { statsRouter };

View File

@ -71,6 +71,7 @@ export interface IConfig {
unfaithfulBugFixes?: { unfaithfulBugFixes?: {
ignore1999LastRegionPlayed?: boolean; ignore1999LastRegionPlayed?: boolean;
fixXtraCheeseTimer?: boolean; fixXtraCheeseTimer?: boolean;
useAnniversaryTagForOldGoals?: boolean;
}; };
worldState?: { worldState?: {
creditBoost?: boolean; creditBoost?: boolean;
@ -79,8 +80,10 @@ export interface IConfig {
tennoLiveRelay?: boolean; tennoLiveRelay?: boolean;
baroTennoConRelay?: boolean; baroTennoConRelay?: boolean;
wolfHunt?: boolean; wolfHunt?: boolean;
orphixVenom?: boolean;
longShadow?: boolean; longShadow?: boolean;
hallowedFlame?: boolean; hallowedFlame?: boolean;
anniversary?: number;
hallowedNightmares?: boolean; hallowedNightmares?: boolean;
hallowedNightmaresRewardsOverride?: number; hallowedNightmaresRewardsOverride?: number;
proxyRebellion?: boolean; proxyRebellion?: boolean;
@ -91,6 +94,10 @@ export interface IConfig {
starDaysOverride?: boolean; starDaysOverride?: boolean;
dogDaysOverride?: boolean; dogDaysOverride?: boolean;
dogDaysRewardsOverride?: number; dogDaysRewardsOverride?: number;
bellyOfTheBeast?: boolean;
bellyOfTheBeastProgressOverride?: number;
eightClaw?: boolean;
eightClawProgressOverride?: number;
eidolonOverride?: string; eidolonOverride?: string;
vallisOverride?: string; vallisOverride?: string;
duviriOverride?: string; duviriOverride?: string;

View File

@ -115,7 +115,14 @@ export const getGuildClient = async (
NumContributors: guild.CeremonyContributors?.length ?? 0, NumContributors: guild.CeremonyContributors?.length ?? 0,
CeremonyResetDate: guild.CeremonyResetDate ? toMongoDate(guild.CeremonyResetDate) : undefined, CeremonyResetDate: guild.CeremonyResetDate ? toMongoDate(guild.CeremonyResetDate) : undefined,
AutoContributeFromVault: guild.AutoContributeFromVault, AutoContributeFromVault: guild.AutoContributeFromVault,
AllianceId: guild.AllianceId ? toOid2(guild.AllianceId, account.BuildLabel) : undefined AllianceId: guild.AllianceId ? toOid2(guild.AllianceId, account.BuildLabel) : undefined,
GoalProgress: guild.GoalProgress
? guild.GoalProgress.map(gp => ({
Count: gp.Count,
Tag: gp.Tag,
_id: { $oid: gp.goalId.toString() }
}))
: undefined
}; };
}; };
@ -809,3 +816,100 @@ export const getAllianceClient = async (
} }
}; };
}; };
export const handleGuildGoalProgress = async (
guild: TGuildDatabaseDocument,
upload: { Count: number; Tag: string; goalId: Types.ObjectId }
): Promise<void> => {
guild.GoalProgress ??= [];
const goalProgress = guild.GoalProgress.find(x => x.goalId.equals(upload.goalId));
if (!goalProgress) {
guild.GoalProgress.push({
Count: upload.Count,
Tag: upload.Tag,
goalId: upload.goalId
});
}
const totalCount = (goalProgress?.Count ?? 0) + upload.Count;
const guildRewards = goalGuildRewardByTag[upload.Tag].rewards;
const tierGoals = goalGuildRewardByTag[upload.Tag].guildGoals[guild.Tier - 1];
const rewards = [];
if (tierGoals.length && guildRewards.length) {
for (let i = 0; i < tierGoals.length; i++) {
if (
tierGoals[i] &&
tierGoals[i] <= totalCount &&
(!goalProgress || goalProgress.Count < tierGoals[i]) &&
guildRewards[i]
) {
rewards.push(guildRewards[i]);
}
}
if (rewards.length) {
logger.debug(`guild goal rewards`, rewards);
guild.VaultDecoRecipes ??= [];
rewards.forEach(type => {
guild.VaultDecoRecipes!.push({
ItemType: type,
ItemCount: 1
});
});
}
}
if (goalProgress) {
goalProgress.Count += upload.Count;
}
await guild.save();
};
export const goalGuildRewardByTag: Record<string, { guildGoals: number[][]; rewards: string[] }> = {
JadeShadowsEvent: {
guildGoals: [
// I don't know what ClanGoal means
[15, 30, 45, 60],
[45, 90, 135, 180],
[150, 300, 450, 600],
[450, 900, 1350, 1800],
[1500, 3000, 4500, 6000]
],
rewards: [
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventPewterTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventBronzeTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventSilverTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/JadeShadowsEventGoldTrophyRecipe"
]
},
DuviriMurmurEvent: {
guildGoals: [
// I don't know what ClanGoal means
[260, 519, 779, 1038],
[779, 1557, 2336, 3114],
[2595, 5190, 7785, 10380],
[7785, 15570, 23355, 31140],
[29950, 51900, 77850, 103800]
],
rewards: [
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventClayTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventBronzeTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventSilverTrophyRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/DuviriMurmurEventGoldTrophyRecipe"
]
},
MechSurvival: {
guildGoals: [
[1390, 5860, 13920, 18850],
[3510, 22275, 69120, 137250],
[11700, 75250, 230400, 457500],
[35100, 222750, 691200, 1372500],
[117000, 742500, 2304000, 4575000]
],
rewards: [
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophyTerracottaRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophyBronzeRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophySilverRecipe",
"/Lotus/Levels/ClanDojo/ComponentPropRecipes/MechEventTrophyGoldRecipe"
]
}
};

View File

@ -44,6 +44,28 @@ import {
IKubrowPetDetailsClient, IKubrowPetDetailsClient,
IKubrowPetDetailsDatabase IKubrowPetDetailsDatabase
} from "@/src/types/equipmentTypes"; } from "@/src/types/equipmentTypes";
import {
IApartmentClient,
IApartmentDatabase,
ICustomizationInfoClient,
ICustomizationInfoDatabase,
IFavouriteLoadout,
IFavouriteLoadoutDatabase,
IGetShipResponse,
IOrbiterClient,
IOrbiterDatabase,
IPersonalRoomsDatabase,
IPlacedDecosClient,
IPlacedDecosDatabase,
IPlantClient,
IPlantDatabase,
IPlanterClient,
IPlanterDatabase,
IRoomClient,
IRoomDatabase,
ITailorShop,
ITailorShopDatabase
} from "@/src/types/personalRoomsTypes";
const convertDate = (value: IMongoDate): Date => { const convertDate = (value: IMongoDate): Date => {
return new Date(parseInt(value.$date.$numberLong)); return new Date(parseInt(value.$date.$numberLong));
@ -429,3 +451,84 @@ export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPrese
db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(convertLoadOutConfig); db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(convertLoadOutConfig);
db.DRIFTER = client.DRIFTER.map(convertLoadOutConfig); db.DRIFTER = client.DRIFTER.map(convertLoadOutConfig);
}; };
export const convertCustomizationInfo = (client: ICustomizationInfoClient): ICustomizationInfoDatabase => {
return {
...client,
LoadOutPreset: client.LoadOutPreset ? convertLoadOutConfig(client.LoadOutPreset) : undefined,
VehiclePreset: client.VehiclePreset ? convertLoadOutConfig(client.VehiclePreset) : undefined
};
};
const convertDeco = (client: IPlacedDecosClient): IPlacedDecosDatabase => {
const { id, ...rest } = client;
return {
...rest,
CustomizationInfo: client.CustomizationInfo ? convertCustomizationInfo(client.CustomizationInfo) : undefined,
_id: new Types.ObjectId(id.$oid)
};
};
const convertRoom = (client: IRoomClient): IRoomDatabase => {
return {
...client,
PlacedDecos: client.PlacedDecos ? client.PlacedDecos.map(convertDeco) : []
};
};
const convertShip = (client: IOrbiterClient): IOrbiterDatabase => {
return {
...client,
ShipInterior: {
...client.ShipInterior,
Colors: Array.isArray(client.ShipInterior.Colors) ? {} : client.ShipInterior.Colors
},
Rooms: client.Rooms.map(convertRoom),
FavouriteLoadoutId: client.FavouriteLoadoutId ? new Types.ObjectId(client.FavouriteLoadoutId.$oid) : undefined
};
};
const convertPlant = (client: IPlantClient): IPlantDatabase => {
return {
...client,
EndTime: convertDate(client.EndTime)
};
};
const convertPlanter = (client: IPlanterClient): IPlanterDatabase => {
return {
...client,
Plants: client.Plants.map(convertPlant)
};
};
const convertFavouriteLoadout = (client: IFavouriteLoadout): IFavouriteLoadoutDatabase => {
return {
...client,
LoadoutId: new Types.ObjectId(client.LoadoutId.$oid)
};
};
const convertApartment = (client: IApartmentClient): IApartmentDatabase => {
return {
...client,
Rooms: client.Rooms.map(convertRoom),
Gardening: { Planters: client.Gardening.Planters.map(convertPlanter) },
FavouriteLoadouts: client.FavouriteLoadouts ? client.FavouriteLoadouts.map(convertFavouriteLoadout) : []
};
};
const convertTailorShop = (client: ITailorShop): ITailorShopDatabase => {
return {
...client,
Rooms: client.Rooms.map(convertRoom),
Colors: Array.isArray(client.Colors) ? {} : client.Colors,
FavouriteLoadouts: client.FavouriteLoadouts ? client.FavouriteLoadouts.map(convertFavouriteLoadout) : []
};
};
export const importPersonalRooms = (db: IPersonalRoomsDatabase, client: Partial<IGetShipResponse>): void => {
if (client.Ship !== undefined) db.Ship = convertShip(client.Ship);
if (client.Apartment !== undefined) db.Apartment = convertApartment(client.Apartment);
if (client.TailorShop !== undefined) db.TailorShop = convertTailorShop(client.TailorShop);
};

View File

@ -847,6 +847,32 @@ export const addItem = async (
return addMotorcycle(inventory, typeName); return addMotorcycle(inventory, typeName);
} }
break; break;
case "Lore":
if (typeName == "/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentRewards") {
const fragmentType = getRandomElement([
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentA",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentB",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentC",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentD",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentE",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentF",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentG",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentH",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentI",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentJ",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentK",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentL",
"/Lotus/Types/Lore/Fragments/GrineerGhoulFragments/GhoulFragmentM"
])!;
addLoreFragmentScans(inventory, [
{
Progress: 1,
Region: "",
ItemType: fragmentType
}
]);
}
break;
} }
break; break;
} }

View File

@ -1,38 +1,66 @@
import { Guild } from "@/src/models/guildModel"; import { Guild } from "@/src/models/guildModel";
import { Leaderboard, TLeaderboardEntryDocument } from "@/src/models/leaderboardModel"; import { Leaderboard, TLeaderboardEntryDocument } from "@/src/models/leaderboardModel";
import { ILeaderboardEntryClient } from "@/src/types/leaderboardTypes"; import { ILeaderboardEntryClient } from "@/src/types/leaderboardTypes";
import { handleGuildGoalProgress } from "@/src/services/guildService";
import { getWorldState } from "@/src/services/worldStateService";
import { Types } from "mongoose";
export const submitLeaderboardScore = async ( export const submitLeaderboardScore = async (
schedule: "weekly" | "daily", schedule: "weekly" | "daily" | "events",
leaderboard: string, leaderboard: string,
ownerId: string, ownerId: string,
displayName: string, displayName: string,
score: number, score: number,
guildId: string | undefined guildId: string | undefined
): Promise<void> => { ): Promise<void> => {
let expiry: Date; let expiry: Date | undefined;
if (schedule == "daily") { if (schedule == "daily") {
expiry = new Date(Math.trunc(Date.now() / 86400000) * 86400000 + 86400000); expiry = new Date(Math.trunc(Date.now() / 86400000) * 86400000 + 86400000);
} else { } else if (schedule == "weekly") {
const EPOCH = 1734307200 * 1000; // Monday const EPOCH = 1734307200 * 1000; // Monday
const week = Math.trunc((Date.now() - EPOCH) / 604800000); const week = Math.trunc((Date.now() - EPOCH) / 604800000);
const weekStart = EPOCH + week * 604800000; const weekStart = EPOCH + week * 604800000;
const weekEnd = weekStart + 604800000; const weekEnd = weekStart + 604800000;
expiry = new Date(weekEnd); expiry = new Date(weekEnd);
} }
if (guildId) {
const guild = (await Guild.findById(guildId, "Name Tier GoalProgress VaultDecoRecipes"))!;
if (schedule == "events") {
const prevAccount = await Leaderboard.findOne(
{ leaderboard: `${schedule}.accounts.${leaderboard}`, ownerId },
"score"
);
const delta = score - (prevAccount?.score ?? 0);
if (delta > 0) {
await Leaderboard.findOneAndUpdate(
{ leaderboard: `${schedule}.guilds.${leaderboard}`, ownerId: guildId },
{ $inc: { score: delta }, $set: { displayName: guild.Name, guildTier: guild.Tier } },
{ upsert: true }
);
const goal = getWorldState().Goals.find(x => x.ScoreMaxTag == leaderboard);
if (goal) {
await handleGuildGoalProgress(guild, {
Count: delta,
Tag: goal.Tag,
goalId: new Types.ObjectId(goal._id.$oid)
});
}
}
} else {
await Leaderboard.findOneAndUpdate(
{ leaderboard: `${schedule}.guilds.${leaderboard}`, ownerId: guildId },
{ $max: { score }, $set: { displayName: guild.Name, guildTier: guild.Tier, expiry } },
{ upsert: true, new: true }
);
}
}
await Leaderboard.findOneAndUpdate( await Leaderboard.findOneAndUpdate(
{ leaderboard: `${schedule}.accounts.${leaderboard}`, ownerId }, { leaderboard: `${schedule}.accounts.${leaderboard}`, ownerId },
{ $max: { score }, $set: { displayName, guildId, expiry } }, { $max: { score }, $set: { displayName, guildId, expiry } },
{ upsert: true } { upsert: true }
); );
if (guildId) {
const guild = (await Guild.findById(guildId, "Name Tier"))!;
await Leaderboard.findOneAndUpdate(
{ leaderboard: `${schedule}.guilds.${leaderboard}`, ownerId: guildId },
{ $max: { score }, $set: { displayName: guild.Name, guildTier: guild.Tier, expiry } },
{ upsert: true }
);
}
}; };
export const getLeaderboard = async ( export const getLeaderboard = async (
@ -43,6 +71,7 @@ export const getLeaderboard = async (
guildId: string | undefined, guildId: string | undefined,
guildTier: number | undefined guildTier: number | undefined
): Promise<ILeaderboardEntryClient[]> => { ): Promise<ILeaderboardEntryClient[]> => {
leaderboard = leaderboard.replace("archived", guildTier || guildId ? "events.guilds" : "events.accounts");
const filter: { leaderboard: string; guildId?: string; guildTier?: number } = { leaderboard }; const filter: { leaderboard: string; guildId?: string; guildTier?: number } = { leaderboard };
if (guildId) { if (guildId) {
filter.guildId = guildId; filter.guildId = guildId;

View File

@ -81,6 +81,8 @@ import { fromOid } from "@/src/helpers/inventoryHelpers";
import { TAccountDocument } from "@/src/services/loginService"; import { TAccountDocument } from "@/src/services/loginService";
import { ITypeCount } from "@/src/types/commonTypes"; import { ITypeCount } from "@/src/types/commonTypes";
import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { IEquipmentClient } from "@/src/types/equipmentTypes";
import { Guild } from "@/src/models/guildModel";
import { handleGuildGoalProgress } from "@/src/services/guildService";
const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => { const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => {
// Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599) // Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599)
@ -650,7 +652,12 @@ export const addMissionInventoryUpdates = async (
} }
} }
if (currentMissionKey && currentMissionKey in goalMessagesByKey) { if (currentMissionKey && currentMissionKey in goalMessagesByKey) {
const totalCount = (goalProgress?.Count ?? 0) + uploadProgress.Count; let countBeforeUpload = goalProgress?.Count ?? 0;
let totalCount = countBeforeUpload + uploadProgress.Count;
if (goal.Best) {
countBeforeUpload = goalProgress?.Best ?? 0;
totalCount = uploadProgress.Best;
}
let reward; let reward;
if (goal.InterimGoals && goal.InterimRewards) { if (goal.InterimGoals && goal.InterimRewards) {
@ -658,7 +665,7 @@ export const addMissionInventoryUpdates = async (
if ( if (
goal.InterimGoals[i] && goal.InterimGoals[i] &&
goal.InterimGoals[i] <= totalCount && goal.InterimGoals[i] <= totalCount &&
(!goalProgress || goalProgress.Count < goal.InterimGoals[i]) && (!goalProgress || countBeforeUpload < goal.InterimGoals[i]) &&
goal.InterimRewards[i] goal.InterimRewards[i]
) { ) {
reward = goal.InterimRewards[i]; reward = goal.InterimRewards[i];
@ -670,7 +677,7 @@ export const addMissionInventoryUpdates = async (
!reward && !reward &&
goal.Goal && goal.Goal &&
goal.Goal <= totalCount && goal.Goal <= totalCount &&
(!goalProgress || goalProgress.Count < goal.Goal) && (!goalProgress || countBeforeUpload < goal.Goal) &&
goal.Reward goal.Reward
) { ) {
reward = goal.Reward; reward = goal.Reward;
@ -679,7 +686,7 @@ export const addMissionInventoryUpdates = async (
!reward && !reward &&
goal.BonusGoal && goal.BonusGoal &&
goal.BonusGoal <= totalCount && goal.BonusGoal <= totalCount &&
(!goalProgress || goalProgress.Count < goal.BonusGoal) && (!goalProgress || countBeforeUpload < goal.BonusGoal) &&
goal.BonusReward goal.BonusReward
) { ) {
reward = goal.BonusReward; reward = goal.BonusReward;
@ -705,6 +712,20 @@ export const addMissionInventoryUpdates = async (
if (reward.credits) { if (reward.credits) {
message.RegularCredits = reward.credits; message.RegularCredits = reward.credits;
} }
if (info.arg) {
const args: Record<string, string | number> = {
PLAYER_NAME: account.DisplayName,
CREDIT_REWARD: reward.credits ?? 0
};
info.arg.forEach(key => {
const value = args[key];
if (value) {
message.arg ??= [];
message.arg.push({ Key: key, Tag: value });
}
});
}
await createMessage(inventory.accountOwnerId, [message]); await createMessage(inventory.accountOwnerId, [message]);
} }
@ -712,10 +733,20 @@ export const addMissionInventoryUpdates = async (
} }
if (goalProgress) { if (goalProgress) {
goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best); goalProgress.Best = Math.max(goalProgress.Best!, uploadProgress.Best);
goalProgress.Count += uploadProgress.Count; goalProgress.Count += uploadProgress.Count;
} }
} }
if (goal && goal.ClanGoal && inventory.GuildId) {
const guild = await Guild.findById(inventory.GuildId, "GoalProgress Tier VaultDecoRecipes");
if (guild) {
await handleGuildGoalProgress(guild, {
Count: uploadProgress.Count,
Tag: goal.Tag,
goalId: new Types.ObjectId(goal._id.$oid)
});
}
}
} }
break; break;
} }
@ -1079,6 +1110,12 @@ export const addMissionRewards = async (
} }
} }
} }
if (rewardInfo.GoalProgressAmount && goal.Tag.startsWith("MechSurvival")) {
MissionRewards.push({
StoreItem: "/Lotus/StoreItems/Types/Items/MiscItems/MechSurvivalEventCreds",
ItemCount: Math.trunc(rewardInfo.GoalProgressAmount / 10)
});
}
} }
} }
@ -1297,6 +1334,27 @@ export const addMissionRewards = async (
logger.error(`unknown droptable ${si.DropTable} for DROP_BLUEPRINT`); logger.error(`unknown droptable ${si.DropTable} for DROP_BLUEPRINT`);
} }
} }
// e.g. H-09 Apex Turret Sumdali
if (si.DROP_MISC_ITEM) {
const resourceDroptable = droptables.find(x => x.type == "resource");
if (resourceDroptable) {
for (let i = 0; i != si.DROP_MISC_ITEM.length; ++i) {
const reward = getRandomReward(resourceDroptable.items)!;
logger.debug(`stripped droptable (resources pool) rolled`, reward);
if (Object.keys(await addItem(inventory, reward.type)).length == 0) {
logger.debug(`item already owned, skipping`);
} else {
MissionRewards.push({
StoreItem: toStoreItem(reward.type),
ItemCount: 1,
FromEnemyCache: true // to show "identified"
});
}
}
} else {
logger.error(`unknown droptable ${si.DropTable} for DROP_BLUEPRINT`);
}
}
} }
} }
@ -2227,7 +2285,7 @@ const getHexBounties = (seed: number): { nodes: string[]; buddies: string[] } =>
return { nodes, buddies }; return { nodes, buddies };
};*/ };*/
const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string; icon: string }> = { const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string; icon: string; arg?: string[] }> = {
"/Lotus/Types/Keys/GalleonRobberyAlert": { "/Lotus/Types/Keys/GalleonRobberyAlert": {
sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek", sndr: "/Lotus/Language/Bosses/BossCouncilorVayHek",
msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgA", msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgA",
@ -2340,19 +2398,22 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody", msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle", sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png" icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["CREDIT_REWARD"]
}, },
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo": { "/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo": {
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody", msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle", sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png" icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["CREDIT_REWARD"]
}, },
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree": { "/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree": {
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody", msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle", sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png" icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["CREDIT_REWARD"]
}, },
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour": { "/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour": {
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
@ -2364,7 +2425,8 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/G1Quests/ProjectNightwatchRewardMsgA", msg: "/Lotus/Language/G1Quests/ProjectNightwatchRewardMsgA",
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionOneTitle", sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionOneTitle",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png" icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["CREDIT_REWARD"]
}, },
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatch": { "/Lotus/Types/Keys/TacAlertKeyProjectNightwatch": {
sndr: "/Lotus/Language/Bosses/Lotus", sndr: "/Lotus/Language/Bosses/Lotus",
@ -2383,5 +2445,175 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody", msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionFourTitle", sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionFourTitle",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png" icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
},
"/Lotus/Types/Keys/MechSurvivalCorpusShip": {
sndr: "/Lotus/Language/Bosses/DeimosFather",
msg: "/Lotus/Language/Inbox/MechEvent2020Tier1CompleteDesc",
sub: "/Lotus/Language/Inbox/MechEvent2020Tier1CompleteTitle",
icon: "/Lotus/Interface/Icons/Npcs/Entrati/Father.png"
},
"/Lotus/Types/Keys/MechSurvivalGrineerGalleon": {
sndr: "/Lotus/Language/Bosses/DeimosFather",
msg: "/Lotus/Language/Inbox/MechEvent2020Tier2CompleteDesc",
sub: "/Lotus/Language/Inbox/MechEvent2020Tier2CompleteTitle",
icon: "/Lotus/Interface/Icons/Npcs/Entrati/Father.png"
},
"/Lotus/Types/Keys/MechSurvivalGasCity": {
sndr: "/Lotus/Language/Bosses/DeimosFather",
msg: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteDesc",
sub: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteTitle",
icon: "/Lotus/Interface/Icons/Npcs/Entrati/Father.png"
},
"/Lotus/Types/Keys/MechSurvivalCorpusShipEndurance": {
sndr: "/Lotus/Language/Bosses/DeimosFather",
msg: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteDesc",
sub: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteTitle",
icon: "/Lotus/Interface/Icons/Npcs/Entrati/Father.png"
},
"/Lotus/Types/Keys/MechSurvivalGrineerGalleonEndurance": {
sndr: "/Lotus/Language/Bosses/DeimosFather",
msg: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteDesc",
sub: "/Lotus/Language/Inbox/MechEvent2020Tier3CompleteTitle",
icon: "/Lotus/Interface/Icons/Npcs/Entrati/Father.png"
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2019E": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgB",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleB",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2020F": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgC",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleB",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeA": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgD",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleD",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2017C": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2019RewardMsgC",
sub: "/Lotus/Language/Messages/Anniversary2019MissionTitleC",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2020H": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2020RewardMsgH",
sub: "/Lotus/Language/Messages/Anniversary2020MissionTitleH",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2022J": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2022RewardMsgJ",
sub: "/Lotus/Language/Messages/Anniversary2022MissionTitleJ",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025D": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgB",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleB",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeA": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgC",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleC",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2020G": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2020RewardMsgG",
sub: "/Lotus/Language/Messages/Anniversary2020MissionTitleG",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2017B": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2019RewardMsgB",
sub: "/Lotus/Language/Messages/Anniversary2019MissionTitleB",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2017A": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2019RewardMsgA",
sub: "/Lotus/Language/Messages/Anniversary2019MissionTitleA",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2023K": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgG",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleG",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeB": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgD",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleD",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025A": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgA",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleA",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2018D": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgG",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleG",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025C": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgF",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleF",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2024L": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgA",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleA",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeB": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgE",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleE",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2021I": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2024RewardMsgH",
sub: "/Lotus/Language/Messages/Anniversary2024MissionTitleH",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
},
"/Lotus/Types/Keys/TacAlertKeyAnniversary2025B": {
sndr: "/Lotus/Language/Bosses/Lotus",
msg: "/Lotus/Language/Messages/Anniversary2025RewardMsgE",
sub: "/Lotus/Language/Messages/Anniversary2025MissionTitleE",
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png",
arg: ["PLAYER_NAME"]
} }
}; };

View File

@ -36,6 +36,9 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento
import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService"; import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService";
import { DailyDeal } from "@/src/models/worldStateModel"; import { DailyDeal } from "@/src/models/worldStateModel";
import { fromMongoDate, toMongoDate } from "@/src/helpers/inventoryHelpers"; import { fromMongoDate, toMongoDate } from "@/src/helpers/inventoryHelpers";
import { Guild } from "@/src/models/guildModel";
import { handleGuildGoalProgress } from "@/src/services/guildService";
import { Types } from "mongoose";
export const getStoreItemCategory = (storeItem: string): string => { export const getStoreItemCategory = (storeItem: string): string => {
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/"); const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
@ -137,6 +140,22 @@ export const handlePurchase = async (
updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges); updateCurrency(inventory, offer.PremiumPrice[0], true, prePurchaseInventoryChanges);
} }
} }
if (
inventory.GuildId &&
offer.ItemPrices &&
manifest.VendorInfo.TypeName ==
"/Lotus/Types/Game/VendorManifests/Events/DuviriMurmurInvasionVendorManifest"
) {
const guild = await Guild.findById(inventory.GuildId, "GoalProgress Tier VaultDecoRecipes");
const goal = getWorldState().Goals.find(x => x.Tag == "DuviriMurmurEvent");
if (guild && goal) {
await handleGuildGoalProgress(guild, {
Count: offer.ItemPrices[0].ItemCount * purchaseRequest.PurchaseParams.Quantity,
Tag: goal.Tag,
goalId: new Types.ObjectId(goal._id.$oid)
});
}
}
if (!config.dontSubtractPurchaseItemCost) { if (!config.dontSubtractPurchaseItemCost) {
if (offer.ItemPrices) { if (offer.ItemPrices) {
handleItemPrices( handleItemPrices(

View File

@ -19,6 +19,7 @@ import { Guild } from "@/src/models/guildModel";
import { hasGuildPermission } from "@/src/services/guildService"; import { hasGuildPermission } from "@/src/services/guildService";
import { GuildPermission } from "@/src/types/guildTypes"; import { GuildPermission } from "@/src/types/guildTypes";
import { ExportResources } from "warframe-public-export-plus"; import { ExportResources } from "warframe-public-export-plus";
import { convertCustomizationInfo } from "@/src/services/importService";
export const setShipCustomizations = async ( export const setShipCustomizations = async (
accountId: string, accountId: string,
@ -269,6 +270,8 @@ export const handleSetPlacedDecoInfo = async (accountId: string, req: ISetPlaced
} }
placedDeco.PictureFrameInfo = req.PictureFrameInfo; placedDeco.PictureFrameInfo = req.PictureFrameInfo;
placedDeco.CustomizationInfo = req.CustomizationInfo ? convertCustomizationInfo(req.CustomizationInfo) : undefined;
placedDeco.AnimPoseItem = req.AnimPoseItem;
await personalRooms.save(); await personalRooms.save();
}; };

View File

@ -382,6 +382,29 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
); );
break; break;
case "Halloween16":
case "AmalgamEventScoreMax":
case "Halloween19ScoreMax":
case "FlotillaEventScore":
case "FlotillaSpaceBadgesTier1":
case "FlotillaSpaceBadgesTier2":
case "FlotillaSpaceBadgesTier3":
case "FlotillaGroundBadgesTier1":
case "FlotillaGroundBadgesTier2":
case "FlotillaGroundBadgesTier3":
case "MechSurvivalScoreMax":
playerStats[category] ??= 0;
if (data > playerStats[category]) playerStats[category] = data as number;
await submitLeaderboardScore(
"events",
category,
accountOwnerId,
payload.displayName,
data as number,
payload.guildId
);
break;
default: default:
if (!ignoredCategories.includes(category)) { if (!ignoredCategories.includes(category)) {
unknownCategories[action] ??= []; unknownCategories[action] ??= [];

View File

@ -8,6 +8,7 @@ import syndicateMissions from "@/static/fixed_responses/worldState/syndicateMiss
import darvoDeals from "@/static/fixed_responses/worldState/darvoDeals.json"; import darvoDeals from "@/static/fixed_responses/worldState/darvoDeals.json";
import invasionNodes from "@/static/fixed_responses/worldState/invasionNodes.json"; import invasionNodes from "@/static/fixed_responses/worldState/invasionNodes.json";
import invasionRewards from "@/static/fixed_responses/worldState/invasionRewards.json"; import invasionRewards from "@/static/fixed_responses/worldState/invasionRewards.json";
import pvpChallenges from "@/static/fixed_responses/worldState/pvpChallenges.json";
import { buildConfig } from "@/src/services/buildConfigService"; import { buildConfig } from "@/src/services/buildConfigService";
import { unixTimesInMs } from "@/src/constants/timeConstants"; import { unixTimesInMs } from "@/src/constants/timeConstants";
import { config } from "@/src/services/configService"; import { config } from "@/src/services/configService";
@ -17,10 +18,12 @@ import {
ICalendarDay, ICalendarDay,
ICalendarEvent, ICalendarEvent,
ICalendarSeason, ICalendarSeason,
IGoal,
IInvasion, IInvasion,
ILiteSortie, ILiteSortie,
IPrimeVaultTrader, IPrimeVaultTrader,
IPrimeVaultTraderOffer, IPrimeVaultTraderOffer,
IPVPChallengeInstance,
ISeasonChallenge, ISeasonChallenge,
ISortie, ISortie,
ISortieMission, ISortieMission,
@ -1401,6 +1404,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
DailyDeals: [], DailyDeals: [],
EndlessXpChoices: [], EndlessXpChoices: [],
KnownCalendarSeasons: [], KnownCalendarSeasons: [],
PVPChallengeInstances: [],
...staticWorldState, ...staticWorldState,
SyndicateMissions: [...staticWorldState.SyndicateMissions], SyndicateMissions: [...staticWorldState.SyndicateMissions],
InGameMarket: { InGameMarket: {
@ -1535,7 +1539,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Personal: true, Personal: true,
Bounty: true, Bounty: true,
ClampNodeScores: true, ClampNodeScores: true,
Node: "EventNode28", // Incompatible with Wolf Hunt (2025) Node: "EventNode28", // Incompatible with Wolf Hunt (2025), Orphix Venom, Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertB", MissionKeyName: "/Lotus/Types/Keys/GalleonRobberyAlertB",
Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle", Desc: "/Lotus/Language/Events/GalleonRobberyEventMissionTitle",
Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png", Icon: "/Lotus/Interface/Icons/Player/GalleonRobberiesEvent.png",
@ -1801,7 +1805,10 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
worldState.Goals.push({ worldState.Goals.push({
_id: { _id: {
$oid: ((dogDaysStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "c57487c3768936df" $oid:
((dogDaysStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") +
"c57487c3768936d" +
year.toString(16)
}, },
Activation: { $date: { $numberLong: activationTimeStamp } }, Activation: { $date: { $numberLong: activationTimeStamp } },
Expiry: { $date: { $numberLong: expiryTimeStamp } }, Expiry: { $date: { $numberLong: expiryTimeStamp } },
@ -1813,14 +1820,14 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Personal: true, Personal: true,
Bounty: true, Bounty: true,
ClampNodeScores: true, ClampNodeScores: true,
Node: "EventNode25", // Incompatible with Hallowed Flame, Hallowed Nightmares Node: "EventNode25", // Incompatible with Hallowed Flame, Hallowed Nightmares, Warframe Anniversary
ConcurrentMissionKeyNames: [ ConcurrentMissionKeyNames: [
"/Lotus/Types/Keys/TacAlertKeyWaterFightB", "/Lotus/Types/Keys/TacAlertKeyWaterFightB",
"/Lotus/Types/Keys/TacAlertKeyWaterFightC", "/Lotus/Types/Keys/TacAlertKeyWaterFightC",
"/Lotus/Types/Keys/TacAlertKeyWaterFightD" "/Lotus/Types/Keys/TacAlertKeyWaterFightD"
], ],
ConcurrentNodeReqs: [25, 50, 100], ConcurrentNodeReqs: [25, 50, 100],
ConcurrentNodes: ["EventNode24", "EventNode34", "EventNode35"], // Incompatible with Hallowed Flame, Hallowed Nightmares ConcurrentNodes: ["EventNode24", "EventNode34", "EventNode35"], // Incompatible with Hallowed Flame, Hallowed Nightmares, Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyWaterFightA", MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyWaterFightA",
Faction: "FC_CORPUS", Faction: "FC_CORPUS",
Desc: "/Lotus/Language/Alerts/TacAlertWaterFight", Desc: "/Lotus/Language/Alerts/TacAlertWaterFight",
@ -1928,6 +1935,226 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
} }
} }
if (config.worldState?.anniversary != undefined) {
// Incompatible with: Use Tag from Warframe Anniversary for old Events, Wolf Hunt (2025), Galleon Of Ghouls, Hallowed Flame, Hallowed Nightmares, Dog Days, Proxy Rebellion, Long Shadow
const goalsByWeek: Partial<IGoal>[][] = [
[
{
Node: "EventNode28",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2019E",
Tag: "Anniversary2019TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Excalibur/ExcaliburDexSkin"]
}
},
{
Node: "EventNode26",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020F",
Tag: "Anniversary2020TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/ShipDecos/ExcaliburDexBobbleHead"]
}
},
{
Node: "EventNode19",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeA",
Tag: "Anniversary2024TacAlertCMA",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker"]
}
}
],
[
{
Node: "EventNode24",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017C",
Tag: "Anniversary2018TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Weapons/Tenno/LongGuns/DexTheThird/DexTheThird"]
}
},
{
Node: "EventNode18",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020H",
Tag: "Anniversary2020TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageDexAnniversary"]
}
}
],
[
{
Node: "EventNode18",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2022J",
Tag: "Anniversary2022TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Rhino/RhinoDexSkin"]
}
},
{
Node: "EventNode38",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025D",
Tag: "Anniversary2020TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/ShipDecos/RhinoDexBobbleHead"]
}
},
{
Node: "EventNode27",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeA",
Tag: "Anniversary2024TacAlertCMA",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"]
}
}
],
[
{
Node: "EventNode2",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2020G",
Tag: "Anniversary2020TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Liset/DexLisetSkin"]
}
},
{
Node: "EventNode17",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017B",
Tag: "Anniversary2018TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/DexTheSecond/DexTheSecond"]
}
}
],
[
{
Node: "EventNode18",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2017A",
Tag: "Anniversary2018TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Weapons/Tenno/Pistols/DexFuris/DexFuris"]
}
},
{
Node: "EventNode26",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2023K",
Tag: "Anniversary2025TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageCommunityClemComic"]
}
},
{
Node: "EventNode12",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025ChallengeModeB",
Tag: "Anniversary2025TacAlertCMB",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker"]
}
}
],
[
{
Node: "EventNode17",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025A",
Tag: "Anniversary2025TacAlert",
Reward: {
items: [
"/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/KatanaAndWakizashi/Dex2023Nikana/Dex2023Nikana"
]
}
},
{
Node: "EventNode27",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2018D",
Tag: "Anniversary2018TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Scarves/DexScarf"]
}
}
],
[
{
Node: "EventNode38",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025C",
Tag: "Anniversary2018TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Wisp/DexWispSkin"]
}
},
{
Node: "EventNode12",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024L",
Tag: "Anniversary2024TacAlert",
Reward: {
items: ["/Lotus/Types/StoreItems/Packages/OperatorDrifterDexBundle"]
}
},
{
Node: "EventNode26",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2024ChallengeModeB",
Tag: "Anniversary2024TacAlertCMB",
Reward: {
items: ["/Lotus/StoreItems/Types/Recipes/Components/UmbraFormaBlueprint"]
}
}
],
[
{
Node: "EventNode37",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2021I",
Tag: "Anniversary2021TacAlert",
Reward: {
items: [
"/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorAArmor",
"/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorCArmor",
"/Lotus/StoreItems/Upgrades/Skins/Armor/Dex2020Armor/Dex2020ArmorLArmor",
"/Lotus/StoreItems/Types/Game/CatbrowPet/CatbrowGeneticSignature"
],
countedItems: [
{
ItemType: "/Lotus/Types/Game/CatbrowPet/CatbrowGeneticSignature",
ItemCount: 10
}
]
}
},
{
Node: "EventNode9",
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyAnniversary2025B",
Tag: "Anniversary2025TacAlert",
Reward: {
items: ["/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerAnniversaryEleven"]
}
}
]
];
goalsByWeek[config.worldState.anniversary].forEach((goal, i) => {
worldState.Goals.push({
_id: {
$oid:
"67c6d8e725b23feb" +
config.worldState?.anniversary!.toString(16).padStart(4, "0") +
i.toString(16).padStart(4, "0")
},
Activation: { $date: { $numberLong: "1745593200000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0,
Goal: 1,
Success: 0,
Personal: true,
ClampNodeScores: true,
Node: goal.Node,
MissionKeyName: goal.MissionKeyName,
Desc: goal.Tag!.endsWith("CMB")
? "/Lotus/Language/Events/Anniversary2024ChallengeMode"
: "/Lotus/Language/G1Quests/Anniversary2017MissionTitle",
Icon: "/Lotus/Interface/Icons/Player/GlyphLotus12Anniversary.png",
Tag: goal.Tag!,
Reward: goal.Reward
});
});
}
if (config.worldState?.wolfHunt) { if (config.worldState?.wolfHunt) {
worldState.Goals.push({ worldState.Goals.push({
_id: { _id: {
@ -1958,7 +2185,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
"/Lotus/Types/Keys/WolfTacAlertReduxD" "/Lotus/Types/Keys/WolfTacAlertReduxD"
], ],
ConcurrentNodeReqs: [1, 2, 3], ConcurrentNodeReqs: [1, 2, 3],
ConcurrentNodes: ["EventNode28", "EventNode39", "EventNode40"], // Incompatible with Galleon Of Ghouls ConcurrentNodes: ["EventNode28", "EventNode39", "EventNode40"], // Incompatible with Galleon Of Ghouls, Orphix Venom, Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/WolfTacAlertReduxA", MissionKeyName: "/Lotus/Types/Keys/WolfTacAlertReduxA",
Faction: "FC_GRINEER", Faction: "FC_GRINEER",
Desc: "/Lotus/Language/Alerts/WolfAlert", Desc: "/Lotus/Language/Alerts/WolfAlert",
@ -1989,6 +2216,18 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
}); });
} }
const tagsForOlderGoals: string[] = [
"Anniversary2018TacAlert",
"Anniversary2019TacAlert",
"Anniversary2020TacAlert",
"Anniversary2021TacAlert",
"Anniversary2022TacAlert",
"Anniversary2024TacAlert",
"Anniversary2024TacAlertCMA",
"Anniversary2025TacAlert",
"Anniversary2025TacAlertCMB"
];
if (config.worldState?.hallowedFlame) { if (config.worldState?.hallowedFlame) {
worldState.Goals.push( worldState.Goals.push(
{ {
@ -2013,7 +2252,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Faction: "FC_INFESTATION", Faction: "FC_INFESTATION",
Desc: "/Lotus/Language/Events/TacAlertHalloweenLantern", Desc: "/Lotus/Language/Events/TacAlertHalloweenLantern",
Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
Tag: "Halloween19", Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween19",
InterimRewards: [ InterimRewards: [
{ items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"] }, { items: ["/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst"] },
{ items: ["/Lotus/StoreItems/Types/Items/MiscItems/Forma"] } { items: ["/Lotus/StoreItems/Types/Items/MiscItems/Forma"] }
@ -2039,7 +2278,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Desc: "/Lotus/Language/Events/TacAlertHalloweenLanternEndless", Desc: "/Lotus/Language/Events/TacAlertHalloweenLanternEndless",
Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
Tag: "Halloween19Endless", Tag: "Halloween19Endless",
PrereqGoalTags: ["Halloween19"], PrereqGoalTags: [
config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween19"
],
Reward: { Reward: {
items: [ items: [
"/Lotus/StoreItems/Upgrades/Skins/Effects/BatsEphemera", "/Lotus/StoreItems/Upgrades/Skins/Effects/BatsEphemera",
@ -2094,7 +2335,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
const year = config.worldState.hallowedNightmaresRewardsOverride ?? 0; const year = config.worldState.hallowedNightmaresRewardsOverride ?? 0;
worldState.Goals.push({ worldState.Goals.push({
_id: { $oid: "5bc9e8f7972d7d184c8398c9" }, _id: { $oid: "5bc98f00000000000000000" + year.toString(16) },
Activation: { $date: { $numberLong: "1539972000000" } }, Activation: { $date: { $numberLong: "1539972000000" } },
Expiry: { $date: { $numberLong: "2000000000000" } }, Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0, Count: 0,
@ -2103,23 +2344,23 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Success: 0, Success: 0,
Personal: true, Personal: true,
Bounty: true, Bounty: true,
Tag: "Halloween", Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween",
Faction: "FC_INFESTATION", Faction: "FC_INFESTATION",
Desc: "/Lotus/Language/G1Quests/TacAlertHalloweenTitle", Desc: "/Lotus/Language/G1Quests/TacAlertHalloweenTitle",
ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip", ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip",
Icon: "/Lotus/Interface/Icons/JackOLanternColour.png", Icon: "/Lotus/Interface/Icons/JackOLanternColour.png",
ClampNodeScores: true, ClampNodeScores: true,
Node: "EventNode2", Node: "EventNode2", // Incompatible with Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyHalloween", MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyHalloween",
ConcurrentMissionKeyNames: ["/Lotus/Types/Keys/TacAlertKeyHalloweenBonus"], ConcurrentMissionKeyNames: ["/Lotus/Types/Keys/TacAlertKeyHalloweenBonus"],
ConcurrentNodeReqs: [1], ConcurrentNodeReqs: [1],
ConcurrentNodes: ["EventNode24"], // Incompatible with Hallowed Flame, Dog Days ConcurrentNodes: ["EventNode24"], // Incompatible with Hallowed Flame, Dog Days, Warframe Anniversary
InterimRewards: [rewards[year][0]], InterimRewards: [rewards[year][0]],
Reward: rewards[year][1] Reward: rewards[year][1]
}); });
if (year != 2) { if (year != 2) {
worldState.Goals.push({ worldState.Goals.push({
_id: { $oid: "5bca18b1e12d9e14a0b6ad27" }, _id: { $oid: "5bc98f01000000000000000" + year.toString(16) },
Activation: { $date: { $numberLong: "1539972000000" } }, Activation: { $date: { $numberLong: "1539972000000" } },
Expiry: { $date: { $numberLong: "2000000000000" } }, Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0, Count: 0,
@ -2129,7 +2370,9 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Bounty: true, Bounty: true,
Best: true, Best: true,
Tag: "Halloween", Tag: "Halloween",
PrereqGoalTags: ["Halloween"], PrereqGoalTags: [
config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[0] : "Halloween"
],
Faction: "FC_INFESTATION", Faction: "FC_INFESTATION",
Desc: "Hallowed Nightmares - Time Attack", Desc: "Hallowed Nightmares - Time Attack",
ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip", ToolTip: "/Lotus/Language/G1Quests/TacAlertHalloweenToolTip",
@ -2192,7 +2435,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
const year = config.worldState.proxyRebellionRewardsOverride ?? 0; const year = config.worldState.proxyRebellionRewardsOverride ?? 0;
worldState.Goals.push({ worldState.Goals.push({
_id: { $oid: "5b5743ac972d7d3ed0517b0d" }, _id: { $oid: "5b5b5da0000000000000000" + year.toString(16) },
Activation: { $date: { $numberLong: "1532714400000" } }, Activation: { $date: { $numberLong: "1532714400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } }, Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0, Count: 0,
@ -2203,19 +2446,19 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Personal: true, Personal: true,
Bounty: true, Bounty: true,
ClampNodeScores: true, ClampNodeScores: true,
Node: "EventNode18", Node: "EventNode18", // Incompatible with Warframe Anniversary
ConcurrentMissionKeyNames: [ ConcurrentMissionKeyNames: [
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo", "/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo",
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree", "/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree",
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour" "/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour"
], ],
ConcurrentNodeReqs: [1, 2, 3], ConcurrentNodeReqs: [1, 2, 3],
ConcurrentNodes: ["EventNode7", "EventNode4", "EventNode17"], ConcurrentNodes: ["EventNode7", "EventNode4", "EventNode17"], // Incompatible with Orphix venom, Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne", MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne",
Faction: "FC_CORPUS", Faction: "FC_CORPUS",
Desc: "/Lotus/Language/Alerts/TacAlertProxyRebellion", Desc: "/Lotus/Language/Alerts/TacAlertProxyRebellion",
Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png", Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png",
Tag: "ProxyRebellion", Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[1] : "ProxyRebellion",
InterimRewards: rewards[year].slice(0, 2), InterimRewards: rewards[year].slice(0, 2),
Reward: rewards[year][2], Reward: rewards[year][2],
BonusReward: rewards[year][3] BonusReward: rewards[year][3]
@ -2234,12 +2477,12 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
Success: 0, Success: 0,
Personal: true, Personal: true,
Bounty: true, Bounty: true,
Tag: "NightwatchTacAlert", Tag: config.unfaithfulBugFixes?.useAnniversaryTagForOldGoals ? tagsForOlderGoals[2] : "NightwatchTacAlert",
Faction: "FC_GRINEER", Faction: "FC_GRINEER",
Desc: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertTitle", Desc: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertTitle",
Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png", Icon: "/Lotus/Materials/Emblems/BountyBadge_e.png",
ClampNodeScores: true, ClampNodeScores: true,
Node: "EventNode9", Node: "EventNode9", // Incompatible with Warframe Anniversary
MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy", MissionKeyName: "/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy",
ConcurrentMissionKeyNames: [ ConcurrentMissionKeyNames: [
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatch", "/Lotus/Types/Keys/TacAlertKeyProjectNightwatch",
@ -2265,6 +2508,126 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
BonusReward: { items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"] } BonusReward: { items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/BountyHunterBadgeItem"] }
}); });
} }
if (config.worldState?.bellyOfTheBeast) {
worldState.Goals.push({
_id: { $oid: "67a5035c2a198564d62e165e" },
Activation: { $date: { $numberLong: "1738868400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: config.worldState.bellyOfTheBeastProgressOverride ?? 0,
HealthPct: (config.worldState.bellyOfTheBeastProgressOverride ?? 0) / 100,
Goal: 0,
Personal: true,
Community: true,
ClanGoal: [72, 216, 648, 1944, 5832],
Tag: "JadeShadowsEvent",
Faction: "FC_MITW",
Desc: "/Lotus/Language/JadeShadows/JadeShadowsEventName",
ToolTip: "/Lotus/Language/JadeShadows/JadeShadowsShortEventDesc",
Icon: "/Lotus/Interface/Icons/WorldStatePanel/JadeShadowsEventBadge.png",
ScoreLocTag: "/Lotus/Language/JadeShadows/JadeShadowsEventScore",
Node: "SolNode723",
MissionKeyName: "/Lotus/Types/Keys/JadeShadowsEventMission",
ItemType: "/Lotus/Types/Gameplay/JadeShadows/Resources/AscensionEventResourceItem"
});
}
if (config.worldState?.eightClaw) {
worldState.Goals.push({
_id: { $oid: "685c15f80000000000000000" },
Activation: { $date: { $numberLong: "1750865400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: config.worldState.eightClawProgressOverride ?? 0,
HealthPct: (config.worldState.eightClawProgressOverride ?? 0) / 100,
Goal: 0,
Personal: true,
Community: true,
ClanGoal: [72, 216, 648, 1944, 5832],
Tag: "DuviriMurmurEvent",
Faction: "FC_MITW",
Desc: "/Lotus/Language/Isleweaver/DuviriMurmurEventTitle",
ToolTip: "/Lotus/Language/Isleweaver/DuviriMurmurEventDescription",
Icon: "/Lotus/Interface/Icons/WorldStatePanel/EightClawEventBadge.png",
ScoreLocTag: "/Lotus/Language/Isleweaver/DuviriMurmurEventScore",
Node: "SolNode236",
MissionKeyName: "/Lotus/Types/Keys/DuviriMITW/DuviriMITWEventKey"
});
}
if (config.worldState?.orphixVenom) {
worldState.Goals.push(
{
_id: { $oid: "5fdcccb875d5ad500dc477d0" },
Activation: { $date: { $numberLong: "1608320400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0,
Goal: 500,
Success: 0,
Personal: true,
Best: true,
Node: "EventNode17", // Incompatible with Proxy Rebellion
MissionKeyName: "/Lotus/Types/Keys/MechSurvivalCorpusShip",
Faction: "FC_SENTIENT",
Desc: "/Lotus/Language/Events/MechEventMissionTier1",
Icon: "/Lotus/Interface/Icons/Categories/IconMech256.png",
Tag: "MechSurvivalA",
ScoreVar: "MechSurvivalScore",
Reward: {
items: ["/Lotus/StoreItems/Upgrades/Skins/Clan/MechEventEmblemItem"]
}
},
{
_id: { $oid: "5fdcccb875d5ad500dc477d1" },
Activation: { $date: { $numberLong: "1608320400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0,
Goal: 1000,
Success: 0,
Personal: true,
Best: true,
Node: "EventNode28", // Incompatible with Galleon Of Ghouls, Wolf Hunt (2025)
MissionKeyName: "/Lotus/Types/Keys/MechSurvivalGrineerGalleon",
Faction: "FC_SENTIENT",
Desc: "/Lotus/Language/Events/MechEventMissionTier2",
Icon: "/Lotus/Interface/Icons/Categories/IconMech256.png",
Tag: "MechSurvivalB",
PrereqGoalTags: ["MechSurvivalA"],
ScoreVar: "MechSurvivalScore",
Reward: {
items: ["/Lotus/StoreItems/Types/Items/FusionTreasures/OroFusexJ"]
}
},
{
_id: { $oid: "5fdcccb875d5ad500dc477d2" },
Activation: { $date: { $numberLong: "1608320400000" } },
Expiry: { $date: { $numberLong: "2000000000000" } },
Count: 0,
Goal: 2000,
Success: 0,
Personal: true,
Best: true,
Node: "EventNode32",
MissionKeyName: "/Lotus/Types/Keys/MechSurvivalGasCity",
MissionKeyRotation: [
"/Lotus/Types/Keys/MechSurvivalGasCity",
"/Lotus/Types/Keys/MechSurvivalCorpusShipEndurance",
"/Lotus/Types/Keys/MechSurvivalGrineerGalleonEndurance"
],
MissionKeyRotationInterval: 3600, // 1 hour
Faction: "FC_SENTIENT",
Desc: "/Lotus/Language/Events/MechEventMissionTier3",
Icon: "/Lotus/Interface/Icons/Categories/IconMech256.png",
Tag: "MechSurvival",
PrereqGoalTags: ["MechSurvivalA", "MechSurvivalB"],
ScoreVar: "MechSurvivalScore",
ScoreMaxTag: "MechSurvivalScoreMax",
Reward: {
items: [
"/Lotus/StoreItems/Types/Items/MiscItems/FormaAura",
"/Lotus/StoreItems/Upgrades/Skins/Necramech/MechWeapon/MechEventMausolonSkin"
]
}
}
);
}
// Nightwave Challenges // Nightwave Challenges
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel); const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
@ -2586,6 +2949,23 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
pushSyndicateMissions(worldState, sdy, rng.randomInt(0, 100_000), "ba6f84724fa48061", "SteelMeridianSyndicate"); pushSyndicateMissions(worldState, sdy, rng.randomInt(0, 100_000), "ba6f84724fa48061", "SteelMeridianSyndicate");
} }
{
const conclaveDayStart = EPOCH + day * unixTimesInMs.day + 5 * unixTimesInMs.hour + 30 * unixTimesInMs.minute;
const conclaveDayEnd = conclaveDayStart + unixTimesInMs.day;
const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
const conclaveWeekEnd = conclaveWeekStart + unixTimesInMs.week;
pushConclaveWeakly(worldState.PVPChallengeInstances, week);
pushConclaveDailys(worldState.PVPChallengeInstances, day);
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveDayEnd)) {
pushConclaveDailys(worldState.PVPChallengeInstances, day + 1);
}
if (isBeforeNextExpectedWorldStateRefresh(timeMs, conclaveWeekEnd)) {
pushConclaveWeakly(worldState.PVPChallengeInstances, week + 1);
}
}
// Archon Hunt cycling every week // Archon Hunt cycling every week
worldState.LiteSorties.push(getLiteSortie(week)); worldState.LiteSorties.push(getLiteSortie(week));
if (isBeforeNextExpectedWorldStateRefresh(timeMs, weekEnd)) { if (isBeforeNextExpectedWorldStateRefresh(timeMs, weekEnd)) {
@ -2971,3 +3351,136 @@ const updateDailyDeal = async (): Promise<void> => {
export const updateWorldStateCollections = async (): Promise<void> => { export const updateWorldStateCollections = async (): Promise<void> => {
await Promise.all([updateFissures(), updateDailyDeal()]); await Promise.all([updateFissures(), updateDailyDeal()]);
}; };
const pushConclaveDaily = (
activeChallenges: IPVPChallengeInstance[],
PVPMode: string,
pool: {
key: string;
ScriptParamValue: number;
PVPModeAllowed: string[];
SyndicateXP: number;
DuringSingleMatch?: boolean;
}[],
day: number,
id: number
): void => {
const conclaveDayStart = EPOCH + day * unixTimesInMs.day + 5 * unixTimesInMs.hour + 30 * unixTimesInMs.minute;
const conclaveDayEnd = conclaveDayStart + unixTimesInMs.day;
const challengeId = day * 8 + id;
const rng = new SRng(new SRng(challengeId).randomInt(0, 100_000));
let challenge: {
key: string;
ScriptParamValue: number;
PVPModeAllowed?: string[];
SyndicateXP?: number;
DuringSingleMatch?: boolean;
};
do {
challenge = rng.randomElement(pool)!;
} while (
activeChallenges.some(x => x.challengeTypeRefID == challenge.key) &&
activeChallenges.some(x => x.PVPMode == PVPMode)
);
activeChallenges.push({
_id: {
$oid: "689ec5d985b55902" + challengeId.toString().padStart(8, "0")
},
challengeTypeRefID: challenge.key,
startDate: { $date: { $numberLong: conclaveDayStart.toString() } },
endDate: { $date: { $numberLong: conclaveDayEnd.toString() } },
params: [{ n: "ScriptParamValue", v: challenge.ScriptParamValue }],
isGenerated: true,
PVPMode,
subChallenges: [],
Category: "PVPChallengeTypeCategory_DAILY"
});
};
const pushConclaveDailys = (activeChallenges: IPVPChallengeInstance[], day: number): void => {
const modes = [
"PVPMODE_SPEEDBALL",
"PVPMODE_CAPTURETHEFLAG",
"PVPMODE_DEATHMATCH",
"PVPMODE_TEAMDEATHMATCH"
] as const;
const challengesMap: Record<
string,
{
key: string;
ScriptParamValue: number;
PVPModeAllowed: string[];
SyndicateXP: number;
DuringSingleMatch?: boolean;
}[]
> = {};
for (const mode of modes) {
challengesMap[mode] = Object.entries(pvpChallenges)
.filter(([_, challenge]) => challenge.PVPModeAllowed.includes(mode))
.map(([key, challenge]) => ({ key, ...challenge }));
}
modes.forEach((mode, index) => {
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2);
pushConclaveDaily(activeChallenges, mode, challengesMap[mode], day, index * 2 + 1);
});
};
const pushConclaveWeakly = (activeChallenges: IPVPChallengeInstance[], week: number): void => {
const weekStart = EPOCH + week * unixTimesInMs.week;
const conclaveWeekStart = weekStart + 40 * unixTimesInMs.minute - 2 * unixTimesInMs.day;
const conclaveWeekEnd = conclaveWeekStart + unixTimesInMs.week;
const conclaveIdStart = ((conclaveWeekStart / 1000) & 0xffffffff).toString(16).padStart(8, "0").padEnd(23, "0");
activeChallenges.push(
{
_id: { $oid: conclaveIdStart + "1" },
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeWins",
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
params: [{ n: "ScriptParamValue", v: 6 }],
isGenerated: true,
PVPMode: "PVPMODE_ALL",
subChallenges: [],
Category: "PVPChallengeTypeCategory_WEEKLY"
},
{
_id: { $oid: conclaveIdStart + "2" },
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeComplete",
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
params: [{ n: "ScriptParamValue", v: 20 }],
isGenerated: true,
PVPMode: "PVPMODE_ALL",
subChallenges: [],
Category: "PVPChallengeTypeCategory_WEEKLY"
},
{
_id: { $oid: conclaveIdStart + "3" },
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeOtherChallengeCompleteANY",
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
params: [{ n: "ScriptParamValue", v: 10 }],
isGenerated: true,
PVPMode: "PVPMODE_ALL",
subChallenges: [],
Category: "PVPChallengeTypeCategory_WEEKLY"
},
{
_id: { $oid: conclaveIdStart + "4" },
challengeTypeRefID: "/Lotus/PVPChallengeTypes/PVPTimedChallengeWeeklyStandardSet",
startDate: { $date: { $numberLong: conclaveWeekStart.toString() } },
endDate: { $date: { $numberLong: conclaveWeekEnd.toString() } },
params: [{ n: "ScriptParamValue", v: 0 }],
isGenerated: true,
PVPMode: "PVPMODE_NONE",
subChallenges: [
{ $oid: conclaveIdStart + "1" },
{ $oid: conclaveIdStart + "2" },
{ $oid: conclaveIdStart + "3" }
],
Category: "PVPChallengeTypeCategory_WEEKLY_ROOT"
}
);
};

View File

@ -73,8 +73,9 @@ interface IWsMsgToClient {
auth_fail?: { auth_fail?: {
isRegister: boolean; isRegister: boolean;
}; };
logged_out?: boolean; nonce_updated?: boolean;
update_inventory?: boolean; update_inventory?: boolean;
logged_out?: boolean;
} }
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => { const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {

View File

@ -1,6 +1,11 @@
import { Types } from "mongoose"; import { Types } from "mongoose";
import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes"; import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes";
import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import {
IFusionTreasure,
IMiscItem,
IGoalProgressDatabase,
IGoalProgressClient
} from "@/src/types/inventoryTypes/inventoryTypes";
import { IPictureFrameInfo } from "@/src/types/personalRoomsTypes"; import { IPictureFrameInfo } from "@/src/types/personalRoomsTypes";
import { IFriendInfo } from "@/src/types/friendTypes"; import { IFriendInfo } from "@/src/types/friendTypes";
@ -23,6 +28,8 @@ export interface IGuildClient {
CrossPlatformEnabled?: boolean; CrossPlatformEnabled?: boolean;
AutoContributeFromVault?: boolean; AutoContributeFromVault?: boolean;
AllianceId?: IOidWithLegacySupport; AllianceId?: IOidWithLegacySupport;
GoalProgress?: IGoalProgressClient[];
} }
export interface IGuildDatabase { export interface IGuildDatabase {
@ -63,6 +70,8 @@ export interface IGuildDatabase {
TechChanges?: IGuildLogEntryContributable[]; TechChanges?: IGuildLogEntryContributable[];
RosterActivity?: IGuildLogEntryRoster[]; RosterActivity?: IGuildLogEntryRoster[];
ClassChanges?: IGuildLogEntryNumber[]; ClassChanges?: IGuildLogEntryNumber[];
GoalProgress?: IGoalProgressDatabase[];
} }
export interface ILongMOTD { export interface ILongMOTD {

View File

@ -109,7 +109,7 @@ export interface IInventoryDatabase
QualifyingInvasions: IInvasionProgressDatabase[]; QualifyingInvasions: IInvasionProgressDatabase[];
LastInventorySync?: Types.ObjectId; LastInventorySync?: Types.ObjectId;
EndlessXP?: IEndlessXpProgressDatabase[]; EndlessXP?: IEndlessXpProgressDatabase[];
PersonalGoalProgress?: IPersonalGoalProgressDatabase[]; PersonalGoalProgress?: IGoalProgressDatabase[];
} }
export interface IQuestKeyDatabase { export interface IQuestKeyDatabase {
@ -318,7 +318,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
HWIDProtectEnabled?: boolean; HWIDProtectEnabled?: boolean;
KubrowPetPrints: IKubrowPetPrintClient[]; KubrowPetPrints: IKubrowPetPrintClient[];
AlignmentReplay?: IAlignment; AlignmentReplay?: IAlignment;
PersonalGoalProgress?: IPersonalGoalProgressClient[]; PersonalGoalProgress?: IGoalProgressClient[];
ThemeStyle: string; ThemeStyle: string;
ThemeBackground: string; ThemeBackground: string;
ThemeSounds: string; ThemeSounds: string;
@ -730,7 +730,7 @@ export enum UpgradeType {
export interface ILoreFragmentScan { export interface ILoreFragmentScan {
Progress: number; Progress: number;
Region?: string; Region: string;
ItemType: string; ItemType: string;
} }
@ -895,8 +895,8 @@ export interface IPeriodicMissionCompletionResponse extends Omit<IPeriodicMissio
date: IMongoDate; date: IMongoDate;
} }
export interface IPersonalGoalProgressClient { export interface IGoalProgressClient {
Best: number; Best?: number;
Count: number; Count: number;
Tag: string; Tag: string;
_id: IOid; _id: IOid;
@ -904,7 +904,7 @@ export interface IPersonalGoalProgressClient {
//ReceivedClanReward1?: boolean; //ReceivedClanReward1?: boolean;
} }
export interface IPersonalGoalProgressDatabase extends Omit<IPersonalGoalProgressClient, "_id"> { export interface IGoalProgressDatabase extends Omit<IGoalProgressClient, "_id"> {
goalId: Types.ObjectId; goalId: Types.ObjectId;
} }

View File

@ -6,7 +6,7 @@ export interface ILeaderboardEntryDatabase {
displayName: string; displayName: string;
score: number; score: number;
guildId?: Types.ObjectId; guildId?: Types.ObjectId;
expiry: Date; expiry?: Date;
guildTier?: number; guildTier?: number;
} }

View File

@ -1,6 +1,6 @@
import { IColor, IShipAttachments, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IColor, IShipAttachments, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes";
import { Document, Model, Types } from "mongoose"; import { Document, Model, Types } from "mongoose";
import { ILoadoutClient } from "@/src/types/saveLoadoutTypes"; import { ILoadoutClient, ILoadoutConfigClient, ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes";
import { IMongoDate, IOid } from "@/src/types/commonTypes"; import { IMongoDate, IOid } from "@/src/types/commonTypes";
export interface IGetShipResponse { export interface IGetShipResponse {
@ -17,7 +17,7 @@ export interface IOrbiterClient {
Features: string[]; Features: string[];
ShipId: IOid; ShipId: IOid;
ShipInterior: IShipCustomization; ShipInterior: IShipCustomization;
Rooms: IRoom[]; Rooms: IRoomClient[];
VignetteFish?: string[]; VignetteFish?: string[];
FavouriteLoadoutId?: IOid; FavouriteLoadoutId?: IOid;
Wallpaper?: string; Wallpaper?: string;
@ -28,7 +28,7 @@ export interface IOrbiterClient {
export interface IOrbiterDatabase { export interface IOrbiterDatabase {
Features: string[]; Features: string[];
Rooms: IRoom[]; Rooms: IRoomDatabase[];
ShipInterior?: IShipCustomization; ShipInterior?: IShipCustomization;
VignetteFish?: string[]; VignetteFish?: string[];
FavouriteLoadoutId?: Types.ObjectId; FavouriteLoadoutId?: Types.ObjectId;
@ -53,12 +53,18 @@ export interface IPersonalRoomsDatabase {
TailorShop: ITailorShopDatabase; TailorShop: ITailorShopDatabase;
} }
export interface IRoom { export interface IRoomDatabase {
Name: string; Name: string;
MaxCapacity: number; MaxCapacity: number;
PlacedDecos?: IPlacedDecosDatabase[]; PlacedDecos?: IPlacedDecosDatabase[];
} }
export interface IRoomClient {
Name: string;
MaxCapacity: number;
PlacedDecos?: IPlacedDecosClient[];
}
export interface IPlantClient { export interface IPlantClient {
PlantType: string; PlantType: string;
EndTime: IMongoDate; EndTime: IMongoDate;
@ -89,15 +95,15 @@ export interface IGardeningDatabase {
export interface IApartmentClient { export interface IApartmentClient {
Gardening: IGardeningClient; Gardening: IGardeningClient;
Rooms: IRoom[]; Rooms: IRoomClient[];
FavouriteLoadouts: IFavouriteLoadout[]; FavouriteLoadouts?: IFavouriteLoadout[];
VideoWallBackdrop?: string; VideoWallBackdrop?: string;
Soundscape?: string; Soundscape?: string;
} }
export interface IApartmentDatabase { export interface IApartmentDatabase {
Gardening: IGardeningDatabase; Gardening: IGardeningDatabase;
Rooms: IRoom[]; Rooms: IRoomDatabase[];
FavouriteLoadouts: IFavouriteLoadoutDatabase[]; FavouriteLoadouts: IFavouriteLoadoutDatabase[];
VideoWallBackdrop?: string; VideoWallBackdrop?: string;
Soundscape?: string; Soundscape?: string;
@ -110,11 +116,14 @@ export interface IPlacedDecosDatabase {
Scale?: number; Scale?: number;
Sockets?: number; Sockets?: number;
PictureFrameInfo?: IPictureFrameInfo; PictureFrameInfo?: IPictureFrameInfo;
CustomizationInfo?: ICustomizationInfoDatabase;
AnimPoseItem?: string;
_id: Types.ObjectId; _id: Types.ObjectId;
} }
export interface IPlacedDecosClient extends Omit<IPlacedDecosDatabase, "_id"> { export interface IPlacedDecosClient extends Omit<IPlacedDecosDatabase, "_id" | "CustomizationInfo"> {
id: IOid; id: IOid;
CustomizationInfo?: ICustomizationInfoClient;
} }
export interface ISetShipCustomizationsRequest { export interface ISetShipCustomizationsRequest {
@ -166,11 +175,13 @@ export interface IResetShipDecorationsResponse {
} }
export interface ISetPlacedDecoInfoRequest { export interface ISetPlacedDecoInfoRequest {
DecoType: string; DecoType?: string;
DecoId: string; DecoId: string;
Room: string; Room: string;
PictureFrameInfo: IPictureFrameInfo; PictureFrameInfo: IPictureFrameInfo; // IsPicture
CustomizationInfo?: ICustomizationInfoClient; // !IsPicture
BootLocation?: TBootLocation; BootLocation?: TBootLocation;
AnimPoseItem?: string; // !IsPicture
ComponentId?: string; ComponentId?: string;
GuildId?: string; GuildId?: string;
} }
@ -191,6 +202,21 @@ export interface IPictureFrameInfo {
TextOrientation: number; TextOrientation: number;
} }
export interface ICustomizationInfoClient {
Anim?: string;
AnimPose?: number;
LoadOutPreset?: ILoadoutConfigClient;
VehiclePreset?: ILoadoutConfigClient;
EquippedWeapon?: "SUIT_SLOT" | "LONG_GUN_SLOT" | "PISTOL_SLOT";
AvatarType?: string;
LoadOutType?: string; // "LOT_NORMAL"
}
export interface ICustomizationInfoDatabase extends Omit<ICustomizationInfoClient, "LoadOutPreset" | "VehiclePreset"> {
LoadOutPreset?: ILoadoutConfigDatabase;
VehiclePreset?: ILoadoutConfigDatabase;
}
export interface IFavouriteLoadout { export interface IFavouriteLoadout {
Tag: string; Tag: string;
LoadoutId: IOid; LoadoutId: IOid;
@ -206,11 +232,12 @@ export interface ITailorShopDatabase {
Colors?: IColor; Colors?: IColor;
CustomJson?: string; CustomJson?: string;
LevelDecosVisible?: boolean; LevelDecosVisible?: boolean;
Rooms: IRoom[]; Rooms: IRoomDatabase[];
} }
export interface ITailorShop extends Omit<ITailorShopDatabase, "FavouriteLoadouts"> { export interface ITailorShop extends Omit<ITailorShopDatabase, "Rooms" | "FavouriteLoadouts"> {
FavouriteLoadouts: IFavouriteLoadout[]; Rooms: IRoomClient[];
FavouriteLoadouts?: IFavouriteLoadout[];
} }
export type RoomsType = { Name: string; MaxCapacity: number; PlacedDecos: Types.DocumentArray<IPlacedDecosDatabase> }; export type RoomsType = { Name: string; MaxCapacity: number; PlacedDecos: Types.DocumentArray<IPlacedDecosDatabase> };

View File

@ -117,6 +117,7 @@ export type IMissionInventoryUpdateRequest = {
DropTable: string; DropTable: string;
DROP_MOD?: number[]; DROP_MOD?: number[];
DROP_BLUEPRINT?: number[]; DROP_BLUEPRINT?: number[];
DROP_MISC_ITEM?: number[];
}[]; }[];
DeathMarks?: string[]; DeathMarks?: string[];
Nemesis?: number; Nemesis?: number;
@ -205,6 +206,7 @@ export interface IRewardInfo {
Q?: boolean; // likely indicates that the bonus objective for this stage was completed Q?: boolean; // likely indicates that the bonus objective for this stage was completed
CheckpointCounter?: number; // starts at 1, is incremented with each job stage upload, and does not reset when starting a new job CheckpointCounter?: number; // starts at 1, is incremented with each job stage upload, and does not reset when starting a new job
challengeMissionId?: string; challengeMissionId?: string;
GoalProgressAmount?: number;
} }
export type IMissionStatus = "GS_SUCCESS" | "GS_FAILURE" | "GS_DUMPED" | "GS_QUIT" | "GS_INTERRUPTED"; export type IMissionStatus = "GS_SUCCESS" | "GS_FAILURE" | "GS_DUMPED" | "GS_QUIT" | "GS_INTERRUPTED";

View File

@ -32,6 +32,19 @@ export interface IStatsClient {
OlliesCrashCourseScore?: number; OlliesCrashCourseScore?: number;
DojoObstacleScore?: number; DojoObstacleScore?: number;
// event scores
Halloween16?: number;
AmalgamEventScoreMax?: number;
Halloween19ScoreMax?: number;
FlotillaEventScore?: number;
FlotillaSpaceBadgesTier1?: number;
FlotillaSpaceBadgesTier2?: number;
FlotillaSpaceBadgesTier3?: number;
FlotillaGroundBadgesTier1?: number;
FlotillaGroundBadgesTier2?: number;
FlotillaGroundBadgesTier3?: number;
MechSurvivalScoreMax?: number;
// not in schema // not in schema
PVP?: { PVP?: {
suitDeaths?: number; suitDeaths?: number;

View File

@ -39,32 +39,44 @@ export interface IGoal {
_id: IOid; _id: IOid;
Activation: IMongoDate; Activation: IMongoDate;
Expiry: IMongoDate; Expiry: IMongoDate;
Count?: number; Count?: number;
HealthPct?: number;
Icon: string;
Desc: string;
ToolTip?: string;
Faction?: string;
Goal?: number; Goal?: number;
InterimGoals?: number[]; InterimGoals?: number[];
BonusGoal?: number; BonusGoal?: number;
HealthPct?: number; ClanGoal?: number[];
Success?: number; Success?: number;
Personal?: boolean; Personal?: boolean;
Best?: boolean; Community?: boolean;
Best?: boolean; // Use Best instead of Count to check for reward
Bounty?: boolean; // Tactical Alert Bounty?: boolean; // Tactical Alert
Faction?: string;
ClampNodeScores?: boolean; ClampNodeScores?: boolean;
Desc: string;
ToolTip?: string;
Transmission?: string; Transmission?: string;
InstructionalItem?: string; InstructionalItem?: string;
Icon: string; ItemType?: string;
Tag: string; Tag: string;
PrereqGoalTags?: string[]; PrereqGoalTags?: string[];
Node?: string; Node?: string;
VictimNode?: string; VictimNode?: string;
ConcurrentMissionKeyNames?: string[]; ConcurrentMissionKeyNames?: string[];
ConcurrentNodeReqs?: number[]; ConcurrentNodeReqs?: number[];
ConcurrentNodes?: string[]; ConcurrentNodes?: string[];
RegionIdx?: number; RegionIdx?: number;
Regions?: number[]; Regions?: number[];
MissionKeyName?: string; MissionKeyName?: string;
Reward?: IMissionReward; Reward?: IMissionReward;
InterimRewards?: IMissionReward[]; InterimRewards?: IMissionReward[];
BonusReward?: IMissionReward; BonusReward?: IMissionReward;
@ -76,7 +88,12 @@ export interface IGoal {
JobPreviousVersion?: IOid; JobPreviousVersion?: IOid;
ScoreVar?: string; ScoreVar?: string;
ScoreMaxTag?: string; ScoreMaxTag?: string; // Field in leaderboard
ScoreLocTag?: string;
MissionKeyRotation?: string[];
MissionKeyRotationInterval?: number;
NightLevel?: string; NightLevel?: string;
} }

View File

@ -0,0 +1,290 @@
{
"/Lotus/PVPChallengeTypes/PVPTimedChallengeFlagCaptureEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_CAPTURETHEFLAG"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeFlagCaptureMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_CAPTURETHEFLAG"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeFlagReturnEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_CAPTURETHEFLAG"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsComboEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsComboMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsHeadShotsEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsHeadShotsMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsMeleeEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsMeleeMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsMeleeHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsMultiMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPaybackEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPayback_MEDIUM": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPowerEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPowerMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPowerHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPrimaryEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPrimaryMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPrimaryHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsSecondaryEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsSecondaryMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsSecondaryHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreak_MEDIUM": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakDominationEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakDomination_MEDIUM": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakDominationHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakStoppedEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakStopped_MEDIUM": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakHARD": {
"ScriptParamValue": 2,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsTargetInAirEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsTargetInAirMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsTargetInAirHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsWhileSlidingEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsWhileSlidingMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsWhileSlidingHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 3000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeMatchCompleteEASY": {
"ScriptParamValue": 1,
"PVPModeAllowed": ["PVPMODE_CAPTURETHEFLAG", "PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeMatchCompleteMEDIUM": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_CAPTURETHEFLAG", "PVPMODE_DEATHMATCH", "PVPMODE_TEAMDEATHMATCH"],
"SyndicateXP": 1500
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballCatchesEASY": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballCatchesMEDIUM": {
"ScriptParamValue": 10,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballCatchesHARD": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballChecksEASY": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballChecksMEDIUM": {
"ScriptParamValue": 10,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballChecksHARD": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballGoalsEASY": {
"ScriptParamValue": 2,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballGoalsMEDIUM": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballGoalsHARD": {
"ScriptParamValue": 4,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballInterceptionsEASY": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballInterceptionsMEDIUM": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballInterceptionsHARD": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballPassesEASY": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballPassesMEDIUM": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballPassesHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000,
"DuringSingleMatch": true
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballStealsEASY": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 1000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballStealsMEDIUM": {
"ScriptParamValue": 6,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 3000
},
"/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballStealsHARD": {
"ScriptParamValue": 3,
"PVPModeAllowed": ["PVPMODE_SPEEDBALL"],
"SyndicateXP": 6000
}
}

View File

@ -311,140 +311,6 @@
"PrimeVaultAvailabilities": [false, false, false, false, false], "PrimeVaultAvailabilities": [false, false, false, false, false],
"PrimeTokenAvailability": true, "PrimeTokenAvailability": true,
"LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" }, "LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" },
"PVPChallengeInstances": [
{
"_id": { "$oid": "6635562d036ce37f7f98e264" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeComplete",
"startDate": { "$date": { "$numberLong": "1714771501460" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 20 }],
"isGenerated": true,
"PVPMode": "PVPMODE_ALL",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_WEEKLY"
},
{
"_id": { "$oid": "6635562d036ce37f7f98e263" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeGameModeWins",
"startDate": { "$date": { "$numberLong": "1714771501460" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 6 }],
"isGenerated": true,
"PVPMode": "PVPMODE_ALL",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_WEEKLY"
},
{
"_id": { "$oid": "6635562d036ce37f7f98e265" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeOtherChallengeCompleteANY",
"startDate": { "$date": { "$numberLong": "1714771501460" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 10 }],
"isGenerated": true,
"PVPMode": "PVPMODE_ALL",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_WEEKLY"
},
{
"_id": { "$oid": "6635562d036ce37f7f98e266" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeWeeklyStandardSet",
"startDate": { "$date": { "$numberLong": "1714771501460" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 0 }],
"isGenerated": true,
"PVPMode": "PVPMODE_NONE",
"subChallenges": [{ "$oid": "6635562d036ce37f7f98e263" }, { "$oid": "6635562d036ce37f7f98e264" }, { "$oid": "6635562d036ce37f7f98e265" }],
"Category": "PVPChallengeTypeCategory_WEEKLY_ROOT"
},
{
"_id": { "$oid": "6639ca6967c1192987d75fee" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeFlagReturnEASY",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 1 }],
"isGenerated": true,
"PVPMode": "PVPMODE_CAPTURETHEFLAG",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75fed" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeMatchCompleteMEDIUM",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 4 }],
"isGenerated": true,
"PVPMode": "PVPMODE_CAPTURETHEFLAG",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75ff2" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeMatchCompleteEASY",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 1 }],
"isGenerated": true,
"PVPMode": "PVPMODE_DEATHMATCH",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75ff1" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsPayback_MEDIUM",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 3 }],
"isGenerated": true,
"PVPMode": "PVPMODE_DEATHMATCH",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75fef" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsStreakDominationEASY",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 1 }],
"isGenerated": true,
"PVPMode": "PVPMODE_TEAMDEATHMATCH",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75ff0" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeKillsWhileInAirHARD",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 3 }],
"isGenerated": true,
"PVPMode": "PVPMODE_TEAMDEATHMATCH",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75ff3" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballCatchesMEDIUM",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 10 }],
"isGenerated": true,
"PVPMode": "PVPMODE_SPEEDBALL",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
},
{
"_id": { "$oid": "6639ca6967c1192987d75ff4" },
"challengeTypeRefID": "/Lotus/PVPChallengeTypes/PVPTimedChallengeSpeedballInterceptionsEASY",
"startDate": { "$date": { "$numberLong": "1715063401824" } },
"endDate": { "$date": { "$numberLong": "2000000000000" } },
"params": [{ "n": "ScriptParamValue", "v": 3 }],
"isGenerated": true,
"PVPMode": "PVPMODE_SPEEDBALL",
"subChallenges": [],
"Category": "PVPChallengeTypeCategory_DAILY"
}
],
"PersistentEnemies": [], "PersistentEnemies": [],
"PVPAlternativeModes": [], "PVPAlternativeModes": [],
"PVPActiveTournaments": [], "PVPActiveTournaments": [],

View File

@ -937,24 +937,35 @@
<input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" /> <input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" />
<label class="form-check-label" for="worldState.varziaFullyStocked" data-loc="worldState_varziaFullyStocked"></label> <label class="form-check-label" for="worldState.varziaFullyStocked" data-loc="worldState_varziaFullyStocked"></label>
</div> </div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="unfaithfulBugFixes.useAnniversaryTagForOldGoals" />
<label class="form-check-label" for="unfaithfulBugFixes.useAnniversaryTagForOldGoals" data-loc="worldState_useAnniversaryTagForOldGoals"></label>
<abbr data-loc-inc="worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.wolfHunt" /> <input class="form-check-input" type="checkbox" id="worldState.wolfHunt" />
<label class="form-check-label" for="worldState.wolfHunt" data-loc="worldState_wolfHunt"></label> <label class="form-check-label" for="worldState.wolfHunt" data-loc="worldState_wolfHunt"></label>
<abbr data-loc-inc="worldState_galleonOfGhouls"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr> <abbr data-loc-inc="worldState_galleonOfGhouls|worldState_orphixVenom|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.orphixVenom" />
<label class="form-check-label" for="worldState.orphixVenom" data-loc="worldState_orphixVenom"></label>
<abbr data-loc-inc="worldState_galleonOfGhouls|worldState_wolfHunt|worldState_proxyRebellion|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div> </div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.longShadow" /> <input class="form-check-input" type="checkbox" id="worldState.longShadow" />
<label class="form-check-label" for="worldState.longShadow" data-loc="worldState_longShadow"></label> <label class="form-check-label" for="worldState.longShadow" data-loc="worldState_longShadow"></label>
<abbr data-loc-inc="worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div> </div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="worldState.hallowedFlame" /> <input class="form-check-input" type="checkbox" id="worldState.hallowedFlame" />
<label class="form-check-label" for="worldState.hallowedFlame" data-loc="worldState_hallowedFlame"></label> <label class="form-check-label" for="worldState.hallowedFlame" data-loc="worldState_hallowedFlame"></label>
<abbr data-loc-inc="worldState_hallowedNightmares|worldState_dogDays"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr> <abbr data-loc-inc="worldState_hallowedNightmares|worldState_dogDays|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div> </div>
<div class="form-group mt-2 d-flex gap-2"> <div class="form-group mt-2 d-flex gap-2">
<div class="flex-fill"> <div class="flex-fill">
<label class="form-label" for="worldState.hallowedNightmares" data-loc="worldState_hallowedNightmares"></label> <label class="form-label" for="worldState.hallowedNightmares" data-loc="worldState_hallowedNightmares"></label>
<abbr data-loc-inc="worldState_hallowedFlame|worldState_dogDays"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr> <abbr data-loc-inc="worldState_hallowedFlame|worldState_dogDays|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<select class="form-control" id="worldState.hallowedNightmares" data-default="false"> <select class="form-control" id="worldState.hallowedNightmares" data-default="false">
<option value="true" data-loc="enabled"></option> <option value="true" data-loc="enabled"></option>
<option value="false" data-loc="disabled"></option> <option value="false" data-loc="disabled"></option>
@ -963,15 +974,16 @@
<div class="flex-fill"> <div class="flex-fill">
<label class="form-label" for="worldState.hallowedNightmaresRewardsOverride" data-loc="worldState_hallowedNightmaresRewards"></label> <label class="form-label" for="worldState.hallowedNightmaresRewardsOverride" data-loc="worldState_hallowedNightmaresRewards"></label>
<select class="form-control" id="worldState.hallowedNightmaresRewardsOverride" data-default="0"> <select class="form-control" id="worldState.hallowedNightmaresRewardsOverride" data-default="0">
<option value="0" data-loc="worldState_from_year" data-loc-year="2018"></option> <option value="0" data-loc="worldState_from_year" data-loc-replace="2018"></option>
<option value="1" data-loc="worldState_from_year" data-loc-year="2016"></option> <option value="1" data-loc="worldState_from_year" data-loc-replace="2016"></option>
<option value="2" data-loc="worldState_from_year" data-loc-year="2015"></option> <option value="2" data-loc="worldState_from_year" data-loc-replace="2015"></option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group mt-2 d-flex gap-2"> <div class="form-group mt-2 d-flex gap-2">
<div class="flex-fill"> <div class="flex-fill">
<label class="form-label" for="worldState.proxyRebellion" data-loc="worldState_proxyRebellion"></label> <label class="form-label" for="worldState.proxyRebellion" data-loc="worldState_proxyRebellion"></label>
<abbr data-loc-inc="worldState_anniversary|worldState_orphixVenom"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<select class="form-control" id="worldState.proxyRebellion" data-default="false"> <select class="form-control" id="worldState.proxyRebellion" data-default="false">
<option value="true" data-loc="enabled"></option> <option value="true" data-loc="enabled"></option>
<option value="false" data-loc="disabled"></option> <option value="false" data-loc="disabled"></option>
@ -980,14 +992,14 @@
<div class="flex-fill"> <div class="flex-fill">
<label class="form-label" for="worldState.proxyRebellionRewardsOverride" data-loc="worldState_proxyRebellionRewards"></label> <label class="form-label" for="worldState.proxyRebellionRewardsOverride" data-loc="worldState_proxyRebellionRewards"></label>
<select class="form-control" id="worldState.proxyRebellionRewardsOverride" data-default="0"> <select class="form-control" id="worldState.proxyRebellionRewardsOverride" data-default="0">
<option value="0" data-loc="worldState_from_year" data-loc-year="2019"></option> <option value="0" data-loc="worldState_from_year" data-loc-replace="2019"></option>
<option value="1" data-loc="worldState_from_year" data-loc-year="2018"></option> <option value="1" data-loc="worldState_from_year" data-loc-replace="2018"></option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group mt-2"> <div class="form-group mt-2">
<label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label> <label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label>
<abbr data-loc-inc="worldState_wolfHunt"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr> <abbr data-loc-inc="worldState_wolfHunt|worldState_anniversary|worldState_orphixVenom"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<select class="form-control" id="worldState.galleonOfGhouls" data-default="0"> <select class="form-control" id="worldState.galleonOfGhouls" data-default="0">
<option value="0" data-loc="disabled"></option> <option value="0" data-loc="disabled"></option>
<option value="1" data-loc="worldState_we1"></option> <option value="1" data-loc="worldState_we1"></option>
@ -995,6 +1007,21 @@
<option value="3" data-loc="worldState_we3"></option> <option value="3" data-loc="worldState_we3"></option>
</select> </select>
</div> </div>
<div class="form-group mt-2">
<label class="form-label" for="worldState.anniversary" data-loc="worldState_anniversary"></label>
<abbr data-loc-inc="worldState_useAnniversaryTagForOldGoals|worldState_wolfHunt|worldState_galleonOfGhouls|worldState_hallowedNightmares|worldState_hallowedFlame|worldState_dogDays|worldState_proxyRebellion|worldState_longShadow|worldState_orphixVenom"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<select class="form-control" id="worldState.anniversary" data-default="null">
<option value="null" data-loc="disabled"></option>
<option value="0" data-loc="worldState_week" data-loc-replace="1"></option>
<option value="1" data-loc="worldState_week" data-loc-replace="2"></option>
<option value="2" data-loc="worldState_week" data-loc-replace="3"></option>
<option value="3" data-loc="worldState_week" data-loc-replace="4"></option>
<option value="4" data-loc="worldState_week" data-loc-replace="5"></option>
<option value="5" data-loc="worldState_week" data-loc-replace="6"></option>
<option value="6" data-loc="worldState_week" data-loc-replace="7"></option>
<option value="7" data-loc="worldState_week" data-loc-replace="8"></option>
</select>
</div>
<div class="form-group mt-2"> <div class="form-group mt-2">
<label class="form-label" for="worldState.ghoulEmergenceOverride" data-loc="worldState_ghoulEmergence"></label> <label class="form-label" for="worldState.ghoulEmergenceOverride" data-loc="worldState_ghoulEmergence"></label>
<select class="form-control" id="worldState.ghoulEmergenceOverride" data-default="null"> <select class="form-control" id="worldState.ghoulEmergenceOverride" data-default="null">
@ -1022,7 +1049,7 @@
<div class="form-group mt-2 d-flex gap-2"> <div class="form-group mt-2 d-flex gap-2">
<div class="flex-fill"> <div class="flex-fill">
<label class="form-label" for="worldState.dogDaysOverride" data-loc="worldState_dogDays"></label> <label class="form-label" for="worldState.dogDaysOverride" data-loc="worldState_dogDays"></label>
<abbr data-loc-inc="worldState_hallowedFlame|worldState_hallowedNightmares"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr> <abbr data-loc-inc="worldState_hallowedFlame|worldState_hallowedNightmares|worldState_anniversary"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<select class="form-control" id="worldState.dogDaysOverride" data-default="null"> <select class="form-control" id="worldState.dogDaysOverride" data-default="null">
<option value="null" data-loc="normal"></option> <option value="null" data-loc="normal"></option>
<option value="true" data-loc="enabled"></option> <option value="true" data-loc="enabled"></option>
@ -1033,13 +1060,49 @@
<label class="form-label" for="worldState.dogDaysRewardsOverride" data-loc="worldState_dogDaysRewards"></label> <label class="form-label" for="worldState.dogDaysRewardsOverride" data-loc="worldState_dogDaysRewards"></label>
<select class="form-control" id="worldState.dogDaysRewardsOverride" data-default="null"> <select class="form-control" id="worldState.dogDaysRewardsOverride" data-default="null">
<option value="null" data-loc="normal"></option> <option value="null" data-loc="normal"></option>
<option value="3" data-loc="worldState_from_year" data-loc-year="2025"></option> <option value="3" data-loc="worldState_from_year" data-loc-replace="2025"></option>
<option value="2" data-loc="worldState_from_year" data-loc-year="2024"></option> <option value="2" data-loc="worldState_from_year" data-loc-replace="2024"></option>
<option value="1" data-loc="worldState_from_year" data-loc-year="2023"></option> <option value="1" data-loc="worldState_from_year" data-loc-replace="2023"></option>
<option value="0" data-loc="worldState_pre_year" data-loc-year="2023"></option> <option value="0" data-loc="worldState_pre_year" data-loc-replace="2023"></option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group mt-2 d-flex gap-2">
<div class="flex-fill">
<label class="form-label" for="worldState.bellyOfTheBeast" data-loc="worldState_bellyOfTheBeast"></label>
<select class="form-control" id="worldState.bellyOfTheBeast" data-default="false">
<option value="true" data-loc="enabled"></option>
<option value="false" data-loc="disabled"></option>
</select>
</div>
<div class="flex-fill">
<form class="form-group" onsubmit="doSaveConfigInt('worldState.bellyOfTheBeastProgressOverride'); return false;">
<label class="form-label" for="worldState.bellyOfTheBeastProgressOverride" data-loc="worldState_bellyOfTheBeastProgressOverride"></label>
<div class="input-group">
<input id="worldState.bellyOfTheBeastProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
</div>
</div>
<div class="form-group mt-2 d-flex gap-2">
<div class="flex-fill">
<label class="form-label" for="worldState.eightClaw" data-loc="worldState_eightClaw"></label>
<select class="form-control" id="worldState.eightClaw" data-default="false">
<option value="true" data-loc="enabled"></option>
<option value="false" data-loc="disabled"></option>
</select>
</div>
<div class="flex-fill">
<form class="form-group" onsubmit="doSaveConfigInt('worldState.eightClawProgressOverride'); return false;">
<label class="form-label" for="worldState.eightClawProgressOverride" data-loc="worldState_eightClawProgressOverride"></label>
<div class="input-group">
<input id="worldState.eightClawProgressOverride" class="form-control" type="number" min="0" max="100" data-default="0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
</div>
</div>
<div class="form-group mt-2"> <div class="form-group mt-2">
<label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label> <label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
<select class="form-control" id="worldState.eidolonOverride" data-default=""> <select class="form-control" id="worldState.eidolonOverride" data-default="">
@ -1121,7 +1184,10 @@
</div> </div>
</div> </div>
<div data-route="/webui/import" data-title="Import | OpenWF WebUI"> <div data-route="/webui/import" data-title="Import | OpenWF WebUI">
<p data-loc="import_importNote"></p> <p>
<span data-loc="import_importNote"></span>
<span data-loc="import_importNote2"></span>
</p>
<textarea class="form-control" id="import-inventory" style="height: calc(100vh - 300px)"></textarea> <textarea class="form-control" id="import-inventory" style="height: calc(100vh - 300px)"></textarea>
<button class="btn btn-primary mt-3" onclick="doImport();" data-loc="import_submit"></button> <button class="btn btn-primary mt-3" onclick="doImport();" data-loc="import_submit"></button>
<p class="mt-3 mb-1" data-loc="import_samples"></p> <p class="mt-3 mb-1" data-loc="import_samples"></p>

View File

@ -81,12 +81,15 @@ function openWebSocket() {
single.loadRoute("/webui/"); single.loadRoute("/webui/");
} }
} }
if ("logged_out" in msg) { if ("nonce_updated" in msg) {
sendAuth(); sendAuth();
} }
if ("update_inventory" in msg) { if ("update_inventory" in msg) {
updateInventory(); updateInventory();
} }
if ("logged_out" in msg) {
logout();
}
}; };
window.ws.onclose = function () { window.ws.onclose = function () {
ws_is_open = false; ws_is_open = false;
@ -145,13 +148,20 @@ function doLogout() {
} }
} }
function renameAccount() { function renameAccount(taken_name) {
const newname = window.prompt(loc("code_changeNameConfirm")); const newname = window.prompt(
(taken_name ? loc("code_changeNameRetry").split("|NAME|").join(taken_name) + " " : "") +
loc("code_changeNameConfirm")
);
if (newname) { if (newname) {
revalidateAuthz().then(() => { revalidateAuthz().then(() => {
fetch("/custom/renameAccount?" + window.authz + "&newname=" + newname).then(() => { fetch("/custom/renameAccount?" + window.authz + "&newname=" + newname).then(res => {
if (res.status == 409) {
renameAccount(newname);
} else {
$(".displayname").text(newname); $(".displayname").text(newname);
updateLocElements(); updateLocElements();
}
}); });
}); });
} }
@ -206,12 +216,12 @@ function updateLocElements() {
const incWith = elm const incWith = elm
.getAttribute("data-loc-inc") .getAttribute("data-loc-inc")
.split("|") .split("|")
.map(key => loc(key)) .map(key => loc(key).replace(/<[^>]+>/g, ""))
.join(", "); .join(", ");
elm.title = `${loc("worldState_incompatibleWith")} ${incWith}`; elm.title = `${loc("worldState_incompatibleWith")} ${incWith}`;
}); });
document.querySelectorAll("[data-loc-year]").forEach(elm => { document.querySelectorAll("[data-loc-replace]").forEach(elm => {
elm.innerHTML = elm.innerHTML.replace("|YEAR|", elm.getAttribute("data-loc-year")); elm.innerHTML = elm.innerHTML.replace("|VAL|", elm.getAttribute("data-loc-replace"));
}); });
} }
@ -662,7 +672,9 @@ function updateInventory() {
"KubrowPets" "KubrowPets"
].forEach(category => { ].forEach(category => {
document.getElementById(category + "-list").innerHTML = ""; document.getElementById(category + "-list").innerHTML = "";
data[category].forEach(item => { data[category]
.sort((a, b) => (b.Favorite ? 1 : 0) - (a.Favorite ? 1 : 0))
.forEach(item => {
const tr = document.createElement("tr"); const tr = document.createElement("tr");
tr.setAttribute("data-item-type", item.ItemType); tr.setAttribute("data-item-type", item.ItemType);
{ {
@ -709,7 +721,8 @@ function updateInventory() {
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);
if (exaltedItem) { if (exaltedItem) {
const exaltedCap = itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; const exaltedCap =
itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000;
if (exaltedItem.XP < exaltedCap) { if (exaltedItem.XP < exaltedCap) {
anyExaltedMissingXP = true; anyExaltedMissingXP = true;
break; break;
@ -729,7 +742,9 @@ function updateInventory() {
} }
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
);
if (exaltedItem) { if (exaltedItem) {
const exaltedCap = const exaltedCap =
itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000;
@ -756,11 +771,14 @@ function updateInventory() {
} }
if ( if (
["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(category) || ["Suits", "LongGuns", "Pistols", "Melee", "SpaceGuns", "SpaceMelee"].includes(
category
) ||
modularWeapons.includes(item.ItemType) modularWeapons.includes(item.ItemType)
) { ) {
const a = document.createElement("a"); const a = document.createElement("a");
a.href = "/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid; a.href =
"/webui/detailedView?productCategory=" + category + "&itemId=" + item.ItemId.$oid;
a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`; a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
td.appendChild(a); td.appendChild(a);
} }

View File

@ -10,6 +10,7 @@ dict = {
code_loginFail: `Anmeldung fehlgeschlagen. Bitte überprüfe deine Angaben.`, code_loginFail: `Anmeldung fehlgeschlagen. Bitte überprüfe deine Angaben.`,
code_regFail: `Registrierung fehlgeschlagen. Account existiert bereits?`, code_regFail: `Registrierung fehlgeschlagen. Account existiert bereits?`,
code_changeNameConfirm: `In welchen Namen möchtest du deinen Account umbenennen?`, code_changeNameConfirm: `In welchen Namen möchtest du deinen Account umbenennen?`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `Bist du sicher, dass du deinen Account |DISPLAYNAME| (|EMAIL|) löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.`, code_deleteAccountConfirm: `Bist du sicher, dass du deinen Account |DISPLAYNAME| (|EMAIL|) löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.`,
code_archgun: `Arch-Gewehr`, code_archgun: `Arch-Gewehr`,
code_melee: `Nahkampf`, code_melee: `Nahkampf`,
@ -246,19 +247,27 @@ dict = {
worldState_baroTennoConRelay: `Baros TennoCon Relais`, worldState_baroTennoConRelay: `Baros TennoCon Relais`,
worldState_starDays: `Sternen-Tage`, worldState_starDays: `Sternen-Tage`,
worldState_galleonOfGhouls: `Galeone der Ghule`, worldState_galleonOfGhouls: `Galeone der Ghule`,
worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `Ghul Ausrottung`, worldState_ghoulEmergence: `Ghul Ausrottung`,
worldState_plagueStar: `Plagenstern`, worldState_plagueStar: `Plagenstern`,
worldState_dogDays: `Hitzefrei`, worldState_dogDays: `Hitzefrei`,
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`, worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
worldState_wolfHunt: `Wolfsjagd (2025)`, worldState_wolfHunt: `Wolfsjagd (2025)`,
worldState_orphixVenom: `Orphix Gift`,
worldState_longShadow: `Lange Schatten`, worldState_longShadow: `Lange Schatten`,
worldState_hallowedFlame: `Geweihte Flamme`, worldState_hallowedFlame: `Geweihte Flamme`,
worldState_hallowedNightmares: `Geweihte Albträume`, worldState_hallowedNightmares: `Geweihte Albträume`,
worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`, worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
worldState_proxyRebellion: `Proxy-Rebellion`, worldState_proxyRebellion: `Proxy-Rebellion`,
worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`, worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
worldState_from_year: `[UNTRANSLATED] from |YEAR|`, worldState_bellyOfTheBeast: `Das Innere der Bestie`,
worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
worldState_eightClaw: `Acht Klauen`,
worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
worldState_from_year: `[UNTRANSLATED] from |VAL|`,
worldState_pre_year: `[UNTRANSLATED] pre |VAL|`,
worldState_week: `[UNTRANSLATED] Week |VAL|`,
worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
enabled: `Aktiviert`, enabled: `Aktiviert`,
disabled: `Deaktiviert`, disabled: `Deaktiviert`,
@ -303,7 +312,8 @@ dict = {
worldState_varziaFullyStocked: `Varzia hat volles Inventar`, worldState_varziaFullyStocked: `Varzia hat volles Inventar`,
worldState_varziaOverride: `Varzia-Angebotsüberschreibung`, worldState_varziaOverride: `Varzia-Angebotsüberschreibung`,
import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, <b>werden in deinem Account überschrieben</b>.`, import_importNote: `[UNTRANSLATED] You can provide a full or partial <code>inventory.php</code> or <code>getShip.php</code> response (client representation) here.`,
import_importNote2: `Alle Felder, die vom Importer unterstützt werden, <b>werden in deinem Account überschrieben</b>.`,
import_submit: `Absenden`, import_submit: `Absenden`,
import_samples: `Beispiele:`, import_samples: `Beispiele:`,
import_samples_maxFocus: `Alle Fokus-Schulen maximiert`, import_samples_maxFocus: `Alle Fokus-Schulen maximiert`,

View File

@ -9,6 +9,7 @@ dict = {
code_loginFail: `Login failed. Double-check the email and password.`, code_loginFail: `Login failed. Double-check the email and password.`,
code_regFail: `Registration failed. Account already exists?`, code_regFail: `Registration failed. Account already exists?`,
code_changeNameConfirm: `What would you like to change your account name to?`, code_changeNameConfirm: `What would you like to change your account name to?`,
code_changeNameRetry: `|NAME| is already taken.`,
code_deleteAccountConfirm: `Are you sure you want to delete your account |DISPLAYNAME| (|EMAIL|)? This action cannot be undone.`, code_deleteAccountConfirm: `Are you sure you want to delete your account |DISPLAYNAME| (|EMAIL|)? This action cannot be undone.`,
code_archgun: `Archgun`, code_archgun: `Archgun`,
code_melee: `Melee`, code_melee: `Melee`,
@ -245,19 +246,27 @@ dict = {
worldState_baroTennoConRelay: `Baro's TennoCon Relay`, worldState_baroTennoConRelay: `Baro's TennoCon Relay`,
worldState_starDays: `Star Days`, worldState_starDays: `Star Days`,
worldState_galleonOfGhouls: `Galleon of Ghouls`, worldState_galleonOfGhouls: `Galleon of Ghouls`,
worldState_anniversary: `Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `Ghoul Purge`, worldState_ghoulEmergence: `Ghoul Purge`,
worldState_plagueStar: `Plague Star`, worldState_plagueStar: `Plague Star`,
worldState_dogDays: `Dog Days`, worldState_dogDays: `Dog Days`,
worldState_dogDaysRewards: `Dog Days Rewards`, worldState_dogDaysRewards: `Dog Days Rewards`,
worldState_wolfHunt: `Wolf Hunt (2025)`, worldState_wolfHunt: `Wolf Hunt (2025)`,
worldState_orphixVenom: `Orphix Venom`,
worldState_longShadow: `Long Shadow`, worldState_longShadow: `Long Shadow`,
worldState_hallowedFlame: `Hallowed Flame`, worldState_hallowedFlame: `Hallowed Flame`,
worldState_hallowedNightmares: `Hallowed Nightmares`, worldState_hallowedNightmares: `Hallowed Nightmares`,
worldState_hallowedNightmaresRewards: `Hallowed Nightmares Rewards`, worldState_hallowedNightmaresRewards: `Hallowed Nightmares Rewards`,
worldState_proxyRebellion: `Proxy Rebellion`, worldState_proxyRebellion: `Proxy Rebellion`,
worldState_proxyRebellionRewards: `Proxy Rebellion Rewards`, worldState_proxyRebellionRewards: `Proxy Rebellion Rewards`,
worldState_from_year: `from |YEAR|`, worldState_bellyOfTheBeast: `Belly of the Beast`,
worldState_pre_year: `pre |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `Belly of the Beast Progress`,
worldState_eightClaw: `Eight Claw`,
worldState_eightClawProgressOverride: `Eight Claw Progress`,
worldState_from_year: `from |VAL|`,
worldState_pre_year: `pre |VAL|`,
worldState_week: `Week |VAL|`,
worldState_incompatibleWith: `Incompatible with:`, worldState_incompatibleWith: `Incompatible with:`,
enabled: `Enabled`, enabled: `Enabled`,
disabled: `Disabled`, disabled: `Disabled`,
@ -302,7 +311,8 @@ dict = {
worldState_varziaFullyStocked: `Varzia Fully Stocked`, worldState_varziaFullyStocked: `Varzia Fully Stocked`,
worldState_varziaOverride: `Varzia Rotation Override`, worldState_varziaOverride: `Varzia Rotation Override`,
import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer <b>will be overwritten</b> in your account.`, import_importNote: `You can provide a full or partial <code>inventory.php</code> or <code>getShip.php</code> response (client representation) here.`,
import_importNote2: `All fields that are supported by the importer <b>will be overwritten</b> in your account.`,
import_submit: `Submit`, import_submit: `Submit`,
import_samples: `Samples:`, import_samples: `Samples:`,
import_samples_maxFocus: `All Focus Schools Maxed Out`, import_samples_maxFocus: `All Focus Schools Maxed Out`,

View File

@ -10,6 +10,7 @@ dict = {
code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`, code_loginFail: `Error al iniciar sesión. Verifica el correo electrónico y la contraseña.`,
code_regFail: `Error al registrar la cuenta. ¿Ya existe una cuenta con este correo?`, code_regFail: `Error al registrar la cuenta. ¿Ya existe una cuenta con este correo?`,
code_changeNameConfirm: `¿Qué nombre te gustaría ponerle a tu cuenta?`, code_changeNameConfirm: `¿Qué nombre te gustaría ponerle a tu cuenta?`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `¿Estás seguro de que deseas eliminar tu cuenta |DISPLAYNAME| (|EMAIL|)? Esta acción es permanente.`, code_deleteAccountConfirm: `¿Estás seguro de que deseas eliminar tu cuenta |DISPLAYNAME| (|EMAIL|)? Esta acción es permanente.`,
code_archgun: `Archcañón`, code_archgun: `Archcañón`,
code_melee: `Cuerpo a cuerpo`, code_melee: `Cuerpo a cuerpo`,
@ -246,19 +247,27 @@ dict = {
worldState_baroTennoConRelay: `Repetidor de Baro de la TennoCon`, worldState_baroTennoConRelay: `Repetidor de Baro de la TennoCon`,
worldState_starDays: `Días estelares`, worldState_starDays: `Días estelares`,
worldState_galleonOfGhouls: `Galeón de Gules`, worldState_galleonOfGhouls: `Galeón de Gules`,
worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `Purga de Gules`, worldState_ghoulEmergence: `Purga de Gules`,
worldState_plagueStar: `Estrella Infestada`, worldState_plagueStar: `Estrella Infestada`,
worldState_dogDays: `Canícula`, worldState_dogDays: `Canícula`,
worldState_dogDaysRewards: `Recompensas de Canícula`, worldState_dogDaysRewards: `Recompensas de Canícula`,
worldState_wolfHunt: `Cacería del Lobo (2025)`, worldState_wolfHunt: `Cacería del Lobo (2025)`,
worldState_orphixVenom: `Veneno de Orphix`,
worldState_longShadow: `Sombra Prolongada`, worldState_longShadow: `Sombra Prolongada`,
worldState_hallowedFlame: `Llama Sagrada`, worldState_hallowedFlame: `Llama Sagrada`,
worldState_hallowedNightmares: `Pesadillas Sagradas`, worldState_hallowedNightmares: `Pesadillas Sagradas`,
worldState_hallowedNightmaresRewards: `Recompensas de Pesadillas Sagradas`, worldState_hallowedNightmaresRewards: `Recompensas de Pesadillas Sagradas`,
worldState_proxyRebellion: `Rebelión Proxy`, worldState_proxyRebellion: `Rebelión Proxy`,
worldState_proxyRebellionRewards: `Recompensas de Rebelión Proxy`, worldState_proxyRebellionRewards: `Recompensas de Rebelión Proxy`,
worldState_from_year: `de |YEAR|`, worldState_bellyOfTheBeast: `Vientre de la Bestia`,
worldState_pre_year: `antes de |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
worldState_eightClaw: `Octava Garra`,
worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
worldState_from_year: `de |VAL|`,
worldState_pre_year: `antes de |VAL|`,
worldState_week: `[UNTRANSLATED] Week |VAL|`,
worldState_incompatibleWith: `No compatible con:`, worldState_incompatibleWith: `No compatible con:`,
enabled: `Activado`, enabled: `Activado`,
disabled: `Desactivado`, disabled: `Desactivado`,
@ -303,7 +312,8 @@ dict = {
worldState_varziaFullyStocked: `Varzia con stock completo`, worldState_varziaFullyStocked: `Varzia con stock completo`,
worldState_varziaOverride: `Cambio en rotación de Varzia`, worldState_varziaOverride: `Cambio en rotación de Varzia`,
import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador <b>serán sobrescritos</b> en tu cuenta.`, import_importNote: `[UNTRANSLATED] You can provide a full or partial <code>inventory.php</code> or <code>getShip.php</code> response (client representation) here.`,
import_importNote2: `Todos los campos compatibles con el importador <b>serán sobrescritos</b> en tu cuenta.`,
import_submit: `Enviar`, import_submit: `Enviar`,
import_samples: `Muestras:`, import_samples: `Muestras:`,
import_samples_maxFocus: `Todas las escuelas de enfoque al máximo`, import_samples_maxFocus: `Todas las escuelas de enfoque al máximo`,

View File

@ -10,6 +10,7 @@ dict = {
code_loginFail: `Connexion échouée. Vérifiez le mot de passe.`, code_loginFail: `Connexion échouée. Vérifiez le mot de passe.`,
code_regFail: `Enregistrement impossible. Compte existant?`, code_regFail: `Enregistrement impossible. Compte existant?`,
code_changeNameConfirm: `Nouveau nom du compte :`, code_changeNameConfirm: `Nouveau nom du compte :`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `Supprimer |DISPLAYNAME| (|EMAIL|) ? Cette action est irreversible.`, code_deleteAccountConfirm: `Supprimer |DISPLAYNAME| (|EMAIL|) ? Cette action est irreversible.`,
code_archgun: `Archgun`, code_archgun: `Archgun`,
code_melee: `Melee`, code_melee: `Melee`,
@ -246,19 +247,27 @@ dict = {
worldState_baroTennoConRelay: `Relais Baro TennoCon`, worldState_baroTennoConRelay: `Relais Baro TennoCon`,
worldState_starDays: `Jours Stellaires`, worldState_starDays: `Jours Stellaires`,
worldState_galleonOfGhouls: `Galion des Goules`, worldState_galleonOfGhouls: `Galion des Goules`,
worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `Purge des Goules`, worldState_ghoulEmergence: `Purge des Goules`,
worldState_plagueStar: `Fléau Céleste`, worldState_plagueStar: `Fléau Céleste`,
worldState_dogDays: `Bataille d'Eau`, worldState_dogDays: `Bataille d'Eau`,
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`, worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
worldState_wolfHunt: `Chasse au Loup (2025)`, worldState_wolfHunt: `Chasse au Loup (2025)`,
worldState_orphixVenom: `Venin Orphix`,
worldState_longShadow: `La Propagation des Ombres`, worldState_longShadow: `La Propagation des Ombres`,
worldState_hallowedFlame: `Flamme Hantée`, worldState_hallowedFlame: `Flamme Hantée`,
worldState_hallowedNightmares: `Cauchemars Hantés`, worldState_hallowedNightmares: `Cauchemars Hantés`,
worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`, worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
worldState_proxyRebellion: `Rébellion Proxy`, worldState_proxyRebellion: `Rébellion Proxy`,
worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`, worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
worldState_from_year: `[UNTRANSLATED] from |YEAR|`, worldState_bellyOfTheBeast: `Ventre de la Bête`,
worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
worldState_eightClaw: `Huitième Griffe`,
worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
worldState_from_year: `[UNTRANSLATED] from |VAL|`,
worldState_pre_year: `[UNTRANSLATED] pre |VAL|`,
worldState_week: `[UNTRANSLATED] Week |VAL|`,
worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
enabled: `Activé`, enabled: `Activé`,
disabled: `Désactivé`, disabled: `Désactivé`,
@ -303,7 +312,8 @@ dict = {
worldState_varziaFullyStocked: `Stock de Varzia au max`, worldState_varziaFullyStocked: `Stock de Varzia au max`,
worldState_varziaOverride: `Rotation de Varzia`, worldState_varziaOverride: `Rotation de Varzia`,
import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire <b>écraseront celles présentes dans la base de données</b>.`, import_importNote: `[UNTRANSLATED] You can provide a full or partial <code>inventory.php</code> or <code>getShip.php</code> response (client representation) here.`,
import_importNote2: `[UNTRANSLATED] All fields that are supported by the importer <b>will be overwritten</b> in your account.`,
import_submit: `Soumettre`, import_submit: `Soumettre`,
import_samples: `Échantillons :`, import_samples: `Échantillons :`,
import_samples_maxFocus: `Toutes les écoles de focus au rang max`, import_samples_maxFocus: `Toutes les écoles de focus au rang max`,

View File

@ -10,6 +10,7 @@ dict = {
code_loginFail: `Не удалось войти. Проверьте адрес электронной почты и пароль.`, code_loginFail: `Не удалось войти. Проверьте адрес электронной почты и пароль.`,
code_regFail: `Не удалось зарегистрироваться. Учетная запись уже существует?`, code_regFail: `Не удалось зарегистрироваться. Учетная запись уже существует?`,
code_changeNameConfirm: `Какое имя вы хотите установить для своей учетной записи?`, code_changeNameConfirm: `Какое имя вы хотите установить для своей учетной записи?`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `Вы уверены, что хотите удалить аккаунт |DISPLAYNAME| (|EMAIL|)? Это действие нельзя отменить.`, code_deleteAccountConfirm: `Вы уверены, что хотите удалить аккаунт |DISPLAYNAME| (|EMAIL|)? Это действие нельзя отменить.`,
code_archgun: `Арч-Пушка`, code_archgun: `Арч-Пушка`,
code_melee: `Ближний бой`, code_melee: `Ближний бой`,
@ -25,12 +26,12 @@ dict = {
code_traumaticPeculiar: `Травмирующая Странность`, code_traumaticPeculiar: `Травмирующая Странность`,
code_starter: `|MOD| (Повреждённый)`, code_starter: `|MOD| (Повреждённый)`,
code_badItem: `(Самозванец)`, code_badItem: `(Самозванец)`,
code_maxRank: `Максимальный ранг`, code_maxRank: `Макс. ранг`,
code_rename: `Переименовать`, code_rename: `Переименовать`,
code_renamePrompt: `Введите новое имя:`, code_renamePrompt: `Введите новое имя:`,
code_remove: `Удалить`, code_remove: `Удалить`,
code_addItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов на ваш аккаунт?`, code_addItemsConfirm: `Вы уверены, что хотите добавить |COUNT| предметов на ваш аккаунт?`,
code_succRankUp: `Ранг успешно повышен`, code_succRankUp: `Ранг успешно повышен.`,
code_noEquipmentToRankUp: `Нет снаряжения для повышения ранга.`, code_noEquipmentToRankUp: `Нет снаряжения для повышения ранга.`,
code_succAdded: `Успешно добавлено.`, code_succAdded: `Успешно добавлено.`,
code_succRemoved: `Успешно удалено.`, code_succRemoved: `Успешно удалено.`,
@ -39,11 +40,11 @@ dict = {
code_rerollsNumber: `Количество рероллов`, code_rerollsNumber: `Количество рероллов`,
code_viewStats: `Просмотр характеристики`, code_viewStats: `Просмотр характеристики`,
code_rank: `Ранг`, code_rank: `Ранг`,
code_rankUp: `Повысить Ранг`, code_rankUp: `Повысить ранг`,
code_rankDown: `Понизить Ранг`, code_rankDown: `Понизить ранг`,
code_count: `Количество`, code_count: `Количество`,
code_focusAllUnlocked: `Все школы фокуса уже разблокированы.`, code_focusAllUnlocked: `Все школы Фокуса уже разблокированы.`,
code_focusUnlocked: `Разблокировано |COUNT| новых школ фокуса! Для отображения изменений в игре потребуется обновление инвентаря. Посещение навигации — самый простой способ этого добиться.`, code_focusUnlocked: `Разблокировано |COUNT| новых школ Фокуса! Для отображения изменений в игре потребуется обновление инвентаря. Посещение навигации — самый простой способ этого добиться.`,
code_addModsConfirm: `Вы уверены, что хотите добавить |COUNT| модов на ваш аккаунт?`, code_addModsConfirm: `Вы уверены, что хотите добавить |COUNT| модов на ваш аккаунт?`,
code_succImport: `Успешно импортировано.`, code_succImport: `Успешно импортировано.`,
code_succRelog: `Готово. Обратите внимание, что вам нужно будет перезайти, чтобы увидеть изменения в игре.`, code_succRelog: `Готово. Обратите внимание, что вам нужно будет перезайти, чтобы увидеть изменения в игре.`,
@ -83,7 +84,7 @@ dict = {
inventory_pistols: `Вторичное оружие`, inventory_pistols: `Вторичное оружие`,
inventory_melee: `Оружие ближнего боя`, inventory_melee: `Оружие ближнего боя`,
inventory_spaceSuits: `Арчвинги`, inventory_spaceSuits: `Арчвинги`,
inventory_spaceGuns: `Оружие арчвинга`, inventory_spaceGuns: `Оружие Арчвинга`,
inventory_spaceMelee: `Оружие ближнего боя арчвинга`, inventory_spaceMelee: `Оружие ближнего боя арчвинга`,
inventory_mechSuits: `Некрамехи`, inventory_mechSuits: `Некрамехи`,
inventory_sentinels: `Стражи`, inventory_sentinels: `Стражи`,
@ -94,21 +95,21 @@ dict = {
inventory_kubrowPets: `Звери`, inventory_kubrowPets: `Звери`,
inventory_evolutionProgress: `Прогресс эволюции Инкарнонов`, inventory_evolutionProgress: `Прогресс эволюции Инкарнонов`,
inventory_Boosters: `Бустеры`, inventory_Boosters: `Бустеры`,
inventory_bulkAddSuits: `Добавить отсутствующие варфреймы`, inventory_bulkAddSuits: `Добавить отсутствующие Варфреймы`,
inventory_bulkAddWeapons: `Добавить отсутствующее оружие`, inventory_bulkAddWeapons: `Добавить отсутствующее оружие`,
inventory_bulkAddSpaceSuits: `Добавить отсутствующие арчвинги`, inventory_bulkAddSpaceSuits: `Добавить отсутствующие Арчвинги`,
inventory_bulkAddSpaceWeapons: `Добавить отсутствующее оружие арчвингов`, inventory_bulkAddSpaceWeapons: `Добавить отсутствующее оружие Арчвингов`,
inventory_bulkAddSentinels: `Добавить отсутствующих стражей`, inventory_bulkAddSentinels: `Добавить отсутствующих Стражей`,
inventory_bulkAddSentinelWeapons: `Добавить отсутствующее оружие стражей`, inventory_bulkAddSentinelWeapons: `Добавить отсутствующее оружие Стражей`,
inventory_bulkAddEvolutionProgress: `Добавить отсутствующий прогресс эволюции Инкарнонов`, inventory_bulkAddEvolutionProgress: `Добавить отсутствующий прогресс эволюции Инкарнонов`,
inventory_bulkRankUpSuits: `Максимальный ранг всех варфреймов`, inventory_bulkRankUpSuits: `Макс. ранг всех Варфреймов`,
inventory_bulkRankUpWeapons: `Максимальный ранг всего оружия`, inventory_bulkRankUpWeapons: `Макс. ранг всего оружия`,
inventory_bulkRankUpSpaceSuits: `Максимальный ранг всех арчвингов`, inventory_bulkRankUpSpaceSuits: `Макс. ранг всех Арчвингов`,
inventory_bulkRankUpSpaceWeapons: `Максимальный ранг всего оружия арчвингов`, inventory_bulkRankUpSpaceWeapons: `Макс. ранг всего оружия Арчвингов`,
inventory_bulkRankUpSentinels: `Максимальный ранг всех стражей`, inventory_bulkRankUpSentinels: `Макс. ранг всех Стражей`,
inventory_bulkRankUpSentinelWeapons: `Максимальный ранг всего оружия стражей`, inventory_bulkRankUpSentinelWeapons: `Макс. ранг всего оружия Стражей`,
inventory_bulkRankUpEvolutionProgress: `Максимальный ранг всех эволюций Инкарнонов`, inventory_bulkRankUpEvolutionProgress: `Макс. ранг всех эволюций Инкарнонов`,
inventory_maxPlexus: `Максимальный ранг Плексуса`, inventory_maxPlexus: `Макс. ранг Плексуса`,
quests_list: `Квесты`, quests_list: `Квесты`,
quests_completeAll: `Завершить все квесты`, quests_completeAll: `Завершить все квесты`,
@ -121,53 +122,53 @@ dict = {
currency_PrimeTokens: `Королевские Айя`, currency_PrimeTokens: `Королевские Айя`,
currency_owned: `У тебя |COUNT|.`, currency_owned: `У тебя |COUNT|.`,
detailedView_archonShardsLabel: `Ячейки осколков архонта`, detailedView_archonShardsLabel: `Ячейки осколков Архонта`,
detailedView_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`, detailedView_archonShardsDescription: `Вы можете использовать эти неограниченные ячейки для установки множества улучшений.`,
detailedView_archonShardsDescription2: `Обратите внимание: каждый осколок архонта применяется с задержкой при загрузке.`, detailedView_archonShardsDescription2: `Обратите внимание: каждый осколок Архонта применяется с задержкой при загрузке.`,
detailedView_valenceBonusLabel: `Бонус Валентности`, detailedView_valenceBonusLabel: `Бонус Валентности`,
detailedView_valenceBonusDescription: `Вы можете установить или убрать бонус валентности с вашего оружия.`, detailedView_valenceBonusDescription: `Вы можете установить или убрать бонус Валентности с вашего оружия.`,
detailedView_modularPartsLabel: `Изменить Модульные Части`, detailedView_modularPartsLabel: `Изменить модульные части`,
detailedView_suitInvigorationLabel: `Воодушевление Варфрейма`, detailedView_suitInvigorationLabel: `Воодушевление Варфрейма`,
detailedView_loadoutLabel: `Конфигурации`, detailedView_loadoutLabel: `Конфигурации`,
invigorations_offensive_AbilityStrength: `+200% Сила Способностей`, invigorations_offensive_AbilityStrength: `+200% к силе способностей.`,
invigorations_offensive_AbilityRange: `+100% Радиус Способностей`, invigorations_offensive_AbilityRange: `+100% к зоне поражения способностей.`,
invigorations_offensive_AbilityDuration: `+100% Длительность Способностей`, invigorations_offensive_AbilityDuration: `+100% к длительности способностей.`,
invigorations_offensive_MeleeDamage: `+250% Урон Ближнего Боя`, invigorations_offensive_MeleeDamage: `+250% к урону оружия ближнего боя.`,
invigorations_offensive_PrimaryDamage: `+250% Урон Основного Оружия`, invigorations_offensive_PrimaryDamage: `+250% к урону основного оружия.`,
invigorations_offensive_SecondaryDamage: `+250% Урон Вторичного Оружия`, invigorations_offensive_SecondaryDamage: `+250% к урону вторичного оружия.`,
invigorations_offensive_PrimaryCritChance: `+200% Шанс Критического Урона Основного Оружия`, invigorations_offensive_PrimaryCritChance: `+200% к шансу крит. урона для основного оружия.`,
invigorations_offensive_SecondaryCritChance: `+200% Шанс Критического Урона Вторичного Оружия`, invigorations_offensive_SecondaryCritChance: `+200% к шансу крит. урона для вторичного оружия.`,
invigorations_offensive_MeleeCritChance: `+200% Шанс Критического Урона Ближнего Боя`, invigorations_offensive_MeleeCritChance: `+200% у шансу крит. урона для оружия ближнего боя.`,
invigorations_utility_AbilityEfficiency: `+75% Энергоэффективность Способностей`, invigorations_utility_AbilityEfficiency: `+75% к энергоэффективности способностей.`,
invigorations_utility_SprintSpeed: `+75% Скорость Бега`, invigorations_utility_SprintSpeed: `+75% к скорости бега.`,
invigorations_utility_ParkourVelocity: `+75% Скорость Паркура`, invigorations_utility_ParkourVelocity: `+75% к скорости паркура.`,
invigorations_utility_HealthMax: `+1000 Здоровья`, invigorations_utility_HealthMax: `+1000 к здоровью.`,
invigorations_utility_EnergyMax: `+200% Максимум Энергии`, invigorations_utility_EnergyMax: `+200% к макс. запасу энергии.`,
invigorations_utility_StatusImmune: `Иммунитет к Эффектам Статуса`, invigorations_utility_StatusImmune: `Иммунитет к статусным эффектам.`,
invigorations_utility_ReloadSpeed: `+75% Скорость Перезарядки`, invigorations_utility_ReloadSpeed: `+75% к скорости перезарядки.`,
invigorations_utility_HealthRegen: `+25 Здоровья в секунду`, invigorations_utility_HealthRegen: `+25 к регенерации здоровья в секунду.`,
invigorations_utility_ArmorMax: `+1000 Брони`, invigorations_utility_ArmorMax: `+1000 к брони.`,
invigorations_utility_Jumps: `+5 Сбросов Прыжков`, invigorations_utility_Jumps: `+5 сбросов прыжка.`,
invigorations_utility_EnergyRegen: `+2 Энергии в секунду`, invigorations_utility_EnergyRegen: `+2 к регенерации энергии в секунду.`,
invigorations_offensiveLabel: `Атакующее Улучшение`, invigorations_offensiveLabel: `Атакующее улучшение`,
invigorations_defensiveLabel: `Вспомогательное Улучшение`, invigorations_defensiveLabel: `Вспомогательное улучшение`,
invigorations_expiryLabel: `Срок действия Воодушевления (необязательно)`, invigorations_expiryLabel: `Срок действия Воодушевления (необязательно)`,
abilityOverride_label: `Переопределение способности`, abilityOverride_label: `Переопределение способности`,
abilityOverride_onSlot: `в ячейке`, abilityOverride_onSlot: `в ячейке`,
mods_addRiven: `Добавить Мод Разлома`, mods_addRiven: `Добавить мод Разлома`,
mods_fingerprint: `Отпечаток`, mods_fingerprint: `Отпечаток`,
mods_fingerprintHelp: `Нужна помощь с отпечатком?`, mods_fingerprintHelp: `Нужна помощь с отпечатком?`,
mods_rivens: `Моды Разлома`, mods_rivens: `Моды Разлома`,
mods_mods: `Моды`, mods_mods: `Моды`,
mods_addMax: `Добавить максимально улучшенный`, mods_addMax: `Добавить макс. улучшенный`,
mods_addMissingUnrankedMods: `Добавить недостающие моды без ранга`, mods_addMissingUnrankedMods: `Добавить недостающие моды без ранга`,
mods_removeUnranked: `Удалить моды без ранга`, mods_removeUnranked: `Удалить моды без ранга`,
mods_addMissingMaxRankMods: `Добавить недостающие моды максимального ранга`, mods_addMissingMaxRankMods: `Добавить недостающие моды макс. ранга`,
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: `Пропустить обучение`,
@ -175,14 +176,14 @@ dict = {
cheats_unlockAllScans: `Разблокировать все сканирования`, cheats_unlockAllScans: `Разблокировать все сканирования`,
cheats_unlockAllMissions: `Разблокировать все миссии`, cheats_unlockAllMissions: `Разблокировать все миссии`,
cheats_unlockAllMissions_ok: `Успех. Пожалуйста, обратите внимание, что вам нужно будет войти в Додзё/Реле или перезайти, чтобы клиент обновил звездную карту.`, cheats_unlockAllMissions_ok: `Успех. Пожалуйста, обратите внимание, что вам нужно будет войти в Додзё/Реле или перезайти, чтобы клиент обновил звездную карту.`,
cheats_infiniteCredits: `Бесконечные кредиты`, cheats_infiniteCredits: `Бесконечные Кредиты`,
cheats_infinitePlatinum: `Бесконечная платина`, cheats_infinitePlatinum: `Бесконечная Платина`,
cheats_infiniteEndo: `Бесконечное эндо`, cheats_infiniteEndo: `Бесконечное Эндо`,
cheats_infiniteRegalAya: `Бесконечная Королевская Айя`, cheats_infiniteRegalAya: `Бесконечная Королевская Айя`,
cheats_infiniteHelminthMaterials: `Бесконечные Секреции Гельминта`, cheats_infiniteHelminthMaterials: `Бесконечные секреции Гельминта`,
cheats_claimingBlueprintRefundsIngredients: `Возврат ингредиентов чертежей`, cheats_claimingBlueprintRefundsIngredients: `Возврат ингредиентов чертежей`,
cheats_dontSubtractPurchaseCreditCost: `Не вычитать стоимость кредитов при покупке`, cheats_dontSubtractPurchaseCreditCost: `Не вычитать стоимость Кредитов при покупке`,
cheats_dontSubtractPurchasePlatinumCost: `Не вычитать стоимость платины при покупке`, cheats_dontSubtractPurchasePlatinumCost: `Не вычитать стоимость Платины при покупке`,
cheats_dontSubtractPurchaseItemCost: `Не вычитать стоимость предметов при покупке`, cheats_dontSubtractPurchaseItemCost: `Не вычитать стоимость предметов при покупке`,
cheats_dontSubtractPurchaseStandingCost: `Не вычитать стоимость репутации при покупке`, cheats_dontSubtractPurchaseStandingCost: `Не вычитать стоимость репутации при покупке`,
cheats_dontSubtractVoidTraces: `Не вычитать количество Отголосков Бездны`, cheats_dontSubtractVoidTraces: `Не вычитать количество Отголосков Бездны`,
@ -196,10 +197,10 @@ dict = {
cheats_universalPolarityEverywhere: `Универсальная полярность везде`, cheats_universalPolarityEverywhere: `Универсальная полярность везде`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Реакторы/Катализаторы орокин везде`, cheats_unlockDoubleCapacityPotatoesEverywhere: `Реакторы/Катализаторы орокин везде`,
cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`, cheats_unlockExilusEverywhere: `Адаптеры Эксилус везде`,
cheats_unlockArcanesEverywhere: `Адаптеры для мистификаторов везде`, cheats_unlockArcanesEverywhere: `Адаптеры для Мистификаторов везде`,
cheats_noDailyStandingLimits: `Без ежедневных лимитов репутации`, cheats_noDailyStandingLimits: `Без ежедневных лимитов репутации`,
cheats_noDailyFocusLimit: `Без ежедневных лимитов фокуса`, cheats_noDailyFocusLimit: `Без ежедневных лимитов Фокуса`,
cheats_noArgonCrystalDecay: `Без распада аргоновых кристаллов`, cheats_noArgonCrystalDecay: `Без распада Аргоновых кристаллов`,
cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`, cheats_noMasteryRankUpCooldown: `Повышение ранга мастерства без кулдауна`,
cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у торговцев`, cheats_noVendorPurchaseLimits: `Отсутствие лимитов на покупки у торговцев`,
cheats_noDeathMarks: `Без меток смерти`, cheats_noDeathMarks: `Без меток смерти`,
@ -209,28 +210,28 @@ dict = {
cheats_baroFullyStocked: `Баро полностью укомплектован`, cheats_baroFullyStocked: `Баро полностью укомплектован`,
cheats_syndicateMissionsRepeatable: `Повторять миссии синдиката`, cheats_syndicateMissionsRepeatable: `Повторять миссии синдиката`,
cheats_unlockAllProfitTakerStages: `Разблокировать все этапы Сферы извлечения прибыли`, cheats_unlockAllProfitTakerStages: `Разблокировать все этапы Сферы извлечения прибыли`,
cheats_instantFinishRivenChallenge: `Мгновенное завершение испытания Мода разлома`, cheats_instantFinishRivenChallenge: `Мгновенное завершение испытания мода Разлома`,
cheats_instantResourceExtractorDrones: `Мгновенно добывающие дроны-сборщики`, cheats_instantResourceExtractorDrones: `Мгновенно добывающие Дроны-сборщики`,
cheats_noResourceExtractorDronesDamage: `Без урона по дронам-сборщикам`, cheats_noResourceExtractorDronesDamage: `Без урона по Дронам-сборщикам`,
cheats_skipClanKeyCrafting: `Пропустить крафт кланового ключа`, cheats_skipClanKeyCrafting: `Пропустить создание кланового ключа`,
cheats_noDojoRoomBuildStage: `Мгновенное строительство Комнат Додзё`, cheats_noDojoRoomBuildStage: `Мгновенное строительство комнат Додзё`,
cheats_noDojoDecoBuildStage: `Мгновенное строительство Декораций Додзё`, cheats_noDojoDecoBuildStage: `Мгновенное строительство декораций Додзё`,
cheats_fastDojoRoomDestruction: `Мгновенные Уничтожение Комнат Додзё`, cheats_fastDojoRoomDestruction: `Мгновенные уничтожение комнат Додзё`,
cheats_noDojoResearchCosts: `Бесплатные Исследование Додзё`, cheats_noDojoResearchCosts: `Бесплатные исследование Додзё`,
cheats_noDojoResearchTime: `Мгновенные Исследование Додзё`, cheats_noDojoResearchTime: `Мгновенные исследование Додзё`,
cheats_fastClanAscension: `Мгновенное Вознесение Клана`, cheats_fastClanAscension: `Мгновенное вознесение клана`,
cheats_missionsCanGiveAllRelics: `Миссии могут давать все реликвии`, cheats_missionsCanGiveAllRelics: `Миссии могут давать все реликвии`,
cheats_exceptionalRelicsAlwaysGiveBronzeReward: `Необычные реликвии всегда дают бронзовую награду`, cheats_exceptionalRelicsAlwaysGiveBronzeReward: `Необычные реликвии всегда дают бронзовую награду`,
cheats_flawlessRelicsAlwaysGiveSilverReward: `Бесподобные реликвии всегда дают серебряную награду`, cheats_flawlessRelicsAlwaysGiveSilverReward: `Бесподобные реликвии всегда дают серебряную награду`,
cheats_radiantRelicsAlwaysGiveGoldReward: `Сияющие реликвии всегда дают золотую награду`, cheats_radiantRelicsAlwaysGiveGoldReward: `Сияющие реликвии всегда дают золотую награду`,
cheats_unlockAllSimarisResearchEntries: `Разблокировать все записи исследований Симэриса`, cheats_unlockAllSimarisResearchEntries: `Разблокировать все записи исследований Симэриса`,
cheats_disableDailyTribute: `Отключить Ежедневные награды`, cheats_disableDailyTribute: `Отключить ежедневные награды`,
cheats_spoofMasteryRank: `Поддельный ранг мастерства (-1 для отключения)`, cheats_spoofMasteryRank: `Поддельный ранг мастерства (-1 для отключения)`,
cheats_relicRewardItemCountMultiplier: `Мультипликатор количества предметов награды реликвии`, cheats_relicRewardItemCountMultiplier: `Мультипликатор количества предметов награды реликвии`,
cheats_nightwaveStandingMultiplier: `Мультипликатор репутации Ночной волны`, cheats_nightwaveStandingMultiplier: `Мультипликатор репутации Ночной волны`,
cheats_save: `Сохранить`, cheats_save: `Сохранить`,
cheats_account: `Аккаунт`, cheats_account: `Аккаунт`,
cheats_unlockAllFocusSchools: `Разблокировать все школы фокуса`, cheats_unlockAllFocusSchools: `Разблокировать все школы Фокуса`,
cheats_helminthUnlockAll: `Полностью улучшить Гельминта`, cheats_helminthUnlockAll: `Полностью улучшить Гельминта`,
cheats_addMissingSubsumedAbilities: `Добавить отсутствующие поглощённые способности`, cheats_addMissingSubsumedAbilities: `Добавить отсутствующие поглощённые способности`,
cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`, cheats_intrinsicsUnlockAll: `Полностью улучшить Модуляры`,
@ -239,26 +240,34 @@ dict = {
cheats_markAllAsRead: `Пометить все входящие как прочитанные`, cheats_markAllAsRead: `Пометить все входящие как прочитанные`,
worldState: `Состояние мира`, worldState: `Состояние мира`,
worldState_creditBoost: `Глобальный бустер кредитов`, worldState_creditBoost: `Глобальный бустер Кредитов`,
worldState_affinityBoost: `Глобальный бустер синтеза`, worldState_affinityBoost: `Глобальный бустер Синтеза`,
worldState_resourceBoost: `Глобальный бустер ресурсов`, worldState_resourceBoost: `Глобальный бустер Ресурсов`,
worldState_tennoLiveRelay: `Реле TennoLive`, worldState_tennoLiveRelay: `Реле TennoLive`,
worldState_baroTennoConRelay: `Реле Баро TennoCon`, worldState_baroTennoConRelay: `Реле Баро TennoCon`,
worldState_starDays: `Звёздные дни`, worldState_starDays: `Звёздные дни`,
worldState_galleonOfGhouls: `Галеон Гулей`, worldState_galleonOfGhouls: `Галеон Гулей`,
worldState_anniversary: `Годовщина Warframe`,
worldState_useAnniversaryTagForOldGoals: `Использовать <code>Tag</code> из Годовщины Warframe для старых событий`,
worldState_ghoulEmergence: `Избавление от гулей`, worldState_ghoulEmergence: `Избавление от гулей`,
worldState_plagueStar: `Чумная звезда`, worldState_plagueStar: `Чумная звезда`,
worldState_dogDays: `Знойные дни`, worldState_dogDays: `Знойные дни`,
worldState_dogDaysRewards: `Награды Знойных дней`, worldState_dogDaysRewards: `Награды Знойных дней`,
worldState_wolfHunt: `Волчья Охота (2025)`, worldState_wolfHunt: `Волчья Охота (2025)`,
worldState_orphixVenom: `Яд Орфикса`,
worldState_longShadow: `Длинная Тень`, worldState_longShadow: `Длинная Тень`,
worldState_hallowedFlame: `Священное пламя`, worldState_hallowedFlame: `Священное пламя`,
worldState_hallowedNightmares: `Священные Кошмары`, worldState_hallowedNightmares: `Священные кошмары`,
worldState_hallowedNightmaresRewards: `Награды Священных Кошмаров`, worldState_hallowedNightmaresRewards: `Награды Священных кошмаров`,
worldState_proxyRebellion: `Восстание Роботов`, worldState_proxyRebellion: `Восстание роботов`,
worldState_proxyRebellionRewards: `Награды Восстания Роботов`, worldState_proxyRebellionRewards: `Награды Восстания роботов`,
worldState_from_year: `из |YEAR|`, worldState_bellyOfTheBeast: `Чрево зверя`,
worldState_pre_year: `до |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `Прогресс Чрева зверя`,
worldState_eightClaw: `Восемь когтей`,
worldState_eightClawProgressOverride: `Прогресс Восьми когтей`,
worldState_from_year: `из |VAL|`,
worldState_pre_year: `до |VAL|`,
worldState_week: `Неделя |VAL|`,
worldState_incompatibleWith: `Несовместимо с:`, worldState_incompatibleWith: `Несовместимо с:`,
enabled: `Включено`, enabled: `Включено`,
disabled: `Отключено`, disabled: `Отключено`,
@ -299,73 +308,74 @@ dict = {
worldState_allAtOnceNormal: `Все сразу, в обычном режиме`, worldState_allAtOnceNormal: `Все сразу, в обычном режиме`,
worldState_allAtOnceSteelPath: `Все сразу, в режиме Стального Пути`, worldState_allAtOnceSteelPath: `Все сразу, в режиме Стального Пути`,
worldState_theCircuitOverride: `Типы миссий в подземелье Дувири`, worldState_theCircuitOverride: `Типы миссий в подземелье Дувири`,
worldState_darvoStockMultiplier: `Множитель Запасов Дарво`, worldState_darvoStockMultiplier: `Множитель запасов Дарво`,
worldState_varziaFullyStocked: `Полный Ассортимент Варзии`, worldState_varziaFullyStocked: `Полный ассортимент Варзии`,
worldState_varziaOverride: `Изменение Ротации Варзии`, worldState_varziaOverride: `Изменение ротации Варзии`,
import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля <b>будут перезаписаны</b> в вашем аккаунте.`, import_importNote: `Вы можете загрузить полный или частичный ответ <code>inventory.php</code> или <code>getShip.php</code> (клиентское представление) здесь. `,
import_importNote2: `Все поддерживаемые поля <b>будут перезаписаны</b> в вашем аккаунте.`,
import_submit: `Отправить`, import_submit: `Отправить`,
import_samples: `Пример:`, import_samples: `Пример:`,
import_samples_maxFocus: `Все школы Фокуса максимального уровня`, import_samples_maxFocus: `Все школы Фокуса макс. уровня`,
upgrade_Equilibrium: `+|VAL|% Энергия от подбирания здоровья, +|VAL|% Здоровье от подбирания энергии`, upgrade_Equilibrium: `Подбор сфер здоровья даёт +|VAL|% энергии. Подбор сфер энергии даёт +|VAL|% здоровья.`,
upgrade_MeleeCritDamage: `+|VAL|% Критический урон ближнего боя`, upgrade_MeleeCritDamage: `+|VAL|% к крит. урону в ближнем бою.`,
upgrade_PrimaryStatusChance: `+|VAL|% Шанс наложения статуса основным оружием`, upgrade_PrimaryStatusChance: `+|VAL|% к шансу статуса основного оружия.`,
upgrade_SecondaryCritChance: `+|VAL|% Шанс критического удара вторичным оружием`, upgrade_SecondaryCritChance: `+|VAL|% к шансу крит. урона от вторичного оружия.`,
upgrade_WarframeAbilityDuration: `+|VAL|% Длительность способностей`, upgrade_WarframeAbilityDuration: `+|VAL|% к длительности способностей.`,
upgrade_WarframeAbilityStrength: `+|VAL|% Сила способностей`, upgrade_WarframeAbilityStrength: `+|VAL|% к силе способностей.`,
upgrade_WarframeArmorMax: `+|VAL| Броня`, upgrade_WarframeArmorMax: `+|VAL| к броне.`,
upgrade_WarframeBlastProc: `+|VAL| Щиты при убийстве с Взрывным Уроном`, upgrade_WarframeBlastProc: `Регенерирует +|VAL| щитов, когда вы убиваете врага, наложив статус Взрыва.`,
upgrade_WarframeCastingSpeed: `+|VAL|% Скорость Применения Способностей`, upgrade_WarframeCastingSpeed: `+|VAL|% к скорости применения способностей.`,
upgrade_WarframeCorrosiveDamageBoost: `+|VAL|% Урон Способностей по врагам, пораженным Коррозией`, upgrade_WarframeCorrosiveDamageBoost: `Даёт +|VAL|% урона от сопсобнстй по врагам, находящимся под действием статуса Коррозии.`,
upgrade_WarframeCorrosiveStack: `Увеличить макс. стаки Коррозии на +|VAL|`, upgrade_WarframeCorrosiveStack: `Увеличить макс. количество стаков статуса Коррози на +|VAL|.`,
upgrade_WarframeCritDamageBoost: `+|VAL|% Критический Урон Ближнего Боя (Удваивается при 500 Энергии)`, upgrade_WarframeCritDamageBoost: `Даёт +|VAL|% крит. урона в ближнем бою. Когда макс. энергия превышает 500, увеличение урона удваивается.`,
upgrade_WarframeElectricDamage: `+|VAL1|% Урон Электричеством Основным Оружием (+|VAL2|% за каждый дополнительный Осколок)`, upgrade_WarframeElectricDamage: `Даёт +|VAL1|% Электрического урона основному оружию. Получите дополнительно +|VAL2|% за каждый экипированный багровый, лазурный или фиолетовый осколок архонта (Комбинируется с модами).`,
upgrade_WarframeElectricDamageBoost: `+|VAL|% Урон Способностей по врагам, пораженным Электричеством`, upgrade_WarframeElectricDamageBoost: `Даёт +|VAL|% урон аот спсобностей по врагам, находящимся под действием статуса Электричества.`,
upgrade_WarframeEnergyMax: `+|VAL| Макс. Энергия`, upgrade_WarframeEnergyMax: `+|VAL| к запасу энергии.`,
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% Эффективность сфер Энергии`, upgrade_WarframeGlobeEffectEnergy: `+|VAL|% к эффективности сфер энергии.`,
upgrade_WarframeGlobeEffectHealth: `+|VAL|% Эффективность сфер Здоровья`, upgrade_WarframeGlobeEffectHealth: `+|VAL|% к эффективности сфер здоровья.`,
upgrade_WarframeHealthMax: `+|VAL| Макс. Здоровье`, upgrade_WarframeHealthMax: `+|VAL| к здоровью.`,
upgrade_WarframeHPBoostFromImpact: `+|VAL1| Здоровья при убийстве с Взрывным Уроном (Макс. |VAL2| Здоровья)`, upgrade_WarframeHPBoostFromImpact: `Даёт +|VAL1| здоровья за каждого врага, убитого с помощью Взрывного урона. Макс. |VAL2| здоровья.`,
upgrade_WarframeParkourVelocity: `+|VAL|% Скорость Паркура`, upgrade_WarframeParkourVelocity: `+|VAL|% к скорости паркура.`,
upgrade_WarframeRadiationDamageBoost: `+|VAL|% Урон Способностей по врагам, пораженным Радиацией`, upgrade_WarframeRadiationDamageBoost: `Даёт +|VAL|% урона от способностей по врагам, находящимся под действием статуса Радиации.`,
upgrade_WarframeHealthRegen: `+|VAL| Здоровья в секунду`, upgrade_WarframeHealthRegen: `+|VAL| к восстановлению здоровья в секунду.`,
upgrade_WarframeShieldMax: `+|VAL| Щитов`, upgrade_WarframeShieldMax: `+|VAL| к мощности щитов.`,
upgrade_WarframeStartingEnergy: `+|VAL|% Энергии при Спавне`, upgrade_WarframeStartingEnergy: `+|VAL|% к макс. энергии при появлении.`,
upgrade_WarframeToxinDamage: `+|VAL|% Урон Токсином`, upgrade_WarframeToxinDamage: `Статусный эффект Токсина наносит на +|VAL|% больше урона.`,
upgrade_WarframeToxinHeal: `+|VAL| Здоровья при нанесении урона врагам с Токсином`, upgrade_WarframeToxinHeal: `Восстанавливает +|VAL| здоровья кадый раз, когда враги получают урон от эффекта статуса Токсина.`,
upgrade_WeaponCritBoostFromHeat: `+|VAL1|% Шанс Критического Удара Вторичным Оружием за каждого убитого врага, пораженного Огнем (Макс. |VAL2|%)`, upgrade_WeaponCritBoostFromHeat: `Увеличивает шанс крит. урона вторичным оружием на |VAL1|% каждый раз, когда вы убиваете врага, назодящегося под действием статуса Огня. Макс.: |VAL2|%.`,
upgrade_AvatarAbilityRange: `+7.5% Радиус Способностей`, upgrade_AvatarAbilityRange: `+7.5% к зоне поражения способностей.`,
upgrade_AvatarAbilityEfficiency: `+5% Энергоэффективность Способностей`, upgrade_AvatarAbilityEfficiency: `+5% к энергоэффективности способностей.`,
upgrade_AvatarEnergyRegen: `+0.5 Регенерация Энергии в секунду`, upgrade_AvatarEnergyRegen: `+0.5 к регенерации энергии в секунду.`,
upgrade_AvatarEnemyRadar: `+5m обнаружение врагов`, upgrade_AvatarEnemyRadar: `+5м обнаружение врагов.`,
upgrade_AvatarLootRadar: `+7m обнаружение добычи`, upgrade_AvatarLootRadar: `+7м к радиусу обнаружения добычи.`,
upgrade_WeaponAmmoMax: `+15% Макс. Патронов`, upgrade_WeaponAmmoMax: `+15% макс. боеприпасов.`,
upgrade_EnemyArmorReductionAura: `-3% Броня Врагов`, upgrade_EnemyArmorReductionAura: `Враги теряют -3% брони.`,
upgrade_OnExecutionAmmo: `+100% Заполнение Магазина Основного и Вторичного Оружия при убийстве Милосердием`, upgrade_OnExecutionAmmo: `Убийство Милосердием пополняет магазины основного и вторичного оружия на 100%.`,
upgrade_OnExecutionHealthDrop: `+100% Шанс Падения сферы Здоровья при убийстве Милосердием`, upgrade_OnExecutionHealthDrop: `+100% шанс выпадения сферы здоровья при убийстве Милосердием.`,
upgrade_OnExecutionEnergyDrop: `+50% Шанс Падения сферы Энергии при убийстве Милосердием`, upgrade_OnExecutionEnergyDrop: `+50% шанс выпадения сферы энергии при убийстве Милосердием.`,
upgrade_OnFailHackReset: `+50% Шанс Повтора Взлома`, upgrade_OnFailHackReset: `+50% шанс доволнительной попытки взлома в случае неудачи.`,
upgrade_DamageReductionOnHack: `+75% Уменьшение Урона во время Взлома`, upgrade_DamageReductionOnHack: `Уменьшает урон на 75% во время взлома.`,
upgrade_OnExecutionReviveCompanion: `Убийства Милосердием уменьшают время восстановления Компаньона на 15 секунд`, upgrade_OnExecutionReviveCompanion: `Убийства Милосердием уменьшают время восстановления компаньона на 15 секунд.`,
upgrade_OnExecutionParkourSpeed: `+60% Скорость Паркура после убийства Милосердием на 15 секунд`, upgrade_OnExecutionParkourSpeed: `+60% к скорости паркура после убийства Милосердием на 15 секунд.`,
upgrade_AvatarTimeLimitIncrease: `+8 секунд к Взлому`, upgrade_AvatarTimeLimitIncrease: `+8 секунд на взлом.`,
upgrade_ElectrifyOnHack: `Шокировать врагов в пределах 20 метров во время Взлома`, upgrade_ElectrifyOnHack: `Шокирует врагов в радиусе 20м во время взлома.`,
upgrade_OnExecutionTerrify: `+50% шанс, что враги в пределах 15 метров будут дрожать от страха в течение 8 секунд после убийства Милосердием`, upgrade_OnExecutionTerrify: `50% шанс, что при убийстве Милосердием враги в радиусе 15м будут параллизованы от страха на 8 секунд.`,
upgrade_OnHackLockers: `Открыть 5 шкафчиков в пределах 20 метров после Взлома`, upgrade_OnHackLockers: `Открывает 5 контейнеров в радиусе 20м после взлома.`,
upgrade_OnExecutionBlind: `Ослепить врагов в пределах 18 метров после убийства Милосердием`, upgrade_OnExecutionBlind: `Ослепляет врагов в радиусе 18м при убийстве Милосердием.`,
upgrade_OnExecutionDrainPower: `Следующее использование способности получает +50% Силы Способности после убийства Милосердием`, upgrade_OnExecutionDrainPower: `Следующая способность, применённая после убийства Милосердием, получает +50% к силе способности.`,
upgrade_OnHackSprintSpeed: `+75% Скорость Бега в течение 15 секунд после Взлома`, upgrade_OnHackSprintSpeed: `+75% к скорости бега после взлома на 15 секунд.`,
upgrade_SwiftExecute: `+50% Скорость Убийства Милосердием`, upgrade_SwiftExecute: `Увеличивает скорость добиваний Милосердием на 50%.`,
upgrade_OnHackInvis: `Невидимость в течение 15 секунд после Взлома`, upgrade_OnHackInvis: `Невидимсть на 15 секунд после взлома.`,
damageType_Electricity: `Электричество`, damageType_Electricity: `Электрический`,
damageType_Fire: `Огонь`, damageType_Fire: `Огненный`,
damageType_Freeze: `Холод`, damageType_Freeze: `Холодовой`,
damageType_Impact: `Удар`, damageType_Impact: `Ударный`,
damageType_Magnetic: `Магнит`, damageType_Magnetic: `Магнитный`,
damageType_Poison: `Токсин`, damageType_Poison: `Токсичный`,
damageType_Radiation: `Радиация`, damageType_Radiation: `Радиационный`,
theme_dark: `Темная тема`, theme_dark: `Темная тема`,
theme_light: `Светлая тема`, theme_light: `Светлая тема`,

View File

@ -1,6 +1,6 @@
// Ukrainian translation by LoseFace // Ukrainian translation by LoseFace
dict = { dict = {
general_inventoryUpdateNote: `Пам'ятка: Щоб побачити зміни в грі, вам потрібно повторно синхронізувати свій інвентар, наприклад, використовуючи команду /sync завантажувача, відвідавши Доджьо/Реле або перезавантаживши гру.`, general_inventoryUpdateNote: `Пам'ятка: Щоб побачити зміни в грі, вам потрібно повторно синхронізувати своє спорядження, наприклад, використовуючи команду /sync завантажувача, відвідавши Доджьо/Реле або перезавантаживши гру.`,
general_addButton: `Добавити`, general_addButton: `Добавити`,
general_setButton: `Встановити`, general_setButton: `Встановити`,
general_none: `Відсутній`, general_none: `Відсутній`,
@ -10,9 +10,10 @@ dict = {
code_loginFail: `Не вдалося увійти. Перевірте адресу електронної пошти та пароль.`, code_loginFail: `Не вдалося увійти. Перевірте адресу електронної пошти та пароль.`,
code_regFail: `Не вдалося зареєструватися. Обліковий запис вже існує?`, code_regFail: `Не вдалося зареєструватися. Обліковий запис вже існує?`,
code_changeNameConfirm: `Яке ім'я ви хочете встановити для свого облікового запису?`, code_changeNameConfirm: `Яке ім'я ви хочете встановити для свого облікового запису?`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `Ви впевнені, що хочете видалити обліковий запис |DISPLAYNAME| (|EMAIL|)? Цю дію не можна скасувати.`, code_deleteAccountConfirm: `Ви впевнені, що хочете видалити обліковий запис |DISPLAYNAME| (|EMAIL|)? Цю дію не можна скасувати.`,
code_archgun: `Арч-Пушка`, code_archgun: `Арк-гармата`,
code_melee: `Ближній бій`, code_melee: `Холодна зброя`,
code_pistol: `Пістолет`, code_pistol: `Пістолет`,
code_rifle: `Гвинтівка`, code_rifle: `Гвинтівка`,
code_shotgun: `Рушниця`, code_shotgun: `Рушниця`,
@ -22,11 +23,11 @@ dict = {
code_amp: `Підсилювач`, code_amp: `Підсилювач`,
code_kDrive: `К-Драйв`, code_kDrive: `К-Драйв`,
code_legendaryCore: `Легендарне ядро`, code_legendaryCore: `Легендарне ядро`,
code_traumaticPeculiar: `Травмуюча Странність`, code_traumaticPeculiar: `Особливе травмування`,
code_starter: `|MOD| (Пошкоджений)`, code_starter: `|MOD| (Пошкоджений)`,
code_badItem: `(Самозванець)`, code_badItem: `(Самозванець)`,
code_maxRank: `Максимальний рівень`, code_maxRank: `Макс. рівень`,
code_rename: `Переіменувати`, code_rename: `Перейменувати`,
code_renamePrompt: `Введіть нове ім'я:`, code_renamePrompt: `Введіть нове ім'я:`,
code_remove: `Видалити`, code_remove: `Видалити`,
code_addItemsConfirm: `Ви впевнені, що хочете додати |COUNT| предметів на ваш обліковий запис?`, code_addItemsConfirm: `Ви впевнені, що хочете додати |COUNT| предметів на ваш обліковий запис?`,
@ -42,15 +43,15 @@ dict = {
code_rankUp: `Підвищити рівень`, code_rankUp: `Підвищити рівень`,
code_rankDown: `Понизити рівень`, code_rankDown: `Понизити рівень`,
code_count: `Кількість`, code_count: `Кількість`,
code_focusAllUnlocked: `Всі школи фокуса вже розблоковані.`, code_focusAllUnlocked: `Всі школи Фокусу вже розблоковані.`,
code_focusUnlocked: `Розблоковано |COUNT| нових шкіл фокуса! Для відображення змін в грі знадобиться оновлення спорядження. Відвідування навігації — найпростіший спосіб цього досягти.`, code_focusUnlocked: `Розблоковано |COUNT| нових шкіл Фокусу! Для відображення змін в грі знадобиться оновлення спорядження. Відвідування навігації — найпростіший спосіб цього досягти.`,
code_addModsConfirm: `Ви впевнені, що хочете додати |COUNT| модифікаторів на ваш обліковий запис?`, code_addModsConfirm: `Ви впевнені, що хочете додати |COUNT| модифікаторів на ваш обліковий запис?`,
code_succImport: `Успішно імпортовано.`, code_succImport: `Успішно імпортовано.`,
code_succRelog: `Готово. Зверніть увагу, що вам потрібно буде перезайти, щоб побачити зміни в грі.`, code_succRelog: `Готово. Зверніть увагу, що вам потрібно буде перезайти, щоб побачити зміни в грі.`,
code_nothingToDo: `Готово. Немає що робити.`, code_nothingToDo: `Готово. Немає що робити.`,
code_gild: `Покращити`, code_gild: `Покращити`,
code_moa: `МОА`, code_moa: `МОА`,
code_zanuka: `Гончарка`, code_zanuka: `Гончак`,
code_stage: `Етап`, code_stage: `Етап`,
code_complete: `Завершити`, code_complete: `Завершити`,
code_nextStage: `Наступний етап`, code_nextStage: `Наступний етап`,
@ -59,56 +60,56 @@ dict = {
code_setInactive: `Зробити пригоду неактивною`, code_setInactive: `Зробити пригоду неактивною`,
code_completed: `Завершено`, code_completed: `Завершено`,
code_active: `Активний`, code_active: `Активний`,
code_pigment: `Пігмент`, code_pigment: `Барвник`,
code_mature: `Підготувати до бою`, code_mature: `Виростити для бою`,
code_unmature: `Обернути старіння`, code_unmature: `Обернути старіння`,
code_succChange: `Успішно змінено.`, code_succChange: `Успішно змінено.`,
code_requiredInvigorationUpgrade: `Ви повинні вибрати як атакуюче, так і допоміжне покращення.`, code_requiredInvigorationUpgrade: `Ви повинні вибрати як атакуюче, так і допоміжне вдосконалення.`,
login_description: `Увійдіть, використовуючи облікові дані OpenWF (ті ж, що й у грі при підключенні до цього сервера).`, login_description: `Увійдіть, використовуючи облікові дані OpenWF (ті ж, що й у грі при підключенні до цього серверу).`,
login_emailLabel: `Адреса електронної пошти`, login_emailLabel: `Адреса електронної пошти`,
login_passwordLabel: `Пароль`, login_passwordLabel: `Пароль`,
login_loginButton: `Увійти`, login_loginButton: `Увійти`,
login_registerButton: `Зареєструватися`, login_registerButton: `Зареєструватися`,
navbar_logout: `Вийти`, navbar_logout: `Вийти`,
navbar_renameAccount: `Переіменувати обліковий запис`, navbar_renameAccount: `Перейменувати обліковий запис`,
navbar_deleteAccount: `Видалити обліковий запис`, navbar_deleteAccount: `Видалити обліковий запис`,
navbar_inventory: `Спорядження`, navbar_inventory: `Спорядження`,
navbar_mods: `Моди`, navbar_mods: `Модифікатори`,
navbar_quests: `Пригоди`, navbar_quests: `Пригоди`,
navbar_cheats: `Чити`, navbar_cheats: `Чити`,
navbar_import: `Імпорт`, navbar_import: `Імпорт`,
inventory_addItems: `Додати предмети`, inventory_addItems: `Додати предмети`,
inventory_suits: `Ворфрейми`, inventory_suits: `Ворфрейми`,
inventory_longGuns: `Основне озброєння`, inventory_longGuns: `Основна зброя`,
inventory_pistols: `Допоміжне озброєння`, inventory_pistols: `Допоміжна зброя`,
inventory_melee: `Холодне озброєння`, inventory_melee: `Холодна зброя`,
inventory_spaceSuits: `Арквінґи`, inventory_spaceSuits: `Арквінґи`,
inventory_spaceGuns: `Озброєння арквінґів`, inventory_spaceGuns: `Зброя Арквінґів`,
inventory_spaceMelee: `Холодне озброєння арквінґів`, inventory_spaceMelee: `Холодна зброя Арквінґів`,
inventory_mechSuits: `Некрамехи`, inventory_mechSuits: `Некрамехи`,
inventory_sentinels: `Вартові`, inventory_sentinels: `Вартові`,
inventory_sentinelWeapons: `Озброєння вартових`, inventory_sentinelWeapons: `Зброя Вартових`,
inventory_operatorAmps: `Підсилювачі`, inventory_operatorAmps: `Підсилювачі`,
inventory_hoverboards: `К-Драйви`, inventory_hoverboards: `К-Драйви`,
inventory_moaPets: `МОА`, inventory_moaPets: `МОА`,
inventory_kubrowPets: `Тварини`, inventory_kubrowPets: `Тварини`,
inventory_evolutionProgress: `Прогрес Еволюції Інкарнонов`, inventory_evolutionProgress: `Прогрес еволюції Інкарнонів`,
inventory_Boosters: `Бустери`, inventory_Boosters: `Посилення`,
inventory_bulkAddSuits: `Додати відсутні ворфрейми`, inventory_bulkAddSuits: `Додати відсутні Ворфрейми`,
inventory_bulkAddWeapons: `Додати відсутнє озброєння`, inventory_bulkAddWeapons: `Додати відсутню зброю`,
inventory_bulkAddSpaceSuits: `Додати відсутні арквінґи`, inventory_bulkAddSpaceSuits: `Додати відсутні Арквінґи`,
inventory_bulkAddSpaceWeapons: `Додати відсутнє озброєння арквінґів`, inventory_bulkAddSpaceWeapons: `Додати відсутню зброю Арквінґів`,
inventory_bulkAddSentinels: `Додати відсутніх вартових`, inventory_bulkAddSentinels: `Додати відсутніх Вартових`,
inventory_bulkAddSentinelWeapons: `Додати відсутнє озброєння вартових`, inventory_bulkAddSentinelWeapons: `Додати відсутню зброю Вартових`,
inventory_bulkAddEvolutionProgress: `Додати відсутній прогрес Еволюції Інкарнонов`, inventory_bulkAddEvolutionProgress: `Додати відсутній прогрес еволюції Інкарнонів`,
inventory_bulkRankUpSuits: `Максимальний рівень всіх ворфреймів`, inventory_bulkRankUpSuits: `Макс. рівень всіх Ворфреймів`,
inventory_bulkRankUpWeapons: `Максимальний рівень всього озброєння`, inventory_bulkRankUpWeapons: `Макс. рівень всієї зброї`,
inventory_bulkRankUpSpaceSuits: `Максимальний рівень всіх арквінґів`, inventory_bulkRankUpSpaceSuits: `Макс. рівень всіх Арквінґів`,
inventory_bulkRankUpSpaceWeapons: `Максимальний рівень всього озброєння арквінґів`, inventory_bulkRankUpSpaceWeapons: `Макс. рівень всієї зброї Арквінґів`,
inventory_bulkRankUpSentinels: `Максимальний рівень всіх вартових`, inventory_bulkRankUpSentinels: `Макс. рівень всіх Вартових`,
inventory_bulkRankUpSentinelWeapons: `Максимальний рівень всього озброєння вартових`, inventory_bulkRankUpSentinelWeapons: `Макс. рівень всієї зброї Вартових`,
inventory_bulkRankUpEvolutionProgress: `Максимальний рівень всіх еволюцій Інкарнонов`, inventory_bulkRankUpEvolutionProgress: `Макс. рівень всіх еволюцій Інкарнонів`,
inventory_maxPlexus: `Максимальний рівень Плексу`, inventory_maxPlexus: `Макс. рівень Плексу`,
quests_list: `Пригоди`, quests_list: `Пригоди`,
quests_completeAll: `Закінчити всі пригоди`, quests_completeAll: `Закінчити всі пригоди`,
@ -121,71 +122,71 @@ dict = {
currency_PrimeTokens: `Королівські Ая`, currency_PrimeTokens: `Королівські Ая`,
currency_owned: `У тебе |COUNT|.`, currency_owned: `У тебе |COUNT|.`,
detailedView_archonShardsLabel: `Клітинки осколків архонта`, detailedView_archonShardsLabel: `Комірки уламків Архонта`,
detailedView_archonShardsDescription: `Ви можете використовувати ці необмежені клітинки для встановлення безлічі вдосконалень.`, detailedView_archonShardsDescription: `Ви можете використовувати ці необмежені комірки для встановлення безлічі вдосконалень.`,
detailedView_archonShardsDescription2: `Зверніть увагу: кожен уламок архонта застосовується з затримкою при завантаженні.`, detailedView_archonShardsDescription2: `Зверніть увагу: кожен уламок Архонта застосовується з затримкою при завантаженні.`,
detailedView_valenceBonusLabel: `Ознака Валентності`, detailedView_valenceBonusLabel: `Ознака Валентності`,
detailedView_valenceBonusDescription: `Ви можете встановити або прибрати ознака валентності з вашої зброї.`, detailedView_valenceBonusDescription: `Ви можете встановити або прибрати ознаку Валентності з вашої зброї.`,
detailedView_modularPartsLabel: `Змінити Модульні Частини`, detailedView_modularPartsLabel: `Змінити модульні частини`,
detailedView_suitInvigorationLabel: `Зміцнення Ворфрейма`, detailedView_suitInvigorationLabel: `Зміцнення Ворфрейма`,
detailedView_loadoutLabel: `Конфігурації`, detailedView_loadoutLabel: `Конфігурації`,
invigorations_offensive_AbilityStrength: `+200% Потужності Здібностей`, invigorations_offensive_AbilityStrength: `+200% до потужності здібностей.`,
invigorations_offensive_AbilityRange: `+100% Досяжність Здібностей`, invigorations_offensive_AbilityRange: `+100% до досяжності здібностей.`,
invigorations_offensive_AbilityDuration: `+100% Тривалість Здібностей`, invigorations_offensive_AbilityDuration: `+100% до тривалості дії здібностей.`,
invigorations_offensive_MeleeDamage: `+250% Шкода Ближнього Бою`, invigorations_offensive_MeleeDamage: `+250% до шкоди від холодної зброї.`,
invigorations_offensive_PrimaryDamage: `+250% Шкода Основного Озброєння`, invigorations_offensive_PrimaryDamage: `+250% до шкоди від основної зброї.`,
invigorations_offensive_SecondaryDamage: `+250% Шкода Допоміжного Озброєння`, invigorations_offensive_SecondaryDamage: `+250% до шкоди від допоміжної зброї.`,
invigorations_offensive_PrimaryCritChance: `+200% Імовірність Критичної Шкоди Основного Озброєння`, invigorations_offensive_PrimaryCritChance: `+200% до ймовірності критичної шкоди від основної зброї.`,
invigorations_offensive_SecondaryCritChance: `+200% Імовірність Критичної Шкоди Допоміжного Озброєння`, invigorations_offensive_SecondaryCritChance: `+200% до ймовірності критичної шкоди від допоміжної зброї.`,
invigorations_offensive_MeleeCritChance: `+200% Імовірність Критичної Шкоди Ближнього Бою`, invigorations_offensive_MeleeCritChance: `+200% до ймовірності критичної шкоди від холодної зброї.`,
invigorations_utility_AbilityEfficiency: `+75% Ощадливість Здібностей`, invigorations_utility_AbilityEfficiency: `+75% до ощадливості здібностей.`,
invigorations_utility_SprintSpeed: `+75% Швидкість Бігу`, invigorations_utility_SprintSpeed: `+75% до швидкості бігу.`,
invigorations_utility_ParkourVelocity: `+75% Швидкість Паркура`, invigorations_utility_ParkourVelocity: `+75% до швидкості паркуру.`,
invigorations_utility_HealthMax: `+1000 Здоров'я`, invigorations_utility_HealthMax: `+1000 до здоров'я.`,
invigorations_utility_EnergyMax: `+200% Максимум Енергії`, invigorations_utility_EnergyMax: `+200% до макс. енергії.`,
invigorations_utility_StatusImmune: `Імунітет до Ефектів Статусу`, invigorations_utility_StatusImmune: `Імунітет до ефектів стану.`,
invigorations_utility_ReloadSpeed: `+75% Швидкість Перезаряджання`, invigorations_utility_ReloadSpeed: `+75% до швидкості перезаряджання.`,
invigorations_utility_HealthRegen: `+25 Здоров'я в секунду`, invigorations_utility_HealthRegen: `+25 до відновлення здоров'я на секунду.`,
invigorations_utility_ArmorMax: `+1000 Захисту`, invigorations_utility_ArmorMax: `+1000 до захисту.`,
invigorations_utility_Jumps: `+5 Оновлень Стрибків`, invigorations_utility_Jumps: `+5 Оновлень стрибків.`,
invigorations_utility_EnergyRegen: `+2 Енергії в секунду`, invigorations_utility_EnergyRegen: `+2 до відновлення енергії на секунду.`,
invigorations_offensiveLabel: `Атакуюче Вдосконалення`, invigorations_offensiveLabel: `Атакуюче вдосконалення`,
invigorations_defensiveLabel: `Вспомогательное Вдосконалення`, invigorations_defensiveLabel: `Допоміжне вдосконалення`,
invigorations_expiryLabel: `Термін дії Зміцнення (необов'язково)`, invigorations_expiryLabel: `Термін дії Зміцнення (необов'язково)`,
abilityOverride_label: `Перевизначення здібностей`, abilityOverride_label: `Перевизначення здібностей`,
abilityOverride_onSlot: `у клітинці`, abilityOverride_onSlot: `у комірці`,
mods_addRiven: `Добавити Модифікатор Розколу`, mods_addRiven: `Добавити модифікатор Розколу`,
mods_fingerprint: `Відбиток`, mods_fingerprint: `Відбиток`,
mods_fingerprintHelp: `Потрібна допомога з відбитком?`, mods_fingerprintHelp: `Потрібна допомога з відбитком?`,
mods_rivens: `Модифікатори Розколу`, mods_rivens: `Модифікатори Розколу`,
mods_mods: `Модифікатори`, mods_mods: `Модифікатори`,
mods_addMax: `Добавити максимально вдосконалений`, mods_addMax: `Добавити макс. вдосконалений`,
mods_addMissingUnrankedMods: `Добавити недостаючі модифікатори без рівня`, mods_addMissingUnrankedMods: `Добавити недостаючі модифікатори без рівня`,
mods_removeUnranked: `Видалити модифікатори без рівня`, mods_removeUnranked: `Видалити модифікатори без рівня`,
mods_addMissingMaxRankMods: `Добавити недостаючі модифікатори максимального рівня`, mods_addMissingMaxRankMods: `Добавити недостаючі модифікатори макс. рівня`,
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: `Пропустити навчання`,
cheats_skipAllDialogue: `Пропустити всі діалоги`, cheats_skipAllDialogue: `Пропустити всі діалоги`,
cheats_unlockAllScans: `Розблокувати всі сканування`, cheats_unlockAllScans: `Розблокувати всі сканування`,
cheats_unlockAllMissions: `Розблокувати всі місії`, cheats_unlockAllMissions: `Розблокувати всі місії`,
cheats_unlockAllMissions_ok: `Успіх. Будь ласка, зверніть увагу, що вам потрібно буде увійти в Доджьо/Реле або перезайти, щоб клієнт оновив зоряну мапу.`, cheats_unlockAllMissions_ok: `Успіх. Будь ласка, зверніть увагу, що вам потрібно буде увійти в Доджьо/Реле або перезайти, щоб клієнт оновив Зоряну мапу.`,
cheats_infiniteCredits: `Бескінечні кредити`, cheats_infiniteCredits: `Бескінечні Кредити`,
cheats_infinitePlatinum: `Бескінечна платина`, cheats_infinitePlatinum: `Бескінечна Платина`,
cheats_infiniteEndo: `Бескінечне ендо`, cheats_infiniteEndo: `Бескінечне Ендо`,
cheats_infiniteRegalAya: `Бескінечна Королівська Ая`, cheats_infiniteRegalAya: `Бескінечна Королівська Ая`,
cheats_infiniteHelminthMaterials: `Бескінечні Секреції Гельмінта`, cheats_infiniteHelminthMaterials: `Бескінечні секреції Гельмінта`,
cheats_claimingBlueprintRefundsIngredients: `Повернення інгредієнтів креслеників`, cheats_claimingBlueprintRefundsIngredients: `Повернення інгредієнтів креслеників`,
cheats_dontSubtractPurchaseCreditCost: `Не вираховувати вартість кредитів при купівлі`, cheats_dontSubtractPurchaseCreditCost: `Не вираховувати вартість Кредитів при купівлі`,
cheats_dontSubtractPurchasePlatinumCost: `Не вираховувати вартість платини при купівлі`, cheats_dontSubtractPurchasePlatinumCost: `Не вираховувати вартість Платини при купівлі`,
cheats_dontSubtractPurchaseItemCost: `Не вираховувати вартість предметів при купівлі`, cheats_dontSubtractPurchaseItemCost: `Не вираховувати вартість предметів при купівлі`,
cheats_dontSubtractPurchaseStandingCost: `Не вираховувати вартість репутації при купівлі`, cheats_dontSubtractPurchaseStandingCost: `Не вираховувати вартість репутації при купівлі`,
cheats_dontSubtractVoidTraces: `Не вираховувати кількість Відголосків Безодні`, cheats_dontSubtractVoidTraces: `Не вираховувати кількість Відлуння`,
cheats_dontSubtractConsumables: `Не вираховувати кількість витратних матеріалів`, cheats_dontSubtractConsumables: `Не вираховувати кількість витратних матеріалів`,
cheats_unlockAllShipFeatures: `Розблокувати всі функції судна`, cheats_unlockAllShipFeatures: `Розблокувати всі функції судна`,
cheats_unlockAllShipDecorations: `Розблокувати всі прикраси судна`, cheats_unlockAllShipDecorations: `Розблокувати всі прикраси судна`,
@ -196,10 +197,10 @@ dict = {
cheats_universalPolarityEverywhere: `Будь-яка полярність скрізь`, cheats_universalPolarityEverywhere: `Будь-яка полярність скрізь`,
cheats_unlockDoubleCapacityPotatoesEverywhere: `Орокінські Реактори/Каталізатори скрізь`, cheats_unlockDoubleCapacityPotatoesEverywhere: `Орокінські Реактори/Каталізатори скрізь`,
cheats_unlockExilusEverywhere: `Ексилотримач скрізь`, cheats_unlockExilusEverywhere: `Ексилотримач скрізь`,
cheats_unlockArcanesEverywhere: `Тримач містифікаторів скрізь`, cheats_unlockArcanesEverywhere: `Тримач Містифікаторів скрізь`,
cheats_noDailyStandingLimits: `Без щоденних лімітів репутації`, cheats_noDailyStandingLimits: `Без щоденних лімітів репутації`,
cheats_noDailyFocusLimit: `Без щоденних лімітів фокуса`, cheats_noDailyFocusLimit: `Без щоденних лімітів Фокусу`,
cheats_noArgonCrystalDecay: `Без розпаду аргонових кристалів`, cheats_noArgonCrystalDecay: `Без розпаду Аргонових кристалів`,
cheats_noMasteryRankUpCooldown: `Підвищення ранга майстерності без очікування`, cheats_noMasteryRankUpCooldown: `Підвищення ранга майстерності без очікування`,
cheats_noVendorPurchaseLimits: `Відсутність лімітів на купівлю у продавців`, cheats_noVendorPurchaseLimits: `Відсутність лімітів на купівлю у продавців`,
cheats_noDeathMarks: `Без позначок смерті`, cheats_noDeathMarks: `Без позначок смерті`,
@ -209,16 +210,16 @@ dict = {
cheats_baroFullyStocked: `Баро повністю укомплектований`, cheats_baroFullyStocked: `Баро повністю укомплектований`,
cheats_syndicateMissionsRepeatable: `Повторювати місії синдиката`, cheats_syndicateMissionsRepeatable: `Повторювати місії синдиката`,
cheats_unlockAllProfitTakerStages: `Розблокувати всі етапи Привласнювачки`, cheats_unlockAllProfitTakerStages: `Розблокувати всі етапи Привласнювачки`,
cheats_instantFinishRivenChallenge: `Миттєве завершення випробування Модифікатора Розколу`, cheats_instantFinishRivenChallenge: `Миттєве завершення випробування модифікатора Розколу`,
cheats_instantResourceExtractorDrones: `Миттєво добуваючі дрони-видобувачі`, cheats_instantResourceExtractorDrones: `Миттєво добуваючі Дрони-видобувачі`,
cheats_noResourceExtractorDronesDamage: `Без шкоди по дронам-видобувачам`, cheats_noResourceExtractorDronesDamage: `Без шкоди по Дронам-видобувачам`,
cheats_skipClanKeyCrafting: `Пропустити створення кланового ключа`, cheats_skipClanKeyCrafting: `Пропустити створення кланового ключа`,
cheats_noDojoRoomBuildStage: `Миттєве будівництво Кімнат Доджьо`, cheats_noDojoRoomBuildStage: `Миттєве будівництво кімнат Доджьо`,
cheats_noDojoDecoBuildStage: `Миттєве будівництво Декорацій Доджьо`, cheats_noDojoDecoBuildStage: `Миттєве будівництво декорацій Доджьо`,
cheats_fastDojoRoomDestruction: `Миттєве знищення Кімнат Доджьо`, cheats_fastDojoRoomDestruction: `Миттєве знищення кімнат Доджьо`,
cheats_noDojoResearchCosts: `Безкоштовні Дослідження Доджьо`, cheats_noDojoResearchCosts: `Безкоштовні дослідження Доджьо`,
cheats_noDojoResearchTime: `Миттєві Дослідження Доджьо`, cheats_noDojoResearchTime: `Миттєві дослідження Доджьо`,
cheats_fastClanAscension: `Миттєве Піднесення Клану`, cheats_fastClanAscension: `Миттєве піднесення клану`,
cheats_missionsCanGiveAllRelics: `Місії можуть давати всі реліквії`, cheats_missionsCanGiveAllRelics: `Місії можуть давати всі реліквії`,
cheats_exceptionalRelicsAlwaysGiveBronzeReward: `Вийняткові реліквії завжди дають бронзову нагороду`, cheats_exceptionalRelicsAlwaysGiveBronzeReward: `Вийняткові реліквії завжди дають бронзову нагороду`,
cheats_flawlessRelicsAlwaysGiveSilverReward: `Бездоганні реліквії завжди дають срібну нагороду`, cheats_flawlessRelicsAlwaysGiveSilverReward: `Бездоганні реліквії завжди дають срібну нагороду`,
@ -230,7 +231,7 @@ dict = {
cheats_nightwaveStandingMultiplier: `Множник репутації Нічної хвилі`, cheats_nightwaveStandingMultiplier: `Множник репутації Нічної хвилі`,
cheats_save: `Зберегти`, cheats_save: `Зберегти`,
cheats_account: `Обліковий запис`, cheats_account: `Обліковий запис`,
cheats_unlockAllFocusSchools: `Розблокувати всі школи фокуса`, cheats_unlockAllFocusSchools: `Розблокувати всі школи Фокусу`,
cheats_helminthUnlockAll: `Повністю покращити Гельмінта`, cheats_helminthUnlockAll: `Повністю покращити Гельмінта`,
cheats_addMissingSubsumedAbilities: `Додати відсутні поглинуті здібності`, cheats_addMissingSubsumedAbilities: `Додати відсутні поглинуті здібності`,
cheats_intrinsicsUnlockAll: `Повністю покращити Кваліфікації`, cheats_intrinsicsUnlockAll: `Повністю покращити Кваліфікації`,
@ -239,26 +240,34 @@ dict = {
cheats_markAllAsRead: `Помітити всі вхідні як прочитані`, cheats_markAllAsRead: `Помітити всі вхідні як прочитані`,
worldState: `Стан світу`, worldState: `Стан світу`,
worldState_creditBoost: `Глобальний бустер кредитів`, worldState_creditBoost: `Глобальне посилення Кредитів`,
worldState_affinityBoost: `Глобальний бустер синтезу`, worldState_affinityBoost: `Глобальне посилення Синтезу`,
worldState_resourceBoost: `Глобальний бустер ресурсів`, worldState_resourceBoost: `Глобальне посилення Ресурсів`,
worldState_tennoLiveRelay: `Реле TennoLive`, worldState_tennoLiveRelay: `Реле TennoLive`,
worldState_baroTennoConRelay: `Реле Баро TennoCon`, worldState_baroTennoConRelay: `Реле Баро TennoCon`,
worldState_starDays: `Зоряні дні`, worldState_starDays: `Зоряні дні`,
worldState_galleonOfGhouls: `Гульський Галеон`, worldState_galleonOfGhouls: `Гульський галеон`,
worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `Зачищення від гулів`, worldState_ghoulEmergence: `Зачищення від гулів`,
worldState_plagueStar: `Морова зірка`, worldState_plagueStar: `Морова зірка`,
worldState_dogDays: `Спекотні дні`, worldState_dogDays: `Спекотні дні`,
worldState_dogDaysRewards: `Нагороди Спекотних днів`, worldState_dogDaysRewards: `Нагороди Спекотних днів`,
worldState_wolfHunt: `Полювання на Вовка (2025)`, worldState_wolfHunt: `Полювання на Вовка (2025)`,
worldState_orphixVenom: `Орфіксова отрута`,
worldState_longShadow: `Довга тінь`, worldState_longShadow: `Довга тінь`,
worldState_hallowedFlame: `Священне полум'я`, worldState_hallowedFlame: `Священне полум'я`,
worldState_hallowedNightmares: `Священні жахіття`, worldState_hallowedNightmares: `Священні жахіття`,
worldState_hallowedNightmaresRewards: `Нагороди Священних Жахіть`, worldState_hallowedNightmaresRewards: `Нагороди Священних жахіть`,
worldState_proxyRebellion: `Повстання роботів`, worldState_proxyRebellion: `Повстання роботів`,
worldState_proxyRebellionRewards: `Нагороди Повстання роботів`, worldState_proxyRebellionRewards: `Нагороди Повстання роботів`,
worldState_from_year: `з |YEAR|`, worldState_bellyOfTheBeast: `У лігві звіра`,
worldState_pre_year: `до |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `Прогрес У лігві звіра`,
worldState_eightClaw: `Вісім кігтів`,
worldState_eightClawProgressOverride: `Прогрес Восьми кігтів`,
worldState_from_year: `з |VAL|`,
worldState_pre_year: `до |VAL|`,
worldState_week: `[UNTRANSLATED] Week |VAL|`,
worldState_incompatibleWith: `Несумісне з:`, worldState_incompatibleWith: `Несумісне з:`,
enabled: `Увімкнено`, enabled: `Увімкнено`,
disabled: `Вимкнено`, disabled: `Вимкнено`,
@ -273,9 +282,9 @@ dict = {
worldState_cold: `Холод`, worldState_cold: `Холод`,
worldState_duviriOverride: `Цикл Дувірі`, worldState_duviriOverride: `Цикл Дувірі`,
worldState_joy: `Радість`, worldState_joy: `Радість`,
worldState_anger: `Гнів`, worldState_anger: `Злість`,
worldState_envy: `Заздрість`, worldState_envy: `Заздрість`,
worldState_sorrow: `Скорбота`, worldState_sorrow: `Журба`,
worldState_fear: `Страх`, worldState_fear: `Страх`,
worldState_nightwaveOverride: `Сезон Нічної хвилі`, worldState_nightwaveOverride: `Сезон Нічної хвилі`,
worldState_RadioLegionIntermission13Syndicate: `Вибірка Нори 9`, worldState_RadioLegionIntermission13Syndicate: `Вибірка Нори 9`,
@ -299,68 +308,69 @@ dict = {
worldState_allAtOnceNormal: `Всі одразу, в звичайному режимі`, worldState_allAtOnceNormal: `Всі одразу, в звичайному режимі`,
worldState_allAtOnceSteelPath: `Всі одразу, в режимі Шляху Сталі`, worldState_allAtOnceSteelPath: `Всі одразу, в режимі Шляху Сталі`,
worldState_theCircuitOverride: `Типи місій у підземеллі Дувірі`, worldState_theCircuitOverride: `Типи місій у підземеллі Дувірі`,
worldState_darvoStockMultiplier: `Множник Запасів Дарво`, worldState_darvoStockMultiplier: `Множник запасів Дарво`,
worldState_varziaFullyStocked: `Повний Асортимент Варзії`, worldState_varziaFullyStocked: `Повний асортимент Варзії`,
worldState_varziaOverride: `Зміна Ротації Варзії`, worldState_varziaOverride: `Зміна ротації Варзії`,
import_importNote: `Ви можете завантажити повну або часткову відповідь спорядження (клієнтське представлення) тут. Всі підтримувані поля <b>будуть перезаписані</b> у вашому акаунті.`, import_importNote: `Ви можете завантажити повну або часткову відповідь <code>inventory.php</code> або <code>getShip.php</code> (клієнтське представлення) тут.`,
import_importNote2: `Всі підтримувані поля <b>будуть перезаписані</b> у вашому акаунті.`,
import_submit: `Відправити`, import_submit: `Відправити`,
import_samples: `Приклад:`, import_samples: `Приклад:`,
import_samples_maxFocus: `Всі школи Фокуса максимального рівня`, import_samples_maxFocus: `Всі школи Фокусу макс. рівня`,
upgrade_Equilibrium: `+|VAL|% Енергія від підбирання здоров'я, +|VAL|% Здоров'я від підбирання енергії`, upgrade_Equilibrium: `Згустки здоров'я дають +|VAL|% енергії, згустки енергії дають +|VAL|% здоров'я.`,
upgrade_MeleeCritDamage: `+|VAL|% Критична шкода ближнього бою`, upgrade_MeleeCritDamage: `+|VAL|% до критичної шкоди від холодної зброї.`,
upgrade_PrimaryStatusChance: `+|VAL|% Імовірність накладення ефекту стану основною зброєю`, upgrade_PrimaryStatusChance: `+|VAL|% до ймовірності ефекту стану від основної зброї.`,
upgrade_SecondaryCritChance: `+|VAL|% Імовірність критичної шкоди допоміжною зброєю`, upgrade_SecondaryCritChance: `+|VAL|% до ймовірності критичної шкоди від допоміжної зброї.`,
upgrade_WarframeAbilityDuration: `+|VAL|% Тривалість здібностей`, upgrade_WarframeAbilityDuration: `+|VAL|% до тривалості дії здібностей.`,
upgrade_WarframeAbilityStrength: `+|VAL|% Потужність здібностей`, upgrade_WarframeAbilityStrength: `+|VAL|% до потужності здібностей.`,
upgrade_WarframeArmorMax: `+|VAL| Захист`, upgrade_WarframeArmorMax: `+|VAL| до захисту.`,
upgrade_WarframeBlastProc: `+|VAL| Щит при вбивстві з Вибуховим Уронoм`, upgrade_WarframeBlastProc: `Відновлює +|VAL| щитів, коли ви вбиваєте ворога Вибуховою шкодою.`,
upgrade_WarframeCastingSpeed: `+|VAL|% Швидкість Застосування Здібностей`, upgrade_WarframeCastingSpeed: `+|VAL|% до швидкості застосування здібностей.`,
upgrade_WarframeCorrosiveDamageBoost: `+|VAL|% Урон Здібностей по ворогам, ураженим Корозією`, upgrade_WarframeCorrosiveDamageBoost: `Дає +|VAL|% до шкоди від здібностей ворогам під впливом Корозійної шкоди.`,
upgrade_WarframeCorrosiveStack: `Збільшити макс. стаки Корозії на +|VAL|`, upgrade_WarframeCorrosiveStack: `Збільшує макс. кількість накопичень Коррозійних ефектів стану на +|VAL|.`,
upgrade_WarframeCritDamageBoost: `+|VAL|% Критична шкода Ближнього Бою (Подвоюється при 500 Енергії)`, upgrade_WarframeCritDamageBoost: `Дає +|VAL|% до критичної шкоди холодної зброї. Коли макс. енергія перевищує 500, то збільшення шкоди подвоюється.`,
upgrade_WarframeElectricDamage: `+|VAL1|% Урон Електрикою Основним Озброєнням (+|VAL2|% за кожен додатковий Уламок)`, upgrade_WarframeElectricDamage: `Дає +|VAL1|% до Електричної шкоди від основної зрої. Додатково дає +|VAL2|% за споряджений багряний, блакитний чи фіолетовий архонтовий уламок (Поєднується з модифікаторами).`,
upgrade_WarframeElectricDamageBoost: `+|VAL|% Шкода Здібностей по ворогам, ураженим Електрикою`, upgrade_WarframeElectricDamageBoost: `Дає +|VAL|% до шкоди від здібностей ворогам під впливом Електричної шкоди.`,
upgrade_WarframeEnergyMax: `+|VAL| Макс. Енергія`, upgrade_WarframeEnergyMax: `+|VAL| до макс. енергії.`,
upgrade_WarframeGlobeEffectEnergy: `+|VAL|% Ефективність згустків Енергії`, upgrade_WarframeGlobeEffectEnergy: `+|VAL|% до дієвості згустків енергії.`,
upgrade_WarframeGlobeEffectHealth: `+|VAL|% Ефективність згустків Здоров'я`, upgrade_WarframeGlobeEffectHealth: `+|VAL|% до дієвості згустків здоров'я.`,
upgrade_WarframeHealthMax: `+|VAL| Макс. Здоров'я`, upgrade_WarframeHealthMax: `+|VAL| до здоров'я.`,
upgrade_WarframeHPBoostFromImpact: `+|VAL1| Здоров'я при вбивстві з Вибуховою шкодою (Макс. |VAL2| Здоров'я)`, upgrade_WarframeHPBoostFromImpact: `Отримайте +|VAL1| здоров'я за ворога, вбитого Вибуховою шкодою. Макс. — |VAL2| здоров'я.`,
upgrade_WarframeParkourVelocity: `+|VAL|% Швидкість Паркура`, upgrade_WarframeParkourVelocity: `+|VAL|% до швидкості паркуру.`,
upgrade_WarframeRadiationDamageBoost: `+|VAL|% Шкода Здібностей по ворогам, ураженим Радіацією`, upgrade_WarframeRadiationDamageBoost: `Дає +|VAL|% до шкоди від здібностей ворогам під впливом Радіаційної шкоди.`,
upgrade_WarframeHealthRegen: `+|VAL| Здоров'я в секунду`, upgrade_WarframeHealthRegen: `+|VAL| до відновлення здоров'я на секунду.`,
upgrade_WarframeShieldMax: `+|VAL| Щиту`, upgrade_WarframeShieldMax: `+|VAL| до місткості щитів.`,
upgrade_WarframeStartingEnergy: `+|VAL|% Енергії при Спавні`, upgrade_WarframeStartingEnergy: `+|VAL|% до початкової макс. енергії.`,
upgrade_WarframeToxinDamage: `+|VAL|% Шкода Токсином`, upgrade_WarframeToxinDamage: `Токсичні ефекти стану завдаватимуть на +|VAL|% більше шкоди.`,
upgrade_WarframeToxinHeal: `+|VAL| Здоров'я при нанесенні шкоди ворогам з Токсином`, upgrade_WarframeToxinHeal: `Відновлює +|VAL| здоров'я за кожен раз як вороги отримують шкоду від Токсичних ефектів стану.`,
upgrade_WeaponCritBoostFromHeat: `+|VAL1|% Імовірність Критичної Шкоди Допоміжною Зброєю за кожного вбитого ворога, ураженого Термічною шкодою (Макс. |VAL2|%)`, upgrade_WeaponCritBoostFromHeat: `Збільшує ймовірність критичної шкоди від допоміжної зброї на |VAL1|% щоразу, коли ви вбиваєте ворога під впливом Термічного ефекту стану. Накопичується до |VAL2|%.`,
upgrade_AvatarAbilityRange: `+7.5% Досяжність Здібностей`, upgrade_AvatarAbilityRange: `+7.5% Досяжність Здібностей.`,
upgrade_AvatarAbilityEfficiency: `+5% Ощадливість Здібностей`, upgrade_AvatarAbilityEfficiency: `+5% Ощадливість Здібностей.`,
upgrade_AvatarEnergyRegen: `+0.5 Відновлення Енергії в секунду`, upgrade_AvatarEnergyRegen: `+0.5 Відновлення Енергії в секунду.`,
upgrade_AvatarEnemyRadar: `+5m Виявлення ворогів`, upgrade_AvatarEnemyRadar: `+5м Виявлення ворогів.`,
upgrade_AvatarLootRadar: `+7m Виявлення здобичі`, upgrade_AvatarLootRadar: `+7м Виявлення здобичі.`,
upgrade_WeaponAmmoMax: `+15% Макс. Набоїв`, upgrade_WeaponAmmoMax: `+15% Макс. Набоїв.`,
upgrade_EnemyArmorReductionAura: `-3% Захист Ворогів`, upgrade_EnemyArmorReductionAura: `-3% Захист Ворогів.`,
upgrade_OnExecutionAmmo: `+100% Заповнення Магазина Основного і Допоміжного Озброєння при вбивстві Милосердям`, upgrade_OnExecutionAmmo: `+100% Заповнення Магазина Основного і Допоміжного Озброєння при вбивстві Милосердям.`,
upgrade_OnExecutionHealthDrop: `+100% Імовірність Падіння згустка Здоров'я при вбивстві Милосердям`, upgrade_OnExecutionHealthDrop: `+100% Імовірність Падіння згустка здоров'я при вбивстві Милосердям.`,
upgrade_OnExecutionEnergyDrop: `+50% Імовірність Падіння згустка Енергії при вбивстві Милосердям`, upgrade_OnExecutionEnergyDrop: `+50% Імовірність Падіння згустка Енергії при вбивстві Милосердям.`,
upgrade_OnFailHackReset: `+50% Імовірність Повтора Зламу`, upgrade_OnFailHackReset: `+50% Імовірність Повтора Зламу.`,
upgrade_DamageReductionOnHack: `+75% Зменшення Шкоди під час Зламу`, upgrade_DamageReductionOnHack: `+75% Зменшення Шкоди під час Зламу.`,
upgrade_OnExecutionReviveCompanion: `Вбивства Милосердям зменшують час відновлення Компаньйона на 15 секунд`, upgrade_OnExecutionReviveCompanion: `Вбивства Милосердям зменшують час відновлення Компаньйона на 15 секунд.`,
upgrade_OnExecutionParkourSpeed: `+60% Швидкість Паркура після вбивства Милосердям на 15 секунд`, upgrade_OnExecutionParkourSpeed: `+60% Швидкість Паркура після вбивства Милосердям на 15 секунд.`,
upgrade_AvatarTimeLimitIncrease: `+8 секунд до Зламу`, upgrade_AvatarTimeLimitIncrease: `+8 секунд до Зламу.`,
upgrade_ElectrifyOnHack: `Шокувати ворогів в межах 20 метрів під час Зламу`, upgrade_ElectrifyOnHack: `Шокувати ворогів в межах 20м під час Зламу.`,
upgrade_OnExecutionTerrify: `+50% Імовірність, що вороги в межах 15 метрів будуть тремтіти від страху протягом 8 секунд після вбивства Милосердям`, upgrade_OnExecutionTerrify: `+50% Імовірність, що вороги в межах 15м будуть тремтіти від страху протягом 8 секунд після вбивства Милосердям.`,
upgrade_OnHackLockers: `Відкрити 5 шафок в межах 20 метрів після Зламу`, upgrade_OnHackLockers: `Відкрити 5 шафок в межах 20м після Зламу.`,
upgrade_OnExecutionBlind: `Засліпити ворогів в межах 18 метрів після вбивства Милосердям`, upgrade_OnExecutionBlind: `Засліпити ворогів в межах 18м після вбивства Милосердям.`,
upgrade_OnExecutionDrainPower: `Наступне застосування здібності отримує +50% Потужності Здібності після вбивства Милосердям`, upgrade_OnExecutionDrainPower: `Наступне застосування здібності отримує +50% Потужності Здібності після вбивства Милосердям.`,
upgrade_OnHackSprintSpeed: `+75% Швидкість Бігу протягом 15 секунд після Зламу`, upgrade_OnHackSprintSpeed: `+75% Швидкість Бігу протягом 15 секунд після Зламу.`,
upgrade_SwiftExecute: `+50% Швидкість Вбивства Милосердям`, upgrade_SwiftExecute: `+50% Швидкість Вбивства Милосердям.`,
upgrade_OnHackInvis: `Невидимість протягом 15 секунд після Зламу`, upgrade_OnHackInvis: `Невидимість протягом 15 секунд після Зламу.`,
damageType_Electricity: `Електричний`, damageType_Electricity: `Електричний`,
damageType_Fire: `Трммічний`, damageType_Fire: `Термічний`,
damageType_Freeze: `Крижаний`, damageType_Freeze: `Крижаний`,
damageType_Impact: `Ударний`, damageType_Impact: `Ударний`,
damageType_Magnetic: `Магнетичний`, damageType_Magnetic: `Магнетичний`,

View File

@ -10,6 +10,7 @@ dict = {
code_loginFail: `登录失败。请检查邮箱和密码。`, code_loginFail: `登录失败。请检查邮箱和密码。`,
code_regFail: `注册失败。账号是否已存在?`, code_regFail: `注册失败。账号是否已存在?`,
code_changeNameConfirm: `您想将账户名称更改为?`, code_changeNameConfirm: `您想将账户名称更改为?`,
code_changeNameRetry: `[UNTRANSLATED] |NAME| is already taken.`,
code_deleteAccountConfirm: `确定要删除您的账户 |DISPLAYNAME|(|EMAIL|) 吗?此操作不可撤销。`, code_deleteAccountConfirm: `确定要删除您的账户 |DISPLAYNAME|(|EMAIL|) 吗?此操作不可撤销。`,
code_archgun: `空战`, code_archgun: `空战`,
code_melee: `近战`, code_melee: `近战`,
@ -246,19 +247,27 @@ dict = {
worldState_baroTennoConRelay: `Baro的TennoCon中继站`, worldState_baroTennoConRelay: `Baro的TennoCon中继站`,
worldState_starDays: `活动:星日`, worldState_starDays: `活动:星日`,
worldState_galleonOfGhouls: `战术警报:尸鬼的帆船战舰`, worldState_galleonOfGhouls: `战术警报:尸鬼的帆船战舰`,
worldState_anniversary: `[UNTRANSLATED] Warframe Anniversary`,
worldState_useAnniversaryTagForOldGoals: `[UNTRANSLATED] Use <code>Tag</code> from Warframe Anniversary for old Events`,
worldState_ghoulEmergence: `尸鬼净化`, worldState_ghoulEmergence: `尸鬼净化`,
worldState_plagueStar: `瘟疫之星`, worldState_plagueStar: `瘟疫之星`,
worldState_dogDays: `三伏天`, worldState_dogDays: `三伏天`,
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`, worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
worldState_wolfHunt: `恶狼狩猎 (2025)`, worldState_wolfHunt: `恶狼狩猎 (2025)`,
worldState_orphixVenom: `奥影之毒`,
worldState_longShadow: `暗夜长影`, worldState_longShadow: `暗夜长影`,
worldState_hallowedFlame: `万圣之焰`, worldState_hallowedFlame: `万圣之焰`,
worldState_hallowedNightmares: `万圣噩梦`, worldState_hallowedNightmares: `万圣噩梦`,
worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`, worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
worldState_proxyRebellion: `机械叛乱`, worldState_proxyRebellion: `机械叛乱`,
worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`, worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
worldState_from_year: `[UNTRANSLATED] from |YEAR|`, worldState_bellyOfTheBeast: `兽之腹`,
worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`, worldState_bellyOfTheBeastProgressOverride: `[UNTRANSLATED] Belly of the Beast Progress`,
worldState_eightClaw: `八爪`,
worldState_eightClawProgressOverride: `[UNTRANSLATED] Eight Claw Progress`,
worldState_from_year: `[UNTRANSLATED] from |VAL|`,
worldState_pre_year: `[UNTRANSLATED] pre |VAL|`,
worldState_week: `[UNTRANSLATED] Week |VAL|`,
worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`, worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
enabled: `启用`, enabled: `启用`,
disabled: `关闭/取消配置`, disabled: `关闭/取消配置`,
@ -303,7 +312,8 @@ dict = {
worldState_varziaFullyStocked: `瓦奇娅开启全部库存商品`, worldState_varziaFullyStocked: `瓦奇娅开启全部库存商品`,
worldState_varziaOverride: `瓦奇娅(Prime重生)轮换状态`, worldState_varziaOverride: `瓦奇娅(Prime重生)轮换状态`,
import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段<b>将被覆盖</b>到您的账户中。`, import_importNote: `[UNTRANSLATED] You can provide a full or partial <code>inventory.php</code> or <code>getShip.php</code> response (client representation) here.`,
import_importNote2: `支持的所有字段<b>将被覆盖</b>到您的账户中。`,
import_submit: `提交`, import_submit: `提交`,
import_samples: `示例:`, import_samples: `示例:`,
import_samples_maxFocus: `所有专精学派完全精通`, import_samples_maxFocus: `所有专精学派完全精通`,