Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterGrapplingHook v1.0.6
BetterGrapplingHook.dll
Decompiled 4 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BetterGrapplingHook.Config; using BetterGrapplingHook.Features; using BetterGrapplingHook.Infrastructure; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BetterGrapplingHook")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.6.0")] [assembly: AssemblyInformationalVersion("1.0.6+7601a6a030dfa45a2aef00146af5760d65e2f7bf")] [assembly: AssemblyProduct("BetterGrapplingHook")] [assembly: AssemblyTitle("BetterGrapplingHook")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 BetterGrapplingHook { [BepInPlugin("JevMods.BetterGrapplingHook", "BetterGrapplingHook", "1.0.6")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "JevMods.BetterGrapplingHook"; public const string PluginName = "BetterGrapplingHook"; private AssistedGrappleFeature _feature; private Harmony _harmony; private void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown GameEvents events = (GameEvents.Instance = new GameEvents()); _feature = new AssistedGrappleFeature(events, new ModSettings(((BaseUnityPlugin)this).Config)); _feature.Enable(); _harmony = new Harmony("JevMods.BetterGrapplingHook"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded"); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _feature?.Disable(); GameEvents.Instance = null; } } internal static class BuildInfo { public const string Version = "1.0.6"; } } namespace BetterGrapplingHook.Patches { internal static class GrapplingPointPatches { [HarmonyPatch(typeof(GrapplingPoint), "Activate")] private static class Activate { private static void Postfix(GrapplingPoint __instance) { if (IsLocalPulling(__instance)) { GameEvents.Instance?.RaiseGrappleLaunched(__instance); } } } [HarmonyPatch(typeof(GrapplingPoint), "Update")] private static class Update { private static void Prefix(GrapplingPoint __instance) { if (IsLocalPulling(__instance)) { GameEvents.Instance?.RaiseGrappleTickStarting(__instance); } } private static void Postfix(GrapplingPoint __instance) { if (IsLocalPulling(__instance)) { GameEvents.Instance?.RaiseGrappleTick(__instance); } } } [HarmonyPatch(typeof(GrapplingPoint), "Deactivate")] private static class Deactivate { private static void Postfix(GrapplingPoint __instance) { if (IsLocalHook(__instance)) { GameEvents.Instance?.RaiseGrapplePullEnded(__instance); } } } [HarmonyPatch(typeof(Character), "CustomFixedUpdate")] private static class CharacterFixedUpdate { private static void Prefix(Character __instance) { if (IsLocalPlayer(__instance)) { GameEvents.Instance?.RaiseLocalPlayerFixedUpdating(Player.m_localPlayer); } } private static void Postfix(Character __instance) { if (IsLocalPlayer(__instance)) { GameEvents.Instance?.RaiseLocalPlayerFixedUpdate(Player.m_localPlayer); } } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] private static class PlayerUpdateStats { private static void Prefix(Player __instance, out float __state) { __state = __instance.m_stamina; } private static void Postfix(Player __instance, float __state) { if (IsLocalPlayer((Character)(object)__instance)) { GameEvents.Instance?.RaiseLocalPlayerStatsUpdated(__instance, __state); } } } private static bool IsLocalPlayer(Character character) { if ((Object)(object)character != (Object)null) { return (Object)(object)character == (Object)(object)Player.m_localPlayer; } return false; } private static bool IsLocalHook(GrapplingPoint point) { if ((Object)(object)point == (Object)null || !IsLocalPlayer(point.m_character)) { return false; } ZNetView nview = point.m_nview; bool num = (Object)(object)nview != (Object)null && nview.IsValid() && nview.IsOwner(); bool flag = (Object)(object)point.m_lineRenderer != (Object)null && ((Renderer)point.m_lineRenderer).enabled; return num && flag; } private static bool IsLocalPulling(GrapplingPoint point) { if (IsLocalHook(point)) { return !point.m_secondary; } return false; } } } namespace BetterGrapplingHook.Infrastructure { public sealed class GameEvents : IGameEvents { internal static GameEvents Instance { get; set; } public event Action<GrapplingPoint> GrappleLaunched; public event Action<GrapplingPoint> GrappleTickStarting; public event Action<GrapplingPoint> GrappleTick; public event Action<GrapplingPoint> GrapplePullEnded; public event Action<Player> LocalPlayerFixedUpdating; public event Action<Player> LocalPlayerFixedUpdate; public event Action<Player, float> LocalPlayerStatsUpdated; internal void RaiseGrappleLaunched(GrapplingPoint point) { this.GrappleLaunched?.Invoke(point); } internal void RaiseGrappleTickStarting(GrapplingPoint point) { this.GrappleTickStarting?.Invoke(point); } internal void RaiseGrappleTick(GrapplingPoint point) { this.GrappleTick?.Invoke(point); } internal void RaiseGrapplePullEnded(GrapplingPoint point) { this.GrapplePullEnded?.Invoke(point); } internal void RaiseLocalPlayerFixedUpdating(Player player) { this.LocalPlayerFixedUpdating?.Invoke(player); } internal void RaiseLocalPlayerFixedUpdate(Player player) { this.LocalPlayerFixedUpdate?.Invoke(player); } internal void RaiseLocalPlayerStatsUpdated(Player player, float staminaBefore) { this.LocalPlayerStatsUpdated?.Invoke(player, staminaBefore); } } public interface IGameEvents { event Action<GrapplingPoint> GrappleLaunched; event Action<GrapplingPoint> GrappleTickStarting; event Action<GrapplingPoint> GrappleTick; event Action<GrapplingPoint> GrapplePullEnded; event Action<Player> LocalPlayerFixedUpdating; event Action<Player> LocalPlayerFixedUpdate; event Action<Player, float> LocalPlayerStatsUpdated; } } namespace BetterGrapplingHook.Features { public sealed class AssistedGrappleFeature { private const float HangDepth = 3f; private const float GroundSettleDistance = 0.6f; private const float MaxProbeError = 2f; private static readonly RaycastHit[] ProbeHits = (RaycastHit[])(object)new RaycastHit[32]; private readonly IGameEvents _events; private readonly IModSettings _settings; private GrapplingPoint _attached; private GrapplingPoint _hanging; private float _depth; private bool _gravityOff; public AssistedGrappleFeature(IGameEvents events, IModSettings settings) { _events = events; _settings = settings; } public void Enable() { _events.GrappleLaunched += OnLaunched; _events.GrappleTickStarting += OnTickStarting; _events.GrappleTick += OnTick; _events.GrapplePullEnded += OnPullEnded; _events.LocalPlayerFixedUpdating += OnPhysicsStepStarting; _events.LocalPlayerFixedUpdate += OnPhysicsStep; _events.LocalPlayerStatsUpdated += OnStatsUpdated; } public void Disable() { _events.GrappleLaunched -= OnLaunched; _events.GrappleTickStarting -= OnTickStarting; _events.GrappleTick -= OnTick; _events.GrapplePullEnded -= OnPullEnded; _events.LocalPlayerFixedUpdating -= OnPhysicsStepStarting; _events.LocalPlayerFixedUpdate -= OnPhysicsStep; _events.LocalPlayerStatsUpdated -= OnStatsUpdated; } private void OnLaunched(GrapplingPoint point) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //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_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) //IL_006b: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (IsConstantVelocity(point)) { _attached = point; _depth = ChooseDepth(point); point.m_closeBreakDist = Mathf.Max(point.m_closeBreakDist, _depth + 0.5f); Character character = point.m_character; Vector3 val = Target(point) - ((Component)character).transform.position; Vector3 val2 = ((Vector3)(ref val)).normalized * point.m_pullForce + Vector3.up * _settings.LaunchLift; character.ForceJump(val2, false); } } private void OnTickStarting(GrapplingPoint point) { //IL_0014: 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_0029: Unknown result type (might be due to invalid IL or missing references) if (IsConstantVelocity(point)) { Vector3 val = ((Component)point.m_character).transform.position - ((Component)point).transform.position; if (((Vector3)(ref val)).magnitude < point.m_lastDist) { point.m_breakingTime = 0f; } } } private void OnTick(GrapplingPoint point) { //IL_0012: 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_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_0072: 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_0079: 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_003e: 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_004e: Unknown result type (might be due to invalid IL or missing references) if (IsConstantVelocity(point)) { Character character = point.m_character; Vector3 val = Target(point) - ((Component)character).transform.position; Vector3 val2 = Vector3.zero; if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { val2 = ((Vector3)(ref val)).normalized * point.m_pullForce; } float num = GrappleMath.LiftSpeed(_settings.LaunchLift, _settings.LiftDuration, point.m_time); character.SetVelocity(val2 + Vector3.up * num); } } private void OnPullEnded(GrapplingPoint point) { if (IsConstantVelocity(point)) { if (_settings.OnArrival == ArrivalBehavior.AutoRetract) { point.Break(true); return; } _hanging = point; point.StandUp(); } } private void OnPhysicsStepStarting(Player player) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (IsHolding()) { ((Character)player).SetMoveDir(Vector3.zero); } } private void OnPhysicsStep(Player player) { if (IsHolding()) { HoldInPlace(player); return; } _hanging = null; if (_gravityOff) { ((Character)player).m_body.useGravity = true; _gravityOff = false; } } private void OnStatsUpdated(Player player, float staminaBefore) { if (!IsAttached()) { _attached = null; return; } if (player.m_stamina > staminaBefore) { player.m_stamina = staminaBefore; } if (player.m_stamina <= 0f) { _attached.Break(true); } } private void HoldInPlace(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) ((Character)player).SetVelocity(Vector3.zero); bool flag = IsGroundWithin(((Component)player).transform.position, 0.6f); ((Character)player).m_body.useGravity = flag; _gravityOff = !flag; } private float ChooseDepth(GrapplingPoint point) { //IL_000b: 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_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_001d: 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_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_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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)point.m_character).transform.position; Vector3 position2 = ((Component)point).transform.position; float? num = SurfaceNormalY(position, position2); float num2 = GrappleMath.HangDepth(position2.y - position.y, 3f, num ?? 1f); Vector3 val = position2 - position; float? num3 = GroundHeightBelow(position2, ((Vector3)(ref val)).normalized); if (num3.HasValue) { num2 = Mathf.Min(num2, Mathf.Max(0f, position2.y - num3.Value)); } return num2; } private Vector3 Target(GrapplingPoint point) { //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_0016: 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) return ((Component)point).transform.position + Vector3.down * _depth; } private bool IsAttached() { if ((Object)(object)_attached != (Object)null) { return IsLineVisible(_attached); } return false; } private bool IsHolding() { if ((Object)(object)_hanging != (Object)null && _hanging.m_secondary) { return IsLineVisible(_hanging); } return false; } private static bool IsLineVisible(GrapplingPoint point) { if ((Object)(object)point.m_lineRenderer != (Object)null) { return ((Renderer)point.m_lineRenderer).enabled; } return false; } private static bool IsConstantVelocity(GrapplingPoint point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 return (int)point.Method == 1; } private static bool IsEnvironment(RaycastHit hit) { bool num = (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Character>() != (Object)null; bool flag = (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<GrapplingPoint>() != (Object)null; if (!num) { return !flag; } return false; } private static float? GroundHeightBelow(Vector3 anchor, Vector3 toAnchor) { //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_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_0011: 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_0048: 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) int num = Physics.RaycastNonAlloc(anchor - toAnchor * 0.3f, Vector3.down, ProbeHits, 100f, -5, (QueryTriggerInteraction)1); float? result = null; float num2 = float.MaxValue; for (int i = 0; i < num; i++) { RaycastHit hit = ProbeHits[i]; if (IsEnvironment(hit) && ((RaycastHit)(ref hit)).distance < num2) { num2 = ((RaycastHit)(ref hit)).distance; result = ((RaycastHit)(ref hit)).point.y; } } return result; } private static bool IsGroundWithin(Vector3 feet, float distance) { //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_000b: 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_0039: Unknown result type (might be due to invalid IL or missing references) int num = Physics.RaycastNonAlloc(feet + Vector3.up * 0.5f, Vector3.down, ProbeHits, 0.5f + distance, -5, (QueryTriggerInteraction)1); for (int i = 0; i < num; i++) { if (IsEnvironment(ProbeHits[i])) { return true; } } return false; } private static float? SurfaceNormalY(Vector3 feet, Vector3 anchor) { //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_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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_002f: 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_0032: 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_0070: 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_007b: 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_009d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = feet + Vector3.up; Vector3 val2 = anchor - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude < 1f) { return null; } int num = Physics.RaycastNonAlloc(val, val2 / magnitude, ProbeHits, magnitude + 1f, -5, (QueryTriggerInteraction)1); float? result = null; float num2 = 2f; for (int i = 0; i < num; i++) { RaycastHit hit = ProbeHits[i]; Vector3 val3 = ((RaycastHit)(ref hit)).point - anchor; float magnitude2 = ((Vector3)(ref val3)).magnitude; if (IsEnvironment(hit) && magnitude2 < num2) { num2 = magnitude2; result = ((RaycastHit)(ref hit)).normal.y; } } return result; } } public static class GrappleMath { private const float FloorNormalY = 0.5f; public static float HangDepth(float anchorAbovePlayer, float maxDepth, float surfaceNormalY) { if (surfaceNormalY >= 0.5f) { return 0f; } return Mathf.Clamp(anchorAbovePlayer, 0f, maxDepth); } public static float LiftSpeed(float lift, float duration, float elapsed) { if (duration <= 0f) { return 0f; } return lift * Mathf.Clamp01(1f - elapsed / duration); } } } namespace BetterGrapplingHook.Config { public enum ArrivalBehavior { Hang, AutoRetract } public interface IModSettings { float LaunchLift { get; } float LiftDuration { get; } ArrivalBehavior OnArrival { get; } } public sealed class ModSettings : IModSettings { private readonly ConfigEntry<float> _launchLift; private readonly ConfigEntry<float> _liftDuration; private readonly ConfigEntry<ArrivalBehavior> _onArrival; public float LaunchLift => _launchLift.Value; public float LiftDuration => _liftDuration.Value; public ArrivalBehavior OnArrival => _onArrival.Value; public ModSettings(ConfigFile file) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown _launchLift = file.Bind<float>("Flight", "LaunchLift", 6f, new ConfigDescription("Extra upward speed at launch, in m/s.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); _liftDuration = file.Bind<float>("Flight", "LiftDuration", 0.75f, new ConfigDescription("How long the extra upward speed lasts, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>())); _onArrival = file.Bind<ArrivalBehavior>("Flight", "OnArrival", ArrivalBehavior.Hang, "What happens when you reach the hook. Hang = stay attached and hold in place. AutoRetract = release the hook."); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }