Decompiled source of Ziplines v1.0.3

plugins/Ziplines.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Ziplines;

public enum MessageLevel
{
	Short,
	All,
	Off
}
[BepInPlugin("anwo.Ziplines", "Ziplines", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class ZiplinesPlugin : BaseUnityPlugin
{
	public const string Guid = "anwo.Ziplines";

	public const string ModName = "Ziplines";

	public const string Version = "1.0.3";

	public const string PostPrefabName = "anwo_zipline_post";

	public const string RopePrefabName = "anwo_zipline_rope";

	internal static ManualLogSource Log;

	internal static ZiplinesPlugin Instance;

	internal static ConfigEntry<float> MaxRopeLength;

	internal static ConfigEntry<float> MaxSlope;

	internal static ConfigEntry<int> MaxRopesPerPost;

	internal static ConfigEntry<bool> RequireClearance;

	internal static ConfigEntry<string> PostRecipe;

	internal static ConfigEntry<float> RopeSag;

	internal static ConfigEntry<float> MaxSpeed;

	internal static ConfigEntry<float> Gravity;

	internal static ConfigEntry<float> AutoPullSpeed;

	internal static ConfigEntry<float> PullSpeed;

	internal static ConfigEntry<float> PullStamina;

	internal static ConfigEntry<float> BrakeStrength;

	internal static ConfigEntry<bool> AutoBrake;

	internal static ConfigEntry<float> ArrivalSpeed;

	internal static ConfigEntry<string> RideAnimation;

	internal static ConfigEntry<float> HangHeight;

	internal static ConfigEntry<float> RopeWidth;

	internal static ConfigEntry<bool> GrabOnTouch;

	internal static ConfigEntry<MessageLevel> Messages;

	internal static ConfigEntry<bool> RideSound;

	internal static ConfigEntry<float> SoundVolume;

	private static GameObject s_container;

	internal static GameObject Container
	{
		get
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)s_container == (Object)null)
			{
				s_container = new GameObject("anwo_Ziplines_Prefabs");
				Object.DontDestroyOnLoad((Object)(object)s_container);
				s_container.SetActive(false);
			}
			return s_container;
		}
	}

	internal static void Say(Player player, string full, string brief, MessageType fullType = (MessageType)2)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || Messages == null)
		{
			return;
		}
		switch (Messages.Value)
		{
		case MessageLevel.Off:
			break;
		case MessageLevel.All:
			if (!string.IsNullOrEmpty(full))
			{
				((Character)player).Message(fullType, full, 0, (Sprite)null, false);
			}
			break;
		default:
			if (!string.IsNullOrEmpty(brief))
			{
				((Character)player).Message((MessageType)1, brief, 0, (Sprite)null, false);
			}
			break;
		}
	}

	private void Awake()
	{
		//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_0027: Expected O, but got Unknown
		//IL_0027: 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)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		BindConfig();
		GameObject val = new GameObject("anwo_Ziplines_Helper");
		Object.DontDestroyOnLoad((Object)val);
		val.AddComponent<RopeCarry>();
		val.AddComponent<RideVisuals>();
		val.AddComponent<RopeGrab>();
		PrefabManager.OnVanillaPrefabsAvailable += RegisterPrefabs;
		Log.LogInfo((object)"Ziplines 1.0.3 loaded.");
	}

	private ConfigEntry<T> Synced<T>(string section, string key, T value, string description, AcceptableValueBase range = null)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes();
		val.IsAdminOnly = true;
		return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { val }));
	}

	private void BindConfig()
	{
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Expected O, but got Unknown
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Expected O, but got Unknown
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Expected O, but got Unknown
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Expected O, but got Unknown
		MaxRopeLength = Synced("1 - Rules", "Max rope length", 150f, "Longest rope you can tie between two posts, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 400f));
		MaxSlope = Synced("1 - Rules", "Max slope", 60f, "Steepest rope allowed, in degrees from horizontal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 80f));
		MaxRopesPerPost = Synced("1 - Rules", "Max ropes per post", 4, "How many ropes one post can hold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8));
		RequireClearance = Synced("1 - Rules", "Require clearance", value: true, "Refuse ropes where a rider would scrape the ground, water, trees, rocks or buildings on the way.");
		RopeSag = Synced("1 - Rules", "Rope sag", 0.02f, "How much a new rope sags in the middle, as a share of its length (0.02 = 2 m on a 100 m rope).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f));
		PostRecipe = Synced("1 - Rules", "Post recipe", "Wood:8,LeatherScraps:4,Iron:2", "Cost of one zipline post, as Item:Amount pairs separated by commas. Needs a game restart.");
		MaxSpeed = Synced("2 - Riding", "Max speed", 20f, "Top speed on the rope, in metres per second (20 m/s = 72 km/h).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 40f));
		Gravity = Synced("2 - Riding", "Gravity", 1f, "How strongly a downhill rope speeds you up. 1 = real gravity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f));
		AutoPullSpeed = Synced("2 - Riding", "Crawl speed", 0f, "Minimum speed towards the far post, in m/s, so you arrive even without pulling. 0 = off: uphill you hold Forward to pull yourself up, and when you stop pulling you slide back down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 6f));
		PullSpeed = Synced("2 - Riding", "Pull speed", 4f, "Speed, in m/s, when you hold Forward to pull yourself along the rope, hand over hand (also uphill).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f));
		PullStamina = Synced("2 - Riding", "Pull stamina per second", 6f, "Stamina used per second while pulling yourself along.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f));
		BrakeStrength = Synced("2 - Riding", "Brake strength", 10f, "How fast Backward (or Block) slows you down, in m/s per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f));
		AutoBrake = Synced("2 - Riding", "Auto-brake at the end", value: true, "Slow down automatically before the far post so you don't slam into it.");
		ArrivalSpeed = Synced("2 - Riding", "Arrival speed", 3f, "Speed, in m/s, that the auto-brake slows you to before the far post.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f));
		RideAnimation = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Look and feel", "Ride animation", "hang", new ConfigDescription("Body pose while riding. hang = hanging from the trolley's handle with both arms up, repell = the grappling hook's rappel pose, grappling = arms forward, attach_chair = sitting as on a chairlift, none = no pose.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "hang", "repell", "grappling", "attach_chair", "none" }), Array.Empty<object>()));
		HangHeight = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Look and feel", "Hang height", 2.3f, new ConfigDescription("Distance from the rope down to your feet while riding, in metres. The trolley's handle hangs where your hands reach.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.2f, 3f), Array.Empty<object>()));
		RopeWidth = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Look and feel", "Rope thickness", 0.05f, new ConfigDescription("Thickness of the drawn rope, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.2f), Array.Empty<object>()));
		GrabOnTouch = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Controls", "Grab the rope in mid-air", true, "Jump or fall into a zipline rope and you catch it and ride on in the direction you were going. Turn off to only get on at a post.");
		Messages = ((BaseUnityPlugin)this).Config.Bind<MessageLevel>("3 - Look and feel", "Messages", MessageLevel.Short, "Short: a few words in the top-left corner, only for what you did or what went wrong. All: the full help in the middle of the screen, and the controls each time you ride. Off: no messages.");
		RideSound = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Look and feel", "Ride sound", true, "Play the rope sound while riding.");
		SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Look and feel", "Ride sound volume", 0.7f, new ConfigDescription("Volume of the ride sound.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
	}

	private void RegisterPrefabs()
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00be: Expected O, but got Unknown
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Expected O, but got Unknown
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Expected O, but got Unknown
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Expected O, but got Unknown
		try
		{
			string text = null;
			string[] array = new string[3] { "wood_pole_log_4", "wood_pole_log", "wood_pole2" };
			foreach (string text2 in array)
			{
				if ((Object)(object)PrefabManager.Instance.GetPrefab(text2) != (Object)null)
				{
					text = text2;
					break;
				}
			}
			if (text == null)
			{
				Log.LogError((object)"Could not find a vanilla pole to build the zipline post from. The post is not added.");
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_zipline_post", text);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)("Cloning " + text + " failed. The zipline post is not added."));
				return;
			}
			Vector3 localRopePoint = Visuals.DecoratePost(val);
			val.AddComponent<ZiplineAnchor>().m_localRopePoint = localRopePoint;
			PieceConfig val2 = new PieceConfig();
			val2.Name = "Zipline post";
			val2.Description = "A log post with an iron pulley. Shift+E takes a rope to another post, E rides it.";
			val2.PieceTable = PieceTables.Hammer;
			val2.Category = PieceCategories.Misc;
			val2.CraftingStation = CraftingStations.Workbench;
			val2.Icon = LoadIcon();
			val2.Requirements = ParseRecipe(PostRecipe.Value);
			PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2));
			GameObject val3 = new GameObject("anwo_zipline_rope");
			val3.transform.SetParent(Container.transform, false);
			ZNetView obj = val3.AddComponent<ZNetView>();
			obj.m_persistent = true;
			obj.m_distant = true;
			obj.m_type = (ObjectType)0;
			val3.AddComponent<ZiplineRope>();
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val3, false));
			Log.LogInfo((object)("Zipline post built from " + text + "; rope point at " + ((Vector3)(ref localRopePoint)).ToString("F2")));
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Registering the zipline pieces failed: " + ex));
		}
		finally
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterPrefabs;
		}
	}

	private static RequirementConfig[] ParseRecipe(string recipe)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		List<RequirementConfig> list = new List<RequirementConfig>();
		if (!string.IsNullOrEmpty(recipe))
		{
			string[] array = recipe.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(':');
				if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result) && result > 0)
				{
					RequirementConfig val = new RequirementConfig();
					val.Item = array2[0].Trim();
					val.Amount = result;
					val.Recover = true;
					list.Add(val);
				}
			}
		}
		if (list.Count == 0)
		{
			RequirementConfig val2 = new RequirementConfig();
			val2.Item = "Wood";
			val2.Amount = 8;
			val2.Recover = true;
			list.Add(val2);
		}
		return list.ToArray();
	}

	private static Sprite LoadIcon()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_0081: 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)
		try
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ziplines.icon.png");
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					break;
				}
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			((Object)val).name = "anwo_zipline_icon";
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Could not load the zipline icon: " + ex.Message));
			return null;
		}
	}
}
[DefaultExecutionOrder(10000)]
public class RideVisuals : MonoBehaviour
{
	private sealed class Rider
	{
		public Player Player;

