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:
parent
d2239db64b
commit
9c58e2e0e5
@ -2835,5 +2835,7 @@
|
|||||||
"max": 100
|
"max": 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"botNameLengthLimit": 19,
|
||||||
|
"botRolesThatMustHaveUniqueName": ["assault", "pmcusec", "pmcbear"]
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,7 @@ export class GameController {
|
|||||||
const bots = this.databaseService.getBots().types;
|
const bots = this.databaseService.getBots().types;
|
||||||
|
|
||||||
// Official names can only be 15 chars in length
|
// Official names can only be 15 chars in length
|
||||||
if (playerName.length > 15) {
|
if (playerName.length > this.botConfig.botNameLengthLimit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ export class BotGenerator {
|
|||||||
botJsonTemplate: IBotType,
|
botJsonTemplate: IBotType,
|
||||||
botGenerationDetails: BotGenerationDetails,
|
botGenerationDetails: BotGenerationDetails,
|
||||||
): IBotBase {
|
): IBotBase {
|
||||||
const botRole = botGenerationDetails.role.toLowerCase();
|
const botRoleLowercase = botGenerationDetails.role.toLowerCase();
|
||||||
const botLevel = this.botLevelGenerator.generateBotLevel(
|
const botLevel = this.botLevelGenerator.generateBotLevel(
|
||||||
botJsonTemplate.experience.level,
|
botJsonTemplate.experience.level,
|
||||||
botGenerationDetails,
|
botGenerationDetails,
|
||||||
@ -169,12 +169,10 @@ export class BotGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bot.Info.Nickname = this.botNameService.generateUniqueBotNickname(
|
bot.Info.Nickname = this.botNameService.generateUniqueBotNickname(
|
||||||
botJsonTemplate.firstName,
|
botJsonTemplate,
|
||||||
botJsonTemplate.lastName,
|
|
||||||
botGenerationDetails,
|
botGenerationDetails,
|
||||||
botRole,
|
botRoleLowercase,
|
||||||
["assault", "pmcusec", "pmcbear"],
|
this.botConfig.botRolesThatMustHaveUniqueName,
|
||||||
sessionId,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this.seasonalEventService.christmasEventEnabled()) {
|
if (!this.seasonalEventService.christmasEventEnabled()) {
|
||||||
@ -213,18 +211,19 @@ export class BotGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add drip
|
||||||
this.setBotAppearance(bot, botJsonTemplate.appearance, botGenerationDetails);
|
this.setBotAppearance(bot, botJsonTemplate.appearance, botGenerationDetails);
|
||||||
|
|
||||||
bot.Inventory = this.botInventoryGenerator.generateInventory(
|
bot.Inventory = this.botInventoryGenerator.generateInventory(
|
||||||
sessionId,
|
sessionId,
|
||||||
botJsonTemplate,
|
botJsonTemplate,
|
||||||
botRole,
|
botRoleLowercase,
|
||||||
botGenerationDetails.isPmc,
|
botGenerationDetails.isPmc,
|
||||||
botLevel.level,
|
botLevel.level,
|
||||||
bot.Info.GameVersion,
|
bot.Info.GameVersion,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.botConfig.botRolesWithDogTags.includes(botRole)) {
|
if (this.botConfig.botRolesWithDogTags.includes(botRoleLowercase)) {
|
||||||
this.addDogtagToBot(bot);
|
this.addDogtagToBot(bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
import { MemberCategory } from "@spt/models/enums/MemberCategory";
|
import { MemberCategory } from "@spt/models/enums/MemberCategory";
|
||||||
import { Money } from "@spt/models/enums/Money";
|
import { Money } from "@spt/models/enums/Money";
|
||||||
|
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
||||||
import {
|
import {
|
||||||
Condition,
|
Condition,
|
||||||
Dynamic,
|
Dynamic,
|
||||||
@ -37,6 +38,7 @@ import { inject, injectable } from "tsyringe";
|
|||||||
@injectable()
|
@injectable()
|
||||||
export class RagfairOfferGenerator {
|
export class RagfairOfferGenerator {
|
||||||
protected ragfairConfig: IRagfairConfig;
|
protected ragfairConfig: IRagfairConfig;
|
||||||
|
protected botConfig: IBotConfig;
|
||||||
protected allowedFleaPriceItemsForBarter: { tpl: string; price: number }[];
|
protected allowedFleaPriceItemsForBarter: { tpl: string; price: number }[];
|
||||||
|
|
||||||
/** Internal counter to ensure each offer created has a unique value for its intId property */
|
/** 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,
|
@inject("PrimaryCloner") protected cloner: ICloner,
|
||||||
) {
|
) {
|
||||||
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
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 {
|
return {
|
||||||
id: userID,
|
id: userID,
|
||||||
memberType: MemberCategory.DEFAULT,
|
memberType: MemberCategory.DEFAULT,
|
||||||
nickname: this.botHelper.getPmcNicknameOfMaxLength(userID, 50),
|
nickname: this.botHelper.getPmcNicknameOfMaxLength(this.botConfig.botNameLengthLimit),
|
||||||
rating: this.randomUtil.getFloat(
|
rating: this.randomUtil.getFloat(
|
||||||
this.ragfairConfig.dynamic.rating.min,
|
this.ragfairConfig.dynamic.rating.min,
|
||||||
this.ragfairConfig.dynamic.rating.max,
|
this.ragfairConfig.dynamic.rating.max,
|
||||||
|
@ -7,6 +7,7 @@ import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
import { RandomUtil } from "@spt/utils/RandomUtil";
|
||||||
|
import { max } from "date-fns";
|
||||||
import { inject, injectable } from "tsyringe";
|
import { inject, injectable } from "tsyringe";
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
@ -168,10 +169,24 @@ export class BotHelper {
|
|||||||
return this.randomUtil.getChance100(this.pmcConfig.isUsec) ? "Usec" : "Bear";
|
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)
|
* Get a name from a PMC that fits the desired length
|
||||||
const randomType = this.randomUtil.getInt(0, 1) === 0 ? "usec" : "bear";
|
* @param maxLength Max length of name, inclusive
|
||||||
const name = this.randomUtil.getStringArrayValue(this.databaseService.getBots().types[randomType].firstName);
|
* @param side OPTIONAL - what side PMC to get name from (usec/bear)
|
||||||
return name.length > maxLength ? this.getPmcNicknameOfMaxLength(userId, maxLength) : name;
|
* @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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import { MemberCategory } from "@spt/models/enums/MemberCategory";
|
|||||||
import { MessageType } from "@spt/models/enums/MessageType";
|
import { MessageType } from "@spt/models/enums/MessageType";
|
||||||
import { RagfairSort } from "@spt/models/enums/RagfairSort";
|
import { RagfairSort } from "@spt/models/enums/RagfairSort";
|
||||||
import { Traders } from "@spt/models/enums/Traders";
|
import { Traders } from "@spt/models/enums/Traders";
|
||||||
|
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
||||||
import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig";
|
import { IQuestConfig } from "@spt/models/spt/config/IQuestConfig";
|
||||||
import { IRagfairConfig, ITieredFlea } from "@spt/models/spt/config/IRagfairConfig";
|
import { IRagfairConfig, ITieredFlea } from "@spt/models/spt/config/IRagfairConfig";
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
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 static goodSoldTemplate = "5bdabfb886f7743e152e867e 0"; // Your {soldItem} {itemCount} items were bought by {buyerNickname}.
|
||||||
protected ragfairConfig: IRagfairConfig;
|
protected ragfairConfig: IRagfairConfig;
|
||||||
protected questConfig: IQuestConfig;
|
protected questConfig: IQuestConfig;
|
||||||
|
protected botConfig: IBotConfig;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
@inject("PrimaryLogger") protected logger: ILogger,
|
||||||
@ -69,6 +71,7 @@ export class RagfairOfferHelper {
|
|||||||
) {
|
) {
|
||||||
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
||||||
this.questConfig = this.configServer.getConfig(ConfigTypes.QUEST);
|
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
|
// Used to replace tokens in sold message sent to player
|
||||||
const tplVars: ISystemData = {
|
const tplVars: ISystemData = {
|
||||||
soldItem: globalLocales[`${itemTpl} Name`] || itemTpl,
|
soldItem: globalLocales[`${itemTpl} Name`] || itemTpl,
|
||||||
buyerNickname: this.botHelper.getPmcNicknameOfMaxLength(this.hashUtil.generate(), 15),
|
buyerNickname: this.botHelper.getPmcNicknameOfMaxLength(this.botConfig.botNameLengthLimit),
|
||||||
itemCount: boughtAmount,
|
itemCount: boughtAmount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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/ */
|
/** What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/ */
|
||||||
disableLootOnBotTypes: string[];
|
disableLootOnBotTypes: string[];
|
||||||
assaultToBossConversion: IAssaultToBossConversion;
|
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 {
|
export interface IAssaultToBossConversion {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
import { BotHelper } from "@spt/helpers/BotHelper";
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||||
|
import { IBotType } from "@spt/models/eft/common/tables/IBotType";
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails";
|
import { BotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails";
|
||||||
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
||||||
@ -21,6 +23,7 @@ export class BotNameService {
|
|||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
@inject("PrimaryLogger") protected logger: ILogger,
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||||
|
@inject("BotHelper") protected botHelper: BotHelper,
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
@inject("DatabaseService") protected databaseService: DatabaseService,
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
@inject("LocalisationService") protected localisationService: LocalisationService,
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||||
@ -41,8 +44,7 @@ export class BotNameService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a unique bot nickname
|
* Create a unique bot nickname
|
||||||
* @param firstNames FIRST names to choose from
|
* @param botJsonTemplate bot JSON data from db
|
||||||
* @param lastNames OPTIONAL: Names to choose from
|
|
||||||
* @param botGenerationDetails
|
* @param botGenerationDetails
|
||||||
* @param botRole role of bot e.g. assault
|
* @param botRole role of bot e.g. assault
|
||||||
* @param uniqueRoles Lowercase roles to always make unique
|
* @param uniqueRoles Lowercase roles to always make unique
|
||||||
@ -50,22 +52,24 @@ export class BotNameService {
|
|||||||
* @returns Nickname for bot
|
* @returns Nickname for bot
|
||||||
*/
|
*/
|
||||||
public generateUniqueBotNickname(
|
public generateUniqueBotNickname(
|
||||||
firstNames: string[],
|
botJsonTemplate: IBotType,
|
||||||
lastNames: string[],
|
|
||||||
botGenerationDetails: BotGenerationDetails,
|
botGenerationDetails: BotGenerationDetails,
|
||||||
botRole: string,
|
botRole: string,
|
||||||
uniqueRoles?: string[],
|
uniqueRoles?: string[],
|
||||||
sessionId?: string,
|
|
||||||
): string {
|
): string {
|
||||||
let isUnique = true;
|
const isPmc = botGenerationDetails.isPmc;
|
||||||
let attempts = 0;
|
|
||||||
|
|
||||||
while (attempts <= 5) {
|
|
||||||
const isPlayerScav = botGenerationDetails.isPlayerScav;
|
const isPlayerScav = botGenerationDetails.isPlayerScav;
|
||||||
const simulateScavName = isPlayerScav ? false : this.shouldSimulatePlayerScavName(botRole);
|
const simulateScavName = isPlayerScav ? false : this.shouldSimulatePlayerScavName(botRole);
|
||||||
|
const showTypeInNickname = this.botConfig.showTypeInNickname && !isPlayerScav;
|
||||||
|
const roleShouldBeUnique = uniqueRoles.includes(botRole.toLowerCase());
|
||||||
|
|
||||||
// Get basic name with no whitespace trimmed off sides
|
let isUnique = true;
|
||||||
let name = `${this.randomUtil.getArrayValue(firstNames)} ${this.randomUtil.getArrayValue(lastNames) || ""}`;
|
let attempts = 0;
|
||||||
|
while (attempts <= 5) {
|
||||||
|
// 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();
|
name = name.trim();
|
||||||
|
|
||||||
// Simulate bot looking like a player scav with the PMC name in brackets.
|
// 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
|
// Config is set to add role to end of bot name
|
||||||
if (this.botConfig.showTypeInNickname && !isPlayerScav) {
|
if (showTypeInNickname) {
|
||||||
name += ` ${botRole}`;
|
name += ` ${botRole}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +90,7 @@ export class BotNameService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is this a role that must be unique
|
// Is this a role that must be unique
|
||||||
if (uniqueRoles.includes(botRole.toLowerCase())) {
|
if (roleShouldBeUnique) {
|
||||||
// Check name in cache
|
// Check name in cache
|
||||||
isUnique = !this.usedNameCache.has(name);
|
isUnique = !this.usedNameCache.has(name);
|
||||||
if (!isUnique) {
|
if (!isUnique) {
|
||||||
|
Loading…
Reference in New Issue
Block a user