From 136b051623333971919329c2d13d01a15b63a2b5 Mon Sep 17 00:00:00 2001 From: DrakiaXYZ Date: Sat, 20 Jan 2024 21:43:02 +0000 Subject: [PATCH] Implement BTR taxi service (!64) - Move creation/init of the BTRManager to before the `ExtractionTimerPanel.SetTime` method, to fix BTR timer panel not functioning - Add subserviceId to the `OnTraderServicePurchased` event - Add BTR taxi service handling Co-authored-by: DrakiaXYZ <565558+TheDgtl@users.noreply.github.com> Reviewed-on: https://dev.sp-tarkov.com/SPT-AKI/Modules/pulls/64 Co-authored-by: DrakiaXYZ Co-committed-by: DrakiaXYZ --- project/Aki.Debugging/BTR/BTRManager.cs | 28 ++++++++++++------- project/Aki.Debugging/BTR/Patches/BTRPatch.cs | 11 +++++--- .../TraderServices/TraderServicesManager.cs | 16 ++++++++--- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/project/Aki.Debugging/BTR/BTRManager.cs b/project/Aki.Debugging/BTR/BTRManager.cs index c51f243..0f973cd 100644 --- a/project/Aki.Debugging/BTR/BTRManager.cs +++ b/project/Aki.Debugging/BTR/BTRManager.cs @@ -49,14 +49,8 @@ namespace Aki.Debugging.BTR Type btrControllerType = typeof(BTRControllerClass); _updateTaxiPriceMethod = AccessTools.GetDeclaredMethods(btrControllerType).Single(IsUpdateTaxiPriceMethod); } - - // Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)` - private bool IsUpdateTaxiPriceMethod(MethodInfo method) - { - return (method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination)); - } - - private void Start() + + public void Init() { try { @@ -88,6 +82,12 @@ namespace Aki.Debugging.BTR } } + // Find `BTRControllerClass.method_9(PathDestination currentDestinationPoint, bool lastRoutePoint)` + private bool IsUpdateTaxiPriceMethod(MethodInfo method) + { + return (method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(PathDestination)); + } + private void Update() { btrController.SyncBTRVehicleFromServer(UpdateDataPacket()); @@ -189,12 +189,18 @@ namespace Aki.Debugging.BTR } /** - * BTR has arrived at a destination, re-calculate taxi prices + * BTR has arrived at a destination, re-calculate taxi prices and remove purchased taxi service */ private void ToDestinationEvent(PathDestination destinationPoint, bool isFirst, bool isFinal, bool isLastRoutePoint) { + // Remove purchased taxi service + TraderServicesManager.Instance.RemovePurchasedService(ETraderServiceType.PlayerTaxi, BTRUtil.BTRTraderId); + // Update the prices for the taxi service _updateTaxiPriceMethod.Invoke(btrController, new object[] { destinationPoint, isFinal }); + + // Update the UI + TraderServicesManager.Instance.GetTraderServicesDataFromServer(BTRUtil.BTRTraderId); } private bool IsBtrService(ETraderServiceType serviceType) @@ -209,7 +215,7 @@ namespace Aki.Debugging.BTR return false; } - private void BTRTraderServicePurchased(ETraderServiceType serviceType) + private void BTRTraderServicePurchased(ETraderServiceType serviceType, string subserviceId) { if (!IsBtrService(serviceType)) { @@ -227,6 +233,8 @@ namespace Aki.Debugging.BTR StartCoverFireTimer(90f); break; case ETraderServiceType.PlayerTaxi: + btrController.BtrVehicle.IsPaid = true; + btrController.BtrVehicle.MoveToDestination(subserviceId); break; } } diff --git a/project/Aki.Debugging/BTR/Patches/BTRPatch.cs b/project/Aki.Debugging/BTR/Patches/BTRPatch.cs index 766e63a..95bd280 100644 --- a/project/Aki.Debugging/BTR/Patches/BTRPatch.cs +++ b/project/Aki.Debugging/BTR/Patches/BTRPatch.cs @@ -14,11 +14,13 @@ namespace Aki.Debugging.BTR.Patches { protected override MethodBase GetTargetMethod() { - return AccessTools.Method(typeof(GameWorld), nameof(GameWorld.OnGameStarted)); + // Note: This may seem like a weird place to hook, but `SetTime` requires that the BtrController + // exist and be setup, so we'll use this as the entry point + return AccessTools.Method(typeof(ExtractionTimersPanel), nameof(ExtractionTimersPanel.SetTime)); } - [PatchPostfix] - private static void PatchPostfix() + [PatchPrefix] + private static void PatchPrefix() { try { @@ -35,7 +37,8 @@ namespace Aki.Debugging.BTR.Patches gameWorld.LocationId = gameWorld.MainPlayer.Location; } - gameWorld.gameObject.AddComponent(); + var btrManager = gameWorld.gameObject.AddComponent(); + btrManager.Init(); } catch (System.Exception) { diff --git a/project/Aki.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs b/project/Aki.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs index 12d6ab9..8321a8e 100644 --- a/project/Aki.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs +++ b/project/Aki.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs @@ -15,7 +15,7 @@ namespace Aki.SinglePlayer.Utils.TraderServices /// /// Subscribe to this event to trigger trader service logic. /// - public event Action OnTraderServicePurchased; + public event Action OnTraderServicePurchased; private static TraderServicesManager _instance; @@ -136,10 +136,10 @@ namespace Aki.SinglePlayer.Utils.TraderServices return; } - SetServicePurchased(serviceType, serviceData.TraderId); + SetServicePurchased(serviceType, subServiceId, serviceData.TraderId); } - public void SetServicePurchased(ETraderServiceType serviceType, string traderId) + public void SetServicePurchased(ETraderServiceType serviceType, string subserviceId, string traderId) { if (_servicePurchased.TryGetValue(serviceType, out var traderDict)) { @@ -150,7 +150,15 @@ namespace Aki.SinglePlayer.Utils.TraderServices _servicePurchased[serviceType] = new Dictionary(); _servicePurchased[serviceType][traderId] = true; } - OnTraderServicePurchased.Invoke(serviceType); + OnTraderServicePurchased.Invoke(serviceType, subserviceId); + } + + public void RemovePurchasedService(ETraderServiceType serviceType, string traderId) + { + if (_servicePurchased.TryGetValue(serviceType, out var traderDict)) + { + traderDict[traderId] = false; + } } public bool IsServicePurchased(ETraderServiceType serviceType, string traderId)