返回提交历史
Modified
src/controllers/api/infestedFoundryController.ts
+67
-9
Modified
src/models/inventoryModels/inventoryModel.ts
+18
-2
Modified
src/types/inventoryTypes/inventoryTypes.ts
+6
-4
XFEstudio/SpaceNinjaServer
feat: helminth losing apetite (#718)
d69ebf89
代码差异
3 个文件
+91
-15
@@ -8,6 +8,7 @@ import { ExportMisc, ExportRecipes } from "warframe-public-export-plus";
8
8
import { getRecipe } from "@/src/services/itemDataService";
9
9
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
10
10
import { toMongoDate } from "@/src/helpers/inventoryHelpers";
11
import { logger } from "@/src/utils/logger";
11
12
12
13
export const infestedFoundryController: RequestHandler = async (req, res) => {
13
14
const accountId = await getAccountIdForRequest(req);
@@ -67,21 +68,43 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
67
68
const miscItemChanges: IMiscItem[] = [];
68
69
let totalPercentagePointsGained = 0;
69
70
71
const currentUnixSeconds = Math.trunc(new Date().getTime() / 1000);
72
70
73
for (const contribution of request.ResourceContributions) {
71
74
const snack = ExportMisc.helminthSnacks[contribution.ItemType];
72
75
73
// Note: Currently ignoring loss of apetite
74
totalPercentagePointsGained += snack.gain * 100; // 30% would be gain=0.3, so percentage points is equal to gain * 100.
75
const resource = inventory.InfestedFoundry.Resources.find(x => x.ItemType == snack.type);
76
if (resource) {
77
resource.Count += Math.trunc(snack.gain * 1000);
76
let resource = inventory.InfestedFoundry.Resources.find(x => x.ItemType == snack.type);
77
if (!resource) {
78
resource =
79
inventory.InfestedFoundry.Resources[
80
inventory.InfestedFoundry.Resources.push({ ItemType: snack.type, Count: 0 }) - 1
81
];
82
}
83
84
resource.RecentlyConvertedResources ??= [];
85
let record = resource.RecentlyConvertedResources.find(x => x.ItemType == contribution.ItemType);
86
if (!record) {
87
record =
88
resource.RecentlyConvertedResources[
89
resource.RecentlyConvertedResources.push({ ItemType: contribution.ItemType, Date: 0 }) - 1
90
];
91
}
92
93
const hoursRemaining = (record.Date - currentUnixSeconds) / 3600;
94
const apetiteFactor = apetiteModel(hoursRemaining) / 30;
95
logger.debug(`helminth eating ${contribution.ItemType} (+${(snack.gain * 100).toFixed(0)}%)`, {
96
hoursRemaining,
97
apetiteFactor
98
});
99
if (hoursRemaining >= 18) {
100
record.Date = currentUnixSeconds + 72 * 60 * 60;
78
101
} else {
79
inventory.InfestedFoundry.Resources.push({
80
ItemType: snack.type,
81
Count: Math.trunc(snack.gain * 1000) // 30% would be gain=0.3 or Count=300, so Count=gain*1000.
82
});
102
record.Date = currentUnixSeconds + 24 * 60 * 60;
83
103
}
84
104
105
totalPercentagePointsGained += snack.gain * 100 * apetiteFactor; // 30% would be gain=0.3, so percentage points is equal to gain * 100.
106
resource.Count += Math.trunc(snack.gain * 1000 * apetiteFactor); // 30% would be gain=0.3 or Count=300, so Count=gain*1000.
107
85
108
// tally items for removal
86
109
const change = miscItemChanges.find(x => x.ItemType == contribution.ItemType);
87
110
if (change) {
@@ -387,3 +410,38 @@ interface IHelminthInvigorationRequest {
387
410
ResourceTypes: string[];
388
411
ResourceCosts: number[];
389
412
}
413
414
// Hours remaining, percentage points gained (out of 30 total)
415
// 0, 30
416
// 5, 25.8
417
// 10, 21.6
418
// 12, 20
419
// 16, 16.6
420
// 17, 15.8
421
// 18, 15
422
// 20, 15
423
// 24, 15
424
// 36, 15
425
// 40, 13.6
426
// 47, 11.3
427
// 48, 11
428
// 50, 10.3
429
// 60, 7
430
// 70, 3.6
431
// 71, 3.3
432
// 72, 3
433
const apetiteModel = (x: number): number => {
434
if (x <= 0) {
435
return 30;
436
}
437
if (x < 18) {
438
return -0.84 * x + 30;
439
}
440
if (x <= 36) {
441
return 15;
442
}
443
if (x < 71.9) {
444
return -0.3327892 * x + 26.94135;
445
}
446
return 3;
447
};
@@ -45,7 +45,8 @@ import {
45
45
ICrewShipMembers,
46
46
ICrewShip,
47
47
ICrewShipPilotWeapon,
48
IShipExterior
48
IShipExterior,
49
IHelminthFoodRecord
49
50
} from "../../types/inventoryTypes/inventoryTypes";
50
51
import { IOid } from "../../types/commonTypes";
51
52
import {
@@ -470,7 +471,22 @@ const consumedSchuitsSchema = new Schema<IConsumedSuit>(
470
471
{ _id: false }
471
472
);
472
473
473
const helminthResourceSchema = new Schema<IHelminthResource>({ ItemType: String, Count: Number }, { _id: false });
474
const helminthFoodRecordSchema = new Schema<IHelminthFoodRecord>(
475
{
476
ItemType: String,
477
Date: Number
478
},
479
{ _id: false }
480
);
481
482
const helminthResourceSchema = new Schema<IHelminthResource>(
483
{
484
ItemType: String,
485
Count: Number,
486
RecentlyConvertedResources: { type: [helminthFoodRecordSchema], default: undefined }
487
},
488
{ _id: false }
489
);
474
490
475
491
const infestedFoundrySchema = new Schema<IInfestedFoundry>(
476
492
{
@@ -513,13 +513,15 @@ export interface IFusionTreasure {
513
513
Sockets: number;
514
514
}
515
515
516
export interface IHelminthFoodRecord {
517
ItemType: string;
518
Date: number;
519
}
520
516
521
export interface IHelminthResource {
517
522
ItemType: string;
518
523
Count: number;
519
RecentlyConvertedResources?: {
520
ItemType: string;
521
Date: number;
522
}[];
524
RecentlyConvertedResources?: IHelminthFoodRecord[];
523
525
}
524
526
525
527
export interface IInfestedFoundry {