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 HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WhiteKnuckleExtraJumps")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: AssemblyInformationalVersion("2.3.0")]
[assembly: AssemblyProduct("WhiteKnuckleExtraJumps")]
[assembly: AssemblyTitle("WhiteKnuckleExtraJumps")]
[assembly: AssemblyVersion("2.3.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 WhiteKnuckleExtraJumps
{
[BepInPlugin("com.whiteknuckle.extrajumpsindicator", "Extra Jumps Indicator", "2.3.1")]
public class ExtraJumpsIndicatorPlugin : BaseUnityPlugin
{
public const string PluginGUID = "com.whiteknuckle.extrajumpsindicator";
public const string PluginName = "Extra Jumps Indicator";
public const string PluginVersion = "2.3.1";
internal static ManualLogSource ModLogger;
public static ConfigEntry<float> VerticalOffset;
public static ConfigEntry<int> FontSize;
public static ConfigEntry<float> TextAlpha;
public static ConfigEntry<bool> ShowOnlyInAir;
private static Object _playerUnityObject;
private static object _playerInstance;
private static FieldInfo _fieldExtraJumps;
private static FieldInfo _fieldTempExtraJumps;
private static FieldInfo _fieldDead;
private static FieldInfo _fieldHealth;
private static MethodInfo _methodIsGrounded;
private static MethodInfo _methodIsLocked;
private static MethodInfo _methodIsInCutscene;
private static MethodInfo _methodIsInteractionLocked;
private static Type _inventoryType;
private static MethodInfo _methodIsShowingInventory;
private static Type _osManagerType;
private static FieldInfo _fieldOSInUse;
private static FieldInfo _fieldOSActiveComputer;
private static MethodInfo _methodIsAnyComputerInUse;
private static Type _uiManagerType;
private static FieldInfo _fieldUIManagerInstance;
private static FieldInfo _fieldCrosshair;
public static int TotalJumpsAvailable;
public static bool IsGrounded = true;
public static float CurrentAlpha = 0.65f;
private float _reconnectTimer;
private static GUIStyle _cachedStyle;
private static int _lastFontSize = -1;
private void Awake()
{
ModLogger = ((BaseUnityPlugin)this).Logger;
VerticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "VerticalOffset", 38f, "Vertical offset below the crosshair");
FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Visual", "FontSize", 30, "Font size of the counter");
TextAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "TextAlpha", 0.65f, "Text opacity (0.0 - 1.0)");
ShowOnlyInAir = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "ShowOnlyInAir", false, "Show counter only when player is airborne");
InitReflection();
SceneManager.sceneLoaded += OnSceneLoaded;
ModLogger.LogInfo((object)"Extra Jumps Indicator v2.3.1 initialized.");
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
ResetState();
}
private static void ResetState()
{
_playerUnityObject = null;
_playerInstance = null;
TotalJumpsAvailable = 0;
CurrentAlpha = 0f;
IsGrounded = true;
}
private void InitReflection()
{
try
{
_inventoryType = AccessTools.TypeByName("Inventory");
if (_inventoryType != null)
{
_methodIsShowingInventory = AccessTools.Method(_inventoryType, "IsShowingInventory", new Type[0], (Type[])null);
}
_osManagerType = AccessTools.TypeByName("OS_Manager");
if (_osManagerType != null)
{
_fieldOSInUse = AccessTools.Field(_osManagerType, "inUse");
_fieldOSActiveComputer = AccessTools.Field(_osManagerType, "activeComputer");
_methodIsAnyComputerInUse = AccessTools.Method(_osManagerType, "IsAnyComputerInUse", new Type[0], (Type[])null);
}
_uiManagerType = AccessTools.TypeByName("CL_UIManager");
if (_uiManagerType != null)
{
_fieldUIManagerInstance = AccessTools.Field(_uiManagerType, "instance");
_fieldCrosshair = AccessTools.Field(_uiManagerType, "crosshair");
}
}
catch
{
}
}
private void Update()
{
if (_playerUnityObject == (Object)null || _playerInstance == null)
{
TotalJumpsAvailable = 0;
CurrentAlpha = 0f;
_reconnectTimer += Time.deltaTime;
if (_reconnectTimer >= 0.5f)
{
_reconnectTimer = 0f;
FindPlayer();
}
return;
}
try
{
if (_fieldDead != null && (bool)_fieldDead.GetValue(_playerInstance))
{
TotalJumpsAvailable = 0;
CurrentAlpha = 0f;
return;
}
if (_fieldHealth != null && Convert.ToSingle(_fieldHealth.GetValue(_playerInstance)) <= 0f)
{
TotalJumpsAvailable = 0;
CurrentAlpha = 0f;
return;
}
int num = 0;
if (_fieldExtraJumps != null)
{
num += Convert.ToInt32(_fieldExtraJumps.GetValue(_playerInstance));
}
if (_fieldTempExtraJumps != null)
{
num += Convert.ToInt32(_fieldTempExtraJumps.GetValue(_playerInstance));
}
TotalJumpsAvailable = num;
if (_methodIsGrounded != null)
{
IsGrounded = (bool)_methodIsGrounded.Invoke(_playerInstance, new object[1] { false });
}
}
catch
{
ResetState();
return;
}
if (ShouldHideIndicator())
{
CurrentAlpha = 0f;
}
else
{
CurrentAlpha = Mathf.Clamp01(TextAlpha.Value);
}
}
private static bool ShouldHideIndicator()
{
if (Time.timeScale == 0f)
{
return true;
}
if (IsInventoryOpen())
{
return true;
}
if (IsComputerOrTerminalOpen())
{
return true;
}
if (IsPlayerLocked())
{
return true;
}
if (IsCrosshairHidden())
{
return true;
}
return false;
}
private static bool IsInventoryOpen()
{
try
{
if (_methodIsShowingInventory != null)
{
return (bool)_methodIsShowingInventory.Invoke(null, null);
}
}
catch
{
}
return false;
}
private static bool IsComputerOrTerminalOpen()
{
try
{
if (_methodIsAnyComputerInUse != null && (bool)_methodIsAnyComputerInUse.Invoke(null, null))
{
return true;
}
if (_fieldOSInUse != null && (bool)_fieldOSInUse.GetValue(null))
{
return true;
}
if (_fieldOSActiveComputer != null && _fieldOSActiveComputer.GetValue(null) != null)
{
return true;
}
}
catch
{
}
return false;
}
private static bool IsPlayerLocked()
{
if (_playerUnityObject == (Object)null || _playerInstance == null)
{
return true;
}
try
{
if (_methodIsLocked != null && (bool)_methodIsLocked.Invoke(_playerInstance, null))
{
return true;
}
if (_methodIsInCutscene != null && (bool)_methodIsInCutscene.Invoke(_playerInstance, null))
{
return true;
}
if (_methodIsInteractionLocked != null && (bool)_methodIsInteractionLocked.Invoke(_playerInstance, null))
{
return true;
}
}
catch
{
}
return false;
}
private static bool IsCrosshairHidden()
{
try
{
if (_fieldUIManagerInstance != null && _fieldCrosshair != null)
{
object value = _fieldUIManagerInstance.GetValue(null);
if (value != null)
{
object? value2 = _fieldCrosshair.GetValue(value);
Component val = (Component)((value2 is Component) ? value2 : null);
if ((Object)(object)val != (Object)null && !val.gameObject.activeInHierarchy)
{
return true;
}
}
}
}
catch
{
}
return false;
}
private void OnGUI()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
if (TotalJumpsAvailable > 0 && !(CurrentAlpha <= 0.001f) && (!ShowOnlyInAir.Value || !IsGrounded))
{
if (_cachedStyle == null || _lastFontSize != FontSize.Value)
{
_lastFontSize = FontSize.Value;
_cachedStyle = new GUIStyle(GUI.skin.label)
{
alignment = (TextAnchor)4,
fontSize = _lastFontSize,
fontStyle = (FontStyle)1
};
}
_cachedStyle.normal.textColor = new Color(1f, 1f, 1f, CurrentAlpha);
float num = (float)Screen.width * 0.5f;
float num2 = (float)Screen.height * 0.5f + VerticalOffset.Value;
GUI.Label(new Rect(num - 60f, num2 - 30f, 120f, 60f), TotalJumpsAvailable.ToString(), _cachedStyle);
}
}
private void FindPlayer()
{
Type type = AccessTools.TypeByName("ENT_Player");
if (type == null)
{
return;
}
object obj = null;
MethodInfo methodInfo = AccessTools.Method(type, "GetPlayer", new Type[0], (Type[])null);
if (methodInfo != null)
{
obj = methodInfo.Invoke(null, null);
}
if (obj == null)
{
FieldInfo fieldInfo = AccessTools.Field(type, "playerObject");
if (fieldInfo != null)
{
obj = fieldInfo.GetValue(null);
}
}
if (obj == null)
{
obj = Object.FindObjectOfType(type);
}
Object val = (Object)((obj is Object) ? obj : null);
if (val != (Object)null)
{
_playerUnityObject = val;
_playerInstance = obj;
_fieldExtraJumps = AccessTools.Field(type, "extraJumpsRemaining") ?? AccessTools.Field(type, "extraJumps");
_fieldTempExtraJumps = AccessTools.Field(type, "temporaryExtraJumpsRemaining") ?? AccessTools.Field(type, "temporaryExtraJumps");
_fieldDead = AccessTools.Field(type, "dead");
_fieldHealth = AccessTools.Field(type, "health");
_methodIsGrounded = AccessTools.Method(type, "IsGrounded", new Type[1] { typeof(bool) }, (Type[])null) ?? AccessTools.Method(type, "IsGrounded", new Type[0], (Type[])null);
_methodIsLocked = AccessTools.Method(type, "IsLocked", new Type[0], (Type[])null);
_methodIsInCutscene = AccessTools.Method(type, "IsInCutsceneMode", new Type[0], (Type[])null);
_methodIsInteractionLocked = AccessTools.Method(type, "IsInteractionLocked", new Type[0], (Type[])null);
}
}
}
}