mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-13 09:50:43 -05:00
Player can now talk to BTR driver (!52)
Todo: * BTR trader services requires implementation server-side * Send items to player stash (2x4) * Provide covering fire * Taxi to a specific location on Streets * Fix turret aiming at player from raid start * Make turret shoot at enemies (including player) Co-authored-by: Nympfonic <arys.steam@gmail.com> Reviewed-on: SPT-AKI/Modules#52 Co-authored-by: Arys <arys@noreply.dev.sp-tarkov.com> Co-committed-by: Arys <arys@noreply.dev.sp-tarkov.com>
This commit is contained in:
parent
5fcc904a89
commit
37432541c3
@ -19,11 +19,13 @@ namespace Aki.Debugging
|
|||||||
// new CoordinatesPatch().Enable();
|
// new CoordinatesPatch().Enable();
|
||||||
// new StaticLootDumper().Enable();
|
// new StaticLootDumper().Enable();
|
||||||
new BTRPathLoadPatch().Enable();
|
new BTRPathLoadPatch().Enable();
|
||||||
|
new BTRActivateTraderDialogPatch().Enable();
|
||||||
new BTRInteractionPatch().Enable();
|
new BTRInteractionPatch().Enable();
|
||||||
|
new BTRExtractPassengersPatch().Enable();
|
||||||
new BTRBotAttachPatch().Enable();
|
new BTRBotAttachPatch().Enable();
|
||||||
new BTRBotInitPatch().Enable();
|
new BTRBotInitPatch().Enable();
|
||||||
new BTRIsDoorsClosedPath().Enable();
|
new BTRIsDoorsClosedPath().Enable();
|
||||||
new BTRPatch().Enable();
|
new BTRPatch().Enable();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
using Comfort.Common;
|
using Aki.Reflection.Utils;
|
||||||
|
using Comfort.Common;
|
||||||
using EFT;
|
using EFT;
|
||||||
using EFT.Vehicle;
|
using EFT.Vehicle;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using BTRController = GClass2911;
|
using BTRController = GClass2911;
|
||||||
using BTRDataPacket = GStruct378;
|
using BTRDataPacket = GStruct378;
|
||||||
@ -12,12 +15,18 @@ namespace Aki.Debugging.BTR
|
|||||||
public class BTRManager : MonoBehaviour
|
public class BTRManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
private GameWorld gameWorld;
|
private GameWorld gameWorld;
|
||||||
|
private BotsController botsController;
|
||||||
|
|
||||||
|
private BotBTRService btrBotService;
|
||||||
private BTRController btrController;
|
private BTRController btrController;
|
||||||
private BTRVehicle serverSideBtr;
|
private BTRVehicle btrServerSide;
|
||||||
private BTRView clientSideBtr;
|
private BTRView btrClientSide;
|
||||||
private BTRDataPacket btrDataPacket = default;
|
private BTRDataPacket btrDataPacket = default;
|
||||||
|
private bool btrBotShooterInitialized = false;
|
||||||
|
|
||||||
private EPlayerBtrState previousPlayerBtrState;
|
private EPlayerBtrState previousPlayerBtrState;
|
||||||
private BTRSide previousInteractedBtrSide;
|
private BTRSide lastInteractedBtrSide;
|
||||||
|
public BTRSide LastInteractedBtrSide => lastInteractedBtrSide;
|
||||||
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
@ -41,27 +50,10 @@ namespace Aki.Debugging.BTR
|
|||||||
gameWorld.BtrController = btrController = Singleton<BTRController>.Instance;
|
gameWorld.BtrController = btrController = Singleton<BTRController>.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
var btrControllerType = btrController.GetType();
|
botsController = Singleton<IBotGame>.Instance.BotsController;
|
||||||
AccessTools.Method(btrControllerType, "method_3").Invoke(btrController, null); // spawns server-side BTR game object
|
btrBotService = botsController.BotTradersServices.BTRServices;
|
||||||
Singleton<IBotGame>.Instance.BotsController.BotSpawner.SpawnBotBTR(); // spawns the scav bot which controls the BTR's turret
|
|
||||||
|
|
||||||
serverSideBtr = btrController.BtrVehicle;
|
InitBTR();
|
||||||
serverSideBtr.moveSpeed = 20f;
|
|
||||||
var btrMapConfig = btrController.MapPathsConfiguration;
|
|
||||||
serverSideBtr.CurrentPathConfig = btrMapConfig.PathsConfiguration.pathsConfigurations.RandomElement();
|
|
||||||
serverSideBtr.Initialization(btrMapConfig);
|
|
||||||
AccessTools.Method(btrControllerType, "method_14").Invoke(btrController, null); // creates and assigns the BTR a fake stash
|
|
||||||
|
|
||||||
clientSideBtr = btrController.BtrView;
|
|
||||||
|
|
||||||
UpdateDataPacket();
|
|
||||||
clientSideBtr.transform.position = btrDataPacket.position;
|
|
||||||
clientSideBtr.transform.rotation = btrDataPacket.rotation;
|
|
||||||
|
|
||||||
DisableServerSideRenderers();
|
|
||||||
|
|
||||||
previousPlayerBtrState = gameWorld.MainPlayer.BtrState;
|
|
||||||
gameWorld.MainPlayer.OnBtrStateChanged += HandleBtrDoorState;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -74,6 +66,15 @@ namespace Aki.Debugging.BTR
|
|||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
btrController.SyncBTRVehicleFromServer(UpdateDataPacket());
|
btrController.SyncBTRVehicleFromServer(UpdateDataPacket());
|
||||||
|
|
||||||
|
// BotShooterBtr doesn't get assigned to BtrController immediately so we nullcheck this in Update
|
||||||
|
if (btrController.BotShooterBtr != null && !btrBotShooterInitialized)
|
||||||
|
{
|
||||||
|
btrBotService.Reset(); // Player will be added to Neutrals list and removed from Enemies list
|
||||||
|
btrBotShooterInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AimAtEnemy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleBtrDoorState(EPlayerBtrState playerBtrState)
|
public void HandleBtrDoorState(EPlayerBtrState playerBtrState)
|
||||||
@ -104,30 +105,55 @@ namespace Aki.Debugging.BTR
|
|||||||
{
|
{
|
||||||
if (interactPacket.SlotId == 0)
|
if (interactPacket.SlotId == 0)
|
||||||
{
|
{
|
||||||
if (playerGoIn) serverSideBtr.LeftSlot0State = 1;
|
if (playerGoIn) btrServerSide.LeftSlot0State = 1;
|
||||||
else if (playerGoOut) serverSideBtr.LeftSlot0State = 0;
|
else if (playerGoOut) btrServerSide.LeftSlot0State = 0;
|
||||||
}
|
}
|
||||||
else if (interactPacket.SlotId == 1)
|
else if (interactPacket.SlotId == 1)
|
||||||
{
|
{
|
||||||
if (playerGoIn) serverSideBtr.LeftSlot1State = 1;
|
if (playerGoIn) btrServerSide.LeftSlot1State = 1;
|
||||||
else if (playerGoOut) serverSideBtr.LeftSlot1State = 0;
|
else if (playerGoOut) btrServerSide.LeftSlot1State = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (interactPacket.SideId == 1)
|
else if (interactPacket.SideId == 1)
|
||||||
{
|
{
|
||||||
if (interactPacket.SlotId == 0)
|
if (interactPacket.SlotId == 0)
|
||||||
{
|
{
|
||||||
if (playerGoIn) serverSideBtr.RightSlot0State = 1;
|
if (playerGoIn) btrServerSide.RightSlot0State = 1;
|
||||||
else if (playerGoOut) serverSideBtr.RightSlot0State = 0;
|
else if (playerGoOut) btrServerSide.RightSlot0State = 0;
|
||||||
}
|
}
|
||||||
else if (interactPacket.SlotId == 1)
|
else if (interactPacket.SlotId == 1)
|
||||||
{
|
{
|
||||||
if (playerGoIn) serverSideBtr.RightSlot1State = 1;
|
if (playerGoIn) btrServerSide.RightSlot1State = 1;
|
||||||
else if (playerGoOut) serverSideBtr.RightSlot1State = 0;
|
else if (playerGoOut) btrServerSide.RightSlot1State = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitBTR()
|
||||||
|
{
|
||||||
|
var btrControllerType = btrController.GetType();
|
||||||
|
AccessTools.Method(btrControllerType, "method_3").Invoke(btrController, null); // spawns server-side BTR game object
|
||||||
|
botsController.BotSpawner.SpawnBotBTR(); // spawns the scav bot which controls the BTR's turret
|
||||||
|
|
||||||
|
btrServerSide = btrController.BtrVehicle;
|
||||||
|
btrServerSide.moveSpeed = 20f;
|
||||||
|
var btrMapConfig = btrController.MapPathsConfiguration;
|
||||||
|
btrServerSide.CurrentPathConfig = btrMapConfig.PathsConfiguration.pathsConfigurations.RandomElement();
|
||||||
|
btrServerSide.Initialization(btrMapConfig);
|
||||||
|
AccessTools.Method(btrControllerType, "method_14").Invoke(btrController, null); // creates and assigns the BTR a fake stash
|
||||||
|
|
||||||
|
DisableServerSideRenderers();
|
||||||
|
|
||||||
|
gameWorld.MainPlayer.OnBtrStateChanged += HandleBtrDoorState;
|
||||||
|
|
||||||
|
btrServerSide.MoveEnable();
|
||||||
|
|
||||||
|
UpdateDataPacket();
|
||||||
|
btrClientSide = btrController.BtrView;
|
||||||
|
btrClientSide.transform.position = btrDataPacket.position;
|
||||||
|
btrClientSide.transform.rotation = btrDataPacket.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateBTRSideDoorState(byte state)
|
private void UpdateBTRSideDoorState(byte state)
|
||||||
{
|
{
|
||||||
var player = gameWorld.MainPlayer;
|
var player = gameWorld.MainPlayer;
|
||||||
@ -136,15 +162,14 @@ namespace Aki.Debugging.BTR
|
|||||||
for (int i = 0; i < btrSides.Length; i++)
|
for (int i = 0; i < btrSides.Length; i++)
|
||||||
{
|
{
|
||||||
if (player.BtrInteractionSide != null && btrSides[i] == player.BtrInteractionSide
|
if (player.BtrInteractionSide != null && btrSides[i] == player.BtrInteractionSide
|
||||||
|| previousInteractedBtrSide != null && btrSides[i] == previousInteractedBtrSide)
|
|| lastInteractedBtrSide != null && btrSides[i] == lastInteractedBtrSide)
|
||||||
{
|
{
|
||||||
if (i == 0) serverSideBtr.LeftSideState = state;
|
if (i == 0) btrServerSide.LeftSideState = state;
|
||||||
else if (i == 1) serverSideBtr.RightSideState = state;
|
else if (i == 1) btrServerSide.RightSideState = state;
|
||||||
|
|
||||||
if ((previousInteractedBtrSide != player.BtrInteractionSide && player.BtrInteractionSide != null)
|
if (lastInteractedBtrSide != player.BtrInteractionSide)
|
||||||
|| previousInteractedBtrSide == null)
|
|
||||||
{
|
{
|
||||||
previousInteractedBtrSide = player.BtrInteractionSide;
|
lastInteractedBtrSide = player.BtrInteractionSide;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,25 +177,25 @@ namespace Aki.Debugging.BTR
|
|||||||
|
|
||||||
private BTRDataPacket UpdateDataPacket()
|
private BTRDataPacket UpdateDataPacket()
|
||||||
{
|
{
|
||||||
btrDataPacket.position = serverSideBtr.transform.position;
|
btrDataPacket.position = btrServerSide.transform.position;
|
||||||
btrDataPacket.rotation = serverSideBtr.transform.rotation;
|
btrDataPacket.rotation = btrServerSide.transform.rotation;
|
||||||
if (serverSideBtr.BTRTurret?.gunsBlockRoot != null)
|
if (btrServerSide.BTRTurret?.gunsBlockRoot != null)
|
||||||
{
|
{
|
||||||
btrDataPacket.turretRotation = serverSideBtr.BTRTurret.transform.rotation;
|
btrDataPacket.turretRotation = btrServerSide.BTRTurret.transform.rotation;
|
||||||
btrDataPacket.gunsBlockRotation = serverSideBtr.BTRTurret.gunsBlockRoot.rotation;
|
btrDataPacket.gunsBlockRotation = btrServerSide.BTRTurret.gunsBlockRoot.rotation;
|
||||||
}
|
}
|
||||||
btrDataPacket.State = (byte)serverSideBtr.BtrState;
|
btrDataPacket.State = (byte)btrServerSide.BtrState;
|
||||||
btrDataPacket.RouteState = (byte)serverSideBtr.VehicleRouteState;
|
btrDataPacket.RouteState = (byte)btrServerSide.VehicleRouteState;
|
||||||
btrDataPacket.LeftSideState = serverSideBtr.LeftSideState;
|
btrDataPacket.LeftSideState = btrServerSide.LeftSideState;
|
||||||
btrDataPacket.LeftSlot0State = serverSideBtr.LeftSlot0State;
|
btrDataPacket.LeftSlot0State = btrServerSide.LeftSlot0State;
|
||||||
btrDataPacket.LeftSlot1State = serverSideBtr.LeftSlot1State;
|
btrDataPacket.LeftSlot1State = btrServerSide.LeftSlot1State;
|
||||||
btrDataPacket.RightSideState = serverSideBtr.RightSideState;
|
btrDataPacket.RightSideState = btrServerSide.RightSideState;
|
||||||
btrDataPacket.RightSlot0State = serverSideBtr.RightSlot0State;
|
btrDataPacket.RightSlot0State = btrServerSide.RightSlot0State;
|
||||||
btrDataPacket.RightSlot1State = serverSideBtr.RightSlot1State;
|
btrDataPacket.RightSlot1State = btrServerSide.RightSlot1State;
|
||||||
btrDataPacket.currentSpeed = serverSideBtr.currentSpeed;
|
btrDataPacket.currentSpeed = btrServerSide.currentSpeed;
|
||||||
btrDataPacket.timeToEndPause = serverSideBtr.timeToEndPause;
|
btrDataPacket.timeToEndPause = btrServerSide.timeToEndPause;
|
||||||
btrDataPacket.moveDirection = (byte)serverSideBtr.VehicleMoveDirection;
|
btrDataPacket.moveDirection = (byte)btrServerSide.VehicleMoveDirection;
|
||||||
btrDataPacket.MoveSpeed = serverSideBtr.moveSpeed;
|
btrDataPacket.MoveSpeed = btrServerSide.moveSpeed;
|
||||||
if (btrController.BotShooterBtr != null)
|
if (btrController.BotShooterBtr != null)
|
||||||
{
|
{
|
||||||
btrDataPacket.BtrBotId = btrController.BotShooterBtr.Id;
|
btrDataPacket.BtrBotId = btrController.BotShooterBtr.Id;
|
||||||
@ -181,30 +206,49 @@ namespace Aki.Debugging.BTR
|
|||||||
|
|
||||||
private void DisableServerSideRenderers()
|
private void DisableServerSideRenderers()
|
||||||
{
|
{
|
||||||
var meshRenderers = serverSideBtr.transform.GetComponentsInChildren<MeshRenderer>();
|
var meshRenderers = btrServerSide.transform.GetComponentsInChildren<MeshRenderer>();
|
||||||
foreach (var renderer in meshRenderers)
|
foreach (var renderer in meshRenderers)
|
||||||
{
|
{
|
||||||
renderer.enabled = false;
|
renderer.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AimAtEnemy()
|
||||||
|
{
|
||||||
|
if (btrController.BotShooterBtr == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var btrTurret = btrServerSide.BTRTurret;
|
||||||
|
var enemies = btrController.BotShooterBtr.BotsGroup.Enemies;
|
||||||
|
if (enemies.Any())
|
||||||
|
{
|
||||||
|
btrTurret.EnableAimingObject(enemies.First().Key.Transform.Original);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btrTurret.DisableAiming();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DestroyGameObjects()
|
private void DestroyGameObjects()
|
||||||
{
|
{
|
||||||
if (btrController != null)
|
if (btrController != null)
|
||||||
{
|
{
|
||||||
if (serverSideBtr != null)
|
if (btrServerSide != null)
|
||||||
{
|
{
|
||||||
Destroy(serverSideBtr.gameObject);
|
Destroy(btrServerSide.gameObject);
|
||||||
}
|
}
|
||||||
if (clientSideBtr != null)
|
if (btrClientSide != null)
|
||||||
{
|
{
|
||||||
Destroy(clientSideBtr.gameObject);
|
Destroy(btrClientSide.gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
btrController.Dispose();
|
btrController.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gameWorld != null)
|
if (gameWorld?.MainPlayer != null)
|
||||||
{
|
{
|
||||||
gameWorld.MainPlayer.OnBtrStateChanged -= HandleBtrDoorState;
|
gameWorld.MainPlayer.OnBtrStateChanged -= HandleBtrDoorState;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
using Aki.Reflection.Patching;
|
||||||
|
using Aki.Reflection.Utils;
|
||||||
|
using Comfort.Common;
|
||||||
|
using EFT;
|
||||||
|
using EFT.UI.Screens;
|
||||||
|
using HarmonyLib;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using static EFT.UI.TraderDialogScreen;
|
||||||
|
|
||||||
|
namespace Aki.Debugging.BTR.Patches
|
||||||
|
{
|
||||||
|
public class BTRActivateTraderDialogPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
var targetType = typeof(GClass1854).GetNestedTypes(PatchConstants.PrivateFlags).Where(x => x.Name == "Class1469").First();
|
||||||
|
return AccessTools.Method(targetType, "method_2");
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static bool PatchPrefix()
|
||||||
|
{
|
||||||
|
var gameWorld = Singleton<GameWorld>.Instance;
|
||||||
|
var player = gameWorld.MainPlayer;
|
||||||
|
|
||||||
|
var questController = (GClass3201)AccessTools.Field(player.GetType(), "_questController").GetValue(player);
|
||||||
|
var inventoryController = (InventoryControllerClass)AccessTools.Field(player.GetType(), "_inventoryController").GetValue(player);
|
||||||
|
|
||||||
|
GClass3130 btrDialog = new GClass3130(player.Profile, Profile.TraderInfo.BTR_TRADER_ID, questController, inventoryController, null);
|
||||||
|
btrDialog.OnClose += player.UpdateInteractionCast;
|
||||||
|
btrDialog.ShowScreen(EScreenState.Queued);
|
||||||
|
//GClass1952.ShowDialogScreen(Profile.ETraderServiceSource.Btr, true);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
using Aki.Reflection.Patching;
|
||||||
|
using Comfort.Common;
|
||||||
|
using EFT;
|
||||||
|
using EFT.Vehicle;
|
||||||
|
using HarmonyLib;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Aki.Debugging.BTR.Patches
|
||||||
|
{
|
||||||
|
public class BTRExtractPassengersPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod()
|
||||||
|
{
|
||||||
|
return AccessTools.Method(typeof(VehicleBase), "ExtractPassengers");
|
||||||
|
}
|
||||||
|
|
||||||
|
[PatchPrefix]
|
||||||
|
public static void PatchPrefix()
|
||||||
|
{
|
||||||
|
var gameWorld = Singleton<GameWorld>.Instance;
|
||||||
|
var player = gameWorld.MainPlayer;
|
||||||
|
var btrManager = gameWorld.GetComponent<BTRManager>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var btrSide = btrManager.LastInteractedBtrSide;
|
||||||
|
if (btrSide == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btrSide.TryGetCachedPlace(out byte b))
|
||||||
|
{
|
||||||
|
var interactionBtrPacket = btrSide.GetInteractWithBtrPacket(b, EInteractionType.GoOut);
|
||||||
|
if (interactionBtrPacket.HasInteraction)
|
||||||
|
{
|
||||||
|
BTRView btrView = gameWorld.BtrController.BtrView;
|
||||||
|
if (btrView == null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("BtrView not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
btrManager.OnPlayerInteractDoor(interactionBtrPacket);
|
||||||
|
btrView.Interaction(player, interactionBtrPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex19)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogException(ex19);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ namespace Aki.Debugging.BTR.Patches
|
|||||||
{
|
{
|
||||||
var gameWorld = Singleton<GameWorld>.Instance;
|
var gameWorld = Singleton<GameWorld>.Instance;
|
||||||
var player = (Player)__instance;
|
var player = (Player)__instance;
|
||||||
|
var btrManager = gameWorld.GetComponent<BTRManager>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -33,10 +34,8 @@ namespace Aki.Debugging.BTR.Patches
|
|||||||
{
|
{
|
||||||
throw new NullReferenceException("BtrView not found");
|
throw new NullReferenceException("BtrView not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
var btrManager = gameWorld.GetComponent<BTRManager>();
|
|
||||||
btrManager.OnPlayerInteractDoor(interactionBtrPacket);
|
btrManager.OnPlayerInteractDoor(interactionBtrPacket);
|
||||||
|
|
||||||
btrView.Interaction(player, interactionBtrPacket);
|
btrView.Interaction(player, interactionBtrPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,13 @@ namespace Aki.Debugging.BTR.Patches
|
|||||||
[PatchPrefix]
|
[PatchPrefix]
|
||||||
public static bool PatchPrefix(ref bool __result)
|
public static bool PatchPrefix(ref bool __result)
|
||||||
{
|
{
|
||||||
var btrView = Singleton<GameWorld>.Instance?.BtrController?.BtrView;
|
var serverSideBTR = Singleton<GameWorld>.Instance?.BtrController.BtrVehicle;
|
||||||
if (btrView == null)
|
if (serverSideBTR == null)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var btrSides = (BTRSide[])AccessTools.Field(typeof(BTRView), "_btrSides").GetValue(btrView);
|
if (serverSideBTR.LeftSideState == 0 && serverSideBTR.RightSideState == 0)
|
||||||
int doorsClosed = 0;
|
|
||||||
foreach (var side in btrSides)
|
|
||||||
{
|
|
||||||
if (side.State == BTRSide.EState.Free)
|
|
||||||
{
|
|
||||||
doorsClosed++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doorsClosed == btrSides.Length)
|
|
||||||
{
|
{
|
||||||
__result = true;
|
__result = true;
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user