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, sessionID: string,
): IItemEventRouterResponse ): 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) if (!recipe)
{ {
this.logger.error(this.localisationService.getText("hideout-missing_recipe_in_db", body.recipeId)); 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)); 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: // @Important: Here we need to be very exact:
// - normal recipe: Production time value is stored in attribute "productionType" with small "p" // - 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" // - scav case recipe: Production time value is stored in attribute "ProductionType" with capital "P"
@ -92,10 +91,7 @@ export class HideoutHelper
pmcData.Hideout.Production = {}; pmcData.Hideout.Production = {};
} }
if (modifiedProductionTime > 0 && this.profileHelper.isDeveloperAccount(sessionID)) const modifiedProductionTime = this.getAdjustedCraftTimeWithSkills(pmcData, body.recipeId);
{
modifiedProductionTime = 40;
}
const production = this.initProduction( const production = this.initProduction(
body.recipeId, body.recipeId,
@ -253,25 +249,6 @@ export class HideoutHelper
return false; 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 * Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update * @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 * Update a productions progress value based on the amount of time that has passed
* @param pmcData Player profile * @param pmcData Player profile
@ -558,6 +554,9 @@ export class HideoutHelper
const prod = pmcData.Hideout.Production[HideoutHelper.waterCollector]; const prod = pmcData.Hideout.Production[HideoutHelper.waterCollector];
if (prod && this.isProduction(prod)) 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); this.updateWaterFilters(area, prod, isGeneratorOn, pmcData);
} }
else 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 * Adjust water filter objects resourceValue or delete when they reach 0 resource
* @param waterFilterArea water filter area to update * @param waterFilterArea water filter area to update
@ -594,7 +622,7 @@ export class HideoutHelper
const productionTime = this.getTotalProductionTimeSeconds(HideoutHelper.waterCollector); const productionTime = this.getTotalProductionTimeSeconds(HideoutHelper.waterCollector);
const secondsSinceServerTick = this.getTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn); const secondsSinceServerTick = this.getTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn);
filterDrainRate = this.adjustWaterFilterDrainRate( filterDrainRate = this.getAdjustWaterFilterDrainRate(
secondsSinceServerTick, secondsSinceServerTick,
productionTime, productionTime,
production.Progress, production.Progress,
@ -605,56 +633,57 @@ export class HideoutHelper
let pointsConsumed = 0; let pointsConsumed = 0;
if (production.Progress < productionTime) if (production.Progress < productionTime)
{ {
// Check all slots that take water filters // Check all slots that take water filters until we find one with filter in it
// Must loop to find first water filter and use that
for (let i = 0; i < waterFilterArea.slots.length; i++) for (let i = 0; i < waterFilterArea.slots.length; i++)
{ {
// Has a water filter installed into slot // No water filter, skip
if (waterFilterArea.slots[i].item) if (!waterFilterArea.slots[i].item)
{ {
// How many units of filter are left continue;
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);
} }
// 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 totalProductionTime Total time collecting water
* @param productionProgress how far water collector has progressed * @param productionProgress how far water collector has progressed
* @param baseFilterDrainRate Base drain rate * @param baseFilterDrainRate Base drain rate
* @returns * @returns drain rate (adjusted)
*/ */
protected adjustWaterFilterDrainRate( protected getAdjustWaterFilterDrainRate(
secondsSinceServerTick: number, secondsSinceServerTick: number,
totalProductionTime: number, totalProductionTime: number,
productionProgress: number, productionProgress: number,
baseFilterDrainRate: number, baseFilterDrainRate: number,
): number ): number
{ {
const drainRateMultiplier = secondsSinceServerTick > totalProductionTime const drainTimeSeconds = secondsSinceServerTick > totalProductionTime
? (totalProductionTime - productionProgress) // more time passed than prod time, get total minus the current progress ? (totalProductionTime - productionProgress) // more time passed than prod time, get total minus the current progress
: secondsSinceServerTick; : secondsSinceServerTick;
// Multiply drain rate by calculated multiplier // Multiply drain rate by calculated multiplier
baseFilterDrainRate *= drainRateMultiplier; return baseFilterDrainRate * drainTimeSeconds;
return baseFilterDrainRate;
} }
/** /**
@ -952,7 +979,7 @@ export class HideoutHelper
protected getHideoutManagementConsumptionBonus(pmcData: IPmcData): number protected getHideoutManagementConsumptionBonus(pmcData: IPmcData): number
{ {
const hideoutManagementSkill = this.profileHelper.getSkillFromProfile(pmcData, SkillTypes.HIDEOUT_MANAGEMENT); const hideoutManagementSkill = this.profileHelper.getSkillFromProfile(pmcData, SkillTypes.HIDEOUT_MANAGEMENT);
if (!hideoutManagementSkill) if (!hideoutManagementSkill || hideoutManagementSkill.Progress === 0)
{ {
return 0; return 0;
} }
@ -976,7 +1003,7 @@ export class HideoutHelper
*/ */
protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number 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) if (!craftingSkill)
{ {
return productionTime; return productionTime;