Decompiled source of JevZiplines v1.0.0

JevZiplines.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JevZiplines.Components;
using JevZiplines.Config;
using JevZiplines.Content;
using JevZiplines.Features;
using JevZiplines.Infrastructure;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("JevZiplines")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5bca580f9db5186b6b95f07b608d99ed8b8b8b16")]
[assembly: AssemblyProduct("JevZiplines")]
[assembly: AssemblyTitle("JevZiplines")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace JevZiplines
{
	[BepInPlugin("JevMods.JevZiplines", "JevZiplines", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "JevMods.JevZiplines";

		public const string PluginName = "JevZiplines";

		private IFeature[] _features;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			GameEvents events = (GameEvents.Instance = new GameEvents());
			ModSettings settings = new ModSettings(((BaseUnityPlugin)this).Config);
			CableSession session = new CableSession(new CableValidator(settings));
			RideFeature rideFeature = new RideFeature(events, settings, new RideEffects());
			_features = new IFeature[4]
			{
				rideFeature,
				new CableFeature(events, session),
				new CablePreviewFeature(events, session),
				new BoardingFeature(events, rideFeature)
			};
			IFeature[] features = _features;
			for (int i = 0; i < features.Length; i++)
			{
				features[i].Enable();
			}
			Translations.Register();
			PrefabManager.OnVanillaPrefabsAvailable += ZiplineContent.Register;
			_harmony = new Harmony("JevMods.JevZiplines");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			PrefabManager.OnVanillaPrefabsAvailable -= ZiplineContent.Register;
			if (_features != null)
			{
				IFeature[] features = _features;
				for (int i = 0; i < features.Length; i++)
				{
					features[i].Disable();
				}
			}
			GameEvents.Instance = null;
		}
	}
	internal static class BuildInfo
	{
		public const string Version = "1.0.0";
	}
}
namespace JevZiplines.Patches
{
	internal static class PlayerPatches
	{
		[HarmonyPatch(typeof(Player), "Update")]
		private static class Update
		{
			private static void Postfix(Player __instance)
			{
				if (IsLocalPlayer((Character)(object)__instance))
				{
					GameEvents.Instance?.RaiseLocalPlayerUpdate(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Character), "CustomFixedUpdate")]
		private static class FixedUpdate
		{
			private static void Prefix(Character __instance)
			{
				if (IsLocalPlayer(__instance))
				{
					GameEvents.Instance?.RaiseLocalPlayerFixedUpdating(Player.m_localPlayer);
				}
			}

			private static void Postfix(Character __instance)
			{
				if (IsLocalPlayer(__instance))
				{
					GameEvents.Instance?.RaiseLocalPlayerFixedUpdate(Player.m_localPlayer);
				}
			}
		}

		private static bool IsLocalPlayer(Character character)
		{
			if ((Object)(object)character != (Object)null)
			{
				return (Object)(object)character == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}
	}
}
namespace JevZiplines.Infrastructure
{
	public sealed class GameEvents : IGameEvents
	{
		internal static GameEvents Instance { get; set; }

		public event Action<ZiplinePost, Player> PostInteracted;

		public event Action<ZiplinePost, StringBuilder> PostHovered;

		public event Action<CableGrip, Player> CableGrabbed;

		public event Action<CableGrip, StringBuilder> CableHovered;

		public event Action<Plug, Player, bool> WingInteracted;

		public event Action<Plug, StringBuilder> WingHovered;

		public event Action<Player> LocalPlayerUpdate;

		public event Action<Player> LocalPlayerFixedUpdating;

		public event Action<Player> LocalPlayerFixedUpdate;

		internal void RaisePostInteracted(ZiplinePost post, Player player)
		{
			this.PostInteracted?.Invoke(post, player);
		}

		internal void RaisePostHovered(ZiplinePost post, StringBuilder text)
		{
			this.PostHovered?.Invoke(post, text);
		}

		internal void RaiseCableGrabbed(CableGrip grip, Player player)
		{
			this.CableGrabbed?.Invoke(grip, player);
		}

		internal void RaiseCableHovered(CableGrip grip, StringBuilder text)
		{
			this.CableHovered?.Invoke(grip, text);
		}

		internal void RaiseWingInteracted(Plug plug, Player player, bool alt)
		{
			this.WingInteracted?.Invoke(plug, player, alt);
		}

		internal void RaiseWingHovered(Plug plug, StringBuilder text)
		{
			this.WingHovered?.Invoke(plug, text);
		}

		internal void RaiseLocalPlayerUpdate(Player player)
		{
			this.LocalPlayerUpdate?.Invoke(player);
		}

		internal void RaiseLocalPlayerFixedUpdating(Player player)
		{
			this.LocalPlayerFixedUpdating?.Invoke(player);
		}

		internal void RaiseLocalPlayerFixedUpdate(Player player)
		{
			this.LocalPlayerFixedUpdate?.Invoke(player);
		}
	}
	internal static class GrappleAssets
	{
		private static readonly Color SteelColor = new Color(0.2f, 0.2f, 0.22f);

		internal static Material Cable { get; private set; }

		internal static Material Steel { get; private set; }

		internal static StatusEffect Effect { get; private set; }

		internal static GameObject PullSound { get; private set; }

		internal static EffectList DoneEffect { get; private set; }

		internal static EffectList LetGoEffect { get; private set; }

		internal static void Load(GameObject grapplingPoint)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			GrapplingPoint component = grapplingPoint.GetComponent<GrapplingPoint>();
			Material sharedMaterial = ((Renderer)grapplingPoint.GetComponent<LineRenderer>()).sharedMaterial;
			Cable = new Material(sharedMaterial);
			Cable.SetFloat("_Glossiness", 0f);
			Cable.SetFloat("_Metallic", 0f);
			Steel = new Material(sharedMaterial)
			{
				mainTexture = null,
				color = SteelColor
			};
			Steel.SetFloat("_Glossiness", 0.35f);
			Steel.SetFloat("_Metallic", 0.6f);
			Effect = (StatusEffect)(object)component.m_grappledSE;
			PullSound = component.m_pullSound;
			DoneEffect = component.m_doneEffect;
			LetGoEffect = component.m_breakEarlyEffect;
		}
	}
	public interface IFeature
	{
		void Enable();

		void Disable();
	}
	public interface IGameEvents
	{
		event Action<ZiplinePost, Player> PostInteracted;

		event Action<ZiplinePost, StringBuilder> PostHovered;

		event Action<CableGrip, Player> CableGrabbed;

		event Action<CableGrip, StringBuilder> CableHovered;

		event Action<Plug, Player, bool> WingInteracted;

		event Action<Plug, StringBuilder> WingHovered;

		event Action<Player> LocalPlayerUpdate;

		event Action<Player> LocalPlayerFixedUpdating;

		event Action<Player> LocalPlayerFixedUpdate;
	}
}
namespace JevZiplines.Features
{
	public sealed class BoardingFeature : IFeature
	{
		private const float BehindPenalty = 100f;

		private readonly IGameEvents _events;

		private readonly IRideController _ride;

		private readonly List<(Plug From, Plug To)> _departures = new List<(Plug, Plug)>();

		public BoardingFeature(IGameEvents events, IRideController ride)
		{
			_events = events;
			_ride = ride;
		}

		public void Enable()
		{
			_events.PostHovered += OnPostHovered;
			_events.PostInteracted += OnPostInteracted;
			_events.CableHovered += OnCableHovered;
			_events.CableGrabbed += OnCableGrabbed;
		}

		public void Disable()
		{
			_events.PostHovered -= OnPostHovered;
			_events.PostInteracted -= OnPostInteracted;
			_events.CableHovered -= OnCableHovered;
			_events.CableGrabbed -= OnCableGrabbed;
		}

		private static void DescribeRide(StringBuilder text)
		{
			HoverText.Action(text, "$jevzip_ride");
			HoverText.KeyHint(text, "$KEY_Jump", "$jevzip_letgo");
		}

		private void OnPostHovered(ZiplinePost post, StringBuilder text)
		{
			CollectDepartures(post);
			if (_departures.Count > 0)
			{
				DescribeRide(text);
			}
			else if (post.HasCable())
			{
				HoverText.Hint(text, "$jevzip_msg_uphill");
			}
			else
			{
				HoverText.Hint(text, "$jevzip_hint_wing");
			}
		}

		private void OnPostInteracted(ZiplinePost post, Player player)
		{
			if ((Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			CollectDepartures(post);
			if (_departures.Count == 0)
			{
				if (post.HasCable())
				{
					CableMessages.Show(player, "$jevzip_msg_uphill");
				}
			}
			else
			{
				(Plug, Plug) tuple = NearestFacingDeparture(player);
				_ride.Start(player, tuple.Item1, tuple.Item2, 0.5f);
			}
		}

		private void OnCableHovered(CableGrip grip, StringBuilder text)
		{
			DescribeRide(text);
		}

		private void OnCableGrabbed(CableGrip grip, Player player)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009b: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player != (Object)(object)Player.m_localPlayer) && grip.Start.Exists && grip.End.Exists)
			{
				bool isDownhill = grip.Start.SpanTo(grip.End).IsDownhill;
				Plug plug = (isDownhill ? grip.Start : grip.End);
				Plug plug2 = (isDownhill ? grip.End : grip.Start);
				CableSpan cableSpan = plug.SpanTo(plug2);
				Vector3 val = ((Component)player).transform.position + Vector3.up * 2.15f - cableSpan.From;
				Vector3 val2 = cableSpan.To - cableSpan.From;
				float startDistance = Vector3.Dot(val, ((Vector3)(ref val2)).normalized);
				_ride.Start(player, plug, plug2, startDistance);
			}
		}

		private void CollectDepartures(ZiplinePost post)
		{
			_departures.Clear();
			for (int i = 0; i < 2; i++)
			{
				Plug item = new Plug(post, i);
				for (int j = 0; j < 2; j++)
				{
					if (item.TryGetFar(j, out var far) && item.SpanTo(far).IsDownhill)
					{
						_departures.Add((item, far));
					}
				}
			}
		}

		private (Plug From, Plug To) NearestFacingDeparture(Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 lookDir = ((Character)player).GetLookDir();
			(Plug, Plug) result = _departures[0];
			float num = float.MinValue;
			foreach (var departure in _departures)
			{
				Vector3 val = departure.To.Anchor - departure.From.Anchor;
				Vector3 val2 = departure.From.Anchor - ((Component)player).transform.position;
				val2.y = 0f;
				float num2 = 0f - ((Vector3.Dot(lookDir, val) < 0f) ? 100f : 0f) - ((Vector3)(ref val2)).magnitude;
				if (num2 > num)
				{
					num = num2;
					result = departure;
				}
			}
			return result;
		}
	}
	public enum CableCheck
	{
		Ok,
		TooShort,
		TooLong,
		TooFlat,
		TooLow,
		Blocked,
		SamePost,
		Taken,
		Busy,
		Across
	}
	public sealed class CableFeature : IFeature
	{
		private const float SlipFactor = 2f;

		private readonly IGameEvents _events;

		private readonly ICableSession _session;

		public CableFeature(IGameEvents events, ICableSession session)
		{
			_events = events;
			_session = session;
		}

		public void Enable()
		{
			_events.WingHovered += OnHovered;
			_events.WingInteracted += OnInteracted;
			_events.LocalPlayerUpdate += OnUpdate;
		}

		public void Disable()
		{
			_events.WingHovered -= OnHovered;
			_events.WingInteracted -= OnInteracted;
			_events.LocalPlayerUpdate -= OnUpdate;
		}

		private static int NearSide(Plug plug, Player player)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			int num = plug.Post.SideToward(((Component)player).transform.position);
			if (!plug.IsPlugged(num))
			{
				return 1 - num;
			}
			return num;
		}

		private string LengthLabel(float length)
		{
			return string.Format(CultureInfo.InvariantCulture, " ({0:0} / {1:0} m)", length, _session.MaxLength);
		}

		private void OnHovered(Plug plug, StringBuilder text)
		{
			Plug? carried = _session.Carried;
			if (carried.HasValue)
			{
				DescribeConnection(carried.Value, plug, text);
				return;
			}
			if (_session.IsHeld(plug))
			{
				HoverText.Refusal(text, CableMessages.For(CableCheck.Busy));
				return;
			}
			bool flag = Chains.CanPay(Player.m_localPlayer);
			if (plug.HasCable)
			{
				HoverText.Action(text, "$jevzip_take");
				if (flag && !plug.IsFull)
				{
					HoverText.AltAction(text, "$jevzip_string_more ($item_chain x1)");
				}
			}
			else if (flag)
			{
				HoverText.Action(text, "$jevzip_string ($item_chain x1)");
			}
			else
			{
				HoverText.Refusal(text, "$msg_missingrequirement: $item_chain");
			}
		}

		private void DescribeConnection(Plug carried, Plug plug, StringBuilder text)
		{
			if (carried.Is(plug))
			{
				HoverText.Action(text, "$jevzip_remove");
				return;
			}
			CableCheck cableCheck = _session.Check(plug);
			string text2 = LengthLabel(carried.SpanTo(plug).Length);
			switch (cableCheck)
			{
			case CableCheck.Ok:
				HoverText.Action(text, "$jevzip_connect" + text2);
				break;
			case CableCheck.TooShort:
			case CableCheck.TooLong:
				HoverText.Refusal(text, CableMessages.For(cableCheck) + text2);
				break;
			default:
				HoverText.Refusal(text, CableMessages.For(cableCheck));
				break;
			}
		}

		private void OnInteracted(Plug plug, Player player, bool alt)
		{
			if (!((Object)(object)player != (Object)(object)Player.m_localPlayer))
			{
				Plug? carried = _session.Carried;
				bool flag = alt && plug.IsFull;
				if (carried.HasValue && carried.Value.Is(plug))
				{
					_session.Cancel(player);
					CableMessages.Show(player, "$jevzip_msg_removed");
				}
				else if (carried.HasValue)
				{
					CableMessages.Show(player, CableMessages.For(_session.Connect(player, plug)));
				}
				else if (_session.IsHeld(plug))
				{
					CableMessages.Show(player, CableMessages.For(CableCheck.Busy));
				}
				else if (flag)
				{
					CableMessages.Show(player, CableMessages.For(CableCheck.Taken));
				}
				else if (plug.HasCable && !alt)
				{
					_session.Take(player, plug, NearSide(plug, player));
					CableMessages.Show(player, "$jevzip_msg_carry");
				}
				else if (!Chains.CanPay(player))
				{
					CableMessages.Show(player, "$msg_missingrequirement: $item_chain");
				}
				else
				{
					_session.Start(player, plug);
					CableMessages.Show(player, "$jevzip_msg_carry");
				}
			}
		}

		private void OnUpdate(Player player)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Plug? carried = _session.Carried;
			if (carried.HasValue && (!carried.Value.Exists || Vector3.Distance(((Component)player).transform.position, carried.Value.Anchor) > _session.MaxLength * 2f || ((Character)player).IsDead()))
			{
				_session.Cancel(player);
				CableMessages.Show(player, "$jevzip_msg_slipped");
			}
		}
	}
	public static class CableMessages
	{
		public const string Carrying = "$jevzip_msg_carry";

		public const string Removed = "$jevzip_msg_removed";

		public const string Slipped = "$jevzip_msg_slipped";

		public const string NoChain = "$msg_missingrequirement: $item_chain";

		public const string ChainCost = " ($item_chain x1)";

		public const string Uphill = "$jevzip_msg_uphill";

		public const string Stalled = "$jevzip_msg_stalled";

		public static void Show(Player player, string message)
		{
			((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false);
		}

		public static string For(CableCheck check)
		{
			return check switch
			{
				CableCheck.TooShort => "$jevzip_msg_short", 
				CableCheck.TooLong => "$jevzip_msg_long", 
				CableCheck.TooFlat => "$jevzip_msg_flat", 
				CableCheck.TooLow => "$jevzip_msg_low", 
				CableCheck.Blocked => "$jevzip_msg_blocked", 
				CableCheck.SamePost => "$jevzip_msg_same", 
				CableCheck.Taken => "$jevzip_msg_taken", 
				CableCheck.Busy => "$jevzip_msg_busy", 
				CableCheck.Across => "$jevzip_msg_across", 
				_ => "$jevzip_msg_strung", 
			};
		}
	}
	public sealed class CablePreviewFeature : IFeature
	{
		private static readonly Color ValidColor = Color.white;

		private static readonly Color InvalidColor = new Color(1f, 0.35f, 0.35f);

		private readonly IGameEvents _events;

		private readonly ICableSession _session;

		private LineRenderer _line;

		public CablePreviewFeature(IGameEvents events, ICableSession session)
		{
			_events = events;
			_session = session;
		}

		public void Enable()
		{
			_events.LocalPlayerUpdate += OnUpdate;
		}

		public void Disable()
		{
			_events.LocalPlayerUpdate -= OnUpdate;
			Hide();
		}

		private static bool TryGetHoveredWing(Player player, out Plug plug)
		{
			plug = default(Plug);
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			PostWing postWing = (((Object)(object)hoverObject != (Object)null) ? hoverObject.GetComponent<PostWing>() : null);
			if ((Object)(object)postWing == (Object)null || !postWing.Plug.Exists)
			{
				return false;
			}
			plug = postWing.Plug;
			return true;
		}

		private void OnUpdate(Player player)
		{
			//IL_0073: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			Plug? carried = _session.Carried;
			if (!carried.HasValue || !carried.Value.Exists)
			{
				Hide();
				return;
			}
			Plug value = carried.Value;
			if (TryGetHoveredWing(player, out var plug) && !plug.Is(value))
			{
				Show(value.SpanTo(plug), _session.Check(plug) == CableCheck.Ok);
				return;
			}
			Vector3 position = ((Humanoid)player).GetVisEquipment().m_leftHand.position;
			CableSpan span = new CableSpan(value.Anchor, position);
			Show(span, span.Length <= _session.MaxLength);
		}

		private void Show(CableSpan span, bool valid)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_line == (Object)null)
			{
				_line = CableLines.Create(null, "ZiplinePreview");
				((Renderer)_line).sharedMaterial = new Material(((Renderer)_line).sharedMaterial);
			}
			((Renderer)_line).sharedMaterial.color = (valid ? ValidColor : InvalidColor);
			CableLines.Draw(_line, span);
		}

		private void Hide()
		{
			if ((Object)(object)_line != (Object)null)
			{
				((Renderer)_line).enabled = false;
			}
		}
	}
	public sealed class CableSession : ICableSession
	{
		private readonly ICableValidator _validator;

		public Plug? Carried { get; private set; }

		public float MaxLength => _validator.MaxLength;

		public CableSession(ICableValidator validator)
		{
			_validator = validator;
		}

		public bool IsHeld(Plug plug)
		{
			//IL_001f: 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)
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (CarriedCable.TryRead(allPlayer, out var post, out var wing) && post == plug.Post.Id && wing == plug.Wing)
				{
					return true;
				}
			}
			return false;
		}

		public void Start(Player player, Plug plug)
		{
			Chains.Pay(player);
			Carry(player, plug);
		}

		public void Take(Player player, Plug plug, int side)
		{
			Carry(player, plug.Unlink(side, out var far) ? far : plug);
		}

		public CableCheck Check(Plug target)
		{
			Plug value = Carried.Value;
			if ((Object)(object)value.Post == (Object)(object)target.Post)
			{
				return CableCheck.SamePost;
			}
			if (IsHeld(target))
			{
				return CableCheck.Busy;
			}
			if (value.IsPlugged(value.SideToward(target)) || target.IsPlugged(target.SideToward(value)))
			{
				return CableCheck.Taken;
			}
			if (!value.RunsAlong(target) || !target.RunsAlong(value))
			{
				return CableCheck.Across;
			}
			return _validator.Check(value.SpanTo(target));
		}

		public CableCheck Connect(Player player, Plug target)
		{
			CableCheck num = Check(target);
			if (num == CableCheck.Ok)
			{
				Carried.Value.Link(target);
				Carry(player, null);
			}
			return num;
		}

		public void Cancel(Player player)
		{
			Carry(player, null);
			Chains.Refund(player);
		}

		private void Carry(Player player, Plug? plug)
		{
			Carried = plug;
			CarriedCable.Write(player, plug);
		}
	}
	public readonly struct CableSpan
	{
		private const float SagFraction = 0.015f;

		public Vector3 From { get; }

		public Vector3 To { get; }

		public float Length { get; }

		public bool IsDownhill => From.y >= To.y;

		public CableSpan Downhill
		{
			get
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (!IsDownhill)
				{
					return new CableSpan(To, From);
				}
				return this;
			}
		}

		private float Sag => Length * 0.015f;

		public CableSpan(Vector3 from, Vector3 to)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			From = from;
			To = to;
			Length = Vector3.Distance(from, to);
		}

		public float DescentAt(float distance)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return 0f - Tangent(distance / Length).y;
		}

		public Vector3 Point(float t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_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)
			return Vector3.Lerp(From, To, t) + Vector3.down * (4f * Sag * t * (1f - t));
		}

		public Vector3 Hang(float t)
		{
			//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_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)
			return Point(t) + Vector3.down * 2.15f;
		}

		public Vector3 Tangent(float t)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003a: 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)
			Vector3 val = To - From + Vector3.down * (4f * Sag * (1f - 2f * t));
			return ((Vector3)(ref val)).normalized;
		}
	}
	public sealed class CableValidator : ICableValidator
	{
		private const float SampleSpacing = 2f;

		private const int CableSegments = 24;

		private const float RiderRadius = 0.35f;

		private const float RiderBottom = 0.4f;

		private const float RiderTop = 1.4f;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[16];

		private static readonly Collider[] Overlaps = (Collider[])(object)new Collider[16];

		private readonly IModSettings _settings;

		private int _mask;

		public float MaxLength => _settings.MaxCableLength;

		public CableValidator(IModSettings settings)
		{
			_settings = settings;
		}

		public CableCheck Check(CableSpan span)
		{
			if (span.Length < 6f)
			{
				return CableCheck.TooShort;
			}
			if (span.Length > MaxLength)
			{
				return CableCheck.TooLong;
			}
			if (!Rideable(span.Downhill))
			{
				return CableCheck.TooFlat;
			}
			if (!HangsClearOfGround(span))
			{
				return CableCheck.TooLow;
			}
			if (!CableIsClear(span) || !RiderPathIsClear(span))
			{
				return CableCheck.Blocked;
			}
			return CableCheck.Ok;
		}

		private static int Samples(CableSpan span)
		{
			return Mathf.CeilToInt(span.Length / 2f);
		}

		private static bool IsPost(Collider collider)
		{
			return (Object)(object)((Component)collider).GetComponentInParent<ZiplinePost>() != (Object)null;
		}

		private static bool HangsClearOfGround(CableSpan span)
		{
			//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_001e: 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)
			int num = Samples(span);
			float num2 = 2.3500001f;
			for (int i = 1; i < num; i++)
			{
				Vector3 val = span.Point((float)i / (float)num);
				if (val.y - ZoneSystem.instance.GetGroundHeight(val) < num2)
				{
					return false;
				}
			}
			return true;
		}

		private bool Rideable(CableSpan span)
		{
			return RideMath.Completes(((CableSpan)span).DescentAt, 0.5f, span.Length - 0.5f, _settings.RideSpeed);
		}

		private bool CableIsClear(CableSpan span)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002c: 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_0037: 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)
			Vector3 val = span.Point(0f);
			for (int i = 1; i <= 24; i++)
			{
				Vector3 val2 = span.Point((float)i / 24f);
				if (!RayIsClear(val, val2) || !RayIsClear(val2, val))
				{
					return false;
				}
				val = val2;
			}
			return true;
		}

		private bool RayIsClear(Vector3 start, Vector3 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = end - start;
			int num = Physics.RaycastNonAlloc(start, ((Vector3)(ref val)).normalized, Hits, ((Vector3)(ref val)).magnitude, Mask(), (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (!IsPost(((RaycastHit)(ref Hits[i])).collider))
				{
					return false;
				}
			}
			return true;
		}

		private bool RiderPathIsClear(CableSpan span)
		{
			//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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0054: 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)
			float num = 0.5f / span.Length;
			int num2 = Samples(span);
			Vector3 start = span.Hang(num);
			for (int i = 1; i <= num2; i++)
			{
				Vector3 val = span.Hang(Mathf.Lerp(num, 1f - num, (float)i / (float)num2));
				if (!RiderFits(val) || !SweepIsClear(start, val))
				{
					return false;
				}
				start = val;
			}
			return true;
		}

		private bool RiderFits(Vector3 feet)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapCapsuleNonAlloc(feet + Vector3.up * 0.4f, feet + Vector3.up * 1.4f, 0.35f, Overlaps, Mask(), (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (!IsPost(Overlaps[i]))
				{
					return false;
				}
			}
			return true;
		}

		private bool SweepIsClear(Vector3 start, Vector3 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0039: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = end - start;
			int num = Physics.CapsuleCastNonAlloc(start + Vector3.up * 0.4f, start + Vector3.up * 1.4f, 0.35f, ((Vector3)(ref val)).normalized, Hits, ((Vector3)(ref val)).magnitude, Mask(), (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (!IsPost(((RaycastHit)(ref Hits[i])).collider))
				{
					return false;
				}
			}
			return true;
		}

		private int Mask()
		{
			if (_mask == 0)
			{
				_mask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vegetation" });
			}
			return _mask;
		}
	}
	public static class Chains
	{
		public static bool CanPay(Player player)
		{
			if (!player.NoCostCheat())
			{
				return ((Humanoid)player).GetInventory().CountItems("$item_chain", -1, true) > 0;
			}
			return true;
		}

		public static void Pay(Player player)
		{
			if (!player.NoCostCheat())
			{
				((Humanoid)player).GetInventory().RemoveItem("$item_chain", 1, -1, true);
			}
		}

		public static void Refund(Player player)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!player.NoCostCheat() && !((Humanoid)player).GetInventory().AddItem(Prefab(), 1))
			{
				Drop(((Component)player).transform.position + Vector3.up);
			}
		}

		public static void Drop(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Object.Instantiate<GameObject>(Prefab(), position, Quaternion.identity);
		}

		private static GameObject Prefab()
		{
			return ObjectDB.instance.GetItemPrefab("Chain");
		}
	}
	public static class HoverText
	{
		private const string KeyStart = "\n[<color=yellow><b>";

		private const string KeyEnd = "</b></color>] ";

		private const string RefusalColor = "\n<color=#ff7a6a>";

		private const string HintColor = "\n<color=#b0b0b0>";

		private const string EndColor = "</color>";

		private static string AltKey
		{
			get
			{
				if (!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive())
				{
					return "$KEY_AltPlace";
				}
				return "$KEY_AltKeys";
			}
		}

		public static void Action(StringBuilder text, string action)
		{
			Key(text, "$KEY_Use", action);
		}

		public static void AltAction(StringBuilder text, string action)
		{
			Key(text, AltKey + " + $KEY_Use", action);
		}

		public static void Refusal(StringBuilder text, string reason)
		{
			text.Append("\n<color=#ff7a6a>").Append(reason).Append("</color>");
		}

		public static void Hint(StringBuilder text, string hint)
		{
			text.Append("\n<color=#b0b0b0>").Append(hint).Append("</color>");
		}

		public static void KeyHint(StringBuilder text, string key, string hint)
		{
			Hint(text, "[" + key + "] " + hint);
		}

		private static void Key(StringBuilder text, string key, string action)
		{
			text.Append("\n[<color=yellow><b>").Append(key).Append("</b></color>] ")
				.Append(action);
		}
	}
	public interface ICableSession
	{
		Plug? Carried { get; }

		float MaxLength { get; }

		bool IsHeld(Plug plug);

		void Start(Player player, Plug plug);

		void Take(Player player, Plug plug, int side);

		CableCheck Check(Plug target);

		CableCheck Connect(Player player, Plug target);

		void Cancel(Player player);
	}
	public interface ICableValidator
	{
		float MaxLength { get; }

		CableCheck Check(CableSpan span);
	}
	public interface IRideController
	{
		void Start(Player player, Plug from, Plug to, float startDistance);
	}
	public interface IRideEffects
	{
		void Enter(Player player);

		void Follow(CableSpan span);

		void Track(float pace);

		void Exit(bool arrived);
	}
	public static class LinkCodec
	{
		private const char Separator = ':';

		public static string Format(long user, uint id, int wing)
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			return user.ToString(invariantCulture) + ":" + id.ToString(invariantCulture) + ":" + wing.ToString(invariantCulture);
		}

		public static bool TryParse(string text, out long user, out uint id, out int wing)
		{
			user = 0L;
			id = 0u;
			wing = 0;
			string[] array = text.Split(new char[1] { ':' });
			if (array.Length != 3)
			{
				return false;
			}
			NumberStyles style = NumberStyles.Integer;
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			if (long.TryParse(array[0], style, invariantCulture, out user) && uint.TryParse(array[1], style, invariantCulture, out id) && int.TryParse(array[2], style, invariantCulture, out wing) && wing >= 0)
			{
				return wing < 2;
			}
			return false;
		}
	}
	public sealed class Ride
	{
		private const float BoardSpeed = 9f;

		private const float BoardReach = 0.6f;

		private const float BoardTimeout = 3f;

		private const float BoardLift = 3f;

		private const float Spring = 8f;

		private const float MaxCorrection = 6f;

		private const float KnockOffDistance = 1.2f;

		private const float StuckFraction = 0.5f;

		private const int StuckSteps = 3;

		private const float StuckGrace = 0.3f;

		private const float ExitLift = 2f;

		private readonly Player _player;

		private readonly float _topSpeed;

		private readonly List<Collider> _ignored = new List<Collider>();

		private CableSpan _span;

		private float _end;

		private bool _stopsAtEnd;

		private float _distance;

		private float _speed = 2.5f;

		private float _boardingTime;

		private int _stuckSteps;

		private float _glideTime;

		private Vector3 _lastPosition;

		private bool _boarding = true;

		public bool Arrived { get; private set; }

		public bool Stalled { get; private set; }

		public bool KnockedOff { get; private set; }

		public bool BoardingFailed => _boardingTime > 3f;

		public CableSpan Span => _span;

		public Vector3 Direction => _span.Tangent(Progress);

		public float Pace => Mathf.Clamp01(_speed / _topSpeed);

		public Vector3 Velocity => Direction * _speed;

		public Vector3 ExitVelocity => Velocity + Vector3.up * 2f;

		private float Progress => _distance / _span.Length;

		public Ride(Player player, float topSpeed)
		{
			_player = player;
			_topSpeed = topSpeed;
		}

		public void Follow(CableSpan span, float startDistance, bool stopsAtEnd)
		{
			_span = span;
			_stopsAtEnd = stopsAtEnd;
			_end = EndOf(stopsAtEnd);
			_distance = Mathf.Clamp(startDistance, 0f, _end);
			_stuckSteps = 0;
			_glideTime = 0f;
			Arrived = false;
		}

		public void StopAtEnd()
		{
			_stopsAtEnd = true;
			_end = EndOf(stopsAtEnd: true);
		}

		public void Continue(CableSpan span, bool stopsAtEnd)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			Vector3 direction = Direction;
			Follow(span, 0f, stopsAtEnd);
			_speed *= Mathf.Max(0f, Vector3.Dot(direction, Direction));
		}

		public void Ignore(ZiplinePost post)
		{
			Collider[] componentsInChildren = ((Component)post).GetComponentsInChildren<Collider>();
			foreach (Collider val in componentsInChildren)
			{
				_ignored.Add(val);
				Physics.IgnoreCollision((Collider)(object)((Character)_player).m_collider, val, true);
			}
		}

		public void Attach()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			((Character)_player).ForceJump(Vector3.up * 3f, false);
		}

		public void Step(float dt)
		{
			//IL_003a: 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)
			if (_boarding)
			{
				Board(dt);
			}
			else
			{
				Glide(dt);
			}
			((Character)_player).m_body.useGravity = false;
			((Character)_player).m_maxAirAltitude = ((Component)_player).transform.position.y;
			Face(Direction);
		}

		public void Release()
		{
			foreach (Collider item in _ignored)
			{
				if ((Object)(object)item != (Object)null)
				{
					Physics.IgnoreCollision((Collider)(object)((Character)_player).m_collider, item, false);
				}
			}
			((Character)_player).m_body.useGravity = true;
		}

		private float EndOf(bool stopsAtEnd)
		{
			if (!stopsAtEnd)
			{
				return _span.Length;
			}
			return _span.Length - 0.5f;
		}

		private void Board(float dt)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0056: 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_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)
			_boardingTime += dt;
			Vector3 val = _span.Hang(Progress) - ((Component)_player).transform.position;
			if (((Vector3)(ref val)).magnitude <= 0.6f)
			{
				_boarding = false;
				_lastPosition = ((Component)_player).transform.position - Direction * (_speed * dt);
			}
			else
			{
				((Character)_player).SetVelocity(((Vector3)(ref val)).normalized * 9f);
			}
		}

		private void Glide(float dt)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = _span.Hang(Progress) - ((Component)_player).transform.position;
			if (((Vector3)(ref val)).magnitude > 1.2f || Blocked(dt))
			{
				KnockedOff = true;
				return;
			}
			float remaining = (_stopsAtEnd ? (_end - _distance) : float.MaxValue);
			_speed = RideMath.NextSpeed(_speed, _span.DescentAt(_distance), remaining, _topSpeed, dt);
			if (_speed <= 0f)
			{
				Stalled = true;
				return;
			}
			_distance = Mathf.Min(_distance + _speed * dt, _end);
			Arrived = _distance >= _end;
			Vector3 val2 = Vector3.ClampMagnitude(val * 8f, 6f);
			((Character)_player).SetVelocity(Velocity + val2);
		}

		private bool Blocked(float dt)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)_player).transform.position;
			float num = Vector3.Dot(position - _lastPosition, Direction);
			float num2 = _speed * dt;
			_lastPosition = position;
			_glideTime += dt;
			bool flag = _glideTime > 0.3f && num < num2 * 0.5f;
			_stuckSteps = (flag ? (_stuckSteps + 1) : 0);
			return _stuckSteps >= 3;
		}

		private void Face(Vector3 direction)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(direction.x, 0f, direction.z);
			if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
			{
				((Component)_player).transform.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
			}
		}
	}
	public sealed class RideEffects : IRideEffects
	{
		private const string HangAnimation = "repell";

		private const float FovBoost = 8f;

		private const float FovInertia = 0.06f;

		private Player _player;

		private RiderRig _rig;

		private SE_Stats _effect;

		private float _baseFov;

		public void Enter(Player player)
		{
			_player = player;
			_rig = ((Component)player).GetComponent<RiderRig>();
			((Character)player).m_zanim.SetBool("repell", true);
			AddGrappleEffect();
			GameCamera instance = GameCamera.instance;
			_baseFov = ((instance.m_fovBase != 0f) ? instance.m_fovBase : instance.m_fov);
		}

		public void Follow(CableSpan span)
		{
			_rig.Begin(span);
		}

		public void Track(float pace)
		{
			GameCamera.instance.SetTempFOV(_baseFov + 8f * pace, 0.06f);
		}

		public void Exit(bool arrived)
		{
			//IL_0051: 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_006f: 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)
			((Character)_player).m_zanim.SetBool("repell", false);
			ReleaseGrappleEffect();
			GameCamera.instance.ResetTempFOV();
			_rig.End();
			EffectList obj = (arrived ? GrappleAssets.DoneEffect : GrappleAssets.LetGoEffect);
			if (obj != null)
			{
				obj.Create(((Component)_player).transform.position, ((Component)_player).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
			}
			_player = null;
		}

		private void AddGrappleEffect()
		{
			SEMan sEMan = ((Character)_player).GetSEMan();
			ref SE_Stats effect = ref _effect;
			StatusEffect obj = sEMan.AddStatusEffect(GrappleAssets.Effect, false, 0, 0f, (short)(-1));
			effect = (SE_Stats)(((object)((obj is SE_Stats) ? obj : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/));
			if ((Object)(object)_effect != (Object)null)
			{
				((StatusEffect)_effect).m_ttl = 0f;
			}
		}

		private void ReleaseGrappleEffect()
		{
			if ((Object)(object)_effect != (Object)null)
			{
				((Character)_player).GetSEMan().RemoveStatusEffect((StatusEffect)(object)_effect, true);
				_effect = null;
			}
		}
	}
	public sealed class RideFeature : IFeature, IRideController
	{
		private const float JumpLift = 3f;

		private readonly IGameEvents _events;

		private readonly IModSettings _settings;

		private readonly IRideEffects _effects;

		private Player _player;

		private Ride _ride;

		private Plug _from;

		private Plug _target;

		private Plug? _onward;

		public RideFeature(IGameEvents events, IModSettings settings, IRideEffects effects)
		{
			_events = events;
			_settings = settings;
			_effects = effects;
		}

		public void Enable()
		{
			_events.LocalPlayerUpdate += OnUpdate;
			_events.LocalPlayerFixedUpdating += OnPhysicsStepStarting;
			_events.LocalPlayerFixedUpdate += OnPhysicsStep;
		}

		public void Disable()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			_events.LocalPlayerUpdate -= OnUpdate;
			_events.LocalPlayerFixedUpdating -= OnPhysicsStepStarting;
			_events.LocalPlayerFixedUpdate -= OnPhysicsStep;
			if (_ride != null && (Object)(object)_player != (Object)null)
			{
				Finish(Vector3.zero, arrived: false);
			}
		}

		public void Start(Player player, Plug from, Plug to, float startDistance)
		{
			if (_ride == null && !IsBusy(player) && !((Character)player).IsSwimming() && !((Character)player).InDodge())
			{
				_player = player;
				_ride = new Ride(player, _settings.RideSpeed);
				_effects.Enter(player);
				SetRoute(from, to);
				_ride.Follow(from.SpanTo(to), startDistance, !_onward.HasValue);
				_effects.Follow(_ride.Span);
				_ride.Attach();
			}
		}

		private static bool IsBusy(Player player)
		{
			if (!((Character)player).IsDead() && !((Character)player).IsTeleporting())
			{
				return ((Character)player).IsAttached();
			}
			return true;
		}

		private static bool WantsToLetGo()
		{
			if (!ZInput.GetButtonDown("Jump"))
			{
				return ZInput.GetButtonDown("JoyJump");
			}
			return true;
		}

		private static Plug? Onward(Plug from, Plug arrival)
		{
			int side = 1 - arrival.SideToward(from);
			if (arrival.TryGetFar(side, out var far) && arrival.SpanTo(far).IsDownhill)
			{
				return far;
			}
			return null;
		}

		private void OnUpdate(Player player)
		{
			//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_002c: 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)
			DropStaleRide(player);
			if (_ride != null && WantsToLetGo())
			{
				Finish(_ride.Velocity + Vector3.up * 3f, arrived: false);
			}
		}

		private void OnPhysicsStepStarting(Player player)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (_ride != null)
			{
				((Character)player).SetMoveDir(Vector3.zero);
			}
		}

		private void OnPhysicsStep(Player player)
		{
			//IL_001b: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			DropStaleRide(player);
			if (_ride == null)
			{
				return;
			}
			if (IsOver(player))
			{
				Finish(((Character)player).GetVelocity(), arrived: false);
				return;
			}
			if (_onward.HasValue && !_target.IsLinkedTo(_onward.Value))
			{
				_onward = null;
				_ride.StopAtEnd();
			}
			_ride.Step(Time.fixedDeltaTime);
			if (_ride.Arrived)
			{
				Advance();
			}
			else if (_ride.KnockedOff)
			{
				Finish(((Character)player).GetVelocity(), arrived: false);
			}
			else if (_ride.Stalled)
			{
				Finish(((Character)player).GetVelocity(), arrived: false);
				CableMessages.Show(player, "$jevzip_msg_stalled");
			}
			else
			{
				_effects.Track(_ride.Pace);
			}
		}

		private bool IsOver(Player player)
		{
			if (_from.IsLinkedTo(_target) && !_ride.BoardingFailed && !IsBusy(player))
			{
				return ((Character)player).IsStaggering();
			}
			return true;
		}

		private void Advance()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (_onward.HasValue)
			{
				Plug target = _target;
				SetRoute(target, _onward.Value);
				_ride.Continue(target.SpanTo(_target), !_onward.HasValue);
				_effects.Follow(_ride.Span);
			}
			else
			{
				Finish(_ride.ExitVelocity, arrived: true);
			}
		}

		private void SetRoute(Plug from, Plug to)
		{
			_from = from;
			_target = to;
			_onward = Onward(from, to);
			_ride.Ignore(from.Post);
			_ride.Ignore(to.Post);
		}

		private void DropStaleRide(Player player)
		{
			if (_ride != null && (Object)(object)player != (Object)(object)_player)
			{
				_ride = null;
				_player = null;
			}
		}

		private void Finish(Vector3 exitVelocity, bool arrived)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_ride.Release();
			((Character)_player).ForceJump(exitVelocity, false);
			_effects.Exit(arrived);
			_ride = null;
			_player = null;
		}
	}
	public static class RideMath
	{
		public const float Gravity = 9.81f;

		public const float Friction = 0.3f;

		public const float Drag = 0.006f;

		public const float StartSpeed = 2.5f;

		public const float BrakeDistance = 6f;

		public const float BrakeDeceleration = 20f;

		public const float ArriveSpeed = 3f;

		private const float SimulationStep = 0.02f;

		private const int MaxSimulationSteps = 50000;

		public static float NextSpeed(float current, float descent, float remaining, float topSpeed, float dt)
		{
			float num = 9.81f * descent - 0.3f - 0.006f * current * current;
			float num2 = Math.Min(current + num * dt, topSpeed);
			float num3 = Math.Max(3f, topSpeed * Clamp(remaining / 6f, 0f, 1f));
			if (num2 > num3)
			{
				num2 = Math.Max(num3, num2 - 20f * dt);
			}
			return num2;
		}

		public static bool Completes(Func<float, float> descentAt, float start, float end, float topSpeed)
		{
			float num = start;
			float num2 = 2.5f;
			for (int i = 0; i < 50000; i++)
			{
				if (num >= end)
				{
					return true;
				}
				float descent = descentAt(num);
				num2 = NextSpeed(num2, descent, end - num, topSpeed, 0.02f);
				if (num2 <= 0f)
				{
					return false;
				}
				num += num2 * 0.02f;
			}
			return false;
		}

		private static float Clamp(float value, float min, float max)
		{
			return Math.Max(min, Math.Min(max, value));
		}
	}
	public static class ZiplineSpec
	{
		public const string PrefabName = "JevZiplinePost";

		public const string ArmName = "Arm";

		public const string ChainPrefab = "Chain";

		public const string ChainItem = "$item_chain";

		public const int Wings = 2;

		public const int Sides = 2;

		public const float MinAlongness = 0.5f;

		public const float ArmHeight = 3f;

		public const float ArmReach = 1.2f;

		public const float CableRise = 0.12f;

		public const float SheaveRadius = 0.18f;

		public const float HangDepth = 2.15f;

		public const float EndMargin = 0.5f;

		public const float MinLength = 6f;

		public const float GroundClearance = 0.2f;
	}
}
namespace JevZiplines.Content
{
	internal static class PostModel
	{
		private const string BeamModel = "woodiron_beam";

