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 GrappleMomentum v0.3.2
BepInEx/plugins/GrappleMomentum/GrappleMomentum.dll
Decompiled 3 weeks 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 BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("GrappleMomentum")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.2.0")] [assembly: AssemblyInformationalVersion("0.3.2+256d7e1c98fca9edf890f043ba84dc9f23ebe80e")] [assembly: AssemblyProduct("GrappleMomentum")] [assembly: AssemblyTitle("GrappleMomentum")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 GrappleMomentum { [BepInPlugin("dugi.GrappleMomentum", "GrappleMomentum", "0.3.2")] public sealed class Plugin : BaseUnityPlugin { internal struct Settings { internal bool Enabled; internal bool Debug; internal float MaxSpeed; internal float InitialImpulse; internal float GroundLift; internal float PullDelay; internal float RampSeconds; internal float PullAcceleration; internal float PullSpeed; internal float SwingPull; internal float AirAcceleration; internal float Stamina; internal float FallGrace; internal float Cooldown; internal float JumpWindow; internal float JumpMultiplier; internal KeyCode OffhandKey; } internal const string Id = "dugi.GrappleMomentum"; internal const string Name = "GrappleMomentum"; internal static Settings Cached; private static ManualLogSource? _log; private Harmony? _harmony; private ConfigEntry<bool> _enabled; private ConfigEntry<float> _maxSpeed; private ConfigEntry<bool> _debug; private ConfigEntry<float> _initialImpulse; private ConfigEntry<float> _groundLift; private ConfigEntry<float> _pullDelay; private ConfigEntry<float> _rampSeconds; private ConfigEntry<float> _pullAcceleration; private ConfigEntry<float> _pullSpeed; private ConfigEntry<float> _swingPull; private ConfigEntry<float> _airAcceleration; private ConfigEntry<float> _stamina; private ConfigEntry<float> _fallGrace; private ConfigEntry<float> _cooldown; private ConfigEntry<float> _jumpWindow; private ConfigEntry<float> _jumpMultiplier; private ConfigEntry<KeyCode> _offhandKey; internal static bool Operational { get; private set; } private void Awake() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Expected O, but got Unknown _log = ((BaseUnityPlugin)this).Logger; try { _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle. Off restores vanilla behaviour."); _maxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Inertia", "MaxSpeed", 50f, new ConfigDescription("Maximum commanded speed (m/s) while attached or preserving inertia.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 150f), Array.Empty<object>())); _initialImpulse = BindFloat("Pull", "InitialImpulse", 8f, 0f, 30f, "Added speed toward anchor on attachment (m/s)."); _groundLift = BindFloat("Pull", "GroundLift", 1.5f, 0f, 5f, "Minimum upward takeoff speed on ground attachment (m/s)."); _pullDelay = BindFloat("Pull", "DelaySeconds", 0.2f, 0f, 1f, "Delay between initial impulse and continuous acceleration. Not a bonus-jump window."); _rampSeconds = BindFloat("Pull", "RampSeconds", 1.5f, 0.05f, 5f, "Time to ramp from initial pull speed to TargetSpeed."); _pullAcceleration = BindFloat("Pull", "Acceleration", 25f, 1f, 100f, "Acceleration toward anchor (m/s squared), added to current velocity."); _pullSpeed = BindFloat("Pull", "TargetSpeed", 24f, 1f, 80f, "Final target inward speed; higher existing momentum is not overwritten."); _swingPull = BindFloat("Pull", "SwingPullFactor", 0.15f, 0f, 1f, "Fraction of inward pull target when looking away from the anchor to swing."); _jumpWindow = BindFloat("Pull", "JumpWindowSeconds", 0.5f, 0.05f, 0.5f, "After a ground attachment, time during which jump is still accepted (tip glows gold meanwhile)."); _jumpMultiplier = BindFloat("Pull", "JumpMultiplier", 1.5f, 1f, 3f, "Jump velocity multiplier for the grapple jump (Apex grapple_jumpFrac). 1 = vanilla jump."); _airAcceleration = BindFloat("Control", "AirAcceleration", 6f, 0f, 25f, "Directional air acceleration (m/s squared), tangent to rope while attached."); _stamina = BindFloat("General", "StaminaPerShot", 5f, 0f, 30f, "Exact cost per grappling-hook shot. Normal jump costs remain vanilla."); _fallGrace = BindFloat("Inertia", "FallGraceSeconds", 0f, 0f, 10f, "Optional fall-damage immunity after release, until landing/reset. Zero preserves vanilla protection only."); _cooldown = BindFloat("General", "CooldownSeconds", 0.2f, 0f, 5f, "Seconds from a hook shot until the next one is ready. Replaces the vanilla reload, also while attached."); _offhandKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Offhand", "Key", (KeyCode)327, "Fires the grappling hook carried in the inventory without equipping it. Mouse4 = back side button, Mouse3 = forward side button, None = off."); _debug = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "DebugTransitions", false, "Log state changes (at most 4 per second)."); ((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged; RefreshSettings(); _harmony = new Harmony("dugi.GrappleMomentum"); Patches.Install(_harmony, ((BaseUnityPlugin)this).Logger); SceneManager.sceneUnloaded += OnSceneUnloaded; Operational = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GrappleMomentum] 0.3.2 loaded. Fixed-step pull, swing and grapple jump; reference assembly Valheim 1.0.16."); } catch (Exception ex) { Operational = false; Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } ((BaseUnityPlugin)this).Logger.LogError((object)("[GrappleMomentum] Disabled: target validation or patch installation failed; all own patches removed. " + ex)); } } private void OnSettingChanged(object sender, SettingChangedEventArgs args) { RefreshSettings(); } private ConfigEntry<float> BindFloat(string section, string key, float value, float min, float max, string description) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>())); } private void RefreshSettings() { //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) Cached = new Settings { Enabled = _enabled.Value, Debug = _debug.Value, MaxSpeed = ValidRange(_maxSpeed.Value, 1f, 150f, 50f), InitialImpulse = ValidRange(_initialImpulse.Value, 0f, 30f, 8f), GroundLift = ValidRange(_groundLift.Value, 0f, 5f, 1.5f), PullDelay = ValidRange(_pullDelay.Value, 0f, 1f, 0.2f), RampSeconds = ValidRange(_rampSeconds.Value, 0.05f, 5f, 1.5f), PullAcceleration = ValidRange(_pullAcceleration.Value, 1f, 100f, 25f), PullSpeed = ValidRange(_pullSpeed.Value, 1f, 80f, 24f), SwingPull = ValidRange(_swingPull.Value, 0f, 1f, 0.15f), AirAcceleration = ValidRange(_airAcceleration.Value, 0f, 25f, 6f), Stamina = ValidRange(_stamina.Value, 0f, 30f, 5f), FallGrace = ValidRange(_fallGrace.Value, 0f, 10f, 0f), Cooldown = ValidRange(_cooldown.Value, 0f, 5f, 0.2f), JumpWindow = ValidRange(_jumpWindow.Value, 0.05f, 0.5f, 0.5f), JumpMultiplier = ValidRange(_jumpMultiplier.Value, 1f, 3f, 1.5f), OffhandKey = _offhandKey.Value }; } private static float ValidRange(float value, float min, float max, float fallback) { if (GrappleController.IsFinite(value)) { return Math.Max(min, Math.Min(max, value)); } return fallback; } private static void OnSceneUnloaded(Scene scene) { GrappleController.Reset(GrappleController.Reason.Scene); } private void OnDestroy() { Operational = false; ((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged; SceneManager.sceneUnloaded -= OnSceneUnloaded; GrappleController.Reset(GrappleController.Reason.Disabled); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } GrappleController.DestroyDot(); } internal static void Fault(Exception error) { if (Operational) { Operational = false; GrappleController.Reset(GrappleController.Reason.Fault); ManualLogSource? log = _log; if (log != null) { log.LogError((object)("[GrappleMomentum] Disabled after a runtime failure; vanilla callbacks remain enabled. " + error)); } } } internal static void NumericFault() { ManualLogSource? log = _log; if (log != null) { log.LogError((object)"[GrappleMomentum] Non-finite velocity detected: no velocity written; state reset."); } } internal static void TransitionLog(string message) { ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)message); } } } internal static class GrappleController { private enum State { Idle, Attached, Inertia } internal enum Reason { Hook, Release, Arrival, Ground, Stopped, Unsafe, AnchorLost, HookLost, Ownership, Disabled, Scene, Death, Teleport, Destroyed, Ship, Rescue, Impact, Fault } internal struct AirControlScope { internal bool Changed; internal float Original; } internal struct ImpactScope { internal bool Local; internal int PreviousId; } private const float Epsilon = 0.0001f; private const float MinRopeLength = 1f; private const float MaxCorrection = 0.05f; private const string HookItemName = "$item_graplinghook"; private const string SparkPrefab = "vfx_HitSparks"; private const float PullLift = 0.6f; private const float PassSpeed = 0.5f; private static State _state; private static Player? _player; private static Player? _tickPlayer; private static GrapplingPoint? _hook; private static GameObject? _anchor; private static Collider? _anchorCollider; private static bool _hadAnchor; private static bool _hadCollider; private static int _hookId; private static int _ignoredHookId; private static bool _inTick; private static bool _walkingReplaced; private static bool _breaking; private static bool _abortQueued; private static Reason _abortReason; private static bool _initialPending; private static bool _releaseRequested; private static bool _jumpRequested; private static bool _jumpUsed; private static bool _groundedOnAttach; private static float _attachedAt; private static float _pullAt; private static float _jumpUntil; private static float _jumpPressedAt; private static float _rampSeconds; private static float _ropeLength; private static float _fallUntil; private static float _nextLogTime; private static bool _numericErrorLogged; private static bool _ownsFallCap; private static SE_Stats? _ownedEffect; private static float _savedFallCap; private static float _effectReleaseTtl; private static Color _savedTipColor; private static Vector3 _approach; private static float _lateJumpUntil; private static float _attachY; private static float _traceUntil; private static float _traceNext; private static int _lastJumpTraceFrame; private static bool _colorSaved; private static bool _colorRestored; private static Vector3 _steer; private static Vector3 _look; private static Plugin.Settings _tickSettings; private static float _lastShotAt = float.NegativeInfinity; private static bool _reloadPending; private static EffectList? _spark; private static bool _sparkMissingLogged; private static readonly RaycastHit[] DotHits = (RaycastHit[])(object)new RaycastHit[16]; private static readonly Color DotInRange = new Color(0.25f, 0.6f, 1f, 1f); private static readonly Color DotOutOfRange = new Color(0.55f, 0.55f, 0.55f, 0.9f); private static int _dotMask; private static Image? _dot; private static Sprite? _dotSprite; private static bool Tracing { get { if (Plugin.Cached.Debug && _traceUntil > 0f) { return Time.fixedTime <= _traceUntil; } return false; } } internal static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } private static float Length(Vector3 value) { //IL_0000: 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_000f: 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_001f: 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) return (float)Math.Sqrt((double)value.x * (double)value.x + (double)value.y * (double)value.y + (double)value.z * (double)value.z); } private static float HorizontalSpeed(Vector3 v) { //IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references) return Length(new Vector3(v.x, 0f, v.z)); } private static float Clamp01(float value) { return Math.Max(0f, Math.Min(1f, value)); } internal static bool TryLimitVelocity(Vector3 velocity, float limit, out Vector3 result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0028: 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_0037: 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_0047: 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_0064: 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_0078: 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_0087: Unknown result type (might be due to invalid IL or missing references) result = velocity; if (!Finite(velocity) || !IsFinite(limit) || limit <= 0f) { return false; } double num = (double)velocity.x * (double)velocity.x + (double)velocity.y * (double)velocity.y + (double)velocity.z * (double)velocity.z; if (num > (double)limit * (double)limit) { double num2 = (double)limit / Math.Sqrt(num); result = new Vector3((float)((double)velocity.x * num2), (float)((double)velocity.y * num2), (float)((double)velocity.z * num2)); } return Finite(result); } internal static float RampSpeed(float elapsed, float duration, float start, float end) { return start + (end - start) * Clamp01(elapsed / Math.Max(0.0001f, duration)); } internal static Vector3 StepPull(Vector3 velocity, Vector3 offset, Vector3 steer, Vector3 look, float target, float acceleration, float airAcceleration, float swingFactor, float dt) { //IL_0000: 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_0019: 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_0037: 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_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_0061: 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_0063: 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_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_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_009d: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) float num = Length(offset); if (!IsFinite(num) || num <= 0.0001f) { return velocity; } Vector3 val = offset / num; float num2 = Length(look); float num3 = ((num2 > 0.0001f) ? Clamp01(Vector3.Dot(look / num2, -val)) : 1f); float num4 = target * (swingFactor + (1f - swingFactor) * num3); float num5 = Vector3.Dot(velocity, -val); float num6 = Math.Max(0f, Math.Min(acceleration * dt, num4 - num5)); Vector3 val2 = steer - val * Vector3.Dot(steer, val); return velocity - val * num6 + val2 * (airAcceleration * dt); } internal static Vector3 ConstrainRope(Vector3 velocity, Vector3 offset, float length) { //IL_0000: 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_0023: 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_002a: 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_003d: 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_0040: 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_003b: Unknown result type (might be due to invalid IL or missing references) float num = Length(offset); if (!IsFinite(num) || num <= 0.0001f || num < length - 0.01f) { return velocity; } Vector3 val = offset / num; float num2 = Vector3.Dot(velocity, val); if (!(num2 > 0f)) { return velocity; } return velocity - val * num2; } internal static Vector3 RopeCorrection(Vector3 offset, float length, float maxStep) { //IL_0000: 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_0021: 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_0040: Unknown result type (might be due to invalid IL or missing references) float num = Length(offset); if (!IsFinite(num) || num <= 0.0001f || num <= length) { return Vector3.zero; } return -offset / num * Math.Min(Math.Max(0f, maxStep), num - length); } internal static bool RopeActive(Vector3 offset) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return offset.y < 0f; } internal static bool PassedAnchor(Vector3 offset, Vector3 velocity, Vector3 approach, float minOutwardSpeed) { //IL_0000: 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_0026: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_006c: Unknown result type (might be due to invalid IL or missing references) float num = Length(offset); if (!IsFinite(num) || num <= 0.0001f) { return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(offset.x, 0f, offset.z); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(approach.x, 0f, approach.z); if (Length(val2) <= 0.0001f || Vector3.Dot(val2, val) > 0f) { return Vector3.Dot(velocity, offset / num) > minOutwardSpeed; } return false; } internal static Vector3 AddJump(Vector3 velocity, Vector3 jump) { //IL_0000: 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_000d: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) return new Vector3(velocity.x + jump.x, Math.Max(velocity.y, jump.y), velocity.z + jump.z); } internal static bool JumpEligible(bool used, bool grounded, bool groundedAtAttach, float pressedAt, float deadline) { if (!used) { if (!grounded) { if (groundedAtAttach) { return pressedAt <= deadline; } return false; } return true; } return false; } private static bool Owns(Player player) { if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)((Character)player).m_nview) && ((Character)player).m_nview.IsValid() && ((Character)player).m_nview.IsOwner()) { return Object.op_Implicit((Object)(object)((Character)player).m_body); } return false; } private static bool Supported(GrapplingPoint? hook, Player player) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)hook) && (Object)(object)hook.m_character == (Object)(object)player && Object.op_Implicit((Object)(object)hook.m_nview) && hook.m_nview.IsValid() && hook.m_nview.IsOwner() && Object.op_Implicit((Object)(object)hook.m_lineRenderer) && ((Renderer)hook.m_lineRenderer).enabled && (int)hook.Method == 1 && !hook.m_secondary && Object.op_Implicit((Object)(object)hook.m_equipCheck)) { return hook.m_equipCheck.m_itemData.m_shared.m_name == "$item_graplinghook"; } return false; } private static bool Unsafe(Player player) { if (!((Character)player).IsDead() && !(((Character)player).GetHealth() <= 0f) && !((Character)player).IsTeleporting() && !((Character)player).InIntro() && !((Character)player).InCutscene() && !((Character)player).InWater() && !((Character)player).IsSwimming() && !((Character)player).IsAttached() && !((Character)player).IsAttachedToShip() && !((Character)player).IsSitting() && !((Character)player).IsRiding()) { return ((Character)player).IsDebugFlying(); } return true; } private static bool AnchorLost() { if (!_hadAnchor || Object.op_Implicit((Object)(object)_anchor)) { if (_hadCollider) { return !Object.op_Implicit((Object)(object)_anchorCollider); } return false; } return true; } private static bool ActiveTick(Character character) { if (_inTick) { return (Object)(object)character == (Object)(object)_tickPlayer; } return false; } private static void RestoreHookPresentation() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_hook) && Object.op_Implicit((Object)(object)_hook.m_lineRenderer) && _colorSaved) { _hook.m_lineRenderer.startColor = _savedTipColor; } GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; bool flag = Object.op_Implicit((Object)(object)localGrappler) && (Object)(object)localGrappler != (Object)(object)_hook && (Object)(object)localGrappler.m_se == (Object)(object)_ownedEffect; if (_ownsFallCap && Object.op_Implicit((Object)(object)_ownedEffect) && !flag) { if (Object.op_Implicit((Object)(object)_hook)) { _ownedEffect.m_maxMaxFallSpeed = _savedFallCap; } else { _ownedEffect.m_maxMaxFallSpeed = 0f; ((StatusEffect)_ownedEffect).ResetTime(); ((StatusEffect)_ownedEffect).m_ttl = _effectReleaseTtl; } } _ownedEffect = null; _ownsFallCap = false; _colorSaved = false; } private static void Transition(State next, Reason reason) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) State state = _state; if (next == State.Inertia && state != State.Attached) { next = State.Idle; } _lateJumpUntil = 0f; if (state != next) { Trace(state.ToString() + " -> " + next.ToString() + " (" + reason.ToString() + ")"); } if (next != State.Attached) { RestoreHookPresentation(); _hook = null; _anchor = null; _anchorCollider = null; _hadAnchor = (_hadCollider = false); _releaseRequested = (_jumpRequested = (_initialPending = false)); _abortQueued = false; } _state = next; if (next == State.Inertia) { _fallUntil = Time.fixedTime + _tickSettings.FallGrace; } if (next == State.Idle) { _player = null; _hookId = 0; _fallUntil = 0f; _steer = (_look = Vector3.zero); } if (state != next && Plugin.Cached.Debug && !Tracing && Time.unscaledTime >= _nextLogTime) { _nextLogTime = Time.unscaledTime + 0.25f; Plugin.TransitionLog("[GrappleMomentum] " + state.ToString() + " -> " + next.ToString() + " (" + reason.ToString() + ")"); } } internal static void Reset(Reason reason) { if (_hookId != 0) { _ignoredHookId = _hookId; } if (reason == Reason.Scene || reason == Reason.Destroyed) { _ignoredHookId = 0; } if ((reason == Reason.Death || reason == Reason.Destroyed || reason == Reason.Teleport || reason == Reason.Scene || reason == Reason.Ownership) && Object.op_Implicit((Object)(object)_hook) && Object.op_Implicit((Object)(object)_hook.m_nview) && _hook.m_nview.IsValid() && _hook.m_nview.IsOwner()) { GrapplingPoint hook = _hook; RestoreHookPresentation(); GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; if (!Object.op_Implicit((Object)(object)localGrappler) || !((Object)(object)localGrappler != (Object)(object)hook)) { int num; if (Object.op_Implicit((Object)(object)_player)) { num = (Owns(_player) ? 1 : 0); if (num != 0) { _player.m_grappling = 0f; } } else { num = 0; } if (num != 0 && Object.op_Implicit((Object)(object)hook.m_anim)) { hook.m_anim.SetBool("grappling", false); hook.m_anim.SetBool("repell", false); } if (num != 0 && Object.op_Implicit((Object)(object)hook.m_se)) { ((StatusEffect)hook.m_se).ResetTime(); ((StatusEffect)hook.m_se).m_ttl = _effectReleaseTtl; hook.m_se.m_maxMaxFallSpeed = 0f; } if (Object.op_Implicit((Object)(object)GameCamera.instance)) { GameCamera.instance.ResetTempFOV(); } } if (Object.op_Implicit((Object)(object)hook.m_lineRenderer)) { ((Renderer)hook.m_lineRenderer).enabled = false; } if (Object.op_Implicit((Object)(object)ZNetScene.instance)) { ZNetScene.instance.Destroy(((Component)hook).gameObject); } else { Object.Destroy((Object)(object)((Component)hook).gameObject); } } Transition(State.Idle, reason); } internal static void ResetLocal(Character character, Reason reason) { if (!((Object)(object)character != (Object)(object)Player.m_localPlayer) || !((Object)(object)character != (Object)(object)_player)) { if (reason != Reason.Death && reason != Reason.Destroyed && reason != Reason.Teleport && reason != Reason.Scene && reason != Reason.Ownership && reason != Reason.Disabled && ActiveTick(character) && _state == State.Attached) { _abortQueued = true; _abortReason = reason; } else { Reset(reason); } } } private static void Track(GrapplingPoint hook, Player player) { //IL_0087: 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_0097: 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_00bc: 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_00eb: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)hook).GetInstanceID(); if (instanceID != _ignoredHookId && (_state != State.Attached || instanceID != _hookId)) { Transition(State.Idle, Reason.Hook); _player = player; _hook = hook; _hookId = instanceID; _ignoredHookId = 0; Plugin.Settings cached = Plugin.Cached; _attachedAt = Time.fixedTime; _pullAt = _attachedAt + cached.PullDelay; _jumpUntil = _attachedAt + cached.JumpWindow; _rampSeconds = cached.RampSeconds; _ropeLength = Math.Max(1f, Length(((Character)player).m_body.position - ((Component)hook).transform.position)); _approach = ((Component)hook).transform.position - ((Character)player).m_body.position; _approach.y = 0f; _groundedOnAttach = ((Character)player).IsOnGround(); _attachY = ((Character)player).m_body.position.y; _traceUntil = _attachedAt + 2f; _traceNext = 0f; Trace("attached: distance " + Length(((Character)player).m_body.position - ((Component)hook).transform.position).ToString("0.0") + " m, anchor height " + (((Component)hook).transform.position.y - _attachY).ToString("0.00") + " m, grounded " + _groundedOnAttach); _jumpUsed = false; _initialPending = true; _savedTipColor = hook.m_lineRenderer.startColor; _colorSaved = true; _colorRestored = false; _effectReleaseTtl = (IsFinite(hook.m_ttlSE) ? Math.Max(0.01f, hook.m_ttlSE) : 2f); Transition(State.Attached, Reason.Hook); AttachSpark(((Component)hook).transform.position); } } private static void AttachSpark(Vector3 position) { //IL_0079: 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_0088: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (_spark == null) { GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("vfx_HitSparks") : null); if (!Object.op_Implicit((Object)(object)val)) { if (!_sparkMissingLogged) { Plugin.TransitionLog("[GrappleMomentum] vfx_HitSparks not found; tip colour only."); } _sparkMissingLogged = true; return; } EffectList val2 = new EffectList(); val2.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = val, m_enabled = true } }; _spark = val2; } _spark.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } internal static void BeginTick(Character character) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown if ((Object)(object)character != (Object)(object)Player.m_localPlayer) { return; } Player val = (Player)character; _tickSettings = Plugin.Cached; if (!Plugin.Operational || !_tickSettings.Enabled) { Reset(Reason.Disabled); return; } if (!Owns(val)) { Reset(Reason.Ownership); return; } if (Object.op_Implicit((Object)(object)_player) && (Object)(object)_player != (Object)(object)val) { Reset(Reason.Destroyed); } _tickPlayer = val; _inTick = true; _walkingReplaced = false; } internal static Exception? EndTick(Character character, Exception? error) { if ((Object)(object)character == (Object)(object)_tickPlayer) { _inTick = false; _tickPlayer = null; if (error != null) { Plugin.Fault(error); } } return error; } internal static void PrepareMotion(Character character) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) if (!ActiveTick(character)) { return; } Player tickPlayer = _tickPlayer; if (!Owns(tickPlayer)) { Reset(Reason.Ownership); return; } GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; if (Supported(localGrappler, tickPlayer)) { Track(localGrappler, tickPlayer); } if (Unsafe(tickPlayer)) { ResetLocal((Character)(object)tickPlayer, Reason.Unsafe); return; } if (((Character)tickPlayer).IsKnockedBack() || ((Character)tickPlayer).IsStaggering()) { ResetLocal((Character)(object)tickPlayer, Reason.Impact); return; } if (_state == State.Attached) { if (!Supported(_hook, tickPlayer) || (Object)(object)_hook != (Object)(object)localGrappler || !Object.op_Implicit((Object)(object)_hook.m_attachPoint)) { ResetLocal((Character)(object)tickPlayer, Reason.HookLost); return; } if (AnchorLost()) { ResetLocal((Character)(object)tickPlayer, Reason.AnchorLost); return; } if (!_ownsFallCap && Object.op_Implicit((Object)(object)_hook.m_se)) { _ownedEffect = _hook.m_se; _savedFallCap = _ownedEffect.m_maxMaxFallSpeed; _ownedEffect.m_maxMaxFallSpeed = 0f; _ownsFallCap = true; } if (CarriedHook(tickPlayer) == null) { ResetLocal((Character)(object)tickPlayer, Reason.Unsafe); return; } } if (_state == State.Inertia) { if (((Character)tickPlayer).IsOnGround() && !LateJumpOpen()) { Reset(Reason.Ground); return; } if (Time.fixedTime >= _fallUntil && !LateJumpOpen() && HorizontalSpeed(((Character)tickPlayer).m_body.linearVelocity) <= ((Character)tickPlayer).m_runSpeed) { Reset(Reason.Stopped); return; } if (((Character)tickPlayer).m_rootMotion != Vector3.zero) { Reset(Reason.Impact); return; } } if (_state != State.Idle && !TryLimitVelocity(((Character)tickPlayer).m_body.linearVelocity, _tickSettings.MaxSpeed, out var _)) { NumericReset(); } } internal static bool BeforeWalking(Character character, out AirControlScope scope) { //IL_0033: 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_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_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_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) scope = default(AirControlScope); if (!ActiveTick(character) || _abortQueued) { return true; } if (_state == State.Attached) { _walkingReplaced = true; character.m_body.useGravity = true; character.m_rootMotion = Vector3.zero; character.m_currentVel = Vector3.zero; character.m_lastPos = ((Component)character).transform.position; character.m_lazyPos = ((Component)character).transform.position; return false; } if (_state == State.Inertia) { scope = new AirControlScope { Changed = true, Original = character.m_airControl }; character.m_airControl = 0f; } return true; } internal static void RestoreAirControl(Character character, AirControlScope scope) { if (scope.Changed && Object.op_Implicit((Object)(object)character)) { character.m_airControl = scope.Original; } } private static void Detach(bool retainMomentum, Reason reason) { GrapplingPoint hook = _hook; RestoreHookPresentation(); _breaking = true; try { if (Object.op_Implicit((Object)(object)hook) && Object.op_Implicit((Object)(object)hook.m_nview) && hook.m_nview.IsValid() && hook.m_nview.IsOwner() && Object.op_Implicit((Object)(object)hook.m_character)) { hook.Break(true); } } finally { _breaking = false; } if (retainMomentum) { Transition(State.Inertia, reason); if (reason == Reason.Arrival && _groundedOnAttach && !_jumpUsed && Time.fixedTime <= _jumpUntil) { _lateJumpUntil = _jumpUntil; } } else { Reset(reason); } } internal static void ObserveBreak(GrapplingPoint hook) { if (!_breaking && (Object)(object)hook == (Object)(object)_hook) { Reset(Reason.HookLost); } } internal static void BeforeSync(Character character) { //IL_0050: 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_0090: 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_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0426: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) if (!ActiveTick(character) || _state == State.Idle) { return; } Player tickPlayer = _tickPlayer; if (!Owns(tickPlayer)) { Reset(Reason.Ownership); return; } if (_abortQueued || Unsafe(tickPlayer)) { Detach(retainMomentum: false, _abortQueued ? _abortReason : Reason.Unsafe); return; } if (!TryLimitVelocity(((Character)tickPlayer).m_body.linearVelocity, _tickSettings.MaxSpeed, out var result)) { NumericReset(); return; } Vector3 val = Vector3.zero; bool flag = false; bool flag2 = false; bool trainJump = false; if (!((Character)tickPlayer).TakeInput()) { _jumpRequested = false; _releaseRequested = false; _steer = Vector3.zero; } if (_state == State.Attached) { if (!Supported(_hook, tickPlayer) || AnchorLost()) { Detach(retainMomentum: false, Reason.HookLost); return; } Vector3 val2 = ((Character)tickPlayer).m_body.position - ((Component)_hook).transform.position; float num = Length(val2); if (!Finite(val2) || !IsFinite(num)) { NumericReset(); return; } if (num > _hook.m_maxLength) { Detach(retainMomentum: false, Reason.HookLost); return; } _hook.m_time = Time.fixedTime - _attachedAt; _hook.m_lastDist = num; _hook.m_breakingTime = 0f; bool flag3 = ((Character)tickPlayer).IsOnGround(); if (_initialPending) { if (Object.op_Implicit((Object)(object)_hook.m_anim)) { _hook.m_anim.SetBool("repell", false); _hook.m_anim.SetBool("grappling", true); } Vector3 val3 = ((num > 0.0001f) ? (-val2 / num) : Vector3.zero); if (flag3 && val3.y < 0f) { val3.y = 0f; float num2 = Length(val3); if (num2 > 0.0001f) { val3 /= num2; } } result += val3 * _tickSettings.InitialImpulse; if (flag3 && !((Character)tickPlayer).IsEncumbered() && _tickSettings.GroundLift > 0f) { result.y = Math.Max(result.y, _tickSettings.GroundLift); flag = true; } _initialPending = false; } bool jumpRequested = _jumpRequested; _jumpRequested = false; if (jumpRequested && TryJump(tickPlayer, flag3, late: false, ref result, out trainJump)) { flag = (flag2 = true); } bool flag4 = RopeActive(val2); if (_releaseRequested || num <= _hook.m_closeBreakDist) { Detach(retainMomentum: true, _releaseRequested ? Reason.Release : Reason.Arrival); } else if (!flag4 && PassedAnchor(val2, result, _approach, 0.5f)) { Detach(retainMomentum: true, Reason.Arrival); } else { if (Time.fixedTime >= _pullAt) { float target = RampSpeed(Time.fixedTime - _pullAt, _rampSeconds, _tickSettings.InitialImpulse, _tickSettings.PullSpeed); float y = result.y; result = StepPull(result, val2 - Vector3.up * 0.6f, _steer, _look, target, _tickSettings.PullAcceleration, _tickSettings.AirAcceleration, _tickSettings.SwingPull, Time.fixedDeltaTime); if (!flag4 && y > 0f && result.y < y) { result.y = y; } } _ropeLength = Math.Min(_ropeLength, Math.Max(1f, num)); if (flag4) { result = ConstrainRope(result, val2, _ropeLength); val = RopeCorrection(val2, _ropeLength, 0.05f); } } } if (_state == State.Inertia && _lateJumpUntil > 0f) { bool jumpRequested2 = _jumpRequested; _jumpRequested = false; if (jumpRequested2 && TryJump(tickPlayer, ((Character)tickPlayer).IsOnGround(), late: true, ref result, out trainJump)) { flag = (flag2 = true); } } if (_state == State.Inertia) { result += _steer * (_tickSettings.AirAcceleration * Time.fixedDeltaTime); } if (_walkingReplaced) { ((Character)tickPlayer).m_seman.ModifyWalkVelocity(ref result); } if (!TryLimitVelocity(result, _tickSettings.MaxSpeed, out result) || !Finite(val)) { NumericReset(); return; } if (flag) { ((Character)tickPlayer).m_body.WakeUp(); ((Character)tickPlayer).ResetGroundContact(); ((Character)tickPlayer).m_lastGroundTouch = 1f; ((Character)tickPlayer).m_jumpTimer = 0f; ((Character)tickPlayer).UpdateBodyFriction(); } ((Character)tickPlayer).m_body.linearVelocity = result; float num3 = Length(val); if (num3 > 0.0001f) { Vector3 val4 = val / num3; RaycastHit val5 = default(RaycastHit); if (((Character)tickPlayer).m_body.SweepTest(val4, ref val5, num3 + 0.01f, (QueryTriggerInteraction)1)) { num3 = Math.Max(0f, Math.Min(num3, ((RaycastHit)(ref val5)).distance - 0.01f)); } if (num3 > 0.0001f) { Rigidbody body = ((Character)tickPlayer).m_body; body.position += val4 * num3; } } TraceSample(tickPlayer, result); if (flag2) { ((Character)tickPlayer).m_zanim.SetTrigger("jump"); ((Character)tickPlayer).OnJump(); if (trainJump) { ((Character)tickPlayer).RaiseSkill((SkillType)100, 1f); } } if (_walkingReplaced) { float num4 = ((Character)tickPlayer).UpdateRotation(((Character)tickPlayer).m_turnSpeed, Time.fixedDeltaTime, false); ((Character)tickPlayer).UpdateEyeRotation(); ((Character)tickPlayer).m_zanim.SetFloat(Character.s_forwardSpeed, 0f); ((Character)tickPlayer).m_zanim.SetFloat(Character.s_sidewaySpeed, 0f); ((Character)tickPlayer).m_zanim.SetFloat(Character.s_turnSpeed, num4); ((Character)tickPlayer).m_zanim.SetBool(Character.s_onGround, ((Character)tickPlayer).IsOnGround()); ((Character)tickPlayer).m_zanim.SetBool(Character.s_inWater, false); ((Character)tickPlayer).m_zanim.SetBool(Character.s_flying, false); ((Character)tickPlayer).m_zanim.SetBool(Character.s_encumbered, ((Character)tickPlayer).IsEncumbered()); ((Character)tickPlayer).m_zanim.SetBool(Character.s_slipping, false); ((Character)tickPlayer).m_zanim.SetBool(Character.s_skating, false); ((Character)tickPlayer).m_zanim.SetBool(Character.s_skatgliding, false); } } private static bool LateJumpOpen() { if (_state == State.Inertia && _lateJumpUntil > 0f && !_jumpUsed) { if (!(Time.fixedTime <= _lateJumpUntil)) { return _jumpRequested; } return true; } return false; } private static bool TryJump(Player player, bool grounded, bool late, ref Vector3 velocity, out bool trainJump) { //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) trainJump = false; bool flag = (late ? JumpEligible(used: false, grounded: false, groundedAtAttach: true, _jumpPressedAt, _lateJumpUntil) : JumpEligible(used: false, grounded, _groundedOnAttach, _jumpPressedAt, _jumpUntil)); string text = (_jumpUsed ? "already used" : (((Character)player).IsEncumbered() ? "encumbered" : (((Character)player).InDodge() ? "dodging" : (flag ? null : (_groundedOnAttach ? "margin closed" : "air attachment"))))); if (text != null) { Trace("jump rejected: " + text + " (pressed +" + (_jumpPressedAt - _attachedAt).ToString("0.00") + " s)"); return false; } float skillFactor = ((Character)player).GetSkillFactor((SkillType)100); float num = (1f + skillFactor * 0.4f) * _tickSettings.JumpMultiplier; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(_steer.x * ((Character)player).m_jumpForceForward * num, ((Character)player).m_jumpForce * num, _steer.z * ((Character)player).m_jumpForceForward * num); float num2 = ((Character)player).m_jumpStaminaUsage * (1f - ((Character)player).GetEquipmentMovementModifier() + ((Character)player).GetEquipmentJumpStaminaModifier()); ((Character)player).m_seman.ModifyJumpStaminaUsage(num2, ref num2, true); num2 *= Game.m_moveStaminaRate; trainJump = ((Character)player).HaveStamina(num2); if (!trainJump) { val *= ((Character)player).m_jumpForceTiredFactor; } ((Character)player).m_seman.ApplyStatusEffectJumpMods(ref val); velocity = AddJump(velocity, val); _jumpUsed = true; Trace("jump accepted" + (late ? " after arrival" : "") + ": pressed +" + (_jumpPressedAt - _attachedAt).ToString("0.00") + " s, jump.y " + val.y.ToString("0.0") + " m/s, vel " + Fmt(velocity) + (trainJump ? "" : " (tired)")); return true; } private static string Fmt(Vector3 v) { //IL_0010: 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_0021: Unknown result type (might be due to invalid IL or missing references) return "(h " + Length(new Vector3(v.x, 0f, v.z)).ToString("0.0") + ", y " + v.y.ToString("0.0") + ")"; } private static void Trace(string message) { if (Tracing) { Plugin.TransitionLog("[GrappleMomentum] trace +" + (Time.fixedTime - _attachedAt).ToString("0.00") + " s " + message); } } private static void TraceSample(Player player, Vector3 velocity) { //IL_0053: 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) if (Tracing && !(Time.fixedTime < _traceNext)) { _traceNext = Time.fixedTime + 0.1f - 0.001f; Trace(_state.ToString() + " height " + (((Character)player).m_body.position.y - _attachY).ToString("0.00") + " m, vel " + Fmt(velocity) + ", ground " + ((Character)player).IsOnGround()); } } private static void NumericReset() { if (_inTick && _state == State.Attached) { Detach(retainMomentum: false, Reason.Fault); } else { Reset(Reason.Fault); } if (!_numericErrorLogged) { _numericErrorLogged = true; Plugin.NumericFault(); } } internal static void CaptureInput() { if (!Plugin.Operational || !Plugin.Cached.Enabled) { Reset(Reason.Disabled); return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Owns(localPlayer)) { Reset(Reason.Ownership); return; } CaptureButtons(localPlayer, GrapplingPoint.m_localGrappler); TryOffhandFire(localPlayer); } private static void CaptureButtons(Player player, GrapplingPoint? hook) { //IL_0019: 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_0028: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) if (Time.inFixedTimeStep) { return; } if (Supported(hook, player)) { Track(hook, player); } _look = ((Character)player).GetLookDir(); _steer = Vector3.zero; if (!((Character)player).TakeInput()) { return; } Vector2 joyLeftStick = ZInput.GetJoyLeftStick(); float num = joyLeftStick.x + (ZInput.GetButton("Right") ? 1f : 0f) - (ZInput.GetButton("Left") ? 1f : 0f); float num2 = joyLeftStick.y + (ZInput.GetButton("Forward") ? 1f : 0f) - (ZInput.GetButton("Backward") ? 1f : 0f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(_look.x, 0f, _look.z); float num3 = Length(val); if (num3 <= 0.0001f) { Vector3 forward = ((Component)player).transform.forward; ((Vector3)(ref val))..ctor(forward.x, 0f, forward.z); num3 = Length(val); } if (num3 > 0.0001f) { val /= num3; } if (!TryLimitVelocity(val * num2 + new Vector3(val.z, 0f, 0f - val.x) * num, 1f, out _steer)) { _steer = Vector3.zero; } bool flag = ZInput.GetButtonDown("Jump") || ZInput.GetButtonDown("JoyJump"); bool flag2 = LateJumpOpen(); if (!flag2 && (_state != State.Attached || (Object)(object)hook != (Object)(object)_hook)) { if (flag && _lastJumpTraceFrame != Time.frameCount) { _lastJumpTraceFrame = Time.frameCount; if (Plugin.Cached.Debug) { Plugin.TransitionLog("[GrappleMomentum] trace jump pressed with no hook to jump from (" + _state.ToString() + ", last attach " + (Time.fixedTime - _attachedAt).ToString("0.00") + " s ago)"); } } } else { if (!flag2 && (ZInput.GetButton("Block") || ZInput.GetButton("JoyBlock"))) { _releaseRequested = true; } if (!_jumpRequested && flag) { _jumpRequested = true; _jumpPressedAt = Time.fixedTime; } } } internal static bool GrappleFrame(GrapplingPoint hook) { //IL_00df: 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) if (!Plugin.Operational || !Plugin.Cached.Enabled) { if ((Object)(object)hook == (Object)(object)_hook) { Reset(Reason.Disabled); } return true; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || (Object)(object)hook.m_character != (Object)(object)localPlayer || (Object)(object)hook != (Object)(object)GrapplingPoint.m_localGrappler || !Owns(localPlayer) || !Supported(hook, localPlayer)) { return true; } if (((Object)hook).GetInstanceID() == _ignoredHookId) { return true; } Track(hook, localPlayer); CaptureButtons(localPlayer, hook); if (Object.op_Implicit((Object)(object)hook.m_attachPoint)) { hook.UpdateLinePosition(); } localPlayer.m_grappling = 0.2f; if (!_colorRestored) { if (Time.fixedTime < _jumpUntil) { hook.m_lineRenderer.startColor = new Color(1f, 0.75f, 0.2f, 1f); } else { hook.m_lineRenderer.startColor = _savedTipColor; _colorRestored = true; } } return false; } internal static bool AllowVanillaJump(Character character) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (!Plugin.Operational || !Plugin.Cached.Enabled || (Object)(object)character != (Object)(object)Player.m_localPlayer) { return true; } Player player = (Player)character; if (!Owns(player)) { return true; } GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; if (_state == State.Inertia && Object.op_Implicit((Object)(object)localGrappler) && ((Object)localGrappler).GetInstanceID() == _hookId) { return false; } if (LateJumpOpen()) { return false; } if (Supported(localGrappler, player)) { return ((Object)localGrappler).GetInstanceID() == _ignoredHookId; } return true; } internal static ImpactScope BeforeImpact(Projectile projectile) { if (!Plugin.Operational || !Plugin.Cached.Enabled || (Object)(object)projectile.m_owner != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return default(ImpactScope); } GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; return new ImpactScope { Local = true, PreviousId = (Object.op_Implicit((Object)(object)localGrappler) ? ((Object)localGrappler).GetInstanceID() : 0) }; } internal static void AfterImpact(Projectile projectile, GameObject? target, Collider? collider, ImpactScope impact) { if (impact.Local && Plugin.Operational && Plugin.Cached.Enabled) { Player localPlayer = Player.m_localPlayer; GrapplingPoint localGrappler = GrapplingPoint.m_localGrappler; if (Object.op_Implicit((Object)(object)localPlayer) && Owns(localPlayer) && !((Object)(object)projectile.m_owner != (Object)(object)localPlayer) && Supported(localGrappler, localPlayer) && ((Object)localGrappler).GetInstanceID() != impact.PreviousId) { Track(localGrappler, localPlayer); _anchor = target; _anchorCollider = collider; _hadAnchor = Object.op_Implicit((Object)(object)target); _hadCollider = Object.op_Implicit((Object)(object)collider); } } } internal static void AttackCost(Attack attack, ref float cost) { Plugin.Settings cached = Plugin.Cached; Player localPlayer = Player.m_localPlayer; if (Plugin.Operational && cached.Enabled && Object.op_Implicit((Object)(object)localPlayer) && (Object)(object)attack.m_character == (Object)(object)localPlayer && Owns(localPlayer) && attack.m_weapon?.m_shared.m_name == "$item_graplinghook") { cost = cached.Stamina; } } internal static void FallDamage(SEMan effects, ref float damage) { if (_inTick && Object.op_Implicit((Object)(object)_tickPlayer) && (Object)(object)effects.m_character == (Object)(object)_tickPlayer && _tickSettings.FallGrace > 0f && _state == State.Inertia && Time.fixedTime < _fallUntil && Owns(_tickPlayer) && !Unsafe(_tickPlayer)) { damage = 0f; } } private static ItemData? CarriedHook(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return null; } foreach (ItemData item in inventory.m_inventory) { if (IsHook(item)) { return item; } } return null; } private static bool IsHook(ItemData? item) { if (item != null) { return item.m_shared.m_name == "$item_graplinghook"; } return false; } internal static bool HookLoading(Player player, ItemData? weapon) { if (!Plugin.Operational || !Plugin.Cached.Enabled || (Object)(object)player != (Object)(object)Player.m_localPlayer || !IsHook(weapon) || !weapon.m_shared.m_attack.m_requiresReload || !Owns(player)) { return true; } if (player.m_weaponLoaded == weapon) { _reloadPending = false; return false; } player.CancelReloadAction(); if (!_reloadPending) { _reloadPending = true; _lastShotAt = Math.Max(_lastShotAt, Time.time); } if (Time.time >= _lastShotAt + Plugin.Cached.Cooldown) { player.SetWeaponLoaded(weapon); _reloadPending = false; } return false; } private static void TryOffhandFire(Player player) { //IL_0005: 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_0012: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 KeyCode offhandKey = Plugin.Cached.OffhandKey; if (Time.inFixedTimeStep || (int)offhandKey == 0 || !ZInput.GetKeyDown(offhandKey, false) || !((Character)player).TakeInput() || ((Character)player).InPlaceMode() || Unsafe(player) || Time.time < _lastShotAt + Plugin.Cached.Cooldown) { return; } ItemData val = CarriedHook(player); if (val == null) { return; } Attack attack = val.m_shared.m_attack; if ((int)attack.m_attackType != 2 || !Object.op_Implicit((Object)(object)attack.m_attackProjectile)) { return; } Attack val2 = attack.Clone(); val2.m_character = (Humanoid)(object)player; val2.m_baseAI = null; val2.m_body = ((Character)player).m_body; val2.m_zanim = ((Character)player).m_zanim; val2.m_animEvent = ((Character)player).m_animEvent; val2.m_visEquipment = ((Humanoid)player).m_visEquipment; val2.m_weapon = val; val2.m_attackDrawPercentage = 0f; if (!attack.m_perBurstResourceUsage) { float attackStamina = val2.GetAttackStamina(); if (attackStamina > 0f && !((Character)player).HaveStamina(attackStamina + 0.1f)) { if (Object.op_Implicit((Object)(object)Hud.instance)) { Hud.instance.StaminaBarEmptyFlash(); } return; } if (attackStamina > 0f) { ((Character)player).UseStamina(attackStamina); } } _lastShotAt = Time.time; val2.FireProjectileBurst(); if (((Humanoid)player).GetCurrentWeapon() == val) { ((Humanoid)player).ResetLoadedWeapon(); } } internal static void UpdateDot(Hud hud, Player player) { //IL_0094: 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) ItemData val = null; if (Plugin.Operational && Plugin.Cached.Enabled && Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)hud.m_crosshair)) { val = CarriedHook(player); } if (val == null) { if (Object.op_Implicit((Object)(object)_dot)) { ((Component)_dot).gameObject.SetActive(false); } return; } Image val2 = EnsureDot(hud.m_crosshair); if (!((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(true); } ((Graphic)val2).color = (HookInRange(player, val) ? DotInRange : DotOutOfRange); } internal static void DestroyDot() { if (Object.op_Implicit((Object)(object)_dot)) { Object.Destroy((Object)(object)((Component)_dot).gameObject); } _dot = null; } private static Image EnsureDot(Image crosshair) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_015c: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_dot) && (Object)(object)((Component)_dot).transform.parent == (Object)(object)((Component)crosshair).transform) { return _dot; } DestroyDot(); if (!Object.op_Implicit((Object)(object)_dotSprite)) { Texture2D val = new Texture2D(16, 16, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { float num = (float)j + 0.5f - 8f; float num2 = (float)i + 0.5f - 8f; float num3 = Clamp01(8f - (float)Math.Sqrt(num * num + num2 * num2)); val.SetPixel(j, i, new Color(1f, 1f, 1f, num3)); } } val.Apply(); _dotSprite = Sprite.Create(val, new Rect(0f, 0f, 16f, 16f), new Vector2(0.5f, 0.5f)); } GameObject val2 = new GameObject("GrappleMomentumDot", new Type[1] { typeof(RectTransform) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent(((Component)crosshair).transform, false); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(0.5f, 0.5f); val3.pivot = val4; Vector2 anchorMin = (val3.anchorMax = val4); val3.anchorMin = anchorMin; val3.anchoredPosition = Vector2.zero; val3.sizeDelta = new Vector2(4f, 4f); _dot = val2.AddComponent<Image>(); _dot.sprite = _dotSprite; ((Graphic)_dot).raycastTarget = false; return _dot; } private static bool HookInRange(Player player, ItemData item) { //IL_0129: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: 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_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) Attack attack = item.m_shared.m_attack; GameObject attackProjectile = attack.m_attackProjectile; Projectile val = (Object.op_Implicit((Object)(object)attackProjectile) ? attackProjectile.GetComponent<Projectile>() : null); GrapplingPoint val2 = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.m_spawnOnHit)) ? val.m_spawnOnHit.GetComponent<GrapplingPoint>() : null); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)((Character)player).m_body)) { return false; } if (_dotMask == 0) { _dotMask = LayerMask.GetMask(new string[12] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle" }); } Transform transform = ((Component)player).transform; Transform val3 = ((attack.m_attackOriginJoint.Length > 0 && Object.op_Implicit((Object)(object)((Character)player).GetVisual())) ? Utils.FindChild(((Character)player).GetVisual().transform, attack.m_attackOriginJoint, (IterativeSearchType)0) : null); if (!Object.op_Implicit((Object)(object)val3)) { val3 = transform; } Vector3 val4 = val3.position + transform.up * attack.m_attackHeight + transform.forward * attack.m_attackRange + transform.right * attack.m_attackOffset; Vector3 val5 = ((Humanoid)player).GetAimDir(val4); if (attack.m_launchAngle != 0f) { val5 = Quaternion.AngleAxis(attack.m_launchAngle, Vector3.Cross(Vector3.up, val5)) * val5; } Vector3 val6 = val5 * attack.m_projectileVel; Vector3 position = ((Character)player).m_body.position; float maxLength = val2.m_maxLength; float num = Math.Max(0.005f, Time.fixedDeltaTime); for (float num2 = 0f; num2 < val.m_ttl; num2 += num) { val6 += Vector3.down * (val.m_gravity * num); float num3 = Length(val6); if (num3 > 0.0001f) { val6 -= val6 / num3 * (num3 * num3 * val.m_drag * num); } Vector3 val7 = val6 * num; float num4 = Length(val7); if (!Finite(val7) || num4 <= 0.0001f) { return false; } int num5 = Physics.RaycastNonAlloc(val4, val7 / num4, DotHits, num4, _dotMask); RaycastHit? val8 = null; RaycastHit value; for (int i = 0; i < num5; i++) { Collider collider = ((RaycastHit)(ref DotHits[i])).collider; if (!Object.op_Implicit((Object)(object)collider) || (Object)(object)((Component)collider).GetComponentInParent<Character>() == (Object)(object)player) { continue; } if (val8.HasValue) { float distance = ((RaycastHit)(ref DotHits[i])).distance; value = val8.Value; if (!(distance < ((RaycastHit)(ref value)).distance)) { continue; } } val8 = DotHits[i]; } if (val8.HasValue) { value = val8.Value; GameObject val9 = Projectile.FindHitObject(((RaycastHit)(ref value)).collider); if (val2.CanAttach(val9)) { value = val8.Value; return Length(((RaycastHit)(ref value)).point - position) <= maxLength; } return false; } val4 += val7; if (Length(val4 - position) > maxLength) { return false; } } return false; } } internal static class Patches { [HarmonyPatch(typeof(Character), "CustomFixedUpdate", new Type[] { typeof(float) })] private static class Tick { private static void Prefix(Character __instance) { GrappleController.BeginTick(__instance); } private static Exception? Finalizer(Character __instance, Exception? __exception) { return GrappleController.EndTick(__instance, __exception); } } [HarmonyPatch(typeof(Character), "UpdateMotion", new Type[] { typeof(float) })] private static class Motion { private static void Prefix(Character __instance) { GrappleController.PrepareMotion(__instance); } } [HarmonyPatch(typeof(Character), "UpdateWalking", new Type[] { typeof(float) })] private static class Walking { private static bool Prefix(Character __instance, out GrappleController.AirControlScope __state) { return GrappleController.BeforeWalking(__instance, out __state); } private static Exception? Finalizer(Character __instance, GrappleController.AirControlScope __state, Exception? __exception) { GrappleController.RestoreAirControl(__instance, __state); return __exception; } } [HarmonyPatch(typeof(Character), "SyncVelocity", new Type[] { })] private static class Sync { private static void Prefix(Character __instance) { GrappleController.BeforeSync(__instance); } } [HarmonyPatch(typeof(ZInput), "Update", new Type[] { typeof(float) })] private static class Input { private static void Postfix() { GrappleController.CaptureInput(); } } [HarmonyPatch(typeof(GrapplingPoint), "Update", new Type[] { })] private static class GrappleInput { private static bool Prefix(GrapplingPoint __instance) { return GrappleController.GrappleFrame(__instance); } } [HarmonyPatch(typeof(GrapplingPoint), "Break", new Type[] { typeof(bool) })] private static class Break { private static void Prefix(GrapplingPoint __instance) { GrappleController.ObserveBreak(__instance); } } [HarmonyPatch(typeof(Projectile), "SpawnOnHit", new Type[] { typeof(GameObject), typeof(Collider), typeof(Vector3) })] private static class Impact { private static void Prefix(Projectile __instance, out GrappleController.ImpactScope __state) { __state = GrappleController.BeforeImpact(__instance); } private static void Postfix(Projectile __instance, GameObject go, Collider collider, GrappleController.ImpactScope __state) { GrappleController.AfterImpact(__instance, go, collider, __state); } } [HarmonyPatch(typeof(Player), "OnDeath", new Type[] { })] private static class Death { private static void Prefix(Player __instance) { GrappleController.ResetLocal((Character)(object)__instance, GrappleController.Reason.Death); } } [HarmonyPatch(typeof(Player), "TeleportTo", new Type[] { typeof(Vector3), typeof(Quaternion), typeof(bool) })] private static class Teleport { private static void Postfix(Player __instance, bool __result) { if (__result) { GrappleController.ResetLocal((Character)(object)__instance, GrappleController.Reason.Teleport); } } } [HarmonyPatch(typeof(Player), "OnDestroy", new Type[] { })] private static class Destroy { private static void Prefix(Player __instance) { GrappleController.ResetLocal((Character)(object)__instance, GrappleController.Reason.Destroyed); } } [HarmonyPatch(typeof(Game), "Logout", new Type[] { typeof(bool), typeof(bool) })] private static class Logout { private static void Prefix() { GrappleController.Reset(GrappleController.Reason.Scene); } } [HarmonyPatch(typeof(Character), "GetStandingOnShip", new Type[] { })] private static class Ship { private static void Postfix(Character __instance, Ship __result) { if (Object.op_Implicit((Object)(object)__result)) { GrappleController.ResetLocal(__instance, GrappleController.Reason.Ship); } } } [HarmonyPatch(typeof(Character), "UnderWorldCheck", new Type[] { typeof(float) })] private static class Rescue { private static void Prefix(Character __instance, out Vector3 __state) { //IL_001f: 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_0016: 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) __state = (Vector3)(((Object)(object)__instance == (Object)(object)Player.m_localPlayer) ? ((Component)__instance).transform.position : default(Vector3)); } private static void Postfix(Character __instance, Vector3 __state) { //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) if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Component)__instance).transform.position != __state) { GrappleController.ResetLocal(__instance, GrappleController.Reason.Rescue); } } } [HarmonyPatch(typeof(Character), "Jump", new Type[] { typeof(bool) })] private static class Jump { private static bool Prefix(Character __instance) { return GrappleController.AllowVanillaJump(__instance); } } [HarmonyPatch(typeof(Attack), "GetAttackStamina", new Type[] { })] private static class Stamina { private static void Postfix(Attack __instance, ref float __result) { GrappleController.AttackCost(__instance, ref __result); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class FallDamage { private static void Postfix(SEMan __instance, ref float damage) { GrappleController.FallDamage(__instance, ref damage); } } [HarmonyPatch(typeof(Player), "UpdateWeaponLoading", new Type[] { typeof(ItemData), typeof(float) })] private static class WeaponLoading { private static bool Prefix(Player __instance, ItemData weapon) { return GrappleController.HookLoading(__instance, weapon); } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair", new Type[] { typeof(Player), typeof(float) })] private static class Crosshair { private static void Postfix(Hud __instance, Player player) { GrappleController.UpdateDot(__instance, player); } } internal static void Install(Harmony harmony, ManualLogSource log) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) Type[] array = new Type[19] { typeof(Tick), typeof(Motion), typeof(Walking), typeof(Sync), typeof(Input), typeof(GrappleInput), typeof(Break), typeof(Impact), typeof(Death), typeof(Teleport), typeof(Destroy), typeof(Logout), typeof(Ship), typeof(Rescue), typeof(Jump), typeof(Stamina), typeof(FallDamage), typeof(WeaponLoading), typeof(Crosshair) }; Type[] array2 = array; foreach (Type type in array2) { HarmonyMethod info = ((HarmonyAttribute)(HarmonyPatch)Attribute.GetCustomAttribute(type, typeof(HarmonyPatch))).info; MethodInfo methodInfo = AccessTools.DeclaredMethod(info.declaringType, info.methodName, info.argumentTypes, (Type[])null) ?? throw new MissingMethodException(info.declaringType.FullName, info.methodName); Type type2 = ((type == typeof(Teleport)) ? typeof(bool) : ((type == typeof(Ship)) ? typeof(Ship) : ((type == typeof(Stamina)) ? typeof(float) : typeof(void)))); if (methodInfo.ReturnType != type2) { throw new MissingMethodException("Unexpected return type: " + methodInfo); } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null) { continue; } foreach (string owner in patchInfo.Owners) { if (owner != "dugi.GrappleMomentum") { log.LogWarning((object)("[GrappleMomentum] Shared target " + methodInfo.DeclaringType.Name + "." + methodInfo.Name + ": " + owner)); } } } RequireField(typeof(Character), "m_body", typeof(Rigidbody)); RequireField(typeof(Character), "m_nview", typeof(ZNetView)); RequireField(typeof(Character), "m_airControl", typeof(float)); RequireField(typeof(Character), "m_rootMotion", typeof(Vector3)); RequireField(typeof(GrapplingPoint), "m_character", typeof(Character)); RequireField(typeof(GrapplingPoint), "m_nview", typeof(ZNetView)); RequireField(typeof(GrapplingPoint), "m_lineRenderer", typeof(LineRenderer)); RequireField(typeof(GrapplingPoint), "Method", typeof(GrapplingMethod)); RequireField(typeof(GrapplingPoint), "m_localGrappler", typeof(GrapplingPoint)); RequireField(typeof(Projectile), "m_owner", typeof(Character)); RequireField(typeof(Attack), "m_character", typeof(Humanoid)); RequireField(typeof(Attack), "m_weapon", typeof(ItemData)); RequireField(typeof(SEMan), "m_character", typeof(Character)); RequireField(typeof(GrapplingPoint), "m_se", typeof(SE_Stats)); RequireField(typeof(GrapplingPoint), "m_equipCheck", typeof(ItemDrop)); RequireField(typeof(GrapplingPoint), "m_secondary", typeof(bool)); RequireField(typeof(Character), "m_lastGroundTouch", typeof(float)); RequireField(typeof(Character), "m_jumpTimer", typeof(float)); RequireField(typeof(Player), "m_weaponLoaded", typeof(ItemData)); RequireField(typeof(Hud), "m_crosshair", typeof(Image)); array2 = array; foreach (Type type3 in array2) { harmony.CreateClassProcessor(type3).Patch(); } } private static void RequireField(Type type, string name, Type fieldType) { if ((AccessTools.Field(type, name) ?? throw new MissingFieldException(type.FullName, name)).FieldType != fieldType) { throw new MissingFieldException("Unexpected field type: " + type.Name + "." + name); } } } internal static class PluginVersion { internal const string Value = "0.3.2"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }