Loosened bot name limit to 19 characters

Moved value into config
Added `botConfig.botRolesThatMustHaveUniqueName`

Refactored `getPmcNicknameOfMaxLength()`, removed all recursion + handles when no name is below desired length
Refactored `generateUniqueBotNickname()` to handle PMC names differently, use centralised pmc name function

Updated ragfair to utilise maxlength value from bot config
This commit is contained in:
Dev 2024-10-18 11:39:51 +01:00
parent d2239db64b
commit 9c58e2e0e5
8 changed files with 61 additions and 31 deletions

View File

@ -2835,5 +2835,7 @@
"max": 100
}
}
}
},
"botNameLengthLimit": 19,
"botRolesThatMustHaveUniqueName": ["assault", "pmcusec", "pmcbear"]
}

View File

@ -910,7 +910,7 @@ export class GameController {
const bots = this.databaseService.getBots().types;
// Official names can only be 15 chars in length
if (playerName.length > 15) {
if (playerName.length > this.botConfig.botNameLengthLimit) {
return;
}

View File

@ -152,7 +152,7 @@ export class BotGenerator {
botJsonTemplate: IBotType,
botGenerationDetails: BotGenerationDetails,
): IBotBase {
const botRole = botGenerationDetails.role.toLowerCase();
const botRoleLowercase = botGenerationDetails.role.toLowerCase();
const botLevel = this.botLevelGenerator.generateBotLevel(
botJsonTemplate.experience.level,
botGenerationDetails,
@ -169,12 +169,10 @@ export class BotGenerator {
}
bot.Info.Nickname = this.botNameService.generateUniqueBotNickname(
botJsonTemplate.firstName,
botJsonTemplate.lastName,
botJsonTemplate,
botGenerationDetails,
botRole,
["assault", "pmcusec", "pmcbear"],
sessionId,
botRoleLowercase,
this.botConfig.botRolesThatMustHaveUniqueName,
);
if (!this.seasonalEventService.christmasEventEnabled()) {
@ -213,18 +211,19 @@ export class BotGenerator {
}
}
// Add drip
this.setBotAppearance(bot, botJsonTemplate.appearance, botGenerationDetails);
bot.Inventory = this.botInventoryGenerator.generateInventory(
sessionId,
botJsonTemplate,
botRole,
botRoleLowercase,
botGenerationDetails.isPmc,
botLevel.level,
bot.Info.GameVersion,
);
if (this.botConfig.botRolesWithDogTags.includes(botRole)) {
if (this.botConfig.botRolesWithDogTags.includes(botRoleLowercase)) {
this.addDogtagToBot(bot);
}

View File

@ -14,6 +14,7 @@ import { BaseClasses } from "@spt/models/enums/BaseClasses";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { MemberCategory } from "@spt/models/enums/MemberCategory";
import { Money } from "@spt/models/enums/Money";
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
import {
Condition,
Dynamic,
@ -37,6 +38,7 @@ import { inject, injectable } from "tsyringe";
@injectable()
export class RagfairOfferGenerator {
protected ragfairConfig: IRagfairConfig;
protected botConfig: IBotConfig;
protected allowedFleaPriceItemsForBarter: { tpl: string; price: number }[];
/** Internal counter to ensure each offer created has a unique value for its intId property */
@ -65,6 +67,7 @@ export class RagfairOfferGenerator {
@inject("PrimaryCloner") protected cloner: ICloner,
) {
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
this.botConfig = this.configServer.getConfig(ConfigTypes.BOT);
}
/**
@ -192,11 +195,11 @@ export class RagfairOfferGenerator {
};
}
// Regular old fake pmc offer
// Fake pmc offer
return {
id: userID,
memberType: MemberCategory.DEFAULT,
nickname: this.botHelper.getPmcNicknameOfMaxLength(userID, 50),
nickname: this.botHelper.getPmcNicknameOfMaxLength(this.botConfig.botNameLengthLimit),
rating: this.randomUtil.getFloat(
this.ragfairConfig.dynamic.rating.min,
this.ragfairConfig.dynamic.rating.max,

View File

@ -7,6 +7,7 @@ import { ILogger } from "@spt/models/spt/utils/ILogger";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { DatabaseService } from "@spt/services/DatabaseService";
import { RandomUtil } from "@spt/utils/RandomUtil";
import { max } from "date-fns";
import { inject, injectable } from "tsyringe";
@injectable()
@ -168,10 +169,24 @@ export class BotHelper {
return this.randomUtil.getChance100(this.pmcConfig.isUsec) ? "Usec" : "Bear";
}
public getPmcNicknameOfMaxLength(userId: string, maxLength: number): string {
// recurivse if name is longer than max characters allowed (15 characters)
const randomType = this.randomUtil.getInt(0, 1) === 0 ? "usec" : "bear";
const name = this.randomUtil.getStringArrayValue(this.databaseService.getBots().types[randomType].firstName);
return name.length > maxLength ? this.getPmcNicknameOfMaxLength(userId, maxLength) : name;
/**
* Get a name from a PMC that fits the desired length
* @param maxLength Max length of name, inclusive
* @param side OPTIONAL - what side PMC to get name from (usec/bear)
* @returns name of PMC
*/
public getPmcNicknameOfMaxLength(maxLength: number, side?: string): string {
const randomType = side ? side : this.randomUtil.getInt(0, 1) === 0 ? "usec" : "bear";
const allNames = this.databaseService.getBots().types[randomType].firstName;
const filteredNames = allNames.filter((name) => name.length <= maxLength);
if (filteredNames.length === 0) {
this.logger.warning(
`Unable to filter: ${randomType} PMC names to only those under: ${maxLength}, none found that match that criteria, selecting from entire name pool instead`,
);
return this.randomUtil.getStringArrayValue(allNames);
}
return this.randomUtil.getStringArrayValue(filteredNames);
}
}

View File

@ -21,6 +21,7 @@ import { MemberCategory } from "@spt/models/enums/MemberCategory";
import { MessageType } from "@spt/models/enums/MessageType";
import { RagfairSort } from "@spt/models/enums/RagfairSort";
import { Traders } from "@spt/models/enums/Traders";
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig";
import { IRagfairConfig, ITieredFlea } from "@spt/models/spt/config/IRagfairConfig";
import { ILogger } from "@spt/models/spt/utils/ILogger";
@ -42,6 +43,7 @@ export class RagfairOfferHelper {
protected static goodSoldTemplate = "5bdabfb886f7743e152e867e 0"; // Your {soldItem} {itemCount} items were bought by {buyerNickname}.
protected ragfairConfig: IRagfairConfig;
protected questConfig: IQuestConfig;
protected botConfig: IBotConfig;
constructor(
@inject("PrimaryLogger") protected logger: ILogger,
@ -69,6 +71,7 @@ export class RagfairOfferHelper {
) {
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
this.questConfig = this.configServer.getConfig(ConfigTypes.QUEST);
this.botConfig = this.configServer.getConfig(ConfigTypes.BOT);
}
/**
@ -565,7 +568,7 @@ export class RagfairOfferHelper {
// Used to replace tokens in sold message sent to player
const tplVars: ISystemData = {
soldItem: globalLocales[`${itemTpl} Name`] || itemTpl,
buyerNickname: this.botHelper.getPmcNicknameOfMaxLength(this.hashUtil.generate(), 15),
buyerNickname: this.botHelper.getPmcNicknameOfMaxLength(this.botConfig.botNameLengthLimit),
itemCount: boughtAmount,
};

View File

@ -45,6 +45,10 @@ export interface IBotConfig extends IBaseConfig {
/** What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/ */
disableLootOnBotTypes: string[];
assaultToBossConversion: IAssaultToBossConversion;
/** Max length a bots name can be */
botNameLengthLimit: number;
/** Bot roles that must have a unique name when generated vs other bots in raid */
botRolesThatMustHaveUniqueName: string[];
}
export interface IAssaultToBossConversion {

View File

@ -1,4 +1,6 @@
import { BotHelper } from "@spt/helpers/BotHelper";
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
import { IBotType } from "@spt/models/eft/common/tables/IBotType";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails";
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
@ -21,6 +23,7 @@ export class BotNameService {
@inject("PrimaryLogger") protected logger: ILogger,
@inject("RandomUtil") protected randomUtil: RandomUtil,
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("BotHelper") protected botHelper: BotHelper,
@inject("DatabaseService") protected databaseService: DatabaseService,
@inject("LocalisationService") protected localisationService: LocalisationService,
@inject("ConfigServer") protected configServer: ConfigServer,
@ -41,8 +44,7 @@ export class BotNameService {
/**
* Create a unique bot nickname
* @param firstNames FIRST names to choose from
* @param lastNames OPTIONAL: Names to choose from
* @param botJsonTemplate bot JSON data from db
* @param botGenerationDetails
* @param botRole role of bot e.g. assault
* @param uniqueRoles Lowercase roles to always make unique
@ -50,22 +52,24 @@ export class BotNameService {
* @returns Nickname for bot
*/
public generateUniqueBotNickname(
firstNames: string[],
lastNames: string[],
botJsonTemplate: IBotType,
botGenerationDetails: BotGenerationDetails,
botRole: string,
uniqueRoles?: string[],
sessionId?: string,
): string {
const isPmc = botGenerationDetails.isPmc;
const isPlayerScav = botGenerationDetails.isPlayerScav;
const simulateScavName = isPlayerScav ? false : this.shouldSimulatePlayerScavName(botRole);
const showTypeInNickname = this.botConfig.showTypeInNickname && !isPlayerScav;
const roleShouldBeUnique = uniqueRoles.includes(botRole.toLowerCase());
let isUnique = true;
let attempts = 0;
while (attempts <= 5) {
const isPlayerScav = botGenerationDetails.isPlayerScav;
const simulateScavName = isPlayerScav ? false : this.shouldSimulatePlayerScavName(botRole);
// Get basic name with no whitespace trimmed off sides
let name = `${this.randomUtil.getArrayValue(firstNames)} ${this.randomUtil.getArrayValue(lastNames) || ""}`;
// Get bot name with leading/trailing whitespace removed
let name = isPmc // Explicit handling of PMCs, all other bots will get "first_name last_name"
? this.botHelper.getPmcNicknameOfMaxLength(this.botConfig.botNameLengthLimit, botGenerationDetails.side)
: `${this.randomUtil.getArrayValue(botJsonTemplate.firstName)} ${this.randomUtil.getArrayValue(botJsonTemplate.lastName) || ""}`;
name = name.trim();
// Simulate bot looking like a player scav with the PMC name in brackets.
@ -75,7 +79,7 @@ export class BotNameService {
}
// Config is set to add role to end of bot name
if (this.botConfig.showTypeInNickname && !isPlayerScav) {
if (showTypeInNickname) {
name += ` ${botRole}`;
}
@ -86,7 +90,7 @@ export class BotNameService {
}
// Is this a role that must be unique
if (uniqueRoles.includes(botRole.toLowerCase())) {
if (roleShouldBeUnique) {
// Check name in cache
isUnique = !this.usedNameCache.has(name);
if (!isUnique) {