XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/XFESpaceNinjaServer

feat: all server-side metamorphosis levels (#716)

06bc0123
Sainan <sainan@calamity.inc>
提交于

代码差异

4 个文件 +95 -16
Modified src/controllers/api/infestedFoundryController.ts +74 -11
@@ -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 {
Modified src/controllers/api/upgradesController.ts +13 -2
@@ -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 => {
Modified src/services/inventoryService.ts +2 -1
@@ -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;
Modified src/types/purchaseTypes.ts +6 -2
@@ -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;