using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UltraHook")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Lets V1's Whiplash latch onto solid surfaces and pull toward them.")]
[assembly: AssemblyFileVersion("1.3.4.0")]
[assembly: AssemblyInformationalVersion("1.3.4+f78cfaa84619023ccf773a408748cf475c69cbf5")]
[assembly: AssemblyProduct("UltraHook")]
[assembly: AssemblyTitle("UltraHook")]
[assembly: AssemblyVersion("1.3.4.0")]
[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 UltraHook
{
internal static class GrappleHook
{
private enum Phase
{
Idle,
Pulling,
Taut
}
private sealed class RaycastHitDistanceComparer : IComparer<RaycastHit>
{
public static readonly RaycastHitDistanceComparer Instance = new RaycastHitDistanceComparer();
public int Compare(RaycastHit x, RaycastHit y)
{
return ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance);
}
}
private const int IgnoreRaycastLayer = 2;
private const int SolidClinkLayer = 26;
private const float ThrowSpeed = 250f;
private const float NoSwingExtraDamping = 5f;
private const float TipEndTolerance = 0.05f;
private const float EndpointContactTolerance = 0.05f;
private const int AttachGraceFrames = 2;
private const float MinNormalSqr = 1E-06f;
private static readonly AnimationCurve MomentumCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
private static readonly FieldRef<HookArm, HookState> StateRef = AccessTools.FieldRefAccess<HookArm, HookState>("state");
private static readonly FieldRef<HookArm, bool> ReturningRef = AccessTools.FieldRefAccess<HookArm, bool>("returning");
private static readonly FieldRef<HookArm, Vector3> HookPointRef = AccessTools.FieldRefAccess<HookArm, Vector3>("hookPoint");
private static readonly FieldRef<HookArm, Vector3> ThrowDirectionRef = AccessTools.FieldRefAccess<HookArm, Vector3>("throwDirection");
private static readonly FieldRef<HookArm, LayerMask> EnviroMaskRef = AccessTools.FieldRefAccess<HookArm, LayerMask>("enviroMask");
private static readonly FieldRef<HookArm, LayerMask> ThrowMaskRef = AccessTools.FieldRefAccess<HookArm, LayerMask>("throwMask");
private static readonly FieldRef<HookArm, Vector3> CaughtPointRef = AccessTools.FieldRefAccess<HookArm, Vector3>("caughtPoint");
private static readonly FieldRef<HookArm, Transform> CaughtTransformRef = AccessTools.FieldRefAccess<HookArm, Transform>("caughtTransform");
private static readonly FieldRef<HookArm, Collider> CaughtColliderRef = AccessTools.FieldRefAccess<HookArm, Collider>("caughtCollider");
private static readonly FieldRef<HookArm, bool> LightTargetRef = AccessTools.FieldRefAccess<HookArm, bool>("lightTarget");
private static readonly FieldInfo CaughtObjectsField = AccessTools.Field(typeof(HookArm), "caughtObjects");
private static readonly FieldInfo PortalTraversalsField = AccessTools.Field(typeof(HookArm), "portalTraversals");
private static readonly FieldInfo CaughtEidField = AccessTools.Field(typeof(HookArm), "caughtEid");
private static readonly FieldInfo CaughtHookField = AccessTools.Field(typeof(HookArm), "caughtHook");
private static readonly FieldInfo HitSoundField = AccessTools.Field(typeof(HookArm), "hitSound");
private static readonly FieldInfo AudField = AccessTools.Field(typeof(HookArm), "aud");
private static readonly RaycastHit[] CastBuffer = (RaycastHit[])(object)new RaycastHit[64];
private static readonly Collider[] OverlapBuffer = (Collider[])(object)new Collider[64];
private static readonly HashSet<Collider> SelfColliders = new HashSet<Collider>();
private static bool _selfCollidersBuilt;
private static GameObject _anchor;
private static SphereCollider _anchorCollider;
private static CapsuleCollider _playerCollider;
private static Phase _phase;
private static bool _tipTracking;
private static Vector3 _prevTipPosition;
private static Collider _hookedCollider;
private static bool _trackCollider;
private static Vector3 _localAnchor;
private static Vector3 _worldAnchor;
private static Vector3 _anchorNormal;
private static int _graceFrames;
private static bool _active;
private static float _initialDistance;
private static float _currentRopeLength;
private static float _storedReleaseSpeed;
private static Vector3 _filteredRopeDir;
private static Vector3 _naturalVelocity;
private static bool _jumpSuppressed;
private static bool _savedLightTarget;
private static bool _playerReleaseRequested;
private static bool _groundSuppressed;
private static float _groundTimer;
private static GroundCheckGroup _suppressedGc;
private static GroundCheckGroup _suppressedSlope;
private static int _diagSweepCount;
private static int _diagRayCount;
private static bool AnchorActive
{
get
{
if ((Object)(object)_anchor != (Object)null)
{
return _anchor.activeSelf;
}
return false;
}
}
private static float TipRadius => Mathf.Max(UltraHookConfig.SphereCastRadius, 0.02f);
private static Rigidbody PlayerRigidbody
{
get
{
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if (!((Object)(object)instance != (Object)null))
{
return null;
}
return instance.rb;
}
}
internal static bool OnFixedUpdatePre(HookArm hook)
{
//IL_0025: 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_0037: 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_00c9: Invalid comparison between Unknown and I4
//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_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: 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_00af: 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)
TickGroundSuppression();
if (_graceFrames > 0)
{
_graceFrames--;
}
HookState val = StateRef.Invoke(hook);
HandleDetection(hook, val);
if (AnchorActive && (int)val != 0)
{
if (_trackCollider && !ColliderUsable(_hookedCollider))
{
if (UltraHookConfig.DebugLogging)
{
Plugin.Log.LogInfo((object)"UltraHook detach: AnchorColliderDestroyed or AnchorColliderDisabled");
}
ForceDetach(hook);
return true;
}
if (_trackCollider)
{
_worldAnchor = ((Component)_hookedCollider).transform.TransformPoint(_localAnchor);
}
_anchor.transform.position = _worldAnchor;
Rigidbody playerRigidbody = PlayerRigidbody;
if ((Object)(object)playerRigidbody != (Object)null)
{
_naturalVelocity = playerRigidbody.velocity;
}
}
if (UltraHookConfig.SwingMode && AnchorActive && (int)val == 3)
{
HookPointRef.Invoke(hook) = _worldAnchor;
hook.beingPulled = true;
return false;
}
return true;
}
internal static void OnFixedUpdatePost(HookArm hook)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0262: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_031b: 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_032b: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Unknown result type (might be due to invalid IL or missing references)
//IL_032e: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Unknown result type (might be due to invalid IL or missing references)
//IL_0339: Unknown result type (might be due to invalid IL or missing references)
//IL_033d: Unknown result type (might be due to invalid IL or missing references)
//IL_0342: Unknown result type (might be due to invalid IL or missing references)
if (!AnchorActive || (int)StateRef.Invoke(hook) != 3)
{
_active = false;
SetPhase(Phase.Idle, "NotPulling");
return;
}
Rigidbody playerRigidbody = PlayerRigidbody;
if ((Object)(object)playerRigidbody == (Object)null)
{
return;
}
float fixedDeltaTime = Time.fixedDeltaTime;
Vector3 position = playerRigidbody.position;
Vector3 val = _worldAnchor - position;
float magnitude = ((Vector3)(ref val)).magnitude;
if (magnitude < 0.0001f)
{
return;
}
Vector3 val2 = val / magnitude;
float num = ResolvedMinRopeLength();
if (!_active)
{
_active = true;
SetPhase(Phase.Pulling, "StartedTerrainPull");
_initialDistance = Mathf.Max(magnitude, num);
_currentRopeLength = magnitude;
_storedReleaseSpeed = 0f;
_filteredRopeDir = val2;
}
float num2 = 1f - Mathf.Exp((0f - UltraHookConfig.DirectionFilterSpeed) * fixedDeltaTime);
Vector3 val3 = Vector3.Slerp(_filteredRopeDir, val2, num2);
_filteredRopeDir = ((Vector3)(ref val3)).normalized;
Vector3 naturalVelocity = _naturalVelocity;
float num3 = Vector3.Dot(naturalVelocity, val2);
Vector3 val4 = naturalVelocity - val2 * num3;
_currentRopeLength = Mathf.Max(num, _currentRopeLength - UltraHookConfig.ReelSpeed * fixedDeltaTime);
AccumulateMomentum(magnitude, num, num3);
float num4 = num + UltraHookConfig.TautTolerance;
bool flag = false;
float storedReleaseSpeed = _storedReleaseSpeed;
if (_phase == Phase.Pulling && magnitude <= num4)
{
SetPhase(Phase.Taut, "ReachedRopeEndpoint");
flag = true;
ClearStoredPullMomentum();
}
else if (_phase == Phase.Taut && magnitude > num4 + 1f)
{
SetPhase(Phase.Pulling, "RopeExtendedPastEndpoint");
}
float num5 = UltraHookConfig.MaxAngularSpeed * Mathf.Max(magnitude, num);
val4 = Vector3.ClampMagnitude(val4, num5);
float num6 = UltraHookConfig.TangentialDamping + (UltraHookConfig.SwingMode ? 0f : 5f);
val4 *= Mathf.Exp((0f - num6) * fixedDeltaTime);
float num7;
if (flag)
{
num7 = 0f;
val4 = ProjectOffSurface(val4);
}
else if (_phase == Phase.Pulling)
{
float num8 = Mathf.Max(0f, magnitude - _currentRopeLength);
float num9 = Mathf.Clamp(UltraHookConfig.MinPullSpeed + num8 * UltraHookConfig.PullSpeedGain, UltraHookConfig.MinPullSpeed, UltraHookConfig.MaxPullSpeed);
num7 = Mathf.MoveTowards(num3, num9, UltraHookConfig.PullAcceleration * fixedDeltaTime);
}
else
{
float num10 = Mathf.Clamp((magnitude - num) * UltraHookConfig.TautCorrectionGain, 0f - UltraHookConfig.MaxOutwardCorrectionSpeed, UltraHookConfig.MaxInwardCorrectionSpeed);
num7 = Mathf.MoveTowards(num3, num10, UltraHookConfig.TautAcceleration * fixedDeltaTime);
}
playerRigidbody.velocity = val4 + val2 * num7;
if (UltraHookConfig.DebugLogging)
{
if (flag)
{
ManualLogSource log = Plugin.Log;
object[] obj = new object[5] { num3, storedReleaseSpeed, _storedReleaseSpeed, playerRigidbody.velocity, null };
val3 = playerRigidbody.velocity;
obj[4] = ((Vector3)(ref val3)).magnitude;
log.LogInfo((object)("UltraHook taut entry (PullMomentumConsumedAtEndpoint, EndpointRadialVelocityRemoved, EnteredTautWithTangentialVelocity): " + string.Format("radialBefore={0:0.00} storedBefore={1:0.00} storedAfter={2:0.00} velAfter={3} mag={4:0.00}", obj)));
}
if (_phase == Phase.Taut && _storedReleaseSpeed > 0.01f)
{
Plugin.Log.LogWarning((object)$"UltraHook UnexpectedMomentumAppliedDuringTaut: storedReleaseSpeed={_storedReleaseSpeed:0.00}");
}
Debug.DrawLine(position, _worldAnchor, Color.cyan);
Debug.DrawRay(position, val4, Color.yellow);
Debug.DrawRay(position, val2 * num7, Color.green);
}
}
private static void AccumulateMomentum(float distance, float minRope, float radialSpeed)
{
if (!UltraHookConfig.Momentum)
{
_storedReleaseSpeed = 0f;
}
else if (_phase == Phase.Pulling)
{
float num = Mathf.Max(_initialDistance - minRope, 0.001f);
float num2 = Mathf.Clamp01((_initialDistance - distance) / num);
float num3 = MomentumCurve.Evaluate(num2) * UltraHookConfig.MaxMomentumBonus;
_storedReleaseSpeed = Mathf.Min(Mathf.Max(_storedReleaseSpeed, Mathf.Max(0f, radialSpeed) + num3), UltraHookConfig.MaxReleaseSpeed);
}
}
private static void ClearStoredPullMomentum()
{
_storedReleaseSpeed = 0f;
}
private static Vector3 ProjectOffSurface(Vector3 velocity)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
if (((Vector3)(ref _anchorNormal)).sqrMagnitude < 1E-06f)
{
return velocity;
}
float num = Vector3.Dot(velocity, _anchorNormal);
if (num < 0f)
{
velocity -= _anchorNormal * num;
}
return velocity;
}
private static void HandleDetection(HookArm hook, HookState state)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
//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_0046: 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_0068: 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_0070: Unknown result type (might be due to invalid IL or missing references)
if ((int)state != 1 || !UltraHookConfig.Enabled || !hook.equipped || ReturningRef.Invoke(hook))
{
_tipTracking = false;
return;
}
Vector3 val = HookPointRef.Invoke(hook);
if (!_tipTracking)
{
_tipTracking = true;
_prevTipPosition = val;
}
if (Count(CaughtObjectsField, hook) > 0 || Count(PortalTraversalsField, hook) > 0)
{
_prevTipPosition = val;
}
else
{
SweepTip(hook, val);
}
}
private static void SweepTip(HookArm hook, Vector3 tip)
{
//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_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_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: 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_0055: 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_005b: 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_0020: 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_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00f5: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = ThrowDirectionRef.Invoke(hook);
if (((Vector3)(ref val)).sqrMagnitude < 1E-08f)
{
_prevTipPosition = tip;
return;
}
val = ((Vector3)(ref val)).normalized;
float num = 250f * Time.fixedDeltaTime;
Vector3 prevTipPosition = _prevTipPosition;
Vector3 val2 = tip + val * num;
_prevTipPosition = tip;
Vector3 val3 = val2 - prevTipPosition;
float magnitude = ((Vector3)(ref val3)).magnitude;
if (magnitude < 0.0001f)
{
return;
}
Vector3 sweepDir = val3 / magnitude;
int num2 = DetectionMask(hook);
int catchMask = ((LayerMask)(ref ThrowMaskRef.Invoke(hook))).value & ~num2;
bool queriesHitBackfaces = Physics.queriesHitBackfaces;
if (UltraHookConfig.BackfaceCompatibility)
{
Physics.queriesHitBackfaces = true;
}
try
{
if (TryTerrainImpact(prevTipPosition, sweepDir, magnitude, num2, catchMask, out var collider, out var point, out var normal, out var distance))
{
CommitTerrainAnchor(hook, collider, point, normal, val, prevTipPosition, val2, distance);
}
else if (TryEndpointOverlap(val2, num2, val, out collider, out point, out normal))
{
CommitTerrainAnchor(hook, collider, point, normal, val, prevTipPosition, val2, Vector3.Distance(prevTipPosition, point));
}
}
finally
{
Physics.queriesHitBackfaces = queriesHitBackfaces;
}
}
private static bool TryTerrainImpact(Vector3 start, Vector3 sweepDir, float length, int detectMask, int catchMask, out Collider collider, out Vector3 point, out Vector3 normal, out float distance)
{
//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_0012: 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_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: 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_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_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
collider = null;
point = Vector3.zero;
normal = Vector3.zero;
distance = float.MaxValue;
bool flag = false;
float num = length + 0.05f;
int num2 = (_diagSweepCount = Physics.SphereCastNonAlloc(start, TipRadius, sweepDir, CastBuffer, num, detectMask, (QueryTriggerInteraction)1));
if (num2 >= CastBuffer.Length && UltraHookConfig.DebugLogging)
{
Plugin.Log.LogWarning((object)"UltraHook TipSweepBufferFull");
}
Array.Sort(CastBuffer, 0, num2, RaycastHitDistanceComparer.Instance);
for (int i = 0; i < num2; i++)
{
RaycastHit val = CastBuffer[i];
if (!(((RaycastHit)(ref val)).distance <= 0f) && IsHookableHit(((RaycastHit)(ref val)).collider))
{
collider = ((RaycastHit)(ref val)).collider;
point = ((RaycastHit)(ref val)).point;
normal = ((RaycastHit)(ref val)).normal;
distance = ((RaycastHit)(ref val)).distance;
flag = true;
break;
}
}
RaycastHit val2 = default(RaycastHit);
if (Physics.Raycast(start, sweepDir, ref val2, num, detectMask, (QueryTriggerInteraction)1) && IsHookableHit(((RaycastHit)(ref val2)).collider))
{
_diagRayCount = 1;
if (!flag || ((RaycastHit)(ref val2)).distance < distance)
{
collider = ((RaycastHit)(ref val2)).collider;
point = ((RaycastHit)(ref val2)).point;
normal = ((RaycastHit)(ref val2)).normal;
distance = ((RaycastHit)(ref val2)).distance;
flag = true;
}
}
else
{
_diagRayCount = 0;
}
if (!flag)
{
return false;
}
if (catchMask != 0 && CatchableStruckCloser(start, sweepDir, distance, catchMask))
{
collider = null;
return false;
}
return true;
}
private static bool CatchableStruckCloser(Vector3 start, Vector3 sweepDir, float terrainDistance, int catchMask)
{
//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_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)
int num = Physics.SphereCastNonAlloc(start, TipRadius, sweepDir, CastBuffer, terrainDistance, catchMask, (QueryTriggerInteraction)2);
for (int i = 0; i < num; i++)
{
RaycastHit val = CastBuffer[i];
Collider collider = ((RaycastHit)(ref val)).collider;
if (!((Object)(object)collider == (Object)null) && !((Object)(object)collider == (Object)(object)_anchorCollider) && !IsSelf(collider) && ((RaycastHit)(ref val)).distance <= terrainDistance - 0.01f)
{
return true;
}
}
return false;
}
private static bool TryEndpointOverlap(Vector3 endpoint, int detectMask, Vector3 fallbackDir, out Collider collider, out Vector3 point, out Vector3 normal)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0018: 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_0047: 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_004e: 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_006e: 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_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
collider = null;
point = endpoint;
normal = -fallbackDir;
int num = Physics.OverlapSphereNonAlloc(endpoint, TipRadius, OverlapBuffer, detectMask, (QueryTriggerInteraction)1);
float num2 = float.MaxValue;
for (int i = 0; i < num; i++)
{
Collider val = OverlapBuffer[i];
if (IsHookableHit(val))
{
Vector3 val2 = val.ClosestPoint(endpoint);
float num3 = Vector3.Distance(endpoint, val2);
if (num3 <= 0.05f && num3 < num2)
{
num2 = num3;
collider = val;
point = val2;
Vector3 val3 = endpoint - val2;
normal = ((((Vector3)(ref val3)).sqrMagnitude > 1E-06f) ? ((Vector3)(ref val3)).normalized : (-fallbackDir));
}
}
}
return (Object)(object)collider != (Object)null;
}
private static void CommitTerrainAnchor(HookArm hook, Collider collider, Vector3 point, Vector3 normal, Vector3 travelDir, Vector3 from, Vector3 to, float distance)
{
//IL_0019: 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_0010: 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_001f: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: 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_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: 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_0171: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = ((((Vector3)(ref normal)).sqrMagnitude > 1E-06f) ? ((Vector3)(ref normal)).normalized : (-travelDir));
Vector3 val2 = point + val * UltraHookConfig.SurfaceOffset;
Transform anchor = GetAnchor();
anchor.position = val2;
((Component)anchor).gameObject.SetActive(true);
CaughtTransformRef.Invoke(hook) = anchor;
CaughtPointRef.Invoke(hook) = Vector3.zero;
HookPointRef.Invoke(hook) = val2;
CaughtColliderRef.Invoke(hook) = (Collider)(object)_anchorCollider;
LightTargetRef.Invoke(hook) = false;
CaughtEidField.SetValue(hook, null);
CaughtHookField.SetValue(hook, null);
StateRef.Invoke(hook) = (HookState)2;
_hookedCollider = collider;
_trackCollider = ColliderUsable(collider);
_localAnchor = (_trackCollider ? ((Component)collider).transform.InverseTransformPoint(val2) : val2);
_worldAnchor = val2;
_anchorNormal = val;
_active = false;
_phase = Phase.Idle;
_tipTracking = false;
_graceFrames = 2;
object? value = HitSoundField.GetValue(hook);
GameObject val3 = (GameObject)((value is GameObject) ? value : null);
if (val3 != null && (Object)(object)val3 != (Object)null)
{
Object.Instantiate<GameObject>(val3, point, Quaternion.identity);
}
object? value2 = AudField.GetValue(hook);
AudioSource val4 = (AudioSource)((value2 is AudioSource) ? value2 : null);
if (val4 != null && (Object)(object)val4 != (Object)null)
{
val4.Stop();
}
if (UltraHookConfig.DebugLogging)
{
LogImpact(collider, point, val, distance, travelDir, from, to);
}
}
internal static void OnRelease()
{
//IL_0076: 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_0067: 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_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
bool flag = UltraHookConfig.SwingMode && AnchorActive && _active && _phase == Phase.Taut;
if (_active)
{
Rigidbody playerRigidbody = PlayerRigidbody;
if ((Object)(object)playerRigidbody != (Object)null && UltraHookConfig.Momentum && _storedReleaseSpeed > 0f)
{
Vector3 normalized;
if (!(((Vector3)(ref _filteredRopeDir)).sqrMagnitude > 0.5f))
{
Vector3 velocity = playerRigidbody.velocity;
normalized = ((Vector3)(ref velocity)).normalized;
}
else
{
normalized = ((Vector3)(ref _filteredRopeDir)).normalized;
}
Vector3 val = normalized;
if (((Vector3)(ref val)).sqrMagnitude > 0.5f)
{
float num = Vector3.Dot(playerRigidbody.velocity, val);
float num2 = Mathf.Max(num, _storedReleaseSpeed);
playerRigidbody.velocity += val * (num2 - num);
}
}
BeginGroundSuppression();
}
if (UltraHookConfig.DebugLogging)
{
if (flag && !_playerReleaseRequested)
{
Plugin.Log.LogWarning((object)"UltraHook UnexpectedEndpointDetach: released during a persistent swing without an explicit hook input");
}
else
{
Plugin.Log.LogInfo((object)string.Format("UltraHook release: reason={0} phase={1} swing={2}", _playerReleaseRequested ? "ExplicitSwingRelease" : "NonSwingOrForced", _phase, UltraHookConfig.SwingMode));
}
}
_playerReleaseRequested = false;
ResetLatchState();
}
internal static void SuppressJumpCancel(HookArm hook)
{
if (AnchorActive && (int)StateRef.Invoke(hook) == 3)
{
if (HookInputPressedThisFrame())
{
_playerReleaseRequested = true;
}
_savedLightTarget = LightTargetRef.Invoke(hook);
LightTargetRef.Invoke(hook) = true;
_jumpSuppressed = true;
}
}
private static bool HookInputPressedThisFrame()
{
InputManager instance = MonoSingleton<InputManager>.Instance;
if ((Object)(object)instance != (Object)null && instance.InputSource != null)
{
return instance.InputSource.Hook.WasPerformedThisFrame;
}
return false;
}
internal static void RestoreJumpCancel(HookArm hook)
{
if (_jumpSuppressed)
{
LightTargetRef.Invoke(hook) = _savedLightTarget;
_jumpSuppressed = false;
}
}
internal static void ScaleLineDistance(ref float result)
{
float maxHookDistance = UltraHookConfig.MaxHookDistance;
if (float.IsPositiveInfinity(maxHookDistance))
{
if (result > 299f)
{
result = 299f;
}
}
else if (maxHookDistance > 0f && !Mathf.Approximately(maxHookDistance, 300f))
{
result *= 300f / maxHookDistance;
}
}
private static void BeginGroundSuppression()
{
float groundSnapSuppressTime = UltraHookConfig.GroundSnapSuppressTime;
if (groundSnapSuppressTime <= 0f)
{
return;
}
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if (!((Object)(object)instance == (Object)null))
{
EndGroundSuppression();
_suppressedGc = instance.gc;
_suppressedSlope = instance.slopeCheck;
if ((Object)(object)_suppressedGc != (Object)null)
{
_suppressedGc.ForceOff();
}
if ((Object)(object)_suppressedSlope != (Object)null)
{
_suppressedSlope.ForceOff();
}
_groundSuppressed = true;
_groundTimer = groundSnapSuppressTime;
}
}
private static void TickGroundSuppression()
{
if (_groundSuppressed)
{
_groundTimer -= Time.fixedDeltaTime;
if (_groundTimer <= 0f)
{
EndGroundSuppression();
}
}
}
private static void EndGroundSuppression()
{
if (_groundSuppressed)
{
if ((Object)(object)_suppressedGc != (Object)null)
{
_suppressedGc.StopForceOff();
}
if ((Object)(object)_suppressedSlope != (Object)null)
{
_suppressedSlope.StopForceOff();
}
_suppressedGc = null;
_suppressedSlope = null;
_groundSuppressed = false;
}
}
private static void ForceDetach(HookArm hook)
{
_active = false;
hook.StopThrow(0f, false);
}
private static void ResetLatchState()
{
_active = false;
_phase = Phase.Idle;
_tipTracking = false;
_graceFrames = 0;
_storedReleaseSpeed = 0f;
_hookedCollider = null;
_trackCollider = false;
if ((Object)(object)_anchor != (Object)null && _anchor.activeSelf)
{
_anchor.SetActive(false);
}
}
internal static void Cleanup()
{
EndGroundSuppression();
if ((Object)(object)_anchor != (Object)null)
{
Object.Destroy((Object)(object)_anchor);
}
_anchor = null;
_anchorCollider = null;
_playerCollider = null;
_active = false;
_phase = Phase.Idle;
_jumpSuppressed = false;
_tipTracking = false;
_graceFrames = 0;
_trackCollider = false;
_hookedCollider = null;
_playerReleaseRequested = false;
SelfColliders.Clear();
_selfCollidersBuilt = false;
}
private static Transform GetAnchor()
{
//IL_0012: 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_0023: Expected O, but got Unknown
if ((Object)(object)_anchor == (Object)null)
{
_anchor = new GameObject("UltraHookAnchor")
{
layer = 2
};
Object.DontDestroyOnLoad((Object)(object)_anchor);
_anchorCollider = _anchor.AddComponent<SphereCollider>();
_anchorCollider.radius = 0.1f;
((Collider)_anchorCollider).isTrigger = true;
_anchor.SetActive(false);
}
return _anchor.transform;
}
private static int DetectionMask(HookArm hook)
{
return (UltraHookConfig.HookableMask | ((LayerMask)(ref EnviroMaskRef.Invoke(hook))).value | 0x4000000) & ~UltraHookConfig.UnhookableMask & -5;
}
private static bool IsHookableHit(Collider collider)
{
if ((Object)(object)collider == (Object)null || !collider.enabled || collider.isTrigger)
{
return false;
}
if ((Object)(object)collider == (Object)(object)_anchorCollider || IsSelf(collider))
{
return false;
}
return true;
}
private static bool IsSelf(Collider collider)
{
if ((Object)(object)collider == (Object)null)
{
return false;
}
EnsureSelfColliders();
if (SelfColliders.Contains(collider))
{
return true;
}
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if ((Object)(object)instance != (Object)null && (Object)(object)collider.attachedRigidbody != (Object)null)
{
return (Object)(object)collider.attachedRigidbody == (Object)(object)instance.rb;
}
return false;
}
private static void EnsureSelfColliders()
{
if (_selfCollidersBuilt)
{
return;
}
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
SelfColliders.Clear();
Collider[] componentsInChildren = ((Component)instance).GetComponentsInChildren<Collider>(true);
foreach (Collider item in componentsInChildren)
{
SelfColliders.Add(item);
}
HookArm instance2 = MonoSingleton<HookArm>.Instance;
if ((Object)(object)instance2 != (Object)null)
{
componentsInChildren = ((Component)instance2).GetComponentsInChildren<Collider>(true);
foreach (Collider item2 in componentsInChildren)
{
SelfColliders.Add(item2);
}
}
_selfCollidersBuilt = true;
}
private static bool ColliderUsable(Collider collider)
{
if ((Object)(object)collider != (Object)null && collider.enabled)
{
return ((Component)collider).gameObject.activeInHierarchy;
}
return false;
}
private static void SetPhase(Phase next, string reason)
{
if (_phase != next)
{
if (UltraHookConfig.DebugLogging)
{
Plugin.Log.LogInfo((object)($"UltraHook phase: {_phase} -> {next} ({reason}) swing={UltraHookConfig.SwingMode} " + $"anchorActive={AnchorActive} rope={_currentRopeLength:0.00} min={ResolvedMinRopeLength():0.00} grace={_graceFrames}"));
}
_phase = next;
}
}
private static float ResolvedMinRopeLength()
{
float num = PlayerRadius();
return Mathf.Max(UltraHookConfig.MinRopeLength, num + 0.3f);
}
private static float PlayerRadius()
{
if ((Object)(object)_playerCollider == (Object)null)
{
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if ((Object)(object)instance != (Object)null)
{
_playerCollider = ((Component)instance).GetComponent<CapsuleCollider>();
}
}
if (!((Object)(object)_playerCollider != (Object)null))
{
return 0.5f;
}
return _playerCollider.radius;
}
private static int Count(FieldInfo listField, HookArm hook)
{
if (!(listField.GetValue(hook) is ICollection collection))
{
return 0;
}
return collection.Count;
}
private static void LogImpact(Collider collider, Vector3 point, Vector3 normal, float distance, Vector3 travelDir, Vector3 from, Vector3 to)
{
//IL_0000: 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_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
float num = Vector3.Dot(-travelDir, normal);
string text = (((Object)(object)collider != (Object)null) ? $"{LayerMask.LayerToName(((Component)collider).gameObject.layer)}({((Component)collider).gameObject.layer})" : "none");
Plugin.Log.LogInfo((object)($"UltraHook tip impact: collider={((collider != null) ? ((Object)collider).name : null)} layer={text} point={point} normal={normal} dist={distance:0.00} " + $"impactDot={num:0.00} sweepHits={_diagSweepCount} rayHits={_diagRayCount} segment={Vector3.Distance(from, to):0.00}"));
}
}
[HarmonyPatch(typeof(HookArm))]
internal static class HookArmPatches
{
private static bool _errorLogged;
[HarmonyPrefix]
[HarmonyPatch("FixedUpdate")]
private static bool FixedUpdatePrefix(HookArm __instance)
{
try
{
return GrappleHook.OnFixedUpdatePre(__instance);
}
catch (Exception arg)
{
LogOnce($"UltraHook detection/tracking failed and is now inert for this session: {arg}");
return true;
}
}
[HarmonyPostfix]
[HarmonyPatch("FixedUpdate")]
private static void FixedUpdatePostfix(HookArm __instance)
{
try
{
GrappleHook.OnFixedUpdatePost(__instance);
}
catch (Exception arg)
{
LogOnce($"UltraHook pull update failed and is now inert for this session: {arg}");
}
}
[HarmonyPrefix]
[HarmonyPatch("Update")]
private static void UpdatePrefix(HookArm __instance)
{
try
{
GrappleHook.SuppressJumpCancel(__instance);
}
catch (Exception arg)
{
LogOnce($"UltraHook jump-suppress failed and is now inert for this session: {arg}");
}
}
[HarmonyFinalizer]
[HarmonyPatch("Update")]
private static void UpdateFinalizer(HookArm __instance)
{
GrappleHook.RestoreJumpCancel(__instance);
}
[HarmonyPostfix]
[HarmonyPatch("GetTotalLineDistance")]
private static void GetTotalLineDistancePostfix(ref float __result)
{
try
{
GrappleHook.ScaleLineDistance(ref __result);
}
catch (Exception arg)
{
LogOnce($"UltraHook max-distance failed and is now inert for this session: {arg}");
}
}
[HarmonyPostfix]
[HarmonyPatch("StopThrow")]
private static void StopThrowPostfix()
{
try
{
GrappleHook.OnRelease();
}
catch (Exception arg)
{
LogOnce($"UltraHook release failed and is now inert for this session: {arg}");
}
}
[HarmonyPostfix]
[HarmonyPatch("Cancel")]
private static void CancelPostfix()
{
try
{
GrappleHook.OnRelease();
}
catch (Exception arg)
{
LogOnce($"UltraHook release failed and is now inert for this session: {arg}");
}
}
private static void LogOnce(string message)
{
if (!_errorLogged)
{
_errorLogged = true;
Plugin.Log.LogError((object)message);
}
}
}
[BepInPlugin("ultrahook.kiyroprower.ultrakill", "UltraHook", "1.3.4")]
[BepInProcess("ULTRAKILL.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "ultrahook.kiyroprower.ultrakill";
public const string PluginConfiguratorGuid = "com.eternalUnion.pluginConfigurator";
internal static ManualLogSource Log;
private Harmony _harmony;
private void Awake()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
UltraHookConfig.Initialize(((BaseUnityPlugin)this).Logger);
_harmony = new Harmony("ultrahook.kiyroprower.ultrakill");
_harmony.PatchAll(typeof(HookArmPatches));
Log.LogInfo((object)("UltraHook loaded (ultrahook.kiyroprower.ultrakill). Wall latching " + (UltraHookConfig.Enabled ? "enabled" : "disabled") + ", swing mode " + (UltraHookConfig.SwingMode ? "on" : "off") + "."));
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
GrappleHook.Cleanup();
}
}
internal static class UltraHookConfig
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static PostBoolValueChangeEvent <>9__107_0;
internal void <CreateMenu>b__107_0(bool _)
{
UpdateMomentumVisibility();
}
}
public const float VanillaMaxHookDistance = 300f;
public const float DefaultSphereCastRadius = 0.12f;
public const float DefaultSurfaceOffset = 0.5f;
public const float DefaultMinRopeLength = 2.5f;
public const float DefaultReelSpeed = 40f;
public const float DefaultMinPullSpeed = 25f;
public const float DefaultMaxPullSpeed = 90f;
public const float DefaultPullAcceleration = 220f;
public const float DefaultPullSpeedGain = 8f;
public const float DefaultTautTolerance = 0.5f;
public const float DefaultTautCorrectionGain = 10f;
public const float DefaultTautAcceleration = 60f;
public const float DefaultMaxInwardCorrectionSpeed = 20f;
public const float DefaultMaxOutwardCorrectionSpeed = 30f;
public const float DefaultMaxAngularSpeed = 6f;
public const float DefaultTangentialDamping = 1.5f;
public const float DefaultMaxMomentumBonus = 60f;
public const float DefaultMaxReleaseSpeed = 150f;
public const float DefaultDirectionFilterSpeed = 12f;
public const float DefaultGroundSnapSuppressTime = 0.08f;
private static PluginConfigurator _configurator;
private static ManualLogSource _log;
private static BoolField _enabledField;
private static BoolField _swingModeField;
private static BoolField _momentumField;
private static StringField _maxHookDistanceField;
private static FloatSliderField _sphereCastRadiusField;
private static FloatSliderField _surfaceOffsetField;
private static BoolField _backfaceField;
private static StringField _extraHookableLayersField;
private static StringField _unhookableLayersField;
private static FloatSliderField _minRopeLengthField;
private static FloatSliderField _reelSpeedField;
private static FloatSliderField _minPullSpeedField;
private static FloatSliderField _maxPullSpeedField;
private static FloatSliderField _pullAccelerationField;
private static FloatSliderField _pullSpeedGainField;
private static FloatSliderField _tautToleranceField;
private static FloatSliderField _tautCorrectionGainField;
private static FloatSliderField _tautAccelerationField;
private static FloatSliderField _maxInwardCorrectionField;
private static FloatSliderField _maxOutwardCorrectionField;
private static FloatSliderField _maxAngularSpeedField;
private static FloatSliderField _tangentialDampingField;
private static FloatSliderField _maxMomentumBonusField;
private static FloatSliderField _maxReleaseSpeedField;
private static FloatSliderField _directionFilterSpeedField;
private static FloatSliderField _groundSnapSuppressField;
private static BoolField _debugLoggingField;
private static ConfigHeader _momentumBonusDescription;
private static ConfigHeader _releaseSpeedDescription;
private static ConfigHeader _directionFilterDescription;
private static readonly Color TitleColor = new Color(1f, 0.62f, 0.16f);
private static readonly Color EnabledColor = new Color(0.56f, 0.86f, 0.56f);
private static readonly Color SwingColor = new Color(0.45f, 0.8f, 1f);
private static readonly Color MomentumColor = new Color(1f, 0.8f, 0.35f);
public static bool Enabled
{
get
{
if (_enabledField != null)
{
return _enabledField.value;
}
return true;
}
}
public static bool SwingMode
{
get
{
if (_swingModeField != null)
{
return _swingModeField.value;
}
return false;
}
}
public static bool Momentum
{
get
{
if (_momentumField != null)
{
return _momentumField.value;
}
return true;
}
}
public static bool BackfaceCompatibility
{
get
{
if (_backfaceField != null)
{
return _backfaceField.value;
}
return false;
}
}
public static bool DebugLogging
{
get
{
if (_debugLoggingField != null)
{
return _debugLoggingField.value;
}
return false;
}
}
public static float SphereCastRadius => Slider(_sphereCastRadiusField, 0.12f, 0.01f);
public static float SurfaceOffset => Slider(_surfaceOffsetField, 0.5f, 0.01f);
public static float MinRopeLength => Slider(_minRopeLengthField, 2.5f, 0.5f);
public static float ReelSpeed => Slider(_reelSpeedField, 40f, 0f);
public static float MinPullSpeed => Slider(_minPullSpeedField, 25f, 0f);
public static float MaxPullSpeed => Slider(_maxPullSpeedField, 90f, MinPullSpeed);
public static float PullAcceleration => Slider(_pullAccelerationField, 220f, 1f);
public static float PullSpeedGain => Slider(_pullSpeedGainField, 8f, 0f);
public static float TautTolerance => Slider(_tautToleranceField, 0.5f, 0f);
public static float TautCorrectionGain => Slider(_tautCorrectionGainField, 10f, 0f);
public static float TautAcceleration => Slider(_tautAccelerationField, 60f, 1f);
public static float MaxInwardCorrectionSpeed => Slider(_maxInwardCorrectionField, 20f, 0f);
public static float MaxOutwardCorrectionSpeed => Slider(_maxOutwardCorrectionField, 30f, 0f);
public static float MaxAngularSpeed => Slider(_maxAngularSpeedField, 6f, 0.1f);
public static float TangentialDamping => Slider(_tangentialDampingField, 1.5f, 0f);
public static float MaxMomentumBonus => Slider(_maxMomentumBonusField, 60f, 0f);
public static float MaxReleaseSpeed => Slider(_maxReleaseSpeedField, 150f, 0f);
public static float DirectionFilterSpeed => Slider(_directionFilterSpeedField, 12f, 0.1f);
public static float GroundSnapSuppressTime => Slider(_groundSnapSuppressField, 0.08f, 0f);
public static int HookableMask
{
get
{
//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)
LayerMask val = LayerMaskDefaults.Get((LMD)1);
int value = ((LayerMask)(ref val)).value;
StringField extraHookableLayersField = _extraHookableLayersField;
int num = value | ParseLayers((extraHookableLayersField != null) ? extraHookableLayersField.value : null);
StringField unhookableLayersField = _unhookableLayersField;
return num & ~ParseLayers((unhookableLayersField != null) ? unhookableLayersField.value : null) & -5;
}
}
public static int UnhookableMask
{
get
{
StringField unhookableLayersField = _unhookableLayersField;
return ParseLayers((unhookableLayersField != null) ? unhookableLayersField.value : null);
}
}
public static float MaxHookDistance
{
get
{
if (_maxHookDistanceField == null)
{
return 300f;
}
string text = _maxHookDistanceField.value?.Trim();
if (string.IsNullOrEmpty(text))
{
return 300f;
}
if (text.Equals("inf", StringComparison.OrdinalIgnoreCase) || text.Equals("infinite", StringComparison.OrdinalIgnoreCase))
{
return float.PositiveInfinity;
}
if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !(result > 0f))
{
return 300f;
}
return result;
}
}
public static void Initialize(ManualLogSource log)
{
_log = log;
try
{
CreateMenu();
_log.LogInfo((object)"Config menu initialized.");
}
catch (Exception ex)
{
_log.LogWarning((object)("PluginConfigurator menu could not be initialized: " + ex.GetType().Name + ": " + ex.Message));
}
}
private static void CreateMenu()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_0043: 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_0065: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_00bc: 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_0100: Expected O, but got Unknown
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Expected O, but got Unknown
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
//IL_056e: Unknown result type (might be due to invalid IL or missing references)
//IL_0578: Expected O, but got Unknown
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
if (_configurator != null)
{
return;
}
_configurator = PluginConfigurator.Create("UltraHook", "ultrahook.kiyroprower.ultrakill");
ConfigPanel rootPanel = _configurator.rootPanel;
_enabledField = new BoolField(rootPanel, "Enabled", "ultrahook.enabled", true, true);
AddDescription(rootPanel, "Let the Whiplash grapple onto solid surfaces.", EnabledColor);
_swingModeField = new BoolField(rootPanel, "Swing Mode", "ultrahook.swingMode", false, true);
AddDescription(rootPanel, "On, the hook is a rope you swing on and it stays attached until you press the hook key again. Off, it reels V1 straight to the surface.", SwingColor);
_momentumField = new BoolField(rootPanel, "Momentum", "ultrahook.momentum", true, true);
BoolField momentumField = _momentumField;
object obj = <>c.<>9__107_0;
if (obj == null)
{
PostBoolValueChangeEvent val = delegate
{
UpdateMomentumVisibility();
};
<>c.<>9__107_0 = val;
obj = (object)val;
}
momentumField.postValueChangeEvent += (PostBoolValueChangeEvent)obj;
AddDescription(rootPanel, "Build launch speed as the pull travels. Cancel with the hook key to keep it, ride to the end and it fades.", MomentumColor);
AddTitle(rootPanel, "Detection");
_maxHookDistanceField = new StringField(rootPanel, "Max Hook Distance", "ultrahook.maxHookDistance", 300f.ToString("0", CultureInfo.InvariantCulture), true);
AddDescription(rootPanel, "How far the hook can reach. Default is the vanilla range. Type \"inf\" for unlimited.");
_sphereCastRadiusField = Slider(rootPanel, "Sphere Cast Radius", "ultrahook.sphereRadius", 0.05f, 0.5f, 0.12f, 2);
AddDescription(rootPanel, "Thickness of the travelling hook tip. Larger values catch edges, seams, and shallow angles more easily.");
_surfaceOffsetField = Slider(rootPanel, "Surface Offset", "ultrahook.surfaceOffset", 0.1f, 3f, 0.5f, 2);
AddDescription(rootPanel, "How far off the surface the anchor sits. Lower values pull V1 closer into the surface.");
_backfaceField = new BoolField(rootPanel, "Backface Compatibility", "ultrahook.backface", false, true);
AddDescription(rootPanel, "Allow the aim probe to hit the reverse side of one-sided meshes. Enable only if some surfaces refuse to hook.");
_extraHookableLayersField = new StringField(rootPanel, "Extra Hookable Layers", "ultrahook.extraLayers", "", true);
AddDescription(rootPanel, "Advanced. Extra layer numbers to treat as hookable, separated by spaces or commas.");
_unhookableLayersField = new StringField(rootPanel, "Unhookable Layers", "ultrahook.unhookableLayers", "", true);
AddDescription(rootPanel, "Advanced. Layer numbers to never hook, separated by spaces or commas.");
AddTitle(rootPanel, "Pull");
_minRopeLengthField = Slider(rootPanel, "Minimum Rope Length", "ultrahook.minRope", 1f, 10f, 2.5f, 1);
AddDescription(rootPanel, "How far from the anchor V1 settles when the rope goes taut. Keeps V1 clear of the surface.");
_reelSpeedField = Slider(rootPanel, "Reel Speed", "ultrahook.reelSpeed", 0f, 150f, 40f, 0);
AddDescription(rootPanel, "How fast the virtual rope shortens toward its minimum length.");
_minPullSpeedField = Slider(rootPanel, "Minimum Pull Speed", "ultrahook.minPull", 0f, 120f, 25f, 0);
AddDescription(rootPanel, "Slowest speed V1 is drawn toward the anchor at.");
_maxPullSpeedField = Slider(rootPanel, "Maximum Pull Speed", "ultrahook.maxPull", 10f, 250f, 90f, 0);
AddDescription(rootPanel, "Fastest speed V1 is drawn toward the anchor at.");
_pullAccelerationField = Slider(rootPanel, "Pull Acceleration", "ultrahook.pullAccel", 10f, 1000f, 220f, 0);
AddDescription(rootPanel, "How quickly the pull speed ramps up. Lower feels heavier.");
_pullSpeedGainField = Slider(rootPanel, "Pull Speed Gain", "ultrahook.pullGain", 0f, 40f, 8f, 1);
AddDescription(rootPanel, "How much the pull speeds up when the rope is stretched far past its length.");
AddTitle(rootPanel, "Taut and Swing");
_tautToleranceField = Slider(rootPanel, "Taut Tolerance", "ultrahook.tautTolerance", 0f, 3f, 0.5f, 2);
AddDescription(rootPanel, "How close to the minimum length the rope is before it counts as taut.");
_tautCorrectionGainField = Slider(rootPanel, "Taut Correction Gain", "ultrahook.tautGain", 0f, 40f, 10f, 1);
AddDescription(rootPanel, "How firmly the taut rope holds its length.");
_tautAccelerationField = Slider(rootPanel, "Taut Acceleration", "ultrahook.tautAccel", 5f, 400f, 60f, 0);
AddDescription(rootPanel, "How quickly the taut correction is applied.");
_maxInwardCorrectionField = Slider(rootPanel, "Max Inward Correction Speed", "ultrahook.maxInward", 0f, 120f, 20f, 0);
AddDescription(rootPanel, "Fastest the taut rope pulls V1 back in when it drifts too far out.");
_maxOutwardCorrectionField = Slider(rootPanel, "Max Outward Correction Speed", "ultrahook.maxOutward", 0f, 120f, 30f, 0);
AddDescription(rootPanel, "Fastest the taut rope lets V1 ease back out when it is pushed too close.");
_maxAngularSpeedField = Slider(rootPanel, "Max Angular Speed", "ultrahook.maxAngular", 0.5f, 20f, 6f, 1);
AddDescription(rootPanel, "Caps how fast V1 can swing around the anchor. Prevents runaway orbiting.");
_tangentialDampingField = Slider(rootPanel, "Tangential Damping", "ultrahook.tangentialDamping", 0f, 10f, 1.5f, 2);
AddDescription(rootPanel, "How quickly swinging motion bleeds off. Higher settles the swing sooner.");
AddTitle(rootPanel, "Momentum");
_maxMomentumBonusField = Slider(rootPanel, "Max Momentum Bonus", "ultrahook.maxMomentum", 0f, 200f, 60f, 0);
_momentumBonusDescription = AddDescription(rootPanel, "Extra launch speed a full-length pull can bank for the cancel.");
_maxReleaseSpeedField = Slider(rootPanel, "Max Release Speed", "ultrahook.maxRelease", 0f, 400f, 150f, 0);
_releaseSpeedDescription = AddDescription(rootPanel, "Hard cap on the speed a cancel can fling V1 at.");
_directionFilterSpeedField = Slider(rootPanel, "Direction Filter Speed", "ultrahook.dirFilter", 1f, 60f, 12f, 0);
_directionFilterDescription = AddDescription(rootPanel, "How quickly the release direction tracks the rope. Lower smooths out sudden angle changes.");
UpdateMomentumVisibility();
AddTitle(rootPanel, "Release and Diagnostics");
_groundSnapSuppressField = Slider(rootPanel, "Ground Snap Suppression", "ultrahook.groundSuppress", 0f, 0.3f, 0.08f, 2);
AddDescription(rootPanel, "Seconds after a cancel where ground snapping is held off so the launch is not redirected upward.");
_debugLoggingField = new BoolField(rootPanel, "Debug Logging", "ultrahook.debug", false, true);
AddDescription(rootPanel, "Log failed hook attempts and draw debug lines. For troubleshooting only.");
}
private static void UpdateMomentumVisibility()
{
bool hidden = !Momentum;
SetHidden(_maxMomentumBonusField, _momentumBonusDescription, hidden);
SetHidden(_maxReleaseSpeedField, _releaseSpeedDescription, hidden);
SetHidden(_directionFilterSpeedField, _directionFilterDescription, hidden);
}
private static void SetHidden(FloatSliderField field, ConfigHeader description, bool hidden)
{
if (field != null)
{
((ConfigField)field).hidden = hidden;
}
if (description != null)
{
((ConfigField)description).hidden = hidden;
}
}
private static FloatSliderField Slider(ConfigPanel panel, string name, string guid, float min, float max, float value, int decimals)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
return new FloatSliderField(panel, name, guid, new Tuple<float, float>(min, max), value, decimals, true);
}
private static float Slider(FloatSliderField field, float fallback, float min)
{
if (field != null)
{
return Mathf.Max(field.value, min);
}
return fallback;
}
private static int ParseLayers(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return 0;
}
int num = 0;
string[] array = raw.Split(new char[4] { ' ', ',', ';', '\t' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < array.Length; i++)
{
if (int.TryParse(array[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && result >= 0 && result <= 31)
{
num |= 1 << result;
}
}
return num;
}
private static ConfigHeader AddTitle(ConfigPanel panel, string text)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
return new ConfigHeader(panel, text, 18)
{
textColor = TitleColor
};
}
private static ConfigHeader AddDescription(ConfigPanel panel, string text)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
return AddDescription(panel, text, Color.gray);
}
private static ConfigHeader AddDescription(ConfigPanel panel, string text, Color color)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return new ConfigHeader(panel, text, 14)
{
textColor = color
};
}
}
}