feat: helminth losing apetite

This commit is contained in:
Sainan 2025-01-05 09:09:41 +01:00
parent 06bc0123ba
commit 0646d995ff
3 changed files with 75 additions and 16 deletions

View File

@ -8,6 +8,7 @@ import { ExportMisc, ExportRecipes } from "warframe-public-export-plus";
import { getRecipe } from "@/src/services/itemDataService"; import { getRecipe } from "@/src/services/itemDataService";
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { toMongoDate } from "@/src/helpers/inventoryHelpers";
import { logger } from "@/src/utils/logger";
export const infestedFoundryController: RequestHandler = async (req, res) => { export const infestedFoundryController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
@ -67,21 +68,44 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
const miscItemChanges: IMiscItem[] = []; const miscItemChanges: IMiscItem[] = [];
let totalPercentagePointsGained = 0; let totalPercentagePointsGained = 0;
const currentUnixSeconds = Math.trunc(new Date().getTime() / 1000);
for (const contribution of request.ResourceContributions) { for (const contribution of request.ResourceContributions) {
const snack = ExportMisc.helminthSnacks[contribution.ItemType]; const snack = ExportMisc.helminthSnacks[contribution.ItemType];
// Note: Currently ignoring loss of apetite let resource = inventory.InfestedFoundry.Resources.find(x => x.ItemType == snack.type);
totalPercentagePointsGained += snack.gain * 100; // 30% would be gain=0.3, so percentage points is equal to gain * 100. if (!resource) {
const resource = inventory.InfestedFoundry.Resources.find(x => x.ItemType == snack.type); resource =
if (resource) { inventory.InfestedFoundry.Resources[
resource.Count += Math.trunc(snack.gain * 1000); inventory.InfestedFoundry.Resources.push({ ItemType: snack.type, Count: 0 }) - 1
} else { ];
inventory.InfestedFoundry.Resources.push({
ItemType: snack.type,
Count: Math.trunc(snack.gain * 1000) // 30% would be gain=0.3 or Count=300, so Count=gain*1000.
});
} }
resource.RecentlyConvertedResources ??= [];
let record = resource.RecentlyConvertedResources.find(x => x.ItemType == contribution.ItemType);
if (!record) {
record =
resource.RecentlyConvertedResources[
resource.RecentlyConvertedResources.push({ ItemType: contribution.ItemType, Date: 0 }) - 1
];
}
const hoursRemaining = (record.Date - currentUnixSeconds) / 3600;
const apetiteFactor = apetiteModel(hoursRemaining) / 30;
logger.debug(`helminth eating ${contribution.ItemType} (+${(snack.gain * 100).toFixed(2)}%)`, {
hoursRemaining,
apetiteFactor
});
if (hoursRemaining >= 18) {
record.Date = currentUnixSeconds + 72 * 60 * 60;
} else {
record.Date = currentUnixSeconds + 24 * 60 * 60;
}
resource.RecentlyConvertedResources.push(record);
totalPercentagePointsGained += snack.gain * 100 * apetiteFactor; // 30% would be gain=0.3, so percentage points is equal to gain * 100.
resource.Count += Math.trunc(snack.gain * 1000 * apetiteFactor); // 30% would be gain=0.3 or Count=300, so Count=gain*1000.
// tally items for removal // tally items for removal
const change = miscItemChanges.find(x => x.ItemType == contribution.ItemType); const change = miscItemChanges.find(x => x.ItemType == contribution.ItemType);
if (change) { if (change) {
@ -371,3 +395,20 @@ interface IHelminthInvigorationRequest {
ResourceTypes: string[]; ResourceTypes: string[];
ResourceCosts: number[]; ResourceCosts: number[];
} }
// Hours remaining -> percentage points gained
const apetiteModel = (x: number): number => {
if (x <= 0) {
return 30;
}
if (x < 18) {
return -0.84 * x + 30;
}
if (x <= 36) {
return 15;
}
if (x < 71.9) {
return -0.3327892 * x + 26.94135;
}
return 3;
};

View File

@ -45,7 +45,8 @@ import {
ICrewShipMembers, ICrewShipMembers,
ICrewShip, ICrewShip,
ICrewShipPilotWeapon, ICrewShipPilotWeapon,
IShipExterior IShipExterior,
IHelminthFoodRecord
} from "../../types/inventoryTypes/inventoryTypes"; } from "../../types/inventoryTypes/inventoryTypes";
import { IOid } from "../../types/commonTypes"; import { IOid } from "../../types/commonTypes";
import { import {
@ -470,7 +471,22 @@ const consumedSchuitsSchema = new Schema<IConsumedSuit>(
{ _id: false } { _id: false }
); );
const helminthResourceSchema = new Schema<IHelminthResource>({ ItemType: String, Count: Number }, { _id: false }); const helminthFoodRecordSchema = new Schema<IHelminthFoodRecord>(
{
ItemType: String,
Date: Number
},
{ _id: false }
);
const helminthResourceSchema = new Schema<IHelminthResource>(
{
ItemType: String,
Count: Number,
RecentlyConvertedResources: { type: [helminthFoodRecordSchema], default: undefined }
},
{ _id: false }
);
const infestedFoundrySchema = new Schema<IInfestedFoundry>( const infestedFoundrySchema = new Schema<IInfestedFoundry>(
{ {

View File

@ -513,13 +513,15 @@ export interface IFusionTreasure {
Sockets: number; Sockets: number;
} }
export interface IHelminthFoodRecord {
ItemType: string;
Date: number;
}
export interface IHelminthResource { export interface IHelminthResource {
ItemType: string; ItemType: string;
Count: number; Count: number;
RecentlyConvertedResources?: { RecentlyConvertedResources?: IHelminthFoodRecord[];
ItemType: string;
Date: number;
}[];
} }
export interface IInfestedFoundry { export interface IInfestedFoundry {