返回提交历史
Modified
src/controllers/api/missionInventoryUpdateController.ts
+4
-1
Modified
src/models/inventoryModels/inventoryModel.ts
+11
-1
Modified
src/services/missionInventoryUpdateService.ts
+77
-17
Modified
src/types/inventoryTypes/inventoryTypes.ts
+6
-0
XFEstudio/XFESpaceNinjaServer
feat: archon hunt rewards (#1713)
also added a check for first completion to avoid giving another reward for repeating the final mission Closes #1624 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1713 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
cdead6fd
代码差异
4 个文件
+98
-19
@@ -53,6 +53,9 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res)
53
53
logger.debug("mission report:", missionReport);
54
54
55
55
const inventory = await getInventory(accountId);
56
const firstCompletion = missionReport.SortieId
57
? inventory.CompletedSorties.indexOf(missionReport.SortieId) == -1
58
: false;
56
59
const inventoryUpdates = await addMissionInventoryUpdates(inventory, missionReport);
57
60
58
61
if (
@@ -69,7 +72,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res)
69
72
}
70
73
71
74
const { MissionRewards, inventoryChanges, credits, AffiliationMods, SyndicateXPItemReward } =
72
await addMissionRewards(inventory, missionReport);
75
await addMissionRewards(inventory, missionReport, firstCompletion);
73
76
74
77
await inventory.save();
75
78
const inventoryResponse = await getInventoryResponse(inventory, true);
@@ -91,7 +91,8 @@ import {
91
91
ICrewMemberSkill,
92
92
ICrewMemberSkillEfficiency,
93
93
ICrewMemberDatabase,
94
ICrewMemberClient
94
ICrewMemberClient,
95
ISortieRewardAttenuation
95
96
} from "../../types/inventoryTypes/inventoryTypes";
96
97
import { IOid } from "../../types/commonTypes";
97
98
import {
@@ -1276,6 +1277,14 @@ lastSortieRewardSchema.set("toJSON", {
1276
1277
}
1277
1278
});
1278
1279
1280
const sortieRewardAttenutationSchema = new Schema<ISortieRewardAttenuation>(
1281
{
1282
Tag: String,
1283
Atten: Number
1284
},
1285
{ _id: false }
1286
);
1287
1279
1288
const lockedWeaponGroupSchema = new Schema<ILockedWeaponGroupDatabase>(
1280
1289
{
1281
1290
s: Schema.Types.ObjectId,
@@ -1495,6 +1504,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>(
1495
1504
CompletedSorties: [String],
1496
1505
LastSortieReward: { type: [lastSortieRewardSchema], default: undefined },
1497
1506
LastLiteSortieReward: { type: [lastSortieRewardSchema], default: undefined },
1507
SortieRewardAttenuation: { type: [sortieRewardAttenutationSchema], default: undefined },
1498
1508
1499
1509
// Resource Extractor Drones
1500
1510
Drones: [droneSchema],
@@ -412,7 +412,9 @@ export const addMissionInventoryUpdates = async (
412
412
break;
413
413
}
414
414
case "SortieId": {
415
inventory.CompletedSorties.push(value);
415
if (inventory.CompletedSorties.indexOf(value) == -1) {
416
inventory.CompletedSorties.push(value);
417
}
416
418
break;
417
419
}
418
420
case "SeasonChallengeCompletions": {
@@ -569,7 +571,8 @@ export const addMissionRewards = async (
569
571
RegularCredits: creditDrops,
570
572
VoidTearParticipantsCurrWave: voidTearWave,
571
573
StrippedItems: strippedItems
572
}: IMissionInventoryUpdateRequest
574
}: IMissionInventoryUpdateRequest,
575
firstCompletion: boolean
573
576
): Promise<AddMissionRewardsReturnType> => {
574
577
if (!rewardInfo) {
575
578
//TODO: if there is a case where you can have credits collected during a mission but no rewardInfo, add credits needs to be handled earlier
@@ -583,22 +586,12 @@ export const addMissionRewards = async (
583
586
}
584
587
585
588
//TODO: check double reward merging
586
const MissionRewards: IMissionReward[] = getRandomMissionDrops(rewardInfo, wagerTier);
589
const MissionRewards: IMissionReward[] = getRandomMissionDrops(inventory, rewardInfo, wagerTier, firstCompletion);
587
590
logger.debug("random mission drops:", MissionRewards);
588
591
const inventoryChanges: IInventoryChanges = {};
589
592
const AffiliationMods: IAffiliationMods[] = [];
590
593
let SyndicateXPItemReward;
591
594
592
if (rewardInfo.sortieTag == "Final") {
593
inventory.LastSortieReward = [
594
{
595
SortieId: new Types.ObjectId(rewardInfo.sortieId!.split("_")[1]),
596
StoreItem: MissionRewards[0].StoreItem,
597
Manifest: "/Lotus/Types/Game/MissionDecks/SortieRewards"
598
}
599
];
600
}
601
602
595
let missionCompletionCredits = 0;
603
596
//inventory change is what the client has not rewarded itself, also the client needs to know the credit changes for display
604
597
if (levelKeyName) {
@@ -962,11 +955,78 @@ function getLevelCreditRewards(node: IRegion): number {
962
955
//TODO: get dark sektor fixed credit rewards and railjack bonus
963
956
}
964
957
965
function getRandomMissionDrops(RewardInfo: IRewardInfo, tierOverride: number | undefined): IMissionReward[] {
958
function getRandomMissionDrops(
959
inventory: TInventoryDatabaseDocument,
960
RewardInfo: IRewardInfo,
961
tierOverride: number | undefined,
962
firstCompletion: boolean
963
): IMissionReward[] {
966
964
const drops: IMissionReward[] = [];
967
if (RewardInfo.sortieTag == "Final") {
968
const drop = getRandomRewardByChance(ExportRewards["/Lotus/Types/Game/MissionDecks/SortieRewards"][0])!;
969
drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
965
if (RewardInfo.sortieTag == "Final" && firstCompletion) {
966
const arr = RewardInfo.sortieId!.split("_");
967
let sortieId = arr[1];
968
if (sortieId == "Lite") {
969
sortieId = arr[2];
970
971
// TODO: Some way to get from sortieId to reward to make this faster + more reliable at week rollover.
972
const boss = getWorldState().LiteSorties[0].Boss as
973
| "SORTIE_BOSS_AMAR"
974
| "SORTIE_BOSS_NIRA"
975
| "SORTIE_BOSS_BOREAL";
976
let crystalType = {
977
SORTIE_BOSS_AMAR: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar",
978
SORTIE_BOSS_NIRA: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalNira",
979
SORTIE_BOSS_BOREAL: "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal"
980
}[boss];
981
const attenTag = {
982
SORTIE_BOSS_AMAR: "NarmerSortieAmarCrystalRewards",
983
SORTIE_BOSS_NIRA: "NarmerSortieNiraCrystalRewards",
984
SORTIE_BOSS_BOREAL: "NarmerSortieBorealCrystalRewards"
985
}[boss];
986
const attenIndex = inventory.SortieRewardAttenuation?.findIndex(x => x.Tag == attenTag) ?? -1;
987
const mythicProbability =
988
0.2 + (inventory.SortieRewardAttenuation?.find(x => x.Tag == attenTag)?.Atten ?? 0);
989
if (Math.random() < mythicProbability) {
990
crystalType += "Mythic";
991
if (attenIndex != -1) {
992
inventory.SortieRewardAttenuation!.splice(attenIndex, 1);
993
}
994
} else {
995
if (attenIndex == -1) {
996
inventory.SortieRewardAttenuation ??= [];
997
inventory.SortieRewardAttenuation.push({
998
Tag: attenTag,
999
Atten: 0.2
1000
});
1001
} else {
1002
inventory.SortieRewardAttenuation![attenIndex].Atten += 0.2;
1003
}
1004
}
1005
1006
drops.push({ StoreItem: crystalType, ItemCount: 1 });
1007
1008
const drop = getRandomRewardByChance(
1009
ExportRewards["/Lotus/Types/Game/MissionDecks/ArchonSortieRewards"][0]
1010
)!;
1011
drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
1012
inventory.LastLiteSortieReward = [
1013
{
1014
SortieId: new Types.ObjectId(sortieId),
1015
StoreItem: drop.type,
1016
Manifest: "/Lotus/Types/Game/MissionDecks/ArchonSortieRewards"
1017
}
1018
];
1019
} else {
1020
const drop = getRandomRewardByChance(ExportRewards["/Lotus/Types/Game/MissionDecks/SortieRewards"][0])!;
1021
drops.push({ StoreItem: drop.type, ItemCount: drop.itemCount });
1022
inventory.LastSortieReward = [
1023
{
1024
SortieId: new Types.ObjectId(sortieId),
1025
StoreItem: drop.type,
1026
Manifest: "/Lotus/Types/Game/MissionDecks/SortieRewards"
1027
}
1028
];
1029
}
970
1030
}
971
1031
if (RewardInfo.periodicMissionTag?.startsWith("HardDaily")) {
972
1032
drops.push({
@@ -285,6 +285,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu
285
285
CompletedSorties: string[];
286
286
LastSortieReward?: ILastSortieRewardClient[];
287
287
LastLiteSortieReward?: ILastSortieRewardClient[];
288
SortieRewardAttenuation?: ISortieRewardAttenuation[];
288
289
Drones: IDroneClient[];
289
290
StepSequencers: IStepSequencer[];
290
291
ActiveAvatarImageType: string;
@@ -746,6 +747,11 @@ export interface ILastSortieRewardDatabase extends Omit<ILastSortieRewardClient,
746
747
SortieId: Types.ObjectId;
747
748
}
748
749
750
export interface ISortieRewardAttenuation {
751
Tag: string;
752
Atten: number;
753
}
754
749
755
export interface ILibraryDailyTaskInfo {
750
756
EnemyTypes: string[];
751
757
EnemyLocTag: string;