Adjust water_collector total craft time every update() to include the players current CRAFTINGskill level instead of the first time profile is created

Refactored `registerProduction()` to also use this code

Fix code that was getting value to 4dp, not 3dp
Skip doing work in `getHideoutManagementConsumptionBonus()` if hideoutMgmt skill is 0
This commit is contained in:
Dev 2024-02-29 16:24:47 +00:00
parent cfee4c10db
commit 767063d291

View File

@ -73,7 +73,9 @@ export class HideoutHelper
sessionID: string,
): IItemEventRouterResponse
{
const recipe = this.databaseServer.getTables().hideout.production.find((p) => p._id === body.recipeId);
const recipe = this.databaseServer.getTables().hideout.production.find((production) =>
production._id === body.recipeId
);
if (!recipe)
{
this.logger.error(this.localisationService.getText("hideout-missing_recipe_in_db", body.recipeId));
@ -81,9 +83,6 @@ export class HideoutHelper
return this.httpResponse.appendErrorToOutput(this.eventOutputHolder.getOutput(sessionID));
}
let modifiedProductionTime = recipe.productionTime
- this.getCraftingSkillProductionTimeReduction(pmcData, recipe.productionTime);
// @Important: Here we need to be very exact:
// - normal recipe: Production time value is stored in attribute "productionType" with small "p"
// - scav case recipe: Production time value is stored in attribute "ProductionType" with capital "P"
@ -92,10 +91,7 @@ export class HideoutHelper
pmcData.Hideout.Production = {};
}
if (modifiedProductionTime > 0 && this.profileHelper.isDeveloperAccount(sessionID))
{
modifiedProductionTime = 40;
}
const modifiedProductionTime = this.getAdjustedCraftTimeWithSkills(pmcData, body.recipeId);
const production = this.initProduction(
body.recipeId,
@ -253,25 +249,6 @@ export class HideoutHelper
return false;
}
/**
* Update progress timer for water collector
* @param pmcData profile to update
* @param productionId id of water collection production to update
* @param hideoutProperties Hideout properties
*/
protected updateWaterCollectorProductionTimer(
pmcData: IPmcData,
productionId: string,
hideoutProperties: { btcFarmCGs?: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; },
): void
{
const timeElapsed = this.getTimeElapsedSinceLastServerTick(pmcData, hideoutProperties.isGeneratorOn);
if (hideoutProperties.waterCollectorHasFilter)
{
pmcData.Hideout.Production[productionId].Progress += timeElapsed;
}
}
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
@ -345,6 +322,25 @@ export class HideoutHelper
}
}
/**
* Update progress timer for water collector
* @param pmcData profile to update
* @param productionId id of water collection production to update
* @param hideoutProperties Hideout properties
*/
protected updateWaterCollectorProductionTimer(
pmcData: IPmcData,
productionId: string,
hideoutProperties: { btcFarmCGs?: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; },
): void
{
const timeElapsed = this.getTimeElapsedSinceLastServerTick(pmcData, hideoutProperties.isGeneratorOn);
if (hideoutProperties.waterCollectorHasFilter)
{
pmcData.Hideout.Production[productionId].Progress += timeElapsed;
}
}
/**
* Update a productions progress value based on the amount of time that has passed
* @param pmcData Player profile
@ -558,6 +554,9 @@ export class HideoutHelper
const prod = pmcData.Hideout.Production[HideoutHelper.waterCollector];
if (prod && this.isProduction(prod))
{
// Update craft time to account for increases in players craft time skill
prod.ProductionTime = this.getAdjustedCraftTimeWithSkills(pmcData, prod.RecipeId);
this.updateWaterFilters(area, prod, isGeneratorOn, pmcData);
}
else
@ -576,6 +575,35 @@ export class HideoutHelper
}
}
/**
* Get craft time and make adjustments to account for dev profile + crafting skill level
* @param pmcData Player profile making craft
* @param recipeId Recipe being crafted
* @returns
*/
protected getAdjustedCraftTimeWithSkills(pmcData: IPmcData, recipeId: string): number
{
const recipe = this.databaseServer.getTables().hideout.production.find((production) =>
production._id === recipeId
);
if (!recipe)
{
this.logger.error(this.localisationService.getText("hideout-missing_recipe_in_db", recipeId));
return undefined;
}
let modifiedProductionTime = recipe.productionTime
- this.getCraftingSkillProductionTimeReduction(pmcData, recipe.productionTime);
if (modifiedProductionTime > 0 && this.profileHelper.isDeveloperAccount(pmcData._id))
{
modifiedProductionTime = 40;
}
return modifiedProductionTime;
}
/**
* Adjust water filter objects resourceValue or delete when they reach 0 resource
* @param waterFilterArea water filter area to update
@ -594,7 +622,7 @@ export class HideoutHelper
const productionTime = this.getTotalProductionTimeSeconds(HideoutHelper.waterCollector);
const secondsSinceServerTick = this.getTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn);
filterDrainRate = this.adjustWaterFilterDrainRate(
filterDrainRate = this.getAdjustWaterFilterDrainRate(
secondsSinceServerTick,
productionTime,
production.Progress,
@ -605,56 +633,57 @@ export class HideoutHelper
let pointsConsumed = 0;
if (production.Progress < productionTime)
{
// Check all slots that take water filters
// Must loop to find first water filter and use that
// Check all slots that take water filters until we find one with filter in it
for (let i = 0; i < waterFilterArea.slots.length; i++)
{
// Has a water filter installed into slot
if (waterFilterArea.slots[i].item)
// No water filter, skip
if (!waterFilterArea.slots[i].item)
{
// How many units of filter are left
let resourceValue = (waterFilterArea.slots[i].item[0].upd?.Resource)
? waterFilterArea.slots[i].item[0].upd.Resource.Value
: null;
if (!resourceValue)
{
// None left
resourceValue = 100 - filterDrainRate;
pointsConsumed = filterDrainRate;
}
else
{
pointsConsumed = (waterFilterArea.slots[i].item[0].upd.Resource.UnitsConsumed || 0)
+ filterDrainRate;
resourceValue -= filterDrainRate;
}
// Round to get values to 3dp
resourceValue = Math.round(resourceValue * 10000) / 10000;
pointsConsumed = Math.round(pointsConsumed * 10000) / 10000;
// Check amount of units consumed for possible increment of hideout mgmt skill point
if (pmcData && Math.floor(pointsConsumed / 10) >= 1)
{
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.HIDEOUT_MANAGEMENT, 1);
pointsConsumed -= 10;
}
// Filter has some juice left in it after we adjusted it
if (resourceValue > 0)
{
// Set filter consumed amount
waterFilterArea.slots[i].item[0].upd = this.getAreaUpdObject(1, resourceValue, pointsConsumed);
this.logger.debug(`Water filter has: ${resourceValue} units left in slot ${i + 1}`);
break; // Break here to avoid updating all filters
}
// Filter ran out / used up
delete waterFilterArea.slots[i].item;
// Update remaining resources to be subtracted
filterDrainRate = Math.abs(resourceValue);
continue;
}
// How many units of filter are left
let resourceValue = (waterFilterArea.slots[i].item[0].upd?.Resource)
? waterFilterArea.slots[i].item[0].upd.Resource.Value
: null;
if (!resourceValue)
{
// Missing, is new filter, add default and subtract usage
resourceValue = 100 - filterDrainRate;
pointsConsumed = filterDrainRate;
}
else
{
pointsConsumed = (waterFilterArea.slots[i].item[0].upd.Resource.UnitsConsumed || 0)
+ filterDrainRate;
resourceValue -= filterDrainRate;
}
// Round to get values to 3dp
resourceValue = Math.round(resourceValue * 1000) / 1000;
pointsConsumed = Math.round(pointsConsumed * 1000) / 1000;
// Check units consumed for possible increment of hideout mgmt skill point
if (pmcData && Math.floor(pointsConsumed / 10) >= 1)
{
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.HIDEOUT_MANAGEMENT, 1);
pointsConsumed -= 10;
}
// Filter has some fuel left in it after our adjustment
if (resourceValue > 0)
{
// Set filters consumed amount
waterFilterArea.slots[i].item[0].upd = this.getAreaUpdObject(1, resourceValue, pointsConsumed);
this.logger.debug(`Water filter has: ${resourceValue} units left in slot ${i + 1}`);
break; // Break here to avoid iterating other filters now w're done
}
// Filter ran out / used up
delete waterFilterArea.slots[i].item;
// Update remaining resources to be subtracted
filterDrainRate = Math.abs(resourceValue);
}
}
}
@ -666,23 +695,21 @@ export class HideoutHelper
* @param totalProductionTime Total time collecting water
* @param productionProgress how far water collector has progressed
* @param baseFilterDrainRate Base drain rate
* @returns
* @returns drain rate (adjusted)
*/
protected adjustWaterFilterDrainRate(
protected getAdjustWaterFilterDrainRate(
secondsSinceServerTick: number,
totalProductionTime: number,
productionProgress: number,
baseFilterDrainRate: number,
): number
{
const drainRateMultiplier = secondsSinceServerTick > totalProductionTime
const drainTimeSeconds = secondsSinceServerTick > totalProductionTime
? (totalProductionTime - productionProgress) // more time passed than prod time, get total minus the current progress
: secondsSinceServerTick;
// Multiply drain rate by calculated multiplier
baseFilterDrainRate *= drainRateMultiplier;
return baseFilterDrainRate;
return baseFilterDrainRate * drainTimeSeconds;
}
/**
@ -952,7 +979,7 @@ export class HideoutHelper
protected getHideoutManagementConsumptionBonus(pmcData: IPmcData): number
{
const hideoutManagementSkill = this.profileHelper.getSkillFromProfile(pmcData, SkillTypes.HIDEOUT_MANAGEMENT);
if (!hideoutManagementSkill)
if (!hideoutManagementSkill || hideoutManagementSkill.Progress === 0)
{
return 0;
}
@ -976,7 +1003,7 @@ export class HideoutHelper
*/
protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number
{
const craftingSkill = pmcData.Skills.Common.find((x) => x.Id === SkillTypes.CRAFTING);
const craftingSkill = pmcData.Skills.Common.find((skill) => skill.Id === SkillTypes.CRAFTING);
if (!craftingSkill)
{
return productionTime;