		public ZNetView NView;

		public GameObject Trolley;

		public Transform Strap;

		public Transform Bar;

		public bool BonesSearched;

		public Transform[] Left;

		public Transform[] Right;

		public float Reach;
	}

	internal const string KeyRiding = "anwo_zl_ride";

	internal const string KeyAxis = "anwo_zl_axis";

	internal const string KeyHang = "anwo_zl_hang";

	internal const string KeyHands = "anwo_zl_hands";

	private const float WheelDrop = 0.1f;

	private const float GripHalfWidth = 0.21f;

	private static readonly Dictionary<Player, Rider> s_riders = new Dictionary<Player, Rider>();

	private static readonly List<Player> s_gone = new List<Player>();

	private static bool s_boneWarning;

	private static bool s_failureLogged;

	internal static void MarkRiding(Player player, bool riding, Vector3 axis, float hang, bool hands)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			ZNetView val = (((Object)(object)player != (Object)null) ? ((Component)player).GetComponent<ZNetView>() : null);
			if (!((Object)(object)val == (Object)null) && val.IsValid() && val.IsOwner())
			{
				ZDO zDO = val.GetZDO();
				zDO.Set("anwo_zl_ride", riding);
				if (riding)
				{
					zDO.Set("anwo_zl_axis", axis);
					zDO.Set("anwo_zl_hang", hang);
					zDO.Set("anwo_zl_hands", hands);
				}
			}
		}
		catch (Exception ex)
		{
			ZiplinesPlugin.Log.LogWarning((object)("Marking the rider failed: " + ex.Message));
		}
	}

	private void LateUpdate()
	{
		try
		{
			List<Player> allPlayers = Player.GetAllPlayers();
			for (int i = 0; i < allPlayers.Count; i++)
			{
				Player val = allPlayers[i];
				if (!((Object)(object)val == (Object)null))
				{
					bool flag = IsRiding(val);
					Rider value;
					bool flag2 = s_riders.TryGetValue(val, out value);
					if (flag && !flag2)
					{
						value = (s_riders[val] = Create(val));
					}
					else if (!flag && flag2)
					{
						Remove(val, value);
						continue;
					}
					if (flag && value != null)
					{
						Pose(value);
					}
				}
			}
			s_gone.Clear();
			foreach (KeyValuePair<Player, Rider> s_rider in s_riders)
			{
				if ((Object)(object)s_rider.Key == (Object)null || !IsRiding(s_rider.Key))
				{
					s_gone.Add(s_rider.Key);
				}
			}
			for (int j = 0; j < s_gone.Count; j++)
			{
				Remove(s_gone[j], s_riders[s_gone[j]]);
			}
		}
		catch (Exception ex)
		{
			if (!s_failureLogged)
			{
				s_failureLogged = true;
				ZiplinesPlugin.Log.LogWarning((object)("Drawing riders failed (reported once): " + ex));
			}
		}
	}

	private static bool IsRiding(Player p)
	{
		if ((Object)(object)p == (Object)null)
		{
			return false;
		}
		ZNetView component = ((Component)p).GetComponent<ZNetView>();
		if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("anwo_zl_ride", false))
		{
			return !((Character)p).IsDead();
		}
		return false;
	}

	private static Rider Create(Player p)
	{
		Rider rider = new Rider();
		rider.Player = p;
		rider.NView = ((Component)p).GetComponent<ZNetView>();
		rider.Trolley = Visuals.MakeTrolley(out rider.Strap, out rider.Bar);
		return rider;
	}

	private static void Remove(Player p, Rider r)
	{
		if (r != null && (Object)(object)r.Trolley != (Object)null)
		{
			Object.Destroy((Object)(object)r.Trolley);
		}
		s_riders.Remove(p);
	}

	private static void Pose(Rider r)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		Player player = r.Player;
		ZDO val = (((Object)(object)r.NView != (Object)null && r.NView.IsValid()) ? r.NView.GetZDO() : null);
		if (val != null && !((Object)(object)r.Trolley == (Object)null))
		{
			Transform transform = ((Component)player).transform;
			Vector3 position = transform.position;
			float num = val.GetFloat("anwo_zl_hang", 2.3f);
			Vector3 val2 = val.GetVec3("anwo_zl_axis", transform.forward);
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
			{
				val2 = transform.forward;
			}
			((Vector3)(ref val2)).Normalize();
			if (!r.BonesSearched)
			{
				FindBones(r, position);
			}
			Vector3 val3 = position + Vector3.up * num;
			r.Trolley.transform.SetPositionAndRotation(val3, Quaternion.LookRotation(val2, Vector3.up));
			float num2 = ((r.Reach > 0.5f) ? r.Reach : (num - 0.3f));
			num2 = Mathf.Clamp(num2, num - 1.2f, num - 0.1f - 0.08f);
			Vector3 val4 = position + Vector3.up * num2;
			r.Bar.SetPositionAndRotation(val4, transform.rotation);
			float num3 = Mathf.Max(0.05f, val3.y - 0.1f - val4.y);
			r.Strap.position = val3 + Vector3.down * 0.1f;
			r.Strap.localScale = new Vector3(1f, num3, 1f);
			if (val.GetBool("anwo_zl_hands", true) && r.Left != null && r.Right != null)
			{
				Vector3 right = transform.right;
				Vector3 val5 = -transform.forward;
				SolveArm(r.Left, val4 - right * 0.21f, -right + val5 * 0.35f + Vector3.down * 0.2f);
				SolveArm(r.Right, val4 + right * 0.21f, right + val5 * 0.35f + Vector3.down * 0.2f);
			}
		}
	}

	private static void FindBones(Rider r, Vector3 feet)
	{
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		r.BonesSearched = true;
		try
		{
			Animator componentInChildren = ((Component)r.Player).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isHuman)
			{
				r.Left = Bones(componentInChildren.GetBoneTransform((HumanBodyBones)13), componentInChildren.GetBoneTransform((HumanBodyBones)15), componentInChildren.GetBoneTransform((HumanBodyBones)17));
				r.Right = Bones(componentInChildren.GetBoneTransform((HumanBodyBones)14), componentInChildren.GetBoneTransform((HumanBodyBones)16), componentInChildren.GetBoneTransform((HumanBodyBones)18));
			}
			if (r.Left == null || r.Right == null)
			{
				Transform root = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform : ((Component)r.Player).transform);
				r.Left = Bones(Find(root, "LeftArm"), Find(root, "LeftForeArm"), Find(root, "LeftHand"));
				r.Right = Bones(Find(root, "RightArm"), Find(root, "RightForeArm"), Find(root, "RightHand"));
			}
			if (r.Left == null || r.Right == null)
			{
				if (!s_boneWarning)
				{
					s_boneWarning = true;
					ZiplinesPlugin.Log.LogWarning((object)"Could not find the arm bones; riders hang without raised arms.");
				}
				return;
			}
			float num = (r.Left[0].position.y + r.Right[0].position.y) * 0.5f - feet.y;
			float num2 = Length(r.Left);
			r.Reach = num + num2 * 0.94f;
			ZiplinesPlugin.Log.LogDebug((object)("Rider arms found (" + ((Object)r.Left[0]).name + "), reach " + r.Reach.ToString("0.00") + " m"));
		}
		catch (Exception ex)
		{
			r.Left = (r.Right = null);
			ZiplinesPlugin.Log.LogWarning((object)("Looking up the arm bones failed: " + ex.Message));
		}
	}

	private static Transform[] Bones(Transform upper, Transform lower, Transform hand)
	{
		if ((Object)(object)upper == (Object)null || (Object)(object)lower == (Object)null || (Object)(object)hand == (Object)null)
		{
			return null;
		}
		if (!lower.IsChildOf(upper) || !hand.IsChildOf(lower))
		{
			return null;
		}
		return (Transform[])(object)new Transform[3] { upper, lower, hand };
	}

	private static float Length(Transform[] arm)
	{
		//IL_0003: 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_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = arm[1].position - arm[0].position;
		float magnitude = ((Vector3)(ref val)).magnitude;
		val = arm[2].position - arm[1].position;
		return magnitude + ((Vector3)(ref val)).magnitude;
	}

	private static Transform Find(Transform root, string name)
	{
		Transform result = null;
		Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			string text = ((Object)val).name;
			int num = text.LastIndexOf(':');
			if (num >= 0)
			{
				text = text.Substring(num + 1);
			}
			if (string.Equals(text, name, StringComparison.OrdinalIgnoreCase))
			{
				result = val;
				break;
			}
		}
		return result;
	}

	internal static void SolveArm(Transform[] arm, Vector3 target, Vector3 pole)
	{
		//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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0036: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//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_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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_00a9: 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_00b0: 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_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		Transform val = arm[0];
		Transform val2 = arm[1];
		Transform val3 = arm[2];
		Vector3 position = val.position;
		Vector3 position2 = val2.position;
		Vector3 position3 = val3.position;
		Vector3 val4 = position2 - position;
		float magnitude = ((Vector3)(ref val4)).magnitude;
		val4 = position3 - position2;
		float magnitude2 = ((Vector3)(ref val4)).magnitude;
		if (magnitude < 0.0001f || magnitude2 < 0.0001f)
		{
			return;
		}
		val4 = target - position;
		float num = Mathf.Clamp(((Vector3)(ref val4)).magnitude, Mathf.Abs(magnitude - magnitude2) + 0.001f, magnitude + magnitude2 - 0.001f);
		float num2 = Angle(position3 - position, position2 - position);
		float num3 = Angle(position - position2, position3 - position2);
		float num4 = Mathf.Acos(Mathf.Clamp((magnitude2 * magnitude2 - magnitude * magnitude - num * num) / (-2f * magnitude * num), -1f, 1f));
		float num5 = Mathf.Acos(Mathf.Clamp((num * num - magnitude * magnitude - magnitude2 * magnitude2) / (-2f * magnitude * magnitude2), -1f, 1f));
		Vector3 val5 = Vector3.Cross(position3 - position, position2 - position);
		if (((Vector3)(ref val5)).sqrMagnitude < 1E-08f)
		{
			val5 = Vector3.Cross(position3 - position, pole);
		}
		if (((Vector3)(ref val5)).sqrMagnitude < 1E-08f)
		{
			return;
		}
		((Vector3)(ref val5)).Normalize();
		val2.rotation = Quaternion.AngleAxis((num5 - num3) * 57.29578f, val5) * val2.rotation;
		val.rotation = Quaternion.AngleAxis((num4 - num2) * 57.29578f, val5) * val.rotation;
		val.rotation = Quaternion.FromToRotation(val3.position - position, target - position) * val.rotation;
		Vector3 val6 = target - position;
		if (!(((Vector3)(ref val6)).sqrMagnitude < 1E-08f))
		{
			((Vector3)(ref val6)).Normalize();
			Vector3 val7 = Vector3.ProjectOnPlane(val2.position - position, val6);
			Vector3 val8 = Vector3.ProjectOnPlane(pole, val6);
			if (!(((Vector3)(ref val7)).sqrMagnitude < 1E-08f) && !(((Vector3)(ref val8)).sqrMagnitude < 1E-08f))
			{
				float num6 = Vector3.SignedAngle(val7, val8, val6);
				val.rotation = Quaternion.AngleAxis(num6, val6) * val.rotation;
			}
		}
	}

	private static float Angle(Vector3 u, Vector3 v)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		float num = ((Vector3)(ref u)).magnitude * ((Vector3)(ref v)).magnitude;
		if (num < 1E-08f)
		{
			return 0f;
		}
		return Mathf.Acos(Mathf.Clamp(Vector3.Dot(u, v) / num, -1f, 1f));
	}

	private void OnDestroy()
	{
		foreach (Rider value in s_riders.Values)
		{
			if (value != null && (Object)(object)value.Trolley != (Object)null)
			{
				Object.Destroy((Object)(object)value.Trolley);
			}
		}
		s_riders.Clear();
	}
}
public class RopeCarry : MonoBehaviour
{
	internal enum Verdict
	{
		Keep,
		NoPlayer,
		Dead,
		Teleported,
		SourceGone,
		TooFar,
		Attached,
		LetGo,
		SourceMoved
	}

