返回提交历史
Modified
config-vanilla.json
+2
-0
Modified
src/services/configService.ts
+2
-0
Modified
src/services/missionInventoryUpdateService.ts
+68
-22
Modified
src/services/worldStateService.ts
+170
-0
Modified
src/types/worldStateTypes.ts
+33
-16
Modified
static/webui/index.html
+16
-0
Modified
static/webui/translations/de.js
+2
-0
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/uk.js
+2
-0
Modified
static/webui/translations/zh.js
+2
-0
XFEstudio/XFESpaceNinjaServer
feat(goals): cetus events (#2598)
Includes `Plague Star` and `Ghoul Purge`. Translation for webUI taken from game files. Re #1103 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2598 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>
51c0ddda
代码差异
13 个文件
+305
-38
@@ -72,6 +72,8 @@
72
72
"resourceBoost": false,
73
73
"tennoLiveRelay": false,
74
74
"galleonOfGhouls": 0,
75
"ghoulEmergenceOverride": null,
76
"plagueStarOverride": null,
75
77
"starDaysOverride": null,
76
78
"eidolonOverride": "",
77
79
"vallisOverride": "",
@@ -84,6 +84,8 @@ export interface IConfig {
84
84
tennoLiveRelay?: boolean;
85
85
baroTennoConRelay?: boolean;
86
86
galleonOfGhouls?: number;
87
ghoulEmergenceOverride?: boolean;
88
plagueStarOverride?: boolean;
87
89
starDaysOverride?: boolean;
88
90
eidolonOverride?: string;
89
91
vallisOverride?: string;
@@ -76,7 +76,7 @@ import {
76
76
} from "@/src/services/worldStateService";
77
77
import { config } from "@/src/services/configService";
78
78
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
79
import { ISyndicateMissionInfo } from "@/src/types/worldStateTypes";
79
import { IGoal, ISyndicateMissionInfo } from "@/src/types/worldStateTypes";
80
80
import { fromOid } from "@/src/helpers/inventoryHelpers";
81
81
import { TAccountDocument } from "@/src/services/loginService";
82
82
import { ITypeCount } from "@/src/types/commonTypes";
@@ -1259,6 +1259,8 @@ export const addMissionRewards = async (
1259
1259
}
1260
1260
}
1261
1261
1262
AffiliationMods ??= [];
1263
1262
1264
if (rewardInfo.JobStage != undefined && rewardInfo.jobId) {
1263
1265
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1264
1266
const [jobType, unkIndex, hubNode, syndicateMissionId] = rewardInfo.jobId.split("_");
@@ -1266,9 +1268,29 @@ export const addMissionRewards = async (
1266
1268
if (syndicateMissionId) {
1267
1269
pushClassicBounties(syndicateMissions, idToBountyCycle(syndicateMissionId));
1268
1270
}
1269
const syndicateEntry = syndicateMissions.find(m => m._id.$oid === syndicateMissionId);
1271
let syndicateEntry: ISyndicateMissionInfo | IGoal | undefined = syndicateMissions.find(
1272
m => m._id.$oid === syndicateMissionId
1273
);
1274
if (
1275
[
1276
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1277
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1278
].some(prefix => jobType.startsWith(prefix))
1279
) {
1280
const { Goals } = getWorldState(undefined);
1281
syndicateEntry = Goals.find(m => m._id.$oid === syndicateMissionId);
1282
if (syndicateEntry) syndicateEntry.Tag = syndicateEntry.JobAffiliationTag!;
1283
}
1270
1284
if (syndicateEntry && syndicateEntry.Jobs) {
1271
1285
let currentJob = syndicateEntry.Jobs[rewardInfo.JobTier!];
1286
if (
1287
[
1288
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1289
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1290
].some(prefix => jobType.startsWith(prefix))
1291
) {
1292
currentJob = syndicateEntry.Jobs.find(j => j.jobType === jobType)!;
1293
}
1272
1294
if (syndicateEntry.Tag === "EntratiSyndicate") {
1273
1295
if (
1274
1296
[
@@ -1311,31 +1333,35 @@ export const addMissionRewards = async (
1311
1333
`Giving ${medallionAmount} medallions for the ${rewardInfo.JobStage} stage of the ${rewardInfo.JobTier} tier bounty`
1312
1334
);
1313
1335
} else {
1314
if (rewardInfo.JobTier! >= 0) {
1315
addStanding(
1316
inventory,
1317
syndicateEntry.Tag,
1318
Math.floor(currentJob.xpAmounts[rewardInfo.JobStage] / (rewardInfo.Q ? 0.8 : 1)),
1319
AffiliationMods
1320
);
1321
} else {
1322
if (jobType.endsWith("Heists/HeistProfitTakerBountyOne") && rewardInfo.JobStage === 2) {
1323
addStanding(inventory, syndicateEntry.Tag, 1000, AffiliationMods);
1324
}
1325
if (jobType.endsWith("Hunts/AllTeralystsHunt") && rewardInfo.JobStage === 2) {
1326
addStanding(inventory, syndicateEntry.Tag, 5000, AffiliationMods);
1327
}
1328
if (
1329
[
1336
const specialCase = [
1337
{ endings: ["Heists/HeistProfitTakerBountyOne"], stage: 2, amount: 1000 },
1338
{ endings: ["Hunts/AllTeralystsHunt"], stage: 2, amount: 5000 },
1339
{
1340
endings: [
1330
1341
"Hunts/TeralystHunt",
1331
1342
"Heists/HeistProfitTakerBountyTwo",
1332
1343
"Heists/HeistProfitTakerBountyThree",
1333
1344
"Heists/HeistProfitTakerBountyFour",
1334
1345
"Heists/HeistExploiterBountyOne"
1335
].some(ending => jobType.endsWith(ending))
1336
) {
1337
addStanding(inventory, syndicateEntry.Tag, 1000, AffiliationMods);
1346
],
1347
amount: 1000
1338
1348
}
1349
];
1350
const specialCaseReward = specialCase.find(
1351
rule =>
1352
rule.endings.some(e => jobType.endsWith(e)) &&
1353
(rule.stage === undefined || rewardInfo.JobStage === rule.stage)
1354
);
1355
1356
if (specialCaseReward) {
1357
addStanding(inventory, syndicateEntry.Tag, specialCaseReward.amount, AffiliationMods);
1358
} else {
1359
addStanding(
1360
inventory,
1361
syndicateEntry.Tag,
1362
Math.floor(currentJob.xpAmounts[rewardInfo.JobStage] / (rewardInfo.Q ? 0.8 : 1)),
1363
AffiliationMods
1364
);
1339
1365
}
1340
1366
}
1341
1367
}
@@ -1672,7 +1698,19 @@ function getRandomMissionDrops(
1672
1698
if (syndicateMissionId) {
1673
1699
pushClassicBounties(syndicateMissions, idToBountyCycle(syndicateMissionId));
1674
1700
}
1675
const syndicateEntry = syndicateMissions.find(m => m._id.$oid === syndicateMissionId);
1701
let syndicateEntry: ISyndicateMissionInfo | IGoal | undefined = syndicateMissions.find(
1702
m => m._id.$oid === syndicateMissionId
1703
);
1704
if (
1705
[
1706
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1707
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1708
].some(prefix => jobType.startsWith(prefix))
1709
) {
1710
const { Goals } = getWorldState(undefined);
1711
syndicateEntry = Goals.find(m => m._id.$oid === syndicateMissionId);
1712
if (syndicateEntry) syndicateEntry.Tag = syndicateEntry.JobAffiliationTag!;
1713
}
1676
1714
if (syndicateEntry && syndicateEntry.Jobs) {
1677
1715
let job = syndicateEntry.Jobs[RewardInfo.JobTier!];
1678
1716
@@ -1757,6 +1795,14 @@ function getRandomMissionDrops(
1757
1795
}
1758
1796
}
1759
1797
}
1798
if (
1799
[
1800
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1801
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1802
].some(prefix => jobType.startsWith(prefix))
1803
) {
1804
job = syndicateEntry.Jobs.find(j => j.jobType === jobType)!;
1805
}
1760
1806
rewardManifests = [job.rewards];
1761
1807
if (job.xpAmounts.length > 1) {
1762
1808
const curentStage = RewardInfo.JobStage! + 1;
@@ -131,6 +131,13 @@ const eidolonNarmerJobs: readonly string[] = [
131
131
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
132
132
];
133
133
134
const eidolonGhoulJobs: readonly string[] = [
135
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBountyAss",
136
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBountyExt",
137
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBountyHunt",
138
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBountyRes"
139
];
140
134
141
const venusJobs: readonly string[] = [
135
142
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
136
143
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
@@ -1556,6 +1563,72 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1556
1563
});
1557
1564
}
1558
1565
1566
const firstNovemberWeekday = new Date(Date.UTC(date.getUTCFullYear(), 10, 1)).getUTCDay();
1567
const firstNovemberMondayOffset = (8 - firstNovemberWeekday) % 7;
1568
1569
const plagueStarStart = Date.UTC(date.getUTCFullYear(), 10, firstNovemberMondayOffset + 1, 16);
1570
const plagueStarEnd = Date.UTC(date.getUTCFullYear(), 10, firstNovemberMondayOffset + 15, 16);
1571
1572
const isPlagueStarActive = timeMs >= plagueStarStart && timeMs < plagueStarEnd;
1573
if (config.worldState?.plagueStarOverride ?? isPlagueStarActive) {
1574
worldState.Goals.push({
1575
_id: { $oid: "654a5058c757487cdb11824f" },
1576
Activation: {
1577
$date: {
1578
$numberLong: config.worldState?.plagueStarOverride ? "1699372800000" : plagueStarStart.toString()
1579
}
1580
},
1581
Expiry: {
1582
$date: {
1583
$numberLong: config.worldState?.plagueStarOverride ? "2000000000000" : plagueStarEnd.toString()
1584
}
1585
},
1586
Tag: "InfestedPlains",
1587
RegionIdx: 2,
1588
Faction: "FC_INFESTATION",
1589
Desc: "/Lotus/Language/InfestedPlainsEvent/InfestedPlainsBountyName",
1590
ToolTip: "/Lotus/Language/InfestedPlainsEvent/InfestedPlainsBountyDesc",
1591
Icon: "/Lotus/Materials/Emblems/PlagueStarEventBadge_e.png",
1592
JobAffiliationTag: "EventSyndicate",
1593
Jobs: [
1594
{
1595
jobType: "/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1596
rewards: "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/PlagueStarTableRewards",
1597
minEnemyLevel: 15,
1598
maxEnemyLevel: 25,
1599
xpAmounts: [50, 300, 100, 575]
1600
},
1601
{
1602
jobType: "/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBountyAdvanced",
1603
rewards: "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/PlagueStarTableRewards",
1604
minEnemyLevel: 55,
1605
maxEnemyLevel: 65,
1606
xpAmounts: [200, 1000, 300, 1700],
1607
requiredItems: [
1608
"/Lotus/StoreItems/Types/Items/Eidolon/InfestedEventIngredient",
1609
"/Lotus/StoreItems/Types/Items/Eidolon/InfestedEventClanIngredient"
1610
],
1611
useRequiredItemsAsMiscItemFee: true
1612
},
1613
{
1614
jobType: "/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBountySteelPath",
1615
rewards: "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/PlagueStarTableSteelPathRewards",
1616
minEnemyLevel: 100,
1617
maxEnemyLevel: 110,
1618
xpAmounts: [200, 1100, 400, 2100],
1619
masteryReq: 10,
1620
requiredItems: [
1621
"/Lotus/StoreItems/Types/Items/Eidolon/InfestedEventIngredient",
1622
"/Lotus/StoreItems/Types/Items/Eidolon/InfestedEventClanIngredient"
1623
],
1624
useRequiredItemsAsMiscItemFee: true
1625
}
1626
],
1627
Transmission: "/Lotus/Sounds/Dialog/PlainsMeteorLeadUp/LeadUp/DLeadUp0021Lotus",
1628
InstructionalItem: "/Lotus/Types/StoreItems/Packages/PlagueStarEventStoreItem"
1629
});
1630
}
1631
1559
1632
// Nightwave Challenges
1560
1633
const nightwaveSyndicateTag = getNightwaveSyndicateTag(buildLabel);
1561
1634
if (nightwaveSyndicateTag) {
@@ -1626,6 +1699,103 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1626
1699
pushClassicBounties(worldState.SyndicateMissions, bountyCycle);
1627
1700
} while (isBeforeNextExpectedWorldStateRefresh(timeMs, bountyCycleEnd) && ++bountyCycle);
1628
1701
1702
const ghoulsCycleDay = day % 21;
1703
const isGhoulEmergenceActive = ghoulsCycleDay >= 17 && ghoulsCycleDay <= 20; // 4 days for event and 17 days for break
1704
if (config.worldState?.ghoulEmergenceOverride ?? isGhoulEmergenceActive) {
1705
const ghoulPool = [...eidolonGhoulJobs];
1706
const pastGhoulPool = [...eidolonGhoulJobs];
1707
1708
const seed = new SRng(bountyCycle).randomInt(0, 100_000);
1709
const pastSeed = new SRng(bountyCycle - 1).randomInt(0, 100_000);
1710
1711
const rng = new SRng(seed);
1712
const pastRng = new SRng(pastSeed);
1713
1714
const activeStartDay = day - ghoulsCycleDay + 17;
1715
const activeEndDay = activeStartDay + 5;
1716
const dayWithFraction = (timeMs - EPOCH) / 86400000;
1717
1718
const progress = (dayWithFraction - activeStartDay) / (activeEndDay - activeStartDay);
1719
const healthPct = 1 - Math.min(Math.max(progress, 0), 1);
1720
1721
worldState.Goals.push({
1722
_id: { $oid: "687ebbe6d1d17841c9c59f38" },
1723
Activation: {
1724
$date: {
1725
$numberLong: config.worldState?.ghoulEmergenceOverride
1726
? "1753204900185"
1727
: Date.UTC(
1728
date.getUTCFullYear(),
1729
date.getUTCMonth(),
1730
date.getUTCDate() + (day - ghoulsCycleDay + 17)
1731
).toString()
1732
}
1733
},
1734
Expiry: {
1735
$date: {
1736
$numberLong: config.worldState?.ghoulEmergenceOverride
1737
? "2000000000000"
1738
: Date.UTC(
1739
date.getUTCFullYear(),
1740
date.getUTCMonth(),
1741
date.getUTCDate() + (day - ghoulsCycleDay + 21)
1742
).toString()
1743
}
1744
},
1745
HealthPct: config.worldState?.ghoulEmergenceOverride ? 1 : healthPct,
1746
VictimNode: "SolNode228",
1747
Regions: [2],
1748
Success: 0,
1749
Desc: "/Lotus/Language/GameModes/RecurringGhoulAlert",
1750
ToolTip: "/Lotus/Language/GameModes/RecurringGhoulAlertDesc",
1751
Icon: "/Lotus/Interface/Icons/Categories/IconGhouls256.png",
1752
Tag: "GhoulEmergence",
1753
JobAffiliationTag: "CetusSyndicate",
1754
JobCurrentVersion: {
1755
$oid: ((bountyCycle * 9000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000008"
1756
},
1757
Jobs: [
1758
{
1759
jobType: rng.randomElementPop(ghoulPool),
1760
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/GhoulBountyTableARewards`,
1761
masteryReq: 1,
1762
minEnemyLevel: 15,
1763
maxEnemyLevel: 25,
1764
xpAmounts: [270, 270, 270, 400] // not faithful
1765
},
1766
{
1767
jobType: rng.randomElementPop(ghoulPool),
1768
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/GhoulBountyTableBRewards`,
1769
masteryReq: 3,
1770
minEnemyLevel: 40,
1771
maxEnemyLevel: 50,
1772
xpAmounts: [480, 480, 480, 710] // not faithful
1773
}
1774
],
1775
JobPreviousVersion: {
1776
$oid: (((bountyCycle - 1) * 9000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000008"
1777
},
1778
PreviousJobs: [
1779
{
1780
jobType: pastRng.randomElementPop(pastGhoulPool),
1781
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/GhoulBountyTableARewards`,
1782
masteryReq: 1,
1783
minEnemyLevel: 15,
1784
maxEnemyLevel: 25,
1785
xpAmounts: [270, 270, 270, 400] // not faithful
1786
},
1787
{
1788
jobType: pastRng.randomElementPop(pastGhoulPool),
1789
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/GhoulBountyTableBRewards`,
1790
masteryReq: 3,
1791
minEnemyLevel: 40,
1792
maxEnemyLevel: 50,
1793
xpAmounts: [480, 480, 480, 710] // not faithful
1794
}
1795
]
1796
});
1797
}
1798
1629
1799
if (config.worldState?.creditBoost) {
1630
1800
worldState.GlobalUpgrades.push({
1631
1801
_id: { $oid: "5b23106f283a555109666672" },
@@ -37,19 +37,46 @@ export interface IGoal {
37
37
_id: IOid;
38
38
Activation: IMongoDate;
39
39
Expiry: IMongoDate;
40
Count: number;
41
Goal: number;
42
Success: number;
43
Personal: boolean;
40
Count?: number;
41
Goal?: number;
42
HealthPct?: number;
43
Success?: number;
44
Personal?: boolean;
44
45
Bounty?: boolean;
46
Faction?: string;
45
47
ClampNodeScores?: boolean;
46
48
Desc: string;
47
49
ToolTip?: string;
50
Transmission?: string;
51
InstructionalItem?: string;
48
52
Icon: string;
49
53
Tag: string;
50
Node: string;
54
Node?: string;
55
VictimNode?: string;
56
RegionIdx?: number;
57
Regions?: number[];
51
58
MissionKeyName?: string;
52
59
Reward?: IMissionReward;
60
61
JobAffiliationTag?: string;
62
Jobs?: ISyndicateJob[];
63
PreviousJobs?: ISyndicateJob[];
64
JobCurrentVersion?: IOid;
65
JobPreviousVersion?: IOid;
66
}
67
68
export interface ISyndicateJob {
69
jobType?: string;
70
rewards: string;
71
masteryReq?: number;
72
minEnemyLevel: number;
73
maxEnemyLevel: number;
74
xpAmounts: number[];
75
endless?: boolean;
76
locationTag?: string;
77
isVault?: boolean;
78
requiredItems?: string[];
79
useRequiredItemsAsMiscItemFee?: boolean;
53
80
}
54
81
55
82
export interface ISyndicateMissionInfo {
@@ -59,17 +86,7 @@ export interface ISyndicateMissionInfo {
59
86
Tag: string;
60
87
Seed: number;
61
88
Nodes: string[];
62
Jobs?: {
63
jobType?: string;
64
rewards: string;
65
masteryReq: number;
66
minEnemyLevel: number;
67
maxEnemyLevel: number;
68
xpAmounts: number[];
69
endless?: boolean;
70
locationTag?: string;
71
isVault?: boolean;
72
}[];
89
Jobs?: ISyndicateJob[];
73
90
}
74
91
75
92
export interface IGlobalUpgrade {
@@ -946,6 +946,22 @@
946
946
<option value="3" data-loc="worldState_we3"></option>
947
947
</select>
948
948
</div>
949
<div class="form-group mt-2">
950
<label class="form-label" for="worldState.ghoulEmergenceOverride" data-loc="worldState_ghoulEmergence"></label>
951
<select class="form-control" id="worldState.ghoulEmergenceOverride" data-default="null">
952
<option value="null" data-loc="normal"></option>
953
<option value="true" data-loc="enabled"></option>
954
<option value="false" data-loc="disabled"></option>
955
</select>
956
</div>
957
<div class="form-group mt-2">
958
<label class="form-label" for="worldState.plagueStarOverride" data-loc="worldState_plagueStar"></label>
959
<select class="form-control" id="worldState.plagueStarOverride" data-default="null">
960
<option value="null" data-loc="normal"></option>
961
<option value="true" data-loc="enabled"></option>
962
<option value="false" data-loc="disabled"></option>
963
</select>
964
</div>
949
965
<div class="form-group mt-2">
950
966
<label class="form-label" for="worldState.starDaysOverride" data-loc="worldState_starDays"></label>
951
967
<select class="form-control" id="worldState.starDaysOverride" data-default="null">
@@ -246,6 +246,8 @@ dict = {
246
246
worldState_baroTennoConRelay: `Baros TennoCon Relais`,
247
247
worldState_starDays: `Sternen-Tage`,
248
248
worldState_galleonOfGhouls: `Galeone der Ghule`,
249
worldState_ghoulEmergence: `Ghul Ausrottung`,
250
worldState_plagueStar: `Plagenstern`,
249
251
enabled: `Aktiviert`,
250
252
disabled: `Deaktiviert`,
251
253
worldState_we1: `Wochenende 1`,
@@ -245,6 +245,8 @@ dict = {
245
245
worldState_baroTennoConRelay: `Baro's TennoCon Relay`,
246
246
worldState_starDays: `Star Days`,
247
247
worldState_galleonOfGhouls: `Galleon of Ghouls`,
248
worldState_ghoulEmergence: `Ghoul Purge`,
249
worldState_plagueStar: `Plague Star`,
248
250
enabled: `Enabled`,
249
251
disabled: `Disabled`,
250
252
worldState_we1: `Weekend 1`,
@@ -246,6 +246,8 @@ dict = {
246
246
worldState_baroTennoConRelay: `Repetidor de Baro de la TennoCon`,
247
247
worldState_starDays: `Días estelares`,
248
248
worldState_galleonOfGhouls: `Galeón de Gules`,
249
worldState_ghoulEmergence: `Purga de Gules`,
250
worldState_plagueStar: `Estrella Infestada`,
249
251
enabled: `Activado`,
250
252
disabled: `Desactivado`,
251
253
worldState_we1: `Semana 1`,
@@ -246,6 +246,8 @@ dict = {
246
246
worldState_baroTennoConRelay: `[UNTRANSLATED] Baro's TennoCon Relay`,
247
247
worldState_starDays: `Jours Stellaires`,
248
248
worldState_galleonOfGhouls: `Galion des Goules`,
249
worldState_ghoulEmergence: `Purge des Goules`,
250
worldState_plagueStar: `Fléau Céleste`,
249
251
enabled: `[UNTRANSLATED] Enabled`,
250
252
disabled: `Désactivé`,
251
253
worldState_we1: `Weekend 1`,
@@ -246,6 +246,8 @@ dict = {
246
246
worldState_baroTennoConRelay: `Реле Баро TennoCon`,
247
247
worldState_starDays: `Звёздные дни`,
248
248
worldState_galleonOfGhouls: `Галеон Гулей`,
249
worldState_ghoulEmergence: `Избавление от гулей`,
250
worldState_plagueStar: `Чумная звезда`,
249
251
enabled: `Включено`,
250
252
disabled: `Отключено`,
251
253
worldState_we1: `Выходные 1`,
@@ -246,6 +246,8 @@ dict = {
246
246
worldState_baroTennoConRelay: `Реле Баро TennoCon`,
247
247
worldState_starDays: `Зоряні дні`,
248
248
worldState_galleonOfGhouls: `Гульський Галеон`,
249
worldState_ghoulEmergence: `Зачищення від гулів`,
250
worldState_plagueStar: `Морова зірка`,
249
251
enabled: `Увімкнено`,
250
252
disabled: `Вимкнено`,
251
253
worldState_we1: `Вихідні 1`,