Decompiled source of Movement Suite v1.0.2

Movement_Suite/SlideCooldownOverlay.dll

Decompiled 7 hours ago
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 ComputerysModdingUtilities;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.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 SlideCooldownOverlay
{
	[BepInPlugin("landa.straftat.slidecooldownoverlay", "Slide Cooldown Overlay", "1.2.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> AlwaysShow;

		internal static ConfigEntry<bool> ShowLabel;

		internal static ConfigEntry<float> YFraction;

		internal static ConfigEntry<float> BarWidth;

		internal static ConfigEntry<float> BarHeight;

		internal static ConfigEntry<float> ReadyFlash;

		private void Awake()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			AlwaysShow = ((BaseUnityPlugin)this).Config.Bind<bool>("SlideCooldownOverlay.Display", "AlwaysShow", false, "Show the bar even while slide is ready. Off = only during cooldown plus a short ready flash.");
			ShowLabel = ((BaseUnityPlugin)this).Config.Bind<bool>("SlideCooldownOverlay.Display", "ShowLabel", true, "Show remaining seconds while cooling down and SLIDE when it becomes ready.");
			YFraction = ((BaseUnityPlugin)this).Config.Bind<float>("SlideCooldownOverlay.Display", "VerticalPosition", 0.78f, new ConfigDescription("Bar position as a fraction of screen height (0 = top, 1 = bottom).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.95f), Array.Empty<object>()));
			BarWidth = ((BaseUnityPlugin)this).Config.Bind<float>("SlideCooldownOverlay.Display", "BarWidth", 180f, "Bar width in pixels at 1080p (scales with resolution).");
			BarHeight = ((BaseUnityPlugin)this).Config.Bind<float>("SlideCooldownOverlay.Display", "BarHeight", 10f, "Bar height in pixels at 1080p (scales with resolution).");
			ReadyFlash = ((BaseUnityPlugin)this).Config.Bind<float>("SlideCooldownOverlay.Display", "ReadyFlashSeconds", 0.35f, "How long the green ready flash stays on screen after the cooldown ends.");
			GameObject val = new GameObject("SlideCooldownOverlay");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<OverlayBehaviour>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Slide Cooldown Overlay loaded.");
		}

		private void OnDisable()
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Plugin component disabled.");
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"Plugin component destroyed.");
		}
	}
	internal class OverlayBehaviour : MonoBehaviour
	{
		private Type _fpcType;

		private FieldInfo _slideResetTimer;

		private FieldInfo _slideResetTime;

		private PropertyInfo _isOwner;

		private Type _phType;

		private PropertyInfo _healthProp;

		private Component _playerHealth;

		private Component _player;

		private float _nextScan;

		private bool _wasCooling;

		private float _readyAt = -1f;

		private bool _loggedFirstCooldown;

		private bool _warnedNoOwner;

		private Texture2D _tex;

		private GUIStyle _labelStyle;

		private void Awake()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			_fpcType = Type.GetType("FirstPersonController, Assembly-CSharp");
			if (_fpcType == null)
			{
				Plugin.Log.LogError((object)"FirstPersonController not found in Assembly-CSharp - the game may have updated. Overlay disabled.");
				((Behaviour)this).enabled = false;
				return;
			}
			_slideResetTimer = _fpcType.GetField("slideResetTimer", BindingFlags.Instance | BindingFlags.NonPublic);
			_slideResetTime = _fpcType.GetField("slideResetTime", BindingFlags.Instance | BindingFlags.NonPublic);
			_isOwner = _fpcType.GetProperty("IsOwner");
			if (_slideResetTimer == null || _slideResetTime == null)
			{
				Plugin.Log.LogError((object)"Slide cooldown fields not found - the game may have updated. Overlay disabled.");
				((Behaviour)this).enabled = false;
				return;
			}
			_phType = Type.GetType("PlayerHealth, Assembly-CSharp");
			_healthProp = ((_phType != null) ? _phType.GetProperty("SyncAccessor_health") : null);
			if (_healthProp == null)
			{
				Plugin.Log.LogWarning((object)"PlayerHealth.SyncAccessor_health not found - overlay will not auto-hide on death.");
			}
			_tex = new Texture2D(1, 1, (TextureFormat)4, false);
			_tex.SetPixel(0, 0, Color.white);
			_tex.Apply();
			Plugin.Log.LogInfo((object)"Overlay behaviour alive.");
		}

		private void Update()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			if ((Object)(object)_player == (Object)null && Time.unscaledTime >= _nextScan)
			{
				_nextScan = Time.unscaledTime + 1f;
				Camera main = Camera.main;
				if ((Object)(object)main != (Object)null)
				{
					Component componentInParent = ((Component)main).GetComponentInParent(_fpcType);
					if ((Object)(object)componentInParent != (Object)null)
					{
						Bind(componentInParent, "camera hierarchy");
						return;
					}
				}
				Object[] array = Object.FindObjectsOfType(_fpcType);
				Object[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					Component val = (Component)array2[i];
					bool flag;
					try
					{
						flag = _isOwner != null && (bool)_isOwner.GetValue(val, null);
					}
					catch
					{
						flag = false;
					}
					if (flag)
					{
						Bind(val, "IsOwner");
						return;
					}
				}
				if (array.Length == 1)
				{
					Bind((Component)array[0], "only controller in scene");
				}
				else if (array.Length != 0 && !_warnedNoOwner)
				{
					_warnedNoOwner = true;
					Plugin.Log.LogWarning((object)$"Found {array.Length} controllers but could not identify the local player.");
				}
			}
			else if ((Object)(object)_player != (Object)null && !_loggedFirstCooldown)
			{
				CheckFirstCooldown();
			}
		}

		private void Bind(Component player, string how)
		{
			_player = player;
			_playerHealth = ((_phType != null) ? player.GetComponent(_phType) : null);
			Plugin.Log.LogInfo((object)("Bound to local player via " + how + ": " + ((Object)player).name));
		}

		private void CheckFirstCooldown()
		{
			float num = (float)_slideResetTimer.GetValue(_player);
			if (num > 0f)
			{
				_loggedFirstCooldown = true;
				Plugin.Log.LogInfo((object)$"Slide cooldown ticking: {num:0.00}s remaining of {(float)_slideResetTime.GetValue(_player):0.00}s.");
			}
		}

		private void OnGUI()
		{
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Expected O, but got Unknown
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null || Cursor.visible)
			{
				return;
			}
			if ((Object)(object)_playerHealth != (Object)null && _healthProp != null)
			{
				try
				{
					if (Convert.ToSingle(_healthProp.GetValue(_playerHealth, null)) <= 0f)
					{
						_wasCooling = false;
						_readyAt = -1f;
						return;
					}
				}
				catch
				{
				}
			}
			float num = (float)_slideResetTimer.GetValue(_player);
			float num2 = Mathf.Max(0.01f, (float)_slideResetTime.GetValue(_player));
			bool flag = num > 0f;
			if (flag)
			{
				_wasCooling = true;
			}
			else if (_wasCooling)
			{
				_wasCooling = false;
				_readyAt = Time.unscaledTime;
			}
			float num3 = ((!flag && _readyAt >= 0f) ? (1f - (Time.unscaledTime - _readyAt) / Mathf.Max(0.01f, Plugin.ReadyFlash.Value)) : 0f);
			bool flag2 = num3 > 0f;
			if (!flag && !flag2 && !Plugin.AlwaysShow.Value)
			{
				return;
			}
			float num4 = (float)Screen.height / 1080f;
			float num5 = Plugin.BarWidth.Value * num4;
			float num6 = Plugin.BarHeight.Value * num4;
			float num7 = ((float)Screen.width - num5) / 2f;
			float num8 = (float)Screen.height * Plugin.YFraction.Value;
			if (flag2)
			{
				for (int num9 = 3; num9 >= 1; num9--)
				{
					float num10 = (float)num9 * 3f * num4;
					GUI.DrawTexture(new Rect(num7 - num10, num8 - num10, num5 + num10 * 2f, num6 + num10 * 2f), (Texture)(object)_tex, (ScaleMode)0, true, 0f, new Color(0.3f, 1f, 0.45f, 0.1f * num3), 0f, (num6 + num10 * 2f) / 2f);
				}
			}
			GUI.DrawTexture(new Rect(num7, num8, num5, num6), (Texture)(object)_tex, (ScaleMode)0, true, 0f, new Color(0.07f, 0.07f, 0.08f, 0.38f), 0f, num6 / 2f);
			float num11 = 1.5f * num4;
			float num12 = num6 - num11 * 2f;
			float num13 = (num5 - num11 * 2f) * (flag ? Mathf.Clamp01(1f - num / num2) : 1f);
			Color val = (flag ? new Color(0.96f, 0.93f, 0.84f, 0.9f) : (flag2 ? new Color(0.3f, 1f, 0.45f, 0.5f + 0.5f * num3) : new Color(0.96f, 0.93f, 0.84f, 0.55f)));
			if (num13 > 0.5f)
			{
				GUI.DrawTexture(new Rect(num7 + num11, num8 + num11, num13, num12), (Texture)(object)_tex, (ScaleMode)0, true, 0f, val, 0f, Mathf.Min(num12, num13) / 2f);
			}
			if (Plugin.ShowLabel.Value)
			{
				if (_labelStyle == null)
				{
					_labelStyle = new GUIStyle
					{
						alignment = (TextAnchor)4,
						fontStyle = (FontStyle)0
					};
				}
				_labelStyle.fontSize = Mathf.RoundToInt(13f * num4);
				float num14 = (flag ? 0.85f : num3);
				if (num14 > 0.01f)
				{
					string text = (flag ? num.ToString("0.0") : "SLIDE");
					Rect val2 = default(Rect);
					((Rect)(ref val2))..ctor(num7, num8 - 20f * num4, num5, 18f * num4);
					_labelStyle.normal.textColor = new Color(0f, 0f, 0f, 0.5f * num14);
					GUI.Label(new Rect(((Rect)(ref val2)).x + 1f * num4, ((Rect)(ref val2)).y + 1f * num4, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), text, _labelStyle);
					_labelStyle.normal.textColor = (flag ? new Color(0.97f, 0.95f, 0.9f, num14) : new Color(0.5f, 1f, 0.6f, num14));
					GUI.Label(val2, text, _labelStyle);
				}
			}
		}

		private void OnDisable()
		{
			Plugin.Log.LogWarning((object)"Overlay behaviour disabled.");
		}

		private void OnDestroy()
		{
			Plugin.Log.LogWarning((object)"Overlay behaviour destroyed.");
		}
	}
}

