using Core.Annotations; using Core.Models.Common; using Core.Models.Eft.Common.Tables; using Core.Models.Eft.Match; using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Servers; using Core.Services; using Core.Utils; using ILogger = Core.Models.Utils.ILogger; namespace Core.Helpers; [Injectable] public class BotHelper { private readonly ILogger _logger; private readonly DatabaseService _databaseService; private readonly RandomUtil _randomUtil; private readonly ConfigServer _configServer; private readonly BotConfig _botConfig; private readonly PmcConfig _pmcConfig; private readonly List _pmcNames = ["usec", "bear", "pmc", "pmcbear", "pmcusec"]; public BotHelper ( ILogger logger, DatabaseService databaseService, RandomUtil randomUtil, ConfigServer configServer ) { _logger = logger; _databaseService = databaseService; _randomUtil = randomUtil; _configServer = configServer; _botConfig = configServer.GetConfig(); _pmcConfig = configServer.GetConfig(); } /// /// Get a template object for the specified botRole from bots.types db /// /// botRole to get template for /// BotType object public BotType GetBotTemplate(string role) { if (!_databaseService.GetBots().Types.TryGetValue(role.ToLower(), out var bot)) { _logger.Error($"Unable to get bot of type: {role} from DB"); return null; } return bot; } /// /// Is the passed in bot role a PMC (usec/bear/pmc) /// /// bot role to check /// true if is pmc public bool IsBotPmc(string botRole) { return _pmcNames.Contains(botRole?.ToLower()); } public bool IsBotBoss(string botRole) { return _botConfig.Bosses.Any(x => x.ToLower() == botRole.ToLower()); } public bool IsBotFollower(string botRole) { return botRole?.ToLower().StartsWith("follower") ?? false; } /// /// Add a bot to the FRIENDLY_BOT_TYPES list /// /// bot settings to alter /// bot type to add to friendly list public void AddBotToFriendlyList(DifficultyCategories difficultySettings, string typeToAdd) { var friendlyBotTypesKey = "FRIENDLY_BOT_TYPES"; // Null guard if (difficultySettings.Mind[friendlyBotTypesKey] is null) { difficultySettings.Mind[friendlyBotTypesKey] = new List(); } ((List)difficultySettings.Mind[friendlyBotTypesKey]).Add(typeToAdd); } /// /// Add a bot to the REVENGE_BOT_TYPES list /// /// bot settings to alter /// bot type to add to revenge list public void AddBotToRevengeList(DifficultyCategories difficultySettings, string[] typesToAdd) { var revengePropKey = "REVENGE_BOT_TYPES"; // Nothing to add if (typesToAdd is null) { return; } // Null guard if (difficultySettings.Mind[revengePropKey] is null) { difficultySettings.Mind[revengePropKey] = new List(); } var revengeArray = (List)difficultySettings.Mind[revengePropKey]; foreach (var botTypeToAdd in typesToAdd) { if (!revengeArray.Contains(botTypeToAdd)) { revengeArray.Add(botTypeToAdd); } } } public bool RollChanceToBePmc(MinMax botConvertMinMax) { return _randomUtil.GetChance100(_randomUtil.GetInt((int)botConvertMinMax.Min, (int)botConvertMinMax.Max)); } protected Dictionary GetPmcConversionValuesForLocation(string location) { var result = _pmcConfig.ConvertIntoPmcChance[location.ToLower()]; if (result is null) { _pmcConfig.ConvertIntoPmcChance = new(); } return result; } /// /// is the provided role a PMC, case-agnostic /// /// Role to check /// True if role is PMC public bool BotRoleIsPmc(string botRole) { List ListToCheck = [_pmcConfig.UsecType.ToLower(), _pmcConfig.BearType.ToLower()]; return ListToCheck.Contains( botRole.ToLower() ); } /// /// Get randomization settings for bot from config/bot.json /// /// level of bot /// bot equipment json /// RandomisationDetails public RandomisationDetails GetBotRandomizationDetails(int botLevel, EquipmentFilters botEquipConfig) { // No randomisation details found, skip if (botEquipConfig is null || botEquipConfig.Randomisation is null) { return null; } return botEquipConfig.Randomisation.FirstOrDefault( (randDetails) => botLevel >= randDetails.LevelRange.Min && botLevel <= randDetails.LevelRange.Max ); } /// /// Choose between pmcBEAR and pmcUSEC at random based on the % defined in pmcConfig.isUsec /// /// pmc role public string GetRandomizedPmcRole() { return _randomUtil.GetChance100(_pmcConfig.IsUsec) ? _pmcConfig.UsecType : _pmcConfig.BearType; } /// /// Get the corresponding side when pmcBEAR or pmcUSEC is passed in /// /// role to get side for /// side (usec/bear) public string GetPmcSideByRole(string botRole) { if (_pmcConfig.BearType.ToLower() == botRole.ToLower()) return "Bear"; if (_pmcConfig.UsecType.ToLower() == botRole.ToLower()) return "Usec"; return GetRandomizedPmcSide(); } /// /// Get a randomized PMC side based on bot config value 'isUsec' /// /// pmc side as string protected string GetRandomizedPmcSide() { return _randomUtil.GetChance100(_pmcConfig.IsUsec) ? "Usec" : "Bear"; } /// /// Get a name from a PMC that fits the desired length /// /// Max length of name, inclusive /// OPTIONAL - what side PMC to get name from (usec/bear) /// name of PMC public string GetPmcNicknameOfMaxLength(int maxLength, string side = null) { var randomType = (side is not null) ? side : (_randomUtil.GetInt(0, 1) == 0) ? "usec" : "bear"; var allNames = _databaseService.GetBots().Types[randomType.ToLower()].FirstNames; var filteredNames = allNames.Where((name) => name.Length <= maxLength); if (filteredNames.Count() == 0) { _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`,\n"); return _randomUtil.GetStringCollectionValue(allNames); } return _randomUtil.GetStringCollectionValue(filteredNames); } }