Decompiled source of JumpingPEAK v1.0.3
plugins/JumpingPEAK.dll
Decompiled 21 hours ago
The result has been truncated due to the large size, download it to view full contents!
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