Implemented more of Bot Generation
This commit is contained in:
@@ -309,25 +309,33 @@ public class BotGenerator
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should this bot have a name like "name (Pmc Name)" and be alterd by client patch to be hostile to player
|
||||
/// Should this bot have a name like "name (Pmc Name)" and be altered by client patch to be hostile to player
|
||||
/// </summary>
|
||||
/// <param name="botRole">Role bot has</param>
|
||||
/// <returns>True if name should be simulated pscav</returns>
|
||||
public bool ShouldSimulatePlayerScav(string botRole)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return botRole == "assault" && _randomUtil.GetChance100(_botConfig.ChanceAssaultScavHasPlayerScavName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get exp for kill by bot difficulty
|
||||
/// </summary>
|
||||
/// <param name="experience">Dict of difficulties and experience</param>
|
||||
/// <param name="experiences">Dict of difficulties and experience</param>
|
||||
/// <param name="botDifficulty">the killed bots difficulty</param>
|
||||
/// <param name="role">Role of bot (optional, used for error logging)</param>
|
||||
/// <returns>Experience for kill</returns>
|
||||
public int GetExperienceRewardForKillByDifficulty(Dictionary<string, MinMax> experience, string botDifficulty, string role)
|
||||
public double GetExperienceRewardForKillByDifficulty(Dictionary<string, MinMax> experiences, string botDifficulty, string role)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var result = experiences[botDifficulty.ToLower()];
|
||||
if (result is null)
|
||||
{
|
||||
_logger.Debug("Unable to find experience for kill value for: ${ role} ${ botDifficulty}, falling back to `normal`");
|
||||
|
||||
return _randomUtil.GetDouble(experiences["normal"].Min.Value, experiences["normal"].Max.Value);
|
||||
}
|
||||
|
||||
return _randomUtil.GetDouble(result.Min.Value, result.Max.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -337,9 +345,16 @@ public class BotGenerator
|
||||
/// <param name="botDifficulty">Difficulty of bot to look up</param>
|
||||
/// <param name="role">Role of bot (optional, used for error logging)</param>
|
||||
/// <returns>Standing change value</returns>
|
||||
public int GetStandingChangeForKillByDifficulty(Dictionary<string, double> standingForKill, string botDifficulty, string role)
|
||||
public double GetStandingChangeForKillByDifficulty(Dictionary<string, double> standingsForKill, string botDifficulty, string role)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!standingsForKill.TryGetValue(botDifficulty.ToLower(), out var result))
|
||||
{
|
||||
_logger.Warning($"Unable to find standing for kill value for: {role} {botDifficulty}, falling back to `normal`");
|
||||
|
||||
return standingsForKill["normal"];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -349,9 +364,16 @@ public class BotGenerator
|
||||
/// <param name="botDifficulty">Difficulty of bot to look up</param>
|
||||
/// <param name="role">Role of bot (optional, used for error logging)</param>
|
||||
/// <returns>Standing change value</returns>
|
||||
public int GetAgressorBonusByDifficulty(Dictionary<string, double> aggressorBonus, string botDifficulty, string role)
|
||||
public double GetAgressorBonusByDifficulty(Dictionary<string, double> aggressorBonuses, string botDifficulty, string role)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!aggressorBonuses.TryGetValue(botDifficulty.ToLower(), out var result))
|
||||
{
|
||||
_logger.Warning($"Unable to find aggressor bonus for kill value for: {role} {botDifficulty}, falling back to `normal`");
|
||||
|
||||
return aggressorBonuses["normal"];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -361,7 +383,24 @@ public class BotGenerator
|
||||
/// <param name="botGenerationDetails">Generation details of bot</param>
|
||||
public void FilterBlacklistedGear(BotType botJsonTemplate, BotGenerationDetails botGenerationDetails)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var blacklist = _botEquipmentFilterService.GetBotEquipmentBlacklist(
|
||||
_botGeneratorHelper.GetBotEquipmentRole(botGenerationDetails.Role),
|
||||
botGenerationDetails.PlayerLevel.Value);
|
||||
|
||||
if (blacklist?.Gear is null)
|
||||
{
|
||||
// Nothing to filter by
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var equipmentKvP in blacklist.Gear) {
|
||||
var equipmentDict = botJsonTemplate.BotInventory.Equipment[equipmentKvP.Key];
|
||||
|
||||
foreach (var blacklistedTpl in equipmentKvP.Value) {
|
||||
// Set weighting to 0, will never be picked
|
||||
equipmentDict[blacklistedTpl] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -370,7 +409,10 @@ public class BotGenerator
|
||||
/// <param name="botJsonTemplate">Bot data to adjust</param>
|
||||
public void AddAdditionalPocketLootWeightsForUnheardBot(BotType botJsonTemplate)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Adjust pocket loot weights to allow for 5 or 6 items
|
||||
var pocketWeights = botJsonTemplate.BotGeneration.Items["pocketLoot"].Weights;
|
||||
pocketWeights["5"] = 1;
|
||||
pocketWeights["6"] = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
using Core.Annotations;
|
||||
using Core.Annotations;
|
||||
using Core.Models.Common;
|
||||
using Core.Models.Eft.Bot;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Spt.Bots;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
using ILogger = Core.Models.Utils.ILogger;
|
||||
|
||||
namespace Core.Generators;
|
||||
|
||||
[Injectable]
|
||||
public class BotLevelGenerator
|
||||
{
|
||||
public BotLevelGenerator()
|
||||
private readonly ILogger _logger;
|
||||
private readonly RandomUtil _randomUtil;
|
||||
private readonly MathUtil _mathUtil;
|
||||
private readonly DatabaseService _databaseService;
|
||||
|
||||
public BotLevelGenerator(
|
||||
ILogger logger,
|
||||
RandomUtil randomUtil,
|
||||
MathUtil mathUtil,
|
||||
DatabaseService databaseService)
|
||||
{
|
||||
_logger = logger;
|
||||
_randomUtil = randomUtil;
|
||||
_mathUtil = mathUtil;
|
||||
_databaseService = databaseService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -22,12 +38,29 @@ public class BotLevelGenerator
|
||||
/// <returns>IRandomisedBotLevelResult object</returns>
|
||||
public RandomisedBotLevelResult GenerateBotLevel(MinMax levelDetails, BotGenerationDetails botGenerationDetails, BotBase bot)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var expTable = _databaseService.GetGlobals().Configuration.Exp.Level.ExperienceTable;
|
||||
var botLevelRange = GetRelativeBotLevelRange(botGenerationDetails, levelDetails, expTable.Length);
|
||||
|
||||
// Get random level based on the exp table.
|
||||
double exp = 0;
|
||||
var level = int.Parse(ChooseBotLevel(botLevelRange.Min.Value, botLevelRange.Max.Value, 1, 1.15).ToString()); // TODO - nasty double to string to int conversion
|
||||
for (var i = 0; i < level; i++)
|
||||
{
|
||||
exp += expTable[i].Experience.Value;
|
||||
}
|
||||
|
||||
// Sprinkle in some random exp within the level, unless we are at max level.
|
||||
if (level < expTable.Length - 1)
|
||||
{
|
||||
exp += _randomUtil.GetDouble(0, expTable[level].Experience.Value - 1);
|
||||
}
|
||||
|
||||
return new RandomisedBotLevelResult{ Level = level, Exp = exp };
|
||||
}
|
||||
|
||||
public int ChooseBotLevel(int min, int max, int shift, int number)
|
||||
public double ChooseBotLevel(double min, double max, int shift, double number)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _randomUtil.GetBiasedRandomNumber(min, max, shift, number);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -39,6 +72,30 @@ public class BotLevelGenerator
|
||||
/// <returns>A MinMax of the lowest and highest level to generate the bots</returns>
|
||||
public MinMax GetRelativeBotLevelRange(BotGenerationDetails botGenerationDetails, MinMax levelDetails, int maxAvailableLevel)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var isPmc = botGenerationDetails.IsPmc.GetValueOrDefault(false);
|
||||
var pmcOverride = botGenerationDetails.LocationSpecificPmcLevelOverride;
|
||||
|
||||
var minPossibleLevel = isPmc && pmcOverride is not null
|
||||
? Math.Min(
|
||||
Math.Max(levelDetails.Min.Value, pmcOverride.Min.Value), // Biggest between json min and the botgen min
|
||||
maxAvailableLevel // Fallback if value above is crazy (default is 79)
|
||||
)
|
||||
: Math.Min(levelDetails.Min.Value, maxAvailableLevel); // Not pmc with override or non-pmc
|
||||
|
||||
var maxPossibleLevel = isPmc && pmcOverride is not null
|
||||
? Math.Min(pmcOverride.Max.Value, maxAvailableLevel) // Was a PMC and they have a level override
|
||||
: Math.Min(levelDetails.Max.Value, maxAvailableLevel); // Not pmc with override or non-pmc
|
||||
|
||||
var minLevel = botGenerationDetails.PlayerLevel.Value - botGenerationDetails.BotRelativeLevelDeltaMin.Value;
|
||||
var maxLevel = botGenerationDetails.PlayerLevel.Value + botGenerationDetails.BotRelativeLevelDeltaMin.Value;
|
||||
|
||||
// Bound the level to the min/max possible
|
||||
maxLevel = Math.Min(Math.Max(maxLevel, minPossibleLevel), maxPossibleLevel);
|
||||
minLevel = Math.Min(Math.Max(minLevel, minPossibleLevel), maxPossibleLevel);
|
||||
|
||||
return new MinMax{
|
||||
Min = minLevel,
|
||||
Max = maxLevel,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Core.Models.Eft.Bot;
|
||||
|
||||
public class RandomisedBotLevelResult
|
||||
{
|
||||
[JsonPropertyName("level")]
|
||||
public int? Level { get; set; }
|
||||
public double? Level { get; set; }
|
||||
|
||||
[JsonPropertyName("exp")]
|
||||
public int? Exp { get; set; }
|
||||
}
|
||||
public double? Exp { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.Hideout;
|
||||
|
||||
namespace Core.Models.Eft.Common;
|
||||
@@ -1255,7 +1255,7 @@ public class Level
|
||||
public class ExpTable
|
||||
{
|
||||
[JsonPropertyName("exp")]
|
||||
public int? Experience { get; set; }
|
||||
public double? Experience { get; set; }
|
||||
}
|
||||
|
||||
public class LootAttempt
|
||||
|
||||
@@ -74,7 +74,7 @@ public class BotEquipmentFilterService
|
||||
/// <param name="botRole">Role of the bot we want the blacklist for</param>
|
||||
/// <param name="playerLevel">Level of the player</param>
|
||||
/// <returns>EquipmentBlacklistDetails object</returns>
|
||||
public EquipmentFilterDetails GetBotEquipmentBlacklist(string botRole, int playerLevel)
|
||||
public EquipmentFilterDetails GetBotEquipmentBlacklist(string botRole, double playerLevel)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user