2024-01-03 16:06:50 +00:00
using Aki.Reflection.Patching ;
2024-01-20 09:20:32 +00:00
using Comfort.Common ;
using EFT ;
using EFT.NextObservedPlayer ;
2024-01-03 16:06:50 +00:00
using EFT.UI ;
using EFT.Vehicle ;
using HarmonyLib ;
2024-01-20 09:20:32 +00:00
using System ;
using System.Linq ;
2024-01-03 16:06:50 +00:00
using System.Reflection ;
using UnityEngine ;
2024-01-23 08:47:09 +00:00
namespace Aki.Custom.BTR.Patches
2024-01-03 16:06:50 +00:00
{
// Fixes the BTR Bot initialization in method_1() of BTRTurretView
//
// Context:
// ClientGameWorld in LiveEFT will register the server-side BTR Bot as type ObservedPlayerView and is stored in GameWorld's allObservedPlayersByID dictionary.
// In SPT, allObservedPlayersByID is empty which results in the game never finishing the initialization of the BTR Bot which includes disabling its gun, voice and mesh renderers.
// For now, we do dirty patches to work around the lack of ObservedPlayerView, using Player instead.
2024-01-23 08:47:09 +00:00
public class BTRBotInitPatch : ModulePatch
2024-01-03 16:06:50 +00:00
{
protected override MethodBase GetTargetMethod ( )
{
2024-01-25 08:52:33 +00:00
return AccessTools . Method ( typeof ( BTRTurretView ) , nameof ( BTRTurretView . method_1 ) ) ;
2024-01-03 16:06:50 +00:00
}
[PatchPostfix]
2024-01-20 09:20:32 +00:00
private static void PatchPostfix ( BTRTurretView __instance , int btrBotId , ref bool __result )
2024-01-03 16:06:50 +00:00
{
var gameWorld = Singleton < GameWorld > . Instance ;
2024-01-20 09:20:32 +00:00
if ( gameWorld = = null )
{
2024-01-25 08:52:33 +00:00
Logger . LogError ( "[AKI-BTR] BTRBotInitPatch - GameWorld is null" ) ;
2024-01-20 09:20:32 +00:00
return ;
}
2024-01-03 16:06:50 +00:00
2024-01-20 09:20:32 +00:00
var alivePlayersList = gameWorld . AllAlivePlayersList ;
bool doesBtrBotExist = alivePlayersList . Exists ( x = > x . Id = = btrBotId ) ;
if ( doesBtrBotExist )
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
try
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
Player player = alivePlayersList . First ( x = > x . Id = = btrBotId ) ;
Renderer [ ] array = player . GetComponentsInChildren < Renderer > ( ) ;
for ( int i = 0 ; i < array . Length ; i + + )
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
array [ i ] . enabled = false ;
}
var aiFirearmController = player . gameObject . GetComponent < Player . FirearmController > ( ) ;
var currentWeaponPrefab = ( WeaponPrefab ) AccessTools . Field ( aiFirearmController . GetType ( ) , "weaponPrefab_0" ) . GetValue ( aiFirearmController ) ;
if ( currentWeaponPrefab . RemoveChildrenOf ! = null )
{
foreach ( var text in currentWeaponPrefab . RemoveChildrenOf )
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
var transform = currentWeaponPrefab . transform . FindTransform ( text ) ;
2024-01-25 08:52:33 +00:00
transform . gameObject . SetActive ( false ) ;
2024-01-03 16:06:50 +00:00
}
2024-01-20 09:20:32 +00:00
}
foreach ( var renderer in currentWeaponPrefab . GetComponentsInChildren < Renderer > ( ) )
{
if ( renderer . name = = "MuzzleJetCombinedMesh" )
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
renderer . transform . localPosition = new Vector3 ( 0.18f , 0f , - 0.095f ) ;
2024-01-03 16:06:50 +00:00
}
2024-01-20 09:20:32 +00:00
else
2024-01-03 16:06:50 +00:00
{
2024-01-20 09:20:32 +00:00
renderer . enabled = false ;
2024-01-03 16:06:50 +00:00
}
2024-01-20 09:20:32 +00:00
}
2024-01-03 16:06:50 +00:00
2024-01-20 09:20:32 +00:00
var tuple = new ValueTuple < ObservedPlayerView , bool > ( new ObservedPlayerView ( ) , true ) ;
var btrTurretViewTupleField = AccessTools . Field ( __instance . GetType ( ) , "valueTuple_0" ) ;
btrTurretViewTupleField . SetValue ( __instance , tuple ) ;
2024-01-03 16:06:50 +00:00
2024-01-20 09:20:32 +00:00
__result = true ;
}
catch
{
ConsoleScreen . LogError ( "[AKI-BTR] BtrBot initialization failed, BtrBot will be visible ingame. Check logs." ) ;
throw ;
2024-01-03 16:06:50 +00:00
}
}
}
}
}