Improved how Level specific PMC levels are handled, not included min and max - stored in pmc.json

This commit is contained in:
Dev 2024-04-30 23:21:52 +01:00
parent 297e35a1ff
commit 06b35ddde8
6 changed files with 54 additions and 68 deletions

View File

@ -705,5 +705,16 @@
], ],
"forceHealingItemsIntoSecure": true, "forceHealingItemsIntoSecure": true,
"addPrefixToSameNamePMCAsPlayerChance": 40, "addPrefixToSameNamePMCAsPlayerChance": 40,
"allPMCsHavePlayerNameWithRandomPrefixChance": 1 "allPMCsHavePlayerNameWithRandomPrefixChance": 1,
"locationSpecificPmcLevelOverride": {
"sandbox_high": {
"min": 1,
"max": 20
},
"sandbox_high": {
"min": 21,
"max": 100
}
}
} }

View File

@ -209,11 +209,11 @@ export class BotController
// Clear bot cache before any work starts // Clear bot cache before any work starts
this.botGenerationCacheService.clearStoredBots(); this.botGenerationCacheService.clearStoredBots();
const minimumPmcLevel = this.getMinimumPmcLevelForRaid( const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue< IGetRaidConfigurationRequestData
IGetRaidConfigurationRequestData >();
>(), const pmcLevelRangeForMap =
); this.pmcConfig.locationSpecificPmcLevelOverride[raidSettings?.location.toLowerCase()];
const allPmcsHaveSameNameAsPlayer = this.randomUtil.getChance100( const allPmcsHaveSameNameAsPlayer = this.randomUtil.getChance100(
this.pmcConfig.allPMCsHavePlayerNameWithRandomPrefixChance, this.pmcConfig.allPMCsHavePlayerNameWithRandomPrefixChance,
@ -231,7 +231,7 @@ export class BotController
botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin, botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin,
botCountToGenerate: this.botConfig.presetBatch[condition.Role], botCountToGenerate: this.botConfig.presetBatch[condition.Role],
botDifficulty: condition.Difficulty, botDifficulty: condition.Difficulty,
minimumPmcLevel: minimumPmcLevel, locationSpecificPmcLevelOverride: pmcLevelRangeForMap,
isPlayerScav: false, isPlayerScav: false,
allPmcsHaveSameNameAsPlayer: allPmcsHaveSameNameAsPlayer, allPmcsHaveSameNameAsPlayer: allPmcsHaveSameNameAsPlayer,
}; };
@ -244,21 +244,6 @@ export class BotController
return []; return [];
} }
/**
* Get the lowest level a bot can be generated with
* @param raidConfig IGetRaidConfigurationRequestData from applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)
* @returns Number
*/
protected getMinimumPmcLevelForRaid(raidConfig: IGetRaidConfigurationRequestData): number
{
if (raidConfig?.location.toLowerCase() === "sandbox_high")
{
return 20;
}
return 1;
}
/** /**
* Generate many bots and store then on the cache * Generate many bots and store then on the cache
* @param condition the condition details to generate the bots with * @param condition the condition details to generate the bots with
@ -338,11 +323,11 @@ export class BotController
const pmcProfile = this.profileHelper.getPmcProfile(sessionId); const pmcProfile = this.profileHelper.getPmcProfile(sessionId);
const requestedBot = request.conditions[0]; const requestedBot = request.conditions[0];
const minimumPmcLevel = this.getMinimumPmcLevelForRaid( const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue< IGetRaidConfigurationRequestData
IGetRaidConfigurationRequestData >();
>(), const pmcLevelRangeForMap =
); this.pmcConfig.locationSpecificPmcLevelOverride[raidSettings.location.toLowerCase()];
// Create gen request for when cache is empty // Create gen request for when cache is empty
const botGenerationDetails: BotGenerationDetails = { const botGenerationDetails: BotGenerationDetails = {
@ -355,7 +340,7 @@ export class BotController
botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin, botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin,
botCountToGenerate: this.botConfig.presetBatch[requestedBot.Role], botCountToGenerate: this.botConfig.presetBatch[requestedBot.Role],
botDifficulty: requestedBot.Difficulty, botDifficulty: requestedBot.Difficulty,
minimumPmcLevel: minimumPmcLevel, locationSpecificPmcLevelOverride: pmcLevelRangeForMap,
isPlayerScav: false, isPlayerScav: false,
}; };

View File

@ -86,7 +86,6 @@ export class BotGenerator
botRelativeLevelDeltaMin: 0, botRelativeLevelDeltaMin: 0,
botCountToGenerate: 1, botCountToGenerate: 1,
botDifficulty: difficulty, botDifficulty: difficulty,
minimumPmcLevel: 1, // unused here
isPlayerScav: true, isPlayerScav: true,
}; };

View File

@ -2,7 +2,6 @@ import { inject, injectable } from "tsyringe";
import { MinMax } from "@spt-aki/models/common/MinMax"; import { MinMax } from "@spt-aki/models/common/MinMax";
import { IRandomisedBotLevelResult } from "@spt-aki/models/eft/bot/IRandomisedBotLevelResult"; import { IRandomisedBotLevelResult } from "@spt-aki/models/eft/bot/IRandomisedBotLevelResult";
import { IExpTable } from "@spt-aki/models/eft/common/IGlobals";
import { IBotBase } from "@spt-aki/models/eft/common/tables/IBotBase"; import { IBotBase } from "@spt-aki/models/eft/common/tables/IBotBase";
import { BotGenerationDetails } from "@spt-aki/models/spt/bots/BotGenerationDetails"; import { BotGenerationDetails } from "@spt-aki/models/spt/bots/BotGenerationDetails";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
@ -22,7 +21,7 @@ export class BotLevelGenerator
/** /**
* Return a randomised bot level and exp value * Return a randomised bot level and exp value
* @param levelDetails Min and max of level for bot * @param levelDetails Min and max of level for bot
* @param botGenerationDetails Deatils to help generate a bot * @param botGenerationDetails Details to help generate a bot
* @param bot Bot the level is being generated for * @param bot Bot the level is being generated for
* @returns IRandomisedBotLevelResult object * @returns IRandomisedBotLevelResult object
*/ */
@ -33,13 +32,8 @@ export class BotLevelGenerator
): IRandomisedBotLevelResult ): IRandomisedBotLevelResult
{ {
const expTable = this.databaseServer.getTables().globals.config.exp.level.exp_table; const expTable = this.databaseServer.getTables().globals.config.exp.level.exp_table;
const highestLevel = this.getHighestRelativeBotLevel( const highestLevel = this.getHighestRelativeBotLevel(botGenerationDetails, levelDetails, expTable.length);
botGenerationDetails.playerLevel, const lowestLevel = this.getLowestRelativeBotLevel(botGenerationDetails, levelDetails, expTable.length);
botGenerationDetails.botRelativeLevelDeltaMax,
levelDetails,
expTable,
);
const lowestLevel = this.getLowestRelativeBotLevel(botGenerationDetails, levelDetails, expTable);
// Get random level based on the exp table. // Get random level based on the exp table.
let exp = 0; let exp = 0;
@ -61,21 +55,22 @@ 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 * Get the highest level a bot can be relative to the players level, but no further than the max size from globals.exp_table
* @param playerLevel Players current level * @param botGenerationDetails Details to help generate a bot
* @param relativeDeltaMax max delta above player level to go * @param levelDetails
* @returns highest level possible for bot * @param maxLevel Max possible level
* @returns Highest level possible for bot
*/ */
protected getHighestRelativeBotLevel( protected getHighestRelativeBotLevel(
playerLevel: number, botGenerationDetails: BotGenerationDetails,
relativeDeltaMax: number,
levelDetails: MinMax, levelDetails: MinMax,
expTable: IExpTable[], maxLevel: number,
): number ): number
{ {
// Some bots have a max level of 1 const maxPossibleLevel = (botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride)
const maxPossibleLevel = Math.min(levelDetails.max, expTable.length); ? 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 = playerLevel + relativeDeltaMax; let level = botGenerationDetails.playerLevel + botGenerationDetails.botRelativeLevelDeltaMax;
if (level > maxPossibleLevel) if (level > maxPossibleLevel)
{ {
level = maxPossibleLevel; level = maxPossibleLevel;
@ -86,30 +81,23 @@ export class BotLevelGenerator
/** /**
* Get the lowest level a bot can be relative to the players level, but no lower than 1 * Get the lowest level a bot can be relative to the players level, but no lower than 1
* @param playerLevel Players current level * @param botGenerationDetails Details to help generate a bot
* @param relativeDeltaMin Min delta below player level to go * @param levelDetails
* @param expTable exp table to calculate level * @param maxlevel Max level allowed
* @returns lowest level possible for bot * @returns Lowest level possible for bot
*/ */
protected getLowestRelativeBotLevel( protected getLowestRelativeBotLevel(
botGenerationDetails: BotGenerationDetails, botGenerationDetails: BotGenerationDetails,
levelDetails: MinMax, levelDetails: MinMax,
expTable: IExpTable[], maxlevel: number,
): number ): number
{ {
let minPossibleLevel: number; const minPossibleLevel = (botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride)
if (botGenerationDetails.isPmc) ? Math.min(
{ Math.max(levelDetails.min, botGenerationDetails.locationSpecificPmcLevelOverride.min), // Biggest between json min and the botgen min
minPossibleLevel = Math.min( maxlevel, // Fallback if value above is crazy (default is 79)
Math.max(levelDetails.min, botGenerationDetails.minimumPmcLevel), )
expTable.length, : Math.min(levelDetails.min, maxlevel); // Not pmc with override or non-pmc
);
}
else
{
// Some bots have a max level of 1
minPossibleLevel = Math.min(levelDetails.min, expTable.length);
}
let level = botGenerationDetails.playerLevel - botGenerationDetails.botRelativeLevelDeltaMin; let level = botGenerationDetails.playerLevel - botGenerationDetails.botRelativeLevelDeltaMin;
if (level < minPossibleLevel) if (level < minPossibleLevel)

View File

@ -1,3 +1,5 @@
import { MinMax } from "@spt-aki/models/common/MinMax";
export interface BotGenerationDetails export interface BotGenerationDetails
{ {
/** Should the bot be generated as a PMC */ /** Should the bot be generated as a PMC */
@ -9,8 +11,8 @@ export interface BotGenerationDetails
/** Active players current level */ /** Active players current level */
playerLevel?: number; playerLevel?: number;
playerName?: string; playerName?: string;
/** Lowest level a PMC can be generated with */ /** Level specific overrides for PMC level */
minimumPmcLevel: number; locationSpecificPmcLevelOverride?: MinMax;
/** Delta of highest level of bot e.g. 50 means 50 levels above player */ /** Delta of highest level of bot e.g. 50 means 50 levels above player */
botRelativeLevelDeltaMax: number; botRelativeLevelDeltaMax: number;
/** Delta of lowest level of bot e.g. 50 means 50 levels below player */ /** Delta of lowest level of bot e.g. 50 means 50 levels below player */

View File

@ -48,6 +48,7 @@ export interface IPmcConfig extends IBaseConfig
/** Force a number of healing items into PMCs secure container to ensure they can heal */ /** Force a number of healing items into PMCs secure container to ensure they can heal */
forceHealingItemsIntoSecure: boolean; forceHealingItemsIntoSecure: boolean;
allPMCsHavePlayerNameWithRandomPrefixChance: number; allPMCsHavePlayerNameWithRandomPrefixChance: number;
locationSpecificPmcLevelOverride: Record<string, MinMax>;
} }
export interface PmcTypes export interface PmcTypes