Decompiled source of Spin v1.6.12

Mods/Spin.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using AudioImportLib;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSystem.Collections.Generic;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Grabbables;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.SDK.Modules;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using TimeStopPublic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(TimeStopPublicMod), "Spin", "1.6.12", "Tapochnik", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: InternalsVisibleTo("TimeStopDio")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.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 TimeStopPublic
{
	internal static class TimeStopPublicBridge
	{
		public const byte NoTarget = byte.MaxValue;

		public static bool HasForeignActiveTimeStop
		{
			get
			{
				if (TimeStopPublicMod.Instance != null)
				{
					return TimeStopPublicMod.Instance.HasActiveAreaStop;
				}
				return false;
			}
		}

		public static bool HasRunningTimeStop
		{
			get
			{
				if (TimeStopPublicMod.Instance != null)
				{
					return TimeStopPublicMod.Instance.HasRunningAreaStop;
				}
				return false;
			}
		}

		public static void SetMassSpinTargetGlow(GameObject root, NetworkEntity entity, bool active)
		{
			TimeStopPublicMod.Instance?.SetMassSpinTargetGlow(root, active);
			if (entity != null && entity.IsRegistered)
			{
				Send(new TimeStopPublicData
				{
					Action = TimeStopPublicAction.MassSpinTargetGlow,
					Radius = (int)entity.ID,
					Duration = (active ? 3f : 0f),
					TargetPlayer = byte.MaxValue
				});
			}
		}

		public static void SetMassSpinHandGlow(bool active)
		{
			TimeStopPublicMod.Instance?.SetMassSpinHandGlow(PlayerIDManager.LocalSmallID, active);
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.MassSpinHandGlow,
				Duration = (active ? 3f : 0f),
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SetNaosuGlow(GameObject root, NetworkEntity entity, bool left, bool active)
		{
			TimeStopPublicMod.Instance?.SetNaosuGlow(PlayerIDManager.LocalSmallID, root, left, active);
			if (entity != null && entity.IsRegistered)
			{
				Send(new TimeStopPublicData
				{
					Action = TimeStopPublicAction.NaosuGlow,
					Radius = (int)entity.ID,
					TargetPlayer = (left ? ((byte)1) : ((byte)0)),
					Duration = (active ? 3f : 0f)
				});
			}
		}

		public static void SendPrivateAbilityCue(Vector3 position, byte cue, bool flash = false)
		{
			//IL_000e: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.PrivateAbilityCue,
				Center = position,
				TargetPlayer = cue,
				Radius = (flash ? 1f : 0f)
			});
		}

		public static void SendPrivateAfterimage(Vector3 position)
		{
			//IL_000e: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.PrivateAfterimage,
				Center = position,
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SendPlayerImpulse(byte targetPlayer, Vector3 velocity, bool replaceVelocity = true)
		{
			//IL_0015: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.PrivatePlayerImpulse,
				TargetPlayer = targetPlayer,
				Center = velocity,
				Duration = (replaceVelocity ? 1f : 0f)
			});
		}

		public static void PlayAndBroadcastImpactFlash(Vector3 position)
		{
			//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)
			TimeStopPublicMod.Instance?.SpawnCodeImpactFlash(position);
			SendPrivateAbilityCue(position, 4);
		}

		public static void RegisterPrivateAbilityOwner()
		{
			TimeStopPublicMod.RegisterPrivateAbilityOwner();
		}

		public static void SetPrivateOwnerTimeStopped(bool stopped)
		{
			TimeStopPublicMod.SetPrivateOwnerTimeStopped(stopped);
		}

		public static void SendOrbitPropDetach(ushort entityId)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.OrbitPropDetach,
				Radius = (int)entityId,
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SendAreaStart(Vector3 center, float radius, float waveTravelDuration)
		{
			//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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.StartArea,
				Center = center,
				Radius = radius,
				MoveDuration = waveTravelDuration,
				TargetPlayer = byte.MaxValue
			});
		}

		public static void ShowLocalWave(Vector3 center, float radius, float waveTravelDuration)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			TimeStopPublicMod.Instance?.SpawnRadiusWave(center, radius, Player.Head, waveTravelDuration, waveTravelDuration);
		}

		public static void SendTargetStart(byte targetPlayer)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.StartTarget,
				TargetPlayer = targetPlayer
			});
		}

		public static void SendEnd()
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.End,
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SendDodge(byte targetPlayer, float freezeDuration, float moveDuration)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.Dodge,
				TargetPlayer = targetPlayer,
				Duration = freezeDuration,
				MoveDuration = moveDuration
			});
		}

		public static void SendCounterGhost(byte targetPlayer, float duration)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.CounterGhost,
				TargetPlayer = targetPlayer,
				Duration = duration
			});
		}

		public static void SendCounterVanish(float duration)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.CounterVanish,
				TargetPlayer = byte.MaxValue,
				Duration = duration
			});
		}

		private static void Send(TimeStopPublicData data)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (TimeStopPublicMod.PrivateAbilityOwner && NetworkInfo.HasServer)
			{
				MessageRelay.RelayModule<TimeStopPublicMessage, TimeStopPublicData>(data, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		public static void SendSuperPunch(byte target, Vector3 direction, float freezeDuration, float launchSpeed)
		{
			//IL_0014: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SuperPunch,
				TargetPlayer = target,
				Center = direction,
				Duration = freezeDuration,
				Radius = launchSpeed
			});
		}

		public static void SendSuperPunchGlow(bool active)
		{
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SuperPunchGlow,
				TargetPlayer = byte.MaxValue,
				Duration = (active ? 1f : 0f)
			});
		}

		public static void SendPrivateStopCue(Vector3 position)
		{
			//IL_000e: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.PrivateStopCue,
				Center = position,
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SendPrivateResumeCue(Vector3 position, bool useZero)
		{
			//IL_000e: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.PrivateResumeCue,
				Center = position,
				TargetPlayer = byte.MaxValue,
				Duration = (useZero ? 1f : 0f)
			});
		}

		public static void SendSpinPlayerStart(byte targetPlayer, Vector3 handPosition)
		{
			//IL_0015: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SpinPlayerStart,
				TargetPlayer = targetPlayer,
				Center = handPosition,
				Duration = 16f
			});
		}

		public static void SendSpinPlayerUpdate(byte targetPlayer, Vector3 handPosition)
		{
			//IL_0015: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SpinPlayerUpdate,
				TargetPlayer = targetPlayer,
				Center = handPosition
			});
		}

		public static void SendSpinPlayerEnd(byte targetPlayer, Vector3 launchVelocity)
		{
			//IL_0015: 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)
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SpinPlayerEnd,
				TargetPlayer = targetPlayer,
				Center = launchVelocity
			});
		}

		public static void SetSpinGlow(bool active)
		{
			TimeStopPublicMod.Instance?.SetLocalSpinGlow(active);
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SpinGlow,
				TargetPlayer = byte.MaxValue,
				Duration = (active ? 1f : 0f)
			});
		}

		public static void PlayAndBroadcastSpinStart(Vector3 position, bool leftHand = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			PlayAndBroadcastSpinCue(TimeStopPublicAction.SpinStartCue, position, null, leftHand);
		}

		public static void PlayAndBroadcastSpinFlying(Rigidbody body)
		{
			//IL_0013: 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)
			PlayAndBroadcastSpinCue(TimeStopPublicAction.SpinFlyingCue, ((Object)(object)body != (Object)null) ? body.worldCenterOfMass : Vector3.zero, body);
		}

		public static void PlayAndBroadcastSpinHoming(Rigidbody body, bool leftHand = false)
		{
			//IL_0013: 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)
			PlayAndBroadcastSpinCue(TimeStopPublicAction.SpinHomingCue, ((Object)(object)body != (Object)null) ? body.worldCenterOfMass : Vector3.zero, body, leftHand);
		}

		private static void PlayAndBroadcastSpinCue(TimeStopPublicAction action, Vector3 position, Rigidbody body, bool leftHand = false)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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)
			object obj;
			if (!leftHand)
			{
				Hand rightHand = Player.RightHand;
				obj = ((rightHand != null) ? ((Component)rightHand).transform : null);
			}
			else
			{
				Hand leftHand2 = Player.LeftHand;
				obj = ((leftHand2 != null) ? ((Component)leftHand2).transform : null);
			}
			Transform val = (Transform)obj;
			Transform val2 = (((Object)(object)body != (Object)null) ? ((Component)body).transform : null);
			if (action == TimeStopPublicAction.SpinStartCue && (Object)(object)val != (Object)null)
			{
				val2 = val;
			}
			TimeStopPublicMod.Instance?.PlaySpinCue(action, position, val2);
			if (action == TimeStopPublicAction.SpinHomingCue && (Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)val2)
			{
				TimeStopPublicMod.Instance?.PlaySpinCue(action, val.position, val);
			}
			SendPublicSpin(new TimeStopPublicData
			{
				Action = action,
				Center = position,
				MoveDuration = (leftHand ? 1f : 0f),
				TargetPlayer = byte.MaxValue
			});
		}

		public static void SendSpinImpactLift(byte targetPlayer, float height, Vector3 direction)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			SendPublicSpin(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.SpinImpactLift,
				TargetPlayer = targetPlayer,
				Radius = height,
				Center = direction
			});
		}

		private static void SendPublicSpin(TimeStopPublicData data)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkInfo.HasServer && (data.Action == TimeStopPublicAction.SpinImpactLift || data.Action == TimeStopPublicAction.SpinStartCue || data.Action == TimeStopPublicAction.SpinFlyingCue || data.Action == TimeStopPublicAction.SpinHomingCue))
			{
				MessageRelay.RelayModule<TimeStopPublicMessage, TimeStopPublicData>(data, CommonMessageRoutes.ReliableToOtherClients);
			}
		}

		public static void SendDodgeAttackerClone(byte attackerPlayer, Vector3 targetHeadPosition)
		{
			//IL_000c: 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)
			TimeStopPublicMod.Instance?.SpawnDodgeAttackerClone(attackerPlayer, targetHeadPosition);
			Send(new TimeStopPublicData
			{
				Action = TimeStopPublicAction.DodgeAttackerClone,
				TargetPlayer = attackerPlayer,
				Center = targetHeadPosition
			});
		}
	}
	public sealed class TimeStopPublicMod : MelonMod
	{
		private sealed class MassSpinHighlight
		{
			public GameObject Root;

			public GameObject Light;

			public float ExpiresAt;

			public readonly List<Renderer> Renderers = new List<Renderer>();

			public readonly List<MaterialPropertyBlock> OriginalBlocks = new List<MaterialPropertyBlock>();
		}

		private sealed class MassSpinHandHighlight
		{
			public GameObject Glow;

			public float ExpiresAt;
		}

		private sealed class NaosuHighlight
		{
			public GameObject Root;

			public GameObject Light;

			public readonly List<Renderer> Renderers = new List<Renderer>();

			public readonly List<MaterialPropertyBlock> Originals = new List<MaterialPropertyBlock>();
		}

		private sealed class NaosuPresentation
		{
			public float ExpiresAt;

			public bool Left;

			public NaosuHighlight Prop;

			public NaosuHighlight Hand;

			public GameObject Halo;

			public Material HaloMaterial;
		}

		private sealed class BodyState
		{
			public Rigidbody Body;

			public bool Kinematic;

			public RigidbodyConstraints Constraints;

			public Vector3 Velocity;

			public Vector3 AngularVelocity;
		}

		private sealed class AnimatorState
		{
			public Animator Animator;

			public float Speed;
		}

		private sealed class RemoteStop
		{
			public TimeStopPublicAction Action;

			public Vector3 Center;

			public float Radius;

			public byte Target;

			public float EndsAt;

			public float FreezeLocalAt;

			public float StartedAt;

			public float WaveOutDuration;

			public byte Initiator;
		}

		private sealed class ScheduledSuperPunch
		{
			public float ExecuteAt;

			public float CollisionRestoreAt;

			public Vector3 Direction;

			public float Speed;

			public byte Attacker;

			public readonly List<CollisionPair> GhostPairs = new List<CollisionPair>();
		}

		private sealed class CollisionPair
		{
			public Collider Local;

			public Collider Remote;
		}

		private sealed class TimedCollisionRestore
		{
			public CollisionPair Pair;

			public float RestoreAt;
		}

		private sealed class LocalSpinState
		{
			public byte Attacker;

			public Vector3 HandCenter;

			public Vector3 PlayerOffset;

			public float SafetyEndsAt;

			public float ReleasedAt;

			public float ContactAt = -1f;

			public bool Released;

			public bool HasContact;

			public BodyState OriginalBodyState;

			public readonly List<SpinRagdollContactRelay> ContactRelays = new List<SpinRagdollContactRelay>();

			public readonly List<BodyState> Bodies = new List<BodyState>();

			public readonly List<AnimatorState> Animators = new List<AnimatorState>();
		}

		private enum PublicSpinTargetKind
		{
			Prop,
			Npc
		}

		private sealed class PublicSpinBodyState
		{
			public Rigidbody Body;

			public bool OriginalKinematic;

			public RigidbodyConstraints OriginalConstraints;

			public Vector3 Velocity;

			public Vector3 AngularVelocity;

			public float OriginalMaxAngularVelocity;
		}

		private sealed class PublicSpinReturnState
		{
			public GameObject Root;

			public GameObject GrabObject;

			public Rigidbody Body;

			public float ReturnAt;

			public float ExpiresAt;

			public bool Homing;

			public bool OriginalUseGravity;

			public float OriginalDrag;

			public float NextPropCollisionScan;

			public float NextDetachAt;

			public bool RequireGrabRelease;

			public Collider[] ReturningColliders;

			public readonly List<CollisionPair> IgnoredPropCollisions = new List<CollisionPair>();

			public readonly HashSet<ulong> IgnoredPropCollisionKeys = new HashSet<ulong>();
		}

		private readonly Dictionary<int, MassSpinHighlight> _massSpinHighlights = new Dictionary<int, MassSpinHighlight>();

		private readonly Dictionary<byte, MassSpinHandHighlight> _massSpinHandHighlights = new Dictionary<byte, MassSpinHandHighlight>();

		private float _nextMassSpinGlowCleanup;

		private readonly Dictionary<byte, NaosuPresentation> _naosuGlows = new Dictionary<byte, NaosuPresentation>();

		private readonly List<byte> _expiredNaosuGlows = new List<byte>();

		private AudioClip _compatCounterSound;

		private AudioClip _compatDashSound;

		private Vector3 _pendingPrivateVelocity;

		private Vector3 _pendingPrivateDelta;

		private bool _hasPendingPrivateVelocity;

		private static bool _privateAbilityOwner;

		private static bool _privateOwnerTimeStopped;

		private readonly Dictionary<byte, RemoteStop> _stops = new Dictionary<byte, RemoteStop>();

		private readonly HashSet<byte> _authenticatedControllerSenders = new HashSet<byte>();

		private readonly Dictionary<int, BodyState> _bodies = new Dictionary<int, BodyState>();

		private readonly Dictionary<int, AnimatorState> _animators = new Dictionary<int, AnimatorState>();

		private bool _localPlayerFrozenByStop;

		private Vector3 _localPlayerFreezeAnchor;

		private float _nextScan;

		private GameObject _volumeObject;

		private Volume _volume;

		private const float ForeignAreaGraceDuration = 2f;

		private const float DefaultWaveTravelDuration = 0.5f;

		private const float SuperPunchCollisionGhostDuration = 10f;

		private const float SuperPunchPlayerTeleportDistance = 500f;

		private const float SuperPunchPlayerTeleportDepth = 500f;

		private const float PublicSpinTapWindow = 0.55f;

		private const float PublicSpinAngularAcceleration = 900f;

		private const float PublicSpinPhysicsAngularLimit = 1000000f;

		private const float PublicSpinNpcImpactHeight = 4f;

		private const float PublicSpinPlayerImpactHeight = 1.5f;

		private const float MaximumTimeStopRadius = 99f;

		private const float MaximumSpinSetting = 99f;

		private const float MaximumPublicSpinThrowSpeed = 40f;

		private const float MaximumPublicSpinHomingSpeed = 40f;

		private const float SpinRagdollContactGetUpDelay = 1.5f;

		private ScheduledSuperPunch _scheduledSuperPunch;

		private readonly List<CollisionPair> _ghostPairs = new List<CollisionPair>();

		private readonly List<Grip> _ghostDisabledGrips = new List<Grip>();

		private float _ghostUntil = -1f;

		private readonly List<Renderer> _vanishedRenderers = new List<Renderer>();

		private readonly List<bool> _vanishedRendererStates = new List<bool>();

		private float _vanishUntil = -1f;

		private byte _vanishSender = byte.MaxValue;

		private float _nextVanishRefresh = -1f;

		private readonly Dictionary<byte, GameObject> _remoteSuperPunchGlows = new Dictionary<byte, GameObject>();

		private readonly Dictionary<byte, GameObject> _remoteSpinGlows = new Dictionary<byte, GameObject>();

		private GameObject _localSpinGlow;

		private readonly List<TimedCollisionRestore> _timedSuperPunchCollisions = new List<TimedCollisionRestore>();

		private AudioClip _dodgeSound;

		private AudioClip _privateStopSound;

		private AudioClip _privateResumeTokiSound;

		private AudioClip _privateResumeZeroSound;

		private AudioClip _spinStartSound;

		private AudioClip _spinFlyingSound;

		private AudioClip _spinHomingSound;

		private MelonPreferences_Category _publicPreferences;

		private MelonPreferences_Entry<bool> _publicSpinEnabled;

		private MelonPreferences_Entry<float> _publicSpinArmTimeout;

		private MelonPreferences_Entry<float> _publicSpinHomingDelay;

		private MelonPreferences_Entry<float> _publicSpinHomingSpeed;

		private MelonPreferences_Entry<float> _publicSpinThrowSpeed;

		private MelonPreferences_Entry<float> _publicSpinNpcThrowSpeed;

		private LocalSpinState _localSpin;

		private readonly List<PublicSpinBodyState> _publicSpinBodies = new List<PublicSpinBodyState>();

		private readonly List<AnimatorState> _publicSpinAnimators = new List<AnimatorState>();

		private readonly List<CollisionPair> _publicSpinIgnoredCollisions = new List<CollisionPair>();

		private readonly List<PublicSpinReturnState> _publicSpinReturns = new List<PublicSpinReturnState>();

		private int _publicSpinTapCount;

		private float _lastPublicSpinTap = -10f;

		private bool _publicSpinArmed;

		private float _publicSpinArmedUntil = -1f;

		private bool _publicSpinActive;

		private bool _publicSpinVirtualHold;

		private PublicSpinTargetKind _publicSpinKind;

		private GameObject _publicSpinHeldObject;

		private Transform _publicSpinRoot;

		private Rigidbody _publicSpinPrimaryBody;

		private Vector3 _publicSpinAnchorLocalPosition;

		private float _publicSpinAngularSpeedDegrees;

		private static ulong TrustedControllerPlatformId => 76561197974397983uL;

		internal static TimeStopPublicMod Instance { get; private set; }

		internal static bool PrivateAbilityOwner => _privateAbilityOwner;

		public static bool SuperPunchBypassActive { get; private set; }

		public bool HasActiveAreaStop => HasAreaStop();

		public bool HasRunningAreaStop => HasAreaStop();

		private static Transform ResolveSpinCueHand(byte sender, bool left)
		{
			if (!left)
			{
				return ResolvePlayerHand(sender);
			}
			if (sender == PlayerIDManager.LocalSmallID)
			{
				Hand leftHand = Player.LeftHand;
				if (leftHand == null)
				{
					return null;
				}
				return ((Component)leftHand).transform;
			}
			NetworkPlayer val = default(NetworkPlayer);
			if (!NetworkPlayerManager.TryGetPlayer(sender, ref val) || val == null || !val.HasRig)
			{
				return null;
			}
			Hand leftHand2 = val.RigRefs.LeftHand;
			if (leftHand2 == null)
			{
				return null;
			}
			return ((Component)leftHand2).transform;
		}

		private void ReceiveMassSpinGlow(byte sender, TimeStopPublicData data)
		{
			if (data.Action == TimeStopPublicAction.MassSpinHandGlow)
			{
				SetMassSpinHandGlow(sender, data.Duration > 0f);
			}
			else
			{
				if (float.IsNaN(data.Radius) || data.Radius < 0f || data.Radius > 65535f || data.Radius != Mathf.Floor(data.Radius))
				{
					return;
				}
				NetworkEntity entity = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity((ushort)data.Radius);
				object obj;
				if (entity == null)
				{
					obj = null;
				}
				else
				{
					NetworkProp extender = entity.GetExtender<NetworkProp>();
					if (extender == null)
					{
						obj = null;
					}
					else
					{
						MarrowEntity marrowEntity = extender.MarrowEntity;
						obj = ((marrowEntity != null) ? ((Component)marrowEntity).gameObject : null);
					}
				}
				GameObject val = (GameObject)obj;
				if ((Object)(object)val != (Object)null)
				{
					SetMassSpinTargetGlow(val, data.Duration > 0f);
				}
			}
		}

		internal void SetMassSpinTargetGlow(GameObject root, bool active)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_016c: Expected O, but got Unknown
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)root).GetInstanceID();
			if (_massSpinHighlights.TryGetValue(instanceID, out var value))
			{
				if (active)
				{
					value.ExpiresAt = Time.realtimeSinceStartup + 3f;
					return;
				}
				RestoreMassSpinHighlight(value);
				_massSpinHighlights.Remove(instanceID);
			}
			else
			{
				if (!active)
				{
					return;
				}
				MassSpinHighlight massSpinHighlight = new MassSpinHighlight
				{
					Root = root,
					ExpiresAt = Time.realtimeSinceStartup + 3f
				};
				foreach (Renderer componentsInChild in root.GetComponentsInChildren<Renderer>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null))
					{
						MaterialPropertyBlock val = new MaterialPropertyBlock();
						componentsInChild.GetPropertyBlock(val);
						massSpinHighlight.Renderers.Add(componentsInChild);
						massSpinHighlight.OriginalBlocks.Add(val);
						MaterialPropertyBlock val2 = new MaterialPropertyBlock();
						componentsInChild.GetPropertyBlock(val2);
						val2.SetColor("_BaseColor", new Color(0.65f, 0.12f, 1f, 1f));
						val2.SetColor("_Color", new Color(0.65f, 0.12f, 1f, 1f));
						val2.SetColor("_EmissionColor", new Color(1.3f, 0.2f, 2f, 1f));
						componentsInChild.SetPropertyBlock(val2);
					}
				}
				massSpinHighlight.Light = new GameObject("Private Mass Spin Purple Light");
				massSpinHighlight.Light.transform.SetParent(root.transform, false);
				Light obj = massSpinHighlight.Light.AddComponent<Light>();
				obj.color = new Color(0.65f, 0.12f, 1f);
				obj.range = 1.5f;
				obj.intensity = 2f;
				obj.shadows = (LightShadows)0;
				_massSpinHighlights[instanceID] = massSpinHighlight;
			}
		}

		internal void SetMassSpinHandGlow(byte sender, bool active)
		{
			if (_massSpinHandHighlights.TryGetValue(sender, out var value))
			{
				if (active && (Object)(object)value.Glow != (Object)null)
				{
					value.ExpiresAt = Time.realtimeSinceStartup + 3f;
					return;
				}
				if ((Object)(object)value.Glow != (Object)null)
				{
					Object.Destroy((Object)(object)value.Glow);
				}
				_massSpinHandHighlights.Remove(sender);
			}
			if (active)
			{
				Transform val = ResolveSpinCueHand(sender, left: true);
				if (!((Object)(object)val == (Object)null))
				{
					_massSpinHandHighlights[sender] = new MassSpinHandHighlight
					{
						Glow = CreateHandGlow(val, "Private Mass Spin Left Hand Glow"),
						ExpiresAt = Time.realtimeSinceStartup + 3f
					};
				}
			}
		}

		private static void RestoreMassSpinHighlight(MassSpinHighlight highlight)
		{
			for (int i = 0; i < highlight.Renderers.Count; i++)
			{
				if ((Object)(object)highlight.Renderers[i] != (Object)null)
				{
					highlight.Renderers[i].SetPropertyBlock(highlight.OriginalBlocks[i]);
				}
			}
			if ((Object)(object)highlight.Light != (Object)null)
			{
				Object.Destroy((Object)(object)highlight.Light);
			}
		}

		private void UpdateMassSpinGlows()
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup < _nextMassSpinGlowCleanup || (_massSpinHighlights.Count == 0 && _massSpinHandHighlights.Count == 0))
			{
				return;
			}
			_nextMassSpinGlowCleanup = realtimeSinceStartup + 0.2f;
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, MassSpinHighlight> massSpinHighlight in _massSpinHighlights)
			{
				if ((Object)(object)massSpinHighlight.Value.Root == (Object)null || realtimeSinceStartup >= massSpinHighlight.Value.ExpiresAt)
				{
					list.Add(massSpinHighlight.Key);
				}
			}
			foreach (int item in list)
			{
				RestoreMassSpinHighlight(_massSpinHighlights[item]);
				_massSpinHighlights.Remove(item);
			}
			List<byte> list2 = new List<byte>();
			foreach (KeyValuePair<byte, MassSpinHandHighlight> massSpinHandHighlight in _massSpinHandHighlights)
			{
				if ((Object)(object)massSpinHandHighlight.Value.Glow == (Object)null || realtimeSinceStartup >= massSpinHandHighlight.Value.ExpiresAt)
				{
					list2.Add(massSpinHandHighlight.Key);
				}
			}
			foreach (byte item2 in list2)
			{
				SetMassSpinHandGlow(item2, active: false);
			}
		}

		private void ClearMassSpinGlows()
		{
			foreach (MassSpinHighlight value in _massSpinHighlights.Values)
			{
				RestoreMassSpinHighlight(value);
			}
			_massSpinHighlights.Clear();
			foreach (MassSpinHandHighlight value2 in _massSpinHandHighlights.Values)
			{
				if ((Object)(object)value2.Glow != (Object)null)
				{
					Object.Destroy((Object)(object)value2.Glow);
				}
			}
			_massSpinHandHighlights.Clear();
		}

		private void ReceiveNaosuGlow(byte sender, TimeStopPublicData data)
		{
			if (data.TargetPlayer > 1 || float.IsNaN(data.Radius) || data.Radius < 0f || data.Radius > 65535f || data.Radius != Mathf.Floor(data.Radius))
			{
				return;
			}
			NetworkEntity entity = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity((ushort)data.Radius);
			object obj;
			if (entity == null)
			{
				obj = null;
			}
			else
			{
				NetworkProp extender = entity.GetExtender<NetworkProp>();
				if (extender == null)
				{
					obj = null;
				}
				else
				{
					MarrowEntity marrowEntity = extender.MarrowEntity;
					obj = ((marrowEntity != null) ? ((Component)marrowEntity).gameObject : null);
				}
			}
			GameObject root = (GameObject)obj;
			SetNaosuGlow(sender, root, data.TargetPlayer == 1, data.Duration > 0f);
		}

		internal void SetNaosuGlow(byte sender, GameObject root, bool left, bool active)
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			if (_naosuGlows.TryGetValue(sender, out var value))
			{
				if (active && (Object)(object)value.Prop?.Root == (Object)(object)root && value.Left == left && (Object)(object)value.Hand?.Root != (Object)null)
				{
					value.ExpiresAt = Time.realtimeSinceStartup + 3f;
					return;
				}
				RestoreNaosuHighlight(value.Prop);
				RestoreNaosuHighlight(value.Hand);
				DestroyNaosuHalo(value);
				_naosuGlows.Remove(sender);
			}
			if (!active)
			{
				return;
			}
			Transform val = ResolveSpinCueHand(sender, left);
			NaosuPresentation naosuPresentation = new NaosuPresentation
			{
				Left = left,
				ExpiresAt = Time.realtimeSinceStartup + 3f,
				Prop = CreateNaosuHighlight(root),
				Hand = CreateNaosuHighlight(((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null)
			};
			naosuPresentation.Halo = CreateHandGlow(val, "Naosu Yellow Hand Glow");
			if ((Object)(object)naosuPresentation.Halo != (Object)null)
			{
				Renderer component = naosuPresentation.Halo.GetComponent<Renderer>();
				naosuPresentation.HaloMaterial = ((component != null) ? component.material : null);
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(1f, 0.85f, 0f, 0.52f);
				if ((Object)(object)naosuPresentation.HaloMaterial != (Object)null)
				{
					naosuPresentation.HaloMaterial.color = val2;
					if (naosuPresentation.HaloMaterial.HasProperty("_BaseColor"))
					{
						naosuPresentation.HaloMaterial.SetColor("_BaseColor", val2);
					}
				}
				Light component2 = naosuPresentation.Halo.GetComponent<Light>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.color = Color.yellow;
				}
			}
			_naosuGlows[sender] = naosuPresentation;
		}

		private static NaosuHighlight CreateNaosuHighlight(GameObject root)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			NaosuHighlight naosuHighlight = new NaosuHighlight
			{
				Root = root
			};
			foreach (Renderer componentsInChild in root.GetComponentsInChildren<Renderer>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					MaterialPropertyBlock val = new MaterialPropertyBlock();
					componentsInChild.GetPropertyBlock(val);
					naosuHighlight.Renderers.Add(componentsInChild);
					naosuHighlight.Originals.Add(val);
					MaterialPropertyBlock val2 = new MaterialPropertyBlock();
					componentsInChild.GetPropertyBlock(val2);
					val2.SetColor("_BaseColor", Color.yellow);
					val2.SetColor("_Color", Color.yellow);
					val2.SetColor("_EmissionColor", new Color(3f, 2.5f, 0f, 1f));
					componentsInChild.SetPropertyBlock(val2);
				}
			}
			naosuHighlight.Light = new GameObject("Naosu Yellow Light");
			naosuHighlight.Light.transform.SetParent(root.transform, false);
			Light obj = naosuHighlight.Light.AddComponent<Light>();
			obj.color = Color.yellow;
			obj.range = 0.8f;
			obj.intensity = 2.5f;
			obj.shadows = (LightShadows)0;
			return naosuHighlight;
		}

		private static void RestoreNaosuHighlight(NaosuHighlight state)
		{
			if (state == null)
			{
				return;
			}
			for (int i = 0; i < state.Renderers.Count; i++)
			{
				if ((Object)(object)state.Renderers[i] != (Object)null)
				{
					state.Renderers[i].SetPropertyBlock(state.Originals[i]);
				}
			}
			if ((Object)(object)state.Light != (Object)null)
			{
				Object.Destroy((Object)(object)state.Light);
			}
		}

		private void UpdateNaosuGlows()
		{
			_expiredNaosuGlows.Clear();
			foreach (KeyValuePair<byte, NaosuPresentation> naosuGlow in _naosuGlows)
			{
				if (Time.realtimeSinceStartup >= naosuGlow.Value.ExpiresAt || (Object)(object)naosuGlow.Value.Prop?.Root == (Object)null)
				{
					_expiredNaosuGlows.Add(naosuGlow.Key);
				}
			}
			foreach (byte expiredNaosuGlow in _expiredNaosuGlows)
			{
				SetNaosuGlow(expiredNaosuGlow, null, left: false, active: false);
			}
		}

		private void ClearNaosuGlows()
		{
			foreach (NaosuPresentation value in _naosuGlows.Values)
			{
				RestoreNaosuHighlight(value.Prop);
				RestoreNaosuHighlight(value.Hand);
				DestroyNaosuHalo(value);
			}
			_naosuGlows.Clear();
		}

		private static void DestroyNaosuHalo(NaosuPresentation state)
		{
			if ((Object)(object)state.Halo != (Object)null)
			{
				Object.Destroy((Object)(object)state.Halo);
			}
			if ((Object)(object)state.HaloMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)state.HaloMaterial);
			}
		}

		private void ReceivePrivatePlayerImpulse(TimeStopPublicData data)
		{
			//IL_000f: 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_0015: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (data.TargetPlayer != PlayerIDManager.LocalSmallID)
			{
				return;
			}
			Vector3 center = data.Center;
			if (float.IsFinite(center.x) && float.IsFinite(center.y) && float.IsFinite(center.z))
			{
				if (data.Duration > 0.5f)
				{
					_pendingPrivateVelocity = center;
					_pendingPrivateDelta = Vector3.zero;
					_hasPendingPrivateVelocity = true;
				}
				else
				{
					_pendingPrivateDelta += center;
				}
			}
		}

		private void ApplyPendingPrivatePlayerImpulse()
		{
			//IL_0070: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if ((!_hasPendingPrivateVelocity && ((Vector3)(ref _pendingPrivateDelta)).sqrMagnitude < 0.0001f) || ShouldFreezeLocalPlayer() || (Object)(object)Player.PhysicsRig == (Object)null)
			{
				return;
			}
			bool flag = false;
			foreach (Rigidbody componentsInChild in ((Component)Player.PhysicsRig).GetComponentsInChildren<Rigidbody>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null) && !componentsInChild.isKinematic)
				{
					componentsInChild.velocity = (_hasPendingPrivateVelocity ? _pendingPrivateVelocity : componentsInChild.velocity) + _pendingPrivateDelta;
					componentsInChild.WakeUp();
					flag = true;
				}
			}
			if (flag)
			{
				ClearPendingPrivatePlayerImpulse();
			}
		}

		private void ClearPendingPrivatePlayerImpulse()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_pendingPrivateVelocity = Vector3.zero;
			_pendingPrivateDelta = Vector3.zero;
			_hasPendingPrivateVelocity = false;
		}

		private void ReceivePrivateAbilityCue(byte sender, TimeStopPublicData data)
		{
			//IL_000b: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			if (data.TargetPlayer == 4)
			{
				SpawnCodeImpactFlash(data.Center);
				return;
			}
			if (data.TargetPlayer == 0)
			{
				if ((Object)(object)_compatCounterSound != (Object)null)
				{
					PlaySpatialSound(_compatCounterSound, data.Center, "Counter Sound", 2f, 65f);
				}
				else
				{
					MelonCoroutines.Start(LoadAndPlayLooseSound("counter.wav", delegate(AudioClip clip)
					{
						_compatCounterSound = clip;
					}, data.Center, "Counter Sound", 2f, 65f));
				}
			}
			else if (data.TargetPlayer == 1)
			{
				if ((Object)(object)_compatDashSound != (Object)null)
				{
					PlaySpatialSound(_compatDashSound, data.Center, "Dash Sound", 1.35f, 65f);
				}
				else
				{
					MelonCoroutines.Start(LoadAndPlayLooseSound("dash.wav", delegate(AudioClip clip)
					{
						_compatDashSound = clip;
					}, data.Center, "Dash Sound", 1.35f, 65f));
				}
			}
			else if (data.TargetPlayer == 2)
			{
				foreach (AudioClip item in Resources.FindObjectsOfTypeAll<AudioClip>())
				{
					if (!((Object)(object)item == (Object)null) && !string.IsNullOrEmpty(((Object)item).name))
					{
						string text = ((Object)item).name.ToLowerInvariant();
						if (text.Contains("void") && (text.Contains("projectile") || text.Contains("energy")))
						{
							PlaySpatialSound(item, data.Center, "Void Punch Sound", 1.25f, 65f);
							break;
						}
					}
				}
			}
			if (data.Radius > 0.5f)
			{
				FlashRemotePlayer(sender);
			}
		}

		internal void SpawnCodeImpactFlash(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			MelonCoroutines.Start(CodeImpactFlash(position));
		}

		private static IEnumerator CodeImpactFlash(Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Unlit");
			if ((Object)(object)val == (Object)null)
			{
				yield break;
			}
			GameObject flash = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)flash).name = "Dash Impact Flash";
			flash.transform.position = position;
			Collider component = flash.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				component.enabled = false;
				Object.Destroy((Object)(object)component);
			}
			Material material = new Material(val);
			Renderer component2 = flash.GetComponent<Renderer>();
			component2.sharedMaterial = material;
			component2.shadowCastingMode = (ShadowCastingMode)0;
			component2.receiveShadows = false;
			Light light = flash.AddComponent<Light>();
			light.color = new Color(0.85f, 0.7f, 1f);
			light.range = 2f;
			float started = Time.realtimeSinceStartup;
			try
			{
				Color val2 = default(Color);
				while ((Object)(object)flash != (Object)null && Time.realtimeSinceStartup - started < 0.25f)
				{
					float num = Mathf.Clamp01((Time.realtimeSinceStartup - started) / 0.25f);
					flash.transform.localScale = Vector3.one * Mathf.Lerp(0.12f, 0.7f, num);
					((Color)(ref val2))..ctor(0.85f, 0.7f, 1f, (1f - num) * 0.6f);
					material.color = val2;
					if (material.HasProperty("_BaseColor"))
					{
						material.SetColor("_BaseColor", val2);
					}
					light.intensity = 2f * (1f - num);
					yield return null;
				}
			}
			finally
			{
				if ((Object)(object)flash != (Object)null)
				{
					Object.Destroy((Object)(object)flash);
				}
				if ((Object)(object)material != (Object)null)
				{
					Object.Destroy((Object)(object)material);
				}
			}
		}

		private void SpawnPrivateAfterimage(byte sender, Vector3 headPosition)
		{
			//IL_0273: 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_0053: Expected O, but got Unknown
			//IL_006f: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_0194: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			NetworkPlayer val = default(NetworkPlayer);
			if (!NetworkPlayerManager.TryGetPlayer(sender, ref val) || val == null || !val.HasRig || (Object)(object)val.RigRefs.Head == (Object)null)
			{
				return;
			}
			Shader val2 = Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Sprites/Default");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Material val3 = new Material(val2);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.82f, 0.94f, 1f, 0.68f);
			val3.color = val4;
			if (val3.HasProperty("_BaseColor"))
			{
				val3.SetColor("_BaseColor", val4);
			}
			if (val3.HasProperty("_Surface"))
			{
				val3.SetFloat("_Surface", 1f);
			}
			if (val3.HasProperty("_SrcBlend"))
			{
				val3.SetFloat("_SrcBlend", 5f);
			}
			if (val3.HasProperty("_DstBlend"))
			{
				val3.SetFloat("_DstBlend", 10f);
			}
			if (val3.HasProperty("_ZWrite"))
			{
				val3.SetFloat("_ZWrite", 0f);
			}
			val3.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val3.renderQueue = 3000;
			GameObject val5 = new GameObject("Counter Avatar Afterimage");
			List<Mesh> list = new List<Mesh>();
			try
			{
				foreach (SkinnedMeshRenderer componentsInChild in ((Component)val.RigRefs.RigManager).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null) && !((Object)(object)componentsInChild.sharedMesh == (Object)null))
					{
						Mesh val6 = new Mesh();
						list.Add(val6);
						componentsInChild.BakeMesh(val6, true);
						GameObject val7 = new GameObject("Afterimage Mesh");
						val7.transform.SetParent(val5.transform, false);
						val7.transform.position = headPosition + ((Component)componentsInChild).transform.position - val.RigRefs.Head.position;
						val7.transform.rotation = ((Component)componentsInChild).transform.rotation;
						val7.transform.localScale = ((Component)componentsInChild).transform.lossyScale;
						val7.AddComponent<MeshFilter>().sharedMesh = val6;
						MeshRenderer obj = val7.AddComponent<MeshRenderer>();
						((Renderer)obj).sharedMaterial = val3;
						((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
						((Renderer)obj).receiveShadows = false;
					}
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Afterimage snapshot: " + ex.Message);
			}
			MelonCoroutines.Start(FadePrivateAfterimage(val5, val3, list, val4));
		}

		private static IEnumerator FadePrivateAfterimage(GameObject root, Material material, List<Mesh> meshes, Color tint)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			float started = Time.realtimeSinceStartup;
			try
			{
				while ((Object)(object)root != (Object)null && (Object)(object)material != (Object)null && Time.realtimeSinceStartup - started < 1f)
				{
					float num = 1f - Mathf.Clamp01(Time.realtimeSinceStartup - started);
					tint.a = 0.68f * num * num;
					material.color = tint;
					if (material.HasProperty("_BaseColor"))
					{
						material.SetColor("_BaseColor", tint);
					}
					yield return null;
				}
			}
			finally
			{
				if ((Object)(object)root != (Object)null)
				{
					Object.Destroy((Object)(object)root);
				}
				if ((Object)(object)material != (Object)null)
				{
					Object.Destroy((Object)(object)material);
				}
				foreach (Mesh mesh in meshes)
				{
					if ((Object)(object)mesh != (Object)null)
					{
						Object.Destroy((Object)(object)mesh);
					}
				}
			}
		}

		public override void OnInitializeMelon()
		{
			Instance = this;
			_publicPreferences = MelonPreferences.CreateCategory("PublicSpin");
			_publicSpinEnabled = _publicPreferences.CreateEntry<bool>("Enabled", true, (string)null, "Enable Spin for physical props and NPCs.", false, false, (ValueValidator)null, (string)null);
			_publicSpinArmTimeout = _publicPreferences.CreateEntry<float>("ArmTimeout", 12f, (string)null, "Seconds Spin waits for a right-hand Grab after four B taps.", false, false, (ValueValidator)null, (string)null);
			_publicSpinHomingDelay = _publicPreferences.CreateEntry<float>("HomingDelay", 1f, (string)null, "Seconds after release before held Grab recalls the prop.", false, false, (ValueValidator)null, (string)null);
			_publicSpinHomingSpeed = _publicPreferences.CreateEntry<float>("HomingSpeed", 16f, (string)null, "Maximum Spin homing return speed in metres per second.", false, false, (ValueValidator)null, (string)null);
			_publicSpinHomingSpeed.Value = Mathf.Clamp(_publicSpinHomingSpeed.Value, 2f, 40f);
			_publicSpinThrowSpeed = _publicPreferences.CreateEntry<float>("ThrowSpeed", 10f, (string)null, "Spin prop launch speed in metres per second.", false, false, (ValueValidator)null, (string)null);
			_publicSpinNpcThrowSpeed = _publicPreferences.CreateEntry<float>("NpcThrowSpeed", 8f, (string)null, "Forward launch speed of an NPC released from Spin.", false, false, (ValueValidator)null, (string)null);
			_publicSpinThrowSpeed.Value = Mathf.Clamp(_publicSpinThrowSpeed.Value, 1f, 40f);
			_publicSpinNpcThrowSpeed.Value = Mathf.Clamp(_publicSpinNpcThrowSpeed.Value, 1f, 40f);
			SetupPublicBoneMenu();
			Hooking.OnLevelUnloaded += OnLevelUnloaded;
			MelonCoroutines.Start(LoadLooseSound("dodge.wav", delegate(AudioClip clip)
			{
				_dodgeSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("toki wa ugukidas.wav", delegate(AudioClip clip)
			{
				_privateResumeTokiSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("mytime.wav", delegate(AudioClip clip)
			{
				_privateStopSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("zero.wav", delegate(AudioClip clip)
			{
				_privateResumeZeroSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("start_spin.wav", delegate(AudioClip clip)
			{
				_spinStartSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("flying.wav", delegate(AudioClip clip)
			{
				_spinFlyingSound = clip;
			}));
			MelonCoroutines.Start(LoadLooseSound("modore.wav", delegate(AudioClip clip)
			{
				_spinHomingSound = clip;
			}));
			((MelonBase)this).LoggerInstance.Msg("Spin ready. Four quick right-B presses arm the next right-hand grab.");
		}

		private void SetupPublicBoneMenu()
		{
			//IL_0019: 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_0062: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Spin", new Color(0.95f, 0.72f, 0.12f), 0, true);
			obj.CreateBool("Enabled", Color.yellow, _publicSpinEnabled.Value, (Action<bool>)delegate(bool value)
			{
				_publicSpinEnabled.Value = value;
				if (!value)
				{
					CancelPublicSpin(restoreReturns: true);
				}
				_publicPreferences.SaveToFile(false);
			});
			obj.CreateFloat("Ready timeout", new Color(0.95f, 0.75f, 0.15f), Mathf.Clamp(_publicSpinArmTimeout.Value, 10f, 15f), 0.5f, 10f, 15f, (Action<float>)delegate(float value)
			{
				_publicSpinArmTimeout.Value = Mathf.Clamp(value, 10f, 15f);
				_publicPreferences.SaveToFile(false);
			});
			obj.CreateFloat("Homing delay", new Color(0.95f, 0.55f, 0.1f), Mathf.Clamp(_publicSpinHomingDelay.Value, 0.25f, 10f), 0.25f, 0.25f, 10f, (Action<float>)delegate(float value)
			{
				_publicSpinHomingDelay.Value = Mathf.Clamp(value, 0.25f, 10f);
				_publicPreferences.SaveToFile(false);
			});
			obj.CreateFloat("Homing speed", new Color(0.95f, 0.42f, 0.12f), Mathf.Clamp(_publicSpinHomingSpeed.Value, 2f, 40f), 1f, 2f, 40f, (Action<float>)delegate(float value)
			{
				_publicSpinHomingSpeed.Value = Mathf.Clamp(value, 2f, 40f);
				_publicPreferences.SaveToFile(false);
			});
			obj.CreateFloat("Throw speed", new Color(1f, 0.42f, 0.08f), Mathf.Clamp(_publicSpinThrowSpeed.Value, 1f, 40f), 1f, 1f, 40f, (Action<float>)delegate(float value)
			{
				_publicSpinThrowSpeed.Value = Mathf.Clamp(value, 1f, 40f);
				_publicPreferences.SaveToFile(false);
			});
			obj.CreateFloat("NPC throw speed", new Color(0.5f, 1f, 0.2f), Mathf.Clamp(_publicSpinNpcThrowSpeed.Value, 1f, 40f), 1f, 1f, 40f, (Action<float>)delegate(float value)
			{
				_publicSpinNpcThrowSpeed.Value = Mathf.Clamp(value, 1f, 40f);
				_publicPreferences.SaveToFile(false);
			});
		}

		internal static void RegisterPrivateAbilityOwner()
		{
			_privateAbilityOwner = true;
		}

		internal static void SetPrivateOwnerTimeStopped(bool stopped)
		{
			_privateOwnerTimeStopped = stopped;
		}

		internal void Receive(byte sender, TimeStopPublicData data)
		{
			//IL_0070: 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_024f: 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_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: 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_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0706: Unknown result type (might be due to invalid IL or missing references)
			//IL_070b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b9: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsTrustedController(sender);
			bool flag2 = flag || _authenticatedControllerSenders.Contains(sender);
			if (IsPrivateControllerAction(data.Action) && !flag2)
			{
				return;
			}
			if (data.Action == TimeStopPublicAction.NaosuGlow)
			{
				ReceiveNaosuGlow(sender, data);
				return;
			}
			if (data.Action == TimeStopPublicAction.PrivatePlayerImpulse)
			{
				ReceivePrivatePlayerImpulse(data);
				return;
			}
			if (data.Action == TimeStopPublicAction.PrivateAbilityCue)
			{
				ReceivePrivateAbilityCue(sender, data);
				return;
			}
			if (data.Action == TimeStopPublicAction.PrivateAfterimage)
			{
				SpawnPrivateAfterimage(sender, data.Center);
				return;
			}
			if (data.Action == TimeStopPublicAction.MassSpinTargetGlow || data.Action == TimeStopPublicAction.MassSpinHandGlow)
			{
				if (flag2)
				{
					ReceiveMassSpinGlow(sender, data);
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.OrbitPropDetach)
			{
				if (!flag2 || data.Radius < 0f || data.Radius > 65535f || data.Radius != Mathf.Floor(data.Radius))
				{
					return;
				}
				NetworkEntity entity = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity((ushort)data.Radius);
				NetworkProp val = ((entity != null) ? entity.GetExtender<NetworkProp>() : null);
				if ((Object)(object)((val != null) ? val.MarrowEntity : null) == (Object)null || entity.IsOwnerLocked)
				{
					return;
				}
				{
					foreach (Grip componentsInChild in ((Component)val.MarrowEntity).GetComponentsInChildren<Grip>(true))
					{
						if ((Object)(object)componentsInChild == (Object)null)
						{
							continue;
						}
						List<Hand> list = new List<Hand>();
						Enumerator<Hand> enumerator2 = componentsInChild.attachedHands.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							Hand current2 = enumerator2.Current;
							if ((Object)(object)current2 != (Object)null && (Object)(object)current2.manager == (Object)(object)Player.RigManager)
							{
								list.Add(current2);
							}
						}
						foreach (Hand item in list)
						{
							componentsInChild.ForceDetach(item);
							item.DetachObject();
							GrabHelper.SendObjectDetach(item);
						}
					}
					return;
				}
			}
			if (flag && (data.Action == TimeStopPublicAction.StartArea || data.Action == TimeStopPublicAction.StartTarget))
			{
				_authenticatedControllerSenders.Add(sender);
			}
			if (data.Action == TimeStopPublicAction.ReservedChildRequest || data.Action == TimeStopPublicAction.ReservedChildPrepare || data.Action == TimeStopPublicAction.ReservedChildStart || data.Action == TimeStopPublicAction.ReservedChildDenied)
			{
				return;
			}
			if (data.Action == TimeStopPublicAction.PrivateStopCue)
			{
				PlayPrivateStopCue(ResolvePlayerSoundPosition(sender, data.Center));
				return;
			}
			if (data.Action == TimeStopPublicAction.PrivateResumeCue)
			{
				PlayPrivateResumeCue(ResolvePlayerSoundPosition(sender, data.Center), data.Duration > 0.5f);
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinPlayerStart)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID && _stops.Count == 0)
				{
					BeginLocalSpin(sender, data.Center, data.Duration);
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinPlayerUpdate)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID && _localSpin != null && _localSpin.Attacker == sender)
				{
					_localSpin.HandCenter = data.Center;
					_localSpin.SafetyEndsAt = Time.realtimeSinceStartup + 2f;
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinPlayerEnd)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID && _localSpin != null && _localSpin.Attacker == sender)
				{
					ReleaseLocalSpin(data.Center);
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinGlow)
			{
				SetRemoteSpinGlow(sender, data.Duration > 0f);
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinStartCue || data.Action == TimeStopPublicAction.SpinFlyingCue || data.Action == TimeStopPublicAction.SpinHomingCue)
			{
				object obj2;
				if (data.Action != TimeStopPublicAction.SpinStartCue)
				{
					Rigidbody obj = FindNearestSpinSoundBody(data.Center);
					obj2 = ((obj != null) ? ((Component)obj).transform : null);
				}
				else
				{
					obj2 = ResolveSpinCueHand(sender, data.MoveDuration > 0.5f);
				}
				Transform val2 = (Transform)obj2;
				PlaySpinCue(data.Action, data.Center, val2);
				if (data.Action == TimeStopPublicAction.SpinHomingCue)
				{
					Transform val3 = ResolveSpinCueHand(sender, data.MoveDuration > 0.5f);
					if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val2)
					{
						PlaySpinCue(data.Action, val3.position, val3);
					}
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.SpinImpactLift)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID)
				{
					ApplyLocalSpinImpactLift(Mathf.Min(data.Radius, flag2 ? 99f : 1.5f), data.Center);
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.DodgeAttackerClone)
			{
				SpawnDodgeAttackerClone(data.TargetPlayer, data.Center);
				return;
			}
			if (data.Action == TimeStopPublicAction.SuperPunch)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID)
				{
					RestoreSuperPunchCollisionGhost(_scheduledSuperPunch);
					_scheduledSuperPunch = new ScheduledSuperPunch
					{
						ExecuteAt = Time.realtimeSinceStartup + Mathf.Max(0.05f, data.Duration),
						CollisionRestoreAt = Time.realtimeSinceStartup + 10f,
						Direction = ((((Vector3)(ref data.Center)).sqrMagnitude > 0.01f) ? ((Vector3)(ref data.Center)).normalized : Vector3.forward),
						Speed = Mathf.Max(1f, data.Radius),
						Attacker = sender
					};
					BeginSuperPunchCollisionGhost(_scheduledSuperPunch);
					_stops[253] = new RemoteStop
					{
						Action = TimeStopPublicAction.StartTarget,
						Target = data.TargetPlayer,
						EndsAt = _scheduledSuperPunch.ExecuteAt
					};
					ScanAndFreeze();
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.SuperPunchGlow)
			{
				SetRemoteSuperPunchGlow(sender, data.Duration > 0f);
				return;
			}
			if (data.Action == TimeStopPublicAction.CounterGhost)
			{
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID)
				{
					BeginRemoteCounterGhost(sender, data.Duration);
				}
				return;
			}
			if (data.Action == TimeStopPublicAction.CounterVanish)
			{
				BeginRemoteCounterVanish(sender, data.Duration);
				return;
			}
			switch (data.Action)
			{
			case TimeStopPublicAction.End:
				_stops.Remove(sender);
				if (_vanishSender == sender)
				{
					RestoreRemoteCounterVanish();
				}
				_authenticatedControllerSenders.Remove(sender);
				RestoreAll();
				if (_stops.Count > 0)
				{
					ScanAndFreeze();
				}
				return;
			case TimeStopPublicAction.Dodge:
			{
				FlashRemotePlayer(sender);
				Vector3 position = ResolvePlayerSoundPosition(sender, data.Center);
				if ((Object)(object)_dodgeSound != (Object)null)
				{
					PlaySpatialSound(_dodgeSound, position, "Dodge Sound", 1.15f, 35f);
				}
				else
				{
					MelonCoroutines.Start(LoadAndPlayLooseSound("dodge.wav", delegate(AudioClip clip)
					{
						_dodgeSound = clip;
					}, position, "Dodge Sound", 1.15f, 35f));
				}
				if (data.TargetPlayer == PlayerIDManager.LocalSmallID)
				{
					_stops[sender] = new RemoteStop
					{
						Action = TimeStopPublicAction.StartTarget,
						Target = data.TargetPlayer,
						EndsAt = Time.realtimeSinceStartup + Mathf.Max(0.1f, data.Duration)
					};
					ScanAndFreeze();
				}
				return;
			}
			}
			_stops[sender] = new RemoteStop
			{
				Action = data.Action,
				Center = data.Center,
				Radius = data.Radius,
				Target = data.TargetPlayer,
				EndsAt = ((data.Duration > 0f) ? (Time.realtimeSinceStartup + data.Duration) : (-1f)),
				FreezeLocalAt = ((data.Action == TimeStopPublicAction.StartArea && _privateAbilityOwner) ? (Time.realtimeSinceStartup + 2f) : Time.realtimeSinceStartup),
				StartedAt = Time.realtimeSinceStartup,
				WaveOutDuration = Mathf.Max(0.05f, data.MoveDuration),
				Initiator = sender
			};
			if (data.Action == TimeStopPublicAction.StartArea && data.MoveDuration > 0f)
			{
				SpawnRadiusWave(data.Center, data.Radius, ResolveWaveTarget(sender), data.MoveDuration, data.MoveDuration);
			}
			if (data.Action == TimeStopPublicAction.StartArea || data.Action == TimeStopPublicAction.StartTarget)
			{
				BeginRemoteTimeStopVanish(sender);
			}
			ScanAndFreeze();
		}

		private static bool IsTrustedController(byte sender)
		{
			PlayerID playerID = PlayerIDManager.GetPlayerID(sender);
			if (playerID != null)
			{
				return playerID.PlatformID == TrustedControllerPlatformId;
			}
			return false;
		}

		private static bool IsPrivateControllerAction(TimeStopPublicAction action)
		{
			return action switch
			{
				TimeStopPublicAction.StartArea => true, 
				TimeStopPublicAction.StartTarget => true, 
				TimeStopPublicAction.End => true, 
				TimeStopPublicAction.Dodge => true, 
				TimeStopPublicAction.CounterGhost => true, 
				TimeStopPublicAction.SuperPunch => true, 
				TimeStopPublicAction.CounterVanish => true, 
				TimeStopPublicAction.SuperPunchGlow => true, 
				TimeStopPublicAction.PrivateStopCue => true, 
				TimeStopPublicAction.PrivateResumeCue => true, 
				TimeStopPublicAction.SpinPlayerStart => true, 
				TimeStopPublicAction.SpinPlayerUpdate => true, 
				TimeStopPublicAction.SpinPlayerEnd => true, 
				TimeStopPublicAction.SpinGlow => true, 
				TimeStopPublicAction.DodgeAttackerClone => true, 
				TimeStopPublicAction.OrbitPropDetach => true, 
				TimeStopPublicAction.MassSpinTargetGlow => true, 
				TimeStopPublicAction.MassSpinHandGlow => true, 
				TimeStopPublicAction.PrivateAbilityCue => true, 
				TimeStopPublicAction.PrivateAfterimage => true, 
				TimeStopPublicAction.PrivatePlayerImpulse => true, 
				TimeStopPublicAction.NaosuGlow => true, 
				_ => false, 
			};
		}

		public override void OnUpdate()
		{
			UpdateMassSpinGlows();
			UpdateNaosuGlows();
			HandlePublicSpinInput();
			UpdatePublicSpin();
			UpdatePublicSpinReturns();
			UpdateRemoteCounterGhost();
			UpdateRemoteCounterVanish();
			UpdateLocalSpin();
			UpdateScheduledSuperPunch();
			UpdateTimedSuperPunchCollisions();
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			List<byte> list = null;
			foreach (KeyValuePair<byte, RemoteStop> stop in _stops)
			{
				if (stop.Value.EndsAt > 0f && realtimeSinceStartup >= stop.Value.EndsAt)
				{
					if (list == null)
					{
						list = new List<byte>();
					}
					list.Add(stop.Key);
				}
			}
			if (list != null)
			{
				foreach (byte item in list)
				{
					_stops.Remove(item);
				}
				RestoreAll();
				if (_stops.Count > 0)
				{
					ScanAndFreeze();
				}
			}
			ApplyPendingPrivatePlayerImpulse();
			if (_stops.Count != 0)
			{
				MaintainFrozenBodies();
				MaintainLocalPlayerFreeze();
				if (realtimeSinceStartup >= _nextScan)
				{
					_nextScan = realtimeSinceStartup + 0.2f;
					ScanAndFreeze();
				}
			}
		}

		public override void OnFixedUpdate()
		{
			UpdateActivePublicSpinPhysics();
			UpdatePublicSpinReturnPhysics();
		}

		public override void OnLateUpdate()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00b6: 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_0094: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_0116: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if (!_publicSpinActive || AnyTimeStopRunning() || (Object)(object)Player.RightHand == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)Player.RightHand).transform;
			Vector3 forward = transform.forward;
			Vector3 val;
			if (!(((Vector3)(ref forward)).sqrMagnitude > 0.001f))
			{
				val = Vector3.up;
			}
			else
			{
				forward = transform.forward;
				val = ((Vector3)(ref forward)).normalized;
			}
			Vector3 val2 = val;
			Quaternion val3 = Quaternion.AngleAxis(_publicSpinAngularSpeedDegrees * Time.unscaledDeltaTime, val2);
			if (_publicSpinKind == PublicSpinTargetKind.Prop && (Object)(object)_publicSpinPrimaryBody != (Object)null)
			{
				((Component)_publicSpinPrimaryBody).transform.rotation = val3 * ((Component)_publicSpinPrimaryBody).transform.rotation;
			}
			else
			{
				if (_publicSpinKind != PublicSpinTargetKind.Npc)
				{
					return;
				}
				Vector3 position = transform.position;
				foreach (PublicSpinBodyState publicSpinBody in _publicSpinBodies)
				{
					if (!((Object)(object)publicSpinBody.Body == (Object)null) && !publicSpinBody.Body.isKinematic)
					{
						Transform transform2 = ((Component)publicSpinBody.Body).transform;
						if ((Object)(object)publicSpinBody.Body != (Object)(object)_publicSpinPrimaryBody)
						{
							transform2.position = position + val3 * (transform2.position - position);
						}
						transform2.rotation = val3 * transform2.rotation;
					}
				}
			}
		}

		private bool AnyTimeStopRunning()
		{
			if (!_privateOwnerTimeStopped)
			{
				return HasAreaStop();
			}
			return true;
		}

		private void HandlePublicSpinInput()
		{
			if (_privateAbilityOwner || _publicSpinEnabled == null || !_publicSpinEnabled.Value || !Player.ControllersExist)
			{
				ResetPublicSpinTapSequence();
			}
			else if ((Player.LeftController.GetBButton() && Player.RightController.GetBButton()) || Player.LeftController.GetBButtonDown() || AnyTimeStopRunning())
			{
				ResetPublicSpinTapSequence();
				if (AnyTimeStopRunning())
				{
					CancelPublicSpin(restoreReturns: true);
				}
			}
			else if (Player.RightController.GetBButtonDown())
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				if (realtimeSinceStartup - _lastPublicSpinTap > 0.55f)
				{
					_publicSpinTapCount = 0;
				}
				_lastPublicSpinTap = realtimeSinceStartup;
				_publicSpinTapCount++;
				if (_publicSpinTapCount >= 4)
				{
					ResetPublicSpinTapSequence();
					ArmPublicSpin();
				}
			}
		}

		private void ResetPublicSpinTapSequence()
		{
			_publicSpinTapCount = 0;
			_lastPublicSpinTap = -10f;
		}

		private void ArmPublicSpin()
		{
			if (!_privateAbilityOwner && !AnyTimeStopRunning() && !_publicSpinActive && !((Object)(object)Player.RightHand == (Object)null))
			{
				_publicSpinArmed = true;
				_publicSpinArmedUntil = Time.realtimeSinceStartup + Mathf.Clamp(_publicSpinArmTimeout.Value, 10f, 15f);
				Notify("SPIN READY", "Hold a prop or NPC with right Grab", (NotificationType)0);
				UpdatePublicSpin();
			}
		}

		private void UpdatePublicSpin()
		{
			//IL_0166: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			if (_privateAbilityOwner)
			{
				return;
			}
			if (AnyTimeStopRunning())
			{
				CancelPublicSpin(restoreReturns: true);
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (_publicSpinArmed && realtimeSinceStartup > _publicSpinArmedUntil)
			{
				_publicSpinArmed = false;
				_publicSpinArmedUntil = -1f;
				Notify("Spin expired", "No valid target was grabbed", (NotificationType)1);
			}
			if ((Object)(object)Player.RightHand == (Object)null || (Object)(object)Player.RightController == (Object)null)
			{
				if (_publicSpinActive)
				{
					EndPublicSpin(releasedNormally: false);
				}
				return;
			}
			bool flag = Player.RightController.GetGripForce() >= 0.72f;
			GameObject objectInHand = Player.GetObjectInHand(Player.RightHand);
			if (_publicSpinArmed && !_publicSpinActive && flag && (Object)(object)objectInHand != (Object)null)
			{
				BeginPublicSpin(objectInHand);
			}
			else if (_publicSpinActive)
			{
				bool flag2 = _publicSpinVirtualHold || ((Object)(object)objectInHand != (Object)null && ((Object)(object)_publicSpinHeldObject == (Object)(object)objectInHand || ((Object)(object)objectInHand.transform != (Object)null && (Object)(object)_publicSpinRoot != (Object)null && (objectInHand.transform.IsChildOf(_publicSpinRoot) || _publicSpinRoot.IsChildOf(objectInHand.transform)))));
				if (!flag || !flag2)
				{
					EndPublicSpin(releasedNormally: true);
				}
				else if (_publicSpinVirtualHold && (Object)(object)_publicSpinPrimaryBody != (Object)null && Vector3.Distance(_publicSpinPrimaryBody.position, ((Component)Player.RightHand).transform.TransformPoint(_publicSpinAnchorLocalPosition)) > 0.9f)
				{
					EndPublicSpin(releasedNormally: true);
				}
			}
		}

		private void BeginPublicSpin(GameObject held)
		{
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)held == (Object)null || (Object)(object)Player.RightHand == (Object)null || _publicSpinActive || AnyTimeStopRunning())
			{
				return;
			}
			RigManager componentInParent = held.GetComponentInParent<RigManager>();
			NetworkPlayer val = default(NetworkPlayer);
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)Player.RigManager && NetworkPlayerManager.TryGetPlayer(componentInParent, ref val) && val != null)
			{
				Notify("Spin locked", "Player Spin is owner-only", (NotificationType)1);
				return;
			}
			_publicSpinArmed = false;
			_publicSpinArmedUntil = -1f;
			_publicSpinHeldObject = held;
			PuppetMaster componentInParent2 = held.GetComponentInParent<PuppetMaster>();
			AIBrain componentInParent3 = held.GetComponentInParent<AIBrain>();
			if ((Object)(object)componentInParent2 != (Object)null || (Object)(object)componentInParent3 != (Object)null)
			{
				_publicSpinKind = PublicSpinTargetKind.Npc;
				_publicSpinRoot = (((Object)(object)componentInParent2 != (Object)null) ? ((Component)componentInParent2).transform : ((Component)componentInParent3).transform);
			}
			else
			{
				_publicSpinKind = PublicSpinTargetKind.Prop;
				MarrowEntity componentInParent4 = held.GetComponentInParent<MarrowEntity>();
				_publicSpinRoot = (((Object)(object)componentInParent4 != (Object)null) ? ((Component)componentInParent4).transform : held.transform);
			}
			_publicSpinBodies.Clear();
			_publicSpinAnimators.Clear();
			HashSet<int> hashSet = new HashSet<int>();
			if ((Object)(object)_publicSpinRoot != (Object)null)
			{
				foreach (Rigidbody componentsInChild in ((Component)_publicSpinRoot).GetComponentsInChildren<Rigidbody>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null) && (!((Object)(object)Player.RigManager != (Object)null) || !((Component)componentsInChild).transform.IsChildOf(((Component)Player.RigManager).transform)) && hashSet.Add(((Object)componentsInChild).GetInstanceID()))
					{
						_publicSpinBodies.Add(new PublicSpinBodyState
						{
							Body = componentsInChild,
							OriginalKinematic = componentsInChild.isKinematic,
							OriginalConstraints = componentsInChild.constraints,
							Velocity = (componentsInChild.isKinematic ? Vector3.zero : componentsInChild.velocity),
							AngularVelocity = (componentsInChild.isKinematic ? Vector3.zero : componentsInChild.angularVelocity),
							OriginalMaxAngularVelocity = componentsInChild.maxAngularVelocity
						});
						componentsInChild.maxAngularVelocity = Mathf.Max(componentsInChild.maxAngularVelocity, 1000000f);
					}
				}
				if (_publicSpinKind == PublicSpinTargetKind.Npc)
				{
					foreach (Animator componentsInChild2 in ((Component)_publicSpinRoot).GetComponentsInChildren<Animator>(true))
					{
						if (!((Object)(object)componentsInChild2 == (Object)null))
						{
							_publicSpinAnimators.Add(new AnimatorState
							{
								Animator = componentsInChild2,
								Speed = componentsInChild2.speed
							});
							componentsInChild2.speed = 0f;
						}
					}
				}
			}
			_publicSpinPrimaryBody = held.GetComponentInParent<Rigidbody>();
			if ((Object)(object)_publicSpinPrimaryBody == (Object)null && (Object)(object)_publicSpinRoot != (Object)null)
			{
				_publicSpinPrimaryBody = ((Component)_publicSpinRoot).GetComponentInChildren<Rigidbody>(true);
			}
			_publicSpinAnchorLocalPosition = (((Object)(object)_publicSpinPrimaryBody != (Object)null) ? ((Component)Player.RightHand).transform.InverseTransformPoint(_publicSpinPrimaryBody.position) : Vector3.zero);
			BeginPublicSpinCollisionGhost();
			BeginPublicVirtualSpinHold();
			_publicSpinAngularSpeedDegrees = 0f;
			_publicSpinActive = true;
			TimeStopPublicBridge.PlayAndBroadcastSpinStart(((Component)Player.RightHand).transform.position);
			Notify("SPIN!", _publicSpinKind.ToString(), (NotificationType)3);
		}

		private void UpdateActivePublicSpinPhysics()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0050: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00a2: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_00da: 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_00f3: 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)
			//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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: 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_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: 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_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: 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_0266: 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_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: 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_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			if (!_publicSpinActive || AnyTimeStopRunning() || (Object)(object)Player.RightHand == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)Player.RightHand).transform;
			Vector3 val = transform.forward;
			Vector3 val2;
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f))
			{
				val2 = Vector3.up;
			}
			else
			{
				val = transform.forward;
				val2 = ((Vector3)(ref val)).normalized;
			}
			Vector3 val3 = val2;
			Vector3 position = transform.position;
			Vector3 val4 = transform.TransformPoint(_publicSpinAnchorLocalPosition);
			_publicSpinAngularSpeedDegrees += 900f * Time.fixedDeltaTime;
			float num = _publicSpinAngularSpeedDegrees * ((float)Math.PI / 180f);
			Quaternion val5 = Quaternion.AngleAxis(_publicSpinAngularSpeedDegrees * Time.fixedDeltaTime, val3);
			if (_publicSpinKind == PublicSpinTargetKind.Prop && (Object)(object)_publicSpinPrimaryBody != (Object)null)
			{
				if (!_publicSpinPrimaryBody.isKinematic)
				{
					Vector3 val6 = (((Object)(object)Player.RightController != (Object)null) ? Player.RightController.GetRelativeVelocityInWorld() : Vector3.zero);
					_publicSpinPrimaryBody.velocity = Vector3.ClampMagnitude(val6 + (val4 - _publicSpinPrimaryBody.position) * 14f, 14f);
					_publicSpinPrimaryBody.angularVelocity = val3 * num;
				}
				_publicSpinPrimaryBody.MoveRotation(val5 * _publicSpinPrimaryBody.rotation);
			}
			else
			{
				if (_publicSpinKind != PublicSpinTargetKind.Npc)
				{
					return;
				}
				foreach (PublicSpinBodyState publicSpinBody in _publicSpinBodies)
				{
					Rigidbody body = publicSpinBody.Body;
					if (!((Object)(object)body == (Object)null) && !body.isKinematic)
					{
						if ((Object)(object)body == (Object)(object)_publicSpinPrimaryBody)
						{
							Vector3 val7 = (((Object)(object)Player.RightController != (Object)null) ? Player.RightController.GetRelativeVelocityInWorld() : Vector3.zero);
							body.velocity = Vector3.ClampMagnitude(val7 + (val4 - body.position) * 14f, 14f);
							body.angularVelocity = val3 * num;
							body.MoveRotation(val5 * body.rotation);
							body.WakeUp();
						}
						else
						{
							Vector3 val8 = body.worldCenterOfMass - position;
							val = Vector3.Cross(val3, val8);
							Vector3 normalized = ((Vector3)(ref val)).normalized;
							Vector3 val9 = Vector3.ClampMagnitude((position - body.worldCenterOfMass) * 11f, 9f);
							body.velocity = Vector3.Lerp(body.velocity, val9 + normalized * 7f, 0.72f);
							body.angularVelocity = val3 * num;
							body.MovePosition(position + val5 * (body.position - position));
							body.MoveRotation(val5 * body.rotation);
							body.WakeUp();
						}
					}
				}
			}
		}

		private void EndPublicSpin(bool releasedNormally)
		{
			//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_0047: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: 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_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: 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_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: 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_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			if (!_publicSpinActive)
			{
				RestorePublicSpinCollisionGhost();
				_publicSpinArmed = false;
				_publicSpinArmedUntil = -1f;
				return;
			}
			Vector3 val;
			if (!((Object)(object)Player.RightHand != (Object)null))
			{
				val = Vector3.forward;
			}
			else
			{
				Vector3 forward = ((Component)Player.RightHand).transform.forward;
				val = ((Vector3)(ref forward)).normalized;
			}
			Vector3 val2 = val;
			Vector3 val3 = (((Object)(object)Player.RightController != (Object)null) ? Player.RightController.GetRelativeVelocityInWorld() : Vector3.zero);
			foreach (PublicSpinBodyState publicSpinBody in _publicSpinBodies)
			{
				if (!((Object)(object)publicSpinBody.Body == (Object)null))
				{
					publicSpinBody.Body.isKinematic = publicSpinBody.OriginalKinematic;
					publicSpinBody.Body.constraints = publicSpinBody.OriginalConstraints;
					publicSpinBody.Body.maxAngularVelocity = publicSpinBody.OriginalMaxAngularVelocity;
					if (!releasedNormally && !publicSpinBody.OriginalKinematic)
					{
						publicSpinBody.Body.velocity = publicSpinBody.Velocity;
						publicSpinBody.Body.angularVelocity = publicSpinBody.AngularVelocity;
						publicSpinBody.Body.WakeUp();
					}
				}
			}
			foreach (AnimatorState publicSpinAnimator in _publicSpinAnimators)
			{
				if ((Object)(object)publicSpinAnimator.Animator != (Object)null)
				{
					publicSpinAnimator.Animator.speed = publicSpinAnimator.Speed;
				}
			}
			if (releasedNormally && _publicSpinKind == PublicSpinTargetKind.Npc)
			{
				Vector3 velocity = val2 * Mathf.Clamp(_publicSpinNpcThrowSpeed.Value, 1f, 40f) + Vector3.up * 1.5f;
				float num = _publicSpinAngularSpeedDegrees * ((float)Math.PI / 180f);
				foreach (PublicSpinBodyState publicSpinBody2 in _publicSpinBodies)
				{
					if (!((Object)(object)publicSpinBody2.Body == (Object)null) && !publicSpinBody2.OriginalKinematic)
					{
						publicSpinBody2.Body.velocity = velocity;
						publicSpinBody2.Body.angularVelocity = val2 * num;
						publicSpinBody2.Body.WakeUp();
					}
				}
				TimeStopPublicBridge.PlayAndBroadcastSpinFlying(_publicSpinPrimaryBody);
			}
			else if (releasedNormally && _publicSpinKind == PublicSpinTargetKind.Prop && (Object)(object)_publicSpinPrimaryBody != (Object)null)
			{
				Vector3 val4 = ((((Vector3)(ref val3)).magnitude >= 1f) ? ((Vector3)(ref val3)).normalized : val2);
				if (!_publicSpinPrimaryBody.isKinematic)
				{
					_publicSpinPrimaryBody.velocity = val4 * Mathf.Clamp(_publicSpinThrowSpeed.Value, 1f, 40f);
					_publicSpinPrimaryBody.angularVelocity = val2 * (_publicSpinAngularSpeedDegrees * ((float)Math.PI / 180f));
					_publicSpinPrimaryBody.WakeUp();
				}
				TimeStopPublicBridge.PlayAndBroadcastSpinFlying(_publicSpinPrimaryBody);
				(((Component)_publicSpinPrimaryBody).GetComponent<SpinThrownImpactRelay>() ?? ((Component)_publicSpinPrimaryBody).gameObject.AddComponent<SpinThrownImpactRelay>()).Initialize(_publicSpinPrimaryBody, 4f, 1.5f, 15f);
				_publicSpinReturns.Add(new PublicSpinReturnState
				{
					Root = (((Object)(object)_publicSpinRoot != (Object)null) ? ((Component)_publicSpinRoot).gameObject : _publicSpinHeldObject),
					GrabObject = _publicSpinHeldObject,
					Body = _publicSpinPrimaryBody,
					ReturnAt = Time.realtimeSinceStartup + Mathf.Clamp(_publicSpinHomingDelay.Value, 0.25f, 10f),
					ExpiresAt = Time.realtimeSinceStartup + 20f,
					OriginalUseGravity = _publicSpinPrimaryBody.useGravity,
					OriginalDrag = _publicSpinPrimaryBody.drag,
					RequireGrabRelease = ((Object)(object)Player.RightController != (Object)null && Player.RightController.GetGripForce() >= 0.55f)
				});
			}
			if (!releasedNormally && _publicSpinVirtualHold && (Object)(object)_publicSpinHeldObject != (Object)null && (Object)(object)Player.RightHand != (Object)null && (Object)(object)Player.RightController != (Object)null && (Object)(object)Player.GetObjectInHand(Player.RightHand) == (Object)null && Player.RightController.GetGripForce() >= 0.55f)
			{
				try
				{
					Player.RightHand.AttachObject(_publicSpinHeldObject);
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Warning("Could not restore public Spin grab: " + ex.Message);
				}
			}
			RestorePublicSpinCollisionGhost();
			_publicSpinBodies.Clear();
			_publicSpinAnimators.Clear();
			_publicSpinActive = false;
			_publicSpinVirtualHold = false;
			_publicSpinArmed = false;
			_publicSpinArmedUntil = -1f;
			_publicSpinAngularSpeedDegrees = 0f;
			_publicSpinHeldObject = null;
			_publicSpinRoot = null;
			_publicSpinPrimaryBody = null;
		}

		private void BeginPublicVirtualSpinHold()
		{
			//IL_007f: 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)
			_publicSpinVirtualHold = false;
			if ((Object)(object)Player.RightHand == (Object)null || (Object)(object)_publicSpinPrimaryBody == (Object)null)
			{
				return;
			}
			try
			{
				HandReciever attachedReceiver = Player.RightHand.AttachedReceiver;
				Grip val = (Grip)(object)((attachedReceiver is Grip) ? attachedReceiver : null);
				if ((Object)(object)val != (Object)null)
				{
					try
					{
						GripExtensions.TryDetach(val, Player.RightHand);
					}
					catch
					{
					}
					try
					{
						Player.RightHand.DetachJoint(true, val);
					}
					catch
					{
					}
				}
				try
				{
					Player.RightHand.DetachIgnoreBodyJoints();
				}
				catch
				{
				}
				Player.RightHand.DetachObject();
				_publicSpinPrimaryBody.velocity = Vector3.zero;
				_publicSpinPrimaryBody.angularVelocity = Vector3.zero;
				_publicSpinVirtualHold = true;
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Public Spin virtual hold fallback: " + ex.Message);
			}
		}

		private void BeginPublicSpinCollisionGhost()
		{
			RestorePublicSpinCollisionGhost();
			if ((Object)(object)Player.RigManager == (Object)null || (Object)(object)_publicSpinRoot == (Object)null)
			{
				return;
			}
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(((Component)Player.RigManager).GetComponentsInChildren<Collider>(true));
			Collider[] array2 = Il2CppArrayBase<Collider>.op_Implicit(((Component)_publicSpinRoot).GetComponentsInChildren<Collider>(true));
			Collider[] array3 = array;
			foreach (Collider val in array3)
			{
				Collider[] array4 = array2;
				foreach (Collider val2 in array4)
				{
					if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val == (Object)(object)val2) && !((Component)val2).transform.IsChildOf(((Component)Player.RigManager).transform))
					{
						Physics.IgnoreCollision(val, val2, true);
						_publicSpinIgnoredCollisions.Add(new CollisionPair
						{
							Local = val,
							Remote = val2
						});
					}
				}
			}
		}

		private void RestorePublicSpinCollisionGhost()
		{
			foreach (CollisionPair publicSpinIgnoredCollision in _publicSpinIgnoredCollisions)
			{
				if ((Object)(object)publicSpinIgnoredCollision.Local != (Object)null && (Object)(object)publicSpinIgnoredCollision.Remote != (Object)null)
				{
					Physics.IgnoreCollision(publicSpinIgnoredCollision.Local, publicSpinIgnoredCollision.Remote, false);
				}
			}
			_publicSpinIgnoredCollisions.Clear();
		}

		private void CancelPublicSpin(bool restoreReturns)
		{
			EndPublicSpin(releasedNormally: false);
			_publicSpinArmed = false;
			_publicSpinArmedUntil = -1f;
			if (!restoreReturns)
			{
				return;
			}
			foreach (PublicSpinReturnState publicSpinReturn in _publicSpinReturns)
			{
				RestorePublicSpinReturn(publicSpinReturn);
			}
			_publicSpinReturns.Clear();
		}

		private void UpdatePublicSpinReturns()
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_012a: 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_0133: 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_01de: 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_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			for (int num = _publicSpinReturns.Count - 1; num >= 0; num--)
			{
				PublicSpinReturnState publicSpinReturnState = _publicSpinReturns[num];
				if ((Object)(object)publicSpinReturnState.Body