	internal struct Snapshot
	{
		public bool HasPlayer;

		public bool Dead;

		public bool Teleporting;

		public bool Attached;

		public float Distance;

		public float MaxLength;

		public bool SourceDestroyed;

		public bool SourceChecked;

		public bool SourceRemoved;

		public bool SourceLoaded;

		public bool SourceMoved;

		public bool AreaReady;

		public bool AnchorAtPoint;

		public int MissesInARow;

		public bool LetGo;
	}

	internal static bool Active;

	internal static ZiplineAnchor From;

	internal static Vector3 FromPoint;

	internal const float SlackMetres = 1f;

	internal const float LetGoHoldSeconds = 1f;

	internal const float SourceCheckInterval = 0.25f;

	internal const int FailuresBeforeDrop = 30;

	private static LineRenderer s_line;

	private static readonly Vector3[] s_points = (Vector3[])(object)new Vector3[20];

	private static ZiplineAnchor s_checkedTarget;

	private static float s_checkedTime;

	private static bool s_checkedOk;

	private static float s_checkedLength;

	private static string s_checkedProblem;

	private static int s_clearanceMask = -1;

	private static float s_warnTime;

	private static bool s_sourceDestroyed;

	private static ZDOID s_fromId = ZDOID.None;

	private static int s_misses;

	private static float s_nextSourceCheck;

