diff --git a/project/Aki.Custom/AkiCustomPlugin.cs b/project/Aki.Custom/AkiCustomPlugin.cs index d2e0087..326122b 100644 --- a/project/Aki.Custom/AkiCustomPlugin.cs +++ b/project/Aki.Custom/AkiCustomPlugin.cs @@ -57,7 +57,7 @@ namespace Aki.Custom new RagfairFeePatch().Enable(); new ScavQuestPatch().Enable(); new FixBrokenSpawnOnSandboxPatch().Enable(); - new BTRControllerConstructorPatch().Enable(); + new BTRControllerInitPatch().Enable(); new BTRPathLoadPatch().Enable(); new BTRActivateTraderDialogPatch().Enable(); new BTRInteractionPatch().Enable(); diff --git a/project/Aki.Custom/BTR/BTRManager.cs b/project/Aki.Custom/BTR/BTRManager.cs index 7fb0d5b..8bd647b 100644 --- a/project/Aki.Custom/BTR/BTRManager.cs +++ b/project/Aki.Custom/BTR/BTRManager.cs @@ -6,11 +6,9 @@ using EFT.InventoryLogic; using EFT.UI; using EFT.Vehicle; using HarmonyLib; -using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using UnityEngine; using Random = UnityEngine.Random; @@ -50,20 +48,8 @@ namespace Aki.Custom.BTR private Player.FirearmController firearmController; private WeaponSoundPlayer weaponSoundPlayer; - private MethodInfo _updateTaxiPriceMethod; - private MethodInfo _playWeaponSoundMethod; - private float originalDamageCoeff; - BTRManager() - { - Type btrControllerType = typeof(BTRControllerClass); - _updateTaxiPriceMethod = AccessTools.GetDeclaredMethods(btrControllerType).Single(IsUpdateTaxiPriceMethod); - - Type firearmControllerType = typeof(Player.FirearmController); - _playWeaponSoundMethod = AccessTools.GetDeclaredMethods(firearmControllerType).Single(IsPlayWeaponSoundMethod); - } - private async void Awake() { try @@ -139,26 +125,6 @@ namespace Aki.Custom.BTR } } - // Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)` - private bool IsUpdateTaxiPriceMethod(MethodInfo method) - { - ParameterInfo[] parameters = method.GetParameters(); - - return parameters.Length == 2 && parameters[0].ParameterType == typeof(PathDestination); - } - - private bool IsPlayWeaponSoundMethod(MethodInfo method) - { - ParameterInfo[] parameters = method.GetParameters(); - - return parameters.Length == 5 - && parameters[0].ParameterType == typeof(WeaponSoundPlayer) - && parameters[1].ParameterType == typeof(BulletClass) - && parameters[2].ParameterType == typeof(Vector3) - && parameters[3].ParameterType == typeof(Vector3) - && parameters[4].ParameterType == typeof(bool); - } - private void Update() { if (!btrInitialized) return; @@ -194,7 +160,7 @@ namespace Aki.Custom.BTR private async Task InitBtr() { // Initial setup - await btrController.method_1(); + await btrController.InitBtrController(); botEventHandler = Singleton.Instance; var botsController = Singleton.Instance.BotsController; @@ -280,7 +246,7 @@ namespace Aki.Custom.BTR TraderServicesManager.Instance.RemovePurchasedService(ETraderServiceType.PlayerTaxi, BTRUtil.BTRTraderId); // Update the prices for the taxi service - _updateTaxiPriceMethod.Invoke(btrController, new object[] { destinationPoint, isFinal }); + btrController.UpdateTaxiPrice(destinationPoint, isFinal); // Update the UI TraderServicesManager.Instance.GetTraderServicesDataFromServer(BTRUtil.BTRTraderId); @@ -488,7 +454,7 @@ namespace Aki.Custom.BTR Vector3 aimDirection = Vector3.Normalize(targetHeadPos - machineGunMuzzle.position); ballisticCalculator.Shoot(btrMachineGunAmmo, machineGunMuzzle.position, aimDirection, btrBotShooter.ProfileId, btrMachineGunWeapon, 1f, 0); - _playWeaponSoundMethod.Invoke(firearmController, new object[] { weaponSoundPlayer, btrMachineGunAmmo, machineGunMuzzle.position, aimDirection, false }); + firearmController.PlayWeaponSound(weaponSoundPlayer, btrMachineGunAmmo, machineGunMuzzle.position, aimDirection, false); burstCount--; yield return new WaitForSecondsRealtime(0.092308f); // 650 RPM diff --git a/project/Aki.Custom/BTR/Patches/BTRControllerConstructorPatch.cs b/project/Aki.Custom/BTR/Patches/BTRControllerConstructorPatch.cs deleted file mode 100644 index 193aba6..0000000 --- a/project/Aki.Custom/BTR/Patches/BTRControllerConstructorPatch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Aki.Reflection.Patching; -using HarmonyLib; -using System.Reflection; - -namespace Aki.Custom.BTR.Patches -{ - public class BTRControllerConstructorPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.GetDeclaredConstructors(typeof(BTRControllerClass))[0]; - } - - [PatchPrefix] - private static bool PatchPrefix() - { - return false; // We don't want the original constructor to run - } - } -} diff --git a/project/Aki.Custom/BTR/Patches/BTRControllerInitPatch.cs b/project/Aki.Custom/BTR/Patches/BTRControllerInitPatch.cs new file mode 100644 index 0000000..44ca79e --- /dev/null +++ b/project/Aki.Custom/BTR/Patches/BTRControllerInitPatch.cs @@ -0,0 +1,34 @@ +using Aki.Reflection.Patching; +using HarmonyLib; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; + +namespace Aki.Custom.BTR.Patches +{ + public class BTRControllerInitPatch : ModulePatch + { + protected override MethodBase GetTargetMethod() + { + return AccessTools.FirstMethod(typeof(BTRControllerClass), IsTargetMethod); + } + + private bool IsTargetMethod(MethodInfo method) + { + ParameterInfo[] parameters = method.GetParameters(); + + return method.ReturnType == typeof(Task) + && parameters.Length == 1 + && parameters[0].ParameterType == typeof(CancellationToken); + } + + [PatchPrefix] + private static bool PatchPrefix(ref Task __result) + { + // The BTRControllerClass constructor expects the original method to return a Task, + // as it calls another method on said Task. + __result = Task.CompletedTask; + return false; + } + } +} diff --git a/project/Aki.Custom/BTR/Patches/BTRReceiveDamageInfoPatch.cs b/project/Aki.Custom/BTR/Patches/BTRReceiveDamageInfoPatch.cs index 8a91a35..9df3256 100644 --- a/project/Aki.Custom/BTR/Patches/BTRReceiveDamageInfoPatch.cs +++ b/project/Aki.Custom/BTR/Patches/BTRReceiveDamageInfoPatch.cs @@ -36,7 +36,7 @@ namespace Aki.Custom.BTR.Patches return; } - var shotBy = (Player)damageInfo.Player; + var shotBy = (Player)damageInfo.Player.iPlayer; if (shotBy != null) { botEventHandler.InterruptTraderServiceBtrSupportByBetrayer(shotBy); diff --git a/project/Aki.Custom/BTR/Utils/BTRReflectionHelper.cs b/project/Aki.Custom/BTR/Utils/BTRReflectionHelper.cs new file mode 100644 index 0000000..75deab2 --- /dev/null +++ b/project/Aki.Custom/BTR/Utils/BTRReflectionHelper.cs @@ -0,0 +1,66 @@ +using EFT; +using EFT.Vehicle; +using HarmonyLib; +using System; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using UnityEngine; + +namespace Aki.Custom.BTR.Utils +{ + public static class BTRReflectionHelper + { + private static Type _btrControllerType = typeof(BTRControllerClass); + private static Type _firearmControllerType = typeof(Player.FirearmController); + + private static MethodInfo _initBtrControllerMethod = AccessTools.GetDeclaredMethods(_btrControllerType).Single(IsInitBtrControllerMethod); + private static MethodInfo _updateTaxiPriceMethod = AccessTools.GetDeclaredMethods(_btrControllerType).Single(IsUpdateTaxiPriceMethod); + + private static MethodInfo _playWeaponSoundMethod = AccessTools.GetDeclaredMethods(_firearmControllerType).Single(IsPlayWeaponSoundMethod); + + public static Task InitBtrController(this BTRControllerClass controller) + { + return (Task)_initBtrControllerMethod.Invoke(controller, null); + } + + public static void UpdateTaxiPrice(this BTRControllerClass controller, PathDestination destinationPoint, bool isFinal) + { + _updateTaxiPriceMethod.Invoke(controller, new object[] { destinationPoint, isFinal }); + } + + public static void PlayWeaponSound(this Player.FirearmController controller, WeaponSoundPlayer weaponSoundPlayer, BulletClass ammo, Vector3 shotPosition, Vector3 shotDirection, bool multiShot) + { + _playWeaponSoundMethod.Invoke(controller, new object[] { weaponSoundPlayer, ammo, shotPosition, shotDirection, multiShot }); + } + + // Find `BTRControllerClass.method_1()` + private static bool IsInitBtrControllerMethod(MethodInfo method) + { + return method.ReturnType == typeof(Task) + && method.GetParameters().Length == 0; + } + + // Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)` + private static bool IsUpdateTaxiPriceMethod(MethodInfo method) + { + ParameterInfo[] parameters = method.GetParameters(); + + return parameters.Length == 2 + && parameters[0].ParameterType == typeof(PathDestination); + } + + // Find `Player.FirearmController.method_54(WeaponSoundPlayer weaponSoundPlayer, BulletClass ammo, Vector3 shotPosition, Vector3 shotDirection, bool multiShot)` + private static bool IsPlayWeaponSoundMethod(MethodInfo method) + { + ParameterInfo[] parameters = method.GetParameters(); + + return parameters.Length == 5 + && parameters[0].ParameterType == typeof(WeaponSoundPlayer) + && parameters[1].ParameterType == typeof(BulletClass) + && parameters[2].ParameterType == typeof(Vector3) + && parameters[3].ParameterType == typeof(Vector3) + && parameters[4].ParameterType == typeof(bool); + } + } +}