Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ClimbingMod v1.1.5
Valheim-Climbing-Mod.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Valheim_Climbing_Mod { public static class ClimbAnimationController { private enum ClipDirection { Up, Down } private class PlayerAnimationState { public Animator Animator; public PlayableGraph Graph; public AnimationClipPlayable UpPlayable; public AnimationClipPlayable DownPlayable; public AnimationMixerPlayable Mixer; public ClipDirection CurrentDirection = ClipDirection.Up; } private static readonly Dictionary<Player, PlayerAnimationState> ActiveStates = new Dictionary<Player, PlayerAnimationState>(); private static ManualLogSource _logger; private static AnimationClip _upClip; private static AnimationClip _downClip; private static bool _initialized; private static readonly FieldInfo AnimatorField = AccessTools.Field(typeof(Character), "m_animator"); public static void Initialize(ManualLogSource logger) { if (_initialized) { return; } _initialized = true; _logger = logger; _upClip = LoadClip("climbingup"); _downClip = LoadClip("climbingdown"); if ((Object)(object)_upClip == (Object)null || (Object)(object)_downClip == (Object)null) { ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)"Climbing animation clips were not loaded. Default animations will be used instead."); } } } private static AnimationClip LoadClip(string bundleName) { try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)("Unable to determine plugin directory while loading '" + bundleName + "'.")); } return null; } string text = Path.Combine(directoryName, bundleName); if (!File.Exists(text)) { ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Animation asset bundle '" + text + "' was not found.")); } return null; } AssetBundle val = AssetBundle.LoadFromFile(text); if ((Object)(object)val == (Object)null) { ManualLogSource logger3 = _logger; if (logger3 != null) { logger3.LogWarning((object)("Failed to load AssetBundle from '" + text + "'.")); } return null; } try { AnimationClip val2 = val.LoadAsset<AnimationClip>(bundleName); if ((Object)(object)val2 == (Object)null) { AnimationClip[] array = val.LoadAllAssets<AnimationClip>(); if (array.Length != 0) { val2 = array[0]; } } if ((Object)(object)val2 == (Object)null) { ManualLogSource logger4 = _logger; if (logger4 != null) { logger4.LogWarning((object)("No AnimationClip found inside '" + bundleName + "'.")); } } return val2; } finally { val.Unload(false); } } catch (Exception arg) { ManualLogSource logger5 = _logger; if (logger5 != null) { logger5.LogError((object)$"Failed to load animation clip '{bundleName}': {arg}"); } return null; } } private static Animator GetAnimator(Player player) { if (AnimatorField != null) { object? value = AnimatorField.GetValue(player); Animator val = (Animator)((value is Animator) ? value : null); if (val != null && (Object)(object)val != (Object)null) { return val; } } return ((Component)player).GetComponentInChildren<Animator>(); } public static void Begin(Player player) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) //IL_00a8: 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) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_upClip == (Object)null || (Object)(object)_downClip == (Object)null || ActiveStates.ContainsKey(player)) { return; } Animator animator = GetAnimator(player); if ((Object)(object)animator == (Object)null) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)"Unable to locate player Animator component for climbing animations."); } return; } PlayableGraph val = PlayableGraph.Create($"ClimbGraph_{player.GetPlayerID()}"); ((PlayableGraph)(ref val)).SetTimeUpdateMode((DirectorUpdateMode)1); AnimationClipPlayable val2 = AnimationClipPlayable.Create(val, _upClip); ((AnimationClipPlayable)(ref val2)).SetApplyFootIK(true); AnimationClipPlayable val3 = AnimationClipPlayable.Create(val, _downClip); ((AnimationClipPlayable)(ref val3)).SetApplyFootIK(true); AnimationMixerPlayable val4 = AnimationMixerPlayable.Create(val, 2); ((PlayableGraph)(ref val)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(val2, 0, val4, 0); ((PlayableGraph)(ref val)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(val3, 0, val4, 1); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(val4, 0, 1f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(val4, 1, 0f); AnimationPlayableOutput val5 = AnimationPlayableOutput.Create(val, "ClimbOutput", animator); PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationMixerPlayable>(val5, val4); ((PlayableGraph)(ref val)).Play(); ActiveStates[player] = new PlayerAnimationState { Animator = animator, Graph = val, UpPlayable = val2, DownPlayable = val3, Mixer = val4, CurrentDirection = ClipDirection.Up }; } public static void Update(Player player, float verticalInput, float animationSpeedMultiplier = 0.9f) { if (ActiveStates.TryGetValue(player, out var value)) { if (Mathf.Abs(verticalInput) <= 0.05f) { Pause(value); } else if (verticalInput > 0f) { SwitchClip(value, ClipDirection.Up, Mathf.Abs(verticalInput), animationSpeedMultiplier); } else { SwitchClip(value, ClipDirection.Down, Mathf.Abs(verticalInput), animationSpeedMultiplier); } } } private static void Pause(PlayerAnimationState state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.UpPlayable, 0.0); PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.DownPlayable, 0.0); } private static void SwitchClip(PlayerAnimationState state, ClipDirection direction, float speed, float animationSpeedMultiplier) { //IL_00b9: 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) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0047: 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_006b: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(speed * Mathf.Max(animationSpeedMultiplier, 0.01f), 0.25f); if (direction == ClipDirection.Up) { if (state.CurrentDirection != 0) { PlayableExtensions.SetTime<AnimationClipPlayable>(state.UpPlayable, 0.0); } PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(state.Mixer, 0, 1f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(state.Mixer, 1, 0f); PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.UpPlayable, (double)num); PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.DownPlayable, 0.0); } else { if (state.CurrentDirection != ClipDirection.Down) { PlayableExtensions.SetTime<AnimationClipPlayable>(state.DownPlayable, 0.0); } PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(state.Mixer, 0, 0f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(state.Mixer, 1, 1f); PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.DownPlayable, (double)num); PlayableExtensions.SetSpeed<AnimationClipPlayable>(state.UpPlayable, 0.0); } state.CurrentDirection = direction; if (!((PlayableGraph)(ref state.Graph)).IsPlaying()) { ((PlayableGraph)(ref state.Graph)).Play(); } } public static void End(Player player) { if (ActiveStates.TryGetValue(player, out var value)) { if (((PlayableGraph)(ref value.Graph)).IsValid()) { ((PlayableGraph)(ref value.Graph)).Destroy(); } ActiveStates.Remove(player); } } public static void Cleanup(Player player) { End(player); } public static bool IsActive(Player player) { return ActiveStates.ContainsKey(player); } } public static class ClimbingConfig { public const float DETECTION_DISTANCE = 0.6f; public const float MIN_SURFACE_ANGLE = 55f; public const float MAX_SURFACE_ANGLE = 240f; public const float STICK_FORCE = 0.5f; public const float SURFACE_TARGET_DISTANCE = 0.18f; public const float SURFACE_REPEL_FORCE = 0.15f; public const float FACE_SURFACE_TURN_SPEED = 10f; public const float STEEP_SURFACE_ANGLE = 90f; public const float SHALLOW_SURFACE_ANGLE = 10f; public const float STEEP_SURFACE_SPEED_FACTOR = 1f; public const float SHALLOW_SURFACE_SPEED_FACTOR = 1.4f; public const float REPEL_DISABLE_SURFACE_ANGLE = 25f; public const float REPEL_FULL_STRENGTH_SURFACE_ANGLE = 60f; public static float CLIMB_SPEED_UP => ClimbingModPlugin.ClimbSpeedUp?.Value ?? 1f; public static float CLIMB_SPEED_DOWN => ClimbingModPlugin.ClimbSpeedDown?.Value ?? 1f; public static float STAMINA_DRAIN_PER_SECOND => ClimbingModPlugin.StaminaDrainPerSecond?.Value ?? 3f; } [BepInPlugin("com.rotceh.valheimclimbingmod", "Valheim Climbing Mod", "1.0.0")] public class ClimbingModPlugin : BaseUnityPlugin { public static ConfigEntry<KeyCode> ClimbKey; public static ConfigEntry<KeyCode> ClimbKey2; public static ConfigEntry<float> ClimbSpeedUp; public static ConfigEntry<float> ClimbSpeedDown; public static ConfigEntry<float> StaminaDrainPerSecond; public static ConfigEntry<float> ClimbSkillXpPerSecond; public static ConfigEntry<float> ClimbSkillBaseXpPerLevel; public static ConfigEntry<float> ClimbSkillXpIncreasePerLevel; public static ConfigEntry<bool> ToggleClimbKey; private void Awake() { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) ClimbKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ClimbKey", (KeyCode)308, "Key to trigger climbing (default: LeftAlt)"); ClimbKey2 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ClimbKey2", (KeyCode)0, "Optional second key that must be held along with ClimbKey."); ToggleClimbKey = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ToggleClimbKey", false, "When enabled, pressing the climb key toggles climbing instead of requiring the key to be held."); ClimbSpeedUp = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "ClimbSpeedUp", 1f, "Base climb speed when moving upward (W)."); ClimbSpeedDown = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "ClimbSpeedDown", 1f, "Base climb speed when moving downward or sideways (S/A/D)."); StaminaDrainPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "StaminaDrainPerSecond", 2f, "Stamina drained per second while climbing (scaled by movement)."); ClimbSkillXpPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "ClimbSkillXpPerSecond", 6f, "Climbing XP gained per second while climbing."); ClimbSkillBaseXpPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "ClimbSkillBaseXpPerLevel", 100f, "XP required for level 0 -> 1."); ClimbSkillXpIncreasePerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Progression", "ClimbSkillXpIncreasePerLevel", 40f, "Additional XP required per level."); Harmony val = new Harmony("com.rotceh.valheimclimbingmod"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Valheim Climbing Mod loaded. Climb key: {ClimbKey.Value} + Modifier: {ClimbKey2.Value}"); ClimbAnimationController.Initialize(((BaseUnityPlugin)this).Logger); } } [HarmonyPatch(typeof(Player), "FixedUpdate")] public class Player_FixedUpdate_Patch { [CompilerGenerated] private sealed class <EnumerateProbeDirections>d__29 : IEnumerable<Vector3>, IEnumerable, IEnumerator<Vector3>, IDisposable, IEnumerator { private int <>1__state; private Vector3 <>2__current; private int <>l__initialThreadId; private Player player; public Player <>3__player; private Vector3 preferredNormal; public Vector3 <>3__preferredNormal; private Transform <t>5__1; private Vector3[] <>s__2; private int <>s__3; private Vector3 <dir>5__4; Vector3 IEnumerator<Vector3>.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } [DebuggerHidden] public <EnumerateProbeDirections>d__29(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <t>5__1 = null; <>s__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0065: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (preferredNormal != Vector3.zero) { <>2__current = -((Vector3)(ref preferredNormal)).normalized; <>1__state = 1; return true; } goto IL_00a0; case 1: <>1__state = -1; goto IL_00a0; case 2: <>1__state = -1; <>2__current = -<t>5__1.forward; <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = <t>5__1.up; <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = -<t>5__1.up; <>1__state = 5; return true; case 5: <>1__state = -1; <>2__current = <t>5__1.right; <>1__state = 6; return true; case 6: <>1__state = -1; <>2__current = -<t>5__1.right; <>1__state = 7; return true; case 7: <>1__state = -1; <>s__2 = WorldProbeDirections; <>s__3 = 0; break; case 8: { <>1__state = -1; <>s__3++; break; } IL_00a0: <t>5__1 = ((Component)player).transform; <>2__current = <t>5__1.forward; <>1__state = 2; return true; } if (<>s__3 < <>s__2.Length) { <dir>5__4 = <>s__2[<>s__3]; <>2__current = <dir>5__4; <>1__state = 8; return true; } <>s__2 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<Vector3> IEnumerable<Vector3>.GetEnumerator() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) <EnumerateProbeDirections>d__29 <EnumerateProbeDirections>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateProbeDirections>d__ = this; } else { <EnumerateProbeDirections>d__ = new <EnumerateProbeDirections>d__29(0); } <EnumerateProbeDirections>d__.player = <>3__player; <EnumerateProbeDirections>d__.preferredNormal = <>3__preferredNormal; return <EnumerateProbeDirections>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Vector3>)this).GetEnumerator(); } } private static readonly int SurfaceLayerMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "Default_small" }); private const float TopOutProbeHeight = 1.2f; private const float TopOutProbeForwardOffset = 0.55f; private const float TopOutGroundCheckDistance = 1.6f; private const float TopOutWallCheckDistance = 0.65f; private const float TopOutJumpUpSpeed = 5.5f; private const float TopOutJumpForwardSpeed = 2.2f; private static readonly FieldInfo MaxAirAltitudeField = AccessTools.Field(typeof(Character), "m_maxAirAltitude"); private static readonly FieldInfo LastGroundPointField = AccessTools.Field(typeof(Character), "m_lastGroundPoint"); private static readonly float[] ProbeHeights = new float[3] { 1.2f, 0.7f, 0.2f }; private static readonly float[] StartProbeHeights = new float[2] { 1.15f, 0.8f }; private static readonly float[] StartProbeYawOffsets = new float[3] { 0f, -20f, 20f }; private const int RequiredStableStartFrames = 3; private const float MinFacingWallDot = 0.55f; private const float MinStartHitHeightOffset = 0.25f; private static readonly Vector3[] WorldProbeDirections = (Vector3[])(object)new Vector3[6] { Vector3.up, Vector3.down, Vector3.right, Vector3.left, Vector3.forward, Vector3.back }; private static MethodInfo _takeInputMethod; private static bool CallTakeInput(Player player) { if (_takeInputMethod == null) { _takeInputMethod = typeof(Player).GetMethod("TakeInput", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_takeInputMethod != null) { return (bool)_takeInputMethod.Invoke(player, null); } return true; } private static void Postfix(Player __instance) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { HandleRemotePlayer(__instance); } else { if (((Character)__instance).IsDead() || ((Character)__instance).InCutscene() || ((Character)__instance).IsTeleporting()) { return; } ClimbingState.ClimbingData orCreate = ClimbingState.GetOrCreate(__instance); float skill = ClimbSkillProgression.GetSkill(__instance); orCreate.climbSkill = skill; bool flag = ClimbingModPlugin.ToggleClimbKey?.Value ?? false; bool flag2 = false; if (CallTakeInput(__instance)) { bool flag3 = (int)ClimbingModPlugin.ClimbKey2.Value == 0 || Input.GetKey(ClimbingModPlugin.ClimbKey2.Value); if (flag) { if (flag3 && Input.GetKeyDown(ClimbingModPlugin.ClimbKey.Value)) { orCreate.toggleActive = !orCreate.toggleActive; if (!orCreate.toggleActive && orCreate.isClimbing) { StopClimbing(__instance, orCreate); } } flag2 = orCreate.toggleActive; } else { flag2 = flag3 && Input.GetKey(ClimbingModPlugin.ClimbKey.Value); if (!flag2) { orCreate.toggleActive = false; orCreate.validStartSurfaceFrames = 0; } } } else { flag2 = orCreate.toggleActive; } Vector3 normal; if (!orCreate.isClimbing) { if (flag2) { TryStartClimbing(__instance, orCreate); } else { orCreate.validStartSurfaceFrames = 0; } } else if (!flag2) { StopClimbing(__instance, orCreate); } else if (!PlayerHasClimbStamina(__instance)) { StopClimbing(__instance, orCreate); } else if (TryGetSurfaceNormal(__instance, out normal, orCreate.surfaceNormal)) { orCreate.surfaceNormal = normal; ClimbSkillProgression.AddSkill(__instance, Time.deltaTime); float skill2 = ClimbSkillProgression.GetSkill(__instance); orCreate.climbSkill = skill2; } else { Vector3 surfaceNormal = orCreate.surfaceNormal; StopClimbing(__instance, orCreate); TryAutoTopOutJump(__instance, surfaceNormal); } } } private static void TryAutoTopOutJump(Player player, Vector3 previousSurfaceNormal) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_005c: 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) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || previousSurfaceNormal == Vector3.zero) { return; } Transform transform = ((Component)player).transform; Vector3 val = Vector3.ProjectOnPlane(-previousSurfaceNormal, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = transform.position + Vector3.up * 1f; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(val2, 0.25f, val, ref val3, 0.65f, SurfaceLayerMask)) { return; } Vector3 val4 = transform.position + Vector3.up * 1.2f + val * 0.55f; RaycastHit val5 = default(RaycastHit); if (!Physics.Raycast(val4, Vector3.down, ref val5, 1.6f, SurfaceLayerMask)) { return; } float num = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val5)).normal); if (!(num > 50f)) { Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if (!((Object)(object)component == (Object)null)) { Vector3 linearVelocity = component.linearVelocity; Vector3 val6 = Vector3.ProjectOnPlane(linearVelocity, Vector3.up); val6 += val * 2.2f; float num2 = Mathf.Max(linearVelocity.y, 5.5f); component.linearVelocity = new Vector3(val6.x, num2, val6.z); } } } private static void HandleRemotePlayer(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { ZDO zDO = component.GetZDO(); bool @bool = zDO.GetBool("IsClimbing", false); float @float = zDO.GetFloat("RotcehClimbSkill", 0f); bool flag = ClimbAnimationController.IsActive(player); if (@bool && !flag) { ClimbAnimationController.Begin(player); } else if (!@bool && flag) { ClimbAnimationController.End(player); } if (@bool) { float float2 = zDO.GetFloat("ClimbInput", 0f); float speedMultiplier = ClimbSkillProgression.GetSpeedMultiplier(@float); ClimbAnimationController.Update(player, float2, speedMultiplier); } } } private static void TryStartClimbing(Player player, ClimbingState.ClimbingData climbData) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 normal; if (!PlayerHasClimbStamina(player)) { climbData.validStartSurfaceFrames = 0; } else if (TryGetStartSurfaceNormal(player, out normal)) { climbData.validStartSurfaceFrames++; if (climbData.validStartSurfaceFrames >= 3) { StartClimbing(player, climbData, normal); } } else { climbData.validStartSurfaceFrames = 0; } } private static bool TryGetStartSurfaceNormal(Player player, out Vector3 normal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //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) //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) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)player).transform; Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = transform.forward; } ((Vector3)(ref val)).Normalize(); float num = 0.8f; float[] startProbeHeights = StartProbeHeights; RaycastHit val4 = default(RaycastHit); foreach (float num2 in startProbeHeights) { Vector3 val2 = transform.position + Vector3.up * num2; float[] startProbeYawOffsets = StartProbeYawOffsets; foreach (float num3 in startProbeYawOffsets) { Vector3 val3 = Quaternion.AngleAxis(num3, transform.up) * val; if (!Physics.SphereCast(val2, 0.3f, val3, ref val4, num, SurfaceLayerMask)) { continue; } float num4 = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val4)).normal); if (!(num4 < 55f) && !(num4 > 240f)) { Vector3 normal2 = ((RaycastHit)(ref val4)).normal; float num5 = Vector3.Dot(-((Vector3)(ref normal2)).normalized, ((Vector3)(ref val3)).normalized); if (!(num5 < 0.55f) && !(((RaycastHit)(ref val4)).point.y < transform.position.y + 0.25f)) { normal = ((RaycastHit)(ref val4)).normal; return true; } } } } normal = Vector3.zero; return false; } public static bool HasReliableClimbSurface(Player player, ClimbingState.ClimbingData climbData) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || climbData == null || !climbData.isClimbing) { return false; } Vector3 normal; return TryGetSurfaceNormal(player, out normal, climbData.surfaceNormal); } private static bool PlayerHasClimbStamina(Player player) { return player.GetStamina() > 0.25f; } private static void StartClimbing(Player player, ClimbingState.ClimbingData climbData, Vector3 surfaceNormal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) climbData.isClimbing = true; climbData.surfaceNormal = surfaceNormal; climbData.validStartSurfaceFrames = 0; ResetFallCalculation(player); ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.GetZDO().Set("IsClimbing", true); component.GetZDO().Set("RotcehClimbSkill", ClimbSkillProgression.GetSkill(player)); } Rigidbody component2 = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component2 != (Object)null) { climbData.wasGravityEnabled = component2.useGravity; component2.useGravity = false; component2.linearVelocity = Vector3.zero; component2.angularVelocity = Vector3.zero; } ClimbAnimationController.Begin(player); } public static void ResetFallCalculation(Player player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { float y = ((Component)player).transform.position.y; if (MaxAirAltitudeField != null) { MaxAirAltitudeField.SetValue(player, y); } if (LastGroundPointField != null) { LastGroundPointField.SetValue(player, ((Component)player).transform.position); } } } public static void StopClimbing(Player player, ClimbingState.ClimbingData climbData) { climbData.isClimbing = false; climbData.validStartSurfaceFrames = 0; ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.GetZDO().Set("IsClimbing", false); component.GetZDO().Set("RotcehClimbSkill", ClimbSkillProgression.GetSkill(player)); } Rigidbody component2 = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component2 != (Object)null) { component2.useGravity = climbData.wasGravityEnabled; } ClimbAnimationController.End(player); } private static bool TryGetSurfaceNormal(Player player, out Vector3 normal, Vector3 preferredNormal = default(Vector3)) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0039: 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) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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) float num = 1.35f; float[] probeHeights = ProbeHeights; RaycastHit val2 = default(RaycastHit); foreach (float num2 in probeHeights) { Vector3 val = ((Component)player).transform.position + Vector3.up * num2; foreach (Vector3 item in EnumerateProbeDirections(player, preferredNormal)) { if (Physics.SphereCast(val, 0.4f, item, ref val2, num, SurfaceLayerMask)) { float num3 = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val2)).normal); if (num3 >= 55f && num3 <= 240f) { normal = ((RaycastHit)(ref val2)).normal; return true; } } } } normal = Vector3.zero; return false; } [IteratorStateMachine(typeof(<EnumerateProbeDirections>d__29))] private static IEnumerable<Vector3> EnumerateProbeDirections(Player player, Vector3 preferredNormal) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateProbeDirections>d__29(-2) { <>3__player = player, <>3__preferredNormal = preferredNormal }; } } [HarmonyPatch(typeof(Character), "UpdateMotion")] internal class Character_UpdateMotion_Patch { private static readonly int SurfaceLayerMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "Default_small" }); private static bool Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && ClimbingState.IsClimbing(val)) { HandleClimbingMovement(val); return false; } return true; } private static void HandleClimbingMovement(Player player) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) //IL_007b: 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) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0115: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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) Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if (!((Object)(object)component == (Object)null)) { component.useGravity = false; Player_FixedUpdate_Patch.ResetFallCalculation(player); float axis = Input.GetAxis("Vertical"); float axis2 = Input.GetAxis("Horizontal"); Vector3 val = Vector3.zero; ClimbingState.ClimbingData orCreate = ClimbingState.GetOrCreate(player); Vector3 val2 = ((orCreate.surfaceNormal != Vector3.zero) ? orCreate.surfaceNormal : (-((Component)player).transform.forward)); float num = CalculateSlopeSpeedFactor(val2); float num2 = Mathf.Lerp(1f, 3f, Mathf.Clamp01(orCreate.climbSkill / 100f)); float num3 = num * num2; Vector3 val3 = ResolveClimbDirection(val2, ((Component)player).transform); Vector3 val4 = ResolveLateralDirection(val2, val3); if (Mathf.Abs(axis) > 0.1f && ((Vector3)(ref val3)).sqrMagnitude > 0.01f) { float num4 = ((axis > 0f) ? ClimbingConfig.CLIMB_SPEED_UP : ClimbingConfig.CLIMB_SPEED_DOWN); val += val3 * num4 * axis * num3; } if (Mathf.Abs(axis2) > 0.1f && ((Vector3)(ref val4)).sqrMagnitude > 0.01f) { val += val4 * ClimbingConfig.CLIMB_SPEED_DOWN * axis2 * num3; } Vector3 val5 = -val2; Vector3 normalized = ((Vector3)(ref val5)).normalized; val += normalized * 0.5f; ApplySurfaceRepulsion(player, val2, ref val); AlignWithSurface(player, val2); component.linearVelocity = val; float num5 = ResolveAnimationInput(axis, axis2); ClimbAnimationController.Update(player, num5, num3); ZNetView component2 = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { component2.GetZDO().Set("ClimbInput", num5); } ApplyClimbStaminaDrain(player, axis, axis2); } } private static float CalculateSlopeSpeedFactor(Vector3 surfaceNormal) { //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) float num = Vector3.Angle(Vector3.up, surfaceNormal); float num2 = Mathf.InverseLerp(90f, 10f, num); return Mathf.Clamp(Mathf.Lerp(1f, 1.4f, num2), 0.1f, 3f); } private static Vector3 ResolveClimbDirection(Vector3 surfaceNormal, Transform transform) { //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) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) //IL_0026: 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) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(Vector3.up, surfaceNormal); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.ProjectOnPlane(transform.forward, surfaceNormal); } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.Cross(surfaceNormal, transform.right); } return (((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.forward; } private static Vector3 ResolveLateralDirection(Vector3 surfaceNormal, Vector3 climbDirection) { //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_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0027: 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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) Vector3 val = Vector3.Cross(surfaceNormal, climbDirection); if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.Cross(surfaceNormal, Vector3.up); } return (((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.zero; } private static float ResolveAnimationInput(float forwardInput, float rightInput) { if (Mathf.Abs(forwardInput) > 0.05f) { return forwardInput; } return (Mathf.Abs(rightInput) > 0.1f) ? Mathf.Abs(rightInput) : 0f; } private static void ApplyClimbStaminaDrain(Player player, float forwardInput, float rightInput) { float sTAMINA_DRAIN_PER_SECOND = ClimbingConfig.STAMINA_DRAIN_PER_SECOND; if (!(sTAMINA_DRAIN_PER_SECOND <= 0f)) { float num = Mathf.Clamp01(Mathf.Max(Mathf.Abs(forwardInput), Mathf.Abs(rightInput))); float num2 = ((num <= 0.05f) ? 0.1f : Mathf.Lerp(0.5f, 1f, num)); ((Character)player).UseStamina(num2 * sTAMINA_DRAIN_PER_SECOND * Time.deltaTime); } } private static void ApplySurfaceRepulsion(Player player, Vector3 surfaceNormal, ref Vector3 climbVelocity) { //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_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_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //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) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (surfaceNormal == Vector3.zero) { return; } Vector3 val = ((Component)player).transform.position + Vector3.up * 1f; float num = 0.93f; float num2 = Vector3.Angle(Vector3.up, surfaceNormal); float num3 = Mathf.Clamp01(Mathf.InverseLerp(25f, 60f, num2)); RaycastHit val2 = default(RaycastHit); if (!(num3 <= 0.001f) && Physics.Raycast(val, -surfaceNormal, ref val2, num, SurfaceLayerMask)) { float num4 = 0.18f - ((RaycastHit)(ref val2)).distance; if (num4 > 0f) { climbVelocity += ((Vector3)(ref surfaceNormal)).normalized * (0.15f * num4 * num3); } } } private static void AlignWithSurface(Player player, Vector3 surfaceNormal) { //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_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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_006e: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00a4: Unknown result type (might be due to invalid IL or missing references) if (!(surfaceNormal == Vector3.zero)) { Vector3 val = -((Vector3)(ref surfaceNormal)).normalized; Vector3 val2 = ((Mathf.Abs(Vector3.Dot(val, Vector3.up)) > 0.95f) ? Vector3.forward : Vector3.up); Vector3 val3 = Vector3.Cross(val2, val); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val2 = Vector3.right; val3 = Vector3.Cross(val2, val); } ((Vector3)(ref val3)).Normalize(); Vector3 val4 = Vector3.Cross(val, val3); Vector3 val5 = ((Vector3)(ref val4)).normalized; if (((Vector3)(ref val5)).sqrMagnitude < 0.0001f) { val5 = val2; } Quaternion val6 = Quaternion.LookRotation(val, val5); ((Component)player).transform.rotation = Quaternion.Slerp(((Component)player).transform.rotation, val6, Time.deltaTime * 10f); } } } [HarmonyPatch(typeof(Character), "ApplySlide")] internal class Character_ApplySlide_Patch { private static bool Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && ClimbingState.IsClimbing(val)) { return false; } return true; } } [HarmonyPatch(typeof(Player), "OnDestroy")] internal class Player_OnDestroy_Patch { private static void Postfix(Player __instance) { ClimbingState.Cleanup(__instance); ClimbAnimationController.Cleanup(__instance); } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal class Humanoid_StartAttack_Patch { private static bool Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && ClimbingState.IsClimbing(val)) { return false; } return true; } } [HarmonyPatch(typeof(Character), "Damage")] internal class Character_Damage_Patch { private static void Prefix(Character __instance, ref HitData hit) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (hit == null) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !ClimbingState.IsClimbing(val)) { return; } if ((int)hit.m_hitType == 3) { ClimbingState.ClimbingData orCreate = ClimbingState.GetOrCreate(val); if (Player_FixedUpdate_Patch.HasReliableClimbSurface(val, orCreate)) { hit.m_damage = default(DamageTypes); hit.m_pushForce = 0f; } } else if (hit.m_pushForce > 5f) { ClimbingState.ClimbingData orCreate2 = ClimbingState.GetOrCreate(val); Player_FixedUpdate_Patch.StopClimbing(val, orCreate2); } } } public static class ClimbingState { public class ClimbingData { public bool isClimbing = false; public Vector3 surfaceNormal = Vector3.zero; public bool wasGravityEnabled = true; public bool toggleActive = false; public float climbSkill = 0f; public int validStartSurfaceFrames = 0; } private static Dictionary<Player, ClimbingData> climbingPlayers = new Dictionary<Player, ClimbingData>(); public static ClimbingData GetOrCreate(Player player) { if (!climbingPlayers.TryGetValue(player, out var value)) { value = new ClimbingData(); climbingPlayers[player] = value; } return value; } public static bool IsClimbing(Player player) { ClimbingData value; return climbingPlayers.TryGetValue(player, out value) && value.isClimbing; } public static void Cleanup(Player player) { climbingPlayers.Remove(player); } } public static class ClimbSkillProgression { public const string SkillKey = "RotcehClimbSkill"; public const string SkillLevelKey = "RotcehClimbSkillLevel"; public const string SkillXpKey = "RotcehClimbSkillXp"; public const float MaxSkill = 100f; private static readonly FieldInfo SkillLevelupFxField = AccessTools.Field(typeof(Player), "m_skillLevelupEffects") ?? AccessTools.Field(typeof(Player), "m_skillLevelUpEffects") ?? AccessTools.Field(typeof(Player), "m_levelupEffects"); public static float GetSkill(Player player) { if ((Object)(object)player == (Object)null) { return 0f; } ReadProgress(player, out var level, out var xp); if (level >= 100) { return 100f; } float xpToNextLevel = GetXpToNextLevel(level); float num = ((xpToNextLevel > 0f) ? Mathf.Clamp01(xp / xpToNextLevel) : 0f); return Mathf.Clamp((float)level + num, 0f, 100f); } public static void SetSkill(Player player, float skill) { if (!((Object)(object)player == (Object)null)) { skill = Mathf.Clamp(skill, 0f, 100f); int num = Mathf.FloorToInt(skill); float xp = 0f; if (num < 100) { float num2 = skill - (float)num; xp = num2 * GetXpToNextLevel(num); } WriteProgress(player, num, xp); } } public static void AddSkill(Player player, float deltaTime) { if ((Object)(object)player == (Object)null || deltaTime <= 0f) { return; } ReadProgress(player, out var level, out var xp); if (level >= 100) { return; } float num = ClimbingModPlugin.ClimbSkillXpPerSecond?.Value ?? 1.5f; float num2 = Mathf.Max(0f, num) * deltaTime; xp += num2; while (level < 100) { float xpToNextLevel = GetXpToNextLevel(level); if (xp < xpToNextLevel) { break; } xp -= xpToNextLevel; level++; ShowLevelUpFeedback(player, level); if (level >= 100) { level = 100; xp = 0f; break; } } WriteProgress(player, level, xp); } private static float GetXpToNextLevel(int level) { float num = ClimbingModPlugin.ClimbSkillBaseXpPerLevel?.Value ?? 100f; float num2 = ClimbingModPlugin.ClimbSkillXpIncreasePerLevel?.Value ?? 40f; return Mathf.Max(1f, num + Mathf.Max(0f, num2) * (float)Mathf.Clamp(level, 0, 100)); } private static void ReadProgress(Player player, out int level, out float xp) { level = 0; xp = 0f; ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); level = zDO.GetInt("RotcehClimbSkillLevel", -1); xp = zDO.GetFloat("RotcehClimbSkillXp", 0f); if (level < 0) { float num = Mathf.Clamp(zDO.GetFloat("RotcehClimbSkill", 0f), 0f, 100f); level = Mathf.FloorToInt(num); float num2 = num - (float)level; if (level >= 100) { level = 100; xp = 0f; } else { xp = num2 * GetXpToNextLevel(level); } zDO.Set("RotcehClimbSkillLevel", level); zDO.Set("RotcehClimbSkillXp", xp); } level = Mathf.Clamp(level, 0, 100); xp = Mathf.Max(0f, xp); if (level >= 100) { xp = 0f; } } private static void WriteProgress(Player player, int level, float xp) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { level = Mathf.Clamp(level, 0, 100); xp = ((level >= 100) ? 0f : Mathf.Max(0f, xp)); ZDO zDO = component.GetZDO(); zDO.Set("RotcehClimbSkillLevel", level); zDO.Set("RotcehClimbSkillXp", xp); float num = level; if (level < 100) { float xpToNextLevel = GetXpToNextLevel(level); num += ((xpToNextLevel > 0f) ? Mathf.Clamp01(xp / xpToNextLevel) : 0f); } zDO.Set("RotcehClimbSkill", Mathf.Clamp(num, 0f, 100f)); } } public static void ShowLevelUpFeedback(Player player, int level) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer)) { ((Character)player).Message((MessageType)2, $"Climbing skill increased to {level}", 0, (Sprite)null); TryPlayNativeSkillLevelupFx(player); } } private static void TryPlayNativeSkillLevelupFx(Player player) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_0080: 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_00a6: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if (SkillLevelupFxField == null) { return; } object value = SkillLevelupFxField.GetValue(player); if (value == null) { return; } MethodInfo methodInfo = AccessTools.Method(value.GetType(), "Create", (Type[])null, (Type[])null); if (!(methodInfo == null)) { Vector3 val = ((Component)player).transform.position + Vector3.up * 1.6f; Quaternion rotation = ((Component)player).transform.rotation; ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 5) { methodInfo.Invoke(value, new object[5] { val, rotation, ((Component)player).transform, 1f, -1 }); } else if (parameters.Length == 4) { methodInfo.Invoke(value, new object[4] { val, rotation, ((Component)player).transform, 1f }); } else if (parameters.Length == 3) { methodInfo.Invoke(value, new object[3] { val, rotation, ((Component)player).transform }); } } } public static float GetSpeedMultiplier(float skill) { return Mathf.Lerp(1f, 3f, Mathf.Clamp01(skill / 100f)); } } }