	private static bool s_useReleased;

	private static float s_holdTime;

	private static int s_failures;

	private static bool s_failureLogged;

	private static bool s_lineFailureLogged;

	private static readonly Func<Player, bool> s_takeInput = MakeTakeInput();

	private static bool s_frameFailed;

	private static bool s_postCheckRan;

	private static Func<Player, bool> MakeTakeInput()
	{
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);
			return (methodInfo != null) ? AccessTools.MethodDelegate<Func<Player, bool>>(methodInfo, (object)null, true) : null;
		}
		catch
		{
			return null;
		}
	}

	private void Awake()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("anwo_zipline_carried_rope");
		val.transform.SetParent(((Component)this).transform, false);
		s_line = val.AddComponent<LineRenderer>();
		s_line.positionCount = s_points.Length;
		((Renderer)s_line).enabled = false;
	}

	internal static bool IsSource(ZiplineAnchor anchor)
	{
		//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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if (!Active || (Object)(object)anchor == (Object)null)
		{
			return false;
		}
		if ((Object)(object)From != (Object)null && (Object)(object)anchor == (Object)(object)From)
		{
			return true;
		}
		float num = 0.4f;
		Vector3 val = anchor.RopePoint - FromPoint;
		return ((Vector3)(ref val)).sqrMagnitude <= num * num;
	}

	internal static bool AltInteract(ZiplineAnchor anchor, Player player)
	{
		//IL_0135: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		if (!Active)
		{
			if ((Object)(object)ZiplineRider.Current != (Object)null)
			{
				return false;
			}
			if (((Character)player).IsAttached())
			{
				ZiplinesPlugin.Say(player, "Get up first: you need both hands free to take a rope", "Get up first to take a rope", (MessageType)2);
				return false;
			}
			if (!PrivateArea.CheckAccess(((Component)anchor).transform.position, 0f, true, false))
			{
				return false;
			}
			int value = ZiplinesPlugin.MaxRopesPerPost.Value;
			if (anchor.RopeCount() >= value)
			{
				ZiplinesPlugin.Say(player, "This post already holds " + ((value == 1) ? "a rope" : (value + " ropes")), "This post is full", (MessageType)2);
				return false;
			}
			Begin(anchor);
			ZiplinesPlugin.Say(player, "Rope in hand. Walk to another zipline post (up to " + ZiplinesPlugin.MaxRopeLength.Value.ToString("0") + " m away), hold $KEY_AltPlace and press $KEY_Use. Hold $KEY_Use while looking at nothing to drop it.", "Rope in hand (" + ZiplinesPlugin.MaxRopeLength.Value.ToString("0") + " m)", (MessageType)2);
			return true;
		}
		if (IsSource(anchor))
		{
			Stop();
			ZiplinesPlugin.Say(player, "You put the rope back", "Rope put back", (MessageType)2);
			return true;
		}
		s_checkedTarget = null;
		if (!CanTieTo(anchor, out var length, out var problem))
		{
			ZiplinesPlugin.Say(player, problem, problem, (MessageType)2);
			return false;
		}
		if (!PrivateArea.CheckAccess(((Component)anchor).transform.position, 0f, true, false))
		{
			return false;
		}
		if ((Object)(object)ZiplineRope.Spawn(FromPoint, anchor.RopePoint) == (Object)null)
		{
			ZiplinesPlugin.Say(player, "The rope could not be tied (see the BepInEx log)", "The rope could not be tied", (MessageType)2);
			return false;
		}
		Stop();
		ZiplinesPlugin.Say(player, "Zipline ready: " + length.ToString("0") + " m. Press $KEY_Use at either post to ride.", "Zipline ready: " + length.ToString("0") + " m", (MessageType)2);
		return true;
	}

	private static void Begin(ZiplineAnchor anchor)
	{
		//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_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)
		Active = true;
		From = anchor;
		FromPoint = anchor.RopePoint;
		s_fromId = anchor.ZdoId;
		s_misses = 0;
		s_checkedTarget = null;
		s_sourceDestroyed = false;
		s_nextSourceCheck = 0f;
		s_useReleased = false;
		s_holdTime = 0f;
		s_failures = 0;
		s_warnTime = 0f;
		if ((Object)(object)s_line != (Object)null)
		{
			Visuals.SetupLine(s_line, ZiplinesPlugin.RopeWidth.Value);
			((Renderer)s_line).enabled = true;
		}
	}

	internal static void Stop()
	{
		//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)
		Active = false;
		From = null;
		s_fromId = ZDOID.None;
		s_misses = 0;
		s_checkedTarget = null;
		s_sourceDestroyed = false;
		s_holdTime = 0f;
		s_failures = 0;
		if ((Object)(object)s_line != (Object)null)
		{
			((Renderer)s_line).enabled = false;
		}
	}

	internal static void SourceDestroyed(ZiplineAnchor anchor)
	{
		if (IsSource(anchor))
		{
			s_sourceDestroyed = true;
			From = null;
		}
	}

	private static bool SourceRemoved()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		if (!((ZDOID)(ref s_fromId)).IsNone() && ZDOMan.instance != null)
		{
			return ZDOMan.instance.GetZDO(s_fromId) == null;
		}
		return false;
	}

	internal static void SourceUnloaded(ZiplineAnchor anchor)
	{
		if (Active && (Object)(object)From == (Object)(object)anchor)
		{
			From = null;
		}
		s_nextSourceCheck = 0f;
	}

	internal static bool CanTieTo(ZiplineAnchor target, out float length, out string problem)
	{
		if ((Object)(object)s_checkedTarget == (Object)(object)target && Time.time - s_checkedTime < 0.3f)
		{
			length = s_checkedLength;
			problem = s_checkedProblem;
			return s_checkedOk;
		}
		bool result = Check(target, out length, out problem);
		s_checkedTarget = target;
		s_checkedTime = Time.time;
		s_checkedOk = result;
		s_checkedLength = length;
		s_checkedProblem = problem;
		return result;
	}

	private static bool Check(ZiplineAnchor target, out float length, out string problem)
	{
		//IL_0003: 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_000a: 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_0011: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		problem = null;
		Vector3 fromPoint = FromPoint;
		Vector3 ropePoint = target.RopePoint;
		length = Vector3.Distance(fromPoint, ropePoint);
		if (s_sourceDestroyed || SourceRemoved() || ((Object)(object)From == (Object)null && s_misses >= 2))
		{
			problem = "The post you took this rope from is gone";
			return false;
		}
		if (length < 4f)
		{
			problem = "Too close to the other post";
			return false;
		}
		float value = ZiplinesPlugin.MaxRopeLength.Value;
		if (length > value)
		{
			problem = "Too far: " + length.ToString("0") + " m (the rope is " + value.ToString("0") + " m long)";
			return false;
		}
		float num = Mathf.Asin(Mathf.Clamp(Mathf.Abs(ropePoint.y - fromPoint.y) / length, 0f, 1f)) * 57.29578f;
		if (num > ZiplinesPlugin.MaxSlope.Value)
		{
			problem = "Too steep (" + num.ToString("0") + "°, max " + ZiplinesPlugin.MaxSlope.Value.ToString("0") + "°)";
			return false;
		}
		int value2 = ZiplinesPlugin.MaxRopesPerPost.Value;
		if (target.RopeCount() >= value2)
		{
			problem = "This post has no free rope slots";
			return false;
		}
		if ((Object)(object)From != (Object)null && From.RopeCount() >= value2)
		{
			problem = "The post you took this rope from has no free rope slots any more";
			return false;
		}
		if (ZiplineRope.Connects(fromPoint, ropePoint))
		{
			problem = "These posts are already connected";
			return false;
		}
		if (ZiplinesPlugin.RequireClearance.Value && !CheckClearance(new RopePath(fromPoint, ropePoint, ZiplinesPlugin.RopeSag.Value), out problem))
		{
			return false;
		}
		return true;
	}

	internal static bool CheckClearance(RopePath path, out string problem)
	{
		//IL_00a2: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		problem = null;
		float value = ZiplinesPlugin.HangHeight.Value;
		float length = path.Length;
		float num = Mathf.Min(3f, length * 0.2f);
		int num2 = Mathf.Max(4, Mathf.CeilToInt(length / 1.5f));
		float num3 = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f);
		if (s_clearanceMask == -1)
		{
			s_clearanceMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
		}
		Vector3 val = Vector3.zero;
		bool flag = false;
		float num5 = default(float);
		RaycastHit val5 = default(RaycastHit);
		for (int i = 0; i <= num2; i++)
		{
			float num4 = length * (float)i / (float)num2;
			Vector3 val2 = path.PointAt(num4) + Vector3.down * value;
			Vector3 val3 = val2 + Vector3.up * 1f;
			if (!(num4 < num) && !(num4 > length - num))
			{
				if (Heightmap.GetHeight(val2, ref num5) && val2.y < num5 + 0.3f)
				{
					problem = "Too low: a rider would hit the ground " + num4.ToString("0") + " m along. Raise one end.";
					return false;
				}
				if (val2.y < num3 + 0.3f)
				{
					problem = "Too low: a rider would drag through the water " + num4.ToString("0") + " m along";
					return false;
				}
				if (flag)
				{
					Vector3 val4 = val3 - val;
					float magnitude = ((Vector3)(ref val4)).magnitude;
					if (magnitude > 0.01f && Physics.SphereCast(val, 0.35f, val4 / magnitude, ref val5, magnitude, s_clearanceMask, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val5)).collider != (Object)null && (Object)(object)((Component)((RaycastHit)(ref val5)).collider).GetComponentInParent<ZiplineAnchor>() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val5)).collider).GetComponentInParent<Character>() == (Object)null)
					{
						problem = "Blocked by " + Describe(((RaycastHit)(ref val5)).collider) + " " + num4.ToString("0") + " m along";
						return false;
					}
				}
			}
			val = val3;
			flag = true;
		}
		return true;
	}

	private static string Describe(Collider collider)
	{
		Transform root = ((Component)collider).transform.root;
		string text = (((Object)(object)root != (Object)null) ? ((Object)root).name : ((Object)collider).name);
		int num = text.IndexOf("(Clone)", StringComparison.Ordinal);
		if (num > 0)
		{
			text = text.Substring(0, num);
		}
		if ((Object)(object)((Component)collider).GetComponentInParent<Piece>() != (Object)null)
		{
			return "a building piece (" + text.Trim() + ")";
		}
		if (((Component)collider).gameObject.layer == LayerMask.NameToLayer("terrain"))
		{
			return "the ground";
		}
		return text.Trim();
	}

	internal static Verdict Judge(Snapshot s)
	{
		if (!s.HasPlayer)
		{
			return Verdict.NoPlayer;
		}
		if (s.Dead)
		{
			return Verdict.Dead;
		}
		if (s.Teleporting)
		{
			return Verdict.Teleported;
		}
		if (s.SourceDestroyed || s.SourceRemoved)
		{
			return Verdict.SourceGone;
		}
		if (!(s.Distance <= s.MaxLength + 1f))
		{
			return Verdict.TooFar;
		}
		if (s.Attached)
		{
			return Verdict.Attached;
		}
		if (s.LetGo)
		{
			return Verdict.LetGo;
		}
		if (s.SourceChecked)
		{
			if (s.SourceLoaded && s.SourceMoved)
			{
				return Verdict.SourceMoved;
			}
			if (!s.SourceLoaded && s.AreaReady && !s.AnchorAtPoint && s.MissesInARow >= 2)
			{
				return Verdict.SourceGone;
			}
		}
		return Verdict.Keep;
	}

	internal static string BriefDropMessage(Verdict verdict, float maxLength)
	{
		return verdict switch
		{
			Verdict.Teleported => "The rope slipped back (no ropes through portals)", 
			Verdict.SourceGone => "Rope dropped: its post is gone", 
			Verdict.TooFar => "The rope ran out (" + maxLength.ToString("0") + " m)", 
			Verdict.SourceMoved => "Rope dropped: its post moved", 
			_ => null, 
		};
	}

	internal static string DropMessage(Verdict verdict, float maxLength)
	{
		return verdict switch
		{
			Verdict.Teleported => "You can't take a rope through a portal, so it slipped back to the post", 
			Verdict.SourceGone => "The post you took the rope from is gone, so you dropped the rope", 
			Verdict.TooFar => "The rope ran out (" + maxLength.ToString("0") + " m) and slipped back to the post", 
			Verdict.Attached => "You let go of the rope and it slipped back to the post", 
			Verdict.LetGo => "You let go of the rope and it slipped back to the post", 
			Verdict.SourceMoved => "The post you took the rope from moved, so you dropped the rope", 
			_ => null, 
		};
	}

	private static Snapshot Observe(Player player)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		Snapshot result = new Snapshot
		{
			HasPlayer = ((Object)(object)player != (Object)null)
		};
		if (!result.HasPlayer)
		{
			return result;
		}
		result.MaxLength = ZiplinesPlugin.MaxRopeLength.Value;
		result.Distance = Vector3.Distance(((Component)player).transform.position, FromPoint);
		result.SourceDestroyed = s_sourceDestroyed;
		try
		{
			result.Dead = ((Character)player).IsDead();
		}
		catch (Exception e)
		{
			Failed("dead check", e);
		}
		try
		{
			result.Teleporting = ((Character)player).IsTeleporting();
		}
		catch (Exception e2)
		{
			Failed("teleport check", e2);
		}
		try
		{
			result.Attached = ((Character)player).IsAttached() || (Object)(object)ZiplineRider.Current != (Object)null;
		}
		catch (Exception e3)
		{
			Failed("attach check", e3);
		}
		try
		{
			result.LetGo = HeldUseToLetGo(player);
		}
		catch (Exception e4)
		{
			Failed("let-go check", e4);
		}
		if (Time.time >= s_nextSourceCheck)
		{
			s_nextSourceCheck = Time.time + 0.25f;
			s_postCheckRan = true;
			try
			{
				float num = 0.4f;
				if ((Object)(object)From != (Object)null && !From.IsValid)
				{
					From = null;
				}
				if ((Object)(object)From == (Object)null)
				{
					From = ZiplineAnchor.FindAt(FromPoint, num);
				}
				result.SourceLoaded = (Object)(object)From != (Object)null;
				result.SourceRemoved = SourceRemoved();
				if (result.SourceLoaded)
				{
					Vector3 val = From.RopePoint - FromPoint;
					result.SourceMoved = ((Vector3)(ref val)).sqrMagnitude > num * num;
					s_misses = 0;
				}
				else
				{
					result.AreaReady = (Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(FromPoint);
					result.AnchorAtPoint = false;
					s_misses = (result.AreaReady ? (s_misses + 1) : 0);
				}
				result.MissesInARow = s_misses;
				result.SourceChecked = true;
			}
			catch (Exception e5)
			{
				Failed("post check", e5);
			}
		}
		return result;
	}

	private static bool HeldUseToLetGo(Player player)
	{
		if (!ZInput.GetButton("Use") && !ZInput.GetButton("JoyUse"))
		{
			s_useReleased = true;
			s_holdTime = 0f;
			return false;
		}
		bool flag = s_takeInput == null || s_takeInput(player);
		if (!s_useReleased || !flag || ((Character)player).InPlaceMode() || Hud.InRadial() || Hud.IsPieceSelectionVisible() || LookingAtSomethingUsable(player))
		{
			s_holdTime = 0f;
			return false;
		}
		s_holdTime += Time.deltaTime;
		return s_holdTime >= 1f;
	}

	private static bool LookingAtSomethingUsable(Player player)
	{
		GameObject hoverObject = ((Humanoid)player).GetHoverObject();
		if ((Object)(object)hoverObject == (Object)null)
		{
			return false;
		}
		if (hoverObject.GetComponentInParent<Interactable>() == null)
		{
			return hoverObject.GetComponentInParent<Hoverable>() != null;
		}
		return true;
	}

	private static void Failed(string what, Exception e)
	{
		s_frameFailed = true;
		if (!s_failureLogged)
		{
			s_failureLogged = true;
			ZiplinesPlugin.Log.LogWarning((object)("Carried rope " + what + " failed (reported once): " + e));
		}
	}

	private void Update()
	{
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		if (!Active)
		{
			if ((Object)(object)s_line != (Object)null && ((Renderer)s_line).enabled)
			{
				((Renderer)s_line).enabled = false;
			}
			return;
		}
		Player val = null;
		s_frameFailed = false;
		s_postCheckRan = false;
		try
		{
			val = Player.m_localPlayer;
			Verdict verdict = Judge(Observe(val));
			if (verdict != Verdict.Keep)
			{
				float value = ZiplinesPlugin.MaxRopeLength.Value;
				Stop();
				ZiplinesPlugin.Say(val, DropMessage(verdict, value), BriefDropMessage(verdict, value), (MessageType)2);
				return;
			}
		}
		catch (Exception e)
		{
			Failed("update", e);
		}
		if (s_frameFailed)
		{
			if (++s_failures >= 30)
			{
				ZiplinesPlugin.Log.LogWarning((object)"The carried rope's checks kept failing, so the rope was dropped.");
				Stop();
				ZiplinesPlugin.Say(val, "Something went wrong with the rope, so you dropped it", "Rope dropped (something went wrong)", (MessageType)2);
				return;
			}
		}
		else if (s_postCheckRan)
		{
			s_failures = 0;
		}
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		try
		{
			float num = Vector3.Distance(((Component)val).transform.position, FromPoint);
			float value2 = ZiplinesPlugin.MaxRopeLength.Value;
			if (num > value2 - 10f && Time.time >= s_warnTime)
			{
				s_warnTime = ((ZiplinesPlugin.Messages.Value == MessageLevel.All) ? (Time.time + 3f) : float.MaxValue);
				string text = "Rope almost out: " + Mathf.Max(0f, value2 - num).ToString("0") + " m left";
				ZiplinesPlugin.Say(val, text, text, (MessageType)1);
			}
			DrawCarriedRope(val, num);
		}
		catch (Exception ex)
		{
			if (!s_lineFailureLogged)
			{
				s_lineFailureLogged = true;
				ZiplinesPlugin.Log.LogWarning((object)("Drawing the carried rope failed (reported once): " + ex));
			}
		}
	}

	private static void DrawCarriedRope(Player player, float distance)
	{
		//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_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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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_008d: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)s_line == (Object)null))
		{
			if (!((Renderer)s_line).enabled)
			{
				((Renderer)s_line).enabled = true;
			}
			Visuals.RefreshLine(s_line);
			Vector3 val = ((Component)player).transform.position + Vector3.up * 1.2f + ((Component)player).transform.forward * 0.25f;
			VisEquipment component = ((Component)player).GetComponent<VisEquipment>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_rightHand != (Object)null)
			{
				val = component.m_rightHand.position;
			}
			float num = Mathf.Clamp(distance * 0.08f, 0.2f, 4f);
			int num2 = s_points.Length - 1;
			for (int i = 0; i <= num2; i++)
			{
				float num3 = (float)i / (float)num2;
				s_points[i] = Vector3.Lerp(FromPoint, val, num3) + Vector3.down * (4f * num * num3 * (1f - num3));
			}
			s_line.SetPositions(s_points);
		}
	}
}
public class RopeGrab : MonoBehaviour
{
	private const float Reach = 0.6f;

