返回提交历史
Modified
src/services/rngService.ts
+10
-0
Modified
src/services/worldStateService.ts
+26
-23
XFEstudio/SpaceNinjaServer
fix: ensure every bounty tier has a unique job type (#2273)
I saw "trash their traps" show up twice on Eudico in different tiers, I don't think that's correct. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2273 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
d5be2028
代码差异
2 个文件
+36
-23
@@ -107,6 +107,16 @@ export class SRng {
107
107
return arr[this.randomInt(0, arr.length - 1)];
108
108
}
109
109
110
randomElementPop<T>(arr: T[]): T | undefined {
111
if (arr.length != 0) {
112
const index = this.randomInt(0, arr.length - 1);
113
const elm = arr[index];
114
arr.splice(index, 1);
115
return elm;
116
}
117
return undefined;
118
}
119
110
120
randomFloat(): number {
111
121
this.state = (0x5851f42d4c957f2dn * this.state + 0x14057b7ef767814fn) & 0xffffffffffffffffn;
112
122
return (Number(this.state >> 38n) & 0xffffff) * 0.000000059604645;
@@ -101,7 +101,7 @@ const sortieBossNode: Record<Exclude<TSortieBoss, "SORTIE_BOSS_CORRUPTED_VOR">,
101
101
SORTIE_BOSS_VOR: "SolNode108"
102
102
};
103
103
104
const eidolonJobs = [
104
const eidolonJobs: readonly string[] = [
105
105
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
106
106
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
107
107
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountySab",
@@ -117,14 +117,14 @@ const eidolonJobs = [
117
117
"/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc"
118
118
];
119
119
120
const eidolonNarmerJobs = [
120
const eidolonNarmerJobs: readonly string[] = [
121
121
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
122
122
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyExt",
123
123
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/ReclamationBountyTheft",
124
124
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
125
125
];
126
126
127
const venusJobs = [
127
const venusJobs: readonly string[] = [
128
128
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
129
129
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
130
130
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobRecovery",
@@ -150,14 +150,14 @@ const venusJobs = [
150
150
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobSpy"
151
151
];
152
152
153
const venusNarmerJobs = [
153
const venusNarmerJobs: readonly string[] = [
154
154
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobAssassinate",
155
155
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
156
156
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusPreservationJobDefense",
157
157
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusTheftJobExcavation"
158
158
];
159
159
160
const microplanetJobs = [
160
const microplanetJobs: readonly string[] = [
161
161
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
162
162
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
163
163
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosCrpSurvivorBounty",
@@ -167,7 +167,7 @@ const microplanetJobs = [
167
167
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosPurifyBounty"
168
168
];
169
169
170
const microplanetEndlessJobs = [
170
const microplanetEndlessJobs: readonly string[] = [
171
171
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessAreaDefenseBounty",
172
172
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
173
173
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
@@ -498,6 +498,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
498
498
499
499
{
500
500
const rng = new SRng(seed);
501
const pool = [...eidolonJobs];
501
502
syndicateMissions.push({
502
503
_id: {
503
504
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000008"
@@ -509,7 +510,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
509
510
Nodes: [],
510
511
Jobs: [
511
512
{
512
jobType: rng.randomElement(eidolonJobs),
513
jobType: rng.randomElementPop(pool),
513
514
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATable${table}Rewards`,
514
515
masteryReq: 0,
515
516
minEnemyLevel: 5,
@@ -517,7 +518,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
517
518
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
518
519
},
519
520
{
520
jobType: rng.randomElement(eidolonJobs),
521
jobType: rng.randomElementPop(pool),
521
522
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTable${table}Rewards`,
522
523
masteryReq: 1,
523
524
minEnemyLevel: 10,
@@ -525,7 +526,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
525
526
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
526
527
},
527
528
{
528
jobType: rng.randomElement(eidolonJobs),
529
jobType: rng.randomElementPop(pool),
529
530
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTable${table}Rewards`,
530
531
masteryReq: 2,
531
532
minEnemyLevel: 20,
@@ -533,7 +534,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
533
534
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
534
535
},
535
536
{
536
jobType: rng.randomElement(eidolonJobs),
537
jobType: rng.randomElementPop(pool),
537
538
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTable${table}Rewards`,
538
539
masteryReq: 3,
539
540
minEnemyLevel: 30,
@@ -541,7 +542,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
541
542
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
542
543
},
543
544
{
544
jobType: rng.randomElement(eidolonJobs),
545
jobType: rng.randomElementPop(pool),
545
546
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
546
547
masteryReq: 5,
547
548
minEnemyLevel: 40,
@@ -549,7 +550,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
549
550
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
550
551
},
551
552
{
552
jobType: rng.randomElement(eidolonJobs),
553
jobType: rng.randomElementPop(pool),
553
554
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
554
555
masteryReq: 10,
555
556
minEnemyLevel: 100,
@@ -570,6 +571,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
570
571
571
572
{
572
573
const rng = new SRng(seed);
574
const pool = [...venusJobs];
573
575
syndicateMissions.push({
574
576
_id: {
575
577
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000025"
@@ -581,7 +583,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
581
583
Nodes: [],
582
584
Jobs: [
583
585
{
584
jobType: rng.randomElement(venusJobs),
586
jobType: rng.randomElementPop(pool),
585
587
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATable${table}Rewards`,
586
588
masteryReq: 0,
587
589
minEnemyLevel: 5,
@@ -589,7 +591,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
589
591
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
590
592
},
591
593
{
592
jobType: rng.randomElement(venusJobs),
594
jobType: rng.randomElementPop(pool),
593
595
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTable${table}Rewards`,
594
596
masteryReq: 1,
595
597
minEnemyLevel: 10,
@@ -597,7 +599,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
597
599
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
598
600
},
599
601
{
600
jobType: rng.randomElement(venusJobs),
602
jobType: rng.randomElementPop(pool),
601
603
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTable${table}Rewards`,
602
604
masteryReq: 2,
603
605
minEnemyLevel: 20,
@@ -605,7 +607,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
605
607
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
606
608
},
607
609
{
608
jobType: rng.randomElement(venusJobs),
610
jobType: rng.randomElementPop(pool),
609
611
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTable${table}Rewards`,
610
612
masteryReq: 3,
611
613
minEnemyLevel: 30,
@@ -613,7 +615,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
613
615
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
614
616
},
615
617
{
616
jobType: rng.randomElement(venusJobs),
618
jobType: rng.randomElementPop(pool),
617
619
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
618
620
masteryReq: 5,
619
621
minEnemyLevel: 40,
@@ -621,7 +623,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
621
623
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
622
624
},
623
625
{
624
jobType: rng.randomElement(venusJobs),
626
jobType: rng.randomElementPop(pool),
625
627
rewards: `/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
626
628
masteryReq: 10,
627
629
minEnemyLevel: 100,
@@ -642,6 +644,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
642
644
643
645
{
644
646
const rng = new SRng(seed);
647
const pool = [...microplanetJobs];
645
648
syndicateMissions.push({
646
649
_id: {
647
650
$oid: ((bountyCycleStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "0000000000000002"
@@ -653,7 +656,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
653
656
Nodes: [],
654
657
Jobs: [
655
658
{
656
jobType: rng.randomElement(microplanetJobs),
659
jobType: rng.randomElementPop(pool),
657
660
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATable${table}Rewards`,
658
661
masteryReq: 0,
659
662
minEnemyLevel: 5,
@@ -661,7 +664,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
661
664
xpAmounts: generateXpAmounts(rng, 3, 12, 18)
662
665
},
663
666
{
664
jobType: rng.randomElement(microplanetJobs),
667
jobType: rng.randomElementPop(pool),
665
668
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTable${table}Rewards`,
666
669
masteryReq: 1,
667
670
minEnemyLevel: 15,
@@ -678,7 +681,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
678
681
xpAmounts: [14, 14, 14]
679
682
},
680
683
{
681
jobType: rng.randomElement(microplanetJobs),
684
jobType: rng.randomElementPop(pool),
682
685
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTable${deimosDTable}Rewards`,
683
686
masteryReq: 2,
684
687
minEnemyLevel: 30,
@@ -686,7 +689,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
686
689
xpAmounts: generateXpAmounts(rng, 4, 72, 88)
687
690
},
688
691
{
689
jobType: rng.randomElement(microplanetJobs),
692
jobType: rng.randomElementPop(pool),
690
693
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
691
694
masteryReq: 3,
692
695
minEnemyLevel: 40,
@@ -694,7 +697,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
694
697
xpAmounts: generateXpAmounts(rng, 5, 115, 135)
695
698
},
696
699
{
697
jobType: rng.randomElement(microplanetJobs),
700
jobType: rng.randomElementPop(pool),
698
701
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
699
702
masteryReq: 10,
700
703
minEnemyLevel: 100,