Movement_Suite/MovementTrainer.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.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 MovementTrainer
{
	[BepInPlugin("landa.straftat.movementtrainer", "Movement Trainer", "1.3.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ShowWallPip;

		internal static ConfigEntry<bool> ShowHopJudge;

		internal static ConfigEntry<bool> ShowSlideGrader;

		internal static ConfigEntry<bool> ShowAirMeter;

		internal static ConfigEntry<bool> ShowMomentum;

		internal static ConfigEntry<bool> ShowCarveMeter;

		internal static ConfigEntry<float> PanelX;

		internal static ConfigEntry<float> PanelY;

		internal static ConfigEntry<float> Scale;

		internal static ConfigEntry<float> CleanHopMs;

		private void Awake()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ShowWallPip = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "WallJumpPip", true, "Wall jump status: bright green pip = armed or stored right now, dim pip = available but needs wall contact, dark pip = spent for this airtime.");
			ShowHopJudge = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "HopJudge", true, "Streak of clean buffered hops; a slow landing resets it.");
			ShowSlideGrader = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "SlideJumpGrader", true, "Times each slide-to-jump exit in milliseconds and grades the rep.");
			ShowAirMeter = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "AirtimeMeter", true, "Rolling share of time spent airborne (about a 15 second window).");
			ShowMomentum = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "MomentumXray", true, "Live speed channels: IN = steerable input speed (flashes when weapon fire slowdown is active), BURST = slide impulse plus the single boost slot, labelled by what fired it (WALL/VAULT/KICK/BOOST).");
			ShowCarveMeter = ((BaseUnityPlugin)this).Config.Bind<bool>("MovementTrainer.Widgets", "CarveMeter", true, "Turn efficiency: how much of your requested input speed is actually delivered. 100% = lossless carve; dips mean the turn is faster than your velocity can follow (the flick tax).");
			PanelX = ((BaseUnityPlugin)this).Config.Bind<float>("MovementTrainer.Panel", "X", 0.015f, new ConfigDescription("Panel left edge as a fraction of screen width.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>()));
			PanelY = ((BaseUnityPlugin)this).Config.Bind<float>("MovementTrainer.Panel", "Y", 0.62f, new ConfigDescription("Panel top edge as a fraction of screen height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.95f), Array.Empty<object>()));
			Scale = ((BaseUnityPlugin)this).Config.Bind<float>("MovementTrainer.Panel", "Scale", 1f, new ConfigDescription("Panel scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2f), Array.Empty<object>()));
			CleanHopMs = ((BaseUnityPlugin)this).Config.Bind<float>("MovementTrainer.Tuning", "CleanHopMs", 80f, "Maximum ground-contact time in milliseconds for a landing to count as a clean buffered hop.");
			GameObject val = new GameObject("MovementTrainer");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<TrainerBehaviour>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Movement Trainer loaded.");
		}
	}
	internal class TrainerBehaviour : MonoBehaviour
	{
		private Type _fpcType;

		private FieldInfo _canWallJump;

		private FieldInfo _wallJumpsCount;

		private FieldInfo _maxWallJumps;

		private FieldInfo _isSliding;

		private FieldInfo _isTouching;

		private FieldInfo _vaultTimer;

		private FieldInfo _moveDirection;

		private FieldInfo _currentInput;

		private FieldInfo _forceAdded;

		private FieldInfo _bforcefinal;

		private FieldInfo _bfactor;

		private FieldInfo _setSpeedTimer;

		private PropertyInfo _isOwner;

		private Type _phType;

		private PropertyInfo _healthProp;

		private Component _player;

		private Component _playerHealth;

		private CharacterController _cc;

		private float _nextScan;

		private bool _warnedNoOwner;

		private bool _wasDead;

		private bool _wasGrounded;

		private float _groundedAt;

		private int _streak;

		private int _bestStreak;

		private bool _wasSliding;

		private float _slideStart = -1f;

		private float _slideEndAt = -1f;

		private bool _slideJudged = true;

		private float _lastSlideMs = -1f;

		private string _lastVerdict = "";

		private readonly Queue<float> _slideReps = new Queue<float>();

		private float _airEma;

		private string _bOwner = "BOOST";

		private float _lastBf;

		private int _lastWallJumps;

		private float _lastVault;

		private bool _slideRepFrame;

		private bool _slideStartFrame;

		private float _carveEma = 1f;

		private bool _carveActive;

		private Texture2D _tex;

		private GUIStyle _style;

		private static readonly Color Cream = new Color(0.96f, 0.93f, 0.84f, 0.92f);

		private static readonly Color CreamDim = new Color(0.96f, 0.93f, 0.84f, 0.45f);

		private static readonly Color Green = new Color(0.3f, 1f, 0.45f, 0.95f);

		private static readonly Color GreenDim = new Color(0.3f, 1f, 0.45f, 0.4f);

		private static readonly Color Dark = new Color(0.25f, 0.25f, 0.27f, 0.85f);

		private static readonly Color Smoke = new Color(0.07f, 0.07f, 0.08f, 0.38f);

		private static readonly Color Warn = new Color(1f, 0.55f, 0.35f, 0.95f);

		private void Awake()
		{
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			_fpcType = Type.GetType("FirstPersonController, Assembly-CSharp");
			if (_fpcType == null)
			{
				Plugin.Log.LogError((object)"FirstPersonController not found - the game may have updated. Trainer disabled.");
				((Behaviour)this).enabled = false;
				return;
			}
			_canWallJump = F("CanWallJump");
			_wallJumpsCount = F("wallJumpsCount");
			_maxWallJumps = F("maxWallJumps");
			_isSliding = F("isSliding");
			_isTouching = F("isTouchingAnything");
			_vaultTimer = F("aftervaultjumpTimer");
			_moveDirection = F("moveDirection");
			_currentInput = F("currentInput");
			_forceAdded = F("forceAdded");
			_bforcefinal = F("bforcefinal");
			_bfactor = F("bfactor");
			_setSpeedTimer = F("setSpeedTimer");
			if (_currentInput == null || _forceAdded == null || _bforcefinal == null)
			{
				Plugin.Log.LogWarning((object)"Momentum fields not found - momentum X-ray disabled.");
			}
			_isOwner = _fpcType.GetProperty("IsOwner");
			if (_canWallJump == null)
			{
				Plugin.Log.LogWarning((object)"CanWallJump not found - wall pip disabled.");
			}
			if (_isSliding == null || _moveDirection == null)
			{
				Plugin.Log.LogWarning((object)"isSliding/moveDirection not found - slide grader disabled.");
			}
			if (_vaultTimer == null)
			{
				Plugin.Log.LogWarning((object)"aftervaultjumpTimer not found - double-jump countdown disabled.");
			}
			_phType = Type.GetType("PlayerHealth, Assembly-CSharp");
			_healthProp = ((_phType != null) ? _phType.GetProperty("SyncAccessor_health") : null);
			if (_healthProp == null)
			{
				Plugin.Log.LogWarning((object)"PlayerHealth.SyncAccessor_health not found - trainer will not auto-hide on death.");
			}
			_tex = new Texture2D(1, 1, (TextureFormat)4, false);
			_tex.SetPixel(0, 0, Color.white);
			_tex.Apply();
			Plugin.Log.LogInfo((object)"Trainer behaviour alive.");
		}

		private FieldInfo F(string name)
		{
			return _fpcType.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private void Update()
		{
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null)
			{
				if (Time.unscaledTime >= _nextScan)
				{
					Rescan();
				}
				return;
			}
			bool flag = (Object)(object)_cc != (Object)null && _cc.isGrounded;
			if (IsDead())
			{
				if (!_wasDead)
				{
					_streak = 0;
					_slideJudged = true;
					_wasDead = true;
				}
				return;
			}
			if (_wasDead)
			{
				_wasDead = false;
				_wasGrounded = flag;
				_wasSliding = false;
			}
			float unscaledTime = Time.unscaledTime;
			if (flag && !_wasGrounded)
			{
				_groundedAt = unscaledTime;
			}
			if (!flag && _wasGrounded)
			{
				if ((unscaledTime - _groundedAt) * 1000f <= Plugin.CleanHopMs.Value)
				{
					_streak++;
					if (_streak > _bestStreak)
					{
						_bestStreak = _streak;
					}
				}
				else
				{
					_streak = 0;
				}
			}
			if (_isSliding != null && _moveDirection != null)
			{
				bool flag2 = (bool)_isSliding.GetValue(_player);
				if (flag2 && !_wasSliding)
				{
					_slideStart = unscaledTime;
					_slideJudged = false;
					_slideStartFrame = true;
				}
				if (!flag2 && _wasSliding)
				{
					_slideEndAt = unscaledTime;
				}
				if (!_slideJudged && _slideStart >= 0f)
				{
					float num = 0f;
					try
					{
						num = ((Vector3)_moveDirection.GetValue(_player)).y;
					}
					catch
					{
					}
					if (num > 2f)
					{
						_lastSlideMs = (unscaledTime - _slideStart) * 1000f;
						_lastVerdict = ((_lastSlideMs <= 150f) ? "PERFECT" : ((_lastSlideMs <= 300f) ? "GOOD" : "LATE"));
						_slideReps.Enqueue(_lastSlideMs);
						while (_slideReps.Count > 10)
						{
							_slideReps.Dequeue();
						}
						_slideJudged = true;
						_slideRepFrame = true;
					}
					else if (!flag2 && unscaledTime - _slideEndAt > 0.25f)
					{
						_lastSlideMs = -1f;
						_lastVerdict = "NO JUMP";
						_slideJudged = true;
					}
				}
				_wasSliding = flag2;
			}
			_airEma = Mathf.Lerp(_airEma, flag ? 0f : 1f, Mathf.Clamp01(Time.deltaTime / 15f));
			if (_bfactor != null)
			{
				float num2 = 0f;
				int num3 = _lastWallJumps;
				float num4 = _lastVault;
				try
				{
					num2 = (float)_bfactor.GetValue(_player);
				}
				catch
				{
				}
				try
				{
					if (_wallJumpsCount != null)
					{
						num3 = (int)_wallJumpsCount.GetValue(_player);
					}
				}
				catch
				{
				}
				try
				{
					if (_vaultTimer != null)
					{
						num4 = (float)_vaultTimer.GetValue(_player);
					}
				}
				catch
				{
				}
				if (num2 > _lastBf + 0.3f)
				{
					if (num3 > _lastWallJumps)
					{
						_bOwner = "WALL";
					}
					else if (num4 > _lastVault + 0.2f)
					{
						_bOwner = "VAULT";
					}
					else if (_slideRepFrame)
					{
						_bOwner = "KICK";
					}
					else
					{
						_bOwner = "BOOST";
					}
				}
				_lastBf = num2;
				_lastWallJumps = num3;
				_lastVault = num4;
			}
			if (_currentInput != null && _moveDirection != null)
			{
				float num5 = 0f;
				Vector3 val = Vector3.zero;
				Vector2 val2;
				try
				{
					val2 = (Vector2)_currentInput.GetValue(_player);
					num5 = ((Vector2)(ref val2)).magnitude;
				}
				catch
				{
				}
				try
				{
					val = (Vector3)_moveDirection.GetValue(_player);
				}
				catch
				{
				}
				if (num5 > 2f && !_slideStartFrame)
				{
					val2 = new Vector2(val.x, val.z);
					float num6 = Mathf.Clamp01(((Vector2)(ref val2)).magnitude / num5);
					_carveEma = Mathf.Lerp(_carveEma, num6, Mathf.Clamp01(Time.deltaTime / 0.12f));
					_carveActive = true;
				}
				else if (num5 <= 2f)
				{
					_carveActive = false;
					_carveEma = 1f;
				}
			}
			_slideRepFrame = false;
			_slideStartFrame = false;
			_wasGrounded = flag;
		}

		private void Rescan()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			_nextScan = Time.unscaledTime + 1f;
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				Component componentInParent = ((Component)main).GetComponentInParent(_fpcType);
				if ((Object)(object)componentInParent != (Object)null)
				{
					Bind(componentInParent, "camera hierarchy");
					return;
				}
			}
			Object[] array = Object.FindObjectsOfType(_fpcType);
			Object[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				Component val = (Component)array2[i];
				bool flag;
				try
				{
					flag = _isOwner != null && (bool)_isOwner.GetValue(val, null);
				}
				catch
				{
					flag = false;
				}
				if (flag)
				{
					Bind(val, "IsOwner");
					return;
				}
			}
			if (array.Length == 1)
			{
				Bind((Component)array[0], "only controller in scene");
			}
			else if (array.Length != 0 && !_warnedNoOwner)
			{
				_warnedNoOwner = true;
				Plugin.Log.LogWarning((object)$"Found {array.Length} controllers but could not identify the local player.");
			}
		}

		private void Bind(Component player, string how)
		{
			_player = player;
			_playerHealth = ((_phType != null) ? player.GetComponent(_phType) : null);
			_cc = player.GetComponent<CharacterController>();
			_wasGrounded = (Object)(object)_cc != (Object)null && _cc.isGrounded;
			_wasSliding = false;
			_slideJudged = true;
			Plugin.Log.LogInfo((object)("Bound to local player via " + how + ": " + ((Object)player).name));
		}

		private bool IsDead()
		{
			if ((Object)(object)_playerHealth == (Object)null || _healthProp == null)
			{
				return false;
			}
			try
			{
				return Convert.ToSingle(_healthProp.GetValue(_playerHealth, null)) <= 0f;
			}
			catch
			{
				return false;
			}
		}

		private void OnGUI()
		{
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null || Cursor.visible || IsDead())
			{
				return;
			}
			bool flag = Plugin.ShowWallPip.Value && _canWallJump != null;
			bool value = Plugin.ShowHopJudge.Value;
			bool flag2 = Plugin.ShowSlideGrader.Value && _isSliding != null;
			bool value2 = Plugin.ShowAirMeter.Value;
			bool flag3 = Plugin.ShowMomentum.Value && _currentInput != null && _forceAdded != null && _bforcefinal != null;
			bool flag4 = Plugin.ShowCarveMeter.Value && _currentInput != null && _moveDirection != null;
			int num = (flag ? 1 : 0) + (value ? 1 : 0) + (flag2 ? 1 : 0) + (value2 ? 1 : 0) + (flag3 ? 2 : 0) + (flag4 ? 1 : 0);
			if (num == 0)
			{
				return;
			}
			float num2 = (float)Screen.height / 1080f * Plugin.Scale.Value;
			float num3 = 19f * num2;
			float num4 = 7f * num2;
			float num5 = 195f * num2;
			float num6 = (float)Screen.width * Plugin.PanelX.Value;
			float num7 = (float)Screen.height * Plugin.PanelY.Value;
			GUI.DrawTexture(new Rect(num6, num7, num5, (float)num * num3 + num4 * 2f), (Texture)(object)_tex, (ScaleMode)0, true, 0f, Smoke, 0f, 8f * num2);
			if (_style == null)
			{
				_style = new GUIStyle
				{
					alignment = (TextAnchor)3,
					fontStyle = (FontStyle)0
				};
			}
			_style.fontSize = Mathf.RoundToInt(12f * num2);
			float num8 = num6 + num4;
			float num9 = num5 - num4 * 2f;
			float num10 = num7 + num4;
			if (flag)
			{
				DrawWallLine(new Rect(num8, num10, num9, num3), num2);
				num10 += num3;
			}
			if (value)
			{
				Text(new Rect(num8, num10, num9, num3), $"HOPS  {_streak}   BEST {_bestStreak}", (_streak >= 5) ? Green : Cream, num2);
				num10 += num3;
			}
			if (flag2)
			{
				string text;
				Color color;
				if (_lastVerdict == "")
				{
					text = "SLIDE-JUMP  --";
					color = CreamDim;
				}
				else if (_lastVerdict == "NO JUMP")
				{
					text = "SLIDE-JUMP  NO JUMP";
					color = Warn;
				}
				else
				{
					text = $"SLIDE-JUMP  {_lastSlideMs:0}ms {_lastVerdict}";
					if (_slideReps.Count > 1)
					{
						float num11 = 0f;
						foreach (float slideRep in _slideReps)
						{
							num11 += slideRep;
						}
						text += $"  avg {num11 / (float)_slideReps.Count:0}";
					}
					color = ((_lastVerdict == "PERFECT") ? Green : ((_lastVerdict == "GOOD") ? Cream : Warn));
				}
				Text(new Rect(num8, num10, num9, num3), text, color, num2);
				num10 += num3;
			}
			if (value2)
			{
				Text(new Rect(num8, num10, num9, num3), $"AIR  {Mathf.RoundToInt(_airEma * 100f)}%", Cream, num2);
				num10 += num3;
			}
			if (flag3)
			{
				DrawMomentum(num8, num10, num9, num3, num2);
				num10 += num3 * 2f;
			}
			if (flag4)
			{
				Color color2 = ((_carveEma >= 0.97f) ? Green : ((_carveEma >= 0.9f) ? Cream : Warn));
				DrawChannel(num8, num10, num9, num3, num2, "CARVE", _carveEma, color2, _carveActive ? $"{_carveEma * 100f:0}%" : "--");
			}
		}

		private void DrawMomentum(float lx, float ly, float lw, float lineH, float s)
		{
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			bool flag = false;
			try
			{
				Vector2 val = (Vector2)_currentInput.GetValue(_player);
				num = ((Vector2)(ref val)).magnitude;
			}
			catch
			{
			}
			Vector3 val2;
			try
			{
				val2 = (Vector3)_forceAdded.GetValue(_player);
				num2 = ((Vector3)(ref val2)).magnitude;
			}
			catch
			{
			}
			try
			{
				val2 = (Vector3)_bforcefinal.GetValue(_player);
				num3 = ((Vector3)(ref val2)).magnitude;
			}
			catch
			{
			}
			try
			{
				flag = _setSpeedTimer != null && (float)_setSpeedTimer.GetValue(_player) > 0f;
			}
			catch
			{
			}
			float num4 = num2 + num3;
			DrawChannel(lx, ly, lw, lineH, s, "IN", num / 14f, flag ? Warn : Cream, $"{num:0.0}" + (flag ? " SLOWED" : ""));
			ly += lineH;
			string arg = "";
			if (num2 > 0.5f && num3 > 0.5f)
			{
				arg = "SLD+" + _bOwner;
			}
			else if (num2 > 0.5f)
			{
				arg = "SLIDE";
			}
			else if (num3 > 0.5f)
			{
				arg = _bOwner;
			}
			DrawChannel(lx, ly, lw, lineH, s, "BURST", num4 / 60f, Green, (num4 > 0.5f) ? $"{num4:0.0} {arg}" : "--");
		}

		private void DrawChannel(float lx, float ly, float lw, float lineH, float s, string label, float frac, Color color, string value)
		{
			//IL_000d: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Text(new Rect(lx, ly, 44f * s, lineH), label, Cream, s);
			float num = 6f * s;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(lx + 46f * s, ly + (lineH - num) / 2f, 64f * s, num);
			GUI.DrawTexture(val, (Texture)(object)_tex, (ScaleMode)0, true, 0f, Smoke, 0f, num / 2f);
			float num2 = ((Rect)(ref val)).width * Mathf.Clamp01(frac);
			if (num2 > 0.5f)
			{
				GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, num2, num), (Texture)(object)_tex, (ScaleMode)0, true, 0f, color, 0f, Mathf.Min(num, num2) / 2f);
			}
			Text(new Rect(lx + 116f * s, ly, lw - 116f * s, lineH), value, (value == "--") ? CreamDim : color, s);
		}

		private void DrawWallLine(Rect r, float s)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			float num = 10f * s;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref r)).x + 46f * s, ((Rect)(ref r)).y + (((Rect)(ref r)).height - num) / 2f, num, num);
			Rect r2 = default(Rect);
			((Rect)(ref r2))..ctor(((Rect)(ref r)).x + 62f * s, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 62f * s, ((Rect)(ref r)).height);
			Text(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, ((Rect)(ref r)).height), "WALL", Cream, s);
			if (_vaultTimer != null)
			{
				float num2 = 0f;
				try
				{
					num2 = (float)_vaultTimer.GetValue(_player);
				}
				catch
				{
				}
				if (num2 > 0f)
				{
					GUI.DrawTexture(val, (Texture)(object)_tex, (ScaleMode)0, true, 0f, Green, 0f, num / 2f);
					Text(r2, $"DBL JUMP {num2:0.00}", Green, s);
					return;
				}
			}
			bool flag = false;
			bool flag2 = false;
			int num3 = 0;
			int num4 = 1;
			try
			{
				flag = (bool)_canWallJump.GetValue(_player);
				if (_isTouching != null)
				{
					flag2 = (bool)_isTouching.GetValue(_player);
				}
				if (_wallJumpsCount != null)
				{
					num3 = (int)_wallJumpsCount.GetValue(_player);
				}
				if (_maxWallJumps != null)
				{
					num4 = (int)_maxWallJumps.GetValue(_player);
				}
			}
			catch
			{
			}
			int num5 = num4 - num3;
			bool flag3 = flag && !flag2;
			Color val2 = (flag3 ? Green : (flag ? GreenDim : ((num5 > 0) ? CreamDim : Dark)));
			GUI.DrawTexture(val, (Texture)(object)_tex, (ScaleMode)0, true, 0f, val2, 0f, num / 2f);
			string text = (flag3 ? "BANKED" : ((!flag && num5 <= 0) ? "SPENT" : ""));
			if (num5 > 1)
			{
				text = text + ((text == "") ? "" : " ") + $"x{num5}";
			}
			if (text != "")
			{
				Text(r2, text, flag3 ? Green : CreamDim, s);
			}
		}

		private void Text(Rect r, string text, Color color, float s)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			_style.normal.textColor = new Color(0f, 0f, 0f, 0.5f * color.a);
			GUI.Label(new Rect(((Rect)(ref r)).x + 1f * s, ((Rect)(ref r)).y + 1f * s, ((Rect)(ref r)).width, ((Rect)(ref r)).height), text, _style);
			_style.normal.textColor = color;
			GUI.Label(r, text, _style);
		}

		private void OnDisable()
		{
			Plugin.Log.LogWarning((object)"Trainer behaviour disabled.");
		}

		private void OnDestroy()
		{
			Plugin.Log.LogWarning((object)"Trainer behaviour destroyed.");
		}
	}
}