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,
"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
this.botGenerationCacheService.clearStoredBots();
const minimumPmcLevel = this.getMinimumPmcLevelForRaid(
this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
IGetRaidConfigurationRequestData
>(),
);
>();
const pmcLevelRangeForMap =
this.pmcConfig.locationSpecificPmcLevelOverride[raidSettings?.location.toLowerCase()];
const allPmcsHaveSameNameAsPlayer = this.randomUtil.getChance100(
this.pmcConfig.allPMCsHavePlayerNameWithRandomPrefixChance,
@ -231,7 +231,7 @@ export class BotController
botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin,
botCountToGenerate: this.botConfig.presetBatch[condition.Role],
botDifficulty: condition.Difficulty,
minimumPmcLevel: minimumPmcLevel,
locationSpecificPmcLevelOverride: pmcLevelRangeForMap,
isPlayerScav: false,
allPmcsHaveSameNameAsPlayer: allPmcsHaveSameNameAsPlayer,
};
@ -244,21 +244,6 @@ export class BotController
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
* @param condition the condition details to generate the bots with
@ -338,11 +323,11 @@ export class BotController
const pmcProfile = this.profileHelper.getPmcProfile(sessionId);
const requestedBot = request.conditions[0];
const minimumPmcLevel = this.getMinimumPmcLevelForRaid(
this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
IGetRaidConfigurationRequestData
>(),
);
>();
const pmcLevelRangeForMap =
this.pmcConfig.locationSpecificPmcLevelOverride[raidSettings.location.toLowerCase()];
// Create gen request for when cache is empty
const botGenerationDetails: BotGenerationDetails = {
@ -355,7 +340,7 @@ export class BotController
botRelativeLevelDeltaMin: this.pmcConfig.botRelativeLevelDeltaMin,
botCountToGenerate: this.botConfig.presetBatch[requestedBot.Role],
botDifficulty: requestedBot.Difficulty,
minimumPmcLevel: minimumPmcLevel,
locationSpecificPmcLevelOverride: pmcLevelRangeForMap,
isPlayerScav: false,
};

View File

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

View File

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

View File

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