返回提交历史
Modified
src/controllers/api/infestedFoundryController.ts
+74
-11
Modified
src/controllers/api/upgradesController.ts
+13
-2
Modified
src/services/inventoryService.ts
+2
-1
Modified
src/types/purchaseTypes.ts
+6
-2
XFEstudio/XFESpaceNinjaServer
feat: all server-side metamorphosis levels (#716)
06bc0123
代码差异
4 个文件
+95
-16
@@ -71,14 +71,14 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
71
71
const snack = ExportMisc.helminthSnacks[contribution.ItemType];
72
72
73
73
// Note: Currently ignoring loss of apetite
74
totalPercentagePointsGained += snack.gain / 0.01;
74
totalPercentagePointsGained += snack.gain * 100; // 30% would be gain=0.3, so percentage points is equal to gain * 100.
75
75
const resource = inventory.InfestedFoundry.Resources.find(x => x.ItemType == snack.type);
76
76
if (resource) {
77
77
resource.Count += Math.trunc(snack.gain * 1000);
78
78
} else {
79
79
inventory.InfestedFoundry.Resources.push({
80
80
ItemType: snack.type,
81
Count: Math.trunc(snack.gain * 1000)
81
Count: Math.trunc(snack.gain * 1000) // 30% would be gain=0.3 or Count=300, so Count=gain*1000.
82
82
});
83
83
}
84
84
@@ -91,19 +91,21 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
91
91
}
92
92
}
93
93
94
addInfestedFoundryXP(inventory.InfestedFoundry, 666 * totalPercentagePointsGained);
94
const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry, 666 * totalPercentagePointsGained);
95
addRecipes(inventory, recipeChanges);
95
96
addMiscItems(inventory, miscItemChanges);
96
97
await inventory.save();
97
98
98
99
res.json({
99
100
InventoryChanges: {
101
Recipes: recipeChanges,
100
102
InfestedFoundry: {
101
103
XP: inventory.InfestedFoundry.XP,
102
104
Resources: inventory.InfestedFoundry.Resources,
103
105
Slots: inventory.InfestedFoundry.Slots
104
}
105
},
106
MiscItems: miscItemChanges
106
},
107
MiscItems: miscItemChanges
108
}
107
109
});
108
110
break;
109
111
}
@@ -144,18 +146,21 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
144
146
if (suit.Configs && suit.Configs[0] && suit.Configs[0].pricol) {
145
147
consumedSuit.c = suit.Configs[0].pricol;
146
148
}
147
inventory.InfestedFoundry!.Slots!--;
149
if ((inventory.InfestedFoundry!.XP ?? 0) < 73125_00) {
150
inventory.InfestedFoundry!.Slots!--;
151
}
148
152
inventory.InfestedFoundry!.ConsumedSuits ??= [];
149
153
inventory.InfestedFoundry!.ConsumedSuits?.push(consumedSuit);
150
154
inventory.InfestedFoundry!.LastConsumedSuit = suit;
151
155
inventory.InfestedFoundry!.AbilityOverrideUnlockCooldown = new Date(
152
156
new Date().getTime() + 24 * 60 * 60 * 1000
153
157
);
154
addInfestedFoundryXP(inventory.InfestedFoundry!, 1600_00);
158
const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry!, 1600_00);
159
addRecipes(inventory, recipeChanges);
155
160
await inventory.save();
156
console.log(inventory.toJSON().InfestedFoundry);
157
161
res.json({
158
162
InventoryChanges: {
163
Recipes: recipeChanges,
159
164
RemovedIdItems: [
160
165
{
161
166
ItemId: request.SuitId
@@ -196,7 +201,8 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
196
201
suit.OffensiveUpgrade = request.OffensiveUpgradeType;
197
202
suit.DefensiveUpgrade = request.DefensiveUpgradeType;
198
203
suit.UpgradesExpiry = upgradesExpiry;
199
addInfestedFoundryXP(inventory.InfestedFoundry!, 4800_00);
204
const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry!, 4800_00);
205
addRecipes(inventory, recipeChanges);
200
206
for (let i = 0; i != request.ResourceTypes.length; ++i) {
201
207
inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == request.ResourceTypes[i])!.Count -=
202
208
request.ResourceCosts[i];
@@ -210,6 +216,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
210
216
DefensiveUpgrade: request.DefensiveUpgradeType,
211
217
UpgradesExpiry: toMongoDate(upgradesExpiry),
212
218
InventoryChanges: {
219
Recipes: recipeChanges,
213
220
InfestedFoundry: inventory.toJSON().InfestedFoundry
214
221
}
215
222
});
@@ -254,7 +261,8 @@ const colorToShard: Record<string, string> = {
254
261
ACC_PURPLE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalVioletMythic"
255
262
};
256
263
257
const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number): void => {
264
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number): ITypeCount[] => {
265
const recipeChanges: ITypeCount[] = [];
258
266
infestedFoundry.XP ??= 0;
259
267
const prevXP = infestedFoundry.XP;
260
268
infestedFoundry.XP += delta;
@@ -262,14 +270,69 @@ const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number):
262
270
infestedFoundry.Slots ??= 0;
263
271
infestedFoundry.Slots += 3;
264
272
}
273
if (prevXP < 5625_00 && infestedFoundry.XP >= 5625_00) {
274
recipeChanges.push({
275
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldsBlueprint",
276
ItemCount: 1
277
});
278
}
279
if (prevXP < 10125_00 && infestedFoundry.XP >= 10125_00) {
280
recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthHackBlueprint", ItemCount: 1 });
281
}
265
282
if (prevXP < 15750_00 && infestedFoundry.XP >= 15750_00) {
266
283
infestedFoundry.Slots ??= 0;
267
284
infestedFoundry.Slots += 10;
268
285
}
286
if (prevXP < 22500_00 && infestedFoundry.XP >= 22500_00) {
287
recipeChanges.push({
288
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthAmmoEfficiencyBlueprint",
289
ItemCount: 1
290
});
291
}
292
if (prevXP < 30375_00 && infestedFoundry.XP >= 30375_00) {
293
recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStunBlueprint", ItemCount: 1 });
294
}
269
295
if (prevXP < 39375_00 && infestedFoundry.XP >= 39375_00) {
270
296
infestedFoundry.Slots ??= 0;
271
297
infestedFoundry.Slots += 20;
272
298
}
299
if (prevXP < 60750_00 && infestedFoundry.XP >= 60750_00) {
300
recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStatusBlueprint", ItemCount: 1 });
301
}
302
if (prevXP < 73125_00 && infestedFoundry.XP >= 73125_00) {
303
infestedFoundry.Slots = 1;
304
}
305
if (prevXP < 86625_00 && infestedFoundry.XP >= 86625_00) {
306
recipeChanges.push({
307
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldArmorBlueprint",
308
ItemCount: 1
309
});
310
}
311
if (prevXP < 101250_00 && infestedFoundry.XP >= 101250_00) {
312
recipeChanges.push({
313
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthProcBlockBlueprint",
314
ItemCount: 1
315
});
316
}
317
if (prevXP < 117000_00 && infestedFoundry.XP >= 117000_00) {
318
recipeChanges.push({
319
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthEnergyShareBlueprint",
320
ItemCount: 1
321
});
322
}
323
if (prevXP < 133875_00 && infestedFoundry.XP >= 133875_00) {
324
recipeChanges.push({
325
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthMaxStatusBlueprint",
326
ItemCount: 1
327
});
328
}
329
if (prevXP < 151875_00 && infestedFoundry.XP >= 151875_00) {
330
recipeChanges.push({
331
ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthTreasureBlueprint",
332
ItemCount: 1
333
});
334
}
335
return recipeChanges;
273
336
};
274
337
275
338
interface IHelminthSubsumeRequest {
@@ -8,13 +8,16 @@ import {
8
8
} from "@/src/types/inventoryTypes/commonInventoryTypes";
9
9
import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes";
10
10
import { getAccountIdForRequest } from "@/src/services/loginService";
11
import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
11
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
12
12
import { getRecipeByResult } from "@/src/services/itemDataService";
13
import { IInventoryChanges } from "@/src/types/purchaseTypes";
14
import { addInfestedFoundryXP } from "./infestedFoundryController";
13
15
14
16
export const upgradesController: RequestHandler = async (req, res) => {
15
17
const accountId = await getAccountIdForRequest(req);
16
18
const payload = JSON.parse(String(req.body)) as IUpgradesRequest;
17
19
const inventory = await getInventory(accountId);
20
const inventoryChanges: IInventoryChanges = {};
18
21
for (const operation of payload.Operations) {
19
22
if (
20
23
operation.UpgradeRequirement == "/Lotus/Types/Items/MiscItems/ModSlotUnlocker" ||
@@ -35,6 +38,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
35
38
const suit = inventory.Suits.find(x => x._id.toString() == payload.ItemId.$oid)!;
36
39
37
40
let newAbilityOverride: IAbilityOverride | undefined;
41
let totalPercentagePointsConsumed = 0;
38
42
if (operation.UpgradeRequirement != "") {
39
43
newAbilityOverride = {
40
44
Ability: operation.UpgradeRequirement,
@@ -43,6 +47,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
43
47
44
48
const recipe = getRecipeByResult(operation.UpgradeRequirement)!;
45
49
for (const ingredient of recipe.ingredients) {
50
totalPercentagePointsConsumed += ingredient.ItemCount / 10;
46
51
inventory.InfestedFoundry!.Resources!.find(x => x.ItemType == ingredient.ItemType)!.Count -=
47
52
ingredient.ItemCount;
48
53
}
@@ -52,6 +57,12 @@ export const upgradesController: RequestHandler = async (req, res) => {
52
57
suit.Configs[entry.Slot] ??= {};
53
58
suit.Configs[entry.Slot].AbilityOverride = newAbilityOverride;
54
59
}
60
61
const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry!, totalPercentagePointsConsumed * 8);
62
addRecipes(inventory, recipeChanges);
63
64
inventoryChanges.Recipes = recipeChanges;
65
inventoryChanges.InfestedFoundry = inventory.toJSON().InfestedFoundry;
55
66
} else
56
67
switch (operation.UpgradeRequirement) {
57
68
case "/Lotus/Types/Items/MiscItems/OrokinReactor":
@@ -146,7 +157,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
146
157
}
147
158
}
148
159
await inventory.save();
149
res.json({ InventoryChanges: {} });
160
res.json({ InventoryChanges: inventoryChanges });
150
161
};
151
162
152
163
const setSlotPolarity = (item: IEquipmentDatabase, slot: number, polarity: ArtifactPolarity): void => {
@@ -79,8 +79,9 @@ export const combineInventoryChanges = (InventoryChanges: IInventoryChanges, del
79
79
}
80
80
} else if (typeof delta[key] == "object") {
81
81
console.assert(key.substring(-3) == "Bin");
82
console.assert(key != "InfestedFoundry");
82
83
const left = InventoryChanges[key] as IBinChanges;
83
const right: IBinChanges = delta[key];
84
const right = delta[key] as IBinChanges;
84
85
left.count += right.count;
85
86
left.platinum += right.platinum;
86
87
left.Slots += right.Slots;
@@ -1,3 +1,5 @@
1
import { IInfestedFoundry } from "./inventoryTypes/inventoryTypes";
2
1
3
export interface IPurchaseRequest {
2
4
PurchaseParams: IPurchaseParams;
3
5
buildLabel: string;
@@ -25,8 +27,10 @@ export interface ICurrencyChanges {
25
27
26
28
export type IInventoryChanges = {
27
29
[_ in SlotNames]?: IBinChanges;
28
} & ICurrencyChanges &
29
Record<string, IBinChanges | number | object[]>;
30
} & ICurrencyChanges & { InfestedFoundry?: IInfestedFoundry } & Record<
31
string,
32
IBinChanges | number | object[] | IInfestedFoundry
33
>;
30
34
31
35
export interface IPurchaseResponse {
32
36
InventoryChanges: IInventoryChanges;