		private const string StrutModel = "woodiron_pole";

		private const string SnapPointTag = "snappoint";

		private const float GroundSink = 0.1f;

		private const float MastTop = 3.45f;

		private const float BeamThickness = 1.1f;

		private const float BraceThickness = 0.6f;

		private const float KickerThickness = 0.7f;

		private const float SheaveWidth = 0.07f;

		private const float CheekOffset = 0.05f;

		private static readonly Vector3 CheekSize = new Vector3(0.02f, 0.3f, 0.44f);

		internal static void Build(GameObject prefab)
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			BuildMast(prefab.transform);
			BuildKickers(prefab.transform);
			Transform transform = new GameObject("Arm").transform;
			transform.SetParent(prefab.transform, false);
			transform.localPosition = Vector3.up * 3f;
			transform.localRotation = Quaternion.Euler(0f, 90f, 0f);
			BuildArm(transform);
			LODGroup component = prefab.GetComponent<LODGroup>();
			if ((Object)(object)component != (Object)null)
			{
				component.RecalculateBounds();
			}
		}

		private static void BuildMast(Transform root)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject("Mast").transform;
			transform.SetParent(root, false);
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				Transform child = root.GetChild(num);
				if (!((Object)(object)child == (Object)(object)transform))
				{
					if (((Component)child).CompareTag("snappoint"))
					{
						Vector3 localPosition = child.localPosition;
						float num2 = ((localPosition.y > 0f) ? 3.45f : (-0.1f));
						child.localPosition = new Vector3(localPosition.x, num2, localPosition.z);
					}
					else
					{
						child.SetParent(transform, false);
					}
				}
			}
			Bounds val = MeshBounds(transform);
			float num3 = 3.55f / ((Bounds)(ref val)).size.y;
			transform.localScale = new Vector3(1f, num3, 1f);
			transform.localPosition = new Vector3(0f - ((Bounds)(ref val)).center.x, -0.1f - ((Bounds)(ref val)).min.y * num3, 0f - ((Bounds)(ref val)).center.z);
		}

		private static void BuildKickers(Transform root)
		{
			//IL_001c: 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_002b: 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_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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 4; i++)
			{
				Vector3 val = Quaternion.Euler(0f, 45f + 90f * (float)i, 0f) * Vector3.forward;
				Fit("woodiron_pole", root, val * 0.8f + Vector3.down * 0.1f, val * 0.12f + Vector3.up * 0.95f, 0.7f);
			}
		}

		private static void BuildArm(Transform arm)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			float num = 1.1010001f;
			Fit("woodiron_beam", arm, Vector3.back * num, Vector3.forward * num, 1.1f);
			float[] array = new float[2] { 1f, -1f };
			foreach (float num2 in array)
			{
				Fit("woodiron_pole", arm, new Vector3(0f, -0.9f, 0.1f * num2), new Vector3(0f, -0.08f, 0.85f * num2), 0.6f);
				BuildSheave(arm, num2);
			}
		}

		private static void BuildSheave(Transform arm, float side)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, -0.06000001f, 1.2f * side);
			SteelParts.Wheel(arm, 0.18f, 0.07f).localPosition = val;
			Vector3 val2 = val + new Vector3(0f, 0.04f, -0.1f * side);
			SteelParts.Plate(arm, val2 + Vector3.right * 0.05f, CheekSize);
			SteelParts.Plate(arm, val2 - Vector3.right * 0.05f, CheekSize);
		}

		private static void Fit(string prefabName, Transform parent, Vector3 from, Vector3 to, float thickness)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0080: 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_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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Copy(prefabName, parent);
			Bounds val2 = MeshBounds(val);
			int num = LongestAxis(((Bounds)(ref val2)).size);
			Vector3 val3 = to - from;
			Vector3 val4 = Vector3.one * thickness;
			float magnitude = ((Vector3)(ref val3)).magnitude;
			Vector3 size = ((Bounds)(ref val2)).size;
			((Vector3)(ref val4))[num] = magnitude / ((Vector3)(ref size))[num];
			Vector3 zero = Vector3.zero;
			((Vector3)(ref zero))[num] = 1f;
			val.localRotation = Quaternion.FromToRotation(zero, val3);
			val.localScale = val4;
			val.localPosition = (from + to) * 0.5f - val.localRotation * Vector3.Scale(val4, ((Bounds)(ref val2)).center);
		}

		private static int LongestAxis(Vector3 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (size.x >= size.y && size.x >= size.z)
			{
				return 0;
			}
			if (!(size.y >= size.z))
			{
				return 2;
			}
			return 1;
		}

		private static Bounds MeshBounds(Transform model)
		{
			//IL_0002: 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_0034: 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_0042: 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_0050: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			bool flag = true;
			MeshFilter[] componentsInChildren = ((Component)model).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, Corner(j));
					Vector3 val3 = model.InverseTransformPoint(((Component)val).transform.TransformPoint(val2));
					if (flag)
					{
						((Bounds)(ref result))..ctor(val3, Vector3.zero);
						flag = false;
					}
					((Bounds)(ref result)).Encapsulate(val3);
				}
			}
			return result;
		}

		private static Vector3 Corner(int index)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(((index & 1) == 0) ? (-1f) : 1f, ((index & 2) == 0) ? (-1f) : 1f, ((index & 4) == 0) ? (-1f) : 1f);
		}

		private static Transform Copy(string prefabName, Transform parent)
		{
			//IL_0018: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(PrefabManager.Instance.GetPrefab(prefabName), parent);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			KeepNewLook(val.GetComponent<WearNTear>());
			Component[] componentsInChildren = val.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				if (!(val2 is Transform) && !(val2 is Renderer) && !(val2 is MeshFilter) && !(val2 is LODGroup) && !(val2 is ZNetView))
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			Object.DestroyImmediate((Object)(object)val.GetComponent<ZNetView>());
			return val.transform;
		}

		private static void KeepNewLook(WearNTear wear)
		{
			if ((Object)(object)wear == (Object)null)
			{
				return;
			}
			GameObject[] array = (GameObject[])(object)new GameObject[3] { wear.m_worn, wear.m_broken, wear.m_wet };
			foreach (GameObject val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)wear.m_new)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			if ((Object)(object)wear.m_new != (Object)null)
			{
				wear.m_new.SetActive(true);
			}
		}
	}
	public static class TranslationFile
	{
		public static Dictionary<string, string> Parse(string text)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			string[] array = text.Split(new char[1] { '\n' });
			foreach (string text2 in array)
			{
				int num = text2.IndexOf('=');
				if (num > 0)
				{
					dictionary[text2.Substring(0, num).Trim()] = text2.Substring(num + 1).Trim();
				}
			}
			return dictionary;
		}
	}
	internal static class Translations
	{
		private const string Extension = ".txt";

		internal static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Assembly assembly = typeof(Translations).Assembly;
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.EndsWith(".txt"))
				{
					continue;
				}
				using Stream stream = assembly.GetManifestResourceStream(text);
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
				string text2 = text.Substring(0, text.Length - ".txt".Length);
				Dictionary<string, string> dictionary = TranslationFile.Parse(streamReader.ReadToEnd());
				localization.AddTranslation(ref text2, dictionary);
			}
		}
	}
	internal static class ZiplineContent
	{
		private const string BasePrefab = "wood_pole_log_4";

		private const string GrapplePrefab = "GrapplingPoint";

		private const string PlayerPrefab = "Player";

		private const float WingRadius = 0.4f;

		private static readonly Quaternion IconRotation = Quaternion.Euler(-12f, 35f, 0f);

		internal static void Register()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			GrappleAssets.Load(PrefabManager.Instance.GetPrefab("GrapplingPoint"));
			CustomPiece val = new CustomPiece("JevZiplinePost", "wood_pole_log_4", PostConfig());
			GameObject piecePrefab = val.PiecePrefab;
			PostModel.Build(piecePrefab);
			val.Piece.m_craftingStation = null;
			piecePrefab.AddComponent<ZiplinePost>();
			AddWings(piecePrefab);
			if (!GUIManager.IsHeadless())
			{
				piecePrefab.AddComponent<CableView>();
				val.Piece.m_icon = RenderManager.Instance.Render(piecePrefab, IconRotation);
				GameObject prefab = PrefabManager.Instance.GetPrefab("Player");
				prefab.AddComponent<RiderRig>();
				prefab.AddComponent<CarriedCable>();
			}
			PieceManager.Instance.AddPiece(val);
		}

		private static void AddWings(GameObject prefab)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			float num = 2.9399998f;
			Vector3 position = default(Vector3);
			for (int i = 0; i < 2; i++)
			{
				float num2 = ((i == 0) ? 1f : (-1f));
				((Vector3)(ref position))..ctor(1.2f * num2, num, 0f);
				PostWing.Add(prefab, i, position, 0.4f);
			}
		}

		private static PieceConfig PostConfig()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Name = "$jevzip_post";
			val.Description = "$jevzip_post_description";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Misc;
			val.Usage = new string[1] { PieceUsages.Transport };
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Wood", 8, 0, true),
				new RequirementConfig("Iron", 2, 0, true)
			};
			return val;
		}
	}
}
namespace JevZiplines.Config
{
	public interface IModSettings
	{
		float MaxCableLength { get; }

