From 82de7c097d3c5812fbd6b7a3e70eba0362deba1f Mon Sep 17 00:00:00 2001 From: Dev Date: Tue, 1 Aug 2023 12:51:40 +0100 Subject: [PATCH] Replace old "evil x" pmc name system with v2 --- project/assets/configs/bot.json | 3 ++- project/src/controllers/GameController.ts | 5 +---- project/src/generators/BotGenerator.ts | 25 +++++++++++++++++---- project/src/models/spt/config/IPmcConfig.ts | 1 + project/src/services/LocalisationService.ts | 15 +++++++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) diff --git a/project/assets/configs/bot.json b/project/assets/configs/bot.json index db19423d..729ea67b 100644 --- a/project/assets/configs/bot.json +++ b/project/assets/configs/bot.json @@ -1556,7 +1556,8 @@ } }, "enemyTypes": ["assault", "marksman", "pmcBot", "bossBully", "bossKilla", "bossKojaniy", "bossGluhar", "bossSanitar", "bossTagilla", "bossKnight", "bossZryachiy", "followerBully", "followerKojaniy", "followerGluharAssault", "followerGluharSecurity", "followerGluharScout", "followerGluharSnipe", "followerSanitar", "followerBirdEye", "followerBigPipe", "followerZryachiy", "sectantWarrior", "sectantPriest"], - "forceHealingItemsIntoSecure": true + "forceHealingItemsIntoSecure": true, + "addPrefixToSameNamePMCAsPlayerChance": 40 }, "showTypeInNickname": false, "maxBotCap": { diff --git a/project/src/controllers/GameController.ts b/project/src/controllers/GameController.ts index a397197d..cea930bd 100644 --- a/project/src/controllers/GameController.ts +++ b/project/src/controllers/GameController.ts @@ -642,12 +642,11 @@ export class GameController /** * Add the logged in players name to PMC name pool - * @param pmcProfile + * @param pmcProfile Profile of player to get name from */ protected addPlayerToPMCNames(pmcProfile: IPmcData): void { const playerName = pmcProfile.Info.Nickname; - if (playerName) { const bots = this.databaseServer.getTables().bots.types; @@ -655,13 +654,11 @@ export class GameController if (bots["bear"]) { bots["bear"].firstName.push(playerName); - bots["bear"].firstName.push(`Evil ${playerName}`); } if (bots["usec"]) { bots["usec"].firstName.push(playerName); - bots["usec"].firstName.push(`Evil ${playerName}`); } } } diff --git a/project/src/generators/BotGenerator.ts b/project/src/generators/BotGenerator.ts index 23708378..5a7bc0f3 100644 --- a/project/src/generators/BotGenerator.ts +++ b/project/src/generators/BotGenerator.ts @@ -21,6 +21,7 @@ import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; import { DatabaseServer } from "../servers/DatabaseServer"; import { BotEquipmentFilterService } from "../services/BotEquipmentFilterService"; +import { LocalisationService } from "../services/LocalisationService"; import { SeasonalEventService } from "../services/SeasonalEventService"; import { HashUtil } from "../utils/HashUtil"; import { JsonUtil } from "../utils/JsonUtil"; @@ -49,6 +50,7 @@ export class BotGenerator @inject("BotHelper") protected botHelper: BotHelper, @inject("BotDifficultyHelper") protected botDifficultyHelper: BotDifficultyHelper, @inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService, + @inject("LocalisationService") protected localisationService: LocalisationService, @inject("ConfigServer") protected configServer: ConfigServer ) { @@ -145,7 +147,7 @@ export class BotGenerator this.botEquipmentFilterService.filterBotEquipment(botJsonTemplate, botLevel.level, botGenerationDetails); } - bot.Info.Nickname = this.generateBotNickname(botJsonTemplate, botGenerationDetails.isPlayerScav, botRole); + bot.Info.Nickname = this.generateBotNickname(botJsonTemplate, botGenerationDetails.isPlayerScav, botRole, sessionId); const skipChristmasItems = !this.seasonalEventService.christmasEventEnabled(); if (skipChristmasItems) @@ -194,9 +196,11 @@ export class BotGenerator * @param botRole role of bot e.g. assault * @returns Nickname for bot */ - protected generateBotNickname(botJsonTemplate: IBotType, isPlayerScav: boolean, botRole: string): string + protected generateBotNickname(botJsonTemplate: IBotType, isPlayerScav: boolean, botRole: string, sessionId: string): string { let name = `${this.randomUtil.getArrayValue(botJsonTemplate.firstName)} ${this.randomUtil.getArrayValue(botJsonTemplate.lastName) || ""}`; + name = name.trim(); + const playerProfile = this.profileHelper.getPmcProfile(sessionId); // Simulate bot looking like a Player scav with the pmc name in brackets if (botRole === "assault" && this.randomUtil.getChance100(this.botConfig.chanceAssaultScavHasPlayerScavName)) @@ -208,17 +212,30 @@ export class BotGenerator const pmcNames = [ ...this.databaseServer.getTables().bots.types["usec"].firstName, - ...this.databaseServer.getTables().bots.types["bear"].firstName]; + ...this.databaseServer.getTables().bots.types["bear"].firstName + ]; return `${name} (${this.randomUtil.getArrayValue(pmcNames)})`; } + if (this.botConfig.showTypeInNickname && !isPlayerScav) { name += ` ${botRole}`; } - return name.trim(); + // If bot name matches current players name, chance to add localised prefix to name + if (name.toLowerCase() === playerProfile.Info.Nickname.toLowerCase()) + { + if (this.randomUtil.getChance100(this.botConfig.pmc.addPrefixToSameNamePMCAsPlayerChance)) + { + + const prefix = this.localisationService.getRandomTextThatMatchesPartialKey("pmc-name_prefix_"); + name = `${prefix} ${name}`; + } + } + + return name; } /** diff --git a/project/src/models/spt/config/IPmcConfig.ts b/project/src/models/spt/config/IPmcConfig.ts index 0c28f633..1f10ae40 100644 --- a/project/src/models/spt/config/IPmcConfig.ts +++ b/project/src/models/spt/config/IPmcConfig.ts @@ -42,6 +42,7 @@ export interface IPmcConfig botRelativeLevelDeltaMax: number /** Force a number of healing items into PMCs secure container to ensure they can heal */ forceHealingItemsIntoSecure: boolean; + addPrefixToSameNamePMCAsPlayerChance: number; } export interface PmcTypes diff --git a/project/src/services/LocalisationService.ts b/project/src/services/LocalisationService.ts index 2e52e430..240cb854 100644 --- a/project/src/services/LocalisationService.ts +++ b/project/src/services/LocalisationService.ts @@ -4,6 +4,7 @@ import { inject, injectable } from "tsyringe"; import { ILocaleConfig } from "../models/spt/config/ILocaleConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { RandomUtil } from "../utils/RandomUtil"; import { LocaleService } from "./LocaleService"; /** @@ -17,6 +18,7 @@ export class LocalisationService constructor( @inject("WinstonLogger") protected logger: ILogger, + @inject("RandomUtil") protected randomUtil: RandomUtil, @inject("DatabaseServer") protected databaseServer: DatabaseServer, @inject("LocaleService") protected localeService: LocaleService ) @@ -53,4 +55,17 @@ export class LocalisationService { return Object.keys(this.databaseServer.getTables().locales.server["en"]); } + + /** + * From the provided partial key, find all keys that start with text and choose a random match + * @param partialKey Key to match locale keys on + * @returns locale text + */ + public getRandomTextThatMatchesPartialKey(partialKey: string): string + { + const filteredKeys = Object.keys(this.databaseServer.getTables().locales.server["en"]).filter(x => x.startsWith(partialKey)); + const chosenKey = this.randomUtil.getArrayValue(filteredKeys); + + return this.getText(chosenKey); + } } \ No newline at end of file