Fix issue in BotLevelGenerator when high level (!388)

Previously `highestValue` could be lower than `lowestValue`, resulting in an exception. These values are now generated in the same method and clamped

Add a catch to the botgen promise await so we get more useful errors if botgen fails

Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com>
Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/388
Co-authored-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
Co-committed-by: DrakiaXYZ <drakiaxyz@noreply.dev.sp-tarkov.com>
This commit is contained in:
DrakiaXYZ 2024-07-30 07:24:29 +00:00 committed by chomp
parent 398bf43444
commit ee1eb7d690
2 changed files with 29 additions and 44 deletions

View File

@ -226,8 +226,9 @@ export class BotController {
conditionPromises.push(this.generateWithBotDetails(condition, botGenerationDetails, sessionId)); conditionPromises.push(this.generateWithBotDetails(condition, botGenerationDetails, sessionId));
} }
await Promise.all(conditionPromises).then((p) => Promise.all(p)); await Promise.all(conditionPromises).then((p) => Promise.all(p)).catch((ex) => {
this.logger.error(ex);
});
return []; return [];
} }

View File

@ -30,12 +30,11 @@ export class BotLevelGenerator {
bot: IBotBase, bot: IBotBase,
): IRandomisedBotLevelResult { ): IRandomisedBotLevelResult {
const expTable = this.databaseService.getGlobals().config.exp.level.exp_table; const expTable = this.databaseService.getGlobals().config.exp.level.exp_table;
const highestLevel = this.getHighestRelativeBotLevel(botGenerationDetails, levelDetails, expTable.length); const botLevelRange = this.getRelativeBotLevelRange(botGenerationDetails, levelDetails, expTable.length);
const lowestLevel = this.getLowestRelativeBotLevel(botGenerationDetails, levelDetails, expTable.length);
// Get random level based on the exp table. // Get random level based on the exp table.
let exp = 0; let exp = 0;
const level = this.chooseBotLevel(lowestLevel, highestLevel, 1, 1.15); const level = this.chooseBotLevel(botLevelRange.min, botLevelRange.max, 1, 1.15);
for (let i = 0; i < level; i++) { for (let i = 0; i < level; i++) {
exp += expTable[i].exp; exp += expTable[i].exp;
} }
@ -53,55 +52,40 @@ export class BotLevelGenerator {
} }
/** /**
* Get the highest level a bot can be relative to the players level, but no further than the max size from globals.exp_table * Return the min and max bot level based on a relative delta from the PMC level
* @param botGenerationDetails Details to help generate a bot
* @param levelDetails
* @param maxLevel Max possible level
* @returns Highest level possible for bot
*/
protected getHighestRelativeBotLevel(
botGenerationDetails: BotGenerationDetails,
levelDetails: MinMax,
maxLevel: number,
): number {
const maxPossibleLevel =
botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride
? Math.min(botGenerationDetails.locationSpecificPmcLevelOverride.max, maxLevel) // Was a PMC and they have a level override
: Math.min(levelDetails.max, maxLevel); // Not pmc with override or non-pmc
let level = botGenerationDetails.playerLevel + botGenerationDetails.botRelativeLevelDeltaMax;
if (level > maxPossibleLevel) {
level = maxPossibleLevel;
}
return level;
}
/**
* Get the lowest level a bot can be relative to the players level, but no lower than 1
* @param botGenerationDetails Details to help generate a bot * @param botGenerationDetails Details to help generate a bot
* @param levelDetails * @param levelDetails
* @param maxlevel Max level allowed * @param maxlevel Max level allowed
* @returns Lowest level possible for bot * @returns A MinMax of the lowest and highest level to generate the bots
*/ */
protected getLowestRelativeBotLevel( protected getRelativeBotLevelRange(
botGenerationDetails: BotGenerationDetails, botGenerationDetails: BotGenerationDetails,
levelDetails: MinMax, levelDetails: MinMax,
maxlevel: number, maxAvailableLevel: number,
): number { ): MinMax {
const minPossibleLevel = const minPossibleLevel =
botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride
? Math.min( ? Math.min(
Math.max(levelDetails.min, botGenerationDetails.locationSpecificPmcLevelOverride.min), // Biggest between json min and the botgen min Math.max(levelDetails.min, botGenerationDetails.locationSpecificPmcLevelOverride.min), // Biggest between json min and the botgen min
maxlevel, // Fallback if value above is crazy (default is 79) maxAvailableLevel, // Fallback if value above is crazy (default is 79)
) )
: Math.min(levelDetails.min, maxlevel); // Not pmc with override or non-pmc : Math.min(levelDetails.min, maxAvailableLevel); // Not pmc with override or non-pmc
let level = botGenerationDetails.playerLevel - botGenerationDetails.botRelativeLevelDeltaMin; const maxPossibleLevel =
if (level < minPossibleLevel) { botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride
level = minPossibleLevel; ? Math.min(botGenerationDetails.locationSpecificPmcLevelOverride.max, maxAvailableLevel) // Was a PMC and they have a level override
: Math.min(levelDetails.max, maxAvailableLevel); // Not pmc with override or non-pmc
let minLevel = botGenerationDetails.playerLevel - botGenerationDetails.botRelativeLevelDeltaMin;
let maxLevel = botGenerationDetails.playerLevel + botGenerationDetails.botRelativeLevelDeltaMax;
// Bound the level to the min/max possible
maxLevel = Math.min(Math.max(maxLevel, minPossibleLevel), maxPossibleLevel);
minLevel = Math.min(Math.max(minLevel, minPossibleLevel), maxPossibleLevel);
return {
min: minLevel,
max: maxLevel,
} }
return level;
} }
} }