Decompiled source of TnH MGO2 GroznyjGrad v1.0.0

TnH_MGO2_GroznyjGrad.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using Atlas;
using Atlas.MappingComponents.Sandbox;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace GroznyjGrad
{
	public sealed class GroznyjGradCollisionReviewPiece : MonoBehaviour
	{
		public enum ReviewDecision
		{
			Unreviewed,
			Keep,
			Remove
		}

		public ReviewDecision Decision;

		public string ReviewId;

		public string Category;

		public string SourceFlags;

		public MeshCollider SourceCollider;

		public Mesh SourceNavigationMesh;

		public int[] NavigationTriangles;

		public float SolidBackingFraction;

		private void OnEnable()
		{
			if (Application.isPlaying)
			{
				((Component)this).gameObject.SetActive(false);
			}
		}
	}
	[DisallowMultipleComponent]
	[DefaultExecutionOrder(-50)]
	public sealed class GroznyjGradCatapult : MonoBehaviour
	{
		public enum SequencePhase
		{
			Idle,
			Boarding,
			Aiming,
			Ready,
			Firing,
			EndStop,
			Returning,
			Resetting,
			Cooldown
		}

		public enum BusyBehaviour
		{
			WalkAround,
			WaitForTurn,
			WaitThenWalk
		}

		private sealed class WaitingRider
		{
			public Sosig Sosig;

			public GroznyjGradCatapultRoute Route;

			public Vector3 Destination;

			public float ArrivedAt;
		}

		private sealed class Flight
		{
			public Object Rider;

			public Sosig Sosig;

			public GroznyjGradCatapultRoute Route;

			public bool Released;

			public bool Started;

			public bool Finished;

			public bool NavigationReleased;

			public bool AgentUpdatePosition;

			public float AfterRelease;

			public float ClockBias;

			public float ClockTau;

			public float Duration;

			public Vector3 BoardingStart;

			public Vector3 ReleasePosition;

			public Vector3 NavigationDestination;

			public Vector3 TargetVelocity;

			public Vector3 BodyOffset;

			public Vector3 PreviousBodyTarget;

			public Quaternion BodyRotation;

			public SosigMovementState ResumeMovement;

			public SosigMoveSpeed ResumeSpeed;

			public SosigBodyPose ResumePose;

			public float AgentSpeed;

			public bool AgentUpdateRotation;

			public bool AgentAutoRepath;

			public readonly List<Collider[]> IgnoredRigPairs = new List<Collider[]>();
		}

		[Header("Recovered rig")]
		public Transform AimPivot;

		public Transform ArmPivot;

		public Transform SeatPivot;

		public Vector3 ArmAxis = Vector3.right;

		[Tooltip("Direction along the launch rail in the rail bone's neutral local space.")]
		public Vector3 RailAxis = Vector3.up;

		[Tooltip("Local launch direction at the neutral rig pose.")]
		public Vector3 AimForward = Vector3.forward;

		[Tooltip("Carriage travel direction in the chair bone's parent space.")]
		public Vector3 SeatSlideAxis = Vector3.up;

		public float SeatTravel = 4.5f;

		[Range(0f, 89f)]
		public float MinLaunchElevation = 15f;

		[Range(1f, 90f)]
		public float MaxLaunchElevation = 80f;

		[Header("Shared player / Sosig sequence")]
		public GroznyjGradCatapultRoute[] Routes = new GroznyjGradCatapultRoute[0];

		[Tooltip("Extra height of the hop onto the stationary chair. Hop duration is the route's Boarding Seconds.")]
		public float BoardingHopHeight = 0.35f;

		public float AimSeconds = 2.2f;

		[FormerlySerializedAs("WindupSeconds")]
		public float ReadySeconds = 0.65f;

		public float FireSeconds = 0.25f;

		[Range(0f, 1f)]
		public float ReleaseAt = 0.85f;

		public float EndStopSeconds = 0.55f;

		public float ReturnSeconds = 1.2f;

		public float ResetSeconds = 0.6f;

		public float CooldownSeconds = 0f;

		[Tooltip("Average flight speed in metres per second along the complete authored arc. Flight duration is recalculated from the current route at release for both riders.")]
		public float BaseFlightSpeed = 25f;

		[Header("Shared sequence sounds")]
		public GroznyjGradCatapultAudioProfile SoundProfile;

		[Header("Sosig launch reactions")]
		[Tooltip("One approved reaction at release, using native speech and the rider's voice pitch/volume. An empty pool disables reactions.")]
		public AudioClip[] LaunchVoiceClips = (AudioClip[])(object)new AudioClip[0];

		[Header("Sosigs arriving while occupied")]
		public BusyBehaviour WhenBusy = BusyBehaviour.WaitForTurn;

		[Tooltip("Maximum Sosigs waiting at the link entrances. A full queue hides the routes from new paths.")]
		[Range(1f, 8f)]
		public int QueueLimit = 3;

		[Tooltip("Only used by Wait Then Walk. Waiting starts on arrival, not when the path was calculated.")]
		public float MaximumWaitSeconds = 8f;

		[Tooltip("Additional grace after the configured flight duration before abandoning a stuck traversal.")]
		public float FlightTimeoutGrace = 1f;

		[Header("Stranded catapult riders")]
		[Tooltip("After getting up, consecutive seconds without a complete path to the rider's travel target before native death.")]
		[Range(1f, 10f)]
		public float StrandedDeathSeconds = 3f;

		[Tooltip("Stationary time before attempting H3VR's native in-place recovery. Only catapult riders are monitored.")]
		public float RecoveryStillSeconds = 2f;

		[Tooltip("Maximum time a released rider can keep stumbling without recovery. Movement does not restart this timer.")]
		public float StumbleTimeoutSeconds = 30f;

		private GroznyjGradCatapultSoundPlayer soundPlayer;

		private static readonly Dictionary<Sosig, GroznyjGradCatapult> riders = new Dictionary<Sosig, GroznyjGradCatapult>();

		private static readonly Dictionary<Sosig, GroznyjGradCatapult> waiting = new Dictionary<Sosig, GroznyjGradCatapult>();

		private readonly List<WaitingRider> queue = new List<WaitingRider>();

		private readonly List<Flight> flights = new List<Flight>();

		private Flight sequenceRider;

		private Quaternion aimRest;

		private Quaternion armRest;

		private Quaternion seatRest;

		private Vector3 seatPositionRest;

		private bool captured;

		private float elapsed;

		private float yaw;

		private float aimFrom;

		private float aimTo;

		private float pitch;

		private float pitchFrom;

		private float pitchTo;

		private float seatDistance;

		private float returningFrom;

		private float returnYaw;

		private float returnPitch;

		private float nextAvailability;

		public int AudioVoiceCount => (soundPlayer != null) ? soundPlayer.Count : 0;

		public SequencePhase Phase { get; private set; }

		public GroznyjGradCatapultRoute ActiveRoute { get; private set; }

		public bool Released { get; private set; }

		public Vector3 ReleasePosition { get; private set; }

		public bool IsBusy => Phase != SequencePhase.Idle;

		public Object Rider => (sequenceRider != null) ? sequenceRider.Rider : null;

		public int WaitingCount => queue.Count;

		public int ActiveFlightCount
		{
			get
			{
				int num = 0;
				foreach (Flight flight in flights)
				{
					if (flight.Released)
					{
						num++;
					}
				}
				return num;
			}
		}

		public event Action<GroznyjGradCatapultRoute> LaunchReleased;

		public event Action<bool> FlightFinished;

		public event Action<Object, bool> RiderFlightFinished;

		public event Action<string> SoundPlayed;

		public event Action<SequencePhase> PhaseChanged;

		private Flight MotionFlight(Sosig s)
		{
			for (int i = 0; i < flights.Count; i++)
			{
				if (object.ReferenceEquals(flights[i].Sosig, s))
				{
					return flights[i];
				}
			}
			return null;
		}

		private static bool MotionOwner(Sosig s, out GroznyjGradCatapult owner, out Flight flight)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			flight = null;
			if (!riders.TryGetValue(s, out owner) || (int)s.BodyState != 0 || s.IsStunned || s.IsUnconscious || (Object)(object)s.Agent == (Object)null || !((Behaviour)s.Agent).enabled)
			{
				return false;
			}
			flight = owner.MotionFlight(s);
			return flight != null && !flight.Finished;
		}

		private void CaptureSosigMotion(Flight flight)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			Sosig sosig = flight.Sosig;
			NavMeshAgent agent = sosig.Agent;
			flight.ResumeMovement = sosig.MovementState;
			flight.ResumeSpeed = sosig.MoveSpeed;
			flight.ResumePose = sosig.BodyPose;
			flight.AgentSpeed = agent.speed;
			flight.AgentUpdateRotation = agent.updateRotation;
			flight.AgentAutoRepath = agent.autoRepath;
			flight.BodyOffset = ((Component)agent).transform.InverseTransformPoint(sosig.CoreTarget.position);
			flight.BodyRotation = Quaternion.Inverse(((Component)agent).transform.rotation) * sosig.CoreTarget.rotation;
			flight.PreviousBodyTarget = sosig.CoreTarget.position;
			agent.updateRotation = false;
			agent.autoRepath = false;
			HoldSosigMotion(flight);
		}

		private static void HoldSosigMotion(Flight flight)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Sosig sosig = flight.Sosig;
			sosig.MovementState = (SosigMovementState)1;
			sosig.MoveSpeed = (SosigMoveSpeed)0;
			sosig.Agent.speed = 0f;
			sosig.Agent.updatePosition = false;
			if (sosig.Agent.isOnNavMesh)
			{
				sosig.Agent.Stop();
				sosig.Agent.velocity = Vector3.zero;
			}
		}

		private static void PinBodyPose(Flight flight)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Sosig sosig = flight.Sosig;
			if (!((Object)(object)sosig.CoreTarget == (Object)null))
			{
				sosig.CoreTarget.position = ((Component)sosig.Agent).transform.TransformPoint(flight.BodyOffset);
				sosig.CoreTarget.rotation = ((Component)sosig.Agent).transform.rotation * flight.BodyRotation;
				sosig.m_targetLocalPos = ((Component)sosig).transform.InverseTransformPoint(sosig.CoreTarget.position);
				sosig.m_targetLocalRot = sosig.CoreTarget.localRotation;
			}
		}

		private static void UpdateBodyTarget(Flight flight)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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)
			HoldSosigMotion(flight);
			PinBodyPose(flight);
			Vector3 position = flight.Sosig.CoreTarget.position;
			flight.TargetVelocity = (position - flight.PreviousBodyTarget) / Mathf.Max(0.001f, Time.fixedDeltaTime);
			flight.PreviousBodyTarget = position;
		}

		private static void RestoreSosigMotion(Flight flight)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			Sosig sosig = flight.Sosig;
			if ((Object)(object)sosig == (Object)null || (Object)(object)sosig.Agent == (Object)null)
			{
				return;
			}
			sosig.Agent.speed = flight.AgentSpeed;
			sosig.Agent.updateRotation = flight.AgentUpdateRotation;
			sosig.Agent.autoRepath = flight.AgentAutoRepath;
			if ((int)sosig.BodyState != 0)
			{
				if ((int)sosig.BodyState != 3 && (int)sosig.MoveSpeed == 0)
				{
					sosig.MoveSpeed = flight.ResumeSpeed;
				}
			}
			else
			{
				sosig.MovementState = flight.ResumeMovement;
				sosig.MoveSpeed = flight.ResumeSpeed;
				sosig.SetBodyPose(flight.ResumePose);
			}
		}

		internal static bool HoldMovementRequest(Sosig s, SosigMovementState requested)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!MotionOwner(s, out var _, out var flight))
			{
				return false;
			}
			flight.ResumeMovement = requested;
			return true;
		}

		internal static bool HoldSpeedRequest(Sosig s, SosigMoveSpeed requested)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!MotionOwner(s, out var _, out var flight))
			{
				return false;
			}
			flight.ResumeSpeed = requested;
			return true;
		}

		internal static bool HoldPoseRequest(Sosig s, SosigBodyPose requested)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!MotionOwner(s, out var _, out var flight))
			{
				return false;
			}
			flight.ResumePose = requested;
			return true;
		}

		internal static bool HoldPathRequest(Sosig s, Vector3 requested)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!MotionOwner(s, out var _, out var _))
			{
				return false;
			}
			s.m_navToPoint = requested;
			return true;
		}

		internal static void AfterBodyUpdate(Sosig s)
		{
			if (MotionOwner(s, out var _, out var flight))
			{
				HoldSosigMotion(flight);
				PinBodyPose(flight);
			}
		}

		internal void UpdateSosigLook(Sosig s)
		{
			if (MotionOwner(s, out var _, out var flight))
			{
				HoldSosigMotion(flight);
				s.TurnTowardsFacingDir();
				PinBodyPose(flight);
			}
		}

		private void OnEnable()
		{
			CaptureRig();
			Phase = SequencePhase.Idle;
			if (Application.isPlaying)
			{
				SetRoutesAvailable(available: true);
			}
		}

		private void OnDisable()
		{
			if (Application.isPlaying)
			{
				SetRoutesAvailable(available: false);
			}
			while (flights.Count > 0)
			{
				InterruptFlight(flights[flights.Count - 1]);
			}
			while (queue.Count > 0)
			{
				RemoveWaiting(queue[0].Sosig, repath: true);
			}
			RestoreRig();
			sequenceRider = null;
			ActiveRoute = null;
			Phase = SequencePhase.Idle;
			if (soundPlayer != null)
			{
				soundPlayer.Dispose();
				soundPlayer = null;
			}
		}

		private void Update()
		{
			if (soundPlayer != null)
			{
				soundPlayer.Tick();
			}
			for (int num = queue.Count - 1; num >= 0; num--)
			{
				if (!CanTravel(queue[num].Sosig))
				{
					RemoveWaiting(queue[num].Sosig, repath: false);
				}
			}
			if (Application.isPlaying && Time.time >= nextAvailability)
			{
				SetRoutesAvailable(CanOfferRoutes());
				nextAvailability = Time.time + 0.25f;
			}
		}

		private void FixedUpdate()
		{
			AdvanceSequence(Time.fixedDeltaTime);
			for (int num = flights.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)flights[num].Sosig != (Object)null)
				{
					AdvanceSosig(flights[num].Sosig);
				}
			}
		}

		private void CaptureRig()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (!Application.isPlaying && Phase == SequencePhase.Idle)
			{
				captured = false;
			}
			if (!captured && !((Object)(object)AimPivot == (Object)null) && !((Object)(object)ArmPivot == (Object)null) && !((Object)(object)SeatPivot == (Object)null))
			{
				aimRest = AimPivot.localRotation;
				armRest = ArmPivot.localRotation;
				seatRest = SeatPivot.localRotation;
				seatPositionRest = SeatPivot.localPosition;
				captured = true;
			}
		}

		public void RestoreRig()
		{
			//IL_0029: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (captured)
			{
				if ((Object)(object)AimPivot != (Object)null)
				{
					AimPivot.localRotation = aimRest;
				}
				if ((Object)(object)ArmPivot != (Object)null)
				{
					ArmPivot.localRotation = armRest;
				}
				if ((Object)(object)SeatPivot != (Object)null)
				{
					SeatPivot.localRotation = seatRest;
					SeatPivot.localPosition = seatPositionRest;
				}
				yaw = (pitch = (seatDistance = 0f));
			}
		}

		private void ApplyPose(float newYaw, float newPitch, float newDistance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			yaw = newYaw;
			pitch = newPitch;
			seatDistance = newDistance;
			AimPivot.localRotation = aimRest * Quaternion.AngleAxis(yaw, Vector3.up);
			ArmPivot.localRotation = armRest * Quaternion.AngleAxis(pitch, ((Vector3)(ref ArmAxis)).normalized);
			SeatPivot.localRotation = seatRest;
			SeatPivot.localPosition = seatPositionRest + ((Vector3)(ref SeatSlideAxis)).normalized * seatDistance;
			if (sequenceRider != null && !sequenceRider.Finished && !sequenceRider.Released && Phase != SequencePhase.Boarding && (Object)(object)sequenceRider.Sosig != (Object)null && (Object)(object)sequenceRider.Sosig.Agent != (Object)null && ((Behaviour)sequenceRider.Sosig.Agent).enabled)
			{
				((Component)sequenceRider.Sosig.Agent).transform.position = sequenceRider.Route.LaunchOrigin.position;
			}
		}

		public bool HasValidRig()
		{
			return (Object)(object)AimPivot != (Object)null && (Object)(object)AimPivot.parent != (Object)null && (Object)(object)ArmPivot != (Object)null && (Object)(object)ArmPivot.parent != (Object)null && (Object)(object)SeatPivot != (Object)null && (Object)(object)SeatPivot.parent != (Object)null && ArmPivot.IsChildOf(AimPivot) && SeatPivot.IsChildOf(ArmPivot) && ((Vector3)(ref ArmAxis)).sqrMagnitude > 0.001f && ((Vector3)(ref RailAxis)).sqrMagnitude > 0.001f && ((Vector3)(ref SeatSlideAxis)).sqrMagnitude > 0.001f && ((Vector3)(ref AimForward)).sqrMagnitude > 0.001f && SeatTravel > 0f && ReleaseAt > 0f && ReleaseAt < 1f && MinLaunchElevation < MaxLaunchElevation;
		}

		private float CarriageProgress(float t)
		{
			t = Mathf.Clamp01(t);
			return (!(t <= ReleaseAt)) ? (1f - (1f - t) * (1f - t) / (1f - ReleaseAt)) : (t * t / ReleaseAt);
		}

		private Matrix4x4 RailMatrix(Matrix4x4 parentFromAim, float newYaw, float newPitch)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 val = AimPivot.parent.localToWorldMatrix * Matrix4x4.TRS(AimPivot.localPosition, aimRest * Quaternion.AngleAxis(newYaw, Vector3.up), AimPivot.localScale);
			return val * parentFromAim * Matrix4x4.TRS(ArmPivot.localPosition, armRest * Quaternion.AngleAxis(newPitch, ((Vector3)(ref ArmAxis)).normalized), ArmPivot.localScale);
		}

		private bool SolveLaunchPose(GroznyjGradCatapultRoute route, out Vector3 release, out float solvedYaw, out float solvedPitch)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: 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)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_026f: 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_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			release = Vector3.zero;
			solvedYaw = (solvedPitch = 0f);
			CaptureRig();
			if (!captured || !HasValidRig() || (Object)(object)route == (Object)null || !route.HasValidConfiguration())
			{
				return false;
			}
			Matrix4x4 parentFromAim = AimPivot.worldToLocalMatrix * ArmPivot.parent.localToWorldMatrix;
			Vector3 val = ArmPivot.InverseTransformVector(SeatPivot.parent.TransformVector(((Vector3)(ref SeatSlideAxis)).normalized));
			Vector3 val2 = ArmPivot.InverseTransformPoint(route.LaunchOrigin.position) - val * seatDistance;
			Vector3 val3 = val2 + val * SeatTravel * CarriageProgress(ReleaseAt);
			Vector3 position = route.Link.endTransform.position;
			AnimationCurve jumpCurve = route.Extension.JumpCurve;
			float num = (jumpCurve.Evaluate(0.001f) - jumpCurve.Evaluate(0f)) / 0.001f * route.Extension.MaxJumpHeight;
			Vector3 aimForward = AimForward;
			aimForward.y = 0f;
			if (((Vector3)(ref aimForward)).sqrMagnitude < 0.001f)
			{
				return false;
			}
			for (int i = 0; i < 8; i++)
			{
				Matrix4x4 val4 = RailMatrix(parentFromAim, solvedYaw, solvedPitch);
				release = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(val3);
				Vector3 val5 = Quaternion.Inverse(aimRest) * AimPivot.parent.InverseTransformDirection(position - release);
				val5.y = 0f;
				if (((Vector3)(ref val5)).sqrMagnitude < 0.001f)
				{
					return false;
				}
				solvedYaw = Mathf.Atan2(Vector3.Cross(((Vector3)(ref aimForward)).normalized, ((Vector3)(ref val5)).normalized).y, Vector3.Dot(((Vector3)(ref aimForward)).normalized, ((Vector3)(ref val5)).normalized)) * 57.29578f;
				Matrix4x4 val6 = RailMatrix(parentFromAim, solvedYaw, 0f);
				Matrix4x4 inverse = ((Matrix4x4)(ref val6)).inverse;
				Vector3 val7 = ((Matrix4x4)(ref inverse)).MultiplyVector(position - release + Vector3.up * num);
				Vector3 normalized = ((Vector3)(ref val7)).normalized;
				Vector3 normalized2 = ((Vector3)(ref RailAxis)).normalized;
				solvedPitch = Mathf.Clamp(Mathf.Atan2(Vector3.Dot(Vector3.Cross(normalized2, normalized), ((Vector3)(ref ArmAxis)).normalized), Vector3.Dot(normalized2, normalized)) * 57.29578f, 90f - MaxLaunchElevation, 90f - MinLaunchElevation);
			}
			Matrix4x4 val8 = RailMatrix(parentFromAim, solvedYaw, solvedPitch);
			release = ((Matrix4x4)(ref val8)).MultiplyPoint3x4(val3);
			return true;
		}

		public bool TryGetReleasePosition(GroznyjGradCatapultRoute route, out Vector3 release)
		{
			float solvedYaw;
			float solvedPitch;
			return SolveLaunchPose(route, out release, out solvedYaw, out solvedPitch);
		}

		private void SetRoutesAvailable(bool available)
		{
			GroznyjGradCatapultRoute[] routes = Routes;
			foreach (GroznyjGradCatapultRoute groznyjGradCatapultRoute in routes)
			{
				if ((Object)(object)groznyjGradCatapultRoute != (Object)null && (Object)(object)groznyjGradCatapultRoute.Link != (Object)null)
				{
					groznyjGradCatapultRoute.Link.costOverride = Mathf.Max(0.01f, groznyjGradCatapultRoute.NavigationCost);
					groznyjGradCatapultRoute.Link.activated = available && groznyjGradCatapultRoute.EnableForSosigs && groznyjGradCatapultRoute.HasValidConfiguration() && (!Application.isPlaying || groznyjGradCatapultRoute.LandingAvailable(-1));
				}
			}
		}

		private bool CanOfferRoutes()
		{
			return ((Behaviour)this).isActiveAndEnabled && (!IsBusy || WhenBusy != BusyBehaviour.WalkAround) && queue.Count < Mathf.Max(1, QueueLimit);
		}

		private static bool CanTravel(Sosig s)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)s != (Object)null && (Object)(object)s.Agent != (Object)null && ((Behaviour)s.Agent).enabled && s.Agent.isOnNavMesh && (int)s.BodyState == 0 && !s.IsStunned;
		}

		internal static bool FindWaiting(Sosig s, out GroznyjGradCatapult catapult)
		{
			return waiting.TryGetValue(s, out catapult);
		}

		internal void ArriveSosig(Sosig s, GroznyjGradCatapultRoute route)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBusy && queue.Count == 0 && BeginSosig(s, route))
			{
				AdvanceSosig(s);
				return;
			}
			if (!CanTravel(s) || !route.HasValidConfiguration() || !route.EnableForSosigs || !route.LandingAvailable(s.Agent.areaMask) || WhenBusy == BusyBehaviour.WalkAround || queue.Count >= Mathf.Max(1, QueueLimit))
			{
				RepathWithoutCatapult(s);
				return;
			}
			queue.Add(new WaitingRider
			{
				Sosig = s,
				Route = route,
				Destination = s.Agent.destination,
				ArrivedAt = Time.time
			});
			waiting.Add(s, this);
			s.Agent.Stop();
			SetRoutesAvailable(CanOfferRoutes());
		}

		internal void AdvanceWaiting(Sosig s)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			WaitingRider waitingRider = queue.Find((WaitingRider q) => object.ReferenceEquals(q.Sosig, s));
			if (waitingRider == null)
			{
				return;
			}
			if (!CanTravel(s))
			{
				RemoveWaiting(s, repath: false);
				return;
			}
			if (Vector3.Distance(waitingRider.Destination, s.Agent.destination) > 0.5f || !s.Agent.isOnOffMeshLink)
			{
				RemoveWaiting(s, repath: true);
				return;
			}
			if (WhenBusy == BusyBehaviour.WalkAround || (WhenBusy == BusyBehaviour.WaitThenWalk && Time.time - waitingRider.ArrivedAt >= Mathf.Max(0.1f, MaximumWaitSeconds)))
			{
				RemoveWaiting(s, repath: true);
				return;
			}
			s.Agent.Stop();
			if (!IsBusy && object.ReferenceEquals(queue[0], waitingRider))
			{
				RemoveWaiting(s, repath: false);
				s.Agent.Resume();
				if (BeginSosig(s, waitingRider.Route))
				{
					AdvanceSosig(s);
				}
				else
				{
					RepathWithoutCatapult(s);
				}
			}
		}

		internal void RemoveWaiting(Sosig s, bool repath)
		{
			WaitingRider waitingRider = queue.Find((WaitingRider q) => object.ReferenceEquals(q.Sosig, s));
			if (waitingRider != null)
			{
				queue.Remove(waitingRider);
				waiting.Remove(s);
				if ((Object)(object)s != (Object)null && (Object)(object)s.Agent != (Object)null && ((Behaviour)s.Agent).enabled && s.Agent.isOnNavMesh)
				{
					s.Agent.Resume();
				}
				if (repath)
				{
					RepathWithoutCatapult(s);
				}
			}
		}

		private void RepathWithoutCatapult(Sosig s)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)s == (Object)null) && !((Object)(object)s.Agent == (Object)null) && ((Behaviour)s.Agent).enabled && s.Agent.isOnNavMesh)
			{
				Vector3 destination = s.Agent.destination;
				s.EndLink(false);
				s.Agent.Resume();
				SetRoutesAvailable(available: false);
				NavMeshPath val = new NavMeshPath();
				bool flag = s.Agent.CalculatePath(destination, val);
				s.Agent.ResetPath();
				if (flag)
				{
					s.Agent.SetPath(val);
				}
				SetRoutesAvailable(CanOfferRoutes());
			}
		}

		public bool TryBeginSequence(GroznyjGradCatapultRoute route, Object rider)
		{
			//IL_0105: 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)
			if (rider is GroznyjGradCatapultPlayer && GroznyjGradCatapultPlayer.PlayerUseBlocked)
			{
				return false;
			}
			CaptureRig();
			if (!captured || !((Behaviour)this).isActiveAndEnabled || IsBusy || rider == (Object)null || (Object)(object)route == (Object)null || (Object)(object)route.Catapult != (Object)(object)this || !route.HasValidConfiguration() || Array.IndexOf(Routes, route) < 0)
			{
				return false;
			}
			if (flights.Exists((Flight f) => object.ReferenceEquals(f.Rider, rider)))
			{
				return false;
			}
			if (!SolveLaunchPose(route, out var release, out aimTo, out pitchTo))
			{
				return false;
			}
			aimFrom = yaw;
			pitchFrom = pitch;
			float num = route.FlightDuration(release, route.Link.endTransform.position);
			route.Extension.BaseTimeToTraverse = num;
			sequenceRider = new Flight
			{
				Rider = rider,
				Route = route,
				Duration = num
			};
			flights.Add(sequenceRider);
			ActiveRoute = route;
			Released = false;
			Enter(SequencePhase.Boarding);
			if (Application.isPlaying)
			{
				SetRoutesAvailable(CanOfferRoutes());
			}
			return true;
		}

		public void AdvanceSequence(float deltaTime)
		{
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: 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_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			if (deltaTime <= 0f)
			{
				return;
			}
			for (int num = flights.Count - 1; num >= 0; num--)
			{
				Flight flight = flights[num];
				if (flight.Rider == (Object)null)
				{
					InterruptFlight(flight);
				}
				else if (flight.Released)
				{
					flight.AfterRelease += deltaTime;
					if (flight.AfterRelease > flight.Duration + Mathf.Max(0.1f, FlightTimeoutGrace))
					{
						InterruptFlight(flight);
					}
				}
			}
			if (!IsBusy)
			{
				return;
			}
			elapsed += deltaTime;
			switch (Phase)
			{
			case SequencePhase.Boarding:
				ApplyPose(aimFrom, pitchFrom, 0f);
				if (elapsed >= Mathf.Max(0.01f, ActiveRoute.BoardingSeconds))
				{
					Enter(SequencePhase.Aiming);
				}
				break;
			case SequencePhase.Aiming:
			{
				float num2 = Smooth(elapsed / Mathf.Max(0.01f, AimSeconds));
				ApplyPose(Mathf.LerpAngle(aimFrom, aimTo, num2), Mathf.Lerp(pitchFrom, pitchTo, num2), 0f);
				if (elapsed >= AimSeconds)
				{
					Enter(SequencePhase.Ready);
				}
				break;
			}
			case SequencePhase.Ready:
				ApplyPose(aimTo, pitchTo, 0f);
				if (elapsed >= ReadySeconds)
				{
					Enter(SequencePhase.Firing);
				}
				break;
			case SequencePhase.Firing:
			{
				float num3 = Mathf.Clamp01(elapsed / Mathf.Max(0.01f, FireSeconds));
				if (!Released && sequenceRider != null && !sequenceRider.Finished && num3 >= ReleaseAt)
				{
					ApplyPose(aimTo, pitchTo, SeatTravel * CarriageProgress(ReleaseAt));
					ReleasePosition = ActiveRoute.LaunchOrigin.position;
					Released = true;
					sequenceRider.ReleasePosition = ReleasePosition;
					sequenceRider.Released = true;
					float num4 = ActiveRoute.FlightDuration(ReleasePosition, ActiveRoute.Link.endTransform.position);
					sequenceRider.Duration = num4;
					ActiveRoute.Extension.BaseTimeToTraverse = num4;
					Vector3 val = (ActiveRoute.EvaluateFlight(ReleasePosition, ActiveRoute.Link.endTransform.position, 0.001f) - ReleasePosition) / (num4 * 0.001f);
					float num5 = SeatTravel * 2f * ReleaseAt / Mathf.Max(0.01f, FireSeconds);
					sequenceRider.ClockTau = 0.12f / num4;
					float num6 = num5 / Mathf.Max(0.1f, ((Vector3)(ref val)).magnitude);
					sequenceRider.ClockBias = Mathf.Clamp((num6 - 1f) * sequenceRider.ClockTau, -0.5f * sequenceRider.ClockTau, 0.3f);
					sequenceRider.TargetVelocity = val * (1f + sequenceRider.ClockBias / sequenceRider.ClockTau);
					SpeakLaunchReaction(sequenceRider.Sosig);
					this.LaunchReleased?.Invoke(ActiveRoute);
				}
				ApplyPose(aimTo, pitchTo, SeatTravel * CarriageProgress(num3));
				if (num3 >= 1f)
				{
					Enter(SequencePhase.EndStop);
				}
				break;
			}
			case SequencePhase.EndStop:
				ApplyPose(aimTo, pitchTo, SeatTravel);
				if (elapsed >= EndStopSeconds)
				{
					StartReturn();
				}
				break;
			case SequencePhase.Returning:
			{
				float num7 = Smooth(elapsed / Mathf.Max(0.01f, ReturnSeconds));
				ApplyPose(Mathf.LerpAngle(returnYaw, 0f, num7), Mathf.Lerp(returnPitch, 0f, num7), Mathf.Lerp(returningFrom, 0f, num7));
				if (elapsed >= ReturnSeconds)
				{
					Enter(SequencePhase.Resetting);
				}
				break;
			}
			case SequencePhase.Resetting:
				ApplyPose(0f, 0f, 0f);
				if (elapsed >= ResetSeconds)
				{
					RestoreRig();
					Enter(SequencePhase.Cooldown);
				}
				break;
			case SequencePhase.Cooldown:
				if (elapsed >= CooldownSeconds)
				{
					sequenceRider = null;
					ActiveRoute = null;
					Released = false;
					Enter(SequencePhase.Idle);
					if (Application.isPlaying)
					{
						SetRoutesAvailable(CanOfferRoutes());
					}
				}
				break;
			}
		}

		private static float Smooth(float t)
		{
			t = Mathf.Clamp01(t);
			return t * t * (3f - 2f * t);
		}

		internal void SpeakLaunchReaction(Sosig sosig)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			if ((Object)(object)sosig == (Object)null || (Object)(object)sosig.Speech == (Object)null || !sosig.IsAllowedToSpeak || (int)sosig.BodyState == 3 || sosig.IsStunned || sosig.IsUnconscious || LaunchVoiceClips == null)
			{
				return;
			}
			List<AudioClip> list = new List<AudioClip>();
			AudioClip[] launchVoiceClips = LaunchVoiceClips;
			foreach (AudioClip val in launchVoiceClips)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
			if (list.Count != 0)
			{
				sosig.KillSpeech();
				sosig.Speak_State(list);
			}
		}

		private void Enter(SequencePhase phase)
		{
			Phase = phase;
			elapsed = 0f;
			if (Application.isPlaying)
			{
				if (soundPlayer == null)
				{
					soundPlayer = new GroznyjGradCatapultSoundPlayer(this);
				}
				soundPlayer.Phase(phase);
			}
			this.PhaseChanged?.Invoke(phase);
		}

		internal void NotifySound(GroznyjGradCatapultAudioProfile.Event item)
		{
			this.SoundPlayed?.Invoke(string.Concat(Phase, " ", item.Name, " gain=", item.Sound.Volume, " tailOnly=", item.TailOnly, " anchor=", (!item.AtSeat) ? "axis" : "seat"));
		}

		private void StartReturn()
		{
			returningFrom = seatDistance;
			returnYaw = yaw;
			returnPitch = pitch;
			Enter(SequencePhase.Returning);
		}

		internal void SetPlayerFlightDuration(Object rider, float duration)
		{
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Rider, rider));
			if (flight != null && flight.Released && (Object)(object)flight.Sosig == (Object)null)
			{
				flight.Duration = Mathf.Max(0.1f, duration);
			}
		}

		public void NotifyFlightComplete(Object rider, bool success)
		{
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Rider, rider));
			if (flight != null)
			{
				CompleteFlight(flight, success);
			}
		}

		public void DetachBeforeLaunch(Object rider)
		{
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Rider, rider));
			if (flight != null && !flight.Released && !((Object)(object)flight.Sosig != (Object)null))
			{
				flight.Finished = true;
				flights.Remove(flight);
				RestoreRiderCollision(flight);
				if (object.ReferenceEquals(sequenceRider, flight))
				{
					sequenceRider = null;
				}
				this.RiderFlightFinished?.Invoke(rider, arg2: false);
				this.FlightFinished?.Invoke(obj: false);
			}
		}

		private void CompleteFlight(Flight flight, bool success)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (!flight.Finished)
			{
				RestoreRiderCollision(flight);
				flight.Finished = true;
				flights.Remove(flight);
				if (!object.ReferenceEquals(flight.Sosig, null))
				{
					riders.Remove(flight.Sosig);
				}
				RestoreSosigMotion(flight);
				if (Application.isPlaying && flight.Released && (Object)(object)flight.Sosig != (Object)null && (int)flight.Sosig.BodyState != 3)
				{
					float airborneGrace = ((!success) ? Mathf.Max(2f, flight.Duration - flight.AfterRelease + FlightTimeoutGrace) : 2f);
					GroznyjGradCatapultRecovery.Watch(flight.Sosig, flight.NavigationDestination, Mathf.Clamp(StrandedDeathSeconds, 1f, 10f), airborneGrace, Mathf.Max(0.25f, RecoveryStillSeconds), Mathf.Max(5f, StumbleTimeoutSeconds));
				}
				if (!flight.Released && object.ReferenceEquals(sequenceRider, flight))
				{
					StartReturn();
				}
				this.RiderFlightFinished?.Invoke(flight.Rider, success);
				this.FlightFinished?.Invoke(success);
			}
		}

		internal static bool FindRider(Sosig s, out GroznyjGradCatapult catapult)
		{
			return riders.TryGetValue(s, out catapult);
		}

		internal bool TryGetCarriageVelocity(Sosig s, out Vector3 velocity)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			velocity = Vector3.zero;
			Flight flight = MotionFlight(s);
			if (flight != null && (int)s.BodyState == 0 && !s.IsStunned)
			{
				velocity = flight.TargetVelocity;
				return true;
			}
			return false;
		}

		internal bool BeginSosig(Sosig s, GroznyjGradCatapultRoute route)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s == (Object)null || (Object)(object)s.Agent == (Object)null || (Object)(object)s.CoreTarget == (Object)null || (Object)(object)s.CoreRB == (Object)null || (int)s.BodyState != 0 || s.IsStunned || !route.EnableForSosigs || !route.LandingAvailable(s.Agent.areaMask) || !TryBeginSequence(route, (Object)(object)s))
			{
				return false;
			}
			sequenceRider.Sosig = s;
			sequenceRider.BoardingStart = ((Component)s.Agent).transform.position;
			sequenceRider.AgentUpdatePosition = s.Agent.updatePosition;
			sequenceRider.NavigationDestination = s.Agent.destination;
			CaptureSosigMotion(sequenceRider);
			riders.Add(s, this);
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			HashSet<Collider> hashSet = new HashSet<Collider>();
			foreach (SosigLink link in s.Links)
			{
				if (!((Object)(object)link != (Object)null))
				{
					continue;
				}
				Collider[] componentsInChildren2 = ((Component)link).GetComponentsInChildren<Collider>(true);
				foreach (Collider val in componentsInChildren2)
				{
					if (((Component)val).gameObject.layer == LayerMask.NameToLayer("AgentBody"))
					{
						hashSet.Add(val);
					}
				}
			}
			if ((Object)(object)s.CoreRB != (Object)null)
			{
				Collider[] components = ((Component)s.CoreRB).GetComponents<Collider>();
				foreach (Collider item in components)
				{
					hashSet.Add(item);
				}
			}
			foreach (CharacterJoint joint in s.m_joints)
			{
				if ((Object)(object)joint != (Object)null)
				{
					Collider[] components2 = ((Component)joint).GetComponents<Collider>();
					foreach (Collider item2 in components2)
					{
						hashSet.Add(item2);
					}
				}
			}
			foreach (Collider item3 in hashSet)
			{
				Collider[] array = componentsInChildren;
				foreach (Collider val2 in array)
				{
					if (val2.enabled && !val2.isTrigger && ((((Component)val2).gameObject.layer == LayerMask.NameToLayer("Environment") && ((Object)val2).name.StartsWith("Physical ", StringComparison.Ordinal)) || (Object)(object)((Component)val2).GetComponent<GroznyjGradCatapultHandle>() != (Object)null))
					{
						Physics.IgnoreCollision(item3, val2, true);
						sequenceRider.IgnoredRigPairs.Add((Collider[])(object)new Collider[2] { item3, val2 });
					}
				}
			}
			s.Agent.autoTraverseOffMeshLink = false;
			s.Agent.updatePosition = false;
			s.Agent.Stop();
			s.InitiateLink(route.Extension);
			return true;
		}

		private static void RestoreRiderCollision(Flight flight)
		{
			foreach (Collider[] ignoredRigPair in flight.IgnoredRigPairs)
			{
				if ((Object)(object)ignoredRigPair[0] != (Object)null && (Object)(object)ignoredRigPair[1] != (Object)null)
				{
					Physics.IgnoreCollision(ignoredRigPair[0], ignoredRigPair[1], false);
				}
			}
			flight.IgnoredRigPairs.Clear();
		}

		internal void AdvanceSosig(Sosig s)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Sosig, s));
			if (flight == null)
			{
				return;
			}
			GroznyjGradCatapultRoute route = flight.Route;
			if ((int)s.BodyState != 0 || s.IsStunned || !((Behaviour)s.Agent).enabled || (Object)(object)s.m_currentlinkExtension != (Object)(object)route.Extension)
			{
				InterruptFlight(flight);
				return;
			}
			if (!flight.Released)
			{
				if (Phase == SequencePhase.Boarding)
				{
					float num = Mathf.Clamp01(elapsed / Mathf.Max(0.01f, route.BoardingSeconds));
					((Component)s.Agent).transform.position = Vector3.Lerp(flight.BoardingStart, route.LaunchOrigin.position, Smooth(num)) + Vector3.up * Mathf.Sin(num * (float)Math.PI) * Mathf.Max(0f, BoardingHopHeight);
				}
				else
				{
					((Component)s.Agent).transform.position = route.LaunchOrigin.position;
				}
				UpdateBodyTarget(flight);
				return;
			}
			if (!flight.Started)
			{
				if (!route.LandingAvailable(s.Agent.areaMask))
				{
					InterruptFlight(flight);
					return;
				}
				flight.Started = true;
				s.m_LinkLerp = 0f;
				s.m_linkStartPos = flight.ReleasePosition;
				s.m_LinkEndPos = route.Link.endTransform.position;
				if (s.Agent.isOnOffMeshLink)
				{
					s.Agent.updatePosition = false;
					s.Agent.Stop();
					s.Agent.CompleteOffMeshLink();
					((Component)s.Agent).transform.position = flight.ReleasePosition;
					flight.NavigationReleased = true;
				}
			}
			float num2 = Mathf.Max(0.1f, flight.Duration);
			float t = Mathf.Clamp01(flight.AfterRelease / num2);
			float num3 = FlightProgress(flight, t);
			float num4 = Mathf.Min(num3, 0.99999f);
			s.m_LinkLerp = num4 - Time.deltaTime / Mathf.Max(0.1f, route.Extension.BaseTimeToTraverse);
			float smoothingSharpness = route.Extension.SmoothingSharpness;
			try
			{
				route.Extension.SmoothingSharpness = Mathf.Max(smoothingSharpness, 1f / Mathf.Max(0.001f, Time.deltaTime));
				route.Extension.Traverse_LateralJump(ref s.m_LinkLerp, s, s.m_linkStartPos, s.m_LinkEndPos);
			}
			finally
			{
				route.Extension.SmoothingSharpness = smoothingSharpness;
			}
			UpdateBodyTarget(flight);
			if (num3 >= 1f && (Object)(object)s.CoreRB != (Object)null && Vector3.Distance(s.CoreRB.position, s.CoreTarget.position) < 0.25f)
			{
				Vector3 velocity = s.CoreRB.velocity;
				if (((Vector3)(ref velocity)).sqrMagnitude < 2.25f)
				{
					s.EndLink(true);
				}
			}
		}

		private static float FlightProgress(Flight flight, float t)
		{
			return Mathf.Clamp01(t + flight.ClockBias * (1f - t) * (1f - Mathf.Exp((0f - t) / Mathf.Max(0.001f, flight.ClockTau))));
		}

		internal bool BeforeNativeEnd(Sosig s, bool success)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Sosig, s));
			if (flight == null)
			{
				return true;
			}
			if (success)
			{
				if (!flight.NavigationReleased)
				{
					flight.Route.Link.activated = true;
				}
				return true;
			}
			if (!flight.Released)
			{
				s.Agent.Warp(flight.BoardingStart);
				s.Agent.updatePosition = flight.AgentUpdatePosition;
				s.Agent.Resume();
				return true;
			}
			if ((int)s.BodyState == 0)
			{
				s.SetBodyState((SosigBodyState)2);
				return false;
			}
			s.m_isOnOffMeshLink = false;
			s.m_currentlinkExtension = null;
			s.Agent.autoTraverseOffMeshLink = false;
			((Behaviour)s.Agent).enabled = false;
			s.Agent.updatePosition = flight.AgentUpdatePosition;
			CompleteFlight(flight, success: false);
			return false;
		}

		internal void AfterNativeEnd(Sosig s, bool success)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Sosig, s));
			if (flight != null)
			{
				if (success && flight.NavigationReleased && ((Behaviour)s.Agent).enabled)
				{
					s.Agent.nextPosition = s.m_LinkEndPos;
					((Component)s.Agent).transform.position = s.m_LinkEndPos;
					s.Agent.updatePosition = flight.AgentUpdatePosition;
					s.Agent.Resume();
				}
				CompleteFlight(flight, success);
			}
			if (Application.isPlaying)
			{
				SetRoutesAvailable(CanOfferRoutes());
			}
		}

		private void InterruptFlight(Flight flight)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Sosig sosig = flight.Sosig;
			if ((Object)(object)sosig == (Object)null)
			{
				CompleteFlight(flight, success: false);
				return;
			}
			if (flight.Released && (int)sosig.BodyState == 0)
			{
				sosig.SetBodyState((SosigBodyState)2);
			}
			else
			{
				sosig.EndLink(false);
			}
			if (!flight.Finished)
			{
				CompleteFlight(flight, success: false);
			}
		}

		internal string RiderState(Sosig s)
		{
			Flight flight = flights.Find((Flight f) => object.ReferenceEquals(f.Sosig, s));
			return (flight == null || !flight.Released) ? Phase.ToString() : "Airborne";
		}

		internal string FlightDiagnostics(Sosig s)
		{
			Flight flight = flights.Find((Flight flight2) => object.ReferenceEquals(flight2.Sosig, s));
			return (flight != null) ? ("clock bias=" + flight.ClockBias.ToString("F4") + ", tau=" + flight.ClockTau.ToString("F4") + ", target speed=" + ((Vector3)(ref flight.TargetVelocity)).magnitude.ToString("F2")) : "no flight";
		}
	}
	public sealed class GroznyjGradCatapultAudioProfile : ScriptableObject
	{
		[Serializable]
		public sealed class Cue
		{
			public AudioClip Intro;

			[Tooltip("Only the original bank's loop region, without its motor startup.")]
			public AudioClip Loop;

			[Range(0f, 1f)]
			public float Volume = 0.35f;
		}

		public sealed class Event
		{
			public readonly string Name;

			public readonly Cue Sound;

			public readonly bool AtSeat;

			public readonly bool TailOnly;

			public Event(string name, Cue sound, bool atSeat, bool tailOnly)
			{
				Name = name;
				Sound = sound;
				AtSeat = atSeat;
				TailOnly = tailOnly;
			}
		}

		public Cue Hop = new Cue();

		public Cue Latch = new Cue();

		public Cue Friction = new Cue();

		public Cue AxisMotor = new Cue();

		public Cue MotorEnd = new Cue();

		public Cue AxisStop = new Cue();

		public Cue Launch = new Cue();

		public Cue Winding = new Cue();

		public Cue HookMotor = new Cue();

		[Tooltip("Overall output trim used in the approved audition; individual cue levels remain unchanged.")]
		[Range(0f, 1f)]
		public float MasterVolume = 0.75f;

		public float MinDistance = 3f;

		public float MaxDistance = 45f;

		[Tooltip("Optional mixer routing. When unassigned, use H3VR's master mixer if present.")]
		public AudioMixerGroup Output;

		public Event[] Events(GroznyjGradCatapult.SequencePhase phase)
		{
			switch (phase)
			{
			case GroznyjGradCatapult.SequencePhase.Boarding:
				return new Event[1]
				{
					new Event("hop", Hop, atSeat: true, tailOnly: false)
				};
			case GroznyjGradCatapult.SequencePhase.Aiming:
				return new Event[3]
				{
					new Event("latch", Latch, atSeat: true, tailOnly: false),
					new Event("friction", Friction, atSeat: false, tailOnly: false),
					new Event("axisMotor", AxisMotor, atSeat: false, tailOnly: false)
				};
			case GroznyjGradCatapult.SequencePhase.Ready:
			case GroznyjGradCatapult.SequencePhase.Resetting:
				return new Event[2]
				{
					new Event("motorEnd", MotorEnd, atSeat: false, tailOnly: false),
					new Event("axisStop", AxisStop, atSeat: false, tailOnly: false)
				};
			case GroznyjGradCatapult.SequencePhase.Firing:
				return new Event[1]
				{
					new Event("launch", Launch, atSeat: true, tailOnly: false)
				};
			case GroznyjGradCatapult.SequencePhase.Returning:
				return new Event[4]
				{
					new Event("winding", Winding, atSeat: true, tailOnly: false),
					new Event("hookMotor", HookMotor, atSeat: true, tailOnly: false),
					new Event("friction", Friction, atSeat: false, tailOnly: false),
					new Event("axisMotor", AxisMotor, atSeat: false, tailOnly: true)
				};
			default:
				return new Event[0];
			}
		}
	}
	public sealed class GroznyjGradCatapultButton : FVRPointable
	{
		public GroznyjGradCatapultPlayer Player;

		public int Destination = -1;

		public Renderer Background;

		public TextMesh Label;

		private MaterialPropertyBlock colors;

		private float nextPress;

		public void SetColor(Color color)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!((Object)(object)Background == (Object)null))
			{
				if (colors == null)
				{
					colors = new MaterialPropertyBlock();
				}
				Background.GetPropertyBlock(colors);
				colors.SetColor("_Color", color);
				Background.SetPropertyBlock(colors);
			}
		}

		public override void OnPoint(FVRViveHand hand)
		{
			((FVRPointable)this).OnPoint(hand);
			if ((Object)(object)hand != (Object)null && hand.Input.TriggerDown)
			{
				Press();
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			if ((Object)(object)((Component)other).GetComponentInParent<FVRViveHand>() != (Object)null)
			{
				Press();
			}
		}

		private bool Press()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextPress || (Object)(object)Player == (Object)null || !Player.SelectDestination(Destination))
			{
				return false;
			}
			nextPress = Time.unscaledTime + 0.2f;
			if ((Object)(object)ManagerSingleton<GM>.Instance != (Object)null)
			{
				SM.PlayGlobalUISound((GlobalUISound)0, ((Component)this).transform.position);
			}
			return true;
		}
	}
	public sealed class GroznyjGradCatapultHandle : FVRInteractiveObject
	{
		public GroznyjGradCatapultPlayer Player;

		public override bool DoesFunctionAsGrabPoint()
		{
			return true;
		}

		public override bool IsInteractable()
		{
			return (Object)(object)Player != (Object)null && Player.CanGrab && ((FVRInteractiveObject)this).IsInteractable();
		}

		public override bool IsDistantGrabbable()
		{
			return false;
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			if (((FVRInteractiveObject)this).IsInteractable() && !((Object)(object)hand == (Object)null) && !((Object)(object)GM.CurrentMovementManager == (Object)null))
			{
				((FVRInteractiveObject)this).BeginInteraction(hand);
				if (!Player.BeginGrab(hand))
				{
					((FVRInteractiveObject)this).EndInteraction(hand);
					hand.EndInteractionIfHeld((FVRInteractiveObject)(object)this);
				}
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).EndInteraction(hand);
			if ((Object)(object)Player != (Object)null)
			{
				Player.EndGrab(hand);
			}
			if ((Object)(object)GM.CurrentMovementManager != (Object)null && (Object)(object)GM.CurrentPlayerBody != (Object)null && (Object)(object)hand != (Object)null && (Object)(object)hand.OtherHand != (Object)null)
			{
				GM.CurrentMovementManager.EndGrabPointMove(hand, Vector3.zero);
			}
		}

		public override Vector3 GetGrabMoveDelta()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			return (!((Object)(object)Player == (Object)null)) ? Player.GrabDelta : Vector3.zero;
		}
	}
	[HarmonyPatch(typeof(Sosig), "AttemptToRecoverFromBallistic")]
	internal static class GroznyjGradCatapultRecoveryPatch
	{
		private static bool Prefix(Sosig __instance)
		{
			GroznyjGradCatapultRecovery component = ((Component)__instance).GetComponent<GroznyjGradCatapultRecovery>();
			return (Object)(object)component == (Object)null || !((Behaviour)component).enabled || component.CanRecoverNow();
		}
	}
	[HarmonyPatch(typeof(Sosig), "LegsUpdate")]
	internal static class GroznyjGradCatapultTraversalPatch
	{
		private static bool Prefix(Sosig __instance)
		{
			if (GroznyjGradCatapult.FindRider(__instance, out var catapult))
			{
				catapult.UpdateSosigLook(__instance);
				return false;
			}
			if (GroznyjGradCatapult.FindWaiting(__instance, out catapult))
			{
				catapult.AdvanceWaiting(__instance);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Sosig), "TryToGetTo")]
	internal static class GroznyjGradCatapultPathIntentPatch
	{
		private static bool Prefix(Sosig __instance, Vector3 __0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !GroznyjGradCatapult.HoldPathRequest(__instance, __0);
		}
	}
	[HarmonyPatch(typeof(Sosig), "SetMovementState")]
	internal static class GroznyjGradCatapultMoveIntentPatch
	{
		private static bool Prefix(Sosig __instance, SosigMovementState __0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !GroznyjGradCatapult.HoldMovementRequest(__instance, __0);
		}
	}
	[HarmonyPatch(typeof(Sosig), "SetMovementSpeed")]
	internal static class GroznyjGradCatapultSpeedIntentPatch
	{
		private static bool Prefix(Sosig __instance, SosigMoveSpeed __0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !GroznyjGradCatapult.HoldSpeedRequest(__instance, __0);
		}
	}
	[HarmonyPatch(typeof(Sosig), "SetBodyPose")]
	internal static class GroznyjGradCatapultPoseIntentPatch
	{
		private static bool Prefix(Sosig __instance, SosigBodyPose __0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !GroznyjGradCatapult.HoldPoseRequest(__instance, __0);
		}
	}
	[HarmonyPatch(typeof(Sosig), "BodyUpdate")]
	internal static class GroznyjGradCatapultBodyMotionPatch
	{
		private static void Postfix(Sosig __instance)
		{
			GroznyjGradCatapult.AfterBodyUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(Sosig), "LegsUpdate_MoveToPoint")]
	internal static class GroznyjGradCatapultMovementPatch
	{
		private static bool Prefix(Sosig __instance)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent agent = __instance.Agent;
			if ((Object)(object)agent == (Object)null || !((Behaviour)agent).enabled || !agent.isOnOffMeshLink)
			{
				return true;
			}
			OffMeshLinkData currentOffMeshLinkData = agent.currentOffMeshLinkData;
			OffMeshLink offMeshLink = ((OffMeshLinkData)(ref currentOffMeshLinkData)).offMeshLink;
			if ((Object)(object)offMeshLink == (Object)null)
			{
				return true;
			}
			GroznyjGradCatapultRoute component = ((Component)offMeshLink).GetComponent<GroznyjGradCatapultRoute>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.Catapult == (Object)null)
			{
				return true;
			}
			component.Catapult.ArriveSosig(__instance, component);
			return false;
		}
	}
	[HarmonyPatch(typeof(Sosig), "EndLink")]
	internal static class GroznyjGradCatapultEndPatch
	{
		private static bool Prefix(Sosig __instance, bool success, out GroznyjGradCatapult __state)
		{
			if (!GroznyjGradCatapult.FindRider(__instance, out __state))
			{
				if (GroznyjGradCatapult.FindWaiting(__instance, out var catapult))
				{
					catapult.RemoveWaiting(__instance, repath: false);
				}
				return true;
			}
			if (__state.BeforeNativeEnd(__instance, success))
			{
				return true;
			}
			__state = null;
			return false;
		}

		private static void Postfix(Sosig __instance, bool success, GroznyjGradCatapult __state)
		{
			if ((Object)(object)__state != (Object)null)
			{
				__state.AfterNativeEnd(__instance, success);
			}
		}
	}
	[HarmonyPatch(typeof(Sosig), "SosigPhys")]
	internal static class GroznyjGradCatapultPhysicsPatch
	{
		internal struct FollowState
		{
			public bool Adjusted;

			public Vector3 FrameVelocity;

			public float Multiplier;

			public float Acceleration;
		}

		private static void Prefix(Sosig __instance, out FollowState __state)
		{
			//IL_0037: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			__state = default(FollowState);
			if (!GroznyjGradCatapult.FindRider(__instance, out var catapult))
			{
				return;
			}
			__instance.m_timeApart = 0f;
			if (!((Object)(object)__instance.CoreTarget == (Object)null) && (int)__instance.BodyState == 0 && !__instance.IsStunned)
			{
				__state.Adjusted = true;
				__state.Multiplier = __instance.AttachedPositionMultiplier;
				__state.Acceleration = __instance.AttachedPositionFudge;
				float num = Mathf.Max(0.001f, Time.deltaTime);
				float num2 = Mathf.Min(__state.Multiplier * num, 0.7f / Mathf.Max(0.001f, Time.fixedDeltaTime));
				__instance.AttachedPositionMultiplier = num2 / num;
				__instance.AttachedPositionFudge = Mathf.Max(__state.Acceleration, 1000f);
				if (num2 > 0.001f && catapult.TryGetCarriageVelocity(__instance, out var velocity))
				{
					__state.FrameVelocity = velocity;
					Rigidbody coreRB = __instance.CoreRB;
					coreRB.velocity -= velocity;
				}
			}
		}

		private static void Postfix(Sosig __instance, FollowState __state)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (__state.Adjusted)
			{
				if ((Object)(object)__instance.CoreRB != (Object)null)
				{
					Rigidbody coreRB = __instance.CoreRB;
					coreRB.velocity += __state.FrameVelocity;
				}
				__instance.AttachedPositionMultiplier = __state.Multiplier;
				__instance.AttachedPositionFudge = __state.Acceleration;
			}
		}
	}
	[DisallowMultipleComponent]
	public sealed class GroznyjGradCatapultPlayer : MonoBehaviour
	{
		public GroznyjGradCatapult Catapult;

		public GroznyjGradCatapultHandle Handle;

		public Transform Interface;

		public TextMesh Status;

		public GroznyjGradCatapultButton[] Buttons = new GroznyjGradCatapultButton[0];

		public GameObject ChairIndicator;

		public GameObject ReadyHighlight;

		public LineRenderer Trajectory;

		public float PreviewDistance = 4f;

		[Tooltip("Player flight speed relative to the shared route speed. Sosigs keep their own timing.")]
		[Range(0.25f, 1.5f)]
		public float FlightSpeedMultiplier = 0.75f;

		public Color Orange = new Color(1f, 0.55f, 0.12f, 1f);

		internal static GroznyjGradCatapultPlayer ActivePlayer;

		private FVRMovementManager movement;

		private FVRViveHand heldHand;

		private GroznyjGradCatapultRoute flightRoute;

		private Vector3 gripLocal;

		private Vector3 flightStart;

		private Vector3 flightVelocity;

		private float flightTime;

		private float flightDuration;

		private bool airborne;

		private bool automaticRelease;

		private bool oldForceControl;

		private readonly Vector3[] previewPoints = (Vector3[])(object)new Vector3[129];

		private int drawnDestination = -2;

		public int SelectedDestination { get; private set; }

		public bool IsControllingPlayer => (Object)(object)movement != (Object)null;

		public bool IsAirborne => airborne;

		public string DisplayState { get; private set; }

		internal static bool HoldActive => (Object)(object)ManagerSingleton<GM>.Instance != (Object)null && (Object)(object)GM.TNH_Manager != (Object)null && (int)GM.TNH_Manager.Phase == 1;

		internal static bool RampartActive => (Object)(object)ManagerSingleton<GM>.Instance != (Object)null && (Object)(object)GM.TNH_Manager != (Object)null && (int)GM.TNH_Manager.GameMode == 2;

		internal static bool PlayerUseBlocked => HoldActive || RampartActive;

		public bool CanSelect => !PlayerUseBlocked && (Object)(object)Catapult != (Object)null && !Catapult.IsBusy && Catapult.WaitingCount == 0 && (Object)(object)ActivePlayer == (Object)null;

		public bool CanGrab => CanSelect && SelectedDestination >= 0 && ValidDestination(SelectedDestination);

		public Vector3 GrabDelta => (!((Object)(object)heldHand == (Object)null)) ? (((Component)Handle).transform.TransformPoint(gripLocal) - ((Component)heldHand).transform.position) : Vector3.zero;

		internal Vector3 MovementAudioVelocity => (!airborne) ? Vector3.zero : flightVelocity;

		private void OnEnable()
		{
			SelectedDestination = -1;
			if ((Object)(object)Catapult != (Object)null)
			{
				Catapult.PhaseChanged += PhaseChanged;
				Catapult.LaunchReleased += Release;
				Catapult.RiderFlightFinished += RiderFinished;
			}
			RefreshFeedback();
		}

		private void OnDisable()
		{
			if ((Object)(object)Catapult != (Object)null)
			{
				Catapult.PhaseChanged -= PhaseChanged;
				Catapult.LaunchReleased -= Release;
				Catapult.RiderFlightFinished -= RiderFinished;
				if (IsControllingPlayer)
				{
					if (!airborne)
					{
						Catapult.DetachBeforeLaunch((Object)(object)this);
					}
					else
					{
						Catapult.NotifyFlightComplete((Object)(object)this, success: false);
					}
				}
			}
			EndControl();
			SelectedDestination = -1;
			if ((Object)(object)ReadyHighlight != (Object)null)
			{
				ReadyHighlight.SetActive(false);
			}
			if ((Object)(object)Trajectory != (Object)null)
			{
				((Renderer)Trajectory).enabled = false;
			}
		}

		private bool ValidDestination(int index)
		{
			return (Object)(object)Catapult != (Object)null && index >= 0 && index < Catapult.Routes.Length && (Object)(object)Catapult.Routes[index] != (Object)null && Catapult.Routes[index].HasValidConfiguration();
		}

		public bool SelectDestination(int index)
		{
			if (!CanSelect || (index >= 0 && !ValidDestination(index)))
			{
				return false;
			}
			SelectedDestination = ((index >= 0) ? index : (-1));
			drawnDestination = -2;
			RefreshFeedback();
			return true;
		}

		internal bool BeginGrab(FVRViveHand hand)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			FVRMovementManager currentMovementManager = GM.CurrentMovementManager;
			if (!CanGrab || (Object)(object)currentMovementManager == (Object)null || (Object)(object)GM.CurrentPlayerBody == (Object)null || currentMovementManager.isForceControlled)
			{
				return false;
			}
			GroznyjGradCatapultRoute route = Catapult.Routes[SelectedDestination];
			movement = currentMovementManager;
			heldHand = hand;
			flightRoute = route;
			gripLocal = ((Component)Handle).transform.InverseTransformPoint(((Component)hand).transform.position);
			oldForceControl = currentMovementManager.isForceControlled;
			ActivePlayer = this;
			airborne = false;
			currentMovementManager.CleanupFlagsForModeSwitch();
			currentMovementManager.ClearInProgressTeleportAction();
			currentMovementManager.isForceControlled = true;
			if (!Catapult.TryBeginSequence(route, (Object)(object)this))
			{
				EndControl();
				return false;
			}
			RefreshFeedback();
			return true;
		}

		internal void EndGrab(FVRViveHand hand)
		{
			if (!automaticRelease && !((Object)(object)hand != (Object)(object)heldHand) && !airborne && IsControllingPlayer)
			{
				heldHand = null;
				Catapult.DetachBeforeLaunch((Object)(object)this);
				EndControl();
				SelectedDestination = -1;
				RefreshFeedback();
			}
		}

		private void PhaseChanged(GroznyjGradCatapult.SequencePhase phase)
		{
			if (phase == GroznyjGradCatapult.SequencePhase.Boarding)
			{
				SelectedDestination = -1;
				drawnDestination = -2;
			}
			RefreshFeedback();
		}

		private void Release(GroznyjGradCatapultRoute route)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (!IsControllingPlayer || airborne || Catapult.Rider != (Object)(object)this || (Object)(object)route != (Object)(object)flightRoute)
			{
				return;
			}
			if (PlayerUseBlocked)
			{
				Catapult.NotifyFlightComplete((Object)(object)this, success: false);
				return;
			}
			Translate(GrabDelta);
			flightStart = PlayerFeet();
			flightTime = 0f;
			airborne = true;
			flightDuration = flightRoute.FlightDuration(flightStart, flightRoute.Link.endTransform.position) / Mathf.Clamp(FlightSpeedMultiplier, 0.25f, 1.5f);
			flightVelocity = Vector3.zero;
			Catapult.SetPlayerFlightDuration((Object)(object)this, flightDuration);
			automaticRelease = true;
			try
			{
				if ((Object)(object)heldHand != (Object)null)
				{
					((FVRInteractiveObject)Handle).EndInteraction(heldHand);
					heldHand.EndInteractionIfHeld((FVRInteractiveObject)(object)Handle);
				}
			}
			finally
			{
				heldHand = null;
				automaticRelease = false;
			}
			RefreshFeedback();
		}

		private void RiderFinished(Object rider, bool success)
		{
			if (rider == (Object)(object)this && IsControllingPlayer)
			{
				EndControl();
			}
		}

		private Vector3 PlayerFeet()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((!((Object)(object)GM.CurrentPlayerBody == (Object)null)) ? GM.CurrentPlayerBody.Head : null);
			return (Vector3)((!((Object)(object)val == (Object)null)) ? new Vector3(val.position.x, ((Component)movement).transform.position.y, val.position.z) : ((Component)movement).transform.position);
		}

		private void Translate(Vector3 delta)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)movement == (Object)null))
			{
				Transform transform = ((Component)movement).transform;
				transform.position += delta;
				movement.ResetNeckPoses();
				if ((Object)(object)movement.Body != (Object)null)
				{
					movement.Body.UpdatePlayerBodyPositions();
					movement.Body.MoveQuickbeltContentsCheap(delta);
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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_01cb: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: 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)
			if (PlayerUseBlocked)
			{
				if (SelectedDestination >= 0)
				{
					SelectedDestination = -1;
					drawnDestination = -2;
				}
				if (IsControllingPlayer && !airborne)
				{
					Catapult.DetachBeforeLaunch((Object)(object)this);
					if (IsControllingPlayer)
					{
						EndControl();
					}
				}
			}
			if (IsControllingPlayer)
			{
				if ((Object)(object)GM.CurrentMovementManager != (Object)(object)movement || (Object)(object)GM.CurrentPlayerBody == (Object)null)
				{
					if (!airborne)
					{
						Catapult.DetachBeforeLaunch((Object)(object)this);
					}
					else
					{
						Catapult.NotifyFlightComplete((Object)(object)this, success: false);
					}
					EndControl();
				}
				else if (!airborne)
				{
					if ((Object)(object)heldHand == (Object)null || (Object)(object)heldHand.CurrentInteractable != (Object)(object)Handle)
					{
						EndGrab(heldHand);
					}
					else
					{
						Translate(GrabDelta);
					}
				}
				else
				{
					flightTime += Time.deltaTime;
					ApplySmoothTurn();
					float num = Mathf.Clamp01(flightTime / flightDuration);
					Vector3 val = flightRoute.EvaluateFlight(flightStart, flightRoute.Link.endTransform.position, num);
					Vector3 val2 = flightRoute.EvaluateFlight(flightStart, flightRoute.Link.endTransform.position, Mathf.Clamp01((flightTime - Time.deltaTime) / flightDuration));
					flightVelocity = (val - val2) / Mathf.Max(0.001f, Time.deltaTime);
					Translate(val - PlayerFeet());
					if (num >= 1f)
					{
						Catapult.NotifyFlightComplete((Object)(object)this, success: true);
					}
				}
			}
			UpdateTrajectory();
			RefreshFeedback();
		}

		private void EndControl()
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			FVRMovementManager val = movement;
			automaticRelease = true;
			try
			{
				if ((Object)(object)heldHand != (Object)null && (Object)(object)heldHand.CurrentInteractable == (Object)(object)Handle)
				{
					((FVRInteractiveObject)Handle).EndInteraction(heldHand);
					heldHand.EndInteractionIfHeld((FVRInteractiveObject)(object)Handle);
				}
			}
			finally
			{
				automaticRelease = false;
				heldHand = null;
			}
			if ((Object)(object)val != (Object)null)
			{
				val.isForceControlled = oldForceControl;
				if ((Object)(object)GM.CurrentPlayerBody != (Object)null && (Object)(object)GM.CurrentPlayerBody.NeckJointTransform != (Object)null)
				{
					val.CleanupFlagsForModeSwitch();
					val.ResetNeckPoses();
				}
				val.m_smoothLocoVelocity = Vector3.zero;
				val.SetFrameSpeed(Vector3.zero);
				val.DelayGround(0.05f);
			}
			movement = null;
			flightRoute = null;
			airborne = false;
			flightVelocity = Vector3.zero;
			if ((Object)(object)ActivePlayer == (Object)(object)this)
			{
				ActivePlayer = null;
			}
		}

		public void RefreshFeedback()
		{
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: 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_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			bool canGrab = CanGrab;
			if ((Object)(object)ReadyHighlight != (Object)null && ReadyHighlight.activeSelf != canGrab)
			{
				ReadyHighlight.SetActive(canGrab);
			}
			if ((Object)(object)ChairIndicator != (Object)null && ChairIndicator.activeSelf != CanSelect)
			{
				ChairIndicator.SetActive(CanSelect);
			}
			DisplayState = (((Object)(object)Catapult == (Object)null) ? "Not configured" : (RampartActive ? "UNAVAILABLE\nIN RAMPART" : (HoldActive ? "UNAVAILABLE\nDURING HOLD" : ((!Catapult.IsBusy) ? ((!canGrab) ? "SELECT\nDESTINATION" : "LAUNCH READY\nGRAB HANDLE") : ((Catapult.Phase == GroznyjGradCatapult.SequencePhase.Boarding) ? "BOARDING" : ((Catapult.Phase == GroznyjGradCatapult.SequencePhase.Aiming) ? "AIMING" : ((Catapult.Phase == GroznyjGradCatapult.SequencePhase.Ready) ? "HOLD HANDLE\nLAUNCH IMMINENT" : ((Catapult.Phase != GroznyjGradCatapult.SequencePhase.Firing && Catapult.Phase != GroznyjGradCatapult.SequencePhase.EndStop) ? "RESETTING" : "LAUNCHING"))))))));
			if ((Object)(object)Status != (Object)null && Status.text != DisplayState)
			{
				Status.text = DisplayState;
			}
			GroznyjGradCatapultButton[] buttons = Buttons;
			foreach (GroznyjGradCatapultButton groznyjGradCatapultButton in buttons)
			{
				if (!((Object)(object)groznyjGradCatapultButton == (Object)null) && !((Object)(object)groznyjGradCatapultButton.Background == (Object)null))
				{
					bool flag = canGrab && groznyjGradCatapultButton.Destination == SelectedDestination;
					groznyjGradCatapultButton.SetColor((Color)((!flag) ? new Color(0.045f, 0.055f, 0.055f, 0.97f) : Orange));
					if ((Object)(object)groznyjGradCatapultButton.Label != (Object)null)
					{
						groznyjGradCatapultButton.Label.color = (Color)((groznyjGradCatapultButton.Destination < 0) ? new Color(1f, 0.25f, 0.15f) : (flag ? new Color(0.035f, 0.04f, 0.04f) : ((!CanSelect) ? new Color(0.45f, 0.4f, 0.3f) : Orange)));
					}
				}
			}
		}

		private void UpdateTrajectory()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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)
			if ((Object)(object)Trajectory == (Object)null)
			{
				return;
			}
			FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody;
			Transform val = ((!((Object)(object)currentPlayerBody == (Object)null)) ? currentPlayerBody.Head : null);
			bool flag = CanGrab && (Object)(object)Interface != (Object)null && (Object)(object)val != (Object)null && Vector3.Distance(val.position, Interface.position) < PreviewDistance;
			((Renderer)Trajectory).enabled = flag;
			if (!flag || drawnDestination == SelectedDestination)
			{
				return;
			}
			GroznyjGradCatapultRoute groznyjGradCatapultRoute = Catapult.Routes[SelectedDestination];
			if (!Catapult.TryGetReleasePosition(groznyjGradCatapultRoute, out var release))
			{
				((Renderer)Trajectory).enabled = false;
				return;
			}
			for (int i = 0; i < previewPoints.Length; i++)
			{
				ref Vector3 reference = ref previewPoints[i];
				reference = groznyjGradCatapultRoute.EvaluateFlight(release, groznyjGradCatapultRoute.Link.endTransform.position, (float)i / 128f);
			}
			Trajectory.positionCount = previewPoints.Length;
			Trajectory.SetPositions(previewPoints);
			drawnDestination = SelectedDestination;
		}

		internal static bool OwnsMovement(FVRMovementManager manager)
		{
			return (Object)(object)ActivePlayer != (Object)null && ActivePlayer.IsControllingPlayer && (Object)(object)ActivePlayer.movement == (Object)(object)manager;
		}

		internal Vector3 BeginTurnInput()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return PlayerFeet();
		}

		internal void EndTurnInput(Vector3 feet)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Translate(feet - PlayerFeet());
			movement.ClearInProgressTeleportAction();
		}

		private void ApplySmoothTurn()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			bool isTwinStickSmoothTurningCounterClockwise = movement.m_isTwinStickSmoothTurningCounterClockwise;
			bool isTwinStickSmoothTurningClockwise = movement.m_isTwinStickSmoothTurningClockwise;
			if (isTwinStickSmoothTurningCounterClockwise != isTwinStickSmoothTurningClockwise && GM.Options != null && GM.Options.MovementOptions != null)
			{
				MovementOptions movementOptions = GM.Options.MovementOptions;
				float num = movementOptions.SmoothTurnMagnitudes[movementOptions.SmoothTurnMagnitudeIndex] * Time.deltaTime * (float)((!isTwinStickSmoothTurningCounterClockwise) ? 1 : (-1));
				((Component)movement).transform.RotateAround(PlayerFeet(), Vector3.up, num);
			}
		}
	}
	[HarmonyPatch(typeof(FVRMovementManager), "Update")]
	internal static class GroznyjGradCatapultPlayerAirSoundPatch
	{
		internal struct AudioState
		{
			public bool Guided;

			public bool GrabHolding;
		}

		private static void Prefix(FVRMovementManager __instance, ref bool ___dirSetThisFrame, ref bool ___m_isGrounded, ref bool ___IsGrabHolding, out AudioState __state)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			__state = default(AudioState);
			if (GroznyjGradCatapultPlayer.OwnsMovement(__instance))
			{
				GroznyjGradCatapultPlayer activePlayer = GroznyjGradCatapultPlayer.ActivePlayer;
				___dirSetThisFrame = false;
				__instance.SetFrameSpeed(activePlayer.MovementAudioVelocity);
				if (activePlayer.IsAirborne)
				{
					___m_isGrounded = false;
					__state.Guided = true;
					__state.GrabHolding = ___IsGrabHolding;
					___IsGrabHolding = true;
				}
			}
		}

		private static void Postfix(ref bool ___IsGrabHolding, AudioState __state)
		{
			if (__state.Guided)
			{
				___IsGrabHolding = __state.GrabHolding;
			}
		}
	}
	[HarmonyPatch(typeof(FVRMovementManager), "FU")]
	internal static class GroznyjGradCatapultPlayerMovementPatch
	{
		private static bool Prefix(FVRMovementManager __instance)
		{
			return !GroznyjGradCatapultPlayer.OwnsMovement(__instance);
		}
	}
	[HarmonyPatch(typeof(FVRMovementManager), "UpdateMovementWithHand")]
	internal static class GroznyjGradCatapultPlayerInputPatch
	{
		internal struct InputState
		{
			public bool Turning;

			public Vector3 Feet;
		}

		private static bool Prefix(FVRMovementManager __instance, out InputState __state)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			__state = default(InputState);
			if (!GroznyjGradCatapultPlayer.OwnsMovement(__instance))
			{
				return true;
			}
			GroznyjGradCatapultPlayer activePlayer = GroznyjGradCatapultPlayer.ActivePlayer;
			if (!activePlayer.IsAirborne)
			{
				return false;
			}
			__state.Turning = true;
			__state.Feet = activePlayer.BeginTurnInput();
			return true;
		}

		private static void Postfix(FVRMovementManager __instance, InputState __state)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (__state.Turning && GroznyjGradCatapultPlayer.OwnsMovement(__instance))
			{
				GroznyjGradCatapultPlayer.ActivePlayer.EndTurnInput(__state.Feet);
			}
		}
	}
	[HarmonyPatch(typeof(FVRMovementManager), "TeleportToPoint", new Type[]
	{
		typeof(Vector3),
		typeof(bool)
	})]
	internal static class GroznyjGradCatapultPlayerTeleportPatch
	{
		private static bool Prefix(FVRMovementManager __instance, ref float __result)
		{
			if (!GroznyjGradCatapultPlayer.OwnsMovement(__instance))
			{
				return true;
			}
			__result = 0f;
			return false;
		}
	}
	[HarmonyPatch(typeof(FVRMovementManager), "Jump")]
	internal static class GroznyjGradCatapultPlayerJumpPatch
	{
		private static bool Prefix(FVRMovementManager __instance)
		{
			return !GroznyjGradCatapultPlayer.OwnsMovement(__instance);
		}
	}
	[DisallowMultipleComponent]
	public sealed class GroznyjGradCatapultRecovery : MonoBehaviour
	{
		internal enum Result
		{
			Pending,
			Reachable,
			Unreachable
		}

		private Sosig sosig;

		private NavMeshPath path;

		private Vector3 destination;

		private Vector3 stillPosition;

		private int areaMask;

		private int geometryMask;

		private float eligibleAt;

		private float startedAt;

		private float nextCheck;

		private float delay;

		private float stillSeconds;

		private float timeout;

		private float failedSince = -1f;

		private float stillSince = -1f;

		private bool resumed;

		public string Status { get; private set; }

		internal static void Watch(Sosig rider, Vector3 target, float deathDelay, float airborneGrace, float stationarySeconds, float stumbleTimeout)
		{
			//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)
			if (!((Object)(object)rider == (Object)null) && !((Object)(object)rider.Agent == (Object)null) && !((Object)(object)rider.CoreRB == (Object)null) && ((Component)rider).gameObject.activeInHierarchy)
			{
				GroznyjGradCatapultRecovery groznyjGradCatapultRecovery = ((Component)rider).GetComponent<GroznyjGradCatapultRecovery>();
				if ((Object)(object)groznyjGradCatapultRecovery == (Object)null)
				{
					groznyjGradCatapultRecovery = ((Component)rider).gameObject.AddComponent<GroznyjGradCatapultRecovery>();
				}
				groznyjGradCatapultRecovery.sosig = rider;
				groznyjGradCatapultRecovery.destination = target;
				groznyjGradCatapultRecovery.areaMask = rider.Agent.areaMask;
				groznyjGradCatapultRecovery.geometryMask = LayerMask.GetMask(new string[3] { "Default", "Environment", "NavBlock" });
				groznyjGradCatapultRecovery.delay = deathDelay;
				groznyjGradCatapultRecovery.stillSeconds = stationarySeconds;
				groznyjGradCatapultRecovery.timeout = stumbleTimeout;
				groznyjGradCatapultRecovery.startedAt = Time.time;
				groznyjGradCatapultRecovery.eligibleAt = Time.time + airborneGrace;
				groznyjGradCatapultRecovery.nextCheck = groznyjGradCatapultRecovery.eligibleAt;
				groznyjGradCatapultRecovery.failedSince = (groznyjGradCatapultRecovery.stillSince = -1f);
				groznyjGradCatapultRecovery.resumed = false;
				groznyjGradCatapultRecovery.Status = "waiting for fall/landing";
				((Behaviour)groznyjGradCatapultRecovery).enabled = true;
			}
		}

		private void Update()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sosig == (Object)null || (Object)(object)sosig.CoreRB == (Object)null || (int)sosig.BodyState == 3)
			{
				Retire();
				return;
			}
			if ((int)sosig.BodyState == 2)
			{
				if (Time.time - startedAt >= timeout)
				{
					Die("stumbling timeout");
					return;
				}
				float time = Time.time;
				Vector3 position = sosig.CoreRB.position;
				Vector3 velocity = sosig.CoreRB.velocity;
				TrackStillness(time, position, ((Vector3)(ref velocity)).sqrMagnitude);
				Status = ((!(stillSince < 0f)) ? "settling before native get-up" : "stumbling");
				if (!CanRecoverNow())
				{
					return;
				}
				sosig.m_ballisticRecoveryAttemptTick = -1f;
				sosig.AttemptToRecoverFromBallistic();
				if ((int)sosig.BodyState != 0)
				{
					return;
				}
			}
			if ((int)sosig.BodyState != 0 || sosig.m_isOnOffMeshLink || (Time.time < eligibleAt && !sosig.m_recoveringFromBallisticState))
			{
				return;
			}
			NavMeshAgent agent = sosig.Agent;
			if (!resumed && ((Behaviour)agent).enabled && agent.isOnNavMesh)
			{
				agent.SetDestination(destination);
				agent.Resume();
				resumed = true;
				Debug.Log((object)("Catapult rider resumed its travel target after native recovery: " + ((Object)sosig).name));
			}
			if (sosig.m_recoveringFromBallisticState)
			{
				Status = "getting up";
			}
			else if (!(Time.time < nextCheck))
			{
				nextCheck = Time.time + 0.25f;
				Result result = CheckBody(sosig.CoreRB.position);
				Status = ((result != Result.Unreachable) ? "checking travel path" : "no complete path to travel target");
				if (result ==