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.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));
}
}
}