返回提交历史
Modified
src/services/missionInventoryUpdateService.ts
+209
-264
XFEstudio/XFESpaceNinjaServer
chore: simplify bounty reward logic (#3230)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3230 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>
1c70ea89
代码差异
1 个文件
+209
-264
@@ -84,7 +84,7 @@ import {
84
84
} from "./worldStateService.ts";
85
85
import { config } from "./configService.ts";
86
86
import libraryDailyTasks from "../../static/fixed_responses/libraryDailyTasks.json" with { type: "json" };
87
import type { IGoal, ISyndicateMissionInfo } from "../types/worldStateTypes.ts";
87
import type { IGoal, ISyndicateJob, ISyndicateMissionInfo } from "../types/worldStateTypes.ts";
88
88
import { fromOid, version_compare } from "../helpers/inventoryHelpers.ts";
89
89
import type { TAccountDocument } from "./loginService.ts";
90
90
import type { ITypeCount } from "../types/commonTypes.ts";
@@ -1488,99 +1488,18 @@ export const addMissionRewards = async (
1488
1488
}
1489
1489
1490
1490
if (rewardInfo.JobStage != undefined && rewardInfo.jobId) {
1491
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1492
const [jobType, unkIndex, hubNode, syndicateMissionId] = rewardInfo.jobId.split("_");
1493
const syndicateMissions: ISyndicateMissionInfo[] = [];
1494
if (syndicateMissionId) {
1495
pushClassicBounties(syndicateMissions, idToBountyCycle(syndicateMissionId), account.BuildLabel);
1496
}
1497
let syndicateEntry: ISyndicateMissionInfo | IGoal | undefined = syndicateMissions.find(
1498
m => m._id.$oid === syndicateMissionId
1499
);
1500
if (
1501
[
1502
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1503
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1504
].some(prefix => jobType.startsWith(prefix))
1505
) {
1506
const { Goals } = getWorldState(account.BuildLabel);
1507
syndicateEntry = Goals.find(m => m._id.$oid === syndicateMissionId);
1508
if (syndicateEntry) syndicateEntry.Tag = syndicateEntry.JobAffiliationTag!;
1509
}
1510
const specialCase = [
1511
{
1512
endings: ["Heists/HeistProfitTakerBountyOne"],
1513
stage: 2,
1514
amount: 1000,
1515
tag: "SolarisSyndicate"
1516
},
1517
{
1518
endings: [
1519
"Heists/HeistProfitTakerBountyTwo",
1520
"Heists/HeistProfitTakerBountyThree",
1521
"Heists/HeistProfitTakerBountyFour",
1522
"Heists/HeistExploiterBountyOne"
1523
],
1524
amount: 1000,
1525
tag: "SolarisSyndicate"
1526
},
1527
{ endings: ["Hunts/AllTeralystsHunt"], stage: 2, amount: 5000, tag: "CetusSyndicate" },
1528
{
1529
endings: ["Hunts/TeralystHunt"],
1530
amount: 1000,
1531
tag: "CetusSyndicate"
1532
},
1533
{ endings: ["Jobs/NewbieJob"], amount: 200, tag: "CetusSyndicate" }
1534
];
1535
const match = specialCase.find(rule => rule.endings.some(e => jobType.endsWith(e)));
1536
if (match) {
1537
const specialCaseReward = match.stage === undefined || rewardInfo.JobStage === match.stage ? match : null;
1538
if (specialCaseReward) {
1539
addStanding(inventory, match.tag, Math.floor(match.amount / (rewardInfo.Q ? 0.8 : 1)), AffiliationMods);
1540
}
1541
} else if (syndicateEntry && syndicateEntry.Jobs) {
1542
let currentJob = syndicateEntry.Jobs[rewardInfo.JobTier!];
1543
if (
1544
[
1545
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
1546
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
1547
].some(prefix => jobType.startsWith(prefix))
1548
) {
1549
currentJob = syndicateEntry.Jobs.find(j => j.jobType === jobType)!;
1550
}
1551
if (syndicateEntry.Tag === "EntratiSyndicate") {
1552
if (
1553
[
1554
"DeimosRuinsExterminateBounty",
1555
"DeimosRuinsEscortBounty",
1556
"DeimosRuinsMistBounty",
1557
"DeimosRuinsPurifyBounty",
1558
"DeimosRuinsSacBounty",
1559
"VaultBounty"
1560
].some(ending => jobType.endsWith(ending))
1561
) {
1562
const vault = syndicateEntry.Jobs.find(j => j.locationTag == rewardInfo.jobId!.split("_").at(-1));
1563
if (vault) {
1564
currentJob = vault;
1565
if (jobType.endsWith("VaultBounty")) {
1566
currentJob.xpAmounts[rewardInfo.JobTier!] = currentJob.xpAmounts.reduce((s, a) => s + a, 0);
1567
}
1568
}
1569
}
1491
const result = getSyndicateJob(rewardInfo, account.BuildLabel);
1492
if (result) {
1493
const currentJob = result.currentJob;
1494
const syndicateTag = result.syndicateTag;
1495
if (syndicateTag === "EntratiSyndicate") {
1570
1496
let medallionAmount = Math.floor(currentJob.xpAmounts[rewardInfo.JobStage] / (rewardInfo.Q ? 0.8 : 1));
1571
if (
1572
["DeimosEndlessAreaDefenseBounty", "DeimosEndlessExcavateBounty", "DeimosEndlessPurifyBounty"].some(
1573
ending => jobType.endsWith(ending)
1574
)
1575
) {
1576
const endlessJob = syndicateEntry.Jobs.find(j => j.endless);
1577
if (endlessJob) {
1578
const index = rewardInfo.JobStage % endlessJob.xpAmounts.length;
1579
const excess = Math.floor(rewardInfo.JobStage / (endlessJob.xpAmounts.length - 1));
1580
medallionAmount = Math.floor(endlessJob.xpAmounts[index] * (1 + 0.15000001 * excess));
1581
}
1497
if (currentJob.endless) {
1498
const index = rewardInfo.JobStage % currentJob.xpAmounts.length;
1499
const excess = Math.floor(rewardInfo.JobStage / (currentJob.xpAmounts.length - 1));
1500
medallionAmount = Math.floor(currentJob.xpAmounts[index] * (1 + 0.15000001 * excess));
1582
1501
}
1583
if (typeof medallionAmount === "number" && !isNaN(medallionAmount)) {
1502
if (!isNaN(medallionAmount)) {
1584
1503
MissionRewards.push({
1585
1504
StoreItem: "/Lotus/StoreItems/Types/Items/Deimos/EntratiFragmentUncommonB",
1586
1505
ItemCount: medallionAmount
@@ -1591,17 +1510,19 @@ export const addMissionRewards = async (
1591
1510
);
1592
1511
} else {
1593
1512
logger.warning(
1594
`${jobType} tried to give ${medallionAmount} medallions for the ${rewardInfo.JobStage} stage of the ${rewardInfo.JobTier} tier bounty`
1513
`${currentJob.jobType} tried to give ${medallionAmount} medallions for the ${rewardInfo.JobStage} stage of the ${rewardInfo.JobTier} tier bounty`
1595
1514
);
1596
1515
logger.warning(`currentJob`, { currentJob: currentJob });
1597
1516
}
1598
} else if (!jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs")) {
1599
addStanding(
1600
inventory,
1601
syndicateEntry.Tag,
1602
Math.floor(currentJob.xpAmounts[rewardInfo.JobStage] / (rewardInfo.Q ? 0.8 : 1)),
1603
AffiliationMods
1604
);
1517
} else if (!currentJob.jobType!.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs")) {
1518
const xpAmount =
1519
rewardInfo.JobStage < currentJob.xpAmounts.length
1520
? currentJob.xpAmounts[rewardInfo.JobStage]
1521
: currentJob.xpAmounts[0];
1522
if (rewardInfo.JobStage >= currentJob.xpAmounts.length) {
1523
logger.debug(`xpAmount for stage ${rewardInfo.JobStage} is out of bounds, fallback to ${xpAmount}`);
1524
}
1525
addStanding(inventory, syndicateTag, Math.floor(xpAmount / (rewardInfo.Q ? 0.8 : 1)), AffiliationMods);
1605
1526
}
1606
1527
}
1607
1528
}
@@ -2047,178 +1968,49 @@ function getRandomMissionDrops(
2047
1968
}
2048
1969
2049
1970
let rotations: number[] = [];
2050
if (RewardInfo.jobId) {
2051
if (RewardInfo.JobStage! >= 0) {
2052
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2053
const [jobType, unkIndex, hubNode, syndicateMissionId] = RewardInfo.jobId.split("_");
2054
let isEndlessJob = false;
2055
if (syndicateMissionId) {
2056
const syndicateMissions: ISyndicateMissionInfo[] = [];
2057
if (syndicateMissionId) {
2058
pushClassicBounties(syndicateMissions, idToBountyCycle(syndicateMissionId), account.BuildLabel);
2059
}
2060
let syndicateEntry: ISyndicateMissionInfo | IGoal | undefined = syndicateMissions.find(
2061
m => m._id.$oid === syndicateMissionId
2062
);
2063
if (
2064
[
2065
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
2066
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
2067
].some(prefix => jobType.startsWith(prefix))
2068
) {
2069
const { Goals } = getWorldState(account.BuildLabel);
2070
syndicateEntry = Goals.find(m => m._id.$oid === syndicateMissionId);
2071
if (syndicateEntry) syndicateEntry.Tag = syndicateEntry.JobAffiliationTag!;
1971
if (RewardInfo.jobId && RewardInfo.JobStage! >= 0) {
1972
const result = getSyndicateJob(RewardInfo, account.BuildLabel);
1973
1974
if (result) {
1975
const currentJob = result.currentJob;
1976
const jobType = currentJob.jobType!;
1977
if (currentJob.rewards != "") rewardManifests = [currentJob.rewards];
1978
if (currentJob.xpAmounts.length > 1) {
1979
const curentStage = RewardInfo.JobStage! + 1;
1980
const totalStage = currentJob.xpAmounts.length;
1981
let tableIndex = 1; // Stage 2, Stage 3 of 4, and Stage 3 of 5
1982
1983
if (curentStage == 1) {
1984
tableIndex = 0;
1985
} else if (curentStage == totalStage) {
1986
tableIndex = 3;
1987
} else if (totalStage == 5 && curentStage == 4) {
1988
tableIndex = 2;
2072
1989
}
2073
if (syndicateEntry && syndicateEntry.Jobs) {
2074
let job;
2075
if (RewardInfo.JobTier !== undefined && RewardInfo.JobTier >= 0) {
2076
job = syndicateEntry.Jobs[RewardInfo.JobTier];
2077
}
2078
2079
if (syndicateEntry.Tag === "EntratiSyndicate") {
2080
if (
2081
[
2082
"DeimosRuinsExterminateBounty",
2083
"DeimosRuinsEscortBounty",
2084
"DeimosRuinsMistBounty",
2085
"DeimosRuinsPurifyBounty",
2086
"DeimosRuinsSacBounty",
2087
"VaultBounty"
2088
].some(ending => jobType.endsWith(ending))
2089
) {
2090
const vault = syndicateEntry.Jobs.find(
2091
j => j.locationTag === RewardInfo.jobId!.split("_").at(-1)
2092
);
2093
if (vault) {
2094
job = vault;
2095
if (jobType.endsWith("VaultBounty")) {
2096
job.rewards = job.rewards.replace(
2097
"/Lotus/Types/Game/MissionDecks/",
2098
"/Supplementals/"
2099
);
2100
job.xpAmounts = [job.xpAmounts.reduce((partialSum, a) => partialSum + a, 0)];
2101
}
2102
}
2103
}
2104
if (
2105
[
2106
"DeimosEndlessAreaDefenseBounty",
2107
"DeimosEndlessExcavateBounty",
2108
"DeimosEndlessPurifyBounty"
2109
].some(ending => jobType.endsWith(ending))
2110
) {
2111
const endlessJob = syndicateEntry.Jobs.find(j => j.endless);
2112
if (endlessJob) {
2113
isEndlessJob = true;
2114
job = endlessJob;
2115
const excess = Math.floor(RewardInfo.JobStage! / (job.xpAmounts.length - 1));
2116
2117
const rotationIndexes = [0, 0, 1, 2];
2118
const rotationIndex = rotationIndexes[excess % rotationIndexes.length];
2119
const dropTable = [
2120
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableARewards",
2121
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableBRewards",
2122
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableCRewards"
2123
];
2124
job.rewards = dropTable[rotationIndex];
2125
}
2126
}
2127
} else if (syndicateEntry.Tag === "SolarisSyndicate") {
2128
if (jobType.endsWith("Heists/HeistProfitTakerBountyOne") && RewardInfo.JobStage == 2) {
2129
job = {
2130
rewards:
2131
"/Lotus/Types/Game/MissionDecks/HeistJobMissionRewards/HeistTierATableARewards",
2132
masteryReq: 0,
2133
minEnemyLevel: 40,
2134
maxEnemyLevel: 60,
2135
xpAmounts: [1000]
2136
};
2137
RewardInfo.Q = false; // Just in case
2138
} else if (jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob")) {
2139
job = {
2140
rewards: jobType
2141
.replace("SteelPath", "Steel")
2142
.replace(
2143
"/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob",
2144
"/Lotus/Types/Game/MissionDecks/NokkoColonyRewards/NokkoColonyRewards"
2145
),
2146
masteryReq: 0,
2147
minEnemyLevel: 30,
2148
maxEnemyLevel: 40,
2149
xpAmounts: [0, 0, 0, 0, 0]
2150
};
2151
} else {
2152
const tierMap = {
2153
Two: "B",
2154
Three: "C",
2155
Four: "D"
2156
};
2157
1990
2158
for (const [key, tier] of Object.entries(tierMap)) {
2159
if (jobType.endsWith(`Heists/HeistProfitTakerBounty${key}`)) {
2160
job = {
2161
rewards: `/Lotus/Types/Game/MissionDecks/HeistJobMissionRewards/HeistTier${tier}TableARewards`,
2162
masteryReq: 0,
2163
minEnemyLevel: 40,
2164
maxEnemyLevel: 60,
2165
xpAmounts: [1000]
2166
};
2167
RewardInfo.Q = false; // Just in case
2168
break;
2169
}
2170
}
2171
}
2172
}
2173
if (
2174
[
2175
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
2176
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
2177
].some(prefix => jobType.startsWith(prefix))
2178
) {
2179
job = syndicateEntry.Jobs.find(j => j.jobType === jobType)!;
2180
}
2181
if (job) {
2182
rewardManifests = [job.rewards];
2183
if (job.xpAmounts.length > 1) {
2184
const curentStage = RewardInfo.JobStage! + 1;
2185
const totalStage = job.xpAmounts.length;
2186
let tableIndex = 1; // Stage 2, Stage 3 of 4, and Stage 3 of 5
2187
2188
if (curentStage == 1) {
2189
tableIndex = 0;
2190
} else if (curentStage == totalStage) {
2191
tableIndex = 3;
2192
} else if (totalStage == 5 && curentStage == 4) {
2193
tableIndex = 2;
2194
}
2195
if (jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob")) {
2196
if (RewardInfo.JobStage === job.xpAmounts.length - 1) {
2197
rotations = [0, 1, 2];
2198
} else {
2199
rewardManifests = [];
2200
}
2201
} else {
2202
rotations = [tableIndex];
2203
}
2204
} else {
2205
rotations = [0];
2206
}
2207
if (
2208
RewardInfo.Q &&
2209
(RewardInfo.JobStage === job.xpAmounts.length - 1 || jobType.endsWith("VaultBounty")) &&
2210
!jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob") &&
2211
!isEndlessJob
2212
) {
2213
rotations.push(ExportRewards[job.rewards].length - 1);
2214
}
1991
if (jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob")) {
1992
if (RewardInfo.JobStage === currentJob.xpAmounts.length - 1) {
1993
rotations = [0, 1, 2];
1994
} else {
1995
rewardManifests = [];
2215
1996
}
1997
} else {
1998
rotations = [tableIndex];
2216
1999
}
2000
} else {
2001
rotations = [0];
2217
2002
}
2218
2003
if (jobType == "/Lotus/Types/Gameplay/Eidolon/Jobs/NewbieJob") {
2219
rewardManifests = ["/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATableARewards"];
2220
2004
rotations = [3];
2221
2005
if (RewardInfo.Q) rotations.push(3);
2006
} else if (
2007
RewardInfo.Q &&
2008
(RewardInfo.JobStage === currentJob.xpAmounts.length - 1 || jobType.endsWith("VaultBounty")) &&
2009
!jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob") &&
2010
!jobType.startsWith("/Lotus/Types/Gameplay/Venus/Jobs/Heists/") &&
2011
!currentJob.endless
2012
) {
2013
rotations.push(ExportRewards[currentJob.rewards].length - 1);
2222
2014
}
2223
2015
}
2224
2016
} else if (RewardInfo.challengeMissionId) {
@@ -2545,6 +2337,159 @@ export const handleConservation = (
2545
2337
}
2546
2338
};
2547
2339
2340
const getSyndicateJob = (
2341
rewardInfo: IRewardInfo,
2342
buildLabel?: string
2343
): { currentJob: ISyndicateJob; syndicateTag: string } | undefined => {
2344
if (!rewardInfo.jobId) return;
2345
2346
const parts = rewardInfo.jobId.split("_");
2347
const jobType = parts[0];
2348
const syndicateMissionId = parts.find(p => p.length === 24);
2349
let syndicateTag = parts.find(p => p.endsWith("Syndicate"));
2350
2351
const isGoalJob = [
2352
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/InfestedPlainsBounty",
2353
"/Lotus/Types/Gameplay/Eidolon/Jobs/Events/GhoulAlertBounty"
2354
].some(prefix => jobType.startsWith(prefix));
2355
2356
let syndicateEntry: ISyndicateMissionInfo | IGoal | undefined;
2357
if (isGoalJob) {
2358
syndicateEntry = getWorldState(buildLabel).Goals.find(g => g._id.$oid === syndicateMissionId);
2359
if (syndicateEntry) syndicateTag = syndicateEntry.JobAffiliationTag!;
2360
} else if (syndicateMissionId) {
2361
const syndicateMissions: ISyndicateMissionInfo[] = [];
2362
pushClassicBounties(syndicateMissions, idToBountyCycle(syndicateMissionId), buildLabel);
2363
syndicateEntry = syndicateMissions.find(m => m._id.$oid == syndicateMissionId);
2364
if (syndicateEntry) syndicateTag = syndicateEntry.Tag;
2365
}
2366
2367
if (jobType.endsWith("Hunts/AllTeralystsHunt") && rewardInfo.JobStage == 2) {
2368
return {
2369
currentJob: {
2370
jobType,
2371
rewards: "",
2372
minEnemyLevel: 20,
2373
maxEnemyLevel: 40,
2374
xpAmounts: [5000]
2375
},
2376
syndicateTag: "CetusSyndicate"
2377
};
2378
} else if (jobType.endsWith("Hunts/TeralystHunt")) {
2379
return {
2380
currentJob: {
2381
jobType,
2382
rewards: "",
2383
minEnemyLevel: 20,
2384
maxEnemyLevel: 40,
2385
xpAmounts: [1000]
2386
},
2387
syndicateTag: "CetusSyndicate"
2388
};
2389
} else if (jobType.endsWith("Jobs/NewbieJob")) {
2390
return {
2391
currentJob: {
2392
jobType,
2393
rewards: "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATableARewards",
2394
minEnemyLevel: 3,
2395
maxEnemyLevel: 5,
2396
xpAmounts: [200]
2397
},
2398
syndicateTag: "CetusSyndicate"
2399
};
2400
}
2401
2402
if (!syndicateTag) return;
2403
2404
if (syndicateTag == "SolarisSyndicate") {
2405
if (jobType.startsWith("/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob")) {
2406
return {
2407
currentJob: {
2408
jobType,
2409
rewards: jobType
2410
.replace("SteelPath", "Steel")
2411
.replace(
2412
"/Lotus/Types/Gameplay/NokkoColony/Jobs/NokkoJob",
2413
"/Lotus/Types/Game/MissionDecks/NokkoColonyRewards/NokkoColonyRewards"
2414
),
2415
masteryReq: 0,
2416
minEnemyLevel: 30,
2417
maxEnemyLevel: 40,
2418
xpAmounts: [0, 0, 0, 0, 0]
2419
},
2420
syndicateTag
2421
};
2422
} else if (jobType == "/Lotus/Types/Gameplay/Venus/Jobs/Heists/ExploiterHunt") {
2423
return {
2424
currentJob: {
2425
jobType,
2426
rewards: "",
2427
masteryReq: 0,
2428
minEnemyLevel: 40,
2429
maxEnemyLevel: 60,
2430
xpAmounts: [1000]
2431
},
2432
syndicateTag
2433
};
2434
}
2435
2436
const tierMap: Record<string, string> = { One: "A", Two: "B", Three: "C", Four: "D" };
2437
for (const [key, tier] of Object.entries(tierMap)) {
2438
if (key == "One" && rewardInfo.JobStage != 2) continue;
2439
if (!jobType.endsWith(`Heists/HeistProfitTakerBounty${key}`)) continue;
2440
2441
return {
2442
currentJob: {
2443
jobType,
2444
rewards: `/Lotus/Types/Game/MissionDecks/HeistJobMissionRewards/HeistTier${tier}TableARewards`,
2445
masteryReq: 0,
2446
minEnemyLevel: 40,
2447
maxEnemyLevel: 60,
2448
xpAmounts: [1000]
2449
},
2450
syndicateTag
2451
};
2452
}
2453
}
2454
2455
if (!syndicateEntry?.Jobs) return;
2456
2457
let currentJob: ISyndicateJob | undefined =
2458
rewardInfo.JobTier !== undefined && !isGoalJob
2459
? syndicateEntry.Jobs[rewardInfo.JobTier]
2460
: syndicateEntry.Jobs.find(j => j.jobType == jobType);
2461
2462
if (syndicateTag == "EntratiSyndicate") {
2463
if (jobType.includes("DeimosEndless")) {
2464
const endlessJob = syndicateEntry.Jobs.find(j => j.endless);
2465
if (endlessJob) {
2466
currentJob = endlessJob;
2467
const excess = Math.floor(rewardInfo.JobStage! / (currentJob.xpAmounts.length - 1));
2468
const rotationIndex = [0, 0, 1, 2][excess % 4];
2469
const dropTable = [
2470
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableARewards",
2471
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableBRewards",
2472
"/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableCRewards"
2473
];
2474
currentJob.rewards = dropTable[rotationIndex];
2475
}
2476
} else if (jobType.endsWith("VaultBounty")) {
2477
const chamberTag = [...parts].reverse().find(p => p.startsWith("Chamber"));
2478
const vault = syndicateEntry.Jobs.find(j => j.locationTag == chamberTag);
2479
if (vault) {
2480
currentJob = vault;
2481
currentJob.jobType = jobType;
2482
currentJob.rewards = currentJob.rewards.replace("/Lotus/Types/Game/MissionDecks/", "/Supplementals/");
2483
currentJob.xpAmounts = [currentJob.xpAmounts.reduce((sum, a) => sum + a, 0)];
2484
}
2485
}
2486
}
2487
2488
if (!currentJob) return;
2489
2490
return { currentJob, syndicateTag };
2491
};
2492
2548
2493
const corruptedMods = [
2549
2494
"/Lotus/StoreItems/Upgrades/Mods/Melee/DualStat/CorruptedHeavyDamageChargeSpeedMod", // Corrupt Charge
2550
2495
"/Lotus/StoreItems/Upgrades/Mods/Pistol/DualStat/CorruptedCritDamagePistol", // Hollow Point