	private const float PostClearance = 2.5f;

	private void Update()
	{
		//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_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!ZiplinesPlugin.GrabOnTouch.Value || (Object)(object)ZiplineRider.Current != (Object)null || RopeCarry.Active || Time.time < ZiplineRider.NoGrabUntil)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsOnGround() || ((Character)localPlayer).IsSwimming() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).InPlaceMode() || localPlayer.GetDoodadController() != null || ((Character)localPlayer).IsTeleporting() || ZiplineRope.All.Count == 0)
			{
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float value = ZiplinesPlugin.HangHeight.Value;
			Vector3 p = position + Vector3.up * (value * 0.6f);
			foreach (ZiplineRope item in ZiplineRope.All)
			{
				RopePath ropePath = (((Object)(object)item != (Object)null) ? item.Path : null);
				if (ropePath == null)
				{
					continue;
				}
				float t = ClosestT(ropePath, p);
				Vector3 val = ropePath.PointT(t);
				float num = val.y - position.y;
				if (num < 0.6f || num > value + 0.4f)
				{
					continue;
				}
				Vector3 val2 = val - position;
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude > 0.36f)
				{
					continue;
				}
				float num2 = DistanceFromA(ropePath, t);
				if (!(num2 < 2.5f) && !(num2 > ropePath.Length - 2.5f))
				{
					Vector3 velocity = ((Character)localPlayer).GetVelocity();
					if (!ZiplineRider.TryGrab(localPlayer, item, num2, velocity))
					{
						ZiplineRider.NoGrabUntil = Time.time + 1f;
					}
					break;
				}
			}
		}
		catch (Exception ex)
		{
			ZiplinesPlugin.Log.LogDebug((object)("Rope grab check failed: " + ex.Message));
			ZiplineRider.NoGrabUntil = Time.time + 2f;
		}
	}

	internal static float ClosestT(RopePath path, Vector3 p)
	{
		//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_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = path.B - path.A;
		float num = Mathf.Clamp01(Vector3.Dot(p - path.A, val) / Mathf.Max(0.0001f, ((Vector3)(ref val)).sqrMagnitude));
		for (int i = 0; i < 4; i++)
		{
			Vector3 val2 = val + Vector3.down * (4f * path.SagDepth * (1f - 2f * num));
			float num2 = Vector3.Dot(p - path.PointT(num), val2) / Mathf.Max(0.0001f, ((Vector3)(ref val2)).sqrMagnitude);
			num = Mathf.Clamp01(num + num2);
		}
		return num;
	}

	internal static float DistanceFromA(RopePath path, float t)
	{
		float num = 0f;
		float num2 = path.Length;
		for (int i = 0; i < 24; i++)
		{
			float num3 = (num + num2) * 0.5f;
			if (path.TAt(num3) < t)
			{
				num = num3;
			}
			else
			{
				num2 = num3;
			}
		}
		return (num + num2) * 0.5f;
	}
}
internal sealed class RopePath
{
	private const int Samples = 64;

