Decompiled source of RunBasedPassives v0.4.1

plugins/RunBasedPassives.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MoreUIPanel;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RunBasedPassives")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RunBasedPassives")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d3524128-8d57-4661-a37a-6231cfd2059c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RunBasedPassives;

[BepInPlugin("cn_xc.RunBasedPassives", "RunBasedPassives", "0.4.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	private ConfigEntry<bool> enableJump;

	private ConfigEntry<bool> enableStrength;

	private ConfigEntry<bool> enableStamina;

	private ConfigEntry<bool> enableHealth;

	private ConfigEntry<bool> enableSprintSpeed;

	private ConfigEntry<bool> enableCrouchRestore;

	private ConfigEntry<bool> verboseLogging;

	private ConfigEntry<int> sprintSpeedCap;

	public static int JumpLevel;

	public static int StrengthLevel;

	public static int StaminaLevel;

	public static int HealthLevel;

	public static int SprintSpeedLevel;

	public static int CrouchRestoreLevel;

	public static int JumpCount;

	public static int GrabCount;

	public static float MoveDistance;

	public static int HealCount;

	public static float SprintDistance;

	public static float CrouchRestoreAmount;

	public static float LastEnergyCurrent = -1f;

	private static int _lastLogJump;

	private static int _lastLogGrab;

	private static int _lastLogHeal;

	private static int _lastLogCrouch;

	private static float _lastLogMove;

	private static float _lastLogSprint;

	private Harmony harmony;

	private static FieldRef<PlayerController, int> jumpExtraRef;

	private static FieldRef<PlayerHealth, int> maxHealthRef;

	private static FieldRef<PlayerAvatar, string> steamIDRef;

	private static FieldRef<PlayerAvatar, bool> isLocalRef;

	private static FieldRef<PlayerHealth, PlayerAvatar> healthPlayerAvatarRef;

	private static FieldRef<StatsManager, SortedDictionary<string, Dictionary<string, int>>> dictOfDictsRef;

	private static FieldRef<PlayerAvatar, bool> crouchRestActiveRef;

	private static FieldRef<PlayerAvatar, float> crouchRestRef;

	private static FieldRef<StatsManager, string> saveFileCurrentRef;

	private bool _uiRegistered;

	private float _staminaBase = -1f;

	private float _originalSprintSpeed = -1f;

	private string _lastSaveFile = "";

	private int GetJumpThreshold()
	{
		return 80 + JumpLevel * 40;
	}

	private int GetGrabThreshold()
	{
		return 50 + StrengthLevel * 10;
	}

	private float GetMoveThreshold()
	{
		return 500f + (float)StaminaLevel * 200f;
	}

	private int GetHealThreshold()
	{
		return 10 + HealthLevel * 3;
	}

	private float GetSprintThreshold()
	{
		return 300f + (float)SprintSpeedLevel * 100f;
	}

	private float GetCrouchThreshold()
	{
		return 80f + (float)CrouchRestoreLevel * 20f;
	}

	private void Awake()
	{
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Expected O, but got Unknown
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Expected O, but got Unknown
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Expected O, but got Unknown
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Expected O, but got Unknown
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b0: Expected O, but got Unknown
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Expected O, but got Unknown
		enableJump = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableJump", true, "启用跳跃升级");
		enableStrength = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableStrength", true, "启用力量升级");
		enableStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableStamina", true, "启用耐力升级");
		enableHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableHealth", true, "启用生命升级");
		enableSprintSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableSprintSpeed", true, "启用冲刺速度升级");
		enableCrouchRestore = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableCrouchRestore", true, "启用蹲伏恢复升级");
		verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "详细日志输出(用于调试)");
		sprintSpeedCap = ((BaseUnityPlugin)this).Config.Bind<int>("Thresholds", "SprintSpeedCap", 0, new ConfigDescription("冲刺速度封顶等级(0=不封顶)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
		jumpExtraRef = AccessTools.FieldRefAccess<PlayerController, int>("JumpExtra");
		maxHealthRef = AccessTools.FieldRefAccess<PlayerHealth, int>("maxHealth");
		steamIDRef = AccessTools.FieldRefAccess<PlayerAvatar, string>("steamID");
		isLocalRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isLocal");
		healthPlayerAvatarRef = AccessTools.FieldRefAccess<PlayerHealth, PlayerAvatar>("playerAvatar");
		dictOfDictsRef = AccessTools.FieldRefAccess<StatsManager, SortedDictionary<string, Dictionary<string, int>>>("dictionaryOfDictionaries");
		crouchRestActiveRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("upgradeCrouchRestActive");
		crouchRestRef = AccessTools.FieldRefAccess<PlayerAvatar, float>("upgradeCrouchRest");
		saveFileCurrentRef = AccessTools.FieldRefAccess<StatsManager, string>("saveFileCurrent");
		Patches.isLocalRef = isLocalRef;
		Patches.steamIDRef = steamIDRef;
		Patches.healthPlayerAvatarRef = healthPlayerAvatarRef;
		Patches.crouchRestActiveRef = crouchRestActiveRef;
		Patches.crouchRestRef = crouchRestRef;
		Patches.pluginLogger = ((BaseUnityPlugin)this).Logger;
		Patches.verboseLogging = verboseLogging;
		Harmony.DEBUG = true;
		harmony = new Harmony("cn_xc.RunBasedPassives");
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Jump", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "JumpPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PhysGrabObject), "GrabStarted", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "GrabStartedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "PlayerAvatarUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerHealth), "Heal", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "HealPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		SceneManager.sceneLoaded += OnSceneLoaded;
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Harmony 补丁总数: {harmony.GetPatchedMethods().Count()}");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"RunBasedPassives v0.4.1 loaded");
		if (verboseLogging.Value)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"详细日志已开启(仅在经验变化时输出)");
		}
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		if (_uiRegistered)
		{
			Plugin.UnregisterLine("runbasedpassives_stats");
		}
		harmony.UnpatchAll((string)null);
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		ResetCounters();
	}

	private void ResetCounters()
	{
		string text = saveFileCurrentRef.Invoke(StatsManager.instance) ?? "";
		if (_lastSaveFile != text)
		{
			_lastSaveFile = text;
			JumpCount = 0;
			GrabCount = 0;
			MoveDistance = 0f;
			HealCount = 0;
			SprintDistance = 0f;
			CrouchRestoreAmount = 0f;
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[场景加载] 检测到存档切换,经验已清零");
			}
		}
		else
		{
			JumpCount %= GetJumpThreshold();
			GrabCount %= GetGrabThreshold();
			MoveDistance %= GetMoveThreshold();
			HealCount %= GetHealThreshold();
			SprintDistance %= GetSprintThreshold();
			CrouchRestoreAmount %= GetCrouchThreshold();
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[场景加载] 经验已继承: 跳跃:{JumpCount}/{GetJumpThreshold()} 力量:{GrabCount}/{GetGrabThreshold()} 耐力:{MoveDistance:F0}/{GetMoveThreshold()} 生命:{HealCount}/{GetHealThreshold()} 冲刺:{SprintDistance:F0}/{GetSprintThreshold()} 蹲伏:{CrouchRestoreAmount:F0}/{GetCrouchThreshold()}");
			}
		}
		_staminaBase = -1f;
		_originalSprintSpeed = -1f;
		LastEnergyCurrent = -1f;
		Patches.ResetState();
	}

	private void Update()
	{
		if ((Object)(object)PlayerAvatar.instance == (Object)null)
		{
			return;
		}
		bool flag = SemiFunc.RunIsLevel() || SemiFunc.RunIsShop();
		if (flag && !_uiRegistered)
		{
			Plugin.RegisterLine("runbasedpassives_stats", (Func<string>)BuildDisplayText);
			_uiRegistered = true;
		}
		else if (!flag && _uiRegistered)
		{
			Plugin.UnregisterLine("runbasedpassives_stats");
			_uiRegistered = false;
		}
		if (!flag)
		{
			return;
		}
		string steamID = GetSteamID();
		if (!string.IsNullOrEmpty(steamID))
		{
			JumpLevel = ReadGameDict("playerUpgradeExtraJump", steamID);
			StrengthLevel = ReadGameDict("playerUpgradeStrength", steamID);
			StaminaLevel = ReadGameDict("playerUpgradeStamina", steamID);
			HealthLevel = ReadGameDict("playerUpgradeHealth", steamID);
			SprintSpeedLevel = ReadGameDict("playerUpgradeSpeed", steamID);
			CrouchRestoreLevel = ReadGameDict("playerUpgradeCrouchRest", steamID);
		}
		if (_staminaBase <= 0f && (Object)(object)PlayerController.instance != (Object)null)
		{
			_staminaBase = PlayerController.instance.EnergyStart;
		}
		CheckUpgrades();
		ApplyStats();
		if (verboseLogging.Value)
		{
			bool flag2 = (int)CrouchRestoreAmount != _lastLogCrouch;
			if (JumpCount != _lastLogJump || GrabCount != _lastLogGrab || (int)MoveDistance != (int)_lastLogMove || HealCount != _lastLogHeal || (int)SprintDistance != (int)_lastLogSprint || flag2)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[状态] 跳跃:{JumpCount}/{GetJumpThreshold()} Lv.{JumpLevel} | 力量:{GrabCount}/{GetGrabThreshold()} Lv.{StrengthLevel} | 耐力:{MoveDistance:F0}/{GetMoveThreshold()} Lv.{StaminaLevel} | 生命:{HealCount}/{GetHealThreshold()} Lv.{HealthLevel} | 冲刺:{SprintDistance:F0}/{GetSprintThreshold()} Lv.{SprintSpeedLevel} | 蹲伏:{CrouchRestoreAmount:F0}/{GetCrouchThreshold()} Lv.{CrouchRestoreLevel}");
				_lastLogJump = JumpCount;
				_lastLogGrab = GrabCount;
				_lastLogMove = MoveDistance;
				_lastLogHeal = HealCount;
				_lastLogSprint = SprintDistance;
				_lastLogCrouch = (int)CrouchRestoreAmount;
			}
		}
	}

	private int ReadGameDict(string dictName, string sid)
	{
		SortedDictionary<string, Dictionary<string, int>> sortedDictionary = dictOfDictsRef.Invoke(StatsManager.instance);
		if (sortedDictionary != null && sortedDictionary.TryGetValue(dictName, out var value) && value != null && value.TryGetValue(sid, out var value2))
		{
			return value2;
		}
		return 0;
	}

	private void CheckUpgrades()
	{
		string steamID = GetSteamID();
		if (string.IsNullOrEmpty(steamID))
		{
			return;
		}
		bool flag = false;
		if (enableJump.Value && JumpCount >= GetJumpThreshold())
		{
			JumpCount -= GetJumpThreshold();
			JumpLevel++;
			StatsManager instance = StatsManager.instance;
			if (instance != null)
			{
				instance.DictionaryUpdateValue("playerUpgradeExtraJump", steamID, JumpLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 跳跃升级至 Lv.{JumpLevel}");
			}
			flag = true;
		}
		if (enableStrength.Value && GrabCount >= GetGrabThreshold())
		{
			GrabCount -= GetGrabThreshold();
			StrengthLevel++;
			StatsManager instance2 = StatsManager.instance;
			if (instance2 != null)
			{
				instance2.DictionaryUpdateValue("playerUpgradeStrength", steamID, StrengthLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 力量升级至 Lv.{StrengthLevel}");
			}
			flag = true;
		}
		if (enableStamina.Value && MoveDistance >= GetMoveThreshold())
		{
			MoveDistance -= GetMoveThreshold();
			StaminaLevel++;
			StatsManager instance3 = StatsManager.instance;
			if (instance3 != null)
			{
				instance3.DictionaryUpdateValue("playerUpgradeStamina", steamID, StaminaLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 耐力升级至 Lv.{StaminaLevel}");
			}
			flag = true;
		}
		if (enableHealth.Value && HealCount >= GetHealThreshold())
		{
			HealCount -= GetHealThreshold();
			HealthLevel++;
			StatsManager instance4 = StatsManager.instance;
			if (instance4 != null)
			{
				instance4.DictionaryUpdateValue("playerUpgradeHealth", steamID, HealthLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 生命升级至 Lv.{HealthLevel}");
			}
			flag = true;
		}
		if (enableSprintSpeed.Value && SprintDistance >= GetSprintThreshold())
		{
			SprintDistance -= GetSprintThreshold();
			SprintSpeedLevel++;
			StatsManager instance5 = StatsManager.instance;
			if (instance5 != null)
			{
				instance5.DictionaryUpdateValue("playerUpgradeSpeed", steamID, SprintSpeedLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 冲刺速度升级至 Lv.{SprintSpeedLevel}");
			}
			flag = true;
		}
		if (enableCrouchRestore.Value && CrouchRestoreAmount >= GetCrouchThreshold())
		{
			CrouchRestoreAmount -= GetCrouchThreshold();
			CrouchRestoreLevel++;
			StatsManager instance6 = StatsManager.instance;
			if (instance6 != null)
			{
				instance6.DictionaryUpdateValue("playerUpgradeCrouchRest", steamID, CrouchRestoreLevel);
			}
			if (verboseLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 蹲伏恢复升级至 Lv.{CrouchRestoreLevel}");
			}
			flag = true;
		}
		if (flag && (Object)(object)StatsUI.instance != (Object)null)
		{
			StatsUI.instance.Fetch();
		}
	}

	private void ApplyStats()
	{
		PlayerController instance = PlayerController.instance;
		PlayerAvatar instance2 = PlayerAvatar.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
		{
			return;
		}
		if (enableJump.Value)
		{
			jumpExtraRef.Invoke(instance) = JumpLevel;
		}
		if (enableStrength.Value)
		{
			PhysGrabber physGrabber = instance2.physGrabber;
			if ((Object)(object)physGrabber != (Object)null)
			{
				physGrabber.grabStrength = 1f + (float)StrengthLevel;
			}
		}
		if (enableStamina.Value)
		{
			float num = ((_staminaBase > 0f) ? _staminaBase : 100f);
			instance.EnergyStart = num + (float)(StaminaLevel * 10);
			if (instance.EnergyCurrent > instance.EnergyStart)
			{
				instance.EnergyCurrent = instance.EnergyStart;
			}
		}
		if (enableHealth.Value)
		{
			PlayerHealth playerHealth = instance2.playerHealth;
			if ((Object)(object)playerHealth != (Object)null)
			{
				maxHealthRef.Invoke(playerHealth) = 100 + HealthLevel * 20;
			}
		}
		if (enableSprintSpeed.Value)
		{
			if (_originalSprintSpeed < 0f)
			{
				_originalSprintSpeed = instance.SprintSpeed;
			}
			int num2 = SprintSpeedLevel;
			if (sprintSpeedCap.Value > 0 && num2 > sprintSpeedCap.Value)
			{
				num2 = sprintSpeedCap.Value;
			}
			instance.SprintSpeed = _originalSprintSpeed + (float)num2 * 1f;
		}
	}

	private string GetSteamID()
	{
		PlayerAvatar instance = PlayerAvatar.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return null;
		}
		return steamIDRef.Invoke(instance);
	}

	private string BuildDisplayText()
	{
		StringBuilder stringBuilder = new StringBuilder();
		if (enableJump.Value)
		{
			stringBuilder.AppendLine($"跳跃 Lv.{JumpLevel} ({JumpCount}/{GetJumpThreshold()})");
		}
		if (enableStrength.Value)
		{
			stringBuilder.AppendLine($"力量 Lv.{StrengthLevel} ({GrabCount}/{GetGrabThreshold()})");
		}
		if (enableStamina.Value)
		{
			stringBuilder.AppendLine($"耐力 Lv.{StaminaLevel} ({MoveDistance:F0}/{GetMoveThreshold()})");
		}
		if (enableHealth.Value)
		{
			stringBuilder.AppendLine($"生命 Lv.{HealthLevel} ({HealCount}/{GetHealThreshold()})");
		}
		if (enableSprintSpeed.Value)
		{
			stringBuilder.AppendLine($"冲刺 Lv.{SprintSpeedLevel} ({SprintDistance:F0}/{GetSprintThreshold()})");
		}
		if (enableCrouchRestore.Value)
		{
			stringBuilder.AppendLine($"蹲伏 Lv.{CrouchRestoreLevel} ({CrouchRestoreAmount:F0}/{GetCrouchThreshold()})");
		}
		return stringBuilder.ToString().TrimEnd(Array.Empty<char>());
	}
}
public static class Patches
{
	internal static FieldRef<PlayerAvatar, bool> isLocalRef;

	internal static FieldRef<PlayerAvatar, string> steamIDRef;

	internal static FieldRef<PlayerHealth, PlayerAvatar> healthPlayerAvatarRef;

	internal static FieldRef<PlayerAvatar, bool> crouchRestActiveRef;

	internal static FieldRef<PlayerAvatar, float> crouchRestRef;

	internal static ManualLogSource pluginLogger;

	internal static ConfigEntry<bool> verboseLogging;

	private static Vector3 lastPos;

	private static Vector3 lastSprintPos;

	private static bool lastPosInit;

	private static bool lastSprintPosInit;

	private static readonly HashSet<int> grabbedThisLevel = new HashSet<int>();

	private static bool IsInGameplay => SemiFunc.RunIsLevel() || SemiFunc.RunIsShop();

	public static void ResetState()
	{
		lastPosInit = (lastSprintPosInit = false);
		grabbedThisLevel.Clear();
	}

	public static void JumpPrefix(PlayerAvatar __instance)
	{
		if (IsInGameplay && isLocalRef.Invoke(__instance))
		{
			Plugin.JumpCount++;
		}
	}

	public static void GrabStartedPostfix(PhysGrabObject __instance)
	{
		if (!IsInGameplay || SemiFunc.RunIsShop())
		{
			return;
		}
		int instanceID = ((Object)__instance).GetInstanceID();
		if (grabbedThisLevel.Contains(instanceID))
		{
			return;
		}
		List<PhysGrabber> playerGrabbing = __instance.playerGrabbing;
		if (playerGrabbing == null)
		{
			return;
		}
		foreach (PhysGrabber item in playerGrabbing)
		{
			if ((Object)(object)item.playerAvatar != (Object)null && isLocalRef.Invoke(item.playerAvatar))
			{
				grabbedThisLevel.Add(instanceID);
				Plugin.GrabCount++;
				break;
			}
		}
	}

	public static void PlayerAvatarUpdatePostfix(PlayerAvatar __instance)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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_004e: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		if (!IsInGameplay || !isLocalRef.Invoke(__instance))
		{
			return;
		}
		Vector3 position = ((Component)__instance).transform.position;
		if (!lastPosInit)
		{
			lastPos = position;
			lastPosInit = true;
			return;
		}
		float num = Vector3.Distance(position, lastPos);
		Plugin.MoveDistance += num;
		lastPos = position;
		if ((Object)(object)PlayerController.instance != (Object)null && PlayerController.instance.sprinting)
		{
			if (!lastSprintPosInit)
			{
				lastSprintPos = position;
				lastSprintPosInit = true;
				return;
			}
			float num2 = Vector3.Distance(position, lastSprintPos);
			Plugin.SprintDistance += num2;
		}
		lastSprintPos = position;
		lastSprintPosInit = true;
		if (crouchRestActiveRef.Invoke(__instance))
		{
			PlayerController instance = PlayerController.instance;
			if (!((Object)(object)instance != (Object)null))
			{
				return;
			}
			float energyCurrent = instance.EnergyCurrent;
			if (Plugin.LastEnergyCurrent >= 0f)
			{
				float num3 = energyCurrent - Plugin.LastEnergyCurrent;
				if (num3 > 0f)
				{
					Plugin.CrouchRestoreAmount += num3;
				}
			}
			Plugin.LastEnergyCurrent = energyCurrent;
		}
		else
		{
			Plugin.LastEnergyCurrent = -1f;
		}
	}

	public static void HealPrefix(int healAmount, PlayerHealth __instance)
	{
		if (IsInGameplay && !SemiFunc.RunIsShop() && healAmount > 0)
		{
			PlayerAvatar val = healthPlayerAvatarRef.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && isLocalRef.Invoke(val))
			{
				Plugin.HealCount++;
			}
		}
	}
}