Decompiled source of JumpingPEAK v1.0.3

plugins/JumpingPEAK.dll

Decompiled 21 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
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("점핑피크")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("점핑피크")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e76b4db5-556b-4707-86df-0fd835832607")]
[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")]
[BepInPlugin("Sapphire009.BeforeStart", "BeforeStart", "1.0.0")]
public sealed class BeforeStart : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterMovement), "TryToJump")]
	private static class CharacterMovementTryToJumpPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(CharacterMovement __instance)
		{
			if (!ShouldBlockJump(__instance, out var character))
			{
				return true;
			}
			CaptureOriginalJumpImpulse(__instance);
			RestoreOriginalJumpImpulse(__instance);
			LogBlockedJump(character, "TryToJump");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "JumpRpc", new Type[] { typeof(bool) })]
	private static class CharacterMovementJumpRpcPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Sapphire009.JumpingPEAK", "Sapphire009.NoGround" })]
		private static bool Prefix(CharacterMovement __instance, bool __0, out bool __state)
		{
			__state = false;
			if (!ShouldBlockJump(__instance, out var character))
			{
				return true;
			}
			CaptureOriginalJumpImpulse(__instance);
			RestoreOriginalJumpImpulse(__instance);
			__state = true;
			LogBlockedJump(character, __0 ? "JumpRpc-PalJump" : "JumpRpc-Normal");
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "Sapphire009.JumpingPEAK", "Sapphire009.NoGround" })]
		private static void Postfix(CharacterMovement __instance, bool __state)
		{
			if (__state)
			{
				RestoreOriginalJumpImpulse(__instance);
			}
		}
	}

	public const string PluginGUID = "Sapphire009.BeforeStart";

	public const string PluginName = "BeforeStart";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "FirstMapWakeJumpLock-R1";

	private const float MinimumJumpLockDuration = 10f;

	private const float MaximumJumpLockDuration = 15f;

	private const int MaximumLogCount = 50;

	internal static ManualLogSource ModLogger;

	private static bool airportWasVisited;

	private static bool waitingForFirstMapCharacter;

	private static bool firstMapProtectionConsumed;

	private static int protectedSceneHandle = -1;

	private static string protectedSceneName = string.Empty;

	private static bool jumpLockActive;

	private static int protectedCharacterId = -1;

	private static float jumpLockStartedAt;

	private static readonly Dictionary<int, float> OriginalJumpImpulses = new Dictionary<int, float>();

	private static int protectionStartedLogCount;

	private static int blockedJumpLogCount;

	private static int protectionEndedLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.BeforeStart");
		harmony.PatchAll();
		SceneManager.sceneLoaded += OnSceneLoaded;
		Scene activeScene = SceneManager.GetActiveScene();
		if (IsAirportScene(activeScene))
		{
			RegisterAirportVisit();
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("BeforeStart 1.0.0 loaded. Build: FirstMapWakeJumpLock-R1. First-map jumping is disabled for approximately " + $"{10f:0} to " + $"{15f:0} seconds after character spawn."));
	}

	private void Update()
	{
		TryStartJumpLock();
		UpdateJumpLock();
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		ResetAllState();
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	private static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (IsAirportScene(scene))
		{
			RegisterAirportVisit();
		}
		else if (airportWasVisited && !firstMapProtectionConsumed && IsGameplayMapScene(scene))
		{
			protectedSceneHandle = ((Scene)(ref scene)).handle;
			protectedSceneName = ((Scene)(ref scene)).name;
			waitingForFirstMapCharacter = true;
			jumpLockActive = false;
			protectedCharacterId = -1;
			OriginalJumpImpulses.Clear();
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				modLogger.LogInfo((object)("[BeforeStart] Waiting for local character spawn. Scene=" + ((Scene)(ref scene)).name));
			}
		}
	}

	private static void RegisterAirportVisit()
	{
		airportWasVisited = true;
		waitingForFirstMapCharacter = false;
		firstMapProtectionConsumed = false;
		protectedSceneHandle = -1;
		protectedSceneName = string.Empty;
		jumpLockActive = false;
		protectedCharacterId = -1;
		jumpLockStartedAt = 0f;
		OriginalJumpImpulses.Clear();
	}

	private static void TryStartJumpLock()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!waitingForFirstMapCharacter || jumpLockActive)
		{
			return;
		}
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).handle != protectedSceneHandle)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || !localCharacter.IsLocal || (Object)(object)localCharacter.data == (Object)null)
		{
			return;
		}
		CharacterMovement val = ResolveMovement(localCharacter);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		protectedCharacterId = ((Object)localCharacter).GetInstanceID();
		jumpLockStartedAt = Time.time;
		jumpLockActive = true;
		waitingForFirstMapCharacter = false;
		firstMapProtectionConsumed = true;
		int instanceID = ((Object)val).GetInstanceID();
		if (val.jumpImpulse > 0f)
		{
			OriginalJumpImpulses[instanceID] = val.jumpImpulse;
		}
		if (protectionStartedLogCount < 50)
		{
			protectionStartedLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				modLogger.LogInfo((object)("[BeforeStart] First-map jump lock started " + $"({protectionStartedLogCount}/{50}). " + "Character=" + ((Object)localCharacter).name + ", " + $"MinimumDuration={10f:0.00}, " + $"MaximumDuration={15f:0.00}, " + "Scene=" + ((Scene)(ref activeScene)).name));
			}
		}
	}

	private static void UpdateJumpLock()
	{
		if (!jumpLockActive)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if ((Object)(object)localCharacter == (Object)null || !localCharacter.IsLocal || ((Object)localCharacter).GetInstanceID() != protectedCharacterId || (Object)(object)localCharacter.data == (Object)null)
		{
			EndJumpLock("CharacterUnavailable");
			return;
		}
		float num = Time.time - jumpLockStartedAt;
		bool flag = num >= 10f;
		bool flag2 = num >= 15f;
		bool flag3 = HasCharacterFinishedWaking(localCharacter);
		if ((flag && flag3) || flag2)
		{
			string reason = ((flag2 && !flag3) ? "MaximumDurationReached" : "CharacterRecovered");
			EndJumpLock(reason);
		}
	}

	private static bool HasCharacterFinishedWaking(Character character)
	{
		if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
		{
			return false;
		}
		if (character.data.dead || character.data.fullyPassedOut || character.data.passedOut)
		{
			return false;
		}
		if (character.data.fallSeconds > 0.01f)
		{
			return false;
		}
		if (character.data.passedOutOnTheBeach > 0f)
		{
			return false;
		}
		if (character.data.currentRagdollControll < 0.9f)
		{
			return false;
		}
		if (character.data.GetTargetRagdollControll() < 0.9f)
		{
			return false;
		}
		return true;
	}

	private static void EndJumpLock(string reason)
	{
		//IL_00db: 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 (!jumpLockActive)
		{
			return;
		}
		float num = Time.time - jumpLockStartedAt;
		Character localCharacter = Character.localCharacter;
		CharacterMovement movement = ResolveMovement(localCharacter);
		RestoreOriginalJumpImpulse(movement);
		jumpLockActive = false;
		protectedCharacterId = -1;
		jumpLockStartedAt = 0f;
		OriginalJumpImpulses.Clear();
		if (protectionEndedLogCount < 50)
		{
			protectionEndedLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[8]
				{
					"[BeforeStart] First-map jump lock ended ",
					$"({protectionEndedLogCount}/{50}). ",
					"Reason=",
					reason,
					", ",
					$"Elapsed={num:0.000}, ",
					"Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[7] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	internal static bool ShouldBlockJump(CharacterMovement movement, out Character character)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		character = ResolveCharacter((Component)(object)movement);
		if (!jumpLockActive || (Object)(object)movement == (Object)null || (Object)(object)character == (Object)null || !character.IsLocal)
		{
			return false;
		}
		if (((Object)character).GetInstanceID() != protectedCharacterId)
		{
			return false;
		}
		Scene activeScene = SceneManager.GetActiveScene();
		if (((Scene)(ref activeScene)).handle != protectedSceneHandle)
		{
			return false;
		}
		return true;
	}

	private static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	private static CharacterMovement ResolveMovement(Character character)
	{
		if ((Object)(object)character == (Object)null)
		{
			return null;
		}
		if (character.refs != null && (Object)(object)character.refs.movement != (Object)null)
		{
			return character.refs.movement;
		}
		CharacterMovement val = ((Component)character).GetComponent<CharacterMovement>();
		if ((Object)(object)val == (Object)null)
		{
			val = ((Component)character).GetComponentInParent<CharacterMovement>();
		}
		return val;
	}

	private static void CaptureOriginalJumpImpulse(CharacterMovement movement)
	{
		if (!((Object)(object)movement == (Object)null))
		{
			int instanceID = ((Object)movement).GetInstanceID();
			if (!OriginalJumpImpulses.ContainsKey(instanceID) && !(movement.jumpImpulse <= 0f))
			{
				OriginalJumpImpulses.Add(instanceID, movement.jumpImpulse);
			}
		}
	}

	private static void RestoreOriginalJumpImpulse(CharacterMovement movement)
	{
		if (!((Object)(object)movement == (Object)null) && OriginalJumpImpulses.TryGetValue(((Object)movement).GetInstanceID(), out var value))
		{
			movement.jumpImpulse = value;
		}
	}

	private static void LogBlockedJump(Character character, string source)
	{
		//IL_0109: 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)
		if (blockedJumpLogCount < 50)
		{
			blockedJumpLogCount++;
			float num = Time.time - jumpLockStartedAt;
			string text = "Unknown";
			string text2 = "Unknown";
			if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null)
			{
				text = character.data.passedOut.ToString();
				text2 = character.data.fallSeconds.ToString("0.000");
			}
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[12]
				{
					"[BeforeStart] Jump blocked ",
					$"({blockedJumpLogCount}/{50}). ",
					"Source=",
					source,
					", ",
					$"Elapsed={num:0.000}, ",
					"PassedOut=",
					text,
					", FallSeconds=",
					text2,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[11] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	private static bool IsAirportScene(Scene scene)
	{
		if (!((Scene)(ref scene)).IsValid() || string.IsNullOrEmpty(((Scene)(ref scene)).name))
		{
			return false;
		}
		return ((Scene)(ref scene)).name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static bool IsGameplayMapScene(Scene scene)
	{
		if (!((Scene)(ref scene)).IsValid() || string.IsNullOrEmpty(((Scene)(ref scene)).name))
		{
			return false;
		}
		return ((Scene)(ref scene)).name.StartsWith("Level_", StringComparison.OrdinalIgnoreCase);
	}

	private static void ResetAllState()
	{
		airportWasVisited = false;
		waitingForFirstMapCharacter = false;
		firstMapProtectionConsumed = false;
		protectedSceneHandle = -1;
		protectedSceneName = string.Empty;
		jumpLockActive = false;
		protectedCharacterId = -1;
		jumpLockStartedAt = 0f;
		OriginalJumpImpulses.Clear();
		protectionStartedLogCount = 0;
		blockedJumpLogCount = 0;
		protectionEndedLogCount = 0;
	}
}
[BepInPlugin("Sapphire009.ClimbX", "ClimbX", "1.0.0")]
public sealed class ClimbX : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterClimbing), "CanClimb")]
	private static class CharacterClimbingCanClimbPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterClimbing __instance, ref bool __result)
		{
			if (!ShouldBlockWallGrab(__instance, out var _))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterClimbing), "TryToStartWallClimb", new Type[]
	{
		typeof(bool),
		typeof(Vector3),
		typeof(bool),
		typeof(float)
	})]
	private static class TryToStartWallClimbPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterClimbing __instance)
		{
			if (!ShouldBlockWallGrab(__instance, out var character))
			{
				return true;
			}
			LogBlockedGrab(character, "TryToStartWallClimb");
			return false;
		}
	}

	public const string PluginGUID = "Sapphire009.ClimbX";

	public const string PluginName = "ClimbX";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "WallGrabDisabled-R3";

	private const int MaximumLogCount = 20;

	internal static ManualLogSource ModLogger;

	private static int blockedGrabLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.ClimbX");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ClimbX 1.0.0 loaded. Build: WallGrabDisabled-R3. Local player wall grabbing is completely disabled outside Airport.");
	}

	private void OnDestroy()
	{
		blockedGrabLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	internal static bool ShouldBlockWallGrab(CharacterClimbing climbing, out Character character)
	{
		character = ResolveCharacter((Component)(object)climbing);
		if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null)
		{
			return false;
		}
		if (IsAirportScene())
		{
			return false;
		}
		return true;
	}

	private static void LogBlockedGrab(Character character, string source)
	{
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		if (blockedGrabLogCount < 20)
		{
			blockedGrabLogCount++;
			string text = (((Object)(object)character != (Object)null) ? ((Object)character).name : "Unknown");
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[8]
				{
					"[ClimbX] Wall grab blocked ",
					$"({blockedGrabLogCount}/{20}). ",
					"Source=",
					source,
					", Character=",
					text,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[7] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}
}
[BepInPlugin("Sapphire009.HelpUp", "HelpUp", "0.0.1")]
public sealed class HelpUp : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterGrabbing), "Reach")]
	private static class CharacterGrabbingReachPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterGrabbing __instance)
		{
			Character val = ResolveCharacter((Component)(object)__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null || val.refs == null || IsAirportScene())
			{
				return true;
			}
			RunExtendedReach(val);
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAnimations), "Update")]
	private static class CharacterAnimationsUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterAnimations __instance)
		{
			Character val = ResolveCharacter((Component)(object)__instance);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && val.refs != null && !((Object)(object)val.refs.animator == (Object)null) && !IsAirportScene() && val.data.isReaching && val.data.grabFriendDistance <= 10f)
			{
				val.refs.animator.SetBool(HelpAnimatorHash, true);
			}
		}
	}

	public const string PluginGUID = "Sapphire009.HelpUp";

	public const string PluginName = "HelpUp";

	public const string PluginVersion = "0.0.1";

	private const string BuildMarker = "ExtendedCoopPull-R1-10Meters";

	private const float ExtendedHelpRange = 10f;

	private const float NativeHelpRange = 4f;

	private const float NativePullForce = 70f;

	private const float MaximumPullForce = 95f;

	private const float MaximumHelpAngle = 65f;

	private const float MinimumAirborneTime = 0.12f;

	private const float MaximumTargetHeightAboveHelper = 1.5f;

	private const int MaximumLogCount = 50;

	private static readonly int HelpAnimatorHash = Animator.StringToHash("Help");

	internal static ManualLogSource ModLogger;

	private static int pullStartedLogCount;

	private static int blockedByWallLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.HelpUp");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("HelpUp 0.0.1 loaded. Build: ExtendedCoopPull-R1-10Meters. " + $"Help range={10f:0.0}m, " + $"angle={65f:0.0} degrees, " + $"pull force={70f:0.0}-" + $"{95f:0.0}. " + "Airborne teammates can now be rescued."));
	}

	private void OnDestroy()
	{
		pullStartedLogCount = 0;
		blockedByWallLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	private static bool CanUseExtendedHelp(Character helper)
	{
		if ((Object)(object)helper == (Object)null || (Object)(object)helper.data == (Object)null || helper.refs == null || (Object)(object)helper.refs.view == (Object)null)
		{
			return false;
		}
		if (IsAirportScene())
		{
			return false;
		}
		return helper.data.isReaching;
	}

	private static bool TargetCanBeHelped(Character helper, Character target)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)helper == (Object)null || (Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)helper || (Object)(object)target.data == (Object)null || target.refs == null || (Object)(object)target.refs.view == (Object)null || (Object)(object)target.refs.afflictions == (Object)null)
		{
			return false;
		}
		if (target.data.dead)
		{
			return false;
		}
		bool flag = target.IsStuck() || target.data.sinceUnstuck < 1f;
		bool isWebbed = target.refs.afflictions.isWebbed;
		bool flag2 = target.data.isClimbing && target.Center.y < helper.Center.y + 1f;
		bool flag3 = target.data.fallSeconds > 0.01f;
		bool flag4 = target.data.passedOut || target.data.fullyPassedOut || target.data.passedOutOnTheBeach > 0f;
		bool flag5 = !target.data.isGrounded && target.data.sinceGrounded > 0.12f;
		bool flag6 = target.Center.y <= helper.Center.y + 1.5f;
		if (flag || isWebbed || flag2)
		{
			return true;
		}
		if (!flag6)
		{
			return false;
		}
		return flag5 || flag3 || flag4;
	}

	private static bool HasClearLineOfSight(Character helper, Character target)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)helper == (Object)null || (Object)(object)target == (Object)null)
		{
			return false;
		}
		RaycastHit val = HelperFunctions.LineCheck(helper.Center, target.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1);
		return (Object)(object)((RaycastHit)(ref val)).transform == (Object)null;
	}

	private static float CalculatePullForce(float distance)
	{
		float num = Mathf.InverseLerp(4f, 10f, distance);
		return Mathf.Lerp(70f, 95f, num);
	}

	private static void ShowGraspEffect()
	{
		if (!((Object)(object)GUIManager.instance == (Object)null))
		{
			GUIManager.instance.Grasp();
		}
	}

	private static void UnstickCharacter(Character target)
	{
		if (!((Object)(object)target == (Object)null) && target.refs != null && !((Object)(object)target.refs.view == (Object)null))
		{
			target.refs.view.RPC("RPCA_Unstick", (RpcTarget)0, Array.Empty<object>());
		}
	}

	private static void DragCharacterTowards(Character target, Vector3 destination, float force)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target == (Object)null || target.refs == null || (Object)(object)target.refs.ragdoll == (Object)null || target.refs.ragdoll.partList == null)
		{
			return;
		}
		target.dragTowardsAction?.Invoke(destination, force);
		Vector3 val = Vector3.ClampMagnitude(destination - target.Center, 1f);
		Vector3 val2 = val * force;
		foreach (Bodypart part in target.refs.ragdoll.partList)
		{
			if (!((Object)(object)part == (Object)null))
			{
				part.AddForce(val2, (ForceMode)5);
			}
		}
	}

	private static void LimitCharacterFalling(Character target)
	{
		if (!((Object)(object)target == (Object)null) && !((Object)(object)target.data == (Object)null))
		{
			target.data.sinceGrounded = Mathf.Min(target.data.sinceGrounded, 0.5f);
			target.data.sinceJump = Mathf.Min(target.data.sinceJump, 0.5f);
		}
	}

	private static void RunExtendedReach(Character helper)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: 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)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		if (!CanUseExtendedHelp(helper))
		{
			return;
		}
		float num = 100f;
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (!TargetCanBeHelped(helper, allCharacter))
			{
				continue;
			}
			Vector3 val = allCharacter.Center - helper.Center;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrMagnitude > num)
			{
				continue;
			}
			float num2 = Mathf.Sqrt(sqrMagnitude);
			if (num2 <= 0.001f)
			{
				continue;
			}
			float num3 = Vector3.Angle(helper.data.lookDirection, val);
			if (num3 > 65f)
			{
				continue;
			}
			Scene activeScene;
			if (!HasClearLineOfSight(helper, allCharacter))
			{
				if (blockedByWallLogCount < 50)
				{
					blockedByWallLogCount++;
					ManualLogSource modLogger = ModLogger;
					if (modLogger != null)
					{
						string[] obj = new string[7]
						{
							"[HelpUp] Pull blocked by terrain ",
							$"({blockedByWallLogCount}/",
							$"{50}). ",
							$"Distance={num2:0.00}, ",
							$"Angle={num3:0.00}, ",
							"Scene=",
							null
						};
						activeScene = SceneManager.GetActiveScene();
						obj[6] = ((Scene)(ref activeScene)).name;
						modLogger.LogInfo((object)string.Concat(obj));
					}
				}
				continue;
			}
			if (allCharacter.IsStuck() && allCharacter.IsLocal)
			{
				UnstickCharacter(allCharacter);
			}
			allCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)11, 1f, false, false);
			if (num2 < helper.data.grabFriendDistance)
			{
				helper.data.grabFriendDistance = num2;
				helper.data.sinceGrabFriend = 0f;
			}
			if (helper.refs.view.IsMine)
			{
				ShowGraspEffect();
			}
			if (!allCharacter.refs.view.IsMine)
			{
				continue;
			}
			float num4 = CalculatePullForce(num2);
			DragCharacterTowards(allCharacter, helper.Center, num4);
			LimitCharacterFalling(allCharacter);
			ShowGraspEffect();
			if (pullStartedLogCount < 50)
			{
				pullStartedLogCount++;
				ManualLogSource modLogger2 = ModLogger;
				if (modLogger2 != null)
				{
					string[] obj2 = new string[17]
					{
						"[HelpUp] Extended teammate pull applied ",
						$"({pullStartedLogCount}/",
						$"{50}). ",
						"Helper=",
						((Object)helper).name,
						", Target=",
						((Object)allCharacter).name,
						", ",
						$"Distance={num2:0.00}, ",
						$"Angle={num3:0.00}, ",
						$"PullForce={num4:0.00}, ",
						"TargetGrounded=",
						$"{allCharacter.data.isGrounded}, ",
						"TargetFallSeconds=",
						$"{allCharacter.data.fallSeconds:0.000}, ",
						"Scene=",
						null
					};
					activeScene = SceneManager.GetActiveScene();
					obj2[16] = ((Scene)(ref activeScene)).name;
					modLogger2.LogInfo((object)string.Concat(obj2));
				}
			}
		}
	}
}
[BepInPlugin("Sapphire009.JumpingPEAK", "JumpingPEAK", "1.0.0")]
public sealed class JumpingPEAK : BaseUnityPlugin
{
	private sealed class StandRecoveryState
	{
		public bool WaitingForStand;