		float RideSpeed { get; }
	}
	public sealed class ModSettings : IModSettings
	{
		private readonly ConfigEntry<float> _maxCableLength;

		private readonly ConfigEntry<float> _rideSpeed;

		public float MaxCableLength => _maxCableLength.Value;

		public float RideSpeed => _rideSpeed.Value;

		public ModSettings(ConfigFile file)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			_maxCableLength = file.Bind<float>("Cable", "MaxLength", 80f, new ConfigDescription("The longest cable you can string between two posts, in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 150f), new object[1] { ServerSynced() }));
			_rideSpeed = file.Bind<float>("Ride", "Speed", 14f, new ConfigDescription("Speed limit on a cable, in m/s. Gravity sets the pace below it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(6f, 25f), new object[1] { ServerSynced() }));
		}

		private static ConfigurationManagerAttributes ServerSynced()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
		}
	}
}
namespace JevZiplines.Components
{
	public sealed class CableGrip : MonoBehaviour, Hoverable, Interactable
	{
		private const string Name = "$jevzip_cable";

		private const string Layer = "piece_nonsolid";

		private const int Segments = 8;

		private const float Radius = 0.15f;

		private const float EndClearance = 0.5f;

		private readonly List<CapsuleCollider> _colliders = new List<CapsuleCollider>();

