返回提交历史
Modified
config-vanilla.json
+9
-0
Modified
src/controllers/api/inboxController.ts
+5
-1
Modified
src/models/inboxModel.ts
+3
-1
Modified
src/services/configService.ts
+9
-0
Modified
src/services/missionInventoryUpdateService.ts
+219
-17
Modified
src/services/worldStateService.ts
+639
-2
Modified
src/types/worldStateTypes.ts
+47
-1
Modified
static/webui/index.html
+70
-0
Modified
static/webui/script.js
+11
-0
Modified
static/webui/style.css
+4
-1
Modified
static/webui/translations/de.js
+12
-0
Modified
static/webui/translations/en.js
+12
-0
Modified
static/webui/translations/es.js
+12
-0
Modified
static/webui/translations/fr.js
+12
-0
Modified
static/webui/translations/ru.js
+12
-0
Modified
static/webui/translations/uk.js
+12
-0
Modified
static/webui/translations/zh.js
+12
-0
XFEstudio/XFESpaceNinjaServer
feat: tactical alerts (#2607)
Includes all `Tactical Alerts` since Star Chart 3.0 with exception: `Snowday Showdown` `Wolf Hunt (2019)` (couldn't find corresponded `EventNode` for that) `Void Corruption` (that's goes into `Alerts`) All `Warframe's Anniversary` Re #1103 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2607 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>
fd2ec696
代码差异
17 个文件
+1100
-23
@@ -71,10 +71,19 @@
71
71
"affinityBoost": false,
72
72
"resourceBoost": false,
73
73
"tennoLiveRelay": false,
74
"wolfHunt": false,
75
"longShadow": false,
76
"hallowedFlame": false,
77
"hallowedNightmares": false,
78
"hallowedNightmaresRewardsOverride": 0,
79
"proxyRebellion": false,
80
"proxyRebellionRewardsOverride": 0,
74
81
"galleonOfGhouls": 0,
75
82
"ghoulEmergenceOverride": null,
76
83
"plagueStarOverride": null,
77
84
"starDaysOverride": null,
85
"dogDaysOverride": null,
86
"dogDaysRewardsOverride": null,
78
87
"eidolonOverride": "",
79
88
"vallisOverride": "",
80
89
"duviriOverride": "",
@@ -13,7 +13,8 @@ import {
13
13
addItems,
14
14
combineInventoryChanges,
15
15
getEffectiveAvatarImageType,
16
getInventory
16
getInventory,
17
updateCurrency
17
18
} from "@/src/services/inventoryService";
18
19
import { logger } from "@/src/utils/logger";
19
20
import { ExportFlavour } from "warframe-public-export-plus";
@@ -100,6 +101,9 @@ export const inboxController: RequestHandler = async (req, res) => {
100
101
}
101
102
}
102
103
}
104
if (message.RegularCredits) {
105
updateCurrency(inventory, -message.RegularCredits, false, inventoryChanges);
106
}
103
107
await inventory.save();
104
108
res.json({ InventoryChanges: inventoryChanges });
105
109
} else if (latestClientMessageId) {
@@ -47,6 +47,7 @@ export interface IMessage {
47
47
acceptAction?: string;
48
48
declineAction?: string;
49
49
hasAccountAction?: boolean;
50
RegularCredits?: number;
50
51
}
51
52
52
53
export interface Arg {
@@ -139,7 +140,8 @@ const messageSchema = new Schema<IMessageDatabase>(
139
140
contextInfo: String,
140
141
acceptAction: String,
141
142
declineAction: String,
142
hasAccountAction: Boolean
143
hasAccountAction: Boolean,
144
RegularCredits: Number
143
145
},
144
146
{ id: false }
145
147
);
@@ -83,10 +83,19 @@ export interface IConfig {
83
83
resourceBoost?: boolean;
84
84
tennoLiveRelay?: boolean;
85
85
baroTennoConRelay?: boolean;
86
wolfHunt?: boolean;
87
longShadow?: boolean;
88
hallowedFlame?: boolean;
89
hallowedNightmares?: boolean;
90
hallowedNightmaresRewardsOverride?: number;
91
proxyRebellion?: boolean;
92
proxyRebellionRewardsOverride?: number;
86
93
galleonOfGhouls?: number;
87
94
ghoulEmergenceOverride?: boolean;
88
95
plagueStarOverride?: boolean;
89
96
starDaysOverride?: boolean;
97
dogDaysOverride?: boolean;
98
dogDaysRewardsOverride?: number;
90
99
eidolonOverride?: string;
91
100
vallisOverride?: string;
92
101
duviriOverride?: string;
@@ -50,7 +50,7 @@ import { getEntriesUnsafe } from "@/src/utils/ts-utils";
50
50
import { handleStoreItemAcquisition } from "@/src/services/purchaseService";
51
51
import { IMissionCredits, IMissionReward } from "@/src/types/missionTypes";
52
52
import { crackRelic } from "@/src/helpers/relicHelper";
53
import { createMessage } from "@/src/services/inboxService";
53
import { createMessage, IMessageCreationTemplate } from "@/src/services/inboxService";
54
54
import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.json";
55
55
import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json";
56
56
import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json";
@@ -624,37 +624,93 @@ export const addMissionInventoryUpdates = async (
624
624
if (goal && goal.Personal) {
625
625
inventory.PersonalGoalProgress ??= [];
626
626
const goalProgress = inventory.PersonalGoalProgress.find(x => x.goalId.equals(goal._id.$oid));
627
if (goalProgress) {
628
goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
629
goalProgress.Count += uploadProgress.Count;
630
} else {
627
if (!goalProgress) {
631
628
inventory.PersonalGoalProgress.push({
632
629
Best: uploadProgress.Best,
633
630
Count: uploadProgress.Count,
634
631
Tag: goal.Tag,
635
632
goalId: new Types.ObjectId(goal._id.$oid)
636
633
});
634
}
637
635
636
const currentNode = inventoryUpdates.RewardInfo!.node;
637
let currentMissionKey;
638
if (currentNode == goal.Node) {
639
currentMissionKey = goal.MissionKeyName;
640
} else if (goal.ConcurrentNodes && goal.ConcurrentMissionKeyNames) {
641
for (let i = 0; i < goal.ConcurrentNodes.length; i++) {
642
if (currentNode == goal.ConcurrentNodes[i]) {
643
currentMissionKey = goal.ConcurrentMissionKeyNames[i];
644
break;
645
}
646
}
647
}
648
if (currentMissionKey && currentMissionKey in goalMessagesByKey) {
649
const totalCount = (goalProgress?.Count ?? 0) + uploadProgress.Count;
650
let reward;
651
652
if (goal.InterimGoals && goal.InterimRewards) {
653
for (let i = 0; i < goal.InterimGoals.length; i++) {
654
if (
655
goal.InterimGoals[i] &&
656
goal.InterimGoals[i] <= totalCount &&
657
(!goalProgress || goalProgress.Count < goal.InterimGoals[i]) &&
658
goal.InterimRewards[i]
659
) {
660
reward = goal.InterimRewards[i];
661
break;
662
}
663
}
664
}
638
665
if (
639
goal.Reward &&
640
goal.Reward.items &&
641
goal.MissionKeyName &&
642
goal.MissionKeyName in goalMessagesByKey
666
!reward &&
667
goal.Goal &&
668
goal.Goal <= totalCount &&
669
(!goalProgress || goalProgress.Count < goal.Goal) &&
670
goal.Reward
643
671
) {
644
// Send reward via inbox
645
const info = goalMessagesByKey[goal.MissionKeyName];
646
await createMessage(inventory.accountOwnerId, [
647
{
672
reward = goal.Reward;
673
}
674
if (
675
!reward &&
676
goal.BonusGoal &&
677
goal.BonusGoal <= totalCount &&
678
(!goalProgress || goalProgress.Count < goal.BonusGoal) &&
679
goal.BonusReward
680
) {
681
reward = goal.BonusReward;
682
}
683
if (reward) {
684
if (currentMissionKey in goalMessagesByKey) {
685
// Send reward via inbox
686
const info = goalMessagesByKey[currentMissionKey];
687
const message: IMessageCreationTemplate = {
648
688
sndr: info.sndr,
649
689
msg: info.msg,
650
att: goal.Reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x)),
651
690
sub: info.sub,
652
691
icon: info.icon,
653
692
highPriority: true
693
};
694
695
if (reward.items) {
696
message.att = reward.items.map(x => (isStoreItem(x) ? fromStoreItem(x) : x));
654
697
}
655
]);
698
if (reward.countedItems) {
699
message.countedAtt = reward.countedItems;
700
}
701
if (reward.credits) {
702
message.RegularCredits = reward.credits;
703
}
704
705
await createMessage(inventory.accountOwnerId, [message]);
706
}
656
707
}
657
708
}
709
710
if (goalProgress) {
711
goalProgress.Best = Math.max(goalProgress.Best, uploadProgress.Best);
712
goalProgress.Count += uploadProgress.Count;
713
}
658
714
}
659
715
}
660
716
break;
@@ -1011,8 +1067,16 @@ export const addMissionRewards = async (
1011
1067
1012
1068
if (rewardInfo.goalId) {
1013
1069
const goal = getWorldState().Goals.find(x => x._id.$oid == rewardInfo.goalId);
1014
if (goal?.MissionKeyName) {
1015
levelKeyName = goal.MissionKeyName;
1070
if (goal) {
1071
if (rewardInfo.node == goal.Node && goal.MissionKeyName) levelKeyName = goal.MissionKeyName;
1072
if (goal.ConcurrentNodes && goal.ConcurrentMissionKeyNames) {
1073
for (let i = 0; i < goal.ConcurrentNodes.length && i < goal.ConcurrentMissionKeyNames.length; i++) {
1074
if (rewardInfo.node == goal.ConcurrentNodes[i]) {
1075
levelKeyName = goal.ConcurrentMissionKeyNames[i];
1076
break;
1077
}
1078
}
1079
}
1016
1080
}
1017
1081
}
1018
1082
@@ -2149,5 +2213,143 @@ const goalMessagesByKey: Record<string, { sndr: string; msg: string; sub: string
2149
2213
msg: "/Lotus/Language/Messages/GalleonRobbery2025RewardMsgC",
2150
2214
sub: "/Lotus/Language/Messages/GalleonRobbery2025MissionTitleC",
2151
2215
icon: "/Lotus/Interface/Icons/Npcs/VayHekPortrait.png"
2216
},
2217
"/Lotus/Types/Keys/TacAlertKeyWaterFightA": {
2218
sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
2219
msg: "/Lotus/Language/Inbox/WaterFightRewardMsgA",
2220
sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectA",
2221
icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
2222
},
2223
"/Lotus/Types/Keys/TacAlertKeyWaterFightB": {
2224
sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
2225
msg: "/Lotus/Language/Inbox/WaterFightRewardMsgB",
2226
sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectB",
2227
icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
2228
},
2229
"/Lotus/Types/Keys/TacAlertKeyWaterFightC": {
2230
sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
2231
msg: "/Lotus/Language/Inbox/WaterFightRewardMsgC",
2232
sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectC",
2233
icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
2234
},
2235
"/Lotus/Types/Keys/TacAlertKeyWaterFightD": {
2236
sndr: "/Lotus/Language/Bosses/BossKelaDeThaym",
2237
msg: "/Lotus/Language/Inbox/WaterFightRewardMsgD",
2238
sub: "/Lotus/Language/Inbox/WaterFightRewardSubjectD",
2239
icon: "/Lotus/Interface/Icons/Npcs/Grineer/KelaDeThaym.png"
2240
},
2241
"/Lotus/Types/Keys/WolfTacAlertReduxA": {
2242
sndr: "/Lotus/Language/Bosses/NoraNight",
2243
msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
2244
sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
2245
icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
2246
},
2247
"/Lotus/Types/Keys/WolfTacAlertReduxB": {
2248
sndr: "/Lotus/Language/Bosses/NoraNight",
2249
msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
2250
sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
2251
icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
2252
},
2253
"/Lotus/Types/Keys/WolfTacAlertReduxD": {
2254
sndr: "/Lotus/Language/Bosses/NoraNight",
2255
msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
2256
sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
2257
icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
2258
},
2259
"/Lotus/Types/Keys/WolfTacAlertReduxC": {
2260
sndr: "/Lotus/Language/Bosses/NoraNight",
2261
msg: "/Lotus/Language/Inbox/WolfTacAlertBody",
2262
sub: "/Lotus/Language/Inbox/WolfTacAlertTitle",
2263
icon: "/Lotus/Interface/Icons/Npcs/Seasonal/NoraNight.png"
2264
},
2265
"/Lotus/Types/Keys/LanternEndlessEventKeyA": {
2266
sndr: "/Lotus/Language/Bosses/Lotus",
2267
msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
2268
sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
2269
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2270
},
2271
"/Lotus/Types/Keys/LanternEndlessEventKeyB": {
2272
sndr: "/Lotus/Language/Bosses/Lotus",
2273
msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
2274
sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
2275
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2276
},
2277
"/Lotus/Types/Keys/LanternEndlessEventKeyD": {
2278
sndr: "/Lotus/Language/Bosses/Lotus",
2279
msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
2280
sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
2281
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2282
},
2283
"/Lotus/Types/Keys/LanternEndlessEventKeyC": {
2284
sndr: "/Lotus/Language/Bosses/Lotus",
2285
msg: "/Lotus/Language/G1Quests/GenericEventRewardMsgDesc",
2286
sub: "/Lotus/Language/G1Quests/GenericTacAlertRewardMsgTitle",
2287
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2288
},
2289
"/Lotus/Types/Keys/TacAlertKeyHalloween": {
2290
sndr: "/Lotus/Language/Bosses/Lotus",
2291
msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBonusBody",
2292
sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBonusTitle",
2293
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2294
},
2295
"/Lotus/Types/Keys/TacAlertKeyHalloweenBonus": {
2296
sndr: "/Lotus/Language/Bosses/Lotus",
2297
msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBody",
2298
sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsTitle",
2299
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2300
},
2301
"/Lotus/Types/Keys/TacAlertKeyHalloweenTimeAttack": {
2302
sndr: "/Lotus/Language/Bosses/Lotus",
2303
msg: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsBody",
2304
sub: "/Lotus/Language/G1Quests/TacAlertHalloweenRewardsTitle",
2305
icon: "/Lotus/Interface/Icons/Npcs/LotusVamp_d.png"
2306
},
2307
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionOne": {
2308
sndr: "/Lotus/Language/Bosses/Lotus",
2309
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
2310
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
2311
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2312
},
2313
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionTwo": {
2314
sndr: "/Lotus/Language/Bosses/Lotus",
2315
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
2316
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
2317
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2318
},
2319
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionThree": {
2320
sndr: "/Lotus/Language/Bosses/Lotus",
2321
msg: "/Lotus/Language/G1Quests/RazorbackArmadaRewardBody",
2322
sub: "/Lotus/Language/G1Quests/GenericTacAlertSmallRewardMsgTitle",
2323
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2324
},
2325
"/Lotus/Types/Keys/TacAlertKeyProxyRebellionFour": {
2326
sndr: "/Lotus/Language/Bosses/Lotus",
2327
msg: "/Lotus/Language/G1Quests/GenericTacAlertBadgeRewardMsgDesc",
2328
sub: "/Lotus/Language/G1Quests/GenericTacAlertBadgeRewardMsgTitle",
2329
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2330
},
2331
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatchEasy": {
2332
sndr: "/Lotus/Language/Bosses/Lotus",
2333
msg: "/Lotus/Language/G1Quests/ProjectNightwatchRewardMsgA",
2334
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionOneTitle",
2335
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2336
},
2337
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatch": {
2338
sndr: "/Lotus/Language/Bosses/Lotus",
2339
msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
2340
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionTwoTitle",
2341
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2342
},
2343
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatchHard": {
2344
sndr: "/Lotus/Language/Bosses/Lotus",
2345
msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
2346
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionThreeTitle",
2347
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2348
},
2349
"/Lotus/Types/Keys/TacAlertKeyProjectNightwatchBonus": {
2350
sndr: "/Lotus/Language/Bosses/Lotus",
2351
msg: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionRewardBody",
2352
sub: "/Lotus/Language/G1Quests/ProjectNightwatchTacAlertMissionFourTitle",
2353
icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png"
2152
2354
}
2153
2355
};
@@ -5,12 +5,14 @@ export interface IWorldState {
5
5
Version: number; // for goals
6
6
BuildLabel: string;
7
7
Time: number;
8
InGameMarket: IInGameMarket;
8
9
Goals: IGoal[];
9
10
Alerts: [];
10
11
Sorties: ISortie[];
11
12
LiteSorties: ILiteSortie[];
12
13
SyndicateMissions: ISyndicateMissionInfo[];
13
14
ActiveMissions: IFissure[];
15
FlashSales: IFlashSale[];
14
16
GlobalUpgrades: IGlobalUpgrade[];
15
17
Invasions: IInvasion[];
16
18
NodeOverrides: INodeOverride[];
@@ -39,10 +41,13 @@ export interface IGoal {
39
41
Expiry: IMongoDate;
40
42
Count?: number;
41
43
Goal?: number;
44
InterimGoals?: number[];
45
BonusGoal?: number;
42
46
HealthPct?: number;
43
47
Success?: number;
44
48
Personal?: boolean;
45
Bounty?: boolean;
49
Best?: boolean;
50
Bounty?: boolean; // Tactical Alert
46
51
Faction?: string;
47
52
ClampNodeScores?: boolean;
48
53
Desc: string;
@@ -51,18 +56,28 @@ export interface IGoal {
51
56
InstructionalItem?: string;
52
57
Icon: string;
53
58
Tag: string;
59
PrereqGoalTags?: string[];
54
60
Node?: string;
55
61
VictimNode?: string;
62
ConcurrentMissionKeyNames?: string[];
63
ConcurrentNodeReqs?: number[];
64
ConcurrentNodes?: string[];
56
65
RegionIdx?: number;
57
66
Regions?: number[];
58
67
MissionKeyName?: string;
59
68
Reward?: IMissionReward;
69
InterimRewards?: IMissionReward[];
70
BonusReward?: IMissionReward;
60
71
61
72
JobAffiliationTag?: string;
62
73
Jobs?: ISyndicateJob[];
63
74
PreviousJobs?: ISyndicateJob[];
64
75
JobCurrentVersion?: IOid;
65
76
JobPreviousVersion?: IOid;
77
78
ScoreVar?: string;
79
ScoreMaxTag?: string;
80
NightLevel?: string;
66
81
}
67
82
68
83
export interface ISyndicateJob {
@@ -321,6 +336,37 @@ export type TCircuitGameMode =
321
336
| "Assassination"
322
337
| "Alchemy";
323
338
339
export interface IFlashSale {
340
TypeName: string;
341
ShowInMarket: boolean;
342
HideFromMarket: boolean;
343
SupporterPack: boolean;
344
Discount: number;
345
BogoBuy: number;
346
BogoGet: number;
347
PremiumOverride: number;
348
RegularOverride: number;
349
ProductExpiryOverride?: IMongoDate;
350
StartDate: IMongoDate;
351
EndDate: IMongoDate;
352
}
353
354
export interface IInGameMarket {
355
LandingPage: ILandingPage;
356
}
357
358
export interface ILandingPage {
359
Categories: IGameMarketCategory[];
360
}
361
362
export interface IGameMarketCategory {
363
CategoryName: string;
364
Name: string;
365
Icon: string;
366
AddToMenu?: boolean;
367
Items?: string[];
368
}
369
324
370
export interface ITmp {
325
371
cavabegin: string;
326
372
PurchasePlatformLockEnabled: boolean; // Seems unused
@@ -937,8 +937,57 @@
937
937
<input class="form-check-input" type="checkbox" id="worldState.varziaFullyStocked" />
938
938
<label class="form-check-label" for="worldState.varziaFullyStocked" data-loc="worldState_varziaFullyStocked"></label>
939
939
</div>
940
<div class="form-check">
941
<input class="form-check-input" type="checkbox" id="worldState.wolfHunt" />
942
<label class="form-check-label" for="worldState.wolfHunt" data-loc="worldState_wolfHunt"></label>
943
<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>
944
</div>
945
<div class="form-check">
946
<input class="form-check-input" type="checkbox" id="worldState.longShadow" />
947
<label class="form-check-label" for="worldState.longShadow" data-loc="worldState_longShadow"></label>
948
</div>
949
<div class="form-check">
950
<input class="form-check-input" type="checkbox" id="worldState.hallowedFlame" />
951
<label class="form-check-label" for="worldState.hallowedFlame" data-loc="worldState_hallowedFlame"></label>
952
<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>
953
</div>
954
<div class="form-group mt-2 d-flex gap-2">
955
<div class="flex-fill">
956
<label class="form-label" for="worldState.hallowedNightmares" data-loc="worldState_hallowedNightmares"></label>
957
<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>
958
<select class="form-control" id="worldState.hallowedNightmares" data-default="false">
959
<option value="true" data-loc="enabled"></option>
960
<option value="false" data-loc="disabled"></option>
961
</select>
962
</div>
963
<div class="flex-fill">
964
<label class="form-label" for="worldState.hallowedNightmaresRewardsOverride" data-loc="worldState_hallowedNightmaresRewards"></label>
965
<select class="form-control" id="worldState.hallowedNightmaresRewardsOverride" data-default="0">
966
<option value="0" data-loc="worldState_from_year" data-loc-year="2018"></option>
967
<option value="1" data-loc="worldState_from_year" data-loc-year="2016"></option>
968
<option value="2" data-loc="worldState_from_year" data-loc-year="2015"></option>
969
</select>
970
</div>
971
</div>
972
<div class="form-group mt-2 d-flex gap-2">
973
<div class="flex-fill">
974
<label class="form-label" for="worldState.proxyRebellion" data-loc="worldState_proxyRebellion"></label>
975
<select class="form-control" id="worldState.proxyRebellion" data-default="false">
976
<option value="true" data-loc="enabled"></option>
977
<option value="false" data-loc="disabled"></option>
978
</select>
979
</div>
980
<div class="flex-fill">
981
<label class="form-label" for="worldState.proxyRebellionRewardsOverride" data-loc="worldState_proxyRebellionRewards"></label>
982
<select class="form-control" id="worldState.proxyRebellionRewardsOverride" data-default="0">
983
<option value="0" data-loc="worldState_from_year" data-loc-year="2019"></option>
984
<option value="1" data-loc="worldState_from_year" data-loc-year="2018"></option>
985
</select>
986
</div>
987
</div>
940
988
<div class="form-group mt-2">
941
989
<label class="form-label" for="worldState.galleonOfGhouls" data-loc="worldState_galleonOfGhouls"></label>
990
<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>
942
991
<select class="form-control" id="worldState.galleonOfGhouls" data-default="0">
943
992
<option value="0" data-loc="disabled"></option>
944
993
<option value="1" data-loc="worldState_we1"></option>
@@ -970,6 +1019,27 @@
970
1019
<option value="false" data-loc="disabled"></option>
971
1020
</select>
972
1021
</div>
1022
<div class="form-group mt-2 d-flex gap-2">
1023
<div class="flex-fill">
1024
<label class="form-label" for="worldState.dogDaysOverride" data-loc="worldState_dogDays"></label>
1025
<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>
1026
<select class="form-control" id="worldState.dogDaysOverride" data-default="null">
1027
<option value="null" data-loc="normal"></option>
1028
<option value="true" data-loc="enabled"></option>
1029
<option value="false" data-loc="disabled"></option>
1030
</select>
1031
</div>
1032
<div class="flex-fill">
1033
<label class="form-label" for="worldState.dogDaysRewardsOverride" data-loc="worldState_dogDaysRewards"></label>
1034
<select class="form-control" id="worldState.dogDaysRewardsOverride" data-default="null">
1035
<option value="null" data-loc="normal"></option>
1036
<option value="3" data-loc="worldState_from_year" data-loc-year="2025"></option>
1037
<option value="2" data-loc="worldState_from_year" data-loc-year="2024"></option>
1038
<option value="1" data-loc="worldState_from_year" data-loc-year="2023"></option>
1039
<option value="0" data-loc="worldState_pre_year" data-loc-year="2023"></option>
1040
</select>
1041
</div>
1042
</div>
973
1043
<div class="form-group mt-2">
974
1044
<label class="form-label" for="worldState.eidolonOverride" data-loc="worldState_eidolonOverride"></label>
975
1045
<select class="form-control" id="worldState.eidolonOverride" data-default="">
@@ -202,6 +202,17 @@ function updateLocElements() {
202
202
document.querySelectorAll("[data-loc-placeholder]").forEach(elm => {
203
203
elm.placeholder = loc(elm.getAttribute("data-loc-placeholder"));
204
204
});
205
document.querySelectorAll("[data-loc-inc]").forEach(elm => {
206
const incWith = elm
207
.getAttribute("data-loc-inc")
208
.split("|")
209
.map(key => loc(key))
210
.join(", ");
211
elm.title = `${loc("worldState_incompatibleWith")} ${incWith}`;
212
});
213
document.querySelectorAll("[data-loc-year]").forEach(elm => {
214
elm.innerHTML = elm.innerHTML.replace("|YEAR|", elm.getAttribute("data-loc-year"));
215
});
205
216
}
206
217
207
218
function setActiveLanguage(lang) {
@@ -29,9 +29,12 @@ body:not(.logged-in) .user-dropdown {
29
29
display: none;
30
30
}
31
31
32
td.text-end > a > svg {
32
/* font awesome icons */
33
svg {
33
34
fill: currentColor;
34
35
height: 1em;
36
}
37
td.text-end > a > svg {
35
38
margin-left: 0.5em;
36
39
margin-bottom: 4px; /* to centre the icon */
37
40
}
@@ -248,6 +248,18 @@ dict = {
248
248
worldState_galleonOfGhouls: `Galeone der Ghule`,
249
249
worldState_ghoulEmergence: `Ghul Ausrottung`,
250
250
worldState_plagueStar: `Plagenstern`,
251
worldState_dogDays: `Hitzefrei`,
252
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
253
worldState_wolfHunt: `Wolfsjagd (2025)`,
254
worldState_longShadow: `Lange Schatten`,
255
worldState_hallowedFlame: `Geweihte Flamme`,
256
worldState_hallowedNightmares: `Geweihte Albträume`,
257
worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
258
worldState_proxyRebellion: `Proxy-Rebellion`,
259
worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
260
worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
261
worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
262
worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
251
263
enabled: `Aktiviert`,
252
264
disabled: `Deaktiviert`,
253
265
worldState_we1: `Wochenende 1`,
@@ -247,6 +247,18 @@ dict = {
247
247
worldState_galleonOfGhouls: `Galleon of Ghouls`,
248
248
worldState_ghoulEmergence: `Ghoul Purge`,
249
249
worldState_plagueStar: `Plague Star`,
250
worldState_dogDays: `Dog Days`,
251
worldState_dogDaysRewards: `Dog Days Rewards`,
252
worldState_wolfHunt: `Wolf Hunt (2025)`,
253
worldState_longShadow: `Long Shadow`,
254
worldState_hallowedFlame: `Hallowed Flame`,
255
worldState_hallowedNightmares: `Hallowed Nightmares`,
256
worldState_hallowedNightmaresRewards: `Hallowed Nightmares Rewards`,
257
worldState_proxyRebellion: `Proxy Rebellion`,
258
worldState_proxyRebellionRewards: `Proxy Rebellion Rewards`,
259
worldState_from_year: `from |YEAR|`,
260
worldState_pre_year: `pre |YEAR|`,
261
worldState_incompatibleWith: `Incompatible with:`,
250
262
enabled: `Enabled`,
251
263
disabled: `Disabled`,
252
264
worldState_we1: `Weekend 1`,
@@ -248,6 +248,18 @@ dict = {
248
248
worldState_galleonOfGhouls: `Galeón de Gules`,
249
249
worldState_ghoulEmergence: `Purga de Gules`,
250
250
worldState_plagueStar: `Estrella Infestada`,
251
worldState_dogDays: `Canícula`,
252
worldState_dogDaysRewards: `[UNTRANSLATED] Dog Days Rewards`,
253
worldState_wolfHunt: `Cacería del Lobo (2025)`,
254
worldState_longShadow: `Sombra Prolongada`,
255
worldState_hallowedFlame: `Llama Sagrada`,
256
worldState_hallowedNightmares: `Pesadillas sagradas`,
257
worldState_hallowedNightmaresRewards: `[UNTRANSLATED] Hallowed Nightmares Rewards`,
258
worldState_proxyRebellion: `Rebelión Proxy`,
259
worldState_proxyRebellionRewards: `[UNTRANSLATED] Proxy Rebellion Rewards`,
260
worldState_from_year: `[UNTRANSLATED] from |YEAR|`,
261
worldState_pre_year: `[UNTRANSLATED] pre |YEAR|`,
262
worldState_incompatibleWith: `[UNTRANSLATED] Incompatible with:`,
251
263
enabled: `Activado`,
252
264
disabled: `Desactivado`,
253
265
worldState_we1: `Semana 1`,