using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Rewired;
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Prone")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Prone")]
[assembly: AssemblyTitle("Prone")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Prone
{
[BepInPlugin("sodmods.prone", "Prone", "1.0.0")]
public class Plugin : BasePlugin
{
internal static ManualLogSource Logger;
internal static ConfigEntry<float> HoldTime;
internal static ConfigEntry<KeyCode> ProneKey;
internal static ConfigEntry<float> BodyHeight;
internal static ConfigEntry<float> EyeHeight;
internal static ConfigEntry<float> CrawlSpeed;
internal static ConfigEntry<float> TransitionTime;
public override void Load()
{
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BasePlugin)this).Log;
HoldTime = ((BasePlugin)this).Config.Bind<float>("Controls", "HoldCrouchSeconds", 0.5f, "Hold Crouch this long to lie down. 0 = disable the hold gesture (use ProneKey instead).");
ProneKey = ((BasePlugin)this).Config.Bind<KeyCode>("Controls", "ProneKey", (KeyCode)0, "Optional dedicated key to lie down / get back up to a crouch.");
BodyHeight = ((BasePlugin)this).Config.Bind<float>("Prone", "BodyHeight", 0.6f, "Height of your body (metres) while lying down.");
EyeHeight = ((BasePlugin)this).Config.Bind<float>("Prone", "EyeHeight", 0.25f, "Height of your eyes above the floor (metres) while lying down.");
CrawlSpeed = ((BasePlugin)this).Config.Bind<float>("Prone", "CrawlSpeed", 0.35f, "Movement speed while lying down, as a fraction of walking speed.");
TransitionTime = ((BasePlugin)this).Config.Bind<float>("Prone", "TransitionSeconds", 0.7f, "How long getting down or up takes.");
new Harmony("sodmods.prone").PatchAll(typeof(Plugin).Assembly);
((BasePlugin)this).Log.LogInfo((object)"Prone loaded");
}
}
internal static class ProneState
{
internal static bool Prone;
internal static float Amount;
internal static void Enter(Player player)
{
if (!Prone)
{
if (!((Actor)player).isCrouched)
{
((Actor)player).SetCrouched(true, false);
}
Prone = true;
player.RestorePlayerMovementSpeed();
}
}
internal static bool TryExit(Player player, bool quiet = false)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (!Prone)
{
return true;
}
if (!Room.ToCrouch(player))
{
if (!quiet)
{
InterfaceController instance = InterfaceController.Instance;
if (instance != null)
{
instance.NewGameMessage((GameMessageType)0, 0, "There's no room to get up here", (Icon)15, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
}
}
return false;
}
Prone = false;
player.RestorePlayerMovementSpeed();
return true;
}
internal static void Reset()
{
Prone = false;
Amount = 0f;
}
}
[HarmonyPatch(typeof(Player), "Update")]
internal static class ProneUpdatePatch
{
private static float crouchDownAt = -1f;
private static bool holdConsumed;
private static void Postfix(Player __instance)
{
try
{
if ((Object)(object)SessionData.Instance == (Object)null || !SessionData.Instance.play)
{
return;
}
if (((Actor)__instance).inAirVent || __instance.transitionActive)
{
if (ProneState.Prone || ProneState.Amount > 0f)
{
ProneState.Reset();
}
return;
}
HandleInput(__instance);
float num = (ProneState.Prone ? 1f : 0f);
if (ProneState.Amount != num || num != 0f)
{
float num2 = Time.deltaTime / Mathf.Max(0.05f, Plugin.TransitionTime.Value);
ProneState.Amount = Mathf.MoveTowards(ProneState.Amount, num, num2);
Apply(__instance, Mathf.SmoothStep(0f, 1f, ProneState.Amount));
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)ex);
}
}
private static void HandleInput(Player player)
{
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
InputController instance = InputController.Instance;
Player val = ((instance != null) ? instance.player : null);
if (val == null)
{
return;
}
bool flag = (Object)(object)InteractionController.Instance != (Object)null && InteractionController.Instance.lockedInInteraction != null;
float value = Plugin.HoldTime.Value;
if (value > 0f)
{
if (val.GetButtonDown("Crouch"))
{
crouchDownAt = Time.unscaledTime;
holdConsumed = false;
}
if (!val.GetButton("Crouch"))
{
crouchDownAt = -1f;
}
if (crouchDownAt > 0f && !holdConsumed && !flag && !ProneState.Prone && Time.unscaledTime - crouchDownAt >= value)
{
holdConsumed = true;
ProneState.Enter(player);
}
}
KeyCode value2 = Plugin.ProneKey.Value;
if ((int)value2 != 0 && Input.GetKeyDown(value2) && !flag)
{
if (ProneState.Prone)
{
ProneState.TryExit(player);
}
else
{
ProneState.Enter(player);
}
}
if (ProneState.Prone && !((Actor)player).isCrouched)
{
ProneState.TryExit(player, quiet: true);
}
}
private static void Apply(Player player, float t)
{
CharacterController charController = player.charController;
float playerHeightCrouched = player.GetPlayerHeightCrouched();
float num = Mathf.Max(Plugin.BodyHeight.Value, charController.radius * 2f + 0.02f);
player.SetPlayerHeight(Mathf.Lerp(playerHeightCrouched, num, t), true);
float num2 = Plugin.EyeHeight.Value - player.GetPlayerHeightNormal() * 0.5f;
player.SetCameraHeight(Mathf.Lerp(GameplayControls.Instance.cameraHeightCrouched, num2, t));
}
}
[HarmonyPatch(typeof(Actor), "SetCrouched")]
internal static class SetCrouchedPatch
{
private static bool Prefix(Actor __instance, bool newVal)
{
if (newVal || !ProneState.Prone || !__instance.isPlayer)
{
return true;
}
Player val = ((Il2CppObjectBase)__instance).TryCast<Player>();
if ((Object)(object)val == (Object)null || ((Actor)val).inAirVent || val.transitionActive)
{
return true;
}
ProneState.TryExit(val);
return false;
}
}
[HarmonyPatch(typeof(Player), "SetMaxSpeed")]
internal static class CrawlSpeedPatch
{
private static void Prefix(Player __instance, ref float newWalkSpeed, ref float newRunSpeed)
{
if (ProneState.Prone && !__instance.transitionActive)
{
newWalkSpeed *= Plugin.CrawlSpeed.Value;
newRunSpeed = newWalkSpeed;
}
}
}
[HarmonyPatch(typeof(FirstPersonController), "UpdateMovement")]
internal static class NoJumpPatch
{
private static void Prefix(FirstPersonController __instance)
{
if (ProneState.Prone || ProneState.Amount > 0f)
{
__instance.m_Jump = false;
}
}
}
internal static class Room
{
public static bool ToCrouch(Player player)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
CharacterController charController = player.charController;
Transform transform = ((Component)player).transform;
Vector3 val = transform.position + Vector3.down * (player.GetPlayerHeightNormal() * 0.5f);
float playerHeightCrouched = player.GetPlayerHeightCrouched();
Vector3 val2 = val + Vector3.up * (charController.radius + 0.05f);
Vector3 val3 = val + Vector3.up * (playerHeightCrouched - charController.radius);
foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapCapsule(val2, val3, charController.radius * 0.9f, Toolbox.Instance.playerMovementLayerMask, (QueryTriggerInteraction)1))
{
if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)charController) && !((Component)item).transform.IsChildOf(transform))
{
return false;
}
}
return true;
}
}
}