		public Plug Start { get; private set; }

		public Plug End { get; private set; }

		public void Bind(Plug start, Plug end, CableSpan span)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0065: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			Start = start;
			End = end;
			float num = Mathf.Clamp01(0.5f / span.Length);
			Vector3 val = span.Point(num);
			for (int i = 0; i < 8; i++)
			{
				Vector3 val2 = span.Point(Mathf.Lerp(num, 1f - num, (float)(i + 1) / 8f));
				CapsuleCollider obj = Collider(i);
				Vector3 val3 = val2 - val;
				((Component)obj).transform.SetPositionAndRotation((val + val2) * 0.5f, Quaternion.LookRotation(val3));
				obj.height = ((Vector3)(ref val3)).magnitude + 0.3f;
				val = val2;
			}
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (!hold)
			{
				Player val = (Player)(object)((user is Player) ? user : null);
				if (val != null)
				{
					GameEvents.Instance?.RaiseCableGrabbed(this, val);
					return true;
				}
			}
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			StringBuilder stringBuilder = new StringBuilder("$jevzip_cable");
			GameEvents.Instance?.RaiseCableHovered(this, stringBuilder);
			return Localization.instance.Localize(stringBuilder.ToString());
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$jevzip_cable");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		private CapsuleCollider Collider(int index)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (index < _colliders.Count)
			{
				return _colliders[index];
			}
			CapsuleCollider val = new GameObject("Grip").AddComponent<CapsuleCollider>();
			((Component)val).gameObject.layer = LayerMask.NameToLayer("piece_nonsolid");
			((Component)val).transform.SetParent(((Component)this).transform, true);
			val.direction = 2;
			val.radius = 0.15f;
			_colliders.Add(val);
			return val;
		}
	}
	public static class CableLines
	{
		private const float CableWidth = 0.07f;

