XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
返回提交历史

XFEstudio/SpaceNinjaServer

feat: Varzia (Prime Resurgence) rotation (#2390)

Also closes #1059 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2390 Co-authored-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Co-committed-by: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>

ee4adc7d
AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com>
提交于

代码差异

18 个文件 +1592 -173
Modified config.json.example +3 -1
@@ -78,7 +78,9 @@
78 78 "nightwaveOverride": "",
79 79 "allTheFissures": "",
80 80 "circuitGameModes": null,
81 "darvoStockMultiplier": 1
81 "darvoStockMultiplier": 1,
82 "varziaOverride": "",
83 "varziaFullyStocked": false
82 84 },
83 85 "dev": {
84 86 "keepVendorsExpired": false
Modified src/controllers/custom/getItemListsController.ts +11 -1
@@ -21,6 +21,7 @@ import {
21 21 TRelicQuality
22 22 } from "warframe-public-export-plus";
23 23 import allIncarnons from "@/static/fixed_responses/allIncarnonList.json";
24 import varzia from "@/static/fixed_responses/worldState/varzia.json";
24 25
25 26 interface ListedItem {
26 27 uniqueName: string;
@@ -55,6 +56,7 @@ interface ItemLists {
55 56 EvolutionProgress: ListedItem[];
56 57 mods: ListedItem[];
57 58 Boosters: ListedItem[];
59 VarziaOffers: ListedItem[];
58 60 //circuitGameModes: ListedItem[];
59 61 }
60 62
@@ -91,7 +93,8 @@ const getItemListsController: RequestHandler = (req, response) => {
91 93 KubrowPets: [],
92 94 EvolutionProgress: [],
93 95 mods: [],
94 Boosters: []
96 Boosters: [],
97 VarziaOffers: []
95 98 /*circuitGameModes: [
96 99 {
97 100 uniqueName: "Survival",
@@ -338,6 +341,13 @@ const getItemListsController: RequestHandler = (req, response) => {
338 341 });
339 342 }
340 343
344 for (const item of Object.values(varzia.primeDualPacks)) {
345 res.VarziaOffers.push({
346 uniqueName: item.ItemType,
347 name: getString(getItemName(item.ItemType) || "", lang)
348 });
349 }
350
341 351 response.json(res);
342 352 };
343 353
Modified src/services/configService.ts +2 -0
@@ -89,6 +89,8 @@ export interface IConfig {
89 89 allTheFissures?: string;
90 90 circuitGameModes?: string[];
91 91 darvoStockMultiplier?: number;
92 varziaOverride?: string;
93 varziaFullyStocked?: boolean;
92 94 };
93 95 dev?: {
94 96 keepVendorsExpired?: boolean;
Modified src/services/configWatcherService.ts +8 -0
@@ -4,6 +4,7 @@ import { logger } from "../utils/logger";
4 4 import { config, configPath, loadConfig } from "./configService";
5 5 import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService";
6 6 import { Inbox } from "../models/inboxModel";
7 import varzia from "@/static/fixed_responses/worldState/varzia.json";
7 8
8 9 let amnesia = false;
9 10 chokidar.watch(configPath).on("change", () => {
@@ -57,6 +58,13 @@ export const validateConfig = (): void => {
57 58 config.worldState.galleonOfGhouls = 0;
58 59 modified = true;
59 60 }
61 if (
62 config.worldState?.varziaOverride &&
63 !varzia.primeDualPacks.some(p => p.ItemType === config.worldState?.varziaOverride)
64 ) {
65 config.worldState.varziaOverride = "";
66 modified = true;
67 }
60 68 if (modified) {
61 69 logger.info(`Updating config file to fix some issues with it.`);
62 70 void saveConfig();
Modified src/services/itemDataService.ts +4 -0
@@ -17,6 +17,7 @@ import {
17 17 dict_zh,
18 18 ExportArcanes,
19 19 ExportBoosters,
20 ExportBundles,
20 21 ExportCustoms,
21 22 ExportDrones,
22 23 ExportGear,
@@ -117,6 +118,9 @@ export const getItemName = (uniqueName: string): string | undefined => {
117 118 if (uniqueName in ExportArcanes) {
118 119 return ExportArcanes[uniqueName].name;
119 120 }
121 if (uniqueName in ExportBundles) {
122 return ExportBundles[uniqueName].name;
123 }
120 124 if (uniqueName in ExportCustoms) {
121 125 return ExportCustoms[uniqueName].name;
122 126 }
Modified src/services/purchaseService.ts +4 -4
@@ -21,7 +21,6 @@ import {
21 21 } from "@/src/types/purchaseTypes";
22 22 import { logger } from "@/src/utils/logger";
23 23 import { getWorldState } from "./worldStateService";
24 import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
25 24 import {
26 25 ExportBoosterPacks,
27 26 ExportBoosters,
@@ -305,14 +304,15 @@ export const handlePurchase = async (
305 304 }
306 305 break;
307 306 case PurchaseSource.PrimeVaultTrader: {
308 if (purchaseRequest.PurchaseParams.SourceId! != staticWorldState.PrimeVaultTraders[0]._id.$oid) {
307 const worldState = getWorldState();
308 if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) {
309 309 throw new Error("invalid request source");
310 310 }
311 311 const offer =
312 staticWorldState.PrimeVaultTraders[0].Manifest.find(
312 worldState.PrimeVaultTraders[0].Manifest.find(
313 313 x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
314 314 ) ??
315 staticWorldState.PrimeVaultTraders[0].EvergreenManifest.find(
315 worldState.PrimeVaultTraders[0].EvergreenManifest.find(
316 316 x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
317 317 );
318 318 if (offer) {
Modified src/services/worldStateService.ts +102 -0
@@ -1,5 +1,6 @@
1 1 import staticWorldState from "@/static/fixed_responses/worldState/worldState.json";
2 2 import baro from "@/static/fixed_responses/worldState/baro.json";
3 import varzia from "@/static/fixed_responses/worldState/varzia.json";
3 4 import fissureMissions from "@/static/fixed_responses/worldState/fissureMissions.json";
4 5 import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json";
5 6 import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json";
@@ -15,6 +16,8 @@ import {
15 16 ICalendarEvent,
16 17 ICalendarSeason,
17 18 ILiteSortie,
19 IPrimeVaultTrader,
20 IPrimeVaultTraderOffer,
18 21 ISeasonChallenge,
19 22 ISortie,
20 23 ISortieMission,
@@ -1101,6 +1104,80 @@ const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
1101 1104 return true;
1102 1105 };
1103 1106
1107 const getVarziaRotation = (week: number): string => {
1108 const seed = new SRng(week).randomInt(0, 100_000);
1109 const rng = new SRng(seed);
1110 return rng.randomElement(varzia.primeDualPacks)!.ItemType;
1111 };
1112
1113 const getVarziaManifest = (dualPack: string): IPrimeVaultTraderOffer[] => {
1114 const rotrationManifest = varzia.primeDualPacks.find(pack => pack.ItemType === dualPack);
1115 if (!rotrationManifest) return [];
1116
1117 const mainPack = [{ ItemType: rotrationManifest.ItemType, PrimePrice: 10 }];
1118 const singlePacks: IPrimeVaultTraderOffer[] = [];
1119 const items: IPrimeVaultTraderOffer[] = [];
1120 const bobbleHeads: IPrimeVaultTraderOffer[] = [];
1121
1122 for (const singlePackType of rotrationManifest.SinglePacks) {
1123 singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 });
1124
1125 const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType);
1126 if (sp) {
1127 items.push(...sp.Items);
1128 sp.BobbleHeads.forEach(bobbleHead => {
1129 bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 });
1130 });
1131 }
1132 }
1133
1134 const relics = rotrationManifest.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 }));
1135
1136 return [singlePacks[0], ...mainPack, singlePacks[1], ...items, ...bobbleHeads, ...relics];
1137 };
1138
1139 const getAllVarziaManifests = (): IPrimeVaultTraderOffer[] => {
1140 const dualPacks: IPrimeVaultTraderOffer[] = [];
1141 const singlePacks: IPrimeVaultTraderOffer[] = [];
1142 const items: IPrimeVaultTraderOffer[] = [];
1143 const bobbleHeads: IPrimeVaultTraderOffer[] = [];
1144 const relics: IPrimeVaultTraderOffer[] = [];
1145
1146 const singlePackSet = new Set<string>();
1147 const itemsSet = new Set<string>();
1148 const bobbleHeadsSet = new Set<string>();
1149
1150 varzia.primeDualPacks.forEach(dualPack => {
1151 dualPacks.push({ ItemType: dualPack.ItemType, PrimePrice: 10 });
1152
1153 dualPack.SinglePacks.forEach(singlePackType => {
1154 if (!singlePackSet.has(singlePackType)) {
1155 singlePackSet.add(singlePackType);
1156 singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 });
1157 }
1158
1159 const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType)!;
1160 sp.Items.forEach(item => {
1161 if (!itemsSet.has(item.ItemType)) {
1162 itemsSet.add(item.ItemType);
1163 items.push(item);
1164 }
1165 });
1166
1167 sp.BobbleHeads.forEach(bobbleHead => {
1168 if (!bobbleHeadsSet.has(bobbleHead)) {
1169 bobbleHeadsSet.add(bobbleHead);
1170 bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 });
1171 }
1172 });
1173 });
1174
1175 relics.push(...dualPack.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 })));
1176 });
1177
1178 return [...dualPacks, ...singlePacks, ...items, ...bobbleHeads, ...relics];
1179 };
1180
1104 1181 export const getWorldState = (buildLabel?: string): IWorldState => {
1105 1182 let timeSecs = Math.round(Date.now() / 1000);
1106 1183 while (!doesTimeSatsifyConstraints(timeSecs)) {
@@ -1122,6 +1199,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1122 1199 ActiveMissions: [],
1123 1200 GlobalUpgrades: [],
1124 1201 VoidTraders: [],
1202 PrimeVaultTraders: [],
1125 1203 VoidStorms: [],
1126 1204 DailyDeals: [],
1127 1205 EndlessXpChoices: [],
@@ -1393,6 +1471,30 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1393 1471 }
1394 1472 }
1395 1473
1474 // Varzia
1475 {
1476 const pt: IPrimeVaultTrader = {
1477 _id: { $oid: ((weekStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "c36af423770eaa97" },
1478 Activation: { $date: { $numberLong: weekStart.toString() } },
1479 Expiry: { $date: { $numberLong: weekEnd.toString() } },
1480 Node: "TradeHUB1",
1481 Manifest: [],
1482 EvergreenManifest: varzia.evergreen,
1483 ScheduleInfo: []
1484 };
1485 worldState.PrimeVaultTraders.push(pt);
1486 const rotation = config.worldState?.varziaOverride || getVarziaRotation(week);
1487 pt.Manifest = config.worldState?.varziaFullyStocked ? getAllVarziaManifests() : getVarziaManifest(rotation);
1488 if (config.worldState?.varziaOverride || config.worldState?.varziaFullyStocked) {
1489 pt.Expiry = { $date: { $numberLong: "2000000000000" } };
1490 } else {
1491 pt.ScheduleInfo.push({
1492 Expiry: { $date: { $numberLong: (weekEnd + unixTimesInMs.week).toString() } },
1493 FeaturedItem: getVarziaRotation(week + 1)
1494 });
1495 }
1496 }
1497
1396 1498 // Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST)
1397 1499 {
1398 1500 const rollover = getSortieTime(day);
Modified src/types/worldStateTypes.ts +26 -0
@@ -14,6 +14,7 @@ export interface IWorldState {
14 14 GlobalUpgrades: IGlobalUpgrade[];
15 15 NodeOverrides: INodeOverride[];
16 16 VoidTraders: IVoidTrader[];
17 PrimeVaultTraders: IPrimeVaultTrader[];
17 18 VoidStorms: IVoidStorm[];
18 19 DailyDeals: IDailyDeal[];
19 20 PVPChallengeInstances: IPVPChallengeInstance[];
@@ -171,6 +172,31 @@ export interface IVoidStorm {
171 172 ActiveMissionTier: string;
172 173 }
173 174
175 export interface IPrimeVaultTrader {
176 _id: IOid;
177 Activation: IMongoDate;
178 Expiry: IMongoDate;
179 InitialStartDate?: IMongoDate;
180 Node: string;
181 Manifest: IPrimeVaultTraderOffer[];
182 EvergreenManifest: IPrimeVaultTraderOffer[];
183 ScheduleInfo: IScheduleInfo[];
184 }
185
186 export interface IPrimeVaultTraderOffer {
187 ItemType: string;
188 PrimePrice?: number;
189 RegularPrice?: number;
190 StartDate?: IMongoDate;
191 EndDate?: IMongoDate;
192 }
193
194 export interface IScheduleInfo {
195 Expiry: IMongoDate;
196 PreviewHiddenUntil?: IMongoDate;
197 FeaturedItem?: string;
198 }
199
174 200 export interface IDailyDeal {
175 201 StoreItem: string;
176 202 Activation: IMongoDate;
Modified static/fixed_responses/worldState/worldState.json +1 -161
@@ -347,169 +347,9 @@
347 347 "Activation": { "$date": { "$numberLong": "1563030000000" } }
348 348 }
349 349 ],
350 "PrimeVaultTraders": [
351 {
352 "_id": { "$oid": "631f8c4ac36af423770eaa97" },
353 "Activation": { "$date": { "$numberLong": "1712858400000" } },
354 "InitialStartDate": { "$date": { "$numberLong": "2000000000000" } },
355 "Node": "TradeHUB1",
356 "Manifest": [
357 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxPrimeSinglePack", "PrimePrice": 6 },
358 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack", "PrimePrice": 10 },
359 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeSinglePack", "PrimePrice": 6 },
360 { "ItemType": "/Lotus/StoreItems/Powersuits/YinYang/EquinoxPrime", "PrimePrice": 3 },
361 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeCapeEquinox", "PrimePrice": 2 },
362 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNarvarrPrimeArmorSet", "PrimePrice": 2 },
363 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeStradavar/PrimeStradavarGun", "PrimePrice": 2 },
364 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Staff/TipedoPrime/TipedoPrimeWeapon", "PrimePrice": 2 },
365 { "ItemType": "/Lotus/StoreItems/Powersuits/MonkeyKing/WukongPrime", "PrimePrice": 3 },
366 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeWukongSyandana", "PrimePrice": 2 },
367 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeKubrowArmor", "PrimePrice": 2 },
368 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/EphemeraPrimeA", "PrimePrice": 2 },
369 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeZhuge/PrimeZhugeCrossbow", "PrimePrice": 2 },
370 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeNinkondi/PrimeNikondi", "PrimePrice": 2 },
371 { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeBobbleHead", "PrimePrice": 1 },
372 { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeNightBobbleHead", "PrimePrice": 1 },
373 { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeDayBobbleHead", "PrimePrice": 1 },
374 { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/WukongPrimeBobbleHead", "PrimePrice": 1 },
375 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 },
376 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultBBronze", "RegularPrice": 1 },
377 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 },
378 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 },
379 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultBBronze", "RegularPrice": 1 },
380 { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 }
381 ],
382 "Expiry": { "$date": { "$numberLong": "2000000000000" } },
383 "EvergreenManifest": [
384 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/DualDagger/FangPrimeDagger", "PrimePrice": 2 },
385 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeLex/PrimeLex", "PrimePrice": 1 },
386 { "ItemType": "/Lotus/StoreItems/Types/Game/ShipScenes/PrimeLisetFiligreeScene", "PrimePrice": 1 },
387 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAviaPrimeArmorSet", "PrimePrice": 2 },
388 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVayasPrimeAccessories", "PrimePrice": 2 },
389 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/TwitchPrimeMeleeDangle", "PrimePrice": 1 },
390 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeAviaSyandana", "PrimePrice": 2 },
391 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeTwitchScarf", "PrimePrice": 2 },
392 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeBurston/PrimeBurston", "PrimePrice": 2 },
393 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/TwitchPrimeScarf", "PrimePrice": 2 },
394 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/TwitchPrimeSigil", "PrimePrice": 1 },
395 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNecraloidBundle", "RegularPrice": 10 },
396 { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Rifle/BratonPrime", "PrimePrice": 1 },
397 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Liset/LisetSkinTwitchPrime", "RegularPrice": 10 },
398 { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/InfMembraneCape", "RegularPrice": 10 },
399 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaraPrimeSongItem", "RegularPrice": 5 },
400 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaussPrimeSongItem", "RegularPrice": 5 },
401 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GrendelPrimeSongItem", "RegularPrice": 5 },
402 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HildrynPrimeSongItem", "RegularPrice": 5 },
403 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HydroidPrimeSongItem", "RegularPrice": 5 },
404 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/KhoraPrimeSongItem", "RegularPrice": 5 },
405 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NekrosPrimeSongItem", "RegularPrice": 5 },
406 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NidusPrimeSongItem", "RegularPrice": 5 },
407 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OberonPrimeSongItem", "RegularPrice": 5 },
408 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OctaviaPrimeSongItem", "RegularPrice": 5 },
409 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/RevenantPrimeSongItem", "RegularPrice": 5 },
410 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/VaubanPrimeSongItem", "RegularPrice": 5 },
411 { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/ProteaPrimeSongItem", "RegularPrice": 5 },
412 { "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PrimeBucks", "RegularPrice": 1 },
413 { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoidTraceBundle", "RegularPrice": 1 }
414 ],
415 "ScheduleInfo": [
416 { "Expiry": { "$date": { "$numberLong": "1667498400000" } }, "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack" },
417 { "Expiry": { "$date": { "$numberLong": "1669921200000" } }, "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVValkyrSarynPrimeDualPack" },
418 {
419 "Expiry": { "$date": { "$numberLong": "1672945200000" } },
420 "PreviewHiddenUntil": { "$date": { "$numberLong": "1668711600000" } },
421 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOberonPrimeSinglePack"
422 },
423 {
424 "Expiry": { "$date": { "$numberLong": "1675364400000" } },
425 "PreviewHiddenUntil": { "$date": { "$numberLong": "1671130800000" } },
426 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoltLokiPrimeDualPack"
427 },
428 {
429 "Expiry": { "$date": { "$numberLong": "1677783600000" } },
430 "PreviewHiddenUntil": { "$date": { "$numberLong": "1674154800000" } },
431 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtlasVaubanPrimeDualPack"
432 },
433 {
434 "Expiry": { "$date": { "$numberLong": "1680804000000" } },
435 "PreviewHiddenUntil": { "$date": { "$numberLong": "1676473200000" } },
436 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosOberonPrimeDualPack"
437 },
438 {
439 "Expiry": { "$date": { "$numberLong": "1683223200000" } },
440 "PreviewHiddenUntil": { "$date": { "$numberLong": "1679594400000" } },
441 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagRhinoPrimeDualPack"
442 },
443 {
444 "Expiry": { "$date": { "$numberLong": "1685718000000" } },
445 "PreviewHiddenUntil": { "$date": { "$numberLong": "1682013600000" } },
446 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosOberonPrimeDualPack"
447 },
448 {
449 "Expiry": { "$date": { "$numberLong": "1688666400000" } },
450 "PreviewHiddenUntil": { "$date": { "$numberLong": "1684433100000" } },
451 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosAshPrimeDualPack"
452 },
453 {
454 "Expiry": { "$date": { "$numberLong": "1691085600000" } },
455 "PreviewHiddenUntil": { "$date": { "$numberLong": "1687456800000" } },
456 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheeMiragePrimeDualPack"
457 },
458 {
459 "Expiry": { "$date": { "$numberLong": "1694109600000" } },
460 "PreviewHiddenUntil": { "$date": { "$numberLong": "1689876000000" } },
461 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostMagPrimeDualPack"
462 },
463 {
464 "Expiry": { "$date": { "$numberLong": "1696528800000" } },
465 "PreviewHiddenUntil": { "$date": { "$numberLong": "1692900000000" } },
466 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack"
467 },
468 {
469 "Expiry": { "$date": { "$numberLong": "1698948000000" } },
470 "PreviewHiddenUntil": { "$date": { "$numberLong": "1695319200000" } },
471 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVZephyrChromaPrimeDualPack"
472 },
473 {
474 "Expiry": { "$date": { "$numberLong": "1703185200000" } },
475 "PreviewHiddenUntil": { "$date": { "$numberLong": "1697738400000" } },
476 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNezhaOctaviaPrimeDualPack"
477 },
478 {
479 "Expiry": { "$date": { "$numberLong": "1704394800000" } },
480 "PreviewHiddenUntil": { "$date": { "$numberLong": "1697738400000" } },
481 "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC"
482 },
483 { "Expiry": { "$date": { "$numberLong": "1705604400000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" },
484 { "Expiry": { "$date": { "$numberLong": "1706814000000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" },
485 { "Expiry": { "$date": { "$numberLong": "1708023600000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" },
486 {
487 "Expiry": { "$date": { "$numberLong": "1710439200000" } },
488 "PreviewHiddenUntil": { "$date": { "$numberLong": "1706814000000" } },
489 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheeMiragePrimeDualPack"
490 },
491 {
492 "Expiry": { "$date": { "$numberLong": "1712858400000" } },
493 "PreviewHiddenUntil": { "$date": { "$numberLong": "1709233200000" } },
494 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitaniaGaraPrimeDualPack"
495 },
496 {
497 "Expiry": { "$date": { "$numberLong": "1715277600000" } },
498 "PreviewHiddenUntil": { "$date": { "$numberLong": "1711648800000" } },
499 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosAshPrimeDualPack"
500 },
501 {
502 "Expiry": { "$date": { "$numberLong": "1717696800000" } },
503 "PreviewHiddenUntil": { "$date": { "$numberLong": "1714068000000" } },
504 "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack"
505 },
506 { "Expiry": { "$date": { "$numberLong": "1720116000000" } }, "PreviewHiddenUntil": { "$date": { "$numberLong": "1716487200000" } } }
507 ]
508 }
509 ],
510 350 "PrimeAccessAvailability": { "State": "PRIME1" },
511 351 "PrimeVaultAvailabilities": [false, false, false, false, false],
512 "PrimeTokenAvailability": true,
352 "PrimeTokenAvailability": false,
513 353 "LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" },
514 354 "PVPChallengeInstances": [
515 355 {
Modified static/webui/index.html +14 -6
@@ -864,9 +864,13 @@
864 864 <input class="form-check-input" type="checkbox" id="worldState.starDays" />
865 865 <label class="form-check-label" for="worldState.starDays" data-loc="worldState_starDays"></label>
866 866 </div>
867 <div class="form-check">
868 <input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" />
869 <label class="form-check-label" for="worldState.varziaFullyStocked" data-loc="worldState_varziaFullyStocked"></label>
870 </div>
867 871 <div class="form-group mt-2">
868 872 <label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label>
869 <select class="form-control" id="worldState.galleonOfGhouls">
873 <select class="form-control" id="worldState.galleonOfGhouls" data-default="">
870 874 <option value="0" data-loc="disabled"></option>
871 875 <option value="1" data-loc="worldState_we1"></option>
872 876 <option value="2" data-loc="worldState_we2"></option>
@@ -875,7 +879,7 @@
875 879 </div>
876 880 <div class="form-group mt-2">
877 881 <label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
878 <select class="form-control" id="worldState.eidolonOverride">
882 <select class="form-control" id="worldState.eidolonOverride" data-default="">
879 883 <option value="" data-loc="disabled"></option>
880 884 <option value="day" data-loc="worldState_day"></option>
881 885 <option value="night" data-loc="worldState_night"></option>
@@ -883,7 +887,7 @@
883 887 </div>
884 888 <div class="form-group mt-2">
885 889 <label class="form-label" for="worldState.vallisOverride" data-loc="worldState_vallisOverride"></label>
886 <select class="form-control" id="worldState.vallisOverride">
890 <select class="form-control" id="worldState.vallisOverride" data-default="">
887 891 <option value="" data-loc="disabled"></option>
888 892 <option value="warm" data-loc="worldState_warm"></option>
889 893 <option value="cold" data-loc="worldState_cold"></option>
@@ -891,7 +895,7 @@
891 895 </div>
892 896 <div class="form-group mt-2">
893 897 <label class="form-label" for="worldState.duviriOverride" data-loc="worldState_duviriOverride"></label>
894 <select class="form-control" id="worldState.duviriOverride">
898 <select class="form-control" id="worldState.duviriOverride" data-default="">
895 899 <option value="" data-loc="disabled"></option>
896 900 <option value="joy" data-loc="worldState_joy"></option>
897 901 <option value="anger" data-loc="worldState_anger"></option>
@@ -902,7 +906,7 @@
902 906 </div>
903 907 <div class="form-group mt-2">
904 908 <label class="form-label" for="worldState.nightwaveOverride" data-loc="worldState_nightwaveOverride"></label>
905 <select class="form-control" id="worldState.nightwaveOverride">
909 <select class="form-control" id="worldState.nightwaveOverride" data-default="">
906 910 <option value="" data-loc="disabled"></option>
907 911 <option value="RadioLegionIntermission13Syndicate" data-loc="worldState_RadioLegionIntermission13Syndicate"></option>
908 912 <option value="RadioLegionIntermission12Syndicate" data-loc="worldState_RadioLegionIntermission12Syndicate"></option>
@@ -924,12 +928,16 @@
924 928 </div>
925 929 <div class="form-group mt-2">
926 930 <label class="form-label" for="worldState.allTheFissures" data-loc="worldState_fissures"></label>
927 <select class="form-control" id="worldState.allTheFissures">
931 <select class="form-control" id="worldState.allTheFissures" data-default="">
928 932 <option value="" data-loc="normal"></option>
929 933 <option value="normal" data-loc="worldState_allAtOnceNormal"></option>
930 934 <option value="hard" data-loc="worldState_allAtOnceSteelPath"></option>
931 935 </select>
932 936 </div>
937 <div class="form-group mt-2">
938 <label class="form-label" for="worldState.varziaOverride" data-loc="worldState_varziaOverride"></label>
939 <select class="form-control" id="worldState.varziaOverride" data-default=""></select>
940 </div>
933 941 <form class="form-group mt-2" onsubmit="doSaveConfigStringArray('worldState.circuitGameModes'); return false;">
934 942 <label class="form-label" for="worldState.circuitGameModes" data-loc="worldState_theCircuitOverride"></label>
935 943 <div class="input-group">
Modified static/webui/script.js +13 -0
@@ -285,6 +285,7 @@ function fetchItemList() {
285 285 document.getElementById("changeSyndicate").appendChild(syndicateNone);
286 286
287 287 document.getElementById("valenceBonus-innateDamage").innerHTML = "";
288 document.getElementById("worldState.varziaOverride").innerHTML = "";
288 289
289 290 // prettier-ignore
290 291 data.archonCrystalUpgrades = {
@@ -420,6 +421,11 @@ function fetchItemList() {
420 421 name: loc("code_pigment")
421 422 });
422 423
424 data.VarziaOffers.unshift({
425 uniqueName: "",
426 name: loc("disabled")
427 });
428
423 429 const itemMap = {
424 430 // Generics for rivens
425 431 "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: loc("code_archgun") },
@@ -469,6 +475,13 @@ function fetchItemList() {
469 475 option.textContent = name;
470 476 document.getElementById("valenceBonus-innateDamage").appendChild(option);
471 477 });
478 } else if (type == "VarziaOffers") {
479 items.forEach(item => {
480 const option = document.createElement("option");
481 option.value = item.uniqueName;
482 option.textContent = item.name;
483 document.getElementById("worldState.varziaOverride").appendChild(option);
484 });
472 485 } else if (type == "uniqueLevelCaps") {
473 486 uniqueLevelCaps = items;
474 487 } else if (type == "Syndicates") {
Modified static/webui/translations/de.js +2 -0
@@ -246,6 +246,8 @@ dict = {
246 246 worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`,
247 247 worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`,
248 248 worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`,
249 worldState_varziaFullyStocked: `[UNTRANSLATED] Varzia Fully Stocked`,
250 worldState_varziaOverride: `[UNTRANSLATED] Varzia Rotation Override`,
249 251
250 252 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>.`,
251 253 import_submit: `Absenden`,
Modified static/webui/translations/en.js +2 -0
Modified static/webui/translations/es.js +2 -0
Modified static/webui/translations/fr.js +2 -0
Modified static/webui/translations/ru.js +2 -0
Modified static/webui/translations/zh.js +2 -0