using 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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[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;
}
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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: 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_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: 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_009b: 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_00a4: 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_00b1: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: 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_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_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: 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_0118: 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)
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);
PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationMixerPlayable>(AnimationPlayableOutput.Create(val, "ClimbOutput", animator), 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_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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_009a: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: 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_0038: 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_005a: 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_0024: 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 = 10f;
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.6f;
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<float> ClimbSpeedUp;
public static ConfigEntry<float> ClimbSpeedDown;
public static ConfigEntry<float> StaminaDrainPerSecond;
public static ConfigEntry<bool> ToggleClimbKey;
private void Awake()
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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)");
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).");
new Harmony("com.rotceh.valheimclimbingmod").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Valheim Climbing Mod loaded. Climb key: {ClimbKey.Value}");
ClimbAnimationController.Initialize(((BaseUnityPlugin)this).Logger);
}
}
[HarmonyPatch(typeof(Player), "FixedUpdate")]
public class Player_FixedUpdate_Patch
{
[CompilerGenerated]
private sealed class <EnumerateProbeDirections>d__12 : IEnumerable<Vector3>, IEnumerable, IEnumerator<Vector3>, IDisposable, IEnumerator
{
private int <>1__state;
private Vector3 <>2__current;
private int <>l__initialThreadId;
private Vector3 preferredNormal;
public Vector3 <>3__preferredNormal;
private Player player;
public Player <>3__player;
private Transform <t>5__2;
private Vector3[] <>7__wrap2;
private int <>7__wrap3;
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__12(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<t>5__2 = null;
<>7__wrap2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003b: 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_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_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: 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_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: 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_0143: 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_008f: 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_0058: 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_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: 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_0072;
case 1:
<>1__state = -1;
goto IL_0072;
case 2:
<>1__state = -1;
<>2__current = -<t>5__2.forward;
<>1__state = 3;
return true;
case 3:
<>1__state = -1;
<>2__current = <t>5__2.up;
<>1__state = 4;
return true;
case 4:
<>1__state = -1;
<>2__current = -<t>5__2.up;
<>1__state = 5;
return true;
case 5:
<>1__state = -1;
<>2__current = <t>5__2.right;
<>1__state = 6;
return true;
case 6:
<>1__state = -1;
<>2__current = -<t>5__2.right;
<>1__state = 7;
return true;
case 7:
<>1__state = -1;
<>7__wrap2 = WorldProbeDirections;
<>7__wrap3 = 0;
break;
case 8:
{
<>1__state = -1;
<>7__wrap3++;
break;
}
IL_0072:
<t>5__2 = ((Component)player).transform;
<>2__current = <t>5__2.forward;
<>1__state = 2;
return true;
}
if (<>7__wrap3 < <>7__wrap2.Length)
{
Vector3 val = <>7__wrap2[<>7__wrap3];
<>2__current = val;
<>1__state = 8;
return true;
}
<>7__wrap2 = 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__12 <EnumerateProbeDirections>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<EnumerateProbeDirections>d__ = this;
}
else
{
<EnumerateProbeDirections>d__ = new <EnumerateProbeDirections>d__12(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 static readonly float[] ProbeHeights = new float[3] { 1.2f, 0.7f, 0.2f };
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_00a2: 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_00f2: 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_0100: 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);
bool flag = ClimbingModPlugin.ToggleClimbKey?.Value ?? false;
bool flag2 = false;
if (CallTakeInput(__instance))
{
if (flag)
{
if (Input.GetKeyDown(ClimbingModPlugin.ClimbKey.Value))
{
orCreate.toggleActive = !orCreate.toggleActive;
if (!orCreate.toggleActive && orCreate.isClimbing)
{
StopClimbing(__instance, orCreate);
}
}
flag2 = orCreate.toggleActive;
}
else
{
flag2 = Input.GetKey(ClimbingModPlugin.ClimbKey.Value);
if (!flag2)
{
orCreate.toggleActive = false;
}
}
}
else
{
flag2 = orCreate.toggleActive;
}
Vector3 normal;
if (!orCreate.isClimbing)
{
if (flag2)
{
TryStartClimbing(__instance, orCreate);
}
}
else if (!flag2)
{
StopClimbing(__instance, orCreate);
}
else if (!PlayerHasClimbStamina(__instance))
{
StopClimbing(__instance, orCreate);
}
else if (TryGetSurfaceNormal(__instance, out normal, orCreate.surfaceNormal))
{
orCreate.surfaceNormal = normal;
}
else
{
StopClimbing(__instance, orCreate);
}
}
}
private static void HandleRemotePlayer(Player player)
{
ZNetView component = ((Component)player).GetComponent<ZNetView>();
if (!((Object)(object)component == (Object)null) && component.IsValid())
{
bool @bool = component.GetZDO().GetBool("IsClimbing", false);
bool flag = ClimbAnimationController.IsActive(player);
if (@bool && !flag)
{
ClimbAnimationController.Begin(player);
}
else if (!@bool && flag)
{
ClimbAnimationController.End(player);
}
if (@bool)
{
ClimbAnimationController.Update(player, 0f, 1f);
}
}
}
private static void TryStartClimbing(Player player, ClimbingState.ClimbingData climbData)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (PlayerHasClimbStamina(player) && TryGetSurfaceNormal(player, out var normal))
{
StartClimbing(player, climbData, normal);
}
}
private static bool PlayerHasClimbStamina(Player player)
{
return player.GetStamina() > 0.25f;
}
private static void StartClimbing(Player player, ClimbingState.ClimbingData climbData, Vector3 surfaceNormal)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: 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_0066: Unknown result type (might be due to invalid IL or missing references)
climbData.isClimbing = true;
climbData.surfaceNormal = surfaceNormal;
ZNetView component = ((Component)player).GetComponent<ZNetView>();
if ((Object)(object)component != (Object)null && component.IsValid())
{
component.GetZDO().Set("IsClimbing", true);
}
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 StopClimbing(Player player, ClimbingState.ClimbingData climbData)
{
climbData.isClimbing = false;
ZNetView component = ((Component)player).GetComponent<ZNetView>();
if ((Object)(object)component != (Object)null && component.IsValid())
{
component.GetZDO().Set("IsClimbing", false);
}
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_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_0028: 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_0035: 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_0046: 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_004d: 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_0065: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: 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 >= 10f && num3 <= 240f)
{
normal = ((RaycastHit)(ref val2)).normal;
return true;
}
}
}
}
normal = Vector3.zero;
return false;
}
[IteratorStateMachine(typeof(<EnumerateProbeDirections>d__12))]
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__12(-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_002e: 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_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_0063: 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)
//IL_0068: 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_0073: 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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_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_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: 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_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_0121: 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_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: 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_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)
//IL_00be: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: 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)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: 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;
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);
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 num2 = ((axis > 0f) ? ClimbingConfig.CLIMB_SPEED_UP : ClimbingConfig.CLIMB_SPEED_DOWN);
val += val3 * num2 * axis * num;
}
if (Mathf.Abs(axis2) > 0.1f && ((Vector3)(ref val4)).sqrMagnitude > 0.01f)
{
val += val4 * ClimbingConfig.CLIMB_SPEED_DOWN * axis2;
}
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 verticalInput = ResolveAnimationInput(axis, axis2);
ClimbAnimationController.Update(player, verticalInput, num);
ApplyClimbStaminaDrain(player, axis, axis2);
}
}
private static float CalculateSlopeSpeedFactor(Vector3 surfaceNormal)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: 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.6f, num2), 0.1f, 3f);
}
private static Vector3 ResolveClimbDirection(Vector3 surfaceNormal, Transform transform)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: 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_0035: 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_003c: 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_0058: 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)
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);
}
if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f))
{
return Vector3.forward;
}
return ((Vector3)(ref val)).normalized;
}
private static Vector3 ResolveLateralDirection(Vector3 surfaceNormal, Vector3 climbDirection)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: 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)
//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)
//IL_0038: 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)
Vector3 val = Vector3.Cross(surfaceNormal, climbDirection);
if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
{
val = Vector3.Cross(surfaceNormal, Vector3.up);
}
if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f))
{
return Vector3.zero;
}
return ((Vector3)(ref val)).normalized;
}
private static float ResolveAnimationInput(float forwardInput, float rightInput)
{
if (Mathf.Abs(forwardInput) > 0.05f)
{
return forwardInput;
}
if (!(Mathf.Abs(rightInput) > 0.1f))
{
return 0f;
}
return Mathf.Abs(rightInput);
}
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_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0028: 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_0034: 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_005f: 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_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: 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)
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_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: 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)
//IL_0015: 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_001b: 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_0039: 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_003e: 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)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: 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_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_0071: 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_007a: 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)
//IL_005b: 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_005d: 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_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: 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_0092: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: 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_008a: 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_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Invalid comparison between Unknown and I4
//IL_0029: 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))
{
if ((int)hit.m_hitType == 3)
{
hit.m_damage = default(DamageTypes);
hit.m_pushForce = 0f;
}
else if (hit.m_pushForce > 5f)
{
ClimbingState.ClimbingData orCreate = ClimbingState.GetOrCreate(val);
Player_FixedUpdate_Patch.StopClimbing(val, orCreate);
}
}
}
}
public static class ClimbingState
{
public class ClimbingData
{
public bool isClimbing;
public Vector3 surfaceNormal = Vector3.zero;
public bool wasGravityEnabled = true;
public bool toggleActive;
}
private static Dictionary<Player, ClimbingData> climbingPlayers = new Dictionary<Player, ClimbingData>();
public static ClimbingData GetOrCreate(Player player)
{
if (!climbingPlayers.ContainsKey(player))
{
climbingPlayers[player] = new ClimbingData();
}
return climbingPlayers[player];
}
public static bool IsClimbing(Player player)
{
if (climbingPlayers.ContainsKey(player))
{
return climbingPlayers[player].isClimbing;
}
return false;
}
public static void Cleanup(Player player)
{
climbingPlayers.Remove(player);
}
}
}