		private const int Segments = 24;

		public static LineRenderer Create(Transform parent, string name, float width = 0.07f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			LineRenderer obj = new GameObject(name).AddComponent<LineRenderer>();
			((Component)obj).transform.SetParent(parent, false);
			obj.useWorldSpace = true;
			((Renderer)obj).sharedMaterial = GrappleAssets.Cable;
			obj.textureMode = (LineTextureMode)1;
			obj.widthMultiplier = width;
			obj.positionCount = 2;
			return obj;
		}

		public static void Draw(LineRenderer line, CableSpan span)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			((Renderer)line).enabled = true;
			line.positionCount = 25;
			for (int i = 0; i <= 24; i++)
			{
				line.SetPosition(i, span.Point((float)i / 24f));
			}
		}
	}
	public sealed class CableView : MonoBehaviour
	{
		private const float RefreshInterval = 1f;

		private readonly List<LineRenderer> _lines = new List<LineRenderer>();

		private ZiplinePost _post;

		private ZNetView _view;

		private uint _drawnRevision;

		private float _timer;

		private void Awake()
		{
			_post = ((Component)this).GetComponent<ZiplinePost>();
			_view = ((Component)this).GetComponent<ZNetView>();
		}

		private void Update()
		{
			if (_post.IsPlaced)
			{
				_timer -= Time.deltaTime;
				uint dataRevision = _view.GetZDO().DataRevision;
				if (_timer <= 0f || dataRevision != _drawnRevision)
				{
					_timer = 1f;
					_drawnRevision = dataRevision;
					Refresh();
				}
			}
		}