	public readonly Vector3 A;

	public readonly Vector3 B;

	public readonly float SagDepth;

	public readonly float Length;

	private readonly float[] m_distance = new float[65];

	public RopePath(Vector3 a, Vector3 b, float sagFactor)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: 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)
		A = a;
		B = b;
		SagDepth = Mathf.Max(0f, sagFactor) * Vector3.Distance(a, b);
		Vector3 val = A;
		m_distance[0] = 0f;
		for (int i = 1; i <= 64; i++)
		{
			Vector3 val2 = PointT((float)i / 64f);
			m_distance[i] = m_distance[i - 1] + Vector3.Distance(val, val2);
			val = val2;
		}
		Length = Mathf.Max(0.01f, m_distance[64]);
	}

	public Vector3 PointT(float t)
	{
		//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_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_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)
		t = Mathf.Clamp01(t);
		return Vector3.LerpUnclamped(A, B, t) + Vector3.down * (4f * SagDepth * t * (1f - t));
	}

	public float TAt(float s)
	{
		if (s <= 0f)
		{
			return 0f;
		}
		if (s >= Length)
		{
			return 1f;
		}
		int num = 0;
		int num2 = 64;
		while (num2 - num > 1)
		{
			int num3 = num + num2 >> 1;
			if (m_distance[num3] <= s)
			{
				num = num3;
			}
			else
			{
				num2 = num3;
			}
		}
		float num4 = m_distance[num2] - m_distance[num];
		float num5 = ((num4 > 1E-05f) ? ((s - m_distance[num]) / num4) : 0f);
		return ((float)num + num5) / 64f;
	}

	public Vector3 PointAt(float s)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		return PointT(TAt(s));
	}

	public Vector3 TangentAt(float s)
	{
		//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_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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)
		float num = TAt(s);
		Vector3 val = B - A + Vector3.up * (4f * SagDepth * (2f * num - 1f));
		if (!(((Vector3)(ref val)).sqrMagnitude > 1E-06f))
		{
			return Vector3.forward;
		}
		return ((Vector3)(ref val)).normalized;
	}

	public bool HasEnd(Vector3 p, float tolerance)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_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)
		float num = tolerance * tolerance;
		Vector3 val = A - p;
		if (!(((Vector3)(ref val)).sqrMagnitude <= num))
		{
			val = B - p;
			return ((Vector3)(ref val)).sqrMagnitude <= num;
		}
		return true;
	}

	public Vector3 OtherEnd(Vector3 p)
	{
		//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_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_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_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_0032: 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)
		Vector3 val = A - p;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		val = B - p;
		if (!(sqrMagnitude <= ((Vector3)(ref val)).sqrMagnitude))
		{
			return A;
		}
		return B;
	}

	public void Fill(Vector3[] points)
	{
		//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)
		int num = points.Length - 1;
		for (int i = 0; i <= num; i++)
		{
			points[i] = PointT((float)i / (float)num);
		}
	}
}
internal static class Visuals
{
	private static bool s_searched;

