Add crafting skill into water filter drain rate calculation
Added small optimisation to only process water filters if a water filter is installed Added crafting skill bonus to water filter craft time calculation Various variable/comment renames for clarity
This commit is contained in:
parent
50f580858d
commit
a66b6644a1
@ -678,7 +678,13 @@ export class HideoutController
|
|||||||
// - normal recipe: Production time value is stored in attribute "productionTime" with small "p"
|
// - normal recipe: Production time value is stored in attribute "productionTime" with small "p"
|
||||||
// - scav case recipe: Production time value is stored in attribute "ProductionTime" with capital "P"
|
// - scav case recipe: Production time value is stored in attribute "ProductionTime" with capital "P"
|
||||||
const adjustedCraftTime = recipe.ProductionTime
|
const adjustedCraftTime = recipe.ProductionTime
|
||||||
- this.hideoutHelper.getCraftingSkillProductionTimeReduction(pmcData, recipe.ProductionTime);
|
- this.hideoutHelper.getSkillProductionTimeReduction(
|
||||||
|
pmcData,
|
||||||
|
recipe.ProductionTime,
|
||||||
|
SkillTypes.CRAFTING,
|
||||||
|
this.databaseServer.getTables().globals.config.SkillsSettings.Crafting.CraftTimeReductionPerLevel,
|
||||||
|
);
|
||||||
|
|
||||||
const modifiedScavCaseTime = this.getScavCaseTime(pmcData, adjustedCraftTime);
|
const modifiedScavCaseTime = this.getScavCaseTime(pmcData, adjustedCraftTime);
|
||||||
|
|
||||||
pmcData.Hideout.Production[body.recipeId] = this.hideoutHelper.initProduction(
|
pmcData.Hideout.Production[body.recipeId] = this.hideoutHelper.initProduction(
|
||||||
|
@ -221,14 +221,14 @@ export class HideoutHelper
|
|||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
): { btcFarmCGs: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; }
|
): { btcFarmCGs: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; }
|
||||||
{
|
{
|
||||||
const bitcoinFarm = pmcData.Hideout.Areas.find((x) => x.type === HideoutAreas.BITCOIN_FARM);
|
const bitcoinFarm = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.BITCOIN_FARM);
|
||||||
const bitcoinCount = bitcoinFarm?.slots.filter((slot) => slot.item).length ?? 0; // Get slots with an item property
|
const bitcoinCount = bitcoinFarm?.slots.filter((slot) => slot.item).length ?? 0; // Get slots with an item property
|
||||||
|
|
||||||
const hideoutProperties = {
|
const hideoutProperties = {
|
||||||
btcFarmCGs: bitcoinCount,
|
btcFarmCGs: bitcoinCount,
|
||||||
isGeneratorOn: pmcData.Hideout.Areas.find((x) => x.type === HideoutAreas.GENERATOR)?.active ?? false,
|
isGeneratorOn: pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.GENERATOR)?.active ?? false,
|
||||||
waterCollectorHasFilter: this.doesWaterCollectorHaveFilter(
|
waterCollectorHasFilter: this.doesWaterCollectorHaveFilter(
|
||||||
pmcData.Hideout.Areas.find((x) => x.type === HideoutAreas.WATER_COLLECTOR),
|
pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.WATER_COLLECTOR),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -237,10 +237,11 @@ export class HideoutHelper
|
|||||||
|
|
||||||
protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean
|
protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean
|
||||||
{
|
{
|
||||||
|
// Can put filters in from L3
|
||||||
if (waterCollector.level === 3)
|
if (waterCollector.level === 3)
|
||||||
{ // can put filters in from L3
|
{
|
||||||
// Has filter in at least one slot
|
// Has filter in at least one slot
|
||||||
return waterCollector.slots.some((x) => x.item);
|
return waterCollector.slots.some((slot) => slot.item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No Filter
|
// No Filter
|
||||||
@ -423,7 +424,7 @@ export class HideoutHelper
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HideoutAreas.WATER_COLLECTOR:
|
case HideoutAreas.WATER_COLLECTOR:
|
||||||
this.updateWaterCollector(sessionID, pmcData, area, hideoutProperties.isGeneratorOn);
|
this.updateWaterCollector(sessionID, pmcData, area, hideoutProperties);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HideoutAreas.AIR_FILTERING:
|
case HideoutAreas.AIR_FILTERING:
|
||||||
@ -544,7 +545,7 @@ export class HideoutHelper
|
|||||||
sessionId: string,
|
sessionId: string,
|
||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
area: HideoutArea,
|
area: HideoutArea,
|
||||||
isGeneratorOn: boolean,
|
hideoutProperties: { btcFarmCGs: number; isGeneratorOn: boolean; waterCollectorHasFilter: boolean; },
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
// Skip water collector when not level 3 (cant collect until 3)
|
// Skip water collector when not level 3 (cant collect until 3)
|
||||||
@ -553,14 +554,23 @@ export class HideoutHelper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hideoutProperties.waterCollectorHasFilter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Canister with purified water craft exists
|
// Canister with purified water craft exists
|
||||||
const prod = pmcData.Hideout.Production[HideoutHelper.waterCollector];
|
const purifiedWaterCraft = pmcData.Hideout.Production[HideoutHelper.waterCollector];
|
||||||
if (prod && this.isProduction(prod))
|
if (purifiedWaterCraft && this.isProduction(purifiedWaterCraft))
|
||||||
{
|
{
|
||||||
// Update craft time to account for increases in players craft time skill
|
// Update craft time to account for increases in players craft time skill
|
||||||
prod.ProductionTime = this.getAdjustedCraftTimeWithSkills(pmcData, prod.RecipeId);
|
purifiedWaterCraft.ProductionTime = this.getAdjustedCraftTimeWithSkills(
|
||||||
|
pmcData,
|
||||||
|
purifiedWaterCraft.RecipeId,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
this.updateWaterFilters(area, prod, isGeneratorOn, pmcData);
|
this.updateWaterFilters(area, purifiedWaterCraft, hideoutProperties.isGeneratorOn, pmcData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -582,10 +592,17 @@ export class HideoutHelper
|
|||||||
* Get craft time and make adjustments to account for dev profile + crafting skill level
|
* Get craft time and make adjustments to account for dev profile + crafting skill level
|
||||||
* @param pmcData Player profile making craft
|
* @param pmcData Player profile making craft
|
||||||
* @param recipeId Recipe being crafted
|
* @param recipeId Recipe being crafted
|
||||||
* @returns
|
* @param applyHideoutManagementBonus should the hideout mgmt bonus be appled to the calculation
|
||||||
|
* @returns Items craft time with bonuses subtracted
|
||||||
*/
|
*/
|
||||||
protected getAdjustedCraftTimeWithSkills(pmcData: IPmcData, recipeId: string): number
|
protected getAdjustedCraftTimeWithSkills(
|
||||||
|
pmcData: IPmcData,
|
||||||
|
recipeId: string,
|
||||||
|
applyHideoutManagementBonus = false,
|
||||||
|
): number
|
||||||
{
|
{
|
||||||
|
const globalSkillsDb = this.databaseServer.getTables().globals.config.SkillsSettings;
|
||||||
|
|
||||||
const recipe = this.databaseServer.getTables().hideout.production.find((production) =>
|
const recipe = this.databaseServer.getTables().hideout.production.find((production) =>
|
||||||
production._id === recipeId
|
production._id === recipeId
|
||||||
);
|
);
|
||||||
@ -596,9 +613,26 @@ export class HideoutHelper
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let modifiedProductionTime = recipe.productionTime
|
// Seconds to deduct from crafts total time
|
||||||
- this.getCraftingSkillProductionTimeReduction(pmcData, recipe.productionTime);
|
let timeReductionSeconds = this.getSkillProductionTimeReduction(
|
||||||
|
pmcData,
|
||||||
|
recipe.productionTime,
|
||||||
|
SkillTypes.CRAFTING,
|
||||||
|
globalSkillsDb.Crafting.ProductionTimeReductionPerLevel,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Some crafts take into account hideout management, e.g. fuel, water/air filters
|
||||||
|
if (applyHideoutManagementBonus)
|
||||||
|
{
|
||||||
|
timeReductionSeconds += this.getSkillProductionTimeReduction(
|
||||||
|
pmcData,
|
||||||
|
recipe.productionTime,
|
||||||
|
SkillTypes.HIDEOUT_MANAGEMENT,
|
||||||
|
globalSkillsDb.HideoutManagement.ConsumptionReductionPerLevel,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let modifiedProductionTime = recipe.productionTime - timeReductionSeconds;
|
||||||
if (modifiedProductionTime > 0 && this.profileHelper.isDeveloperAccount(pmcData._id))
|
if (modifiedProductionTime > 0 && this.profileHelper.isDeveloperAccount(pmcData._id))
|
||||||
{
|
{
|
||||||
modifiedProductionTime = 40;
|
modifiedProductionTime = 40;
|
||||||
@ -625,7 +659,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.getAdjustWaterFilterDrainRate(
|
filterDrainRate = this.getTimeAdjustedWaterFilterDrainRate(
|
||||||
secondsSinceServerTick,
|
secondsSinceServerTick,
|
||||||
productionTime,
|
productionTime,
|
||||||
production.Progress,
|
production.Progress,
|
||||||
@ -708,7 +742,7 @@ export class HideoutHelper
|
|||||||
* @param baseFilterDrainRate Base drain rate
|
* @param baseFilterDrainRate Base drain rate
|
||||||
* @returns drain rate (adjusted)
|
* @returns drain rate (adjusted)
|
||||||
*/
|
*/
|
||||||
protected getAdjustWaterFilterDrainRate(
|
protected getTimeAdjustedWaterFilterDrainRate(
|
||||||
secondsSinceServerTick: number,
|
secondsSinceServerTick: number,
|
||||||
totalProductionTime: number,
|
totalProductionTime: number,
|
||||||
productionProgress: number,
|
productionProgress: number,
|
||||||
@ -716,10 +750,10 @@ export class HideoutHelper
|
|||||||
): number
|
): number
|
||||||
{
|
{
|
||||||
const drainTimeSeconds = 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 base drain rate by time passed
|
||||||
return baseFilterDrainRate * drainTimeSeconds;
|
return baseFilterDrainRate * drainTimeSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,11 +764,28 @@ export class HideoutHelper
|
|||||||
*/
|
*/
|
||||||
protected getWaterFilterDrainRate(pmcData: IPmcData): number
|
protected getWaterFilterDrainRate(pmcData: IPmcData): number
|
||||||
{
|
{
|
||||||
|
const globalSkillsDb = this.databaseServer.getTables().globals.config.SkillsSettings;
|
||||||
|
|
||||||
// 100 resources last 8 hrs 20 min, 100/8.33/60/60 = 0.00333
|
// 100 resources last 8 hrs 20 min, 100/8.33/60/60 = 0.00333
|
||||||
const filterDrainRate = 0.00333;
|
const filterDrainRate = 0.00333;
|
||||||
const hideoutManagementConsumptionBonus = 1.0 - this.getHideoutManagementConsumptionBonus(pmcData);
|
|
||||||
|
|
||||||
return filterDrainRate * hideoutManagementConsumptionBonus;
|
const hideoutManagementConsumptionBonus = this.getSkillBonusMultipliedBySkillLevel(
|
||||||
|
pmcData,
|
||||||
|
SkillTypes.HIDEOUT_MANAGEMENT,
|
||||||
|
globalSkillsDb.HideoutManagement.ConsumptionReductionPerLevel,
|
||||||
|
);
|
||||||
|
const craftSkillTimeReductionMultipler = this.getSkillBonusMultipliedBySkillLevel(
|
||||||
|
pmcData,
|
||||||
|
SkillTypes.CRAFTING,
|
||||||
|
globalSkillsDb.Crafting.CraftTimeReductionPerLevel,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Never let bonus become 0
|
||||||
|
const reductionBonus = hideoutManagementConsumptionBonus + craftSkillTimeReductionMultipler === 0
|
||||||
|
? 1
|
||||||
|
: 1 - (hideoutManagementConsumptionBonus + craftSkillTimeReductionMultipler);
|
||||||
|
|
||||||
|
return filterDrainRate * reductionBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1013,22 +1064,46 @@ export class HideoutHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjust craft time based on crafting skill level found in player profile
|
* Get a multipler based on players skill level and value per level
|
||||||
|
* @param pmcData Player profile
|
||||||
|
* @param skill Player skill from profile
|
||||||
|
* @param valuePerLevel Value from globals.config.SkillsSettings - `PerLevel`
|
||||||
|
* @returns Multipler from 0 to 1
|
||||||
|
*/
|
||||||
|
protected getSkillBonusMultipliedBySkillLevel(pmcData: IPmcData, skill: SkillTypes, valuePerLevel: number): number
|
||||||
|
{
|
||||||
|
const profileSkill = this.profileHelper.getSkillFromProfile(pmcData, skill);
|
||||||
|
if (!profileSkill || profileSkill.Progress === 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the level is 51 we need to round it at 50 so on elite you dont get 25.5%
|
||||||
|
// at level 1 you already get 0.5%, so it goes up until level 50. For some reason the wiki
|
||||||
|
// says that it caps at level 51 with 25% but as per dump data that is incorrect apparently
|
||||||
|
let roundedLevel = Math.floor(profileSkill.Progress / 100);
|
||||||
|
roundedLevel = (roundedLevel === 51) ? roundedLevel - 1 : roundedLevel;
|
||||||
|
|
||||||
|
return (roundedLevel * valuePerLevel) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @param pmcData Player profile
|
* @param pmcData Player profile
|
||||||
* @param productionTime Time to complete hideout craft in seconds
|
* @param productionTime Time to complete hideout craft in seconds
|
||||||
* @returns Adjusted craft time in seconds
|
* @param skill Skill bonus to get reduction from
|
||||||
|
* @param amountPerLevel Skill bonus amount to apply
|
||||||
|
* @returns Seconds to reduce craft time by
|
||||||
*/
|
*/
|
||||||
public getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number
|
public getSkillProductionTimeReduction(
|
||||||
|
pmcData: IPmcData,
|
||||||
|
productionTime: number,
|
||||||
|
skill: SkillTypes,
|
||||||
|
amountPerLevel: number,
|
||||||
|
): number
|
||||||
{
|
{
|
||||||
const craftingSkill = pmcData.Skills.Common.find((skill) => skill.Id === SkillTypes.CRAFTING);
|
const skillTimeReductionMultipler = this.getSkillBonusMultipliedBySkillLevel(pmcData, skill, amountPerLevel);
|
||||||
if (!craftingSkill)
|
|
||||||
{
|
|
||||||
return productionTime;
|
|
||||||
}
|
|
||||||
const roundedLevel = Math.floor(Math.min(HideoutHelper.maxSkillPoint, craftingSkill.Progress) / 100);
|
|
||||||
const percentageToDrop = roundedLevel * 0.75;
|
|
||||||
|
|
||||||
return (productionTime * percentageToDrop) / 100;
|
return productionTime * skillTimeReductionMultipler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isProduction(productive: Productive): productive is Production
|
public isProduction(productive: Productive): productive is Production
|
||||||
|
@ -495,12 +495,12 @@ export class ProfileHelper
|
|||||||
/**
|
/**
|
||||||
* Get a speciic common skill from supplied profile
|
* Get a speciic common skill from supplied profile
|
||||||
* @param pmcData Player profile
|
* @param pmcData Player profile
|
||||||
* @param skill Skill get get
|
* @param skill Skill to look up and return value from
|
||||||
* @returns Common skill object from desired profile
|
* @returns Common skill object from desired profile
|
||||||
*/
|
*/
|
||||||
public getSkillFromProfile(pmcData: IPmcData, skill: SkillTypes): Common
|
public getSkillFromProfile(pmcData: IPmcData, skill: SkillTypes): Common
|
||||||
{
|
{
|
||||||
const skillToReturn = pmcData.Skills.Common.find((x) => x.Id === skill);
|
const skillToReturn = pmcData.Skills.Common.find((commonSkill) => commonSkill.Id === skill);
|
||||||
if (!skillToReturn)
|
if (!skillToReturn)
|
||||||
{
|
{
|
||||||
this.logger.warning(`Profile ${pmcData.sessionId} does not have a skill named: ${skill}`);
|
this.logger.warning(`Profile ${pmcData.sessionId} does not have a skill named: ${skill}`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user