NAK_CVR_Mods/DoubleTapJumpToExitSeat/Main.cs
2025-04-12 16:20:22 -05:00

92 lines
No EOL
3.3 KiB
C#

using System.Reflection;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Systems.InputManagement;
using ABI_RC.Systems.Movement;
using HarmonyLib;
using MelonLoader;
using UnityEngine;
namespace NAK.DoubleTapJumpToExitSeat;
public class DoubleTapJumpToExitSeatMod : MelonMod
{
#region Melon Events
public override void OnInitializeMelon()
{
#region CVRSeat Patches
HarmonyInstance.Patch(
typeof(CVRSeat).GetMethod(nameof(CVRSeat.Update),
BindingFlags.NonPublic | BindingFlags.Instance),
prefix: new HarmonyMethod(typeof(DoubleTapJumpToExitSeatMod).GetMethod(nameof(OnPreCVRSeatUpdate),
BindingFlags.NonPublic | BindingFlags.Static))
);
#endregion CVRSeat Patches
#region ViewManager Patches
HarmonyInstance.Patch(
typeof(ViewManager).GetMethod(nameof(ViewManager.Update),
BindingFlags.NonPublic | BindingFlags.Instance),
prefix: new HarmonyMethod(typeof(DoubleTapJumpToExitSeatMod).GetMethod(nameof(OnPreViewManagerUpdate),
BindingFlags.NonPublic | BindingFlags.Static)),
postfix: new HarmonyMethod(typeof(DoubleTapJumpToExitSeatMod).GetMethod(nameof(OnPostViewManagerUpdate),
BindingFlags.NonPublic | BindingFlags.Static))
);
#endregion ViewManager Patches
}
#endregion Melon Events
#region Harmony Patches
private static float _lastJumpTime = -1f;
private static bool _wasJumping;
private static bool OnPreCVRSeatUpdate(CVRSeat __instance)
{
if (!__instance.occupied) return false;
// Crazy?
bool jumped = CVRInputManager.Instance.jump;
bool justJumped = jumped && !_wasJumping;
_wasJumping = jumped;
if (justJumped)
{
float t = Time.time;
if (t - _lastJumpTime <= BetterBetterCharacterController.DoubleJumpFlightTimeOut)
{
_lastJumpTime = -1f;
__instance.ExitSeat();
return false;
}
_lastJumpTime = t;
}
// Double update this frame (this ensures Extrapolate / Every Frame Updated objects are seated correctly)
if (__instance.vrSitPosition.position != __instance._lastPosition || __instance.vrSitPosition.rotation != __instance._lastRotation)
__instance.MovePlayerToSeat(__instance.vrSitPositionReady ? __instance.vrSitPosition : __instance.transform);
// Steal sync
if (__instance.lockControls)
{
if (__instance._spawnable != null) __instance._spawnable.ForceUpdate(4);
if (__instance._objectSync != null) __instance._objectSync.ForceUpdate(4);
}
return false; // don't call original method
}
// ReSharper disable once RedundantAssignment
private static void OnPreViewManagerUpdate(ref bool __state)
=> (__state, BetterBetterCharacterController.Instance._isSitting)
= (BetterBetterCharacterController.Instance._isSitting, false);
private static void OnPostViewManagerUpdate(ref bool __state)
=> BetterBetterCharacterController.Instance._isSitting = __state;
#endregion Harmony Patches
}