From 2faf204d77be09db5116c50d8eff17d710d076ce Mon Sep 17 00:00:00 2001 From: Dev Date: Fri, 2 Aug 2024 17:25:50 +0100 Subject: [PATCH] Revert "Removed unused patches:" This reverts commit cc674f5d4816e98d4b84d52f364cb867bfa30def. --- .../Patches/BotCalledDataTryCallPatch.cs | 49 +++++++++++++++++ .../SPT.Custom/Patches/BotEnemyTargetPatch.cs | 52 +++++++++++++++++++ .../Patches/BotOwnerDisposePatch.cs | 28 ++++++++++ .../SPT.Custom/Patches/BotSelfEnemyPatch.cs | 40 ++++++++++++++ project/SPT.Custom/SPTCustomPlugin.cs | 5 +- 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 project/SPT.Custom/Patches/BotCalledDataTryCallPatch.cs create mode 100644 project/SPT.Custom/Patches/BotEnemyTargetPatch.cs create mode 100644 project/SPT.Custom/Patches/BotOwnerDisposePatch.cs create mode 100644 project/SPT.Custom/Patches/BotSelfEnemyPatch.cs diff --git a/project/SPT.Custom/Patches/BotCalledDataTryCallPatch.cs b/project/SPT.Custom/Patches/BotCalledDataTryCallPatch.cs new file mode 100644 index 0000000..663a56f --- /dev/null +++ b/project/SPT.Custom/Patches/BotCalledDataTryCallPatch.cs @@ -0,0 +1,49 @@ +using SPT.Reflection.Patching; +using EFT; +using HarmonyLib; +using System.Reflection; + +namespace SPT.Custom.Patches +{ + /** + * It's possible for `AddEnemy` to return false, in that case, further code in TryCall will fail, + * so we do the first bit of `TryCall` ourselves, and skip the original function if AddEnemy fails + */ + public class BotCalledDataTryCallPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(BotCalledData), nameof(BotCalledData.TryCall)); + } + + [PatchPrefix] + private static bool PatchPrefix(ref bool __result, BotOwner caller, BotOwner ___botOwner_0, BotOwner ____caller) + { + if (___botOwner_0.EnemiesController.IsEnemy(caller.AIData.Player) || ____caller != null) + { + __result = false; + + // Skip original + return false; + } + + if (caller.Memory.GoalEnemy != null) + { + IPlayer person = caller.Memory.GoalEnemy.Person; + if (!___botOwner_0.BotsGroup.Enemies.ContainsKey(person)) + { + if (!___botOwner_0.BotsGroup.AddEnemy(person, EBotEnemyCause.callBot)) + { + __result = false; + + // Skip original + return false; + } + } + } + + // Allow original + return true; + } + } +} diff --git a/project/SPT.Custom/Patches/BotEnemyTargetPatch.cs b/project/SPT.Custom/Patches/BotEnemyTargetPatch.cs new file mode 100644 index 0000000..9810079 --- /dev/null +++ b/project/SPT.Custom/Patches/BotEnemyTargetPatch.cs @@ -0,0 +1,52 @@ +using SPT.Reflection.Patching; +using EFT; +using System.Reflection; +using HarmonyLib; + +namespace SPT.Custom.Patches +{ + public class BotEnemyTargetPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(BotsController), nameof(BotsController.AddEnemyToAllGroupsInBotZone)); + } + + /// + /// AddEnemyToAllGroupsInBotZone() + /// Goal: by default, AddEnemyToAllGroupsInBotZone doesn't check if the bot group is on the same side as the player. + /// The effect of this is that when you are a Scav and kill a Usec, every bot group in the zone will aggro you including other Scavs. + /// This should fix that. + /// + [PatchPrefix] + private static bool PatchPrefix(BotsController __instance, IPlayer aggressor, IPlayer groupOwner, IPlayer target) + { + BotZone botZone = groupOwner.AIData.BotOwner.BotsGroup.BotZone; + foreach (var item in __instance.Groups()) + { + if (item.Key != botZone) + { + continue; + } + + foreach (var group in item.Value.GetGroups(notNull: true)) + { + if (!group.Enemies.ContainsKey(aggressor) && ShouldAttack(aggressor, target, group)) + { + group.AddEnemy(aggressor, EBotEnemyCause.AddEnemyToAllGroupsInBotZone); + } + } + } + + return false; + } + private static bool ShouldAttack(IPlayer attacker, IPlayer victim, BotsGroup groupToCheck) + { + // Group should target if player attack a victim on the same side or if the group is not on the same side as the player. + bool shouldAttack = attacker.Side != groupToCheck.Side + || attacker.Side == victim.Side; + + return !groupToCheck.HaveMemberWithRole(WildSpawnType.gifter) && groupToCheck.ShallRevengeFor(victim) && shouldAttack; + } + } +} diff --git a/project/SPT.Custom/Patches/BotOwnerDisposePatch.cs b/project/SPT.Custom/Patches/BotOwnerDisposePatch.cs new file mode 100644 index 0000000..9242e71 --- /dev/null +++ b/project/SPT.Custom/Patches/BotOwnerDisposePatch.cs @@ -0,0 +1,28 @@ +using SPT.Reflection.Patching; +using EFT; +using HarmonyLib; +using System.Reflection; + +namespace SPT.Custom.Patches +{ + /** + * BotOwner doesn't call SetOff on the CalledData object when a bot is disposed, this can result + * in bots that are no longer alive having their `OnEnemyAdd` method called + */ + public class BotOwnerDisposePatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(BotOwner), nameof(BotOwner.Dispose)); + } + + [PatchPrefix] + private static void PatchPrefix(BotOwner __instance) + { + if (__instance.CalledData != null) + { + __instance.CalledData.SetOff(); + } + } + } +} diff --git a/project/SPT.Custom/Patches/BotSelfEnemyPatch.cs b/project/SPT.Custom/Patches/BotSelfEnemyPatch.cs new file mode 100644 index 0000000..97a0482 --- /dev/null +++ b/project/SPT.Custom/Patches/BotSelfEnemyPatch.cs @@ -0,0 +1,40 @@ +using SPT.Reflection.Patching; +using EFT; +using System.Reflection; +using HarmonyLib; + +namespace SPT.Custom.Patches +{ + /// + /// Goal: patch removes the current bot from its own enemy list - occurs when adding bots type to its enemy array in difficulty settings + /// + public class BotSelfEnemyPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.Method(typeof(BotOwner), nameof(BotOwner.PreActivate)); + } + + [PatchPrefix] + private static bool PatchPrefix(BotOwner __instance, BotsGroup group) + { + IPlayer selfToRemove = null; + + foreach (var enemy in group.Enemies) + { + if (enemy.Key.Id == __instance.Id) + { + selfToRemove = enemy.Key; + break; + } + } + + if (selfToRemove != null) + { + group.Enemies.Remove(selfToRemove); + } + + return true; + } + } +} diff --git a/project/SPT.Custom/SPTCustomPlugin.cs b/project/SPT.Custom/SPTCustomPlugin.cs index 5d942b9..77e2b56 100644 --- a/project/SPT.Custom/SPTCustomPlugin.cs +++ b/project/SPT.Custom/SPTCustomPlugin.cs @@ -34,10 +34,13 @@ namespace SPT.Custom // new SessionIdPatch().Enable(); new VersionLabelPatch().Enable(); new IsEnemyPatch().Enable(); + new BotCalledDataTryCallPatch().Enable(); + new BotOwnerDisposePatch().Enable(); new LocationLootCacheBustingPatch().Enable(); //new AddSelfAsEnemyPatch().Enable(); new CheckAndAddEnemyPatch().Enable(); - //new AddEnemyToAllGroupsInBotZonePatch().Enable(); + new BotSelfEnemyPatch().Enable(); // needed + new AddEnemyToAllGroupsInBotZonePatch().Enable(); new AirdropPatch().Enable(); new AirdropFlarePatch().Enable(); //new AddSptBotSettingsPatch().Enable();