		public float StableSince = -1f;

		public string LastReason = "Stable";
	}

	[HarmonyPatch(typeof(CharacterInput), "Sample", new Type[] { typeof(bool) })]
	private static class CharacterInputSamplePatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Sapphire009.WASDX" })]
		private static void Postfix(CharacterInput __instance)
		{
			StoreInput(__instance);
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "Update")]
	private static class CharacterMovementUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance)
		{
			Character character = ResolveCharacter((Component)(object)__instance);
			UpdateStandRecovery(character);
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "TryToJump")]
	private static class CharacterMovementTryToJumpPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Sapphire009.BeforeStart", "Sapphire009.NoGround" })]
		private static bool Prefix(CharacterMovement __instance)
		{
			Character val = ResolveCharacter((Component)(object)__instance);
			if ((Object)(object)val == (Object)null || !val.IsLocal || IsAirportScene())
			{
				return true;
			}
			if (!ShouldBlockJump(val, out var reason))
			{
				return true;
			}
			CharacterMovementJumpRpcPatch.RestoreOriginalJumpImpulse(__instance);
			LogBlockedJump(val, "TryToJump", reason);
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "JumpRpc", new Type[] { typeof(bool) })]
	private static class CharacterMovementJumpRpcPatch
	{
		private sealed class JumpPatchState
		{
			public Character Character;

			public Vector2 MovementInput = Vector2.zero;

			public Vector3 MovementDirection = Vector3.zero;

			public float DirectionalSpeed;

			public bool ApplyDirectionalBoost;

			public bool ShiftBoosted;

			public bool WasGrounded;
		}

		private const float ControlledJumpMultiplier = 5f;

		private const float ShiftBoostMultiplier = 2f;

		private const float DirectionalJumpSpeed = 15f;

		private const float ShiftDirectionalSpeedMultiplier = 2f;

		private const int MaximumTakeoffWaitFrames = 30;

		private static readonly WaitForFixedUpdate WaitForPhysics = new WaitForFixedUpdate();

		private static readonly Dictionary<int, float> OriginalJumpImpulses = new Dictionary<int, float>();

		private static int boostedJumpLogCount;

		private static int directionalBoostLogCount;

		private static int defaultJumpLogCount;

		private static int rejectedLogCount;

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Sapphire009.NoGround" })]
		private static bool Prefix(CharacterMovement __instance, bool __0, out JumpPatchState __state)
		{
			//IL_01dd: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			__state = new JumpPatchState();
			bool flag = __0;
			if ((Object)(object)__instance == (Object)null)
			{
				LogRejected("CharacterMovement is null.");
				return true;
			}
			Character val = ResolveCharacter((Component)(object)__instance);
			if ((Object)(object)val == (Object)null)
			{
				LogRejected("Character could not be resolved.");
				return true;
			}
			if (!val.IsLocal)
			{
				return true;
			}
			if ((Object)(object)val.data == (Object)null)
			{
				LogRejected("Character.data is null.");
				return true;
			}
			if ((Object)(object)val.input == (Object)null)
			{
				LogRejected("Character.input is null.");
				return true;
			}
			CaptureOriginalJumpImpulse(__instance);
			RestoreOriginalJumpImpulse(__instance);
			if (!OriginalJumpImpulses.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
			{
				LogRejected("Original jumpImpulse was not captured.");
				return true;
			}
			if (value <= 0f)
			{
				LogRejected("Original jumpImpulse is invalid: " + $"{value:0.000}");
				return true;
			}
			if (IsAirportScene() || flag)
			{
				LogDefaultJump(val, value, flag ? "PalJump" : "Airport");
				return true;
			}
			if (ShouldBlockJump(val, out var reason))
			{
				RestoreOriginalJumpImpulse(__instance);
				LogBlockedJump(val, "JumpRpc", reason);
				return false;
			}
			bool isGrounded = val.data.isGrounded;
			bool shiftHeld = GetShiftHeld(val);
			bool flag2 = isGrounded && shiftHeld;
			float num = 5f;
			float num2 = 15f;
			if (flag2)
			{
				num *= 2f;
				num2 *= 2f;
			}
			float num3 = (__instance.jumpImpulse = value * num);
			Vector2 movementInput = GetMovementInput(val);
			Vector3 val2 = CalculateMovementDirection(val, movementInput);
			__state.Character = val;
			__state.MovementInput = movementInput;
			__state.MovementDirection = val2;
			__state.DirectionalSpeed = num2;
			__state.ApplyDirectionalBoost = ((Vector3)(ref val2)).sqrMagnitude > 0.0001f;
			__state.ShiftBoosted = flag2;
			__state.WasGrounded = isGrounded;
			if (boostedJumpLogCount < 50)
			{
				boostedJumpLogCount++;
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[18]
					{
						"[JumpingPEAK] Standing jump applied ",
						$"({boostedJumpLogCount}/{50}). ",
						$"OriginalImpulse={value:0.000}, ",
						$"JumpMultiplier={num:0.00}, ",
						$"BoostedImpulse={num3:0.000}, ",
						$"ShiftHeld={shiftHeld}, ",
						$"ShiftBoosted={flag2}, ",
						$"WasGrounded={isGrounded}, ",
						$"MovementInput={movementInput}, ",
						$"MovementDirection={val2}, ",
						"DirectionalSpeed=",
						$"{num2:0.00}, ",
						"CurrentControl=",
						$"{val.data.currentRagdollControll:0.000}, ",
						"TargetControl=",
						$"{val.data.GetTargetRagdollControll():0.000}, ",
						"Scene=",
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[17] = ((Scene)(ref activeScene)).name;
					modLogger.LogInfo((object)string.Concat(obj));
				}
			}
			return true;
		}

		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance, JumpPatchState __state)
		{
			if (!((Object)(object)__instance == (Object)null) && __state != null && __state.ApplyDirectionalBoost && !((Object)(object)__state.Character == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(ApplyDirectionalVelocityAfterTakeoff(__state));
			}
		}

		private static void CaptureOriginalJumpImpulse(CharacterMovement movement)
		{
			if (!((Object)(object)movement == (Object)null))
			{
				int instanceID = ((Object)movement).GetInstanceID();
				if (!OriginalJumpImpulses.ContainsKey(instanceID) && !(movement.jumpImpulse <= 0f))
				{
					OriginalJumpImpulses.Add(instanceID, movement.jumpImpulse);
				}
			}
		}

		internal static void RestoreOriginalJumpImpulse(CharacterMovement movement)
		{
			if (!((Object)(object)movement == (Object)null))
			{
				CaptureOriginalJumpImpulse(movement);
				if (OriginalJumpImpulses.TryGetValue(((Object)movement).GetInstanceID(), out var value))
				{
					movement.jumpImpulse = value;
				}
			}
		}

		private static Vector3 CalculateMovementDirection(Character character, Vector2 movementInput)
		{
			//IL_0043: 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_0031: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || ((Vector2)(ref movementInput)).sqrMagnitude <= 0.0001f)
			{
				return Vector3.zero;
			}
			Vector3 val = character.data.lookDirection_Flat;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
			{
				val = character.data.lookDirection;
				val.y = 0f;
			}
			if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				((Vector3)(ref val)).Normalize();
			}
			Vector3 val2 = character.data.lookDirection_Right;
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f && ((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				val2 = Vector3.Cross(Vector3.up, val);
			}
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				((Vector3)(ref val2)).Normalize();
			}
			Vector3 val3 = val * movementInput.y;
			val3 += val2 * movementInput.x;
			val3.y = 0f;
			if (((Vector3)(ref val3)).sqrMagnitude <= 0.0001f)
			{
				return Vector3.zero;
			}
			return ((Vector3)(ref val3)).normalized;
		}

		private static IEnumerator ApplyDirectionalVelocityAfterTakeoff(JumpPatchState state)
		{
			for (int frame = 0; frame < 30; frame++)
			{
				yield return WaitForPhysics;
				Character character = state.Character;
				if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null || character.data.dead || character.data.fullyPassedOut)
				{
					yield break;
				}
				if (!character.data.isGrounded && character.data.sinceJump < 0.3f)
				{
					ApplyDirectionalVelocity(character, state);
					yield break;
				}
			}
			LogRejected("Directional boost timed out before takeoff.");
		}

		private static void ApplyDirectionalVelocity(Character character, JumpPatchState state)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.ragdoll == (Object)null || character.refs.ragdoll.partList == null)
			{
				LogRejected("Ragdoll bodyparts are unavailable.");
			}
			else
			{
				if (state == null || ((Vector3)(ref state.MovementDirection)).sqrMagnitude <= 0.0001f)
				{
					return;
				}
				Vector3 val = state.MovementDirection * state.DirectionalSpeed;
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				float num4 = 0f;
				float num5 = 0f;
				Vector3 val3 = default(Vector3);
				Vector3 val4 = default(Vector3);
				for (int i = 0; i < character.refs.ragdoll.partList.Count; i++)
				{
					Bodypart val2 = character.refs.ragdoll.partList[i];
					if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Rig == (Object)null)
					{
						num3++;
						continue;
					}
					Rigidbody rig = val2.Rig;
					if (rig.isKinematic)
					{
						num2++;
						continue;
					}
					Vector3 linearVelocity = rig.linearVelocity;
					((Vector3)(ref val3))..ctor(linearVelocity.x, 0f, linearVelocity.z);
					num4 += ((Vector3)(ref val3)).magnitude;
					linearVelocity.x = val.x;
					linearVelocity.z = val.z;
					rig.linearVelocity = linearVelocity;
					((Vector3)(ref val4))..ctor(rig.linearVelocity.x, 0f, rig.linearVelocity.z);
					num5 += ((Vector3)(ref val4)).magnitude;
					num++;
				}
				float num6 = ((num > 0) ? (num4 / (float)num) : 0f);
				float num7 = ((num > 0) ? (num5 / (float)num) : 0f);
				if (directionalBoostLogCount < 50)
				{
					directionalBoostLogCount++;
					ManualLogSource modLogger = ModLogger;
					if (modLogger != null)
					{
						string[] obj = new string[19]
						{
							"[JumpingPEAK] Directional jump applied ",
							$"({directionalBoostLogCount}/{50}). ",
							$"MovementInput={state.MovementInput}, ",
							$"Direction={state.MovementDirection}, ",
							$"ShiftBoosted={state.ShiftBoosted}, ",
							$"WasGrounded={state.WasGrounded}, ",
							$"DirectionalSpeed={state.DirectionalSpeed:0.00}, ",
							"TargetHorizontalVelocity=",
							$"{val}, ",
							"AverageSpeedBefore=",
							$"{num6:0.00}, ",
							"AverageSpeedAfter=",
							$"{num7:0.00}, ",
							$"AppliedBodyparts={num}, ",
							$"KinematicBodyparts={num2}, ",
							"UnavailableBodyparts=",
							$"{num3}, ",
							"Scene=",
							null
						};
						Scene activeScene = SceneManager.GetActiveScene();
						obj[18] = ((Scene)(ref activeScene)).name;
						modLogger.LogInfo((object)string.Concat(obj));
					}
				}
			}
		}

		private static void LogDefaultJump(Character character, float originalJumpImpulse, string reason)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (defaultJumpLogCount < 50)
			{
				defaultJumpLogCount++;
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[10]
					{
						"[JumpingPEAK] Default jump used ",
						$"({defaultJumpLogCount}/{50}). ",
						"Reason=",
						reason,
						", ",
						$"Impulse={originalJumpImpulse:0.000}, ",
						"CurrentControl=",
						$"{character.data.currentRagdollControll:0.000}, ",
						"Scene=",
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[9] = ((Scene)(ref activeScene)).name;
					modLogger.LogInfo((object)string.Concat(obj));
				}
			}
		}

		private static void LogRejected(string reason)
		{
			if (rejectedLogCount < 50)
			{
				rejectedLogCount++;
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					modLogger.LogWarning((object)("[JumpingPEAK] Jump modification rejected " + $"({rejectedLogCount}/{50}): " + reason));
				}
			}
		}

		internal static void ClearCache()
		{
			OriginalJumpImpulses.Clear();
			boostedJumpLogCount = 0;
			directionalBoostLogCount = 0;
			defaultJumpLogCount = 0;
			rejectedLogCount = 0;
		}
	}

	public const string PluginGUID = "Sapphire009.JumpingPEAK";

	public const string PluginName = "JumpingPEAK";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "FungusJump-R12-BlockUntilStand";

	internal static ManualLogSource ModLogger;

	private static readonly Dictionary<int, Vector2> CapturedMovementInputs = new Dictionary<int, Vector2>();

	private static readonly Dictionary<int, bool> CapturedShiftInputs = new Dictionary<int, bool>();

	private static readonly Dictionary<int, StandRecoveryState> StandRecoveryStates = new Dictionary<int, StandRecoveryState>();

	private const float StandConfirmationDuration = 0.35f;

	private const float RagdollControlThreshold = 0.9f;

	private const int MaximumLogCount = 50;

	private static int blockedJumpLogCount;

	private static int recoveryStartedLogCount;

	private static int recoveryCompletedLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.JumpingPEAK");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"JumpingPEAK 1.0.0 loaded. Build: FungusJump-R12-BlockUntilStand. Jumping is blocked while fallen or asleep. Jumping resumes after the character returns to Stand.");
	}

	private void OnDestroy()
	{
		CharacterMovementJumpRpcPatch.ClearCache();
		CapturedMovementInputs.Clear();
		CapturedShiftInputs.Clear();
		StandRecoveryStates.Clear();
		blockedJumpLogCount = 0;
		recoveryStartedLogCount = 0;
		recoveryCompletedLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	private static bool IsKeyboardShiftHeld()
	{
		return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
	}

	private static void StoreInput(CharacterInput characterInput)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)characterInput == (Object)null))
		{
			int instanceID = ((Object)characterInput).GetInstanceID();
			CapturedMovementInputs[instanceID] = Vector2.ClampMagnitude(characterInput.movementInput, 1f);
			CapturedShiftInputs[instanceID] = IsKeyboardShiftHeld();
		}
	}

	private static Vector2 GetMovementInput(Character character)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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_0059: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || (Object)(object)character.input == (Object)null)
		{
			return Vector2.zero;
		}
		Vector2 val = character.input.movementInput;
		if (CapturedMovementInputs.TryGetValue(((Object)character.input).GetInstanceID(), out var value))
		{
			val = value;
		}
		return Vector2.ClampMagnitude(val, 1f);
	}

	private static bool GetShiftHeld(Character character)
	{
		if ((Object)(object)character == (Object)null || (Object)(object)character.input == (Object)null)
		{
			return false;
		}
		if (CapturedShiftInputs.TryGetValue(((Object)character.input).GetInstanceID(), out var value))
		{
			return value;
		}
		return IsKeyboardShiftHeld();
	}

	private static bool IsFallOrSleepState(Character character, out string reason)
	{
		reason = "Stable";
		if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
		{
			reason = "MissingCharacterData";
			return true;
		}
		if (character.data.dead)
		{
			reason = "Dead";
			return true;
		}
		if (character.data.fullyPassedOut)
		{
			reason = "FullyPassedOut";
			return true;
		}
		if (character.data.passedOut)
		{
			reason = "PassedOut";
			return true;
		}
		if (character.data.passedOutOnTheBeach > 0f)
		{
			reason = "PassedOutOnTheBeach";
			return true;
		}
		if (character.data.fallSeconds > 0.01f)
		{
			reason = "FallSeconds";
			return true;
		}
		if (character.data.currentRagdollControll < 0.9f)
		{
			reason = "CurrentRagdollControl";
			return true;
		}
		if (character.data.GetTargetRagdollControll() < 0.9f)
		{
			reason = "TargetRagdollControl";
			return true;
		}
		return false;
	}

	private static void UpdateStandRecovery(Character character)
	{
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: 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_02f5: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null)
		{
			return;
		}
		int instanceID = ((Object)character).GetInstanceID();
		if (IsAirportScene())
		{
			StandRecoveryStates.Remove(instanceID);
			return;
		}
		string reason;
		bool flag = IsFallOrSleepState(character, out reason);
		if (!StandRecoveryStates.TryGetValue(instanceID, out var value))
		{
			if (!flag)
			{
				return;
			}
			value = new StandRecoveryState();
			StandRecoveryStates.Add(instanceID, value);
		}
		Scene activeScene;
		if (flag)
		{
			bool flag2 = !value.WaitingForStand;
			value.WaitingForStand = true;
			value.StableSince = -1f;
			value.LastReason = reason;
			if (flag2 && recoveryStartedLogCount < 50)
			{
				recoveryStartedLogCount++;
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[13]
					{
						"[JumpingPEAK] Stand recovery started ",
						$"({recoveryStartedLogCount}/{50}). ",
						"Reason=",
						reason,
						", FallSeconds=",
						$"{character.data.fallSeconds:0.000}, ",
						$"PassedOut={character.data.passedOut}, ",
						"CurrentControl=",
						$"{character.data.currentRagdollControll:0.000}, ",
						"TargetControl=",
						$"{character.data.GetTargetRagdollControll():0.000}, ",
						"Scene=",
						null
					};
					activeScene = SceneManager.GetActiveScene();
					obj[12] = ((Scene)(ref activeScene)).name;
					modLogger.LogInfo((object)string.Concat(obj));
				}
			}
			return;
		}
		if (!value.WaitingForStand)
		{
			StandRecoveryStates.Remove(instanceID);
			return;
		}
		if (value.StableSince < 0f)
		{
			value.StableSince = Time.time;
			return;
		}
		float num = Time.time - value.StableSince;
		if (num < 0.35f)
		{
			return;
		}
		string lastReason = value.LastReason;
		StandRecoveryStates.Remove(instanceID);
		if (recoveryCompletedLogCount < 50)
		{
			recoveryCompletedLogCount++;
			ManualLogSource modLogger2 = ModLogger;
			if (modLogger2 != null)
			{
				string[] obj2 = new string[8]
				{
					"[JumpingPEAK] Stand recovery completed ",
					$"({recoveryCompletedLogCount}/{50}). ",
					"PreviousReason=",
					lastReason,
					", ",
					$"StableDuration={num:0.000}, ",
					"Scene=",
					null
				};
				activeScene = SceneManager.GetActiveScene();
				obj2[7] = ((Scene)(ref activeScene)).name;
				modLogger2.LogInfo((object)string.Concat(obj2));
			}
		}
	}

	private static bool ShouldBlockJump(Character character, out string reason)
	{
		reason = "Stable";
		if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null)
		{
			return false;
		}
		if (IsAirportScene())
		{
			StandRecoveryStates.Remove(((Object)character).GetInstanceID());
			return false;
		}
		UpdateStandRecovery(character);
		if (IsFallOrSleepState(character, out var reason2))
		{
			reason = reason2;
			return true;
		}
		if (!StandRecoveryStates.TryGetValue(((Object)character).GetInstanceID(), out var value))
		{
			return false;
		}
		if (!value.WaitingForStand)
		{
			return false;
		}
		if (value.StableSince < 0f)
		{
			reason = "WaitingForStand";
			return true;
		}
		float num = Time.time - value.StableSince;
		if (num < 0.35f)
		{
			reason = "StandConfirmation";
			return true;
		}
		StandRecoveryStates.Remove(((Object)character).GetInstanceID());
		return false;
	}

	private static void LogBlockedJump(Character character, string source, string reason)
	{
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		if (blockedJumpLogCount < 50)
		{
			blockedJumpLogCount++;
			string text = "Unknown";
			string text2 = "Unknown";
			string text3 = "Unknown";
			string text4 = "Unknown";
			if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null)
			{
				text = character.data.fallSeconds.ToString("0.000");
				text2 = character.data.passedOut.ToString();
				text3 = character.data.currentRagdollControll.ToString("0.000");
				text4 = character.data.GetTargetRagdollControll().ToString("0.000");
			}
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[16]
				{
					"[JumpingPEAK] Jump blocked ",
					$"({blockedJumpLogCount}/{50}). ",
					"Source=",
					source,
					", Reason=",
					reason,
					", FallSeconds=",
					text,
					", PassedOut=",
					text2,
					", CurrentControl=",
					text3,
					", TargetControl=",
					text4,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[15] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}
}
[BepInPlugin("Sapphire009.JumpSound", "JumpSound", "1.0.0")]
public sealed class JumpSound : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterMovement), "JumpRpc", new Type[] { typeof(bool) })]
	private static class CharacterMovementJumpRpcPatch
	{
		private sealed class JumpSoundState
		{
			public Character Character;

			public int JumpsRemainingBefore;

			public bool ChargingJumpBefore;

			public bool IsPalJump;

			public bool Valid;
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Sapphire009.JumpingPEAK", "Sapphire009.BeforeStart" })]
		private static void Prefix(CharacterMovement __instance, bool __0, out JumpSoundState __state)
		{
			__state = new JumpSoundState();
			Character val = ResolveCharacter((Component)(object)__instance);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null))
			{
				__state.Character = val;
				__state.JumpsRemainingBefore = val.data.jumpsRemaining;
				__state.ChargingJumpBefore = val.data.chargingJump;
				__state.IsPalJump = __0;
				__state.Valid = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(JumpSoundState __state)
		{
			if (__state != null && __state.Valid && !__state.IsPalJump && !((Object)(object)__state.Character == (Object)null) && !((Object)(object)__state.Character.data == (Object)null))
			{
				Character character = __state.Character;
				bool flag = character.data.jumpsRemaining < __state.JumpsRemainingBefore;
				bool flag2 = !__state.ChargingJumpBefore && character.data.chargingJump;
				if (flag || flag2)
				{
					PlayJumpSound(character);
				}
			}
		}
	}

	public const string PluginGUID = "Sapphire009.JumpSound";

	public const string PluginName = "JumpSound";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "BounceShroomJumpSound-R1";

	private const float SoundSearchInterval = 1f;

	private const int MinimumSoundScore = 80;

	private const int MaximumLogCount = 30;

	internal static ManualLogSource ModLogger;

	private static SFX_Instance sourceBounceSound;

	private static SFX_Instance runtimeJumpSound;

	private static float nextSoundSearchTime;

	private static int soundFoundLogCount;

	private static int soundPlayedLogCount;

	private static int soundMissingLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.JumpSound");
		harmony.PatchAll();
		SceneManager.sceneLoaded += OnSceneLoaded;
		TryFindBounceShroomSound();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"JumpSound 1.0.0 loaded. Build: BounceShroomJumpSound-R1. Successful character jumps will use the PEAK bounce-shroom sound.");
	}

	private void Update()
	{
		if (!((Object)(object)runtimeJumpSound != (Object)null) && !(Time.unscaledTime < nextSoundSearchTime))
		{
			nextSoundSearchTime = Time.unscaledTime + 1f;
			TryFindBounceShroomSound();
		}
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		DestroyRuntimeSound();
		sourceBounceSound = null;
		soundFoundLogCount = 0;
		soundPlayedLogCount = 0;
		soundMissingLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	private static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
	{
		nextSoundSearchTime = 0f;
		if ((Object)(object)runtimeJumpSound == (Object)null)
		{
			TryFindBounceShroomSound();
		}
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	private static bool TryFindBounceShroomSound()
	{
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		if (IsValidSound(runtimeJumpSound))
		{
			return true;
		}
		SFX_Instance val = null;
		string text = string.Empty;
		int num = int.MinValue;
		CollisionModifier[] array = Resources.FindObjectsOfTypeAll<CollisionModifier>();
		if (array != null)
		{
			foreach (CollisionModifier val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && IsValidSound(val2.bounceSFX))
				{
					string hierarchyText = GetHierarchyText(((Component)val2).transform);
					string soundText = GetSoundText(val2.bounceSFX);
					int num2 = ScoreBounceShroomText(hierarchyText);
					num2 += ScoreBounceShroomText(soundText);
					if (val2.knockback > 0f)
					{
						num2 += 10;
					}
					if (num2 > num)
					{
						num = num2;
						val = val2.bounceSFX;
						text = hierarchyText;
					}
				}
			}
		}
		if ((Object)(object)val == (Object)null || num < 80)
		{
			SFX_Instance[] array2 = Resources.FindObjectsOfTypeAll<SFX_Instance>();
			if (array2 != null)
			{
				foreach (SFX_Instance val3 in array2)
				{
					if (IsValidSound(val3))
					{
						string soundText2 = GetSoundText(val3);
						int num3 = ScoreBounceShroomText(soundText2);
						if (num3 > num)
						{
							num = num3;
							val = val3;
							text = soundText2;
						}
					}
				}
			}
		}
		if ((Object)(object)val == (Object)null || num < 80)
		{
			if (soundMissingLogCount < 30)
			{
				soundMissingLogCount++;
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[7]
					{
						"[JumpSound] Bounce-shroom sound not found ",
						$"({soundMissingLogCount}/{30}). ",
						$"BestScore={num}, ",
						"BestCandidate=",
						text,
						", Scene=",
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[6] = ((Scene)(ref activeScene)).name;
					modLogger.LogWarning((object)string.Concat(obj));
				}
			}
			return false;
		}
		SetBounceShroomSound(val, text, num);
		return (Object)(object)runtimeJumpSound != (Object)null;
	}

	private static void SetBounceShroomSound(SFX_Instance sound, string source, int score)
	{
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		if (!IsValidSound(sound) || ((Object)(object)sourceBounceSound == (Object)(object)sound && IsValidSound(runtimeJumpSound)))
		{
			return;
		}
		DestroyRuntimeSound();
		sourceBounceSound = sound;
		runtimeJumpSound = Object.Instantiate<SFX_Instance>(sourceBounceSound);
		if ((Object)(object)runtimeJumpSound == (Object)null)
		{
			return;
		}
		((Object)runtimeJumpSound).name = "Sapphire009_JumpSound_BounceShroom";
		((Object)runtimeJumpSound).hideFlags = (HideFlags)61;
		if (soundFoundLogCount < 30)
		{
			soundFoundLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[12]
				{
					"[JumpSound] Bounce-shroom sound selected ",
					$"({soundFoundLogCount}/{30}). ",
					"SFX=",
					((Object)sourceBounceSound).name,
					", ",
					$"Score={score}, ",
					"Source=",
					source,
					", ClipCount=",
					$"{sourceBounceSound.clips.Length}, ",
					"Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[11] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	private static void DestroyRuntimeSound()
	{
		if ((Object)(object)runtimeJumpSound != (Object)null)
		{
			Object.Destroy((Object)(object)runtimeJumpSound);
			runtimeJumpSound = null;
		}
	}

	private static bool IsValidSound(SFX_Instance sound)
	{
		return (Object)(object)sound != (Object)null && sound.clips != null && sound.clips.Length != 0;
	}

	private static string GetHierarchyText(Transform transform)
	{
		if ((Object)(object)transform == (Object)null)
		{
			return string.Empty;
		}
		string text = string.Empty;
		Transform val = transform;
		int num = 0;
		while ((Object)(object)val != (Object)null && num < 8)
		{
			text = (string.IsNullOrEmpty(text) ? ((Object)val).name : (((Object)val).name + "/" + text));
			val = val.parent;
			num++;
		}
		return text;
	}

	private static string GetSoundText(SFX_Instance sound)
	{
		if ((Object)(object)sound == (Object)null)
		{
			return string.Empty;
		}
		string text = ((Object)sound).name;
		if (sound.clips == null)
		{
			return text;
		}
		for (int i = 0; i < sound.clips.Length; i++)
		{
			AudioClip val = sound.clips[i];
			if (!((Object)(object)val == (Object)null))
			{
				text = text + "/" + ((Object)val).name;
			}
		}
		return text;
	}

	private static int ScoreBounceShroomText(string text)
	{
		if (string.IsNullOrEmpty(text))
		{
			return 0;
		}
		string source = text.ToLowerInvariant();
		int num = 0;
		if (Contains(source, "bounceshroom"))
		{
			num += 200;
		}
		if (Contains(source, "bounce shroom"))
		{
			num += 200;
		}
		if (Contains(source, "bounce_shroom"))
		{
			num += 200;
		}
		if (Contains(source, "shroombounce"))
		{
			num += 180;
		}
		if (Contains(source, "shroom bounce"))
		{
			num += 180;
		}
		if (Contains(source, "mushroom bounce"))
		{
			num += 170;
		}
		if (Contains(source, "bounce mushroom"))
		{
			num += 170;
		}
		if (Contains(source, "bounce"))
		{
			num += 25;
		}
		if (Contains(source, "shroom"))
		{
			num += 80;
		}
		if (Contains(source, "mushroom"))
		{
			num += 70;
		}
		if (Contains(source, "fungus"))
		{
			num += 50;
		}
		return num;
	}

	private static bool Contains(string source, string value)
	{
		return source.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static void PlayJumpSound(Character character)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: 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)
		if ((Object)(object)character == (Object)null || IsAirportScene())
		{
			return;
		}
		if (!IsValidSound(runtimeJumpSound))
		{
			TryFindBounceShroomSound();
		}
		if (!IsValidSound(runtimeJumpSound) || (Object)(object)SFX_Player.instance == (Object)null)
		{
			return;
		}
		SFX_Player.instance.PlaySFX(runtimeJumpSound, character.Center, (Transform)null, (SFX_Settings)null, 1f, false);
		if (soundPlayedLogCount < 30)
		{
			soundPlayedLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[8]
				{
					"[JumpSound] Bounce-shroom jump sound played ",
					$"({soundPlayedLogCount}/{30}). ",
					"Character=",
					((Object)character).name,
					", ",
					$"Position={character.Center}, ",
					"Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[7] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}
}
[BepInPlugin("Sapphire009.Runup", "Runup", "1.0.0")]
public sealed class Runup : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterMovement), "Start")]
	private static class CharacterMovementStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance)
		{
			StoreOriginalJumpImpulse(__instance, overwrite: true);
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "JumpRpc", new Type[] { typeof(bool) })]
	private static class CharacterMovementJumpRpcPatch
	{
		private sealed class PalJumpPatchState
		{
			public bool Applied;

			public Character Character;

			public float OriginalJumpImpulse;

			public float PreviousSincePalJump;

			public int RestoreToken;
		}

		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "Sapphire009.JumpingPEAK" })]
		private static void Prefix(CharacterMovement __instance, bool __0, out PalJumpPatchState __state)
		{
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			__state = new PalJumpPatchState();
			if (!__0)
			{
				return;
			}
			if ((Object)(object)__instance == (Object)null)
			{
				LogRejected("CharacterMovement is null.");
				return;
			}
			Character val = ResolveCharacter((Component)(object)__instance);
			if ((Object)(object)val == (Object)null)
			{
				LogRejected("Character could not be resolved.");
			}
			else
			{
				if (!val.IsLocal)
				{
					return;
				}
				if ((Object)(object)val.data == (Object)null)
				{
					LogRejected("Character.data is null.");
				}
				else
				{
					if (IsAirportScene() || val.data.dead || val.data.fullyPassedOut)
					{
						return;
					}
					if (!TryGetOriginalJumpImpulse(__instance, out var originalJumpImpulse))
					{
						LogRejected("Original jumpImpulse could not be resolved.");
						return;
					}
					float num = originalJumpImpulse * 10.416666f;
					int restoreToken = CreateRestoreToken(__instance);
					__state.Applied = true;
					__state.Character = val;
					__state.OriginalJumpImpulse = originalJumpImpulse;
					__state.PreviousSincePalJump = val.data.sincePalJump;
					__state.RestoreToken = restoreToken;
					__instance.jumpImpulse = num;
					if (appliedLogCount < 50)
					{
						appliedLogCount++;
						ManualLogSource modLogger = ModLogger;
						if (modLogger != null)
						{
							string[] obj = new string[12]
							{
								"[Runup] Enhanced Pal Jump applied ",
								$"({appliedLogCount}/{50}). ",
								$"OriginalImpulse={originalJumpImpulse:0.000}, ",
								"RunupImpulseMultiplier=",
								$"{10.416666f:0.000}, ",
								$"PatchedImpulse={num:0.000}, ",
								"NativePalMultiplier=",
								$"{2f:0.000}, ",
								"FinalEffectiveMultiplier=",
								$"{20.833332f:0.000}, ",
								"Scene=",
								null
							};
							Scene activeScene = SceneManager.GetActiveScene();
							obj[11] = ((Scene)(ref activeScene)).name;
							modLogger.LogInfo((object)string.Concat(obj));
						}
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "Sapphire009.JumpingPEAK" })]
		private static void Postfix(CharacterMovement __instance, PalJumpPatchState __state)
		{
			if (!((Object)(object)__instance == (Object)null) && __state != null && __state.Applied && !((Object)(object)__state.Character == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(RestoreAfterPalJump(__instance, __state.Character, __state.OriginalJumpImpulse, __state.PreviousSincePalJump, __state.RestoreToken));
			}
		}
	}

	public const string PluginGUID = "Sapphire009.Runup";

	public const string PluginName = "Runup";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "PalJump-AboveJumpingPEAK-R4";

	private const float JumpingPeakJumpMultiplier = 5f;

	private const float RunupRelativeMultiplier = 4.1666665f;

	private const float NativePalJumpMultiplier = 2f;

	private const float RunupImpulseMultiplier = 10.416666f;

	private const float FinalEffectiveMultiplier = 20.833332f;

	private const int MaximumRestoreWaitFrames = 120;

	private const int RestoreSafetyFrames = 4;

	private const int MaximumLogCount = 50;

	internal static ManualLogSource ModLogger;

	private static readonly Dictionary<int, float> OriginalJumpImpulses = new Dictionary<int, float>();

	private static readonly Dictionary<int, int> ActiveRestoreTokens = new Dictionary<int, int>();

	private static readonly WaitForFixedUpdate WaitForPhysics = new WaitForFixedUpdate();

	private static int nextRestoreToken;

	private static int appliedLogCount;

	private static int restoredLogCount;

	private static int rejectedLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.Runup");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Runup 1.0.0 loaded. Build: PalJump-AboveJumpingPEAK-R4. Runup impulse multiplier=" + $"{10.416666f:0.000}. " + "Final effective multiplier=" + $"{20.833332f:0.000}. " + "Pal Jump strength is now half of the previous value."));
	}

	private void OnDestroy()
	{
		OriginalJumpImpulses.Clear();
		ActiveRestoreTokens.Clear();
		nextRestoreToken = 0;
		appliedLogCount = 0;
		restoredLogCount = 0;
		rejectedLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	private static void StoreOriginalJumpImpulse(CharacterMovement movement, bool overwrite)
	{
		if ((Object)(object)movement == (Object)null)
		{
			return;
		}
		float jumpImpulse = movement.jumpImpulse;
		if (!(jumpImpulse <= 0f))
		{
			int instanceID = ((Object)movement).GetInstanceID();
			if (overwrite || !OriginalJumpImpulses.ContainsKey(instanceID))
			{
				OriginalJumpImpulses[instanceID] = jumpImpulse;
			}
		}
	}

	private static bool TryGetOriginalJumpImpulse(CharacterMovement movement, out float originalJumpImpulse)
	{
		originalJumpImpulse = 0f;
		if ((Object)(object)movement == (Object)null)
		{
			return false;
		}
		int instanceID = ((Object)movement).GetInstanceID();
		if (OriginalJumpImpulses.TryGetValue(instanceID, out originalJumpImpulse))
		{
			return originalJumpImpulse > 0f;
		}
		StoreOriginalJumpImpulse(movement, overwrite: false);
		return OriginalJumpImpulses.TryGetValue(instanceID, out originalJumpImpulse) && originalJumpImpulse > 0f;
	}

	private static int CreateRestoreToken(CharacterMovement movement)
	{
		nextRestoreToken++;
		if (nextRestoreToken <= 0)
		{
			nextRestoreToken = 1;
		}
		int instanceID = ((Object)movement).GetInstanceID();
		ActiveRestoreTokens[instanceID] = nextRestoreToken;
		return nextRestoreToken;
	}

	private static bool IsCurrentRestoreToken(CharacterMovement movement, int restoreToken)
	{
		if ((Object)(object)movement == (Object)null)
		{
			return false;
		}
		int value;
		return ActiveRestoreTokens.TryGetValue(((Object)movement).GetInstanceID(), out value) && value == restoreToken;
	}

	private static void RestoreOriginalJumpImpulse(CharacterMovement movement, float originalJumpImpulse, int restoreToken, string reason)
	{
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		if (!IsCurrentRestoreToken(movement, restoreToken))
		{
			return;
		}
		int instanceID = ((Object)movement).GetInstanceID();
		if ((Object)(object)movement != (Object)null && originalJumpImpulse > 0f)
		{
			movement.jumpImpulse = originalJumpImpulse;
		}
		ActiveRestoreTokens.Remove(instanceID);
		if (restoredLogCount < 50)
		{
			restoredLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[7]
				{
					"[Runup] Original jump impulse restored ",
					$"({restoredLogCount}/{50}). ",
					$"Impulse={originalJumpImpulse:0.000}, ",
					"Reason=",
					reason,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[6] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	private static IEnumerator RestoreAfterPalJump(CharacterMovement movement, Character character, float originalJumpImpulse, float previousSincePalJump, int restoreToken)
	{
		if ((Object)(object)movement == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
		{
			RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "InvalidCharacter");
			yield break;
		}
		bool palJumpStarted = false;
		for (int frame = 0; frame < 120; frame++)
		{
			if (!IsCurrentRestoreToken(movement, restoreToken))
			{
				yield break;
			}
			if ((Object)(object)movement == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "CharacterDestroyed");
				yield break;
			}
			if (character.data.dead || character.data.fullyPassedOut)
			{
				RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "CharacterUnavailable");
				yield break;
			}
			bool sincePalJumpWasReset = character.data.sincePalJump < previousSincePalJump - 0.0001f;
			if (character.data.chargingJump || sincePalJumpWasReset)
			{
				palJumpStarted = true;
				break;
			}
			yield return WaitForPhysics;
		}
		if (!palJumpStarted)
		{
			RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "PalJumpDidNotStart");
			yield break;
		}
		for (int i = 0; i < 120; i++)
		{
			yield return WaitForPhysics;
			if (!IsCurrentRestoreToken(movement, restoreToken))
			{
				yield break;
			}
			if ((Object)(object)movement == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
			{
				RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "CharacterDestroyedDuringJump");
				yield break;
			}
			if (character.data.chargingJump)
			{
				continue;
			}
			for (int safetyFrame = 0; safetyFrame < 4; safetyFrame++)
			{
				yield return WaitForPhysics;
				if (!IsCurrentRestoreToken(movement, restoreToken))
				{
					yield break;
				}
			}
			RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "PalJumpCompleted");
			yield break;
		}
		RestoreOriginalJumpImpulse(movement, originalJumpImpulse, restoreToken, "RestoreTimeout");
	}

	private static void LogRejected(string reason)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if (rejectedLogCount < 50)
		{
			rejectedLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[6]
				{
					"[Runup] Pal Jump boost rejected ",
					$"({rejectedLogCount}/{50}). ",
					"Reason=",
					reason,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[5] = ((Scene)(ref activeScene)).name;
				modLogger.LogWarning((object)string.Concat(obj));
			}
		}
	}
}
[BepInPlugin("Sapphire009.StaminaFull", "StaminaFull", "1.0.0")]
public sealed class StaminaFull : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Character), "UseStamina", new Type[]
	{
		typeof(float),
		typeof(bool)
	})]
	private static class CharacterUseStaminaPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Character __instance, float __0, bool __1, ref bool __result)
		{
			if (__0 <= 0f)
			{
				return true;
			}
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			FillAndPreserveStamina(__instance);
			__instance.data.sinceUseStamina = 0f;
			__result = true;
			return false;
		}
	}

	[HarmonyPatch(typeof(Character), "AddStamina", new Type[] { typeof(float) })]
	private static class CharacterAddStaminaPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Character __instance, float __0)
		{
			if (__0 >= 0f)
			{
				return true;
			}
			return !CanApplyProtection(__instance);
		}
	}

	[HarmonyPatch(typeof(Character), "SetExtraStamina", new Type[] { typeof(float) })]
	private static class CharacterSetExtraStaminaPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Character __instance, float __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			if (__0 >= __instance.data.extraStamina)
			{
				return true;
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Character), "AddExtraStamina", new Type[] { typeof(float) })]
	private static class CharacterAddExtraStaminaPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Character __instance, float __0)
		{
			if (__0 >= 0f)
			{
				return true;
			}
			return !CanApplyProtection(__instance);
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool),
		typeof(bool),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAddStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2, bool __3, bool __4, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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)
			if (__1 <= 0f || !CanApplyProtection(__instance))
			{
				return true;
			}
			__result = false;
			LogBlockedStatus(__0, __1, "AddStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AdjustStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAdjustStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (__1 <= 0f || !CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedStatus(__0, __1, "AdjustStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "SetStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool)
	})]
	private static class CharacterAfflictionsSetStatusPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE __0, float __1, bool __2)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			float currentStatus = __instance.GetCurrentStatus(__0);
			if (__1 <= currentStatus)
			{
				return true;
			}
			LogBlockedStatus(__0, __1 - currentStatus, "SetStatus");
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddAffliction", new Type[]
	{
		typeof(Affliction),
		typeof(bool)
	})]
	private static class CharacterAfflictionsAddAfflictionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, Affliction __0, bool __1)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			if (blockedAfflictionLogCount < 50)
			{
				blockedAfflictionLogCount++;
				string text = ((__0 != null) ? ((object)__0).GetType().Name : "null");
				ManualLogSource modLogger = ModLogger;
				if (modLogger != null)
				{
					string[] obj = new string[7]
					{
						"[StaminaFull] Affliction blocked ",
						$"({blockedAfflictionLogCount}/",
						$"{50}). ",
						"Affliction=",
						text,
						", Scene=",
						null
					};
					Scene activeScene = SceneManager.GetActiveScene();
					obj[6] = ((Scene)(ref activeScene)).name;
					modLogger.LogInfo((object)string.Concat(obj));
				}
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(Vector3) })]
	private static class CharacterAfflictionsAddThornPositionPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, Vector3 __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "AddThorn", new Type[] { typeof(ushort) })]
	private static class CharacterAfflictionsAddThornIndexPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, ushort __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(CharacterAfflictions), "RPC_EnableThorn", new Type[] { typeof(int) })]
	private static class CharacterAfflictionsEnableThornPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(CharacterAfflictions __instance, int __0)
		{
			if (!CanApplyProtection(__instance))
			{
				return true;
			}
			LogBlockedThorn();
			return false;
		}
	}

	[HarmonyPatch(typeof(Character), "FixedUpdate")]
	private static class CharacterFixedUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			if (!CanApplyProtection(__instance))
			{
				if ((Object)(object)__instance != (Object)null)
				{
					PreservedExtraStamina.Remove(((Object)__instance).GetInstanceID());
				}
			}
			else
			{
				ClearAllNegativeStates(__instance);
				FillAndPreserveStamina(__instance);
			}
		}
	}

	public const string PluginGUID = "Sapphire009.StaminaFull";

	public const string PluginName = "StaminaFull";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "InfiniteStamina-AllStatusBlock-R2";

	private const int MaximumLogCount = 50;

	internal static ManualLogSource ModLogger;

	private static readonly Dictionary<int, float> PreservedExtraStamina = new Dictionary<int, float>();

	private static int blockedStatusLogCount;

	private static int blockedAfflictionLogCount;

	private static int blockedThornLogCount;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.StaminaFull");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"StaminaFull 1.0.0 loaded. Build: InfiniteStamina-AllStatusBlock-R2. Infinite stamina and complete status protection are enabled outside Airport.");
	}

	private void OnDestroy()
	{
		PreservedExtraStamina.Clear();
		blockedStatusLogCount = 0;
		blockedAfflictionLogCount = 0;
		blockedThornLogCount = 0;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static bool CanApplyProtection(Character character)
	{
		if ((Object)(object)character == (Object)null || !character.IsLocal || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null)
		{
			return false;
		}
		if (IsAirportScene())
		{
			return false;
		}
		return true;
	}

	internal static bool CanApplyProtection(CharacterAfflictions afflictions)
	{
		if ((Object)(object)afflictions == (Object)null)
		{
			return false;
		}
		return CanApplyProtection(afflictions.character);
	}

	internal static void FillAndPreserveStamina(Character character)
	{
		if (!CanApplyProtection(character))
		{
			if ((Object)(object)character != (Object)null)
			{
				PreservedExtraStamina.Remove(((Object)character).GetInstanceID());
			}
			return;
		}
		float maxStamina = character.GetMaxStamina();
		maxStamina = Mathf.Max(maxStamina, 1f);
		bool flag = false;
		if (Mathf.Abs(character.data.currentStamina - maxStamina) > 0.0001f)
		{
			character.data.currentStamina = maxStamina;
			flag = true;
		}
		int instanceID = ((Object)character).GetInstanceID();
		if (!PreservedExtraStamina.TryGetValue(instanceID, out var value))
		{
			value = character.data.extraStamina;
			PreservedExtraStamina.Add(instanceID, value);
		}
		else if (character.data.extraStamina > value)
		{
			value = character.data.extraStamina;
			PreservedExtraStamina[instanceID] = value;
		}
		else if (character.data.extraStamina < value)
		{
			character.data.extraStamina = value;
			flag = true;
		}
		if (flag && (Object)(object)GUIManager.instance != (Object)null && (Object)(object)GUIManager.instance.bar != (Object)null)
		{
			GUIManager.instance.bar.ChangeBar();
		}
	}

	internal static void ClearAllNegativeStates(Character character)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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)
		if (!CanApplyProtection(character))
		{
			return;
		}
		CharacterAfflictions afflictions = character.refs.afflictions;
		bool flag = false;
		int numStatusTypes = CharacterAfflictions.NumStatusTypes;
		for (int i = 0; i < numStatusTypes; i++)
		{
			STATUSTYPE val = (STATUSTYPE)i;
			if (!(afflictions.GetCurrentStatus(val) <= 0f))
			{
				afflictions.SetStatus(val, 0f, false);
				flag = true;
			}
		}
		if (afflictions.isWebbed)
		{
			afflictions.SetStatus((STATUSTYPE)11, 0f, false);
			afflictions.isWebbed = false;
			flag = true;
		}
		if (flag)
		{
			afflictions.PushStatuses((Player)null);
		}
		if (afflictions.afflictionList != null && afflictions.afflictionList.Count > 0)
		{
			afflictions.ClearAllAfflictions();
		}
		if (afflictions.physicalThorns == null)
		{
			return;
		}
		for (int num = afflictions.physicalThorns.Count - 1; num >= 0; num--)
		{
			ThornOnMe val2 = afflictions.physicalThorns[num];
			if (!((Object)(object)val2 == (Object)null) && val2.stuckIn)
			{
				afflictions.RemoveThorn(val2);
			}
		}
	}

	private static void LogBlockedStatus(STATUSTYPE statusType, float amount, string source)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		if (blockedStatusLogCount < 50)
		{
			blockedStatusLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string[] obj = new string[8]
				{
					"[StaminaFull] Status blocked ",
					$"({blockedStatusLogCount}/{50}). ",
					$"Status={statusType}, ",
					$"Amount={amount:0.0000}, ",
					"Source=",
					source,
					", Scene=",
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[7] = ((Scene)(ref activeScene)).name;
				modLogger.LogInfo((object)string.Concat(obj));
			}
		}
	}

	private static void LogBlockedThorn()
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (blockedThornLogCount < 50)
		{
			blockedThornLogCount++;
			ManualLogSource modLogger = ModLogger;
			if (modLogger != null)
			{
				string text = $"({blockedThornLogCount}/{50}). ";
				Scene activeScene = SceneManager.GetActiveScene();
				modLogger.LogInfo((object)("[StaminaFull] Thorn blocked " + text + "Scene=" + ((Scene)(ref activeScene)).name));
			}
		}
	}
}
[BepInPlugin("Sapphire009.WASDX", "WASDX", "1.0.0")]
public sealed class WASDX : BaseUnityPlugin
{
	[HarmonyPatch(typeof(CharacterInput), "Sample", new Type[] { typeof(bool) })]
	private static class CharacterInputSamplePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterInput __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				GroundLeanInput = Vector2.zero;
				return;
			}
			Character val = ResolveCharacter((Component)(object)__instance);
			if (!((Object)(object)val == (Object)null) && val.IsLocal && !((Object)(object)val.data == (Object)null))
			{
				if (!ShouldBlockGroundMovement(val))
				{
					GroundLeanInput = Vector2.zero;
					return;
				}
				GroundLeanInput = __instance.movementInput;
				__instance.movementInput = Vector2.zero;
			}
		}
	}

	[HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")]
	private static class CharacterMovementGetMovementForcePatch
	{
		[HarmonyPostfix]
		private static void Postfix(CharacterMovement __instance, ref float __result)
		{
			Character character = ResolveCharacter((Component)(object)__instance);
			if (ShouldBlockGroundMovement(character))
			{
				__result = 0f;
			}
		}
	}

	[HarmonyPatch(typeof(MainCameraMovement), "CharacterCam")]
	private static class MainCameraMovementCharacterCamPatch
	{
		private const float ForwardTiltDegrees = 4f;

		private const float SideTiltDegrees = 4f;

		private const float TiltSmoothSpeed = 9f;

		private static Vector2 currentTilt = Vector2.zero;

		[HarmonyPostfix]
		private static void Postfix(MainCameraMovement __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)null))
			{
				Character localCharacter = Character.localCharacter;
				Vector2 val = Vector2.zero;
				if (ShouldBlockGroundMovement(localCharacter))
				{
					val = GroundLeanInput;
				}
				float num = 1f - Mathf.Exp(-9f * Time.deltaTime);
				currentTilt = Vector2.Lerp(currentTilt, val, num);
				if (((Vector2)(ref currentTilt)).sqrMagnitude < 1E-06f)
				{
					currentTilt = Vector2.zero;
				}
				float num2 = currentTilt.y * 4f;
				float num3 = (0f - currentTilt.x) * 4f;
				Quaternion val2 = Quaternion.Euler(num2, 0f, num3);
				((Component)__instance).transform.rotation = ((Component)__instance).transform.rotation * val2;
			}
		}

		internal static void ResetTilt()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			currentTilt = Vector2.zero;
		}
	}

	public const string PluginGUID = "Sapphire009.WASDX";

	public const string PluginName = "WASDX";

	public const string PluginVersion = "1.0.0";

	private const string BuildMarker = "GroundLock-CameraLean-R1";

	internal static ManualLogSource ModLogger;

	internal static Vector2 GroundLeanInput = Vector2.zero;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		ModLogger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("Sapphire009.WASDX");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"WASDX 1.0.0 loaded. Build: GroundLock-CameraLean-R1. Ground WASD movement is blocked outside Airport. Air movement remains enabled.");
	}

	private void OnDestroy()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		GroundLeanInput = Vector2.zero;
		MainCameraMovementCharacterCamPatch.ResetTilt();
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		ModLogger = null;
	}

	internal static bool IsAirportScene()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		Scene activeScene = SceneManager.GetActiveScene();
		string name = ((Scene)(ref activeScene)).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0;
	}

	internal static Character ResolveCharacter(Component component)
	{
		if ((Object)(object)component == (Object)null)
		{
			return null;
		}
		Character val = component.GetComponent<Character>();
		if ((Object)(object)val == (Object)null)
		{
			val = component.GetComponentInParent<Character>();
		}
		return val;
	}

	internal static bool ShouldBlockGroundMovement(Character character)
	{
		if ((Object)(object)character == (Obj