返回提交历史
Modified
src/services/worldStateService.ts
+42
-18
XFEstudio/XFESpaceNinjaServer
feat: randomise classic bounty xpAmounts (#2150)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2150 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
71d1b609
代码差异
1 个文件
+42
-18
@@ -453,13 +453,37 @@ const pushWeeklyActs = (
453
453
}
454
454
};
455
455
456
const generateXpAmounts = (rng: SRng, stageCount: number, minXp: number, maxXp: number): number[] => {
457
const step = minXp < 1000 ? 1 : 10;
458
const totalDeciXp = rng.randomInt(minXp / step, maxXp / step);
459
const xpAmounts: number[] = [];
460
if (stageCount < 4) {
461
const perStage = Math.ceil(totalDeciXp / stageCount) * step;
462
for (let i = 0; i != stageCount; ++i) {
463
xpAmounts.push(perStage);
464
}
465
} else {
466
const perStage = Math.ceil(Math.round(totalDeciXp * 0.667) / (stageCount - 1)) * step;
467
for (let i = 0; i != stageCount - 1; ++i) {
468
xpAmounts.push(perStage);
469
}
470
xpAmounts.push(Math.ceil(totalDeciXp * 0.332) * step);
471
}
472
return xpAmounts;
473
};
474
// Test vectors:
475
//console.log(generateXpAmounts(new SRng(1337n), 5, 5000, 5000)); // [840, 840, 840, 840, 1660]
476
//console.log(generateXpAmounts(new SRng(1337n), 3, 40, 40)); // [14, 14, 14]
477
//console.log(generateXpAmounts(new SRng(1337n), 5, 150, 150)); // [25, 25, 25, 25, 50]
478
//console.log(generateXpAmounts(new SRng(1337n), 4, 10, 10)); // [2, 2, 2, 4]
479
//console.log(generateXpAmounts(new SRng(1337n), 4, 15, 15)); // [4, 4, 4, 5]
480
//console.log(generateXpAmounts(new SRng(1337n), 4, 20, 20)); // [5, 5, 5, 7]
481
456
482
export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[], bountyCycle: number): void => {
457
483
const table = String.fromCharCode(65 + (bountyCycle % 3));
458
484
const vaultTable = String.fromCharCode(65 + ((bountyCycle + 1) % 3));
459
485
const deimosDTable = String.fromCharCode(65 + (bountyCycle % 2));
460
486
461
// TODO: xpAmounts need to be calculated based on the jobType somehow?
462
463
487
const seed = new SRng(bountyCycle).randomInt(0, 100_000);
464
488
const bountyCycleStart = bountyCycle * 9000000;
465
489
const bountyCycleEnd = bountyCycleStart + 9000000;
@@ -482,7 +506,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
482
506
masteryReq: 0,
483
507
minEnemyLevel: 5,
484
508
maxEnemyLevel: 15,
485
xpAmounts: [430, 430, 430]
509
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
486
510
},
487
511
{
488
512
jobType: rng.randomElement(eidolonJobs),
@@ -490,7 +514,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
490
514
masteryReq: 1,
491
515
minEnemyLevel: 10,
492
516
maxEnemyLevel: 30,
493
xpAmounts: [620, 620, 620]
517
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
494
518
},
495
519
{
496
520
jobType: rng.randomElement(eidolonJobs),
@@ -498,7 +522,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
498
522
masteryReq: 2,
499
523
minEnemyLevel: 20,
500
524
maxEnemyLevel: 40,
501
xpAmounts: [670, 670, 670, 990]
525
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
502
526
},
503
527
{
504
528
jobType: rng.randomElement(eidolonJobs),
@@ -506,7 +530,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
506
530
masteryReq: 3,
507
531
minEnemyLevel: 30,
508
532
maxEnemyLevel: 50,
509
xpAmounts: [570, 570, 570, 570, 1110]
533
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
510
534
},
511
535
{
512
536
jobType: rng.randomElement(eidolonJobs),
@@ -514,7 +538,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
514
538
masteryReq: 5,
515
539
minEnemyLevel: 40,
516
540
maxEnemyLevel: 60,
517
xpAmounts: [740, 740, 740, 740, 1450]
541
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
518
542
},
519
543
{
520
544
jobType: rng.randomElement(eidolonJobs),
@@ -530,7 +554,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
530
554
masteryReq: 0,
531
555
minEnemyLevel: 50,
532
556
maxEnemyLevel: 70,
533
xpAmounts: [840, 840, 840, 840, 1650]
557
xpAmounts: generateXpAmounts(rng, 5, 4500, 5000)
534
558
}
535
559
]
536
560
});
@@ -554,7 +578,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
554
578
masteryReq: 0,
555
579
minEnemyLevel: 5,
556
580
maxEnemyLevel: 15,
557
xpAmounts: [340, 340, 340]
581
xpAmounts: generateXpAmounts(rng, 3, 1000, 1500)
558
582
},
559
583
{
560
584
jobType: rng.randomElement(venusJobs),
@@ -562,7 +586,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
562
586
masteryReq: 1,
563
587
minEnemyLevel: 10,
564
588
maxEnemyLevel: 30,
565
xpAmounts: [660, 660, 660]
589
xpAmounts: generateXpAmounts(rng, 3, 1750, 2250)
566
590
},
567
591
{
568
592
jobType: rng.randomElement(venusJobs),
@@ -570,7 +594,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
570
594
masteryReq: 2,
571
595
minEnemyLevel: 20,
572
596
maxEnemyLevel: 40,
573
xpAmounts: [610, 610, 610, 900]
597
xpAmounts: generateXpAmounts(rng, 4, 2500, 3000)
574
598
},
575
599
{
576
600
jobType: rng.randomElement(venusJobs),
@@ -578,7 +602,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
578
602
masteryReq: 3,
579
603
minEnemyLevel: 30,
580
604
maxEnemyLevel: 50,
581
xpAmounts: [600, 600, 600, 600, 1170]
605
xpAmounts: generateXpAmounts(rng, 5, 3250, 3750)
582
606
},
583
607
{
584
608
jobType: rng.randomElement(venusJobs),
@@ -586,7 +610,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
586
610
masteryReq: 5,
587
611
minEnemyLevel: 40,
588
612
maxEnemyLevel: 60,
589
xpAmounts: [690, 690, 690, 690, 1350]
613
xpAmounts: generateXpAmounts(rng, 5, 4000, 4500)
590
614
},
591
615
{
592
616
jobType: rng.randomElement(venusJobs),
@@ -602,7 +626,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
602
626
masteryReq: 0,
603
627
minEnemyLevel: 50,
604
628
maxEnemyLevel: 70,
605
xpAmounts: [780, 780, 780, 780, 1540]
629
xpAmounts: generateXpAmounts(rng, 5, 4500, 5000)
606
630
}
607
631
]
608
632
});
@@ -626,7 +650,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
626
650
masteryReq: 0,
627
651
minEnemyLevel: 5,
628
652
maxEnemyLevel: 15,
629
xpAmounts: [5, 5, 5]
653
xpAmounts: generateXpAmounts(rng, 3, 12, 18)
630
654
},
631
655
{
632
656
jobType: rng.randomElement(microplanetJobs),
@@ -634,7 +658,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
634
658
masteryReq: 1,
635
659
minEnemyLevel: 15,
636
660
maxEnemyLevel: 25,
637
xpAmounts: [12, 12, 12]
661
xpAmounts: generateXpAmounts(rng, 3, 24, 36)
638
662
},
639
663
{
640
664
jobType: rng.randomElement(microplanetEndlessJobs),
@@ -651,7 +675,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
651
675
masteryReq: 2,
652
676
minEnemyLevel: 30,
653
677
maxEnemyLevel: 40,
654
xpAmounts: [17, 17, 17, 25]
678
xpAmounts: generateXpAmounts(rng, 4, 72, 88)
655
679
},
656
680
{
657
681
jobType: rng.randomElement(microplanetJobs),
@@ -659,7 +683,7 @@ export const pushClassicBounties = (syndicateMissions: ISyndicateMissionInfo[],
659
683
masteryReq: 3,
660
684
minEnemyLevel: 40,
661
685
maxEnemyLevel: 60,
662
xpAmounts: [22, 22, 22, 22, 43]
686
xpAmounts: generateXpAmounts(rng, 5, 115, 135)
663
687
},
664
688
{
665
689
jobType: rng.randomElement(microplanetJobs),