		private void Refresh()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			for (int i = 0; i < 2; i++)
			{
				Plug start = new Plug(_post, i);
				for (int j = 0; j < 2; j++)
				{
					if (start.TryGetFar(j, out var far))
					{
						ZDOID id = _post.Id;
						if (((ZDOID)(ref id)).CompareTo(far.Post.Id) < 0)
						{
							LineRenderer obj = Line(num++);
							CableSpan span = start.SpanTo(far);
							CableLines.Draw(obj, span);
							((Component)obj).GetComponent<CableGrip>().Bind(start, far, span);
						}
					}
				}
			}
			for (int k = 0; k < _lines.Count; k++)
			{
				((Component)_lines[k]).gameObject.SetActive(k < num);
			}
		}

		private LineRenderer Line(int index)
		{
			if (index == _lines.Count)
			{
				LineRenderer val = CableLines.Create(((Component)this).transform, "Cable");
				((Component)val).gameObject.AddComponent<CableGrip>();
				_lines.Add(val);
			}
			return _lines[index];
		}
	}
	public sealed class CarriedCable : MonoBehaviour
	{
		private const string Key = "JevZiplines_Carry";

		private Player _player;

		private LineRenderer _line;

		public static void Write(Player player, Plug? plug)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ZNetView nview = ((Character)player).m_nview;
			if (!((Object)(object)nview == (Object)null) && nview.IsValid())
			{
				string text = string.Empty;
				if (plug.HasValue)
				{
					ZDOID id = plug.Value.Post.Id;
					text = LinkCodec.Format(((ZDOID)(ref id)).UserID, ((ZDOID)(ref id)).ID, plug.Value.Wing);
				}
				nview.GetZDO().Set("JevZiplines_Carry", text);
			}
		}

		public static bool TryRead(Player player, out ZDOID post, out int wing)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			post = ZDOID.None;
			wing = 0;
			ZNetView nview = ((Character)player).m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return false;
			}
			if (!LinkCodec.TryParse(nview.GetZDO().GetString("JevZiplines_Carry", string.Empty), out var user, out var id, out wing))
			{
				return false;
			}
			post = new ZDOID(user, id);
			return true;
		}

		private void Awake()
		{
			_player = ((Component)this).GetComponent<Player>();
		}

		private void LateUpdate()
		{
			//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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)(object)Player.m_localPlayer || !TryAnchor(out var anchor))
			{
				Hide();
				return;
			}
			if ((Object)(object)_line == (Object)null)
			{
				_line = CableLines.Create(((Component)this).transform, "CarriedCable");
			}
			Vector3 position = ((Humanoid)_player).GetVisEquipment().m_leftHand.position;
			CableLines.Draw(_line, new CableSpan(anchor, position));
		}

		private bool TryAnchor(out Vector3 anchor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			anchor = Vector3.zero;
			if (!TryRead(_player, out var post, out var wing))
			{
				return false;
			}
			GameObject val = ZNetScene.instance.FindInstance(post);
			ZiplinePost ziplinePost = (((Object)(object)val != (Object)null) ? val.GetComponent<ZiplinePost>() : null);
			if ((Object)(object)ziplinePost == (Object)null)
			{
				return false;
			}
			anchor = ziplinePost.Anchor(wing);
			return true;
		}

		private void Hide()
		{
			if ((Object)(object)_line != (Object)null)
			{
				((Renderer)_line).enabled = false;
			}
		}
	}
	public readonly struct Plug
	{
		public ZiplinePost Post { get; }

		public int Wing { get; }

		public bool Exists
		{
			get
			{
				if ((Object)(object)Post != (Object)null)
				{
					return Post.IsPlaced;
				}
				return false;
			}
		}

		public Vector3 Anchor => Post.Anchor(Wing);

		public bool HasCable => Post.IsPlugged(Wing);

		public bool IsFull
		{
			get
			{
				if (IsPlugged(0))
				{
					return IsPlugged(1);
				}
				return false;
			}
		}

		public Plug(ZiplinePost post, int wing)
		{
			Post = post;
			Wing = wing;
		}

		public bool Is(Plug other)
		{
			if ((Object)(object)Post == (Object)(object)other.Post)
			{
				return Wing == other.Wing;
			}
			return false;
		}

		public int SideToward(Plug other)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return Post.SideToward(other.Anchor);
		}

		public bool RunsAlong(Plug other)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return Post.Alongness(other.Anchor) >= 0.5f;
		}

		public bool IsPlugged(int side)
		{
			return Post.IsPlugged(Wing, side);
		}

		public bool IsLinkedTo(Plug other)
		{
			if (Exists && other.Exists && TryGetFar(SideToward(other), out var far))
			{
				return far.Is(other);
			}
			return false;
		}

		public CableSpan SpanTo(Plug other)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return new CableSpan(Anchor, other.Anchor);
		}

		public bool TryGetFar(int side, out Plug far)
		{
			return Post.TryGetFar(Wing, side, out far);
		}

		public void Link(Plug far)
		{
			Post.Connect(Wing, SideToward(far), far);
			far.Post.Connect(far.Wing, far.SideToward(this), this);
		}

		public bool Unlink(int side, out Plug far)
		{
			bool num = TryGetFar(side, out far);
			if (num)
			{
				far.Post.Disconnect(far.Wing, far.SideToward(this));
			}
			Post.Disconnect(Wing, side);
			return num;
		}
	}
	public sealed class PostLinks
	{
		private static readonly string[] Keys = new string[4] { "JevZiplines_Wing0Front", "JevZiplines_Wing0Back", "JevZiplines_Wing1Front", "JevZiplines_Wing1Back" };

		private readonly ZNetView _view;

		public PostLinks(ZNetView view)
		{
			_view = view;
		}

		public bool TryGet(int wing, int side, out ZDOID post, out int farWing)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			long user;
			uint id;
			bool flag = LinkCodec.TryParse(_view.GetZDO().GetString(Key(wing, side), string.Empty), out user, out id, out farWing);
			post = (ZDOID)(flag ? new ZDOID(user, id) : ZDOID.None);
			return flag;
		}

		public void Set(int wing, int side, ZDOID post, int farWing)
		{
			Write(wing, side, LinkCodec.Format(((ZDOID)(ref post)).UserID, ((ZDOID)(ref post)).ID, farWing));
		}

		public void Clear(int wing, int side)
		{
			Write(wing, side, string.Empty);
		}

		private static string Key(int wing, int side)
		{
			return Keys[wing * 2 + side];
		}

		private void Write(int wing, int side, string value)
		{
			_view.ClaimOwnership();
			_view.GetZDO().Set(Key(wing, side), value);
		}
	}
	public sealed class PostWing : MonoBehaviour, Hoverable, Interactable
	{
		[SerializeField]
		private int _wing;

		private ZiplinePost _post;

		public Plug Plug => new Plug(_post, _wing);

		public static void Add(GameObject prefab, int wing, Vector3 position, float radius)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Wing" + wing)
			{
				layer = LayerMask.NameToLayer("piece_nonsolid")
			};
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = position;
			val.AddComponent<SphereCollider>().radius = radius;
			val.AddComponent<PostWing>()._wing = wing;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (!hold)
			{
				Player val = (Player)(object)((user is Player) ? user : null);
				if (val != null && Plug.Exists)
				{
					GameEvents.Instance?.RaiseWingInteracted(Plug, val, alt);
					return true;
				}
			}
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			if (!Plug.Exists)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(_post.GetHoverName());
			GameEvents.Instance?.RaiseWingHovered(Plug, stringBuilder);
			return Localization.instance.Localize(stringBuilder.ToString());
		}

		public string GetHoverName()
		{
			return _post.GetHoverName();
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		private void Awake()
		{
			_post = ((Component)this).GetComponentInParent<ZiplinePost>();
		}
	}
	public sealed class RiderRig : MonoBehaviour
	{
		private const string RidingKey = "JevZiplines_Riding";

		private const string FromKey = "JevZiplines_From";

		private const string ToKey = "JevZiplines_To";

		private const float RopeWidth = 0.045f;

		private const float WheelRadius = 0.09f;

		private const float WheelWidth = 0.05f;

		private const float LoudSpeed = 20f;

		private const float Smoothing = 8f;

		private ZNetView _view;

		private Transform _hand;

		private Transform _trolley;

		private Transform _wheel;

		private LineRenderer _rope;

		private ZSFX _sound;

		private CableSpan _span;

		private float _distance;

		private float _speed;

		private float _spin;

		public void Begin(CableSpan span)
		{
			//IL_001b: 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)
			if (IsValid())
			{
				ZDO zDO = _view.GetZDO();
				zDO.Set("JevZiplines_From", span.From);
				zDO.Set("JevZiplines_To", span.To);
				zDO.Set("JevZiplines_Riding", true);
			}
		}

		public void End()
		{
			if (IsValid())
			{
				_view.GetZDO().Set("JevZiplines_Riding", false);
			}
		}

		private void Awake()
		{
			_view = ((Component)this).GetComponent<ZNetView>();
		}

		private void LateUpdate()
		{
			if (!IsValid() || !_view.GetZDO().GetBool("JevZiplines_Riding", false))
			{
				Hide();
				return;
			}
			if ((Object)(object)_trolley == (Object)null)
			{
				Show();
			}
			if (ReadSpan())
			{
				_distance = NearestDistance();
			}
			Roll();
		}

		private void OnDestroy()
		{
			Hide();
		}

		private bool IsValid()
		{
			if ((Object)(object)_view != (Object)null)
			{
				return _view.IsValid();
			}
			return false;
		}

		private float NearestDistance()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.position + Vector3.up * 2.15f;
			Vector3 val2 = _span.To - _span.From;
			return Mathf.Clamp01(Vector3.Dot(val - _span.From, val2) / ((Vector3)(ref val2)).sqrMagnitude) * _span.Length;
		}

		private bool ReadSpan()
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			ZDO zDO = _view.GetZDO();
			Vector3 vec = zDO.GetVec3("JevZiplines_From", Vector3.zero);
			Vector3 vec2 = zDO.GetVec3("JevZiplines_To", Vector3.zero);
			if (vec == _span.From && vec2 == _span.To)
			{
				return false;
			}
			_span = new CableSpan(vec, vec2);
			return true;
		}

		private void Show()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			ReadSpan();
			_hand = ((Component)this).GetComponent<VisEquipment>().m_leftHand;
			_trolley = new GameObject("ZiplineTrolley").transform;
			_trolley.SetParent(((Component)this).transform, false);
			_wheel = SteelParts.Wheel(_trolley, 0.09f, 0.05f);
			_wheel.localPosition = Vector3.up * 0.09f;
			_rope = CableLines.Create(_trolley, "Rope", 0.045f);
			if ((Object)(object)GrappleAssets.PullSound != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(GrappleAssets.PullSound, _trolley);
				_sound = val.GetComponentInChildren<ZSFX>();
			}
			_distance = NearestDistance();
			_speed = 0f;
		}

		private void Hide()
		{
			if ((Object)(object)_trolley != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_trolley).gameObject);
				_trolley = null;
			}
		}

		private void Roll()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(Time.deltaTime, 0.001f);
			float num2 = NearestDistance();
			float num3 = num2 - _distance;
			_distance = num2;
			_speed = Mathf.Lerp(_speed, num3 / num, Mathf.Clamp01(8f * num));
			_spin = Mathf.Repeat(_spin + num3 / 0.09f * 57.29578f, 360f);
			float t = num2 / _span.Length;
			_trolley.SetPositionAndRotation(_span.Point(t), Quaternion.LookRotation(_span.Tangent(t), Vector3.up));
			_wheel.localRotation = Quaternion.AngleAxis(_spin, Vector3.right) * Quaternion.Euler(0f, 0f, 90f);
			_rope.SetPosition(0, _hand.position);
			_rope.SetPosition(1, _wheel.position);
			if ((Object)(object)_sound != (Object)null)
			{
				_sound.SetPitchModifier(0.8f + 0.5f * Mathf.Clamp01(_speed / 20f));
			}
		}
	}
	public static class SteelParts
	{
		public static Transform Wheel(Transform parent, float radius, float width)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = Part((PrimitiveType)2, parent, "Wheel");
			obj.localRotation = Quaternion.Euler(0f, 0f, 90f);
			obj.localScale = new Vector3(radius * 2f, width * 0.5f, radius * 2f);
			return obj;
		}

		public static Transform Plate(Transform parent, Vector3 position, Vector3 size)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = Part((PrimitiveType)3, parent, "Plate");
			o