	private static Material s_ropeMaterial;

	private static LineTextureMode s_textureMode = (LineTextureMode)1;

	private static Vector2 s_textureScale = Vector2.one;

	private static GameObject s_pullSound;

	private static Material s_trolleyIron;

	private static Material s_trolleyWood;

	private static Mesh s_wheel;

	private static Mesh s_plate;

	private static Mesh s_hook;

	private static Mesh s_rod;

	private static Mesh s_grip;

	private static Mesh s_ring;

	internal static GameObject PullSoundPrefab
	{
		get
		{
			FindRopeAssets();
			return s_pullSound;
		}
	}

	private static void FindRopeAssets()
	{
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Expected O, but got Unknown
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Expected O, but got Unknown
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		if (s_searched || (Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		s_searched = true;
		LineRenderer val = null;
		try
		{
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null)
				{
					SharedData shared = component.m_itemData.m_shared;
					val = FromProjectile(shared.m_attack);
					if ((Object)(object)val == (Object)null)
					{
						val = FromProjectile(shared.m_secondaryAttack);
					}
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab == (Object)null)
					{
						continue;
					}
					GrapplingPoint componentInChildren = prefab.GetComponentInChildren<GrapplingPoint>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						LineRenderer component2 = ((Component)componentInChildren).GetComponent<LineRenderer>();
						if ((Object)(object)component2 != (Object)null && (Object)(object)((Renderer)component2).sharedMaterial != (Object)null)
						{
							val = component2;
							s_pullSound = componentInChildren.m_pullSound;
							break;
						}
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				foreach (GameObject prefab2 in ZNetScene.instance.m_prefabs)
				{
					if (!((Object)(object)prefab2 == (Object)null) && !((Object)(object)prefab2.GetComponent<Vagon>() == (Object)null))
					{
						LineRenderer componentInChildren2 = prefab2.GetComponentInChildren<LineRenderer>(true);
						if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)((Renderer)componentInChildren2).sharedMaterial != (Object)null)
						{
							val = componentInChildren2;
							break;
						}
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				s_ropeMaterial = new Material(((Renderer)val).sharedMaterial);
				((Object)s_ropeMaterial).name = "anwo_zipline_rope";
				s_textureMode = val.textureMode;
				s_textureScale = val.textureScale;
				ZiplinesPlugin.Log.LogInfo((object)("Zipline rope uses the look of " + ((Object)((Component)val).gameObject).name));
			}
		}
		catch (Exception ex)
		{
			ZiplinesPlugin.Log.LogWarning((object)("Finding a rope to copy the look from failed: " + ex.Message));
		}
		if ((Object)(object)s_ropeMaterial == (Object)null)
		{
			Shader val2 = Shader.Find("Sprites/Default");
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = Shader.Find("Legacy Shaders/Diffuse");
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = Shader.Find("Standard");
			}
			s_ropeMaterial = new Material(val2);
			s_ropeMaterial.color = new Color(0.55f, 0.42f, 0.26f);
			s_textureMode = (LineTextureMode)0;
			ZiplinesPlugin.Log.LogWarning((object)"Using a plain rope colour (no rope found in the game to copy).");
		}
	}

	private static LineRenderer FromProjectile(Attack attack)
	{
		if (attack == null || (Object)(object)attack.m_attackProjectile == (Object)null)
		{
			return null;
		}
		GrapplingPoint componentInChildren = attack.m_attackProjectile.GetComponentInChildren<GrapplingPoint>(true);
		if ((Object)(object)componentInChildren == (Object)null)
		{
			return null;
		}
		LineRenderer component = ((Component)componentInChildren).GetComponent<LineRenderer>();
		if ((Object)(object)component == (Object)null || (Object)(object)((Renderer)component).sharedMaterial == (Object)null)
		{
			return null;
		}
		s_pullSound = componentInChildren.m_pullSound;
		return component;
	}

	internal static void SetupLine(LineRenderer line, float width)
	{
		//IL_0018: 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_0058: 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)
		FindRopeAssets();
		line.useWorldSpace = true;
		((Renderer)line).sharedMaterial = s_ropeMaterial;
		line.textureMode = s_textureMode;
		line.textureScale = s_textureScale;
		line.widthMultiplier = width;
		line.numCapVertices = 2;
		line.numCornerVertices = 2;
		line.alignment = (LineAlignment)0;
		((Renderer)line).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)line).receiveShadows = false;
		line.startColor = Color.white;
		line.endColor = Color.white;
	}

	internal static void RefreshLine(LineRenderer line)
	{
		//IL_0041: 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)
		if (!((Object)(object)line == (Object)null) && ((Object)(object)((Renderer)line).sharedMaterial != (Object)(object)s_ropeMaterial || !s_searched))
		{
			FindRopeAssets();
			if ((Object)(object)s_ropeMaterial != (Object)null)
			{
				((Renderer)line).sharedMaterial = s_ropeMaterial;
				line.textureMode = s_textureMode;
				line.textureScale = s_textureScale;
			}
		}
	}

	internal static Vector3 DecoratePost(GameObject post)
	{
		//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_0009: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		Bounds val = LocalBounds(post);
		float y = ((Bounds)(ref val)).max.y;
		float num = Mathf.Clamp(Mathf.Min(((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).extents.z), 0.08f, 0.35f);
		Material val2 = FirstMaterial(post);
		Material val3 = ItemMaterial("Iron", "IronScrap", "IronNails", "BronzeNails");
		Material val4 = ItemMaterial("LeatherScraps", "DeerHide", "TrollHide");
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = val2;
		}
		if ((Object)(object)val4 == (Object)null)
		{
			val4 = val2;
		}
		GameObject val5 = new GameObject("anwo_zipline_gear");
		val5.layer = post.layer;
		val5.transform.SetParent(post.transform, false);
		val5.transform.localPosition = new Vector3(((Bounds)(ref val)).center.x, y, ((Bounds)(ref val)).center.z);
		AddPart(val5, "cap", Box(new Vector3(0.38f, 0.05f, 0.38f)), val3, new Vector3(0f, 0.025f, 0f), Quaternion.identity);
		AddPart(val5, "cheek_left", Box(new Vector3(0.035f, 0.46f, 0.3f)), val3, new Vector3(-0.095f, 0.25f, 0f), Quaternion.identity);
		AddPart(val5, "cheek_right", Box(new Vector3(0.035f, 0.46f, 0.3f)), val3, new Vector3(0.095f, 0.25f, 0f), Quaternion.identity);
		Quaternion rotation = Quaternion.Euler(0f, 0f, 90f);
		AddPart(val5, "wheel", Torus(0.15f, 0.045f, 28, 10), val3, new Vector3(0f, 0.3f, 0f), rotation);
		AddPart(val5, "wheel_disc", Cylinder(0.12f, 0.03f, 20), val3, new Vector3(0f, 0.3f, 0f), rotation);
		AddPart(val5, "axle", Cylinder(0.035f, 0.26f, 12), val3, new Vector3(0f, 0.3f, 0f), rotation);
		float num2 = Mathf.Lerp(((Bounds)(ref val)).min.y, y, 0.6f) - y;
		for (int i = 0; i < 3; i++)
		{
			AddPart(val5, "coil_" + i, Torus(num + 0.045f, 0.042f, 24, 8), val4, new Vector3(0f, num2 + (float)(i - 1) * 0.09f, 0f), Quaternion.Euler(0f, (float)i * 40f, 0f));
		}
		return val5.transform.localPosition + new Vector3(0f, 0.495f, 0f);
	}

	private static Bounds LocalBounds(GameObject root)
	{
		//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_0010: 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_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_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		Matrix4x4 worldToLocalMatrix = root.transform.worldToLocalMatrix;
		bool flag = false;
		Bounds result = default(Bounds);
		MeshFilter[] componentsInChildren = root.GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val in componentsInChildren)
		{
			if ((Object)(object)val.sharedMesh == (Object)null)
			{
				continue;
			}
			Matrix4x4 val2 = worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
			Bounds bounds = val.sharedMesh.bounds;
			for (int j = 0; j < 8; j++)
			{
				Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3(((j & 1) == 0) ? (-1f) : 1f, ((j & 2) == 0) ? (-1f) : 1f, ((j & 4) == 0) ? (-1f) : 1f));
				Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
				if (!flag)
				{
					((Bounds)(ref result))..ctor(val4, Vector3.zero);
					flag = true;
				}
				else
				{
					((Bounds)(ref result)).Encapsulate(val4);
				}
			}
		}
		if (!flag)
		{
			((Bounds)(ref result))..ctor(new Vector3(0f, 2f, 0f), new Vector3(0.3f, 4f, 0.3f));
		}
		return result;
	}

	private static Material FirstMaterial(GameObject root)
	{
		MeshRenderer[] componentsInChildren = root.GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val in componentsInChildren)
		{
			if ((Object)(object)((Renderer)val).sharedMaterial != (Object)null)
			{
				return ((Renderer)val).sharedMaterial;
			}
		}
		return null;
	}

	internal static Material ItemMaterial(params string[] names)
	{
		foreach (string text in names)
		{
			GameObject val = null;
			try
			{
				val = PrefabManager.Instance.GetPrefab(text);
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val2 in componentsInChildren)
			{
				if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null)
				{
					return ((Renderer)val2).sharedMaterial;
				}
			}
		}
		return null;
	}

	private static void AddPart(GameObject parent, string name, Mesh mesh, Material material, Vector3 position, Quaternion rotation)
	{
		//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_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: 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)
		GameObject val = new GameObject(name)
		{
			layer = parent.layer
		};
		val.transform.SetParent(parent.transform, false);
		val.transform.localPosition = position;
		val.transform.localRotation = rotation;
		val.AddComponent<MeshFilter>().sharedMesh = mesh;
		MeshRenderer obj = val.AddComponent<MeshRenderer>();
		((Renderer)obj).sharedMaterial = material;
		((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
		((Renderer)obj).receiveShadows = true;
	}

	internal static GameObject MakeTrolley(out Transform strap, out Transform bar)
	{
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Expected O, but got Unknown
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Expected O, but got Unknown
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Expected O, but got Unknown
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)s_trolleyIron == (Object)null)
		{
			s_trolleyIron = ItemMaterial("Iron", "IronScrap", "IronNails", "BronzeNails");
		}
		if ((Object)(object)s_trolleyWood == (Object)null)
		{
			s_trolleyWood = ItemMaterial("Wood", "FineWood", "RoundLog");
		}
		Material material = s_trolleyIron;
		Material material2 = (((Object)(object)s_trolleyWood != (Object)null) ? s_trolleyWood : s_trolleyIron);
		if ((Object)(object)s_wheel == (Object)null)
		{
			s_wheel = Torus(0.055f, 0.02f, 20, 8);
			s_plate = Box(new Vector3(0.018f, 0.16f, 0.3f));
			s_hook = Box(new Vector3(0.11f, 0.03f, 0.05f));
			s_rod = Cylinder(0.014f, 1f, 8);
			s_grip = Cylinder(0.022f, 0.62f, 12);
			s_ring = Torus(0.03f, 0.01f, 12, 6);
		}
		GameObject val = new GameObject("anwo_zipline_trolley");
		Quaternion rotation = Quaternion.Euler(0f, 0f, 90f);
		AddPart(val, "wheel_front", s_wheel, material, new Vector3(0f, 0.065f, 0.09f), rotation);
		AddPart(val, "wheel_back", s_wheel, material, new Vector3(0f, 0.065f, -0.09f), rotation);
		AddPart(val, "plate_left", s_plate, material, new Vector3(-0.045f, 0.03f, 0f), Quaternion.identity);
		AddPart(val, "plate_right", s_plate, material, new Vector3(0.045f, 0.03f, 0f), Quaternion.identity);
		AddPart(val, "hook", s_hook, material, new Vector3(0f, -0.07f, 0f), Quaternion.identity);
		GameObject val2 = new GameObject("strap");
		val2.transform.SetParent(val.transform, false);
		AddPart(val2, "rod", s_rod, material, new Vector3(0f, -0.5f, 0f), Quaternion.identity);
		strap = val2.transform;
		GameObject val3 = new GameObject("bar");
		val3.transform.SetParent(val.transform, false);
		AddPart(val3, "grip", s_grip, material2, Vector3.zero, Quaternion.Euler(0f, 0f, 90f));
		AddPart(val3, "ring", s_ring, material, new Vector3(0f, 0.03f, 0f), Quaternion.Euler(90f, 0f, 0f));
		bar = val3.transform;
		return val;
	}

	private static Mesh Finish(string name, List<Vector3> v, List<Vector3> n, List<Vector2> uv, List<int> tris)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//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)
		Mesh val = new Mesh();
		((Object)val).name = name;
		val.SetVertices(v);
		val.SetNormals(n);
		val.SetUVs(0, uv);
		Color[] array = (Color[])(object)new Color[v.Count];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = Color.white;
		}
		val.colors = array;
		val.SetTriangles(tris, 0);
		val.RecalculateBounds();
		val.RecalculateTangents();
		return val;
	}

	internal static Mesh Torus(float major, float minor, int segments, int sides)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Vector2> list3 = new List<Vector2>();
		List<int> list4 = new List<int>();
		Vector3 val = default(Vector3);
		for (int i = 0; i <= segments; i++)
		{
			float num = (float)i / (float)segments * (float)Math.PI * 2f;
			((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
			for (int j = 0; j <= sides; j++)
			{
				float num2 = (float)j / (float)sides * (float)Math.PI * 2f;
				Vector3 val2 = val * Mathf.Cos(num2) + Vector3.up * Mathf.Sin(num2);
				list.Add(val * major + val2 * minor);
				list2.Add(val2);
				list3.Add(new Vector2((float)i / (float)segments * 4f, (float)j / (float)sides));
			}
		}
		int num3 = sides + 1;
		for (int k = 0; k < segments; k++)
		{
			for (int l = 0; l < sides; l++)
			{
				int item = k * num3 + l;
				int item2 = (k + 1) * num3 + l;
				int item3 = (k + 1) * num3 + l + 1;
				int item4 = k * num3 + l + 1;
				list4.Add(item);
				list4.Add(item4);
				list4.Add(item2);
				list4.Add(item2);
				list4.Add(item4);
				list4.Add(item3);
			}
		}
		return Finish("anwo_torus", list, list2, list3, list4);
	}

	internal static Mesh Cylinder(float radius, float height, int segments)
	{
		//IL_0058: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missi