Decompiled source of Coastal Carrack v0.5.4

BigWalkShipMod.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BigWalkShipMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BigWalkShipMod")]
[assembly: AssemblyTitle("BigWalkShipMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BigWalkShipMod
{
	internal sealed class CoastalRoute
	{
		private readonly Vector3[] _points;

		private readonly float[] _cumulativeDistance;

		internal float Length { get; }

		internal int PointCount => _points.Length;

		internal float MinimumRadius { get; }

		internal float MaximumRadius { get; }

		private CoastalRoute(Vector3[] points, bool smooth = true)
		{
			//IL_0051: 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)
			Vector3[] array = SanitizeLoop(points);
			_points = (smooth ? Smooth(array, 2) : array);
			_cumulativeDistance = new float[_points.Length + 1];
			for (int i = 0; i < _points.Length; i++)
			{
				_cumulativeDistance[i + 1] = _cumulativeDistance[i] + Vector3.Distance(_points[i], _points[(i + 1) % _points.Length]);
			}
			Length = _cumulativeDistance[^1];
			MinimumRadius = _points.Min(delegate(Vector3 point)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				Vector2 val = new Vector2(point.x, point.z);
				return ((Vector2)(ref val)).magnitude;
			});
			MaximumRadius = _points.Max(delegate(Vector3 point)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				Vector2 val = new Vector2(point.x, point.z);
				return ((Vector2)(ref val)).magnitude;
			});
		}

		internal CoastalRoute WithTerrainClearance(float seaLevel, out int adjustedPoints, out float maximumAdjustment)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_015e: 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)
			Terrain[] terrains = ((IEnumerable<Terrain>)Resources.FindObjectsOfTypeAll<Terrain>()).Where((Terrain terrain) => (Object)(object)terrain != (Object)null && (Object)(object)((Component)terrain).gameObject != (Object)null && ((Object)((Component)terrain).gameObject).name.StartsWith("Terrain_", StringComparison.Ordinal)).ToArray();
			Vector3[] array = ((IEnumerable<Vector3>)_points).Select((Func<Vector3, Vector3>)((Vector3 point) => new Vector3(point.x * 0.82f, point.y, point.z * 0.82f))).ToArray();
			Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
			adjustedPoints = 0;
			maximumAdjustment = 0f;
			Vector3 outward = default(Vector3);
			for (int num = 0; num < array.Length; num++)
			{
				Vector3 val = array[num];
				Vector3 val2 = array[(num - 1 + array.Length) % array.Length];
				Vector3 forward = array[(num + 1) % array.Length] - val2;
				forward.y = 0f;
				forward = ((((Vector3)(ref forward)).sqrMagnitude > 0.001f) ? ((Vector3)(ref forward)).normalized : Vector3.forward);
				((Vector3)(ref outward))..ctor(val.x, 0f, val.z);
				outward = ((((Vector3)(ref outward)).sqrMagnitude > 0.001f) ? ((Vector3)(ref outward)).normalized : Vector3.left);
				float shorelineBuffer = (IsBoardingApproach(num, array.Length) ? 1f : 12f);
				Vector3 val3 = FindNearestSafeCoastalPoint(val, forward, outward, terrains, seaLevel, shorelineBuffer);
				float num2 = Vector3.Distance(val, val3);
				if (num2 > 0.1f)
				{
					adjustedPoints++;
					maximumAdjustment = Mathf.Max(maximumAdjustment, num2);
				}
				array2[num] = val3;
			}
			array2 = SmoothSafely(array2, terrains, seaLevel, 7);
			return new CoastalRoute(array2, smooth: false);
		}

		private static Vector3 FindNearestSafeCoastalPoint(Vector3 seed, Vector3 forward, Vector3 outward, Terrain[] terrains, float seaLevel, float shorelineBuffer)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_005a: 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_008e: 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_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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = seed;
			while (!HasHullClearance(val, forward, terrains, seaLevel) && Vector3.Distance(seed, val) < 650f)
			{
				val += outward * 5f;
			}
			if (!HasHullClearance(val, forward, terrains, seaLevel))
			{
				return val;
			}
			for (int i = 0; i < 320; i++)
			{
				Vector3 val2 = val - outward * 5f;
				Vector2 val3 = new Vector2(val2.x, val2.z);
				if (((Vector2)(ref val3)).magnitude < 150f || !HasHullClearance(val2, forward, terrains, seaLevel))
				{
					break;
				}
				val = val2;
			}
			return val + outward * shorelineBuffer;
		}

		private static bool IsBoardingApproach(int index, int pointCount)
		{
			int num = Mathf.Max(1, pointCount / 12);
			int num2 = Mathf.Max(4, num / 5);
			for (int i = 0; i < 12; i++)
			{
				int num3 = i * num;
				int num4 = Math.Abs(index - num3);
				num4 = Math.Min(num4, pointCount - num4);
				if (num4 <= num2)
				{
					return true;
				}
			}
			return false;
		}

		internal static bool TryLoadCache(string path, out CoastalRoute route)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			route = null;
			if (!File.Exists(path))
			{
				return false;
			}
			try
			{
				using JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(path));
				if (jsonDocument.RootElement.GetProperty("version").GetInt32() != 7)
				{
					return false;
				}
				JsonElement property = jsonDocument.RootElement.GetProperty("points");
				Vector3[] array = (Vector3[])(object)new Vector3[property.GetArrayLength()];
				int num = 0;
				foreach (JsonElement item in property.EnumerateArray())
				{
					array[num++] = new Vector3(item.GetProperty("x").GetSingle(), 0f, item.GetProperty("z").GetSingle());
				}
				if (array.Length < 4)
				{
					return false;
				}
				route = new CoastalRoute(array, smooth: false);
				return true;
			}
			catch
			{
				return false;
			}
		}

		internal void SaveCache(string path)
		{
			Directory.CreateDirectory(Path.GetDirectoryName(path));
			var value = new
			{
				version = 7,
				points = _points.Select((Vector3 point) => new { point.x, point.z }).ToArray()
			};
			File.WriteAllText(path, JsonSerializer.Serialize(value));
		}

		private static Vector3[] SmoothSafely(Vector3[] source, Terrain[] terrains, float seaLevel, int passes)
		{
			//IL_0025: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a3: 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_00b3: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = source;
			Vector3 val4 = default(Vector3);
			for (int i = 0; i < passes; i++)
			{
				Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length];
				for (int j = 0; j < array.Length; j++)
				{
					Vector3 val = array[(j - 1 + array.Length) % array.Length];
					Vector3 val2 = array[(j + 1) % array.Length];
					Vector3 val3 = val * 0.2f + array[j] * 0.6f + val2 * 0.2f;
					Vector3 forward = val2 - val;
					forward.y = 0f;
					forward = ((((Vector3)(ref forward)).sqrMagnitude > 0.001f) ? ((Vector3)(ref forward)).normalized : Vector3.forward);
					((Vector3)(ref val4))..ctor(val3.x, 0f, val3.z);
					val4 = ((((Vector3)(ref val4)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val4)).normalized : Vector3.left);
					int num = 0;
					while (!HasHullClearance(val3, forward, terrains, seaLevel) && num++ < 360)
					{
						val3 += val4 * 2.5f;
					}
					array2[j] = val3;
				}
				array = array2;
			}
			return array;
		}

		private static bool HasHullClearance(Vector3 center, Vector3 forward, Terrain[] terrains, float seaLevel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Cross(Vector3.up, forward);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float[] array = new float[5] { -31f, -16f, 0f, 16f, 31f };
			float[] array2 = new float[3] { -10.5f, 0f, 10.5f };
			float[] array3 = array;
			foreach (float num in array3)
			{
				float[] array4 = array2;
				foreach (float num2 in array4)
				{
					if (TrySampleGround(center + forward * num + normalized * num2, terrains, out var groundHeight) && groundHeight > seaLevel - 6.5f)
					{
						return false;
					}
				}
			}
			return true;
		}

		private static bool TrySampleGround(Vector3 point, Terrain[] terrains, out float groundHeight)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_005e: 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_006d: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			foreach (Terrain val in terrains)
			{
				TerrainData terrainData = val.terrainData;
				if (!((Object)(object)terrainData == (Object)null))
				{
					Vector3 position = ((Component)val).transform.position;
					Vector3 size = terrainData.size;
					if (!(point.x < position.x) && !(point.x > position.x + size.x) && !(point.z < position.z) && !(point.z > position.z + size.z))
					{
						groundHeight = val.SampleHeight(point) + position.y;
						return true;
					}
				}
			}
			groundHeight = float.NegativeInfinity;
			return false;
		}

		internal static CoastalRoute LoadEmbedded()
		{
			//IL_00c3: 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)
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single((string text) => text.EndsWith("coastal-route-v1.json", StringComparison.OrdinalIgnoreCase));
			using Stream utf8Json = executingAssembly.GetManifestResourceStream(name);
			using JsonDocument jsonDocument = JsonDocument.Parse(utf8Json);
			JsonElement property = jsonDocument.RootElement.GetProperty("waypoints");
			Vector3[] array = (Vector3[])(object)new Vector3[property.GetArrayLength()];
			int num = 0;
			foreach (JsonElement item in property.EnumerateArray())
			{
				array[num++] = new Vector3(item.GetProperty("x").GetSingle(), 0f, item.GetProperty("z").GetSingle());
			}
			if (array.Length < 4)
			{
				throw new InvalidDataException("The embedded coastal route does not contain enough waypoints.");
			}
			return new CoastalRoute(array);
		}

		internal Vector3 Evaluate(float distance)
		{
			//IL_004d: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			distance = Mathf.Repeat(distance, Length);
			int num = FindSegment(distance);
			float num2 = _cumulativeDistance[num + 1] - _cumulativeDistance[num];
			float num3 = ((num2 > 0.001f) ? ((distance - _cumulativeDistance[num]) / num2) : 0f);
			return Vector3.Lerp(_points[num], _points[(num + 1) % _points.Length], num3);
		}

		internal Vector3 Tangent(float distance, float lookAhead = 7f)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Evaluate(distance - lookAhead);
			Vector3 val2 = Evaluate(distance + lookAhead) - val;
			val2.y = 0f;
			if (!(((Vector3)(ref val2)).sqrMagnitude > 0.001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val2)).normalized;
		}

		private int FindSegment(float distance)
		{
			int num = 0;
			int num2 = _points.Length - 1;
			while (num <= num2)
			{
				int num3 = (num + num2) / 2;
				if (distance < _cumulativeDistance[num3])
				{
					num2 = num3 - 1;
					continue;
				}
				if (distance >= _cumulativeDistance[num3 + 1])
				{
					num = num3 + 1;
					continue;
				}
				return num3;
			}
			return _points.Length - 1;
		}

		private static Vector3[] Smooth(Vector3[] source, int passes)
		{
			//IL_0017: 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_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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = source;
			for (int i = 0; i < passes; i++)
			{
				Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length * 2];
				for (int j = 0; j < array.Length; j++)
				{
					Vector3 val = array[j];
					Vector3 val2 = array[(j + 1) % array.Length];
					array2[j * 2] = Vector3.Lerp(val, val2, 0.25f);
					array2[j * 2 + 1] = Vector3.Lerp(val, val2, 0.75f);
				}
				array = array2;
			}
			return array;
		}

		private static Vector3[] SanitizeLoop(Vector3[] source)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002e: 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_003d: 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_0079: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0144: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			if (source.Length < 8)
			{
				return source;
			}
			float num = 0f;
			for (int i = 0; i < source.Length; i++)
			{
				Vector3 val = source[i];
				Vector3 val2 = source[(i + 1) % source.Length];
				num += val.x * val2.z - val2.x * val.z;
			}
			float num2 = ((num >= 0f) ? 1f : (-1f));
			List<Vector3> list = new List<Vector3> { source[0] };
			float num3 = Mathf.Atan2(source[0].z, source[0].x) * 57.29578f;
			for (int j = 1; j < source.Length; j++)
			{
				Vector3 val3 = source[j];
				float num4 = Mathf.Atan2(val3.z, val3.x) * 57.29578f;
				if (!(num2 * Mathf.DeltaAngle(num3, num4) < -0.12f))
				{
					if (!(Vector3.Distance(list[list.Count - 1], val3) < 1f))
					{
						list.Add(val3);
						num3 = num4;
					}
				}
			}
			for (int k = 0; k < 8; k++)
			{
				if (list.Count <= 8)
				{
					break;
				}
				bool flag = false;
				for (int num5 = list.Count - 1; num5 >= 0; num5--)
				{
					Vector3 val4 = list[(num5 - 1 + list.Count) % list.Count];
					Vector3 val5 = list[num5];
					Vector3 val6 = list[(num5 + 1) % list.Count];
					Vector3 val7 = val5 - val4;
					Vector3 val8 = val6 - val5;
					if (((Vector3)(ref val7)).magnitude < 2f || ((Vector3)(ref val8)).magnitude < 2f || Vector3.Dot(((Vector3)(ref val7)).normalized, ((Vector3)(ref val8)).normalized) < -0.35f)
					{
						list.RemoveAt(num5);
						flag = true;
					}
				}
				if (!flag)
				{
					break;
				}
			}
			return list.ToArray();
		}
	}
	public sealed class CoastalShipController : MonoBehaviour
	{
		private const int ShipCount = 3;

		private CoastalRoute _route;

		private readonly BuiltShip[] _ships = new BuiltShip[3];

		private float _nextSpawnCheck;

		private float _lastDistance;

		private bool _loggedWaiting;

		private bool _routeTerrainValidated;

		private float _throttle = 0.5f;

		private float _actualSpeed;

		private readonly Quaternion[] _smoothedRotations = (Quaternion[])(object)new Quaternion[3];

		private PlayerCharacter _localPlayer;

		private float _nextPlayerSearch;

		private bool _isAimingAtLever;

		public CoastalShipController(IntPtr pointer)
			: base(pointer)
		{
		}

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				_route = CoastalRoute.LoadEmbedded();
				ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded coastal route: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_route.PointCount);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" smoothed points, ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.Length, "F0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" metres, ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("radius=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MinimumRadius, "F0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MaximumRadius, "F0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m.");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = ((BasePlugin)Plugin.Instance).Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not load the coastal ship route: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val2);
			}
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			if (Input.GetKeyDown(Plugin.DiagnosticKey.Value))
			{
				LogStatus();
			}
			HandleHelmControls();
			if (!Plugin.Enabled.Value)
			{
				DestroyShips();
			}
			else
			{
				if (AnyShipSpawned() || _route == null || Time.unscaledTime < _nextSpawnCheck)
				{
					return;
				}
				_nextSpawnCheck = Time.unscaledTime + 1f;
				PlayerCharacter localPlayer = GetLocalPlayer();
				if ((Object)(object)localPlayer == (Object)null || !IslandTerrainLoaded())
				{
					if (!_loggedWaiting)
					{
						_loggedWaiting = true;
						((BasePlugin)Plugin.Instance).Log.LogInfo((object)"Coastal carrack is waiting for the island and local player.");
					}
					return;
				}
				if (!_routeTerrainValidated)
				{
					string path = Path.Combine(Paths.ConfigPath, "CoastalCarrack.safe-route-v7.json");
					bool flag = default(bool);
					if (CoastalRoute.TryLoadCache(path, out var route))
					{
						_route = route;
						ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(56, 4, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded cached terrain-safe route: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_route.PointCount);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" points, ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.Length, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m, ");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("radius=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MinimumRadius, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MaximumRadius, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m.");
						}
						log.LogInfo(val);
					}
					else
					{
						_route = _route.WithTerrainClearance(Plugin.SeaLevel.Value, out var adjustedPoints, out var maximumAdjustment);
						ManualLogSource log2 = ((BasePlugin)Plugin.Instance).Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(99, 6, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Validated route against live terrain: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(adjustedPoints);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_route.PointCount);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" points moved, ");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("maximum correction=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(maximumAdjustment, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m, safe loop=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.Length, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m, ");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("radius=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MinimumRadius, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.MaximumRadius, "F0");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m.");
						}
						log2.LogInfo(val);
						try
						{
							_route.SaveCache(path);
						}
						catch (Exception ex)
						{
							ManualLogSource log3 = ((BasePlugin)Plugin.Instance).Log;
							BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not cache the terrain-safe route: ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
							}
							log3.LogWarning(val2);
						}
					}
					_routeTerrainValidated = true;
				}
				SpawnShips(localPlayer);
			}
		}

		private void FixedUpdate()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if (!AnyShipSpawned() || _route == null)
			{
				return;
			}
			float num = Mathf.Max(0f, Plugin.ShipSpeed.Value) * _throttle;
			float num2 = ((num > _actualSpeed) ? 0.65f : 1.2f);
			_actualSpeed = Mathf.MoveTowards(_actualSpeed, num, num2 * Time.fixedDeltaTime);
			_lastDistance = Mathf.Repeat(_lastDistance + _actualSpeed * Time.fixedDeltaTime, _route.Length);
			for (int i = 0; i < 3; i++)
			{
				BuiltShip builtShip = _ships[i];
				if (!((Object)(object)builtShip?.Root == (Object)null))
				{
					float distance = Mathf.Repeat(_lastDistance + _route.Length * (float)i / 3f, _route.Length);
					Vector3 val = _route.Evaluate(distance);
					val.y = Plugin.SeaLevel.Value;
					Quaternion val2 = Quaternion.LookRotation(_route.Tangent(distance, 32f), Vector3.up);
					_smoothedRotations[i] = Quaternion.RotateTowards(_smoothedRotations[i], val2, 7f * Time.fixedDeltaTime);
					builtShip.Body.MovePosition(val);
					builtShip.Body.MoveRotation(_smoothedRotations[i]);
				}
			}
		}

		private void OnDestroy()
		{
			DestroyShips();
		}

		private void SpawnShips(PlayerCharacter localPlayer)
		{
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_0170: 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)
			float num = (_actualSpeed = Mathf.Max(0.5f, Plugin.ShipSpeed.Value) * _throttle);
			_lastDistance = Mathf.Repeat((float)(GetSynchronizedTime() * (double)num), _route.Length);
			string source;
			int num2 = FindVanillaPlatformLayer(localPlayer, out source);
			bool flag = default(bool);
			try
			{
				for (int i = 0; i < 3; i++)
				{
					float distance = Mathf.Repeat(_lastDistance + _route.Length * (float)i / 3f, _route.Length);
					Vector3 position = _route.Evaluate(distance);
					position.y = Plugin.SeaLevel.Value;
					Quaternion val = Quaternion.LookRotation(_route.Tangent(distance, 32f), Vector3.up);
					BuiltShip builtShip = ShipBuilder.Build(position, val, num2);
					((Object)builtShip.Root).name = $"BigWalkCoastalCarrack_{i + 1}";
					_ships[i] = builtShip;
					_smoothedRotations[i] = val;
					if (i == 0)
					{
						LogLeverValidation(builtShip);
					}
				}
				_loggedWaiting = false;
				float num3 = float.PositiveInfinity;
				BuiltShip[] ships = _ships;
				foreach (BuiltShip builtShip2 in ships)
				{
					if ((Object)(object)builtShip2?.Root != (Object)null)
					{
						num3 = Mathf.Min(num3, Vector3.Distance(((Component)localPlayer).transform.position, builtShip2.Root.transform.position));
					}
				}
				ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(110, 8, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawned ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(3);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" coastal carracks at equal ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(_route.Length / 3f, "F0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m route intervals; ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("route=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(_lastDistance, "F0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(_route.Length, "F0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("speed=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num, "F1");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m/s, layer=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(source);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("), ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("nearestPlayerDistance=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num3, "F0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m.");
				}
				log.LogInfo(val2);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = ((BasePlugin)Plugin.Instance).Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to build the coastal carrack fleet: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val3);
				DestroyShips();
				_nextSpawnCheck = Time.unscaledTime + 5f;
			}
		}

		private void HandleHelmControls()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_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_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			PlayerCharacter localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			_isAimingAtLever = false;
			BuiltShip builtShip = null;
			float num = float.PositiveInfinity;
			BuiltShip[] ships = _ships;
			foreach (BuiltShip builtShip2 in ships)
			{
				if (!((Object)(object)builtShip2?.ThrottleLever == (Object)null))
				{
					float num2 = Vector3.Distance(((Component)localPlayer).transform.position, builtShip2.ThrottleLever.position);
					if (num2 < num)
					{
						num = num2;
						builtShip = builtShip2;
					}
				}
			}
			if (builtShip == null || num > 12f)
			{
				return;
			}
			float num3 = _throttle;
			object obj;
			if (!((Object)(object)localPlayer.cameraTransform != (Object)null))
			{
				Camera main = Camera.main;
				obj = ((main != null) ? ((Component)main).transform : null);
			}
			else
			{
				obj = localPlayer.cameraTransform;
			}
			Transform val = (Transform)obj;
			if ((Object)(object)val != (Object)null)
			{
				RaycastHit[] array = Il2CppArrayBase<RaycastHit>.op_Implicit((Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(val.position, val.forward, 12f, -1, (QueryTriggerInteraction)2));
				for (int i = 0; i < array.Length; i++)
				{
					RaycastHit val2 = array[i];
					if ((Object)(object)((RaycastHit)(ref val2)).transform != (Object)null && (((Object)((Component)((RaycastHit)(ref val2)).transform).gameObject).name == "Carriage_front_dashboard_brakelever" || ((Object)((Component)((RaycastHit)(ref val2)).transform).gameObject).name == "TrainStyleThrottleLever"))
					{
						_isAimingAtLever = true;
						break;
					}
				}
				Vector3 val3 = builtShip.ThrottleLever.TransformPoint(new Vector3(0f, 0.2f, 0.45f)) - val.position;
				if (((Vector3)(ref val3)).sqrMagnitude <= 144f && ((Vector3)(ref val3)).sqrMagnitude > 0.001f && Vector3.Dot(val.forward, ((Vector3)(ref val3)).normalized) >= 0.97f)
				{
					_isAimingAtLever = true;
				}
			}
			if (_isAimingAtLever)
			{
				float axis = Input.GetAxis("Mouse ScrollWheel");
				if (axis > 0.01f)
				{
					num3 = Mathf.Min(1f, _throttle + 0.1f);
				}
				else if (axis < -0.01f)
				{
					num3 = Mathf.Max(0f, _throttle - 0.1f);
				}
				if (Input.GetMouseButtonDown(0) || Input.GetKeyDown((KeyCode)101))
				{
					num3 = Mathf.Min(1f, _throttle + 0.25f);
				}
				if (Input.GetMouseButtonDown(1))
				{
					num3 = Mathf.Max(0f, _throttle - 0.25f);
				}
			}
			if (Mathf.Approximately(num3, _throttle))
			{
				return;
			}
			_throttle = num3;
			ships = _ships;
			foreach (BuiltShip builtShip3 in ships)
			{
				if ((Object)(object)builtShip3?.ThrottleLever != (Object)null)
				{
					builtShip3.ThrottleLever.localRotation = Quaternion.Euler(Mathf.Lerp(-35f, 5f, _throttle), 0f, 0f);
				}
			}
			ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Train lever changed ship throttle to ");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<float>(_throttle * 100f, "F0");
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("% ");
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("(target speed ");
				((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<float>(Plugin.ShipSpeed.Value * _throttle, "F1");
				((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("m/s).");
			}
			log.LogInfo(val4);
		}

		private void OnGUI()
		{
			//IL_0017: 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)
			PlayerCharacter localPlayer = GetLocalPlayer();
			if (!((Object)(object)localPlayer == (Object)null) && IsNearAnyControl(((Component)localPlayer).transform.position, 12f))
			{
				string value = (_isAimingAtLever ? "TARGETED" : "AIM AT BLUE HANDLE");
				string text = $"TRAIN LEVER [{value}]  |  Scroll adjust | Click/E +25% | Right Click -25%  |  {_throttle * 100f:F0}%  |  Speed {_actualSpeed:F1} m/s";
				GUI.Box(new Rect((float)Screen.width * 0.5f - 350f, (float)Screen.height - 92f, 700f, 42f), text);
			}
		}

		private bool IsNearAnyControl(Vector3 position, float range)
		{
			//IL_0023: 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)
			BuiltShip[] ships = _ships;
			foreach (BuiltShip builtShip in ships)
			{
				if ((Object)(object)builtShip?.ThrottleLever != (Object)null && Vector3.Distance(position, builtShip.ThrottleLever.position) <= range)
				{
					return true;
				}
			}
			return false;
		}

		private static void LogLeverValidation(BuiltShip ship)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(((Component)ship.ThrottleLever).GetComponentsInChildren<Collider>(true));
			Renderer[] array2 = Il2CppArrayBase<Renderer>.op_Implicit(((Component)ship.ThrottleLever).GetComponentsInChildren<Renderer>(true));
			Collider component = ((Component)ship.ThrottleLever).gameObject.GetComponent<Collider>();
			ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(110, 7, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Lever validation: root='");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)((Component)ship.ThrottleLever).gameObject).name);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("layer=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((Component)ship.ThrottleLever).gameObject.layer);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", renderers=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(array2.Length);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("colliders=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(array.Length);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", rootTrigger=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)component != (Object)null && component.isTrigger);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("rootColliderEnabled=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)component != (Object)null && component.enabled);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("worldPosition=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(ship.ThrottleLever.position);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
		}

		private void DestroyShips()
		{
			for (int i = 0; i < _ships.Length; i++)
			{
				if ((Object)(object)_ships[i]?.Root != (Object)null)
				{
					Object.Destroy((Object)(object)_ships[i].Root);
				}
				_ships[i] = null;
			}
		}

		private bool AnyShipSpawned()
		{
			BuiltShip[] ships = _ships;
			for (int i = 0; i < ships.Length; i++)
			{
				if ((Object)(object)ships[i]?.Root != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private void LogStatus()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			PlayerCharacter localPlayer = GetLocalPlayer();
			bool flag = default(bool);
			if (!AnyShipSpawned())
			{
				ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(94, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Coastal carrack diagnostic: not spawned; routeLoaded=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_route != null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("playerFound=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)localPlayer != (Object)null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", terrainLoaded=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(IslandTerrainLoaded());
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", enabled=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(Plugin.Enabled.Value);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				log.LogInfo(val);
				return;
			}
			for (int i = 0; i < _ships.Length; i++)
			{
				BuiltShip builtShip = _ships[i];
				if (!((Object)(object)builtShip?.Root == (Object)null))
				{
					float num = (((Object)(object)localPlayer != (Object)null) ? Vector3.Distance(((Component)localPlayer).transform.position, builtShip.Root.transform.position) : (-1f));
					Renderer[] array = Il2CppArrayBase<Renderer>.op_Implicit(builtShip.Root.GetComponentsInChildren<Renderer>(true));
					Collider[] array2 = Il2CppArrayBase<Collider>.op_Implicit(builtShip.Root.GetComponentsInChildren<Collider>(true));
					float num2 = Mathf.Repeat(_lastDistance + _route.Length * (float)i / 3f, _route.Length);
					ManualLogSource log2 = ((BasePlugin)Plugin.Instance).Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(113, 11, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Carrack ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(i + 1);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(3);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": position=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(builtShip.Root.transform.position);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("route=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "F0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(_route.Length, "F0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m, playerDistance=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m, ");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("renderers=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(array.Length);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", colliders=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(array2.Length);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", layer=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(builtShip.Root.layer);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("platformBody=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)builtShip.PlatformingBody != (Object)null);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", stickyPlatform=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)builtShip.StickyPlatform != (Object)null);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					}
					log2.LogInfo(val);
				}
			}
		}

		private static double GetSynchronizedTime()
		{
			if (!NetworkClient.active && !NetworkServer.active)
			{
				return Time.timeAsDouble;
			}
			return NetworkTime.time;
		}

		private static int FindVanillaPlatformLayer(PlayerCharacter localPlayer, out string source)
		{
			//IL_0017: 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)
			int num;
			if (((localPlayer != null) ? localPlayer.ground : null) == null)
			{
				num = -1;
			}
			else
			{
				LayerMask layerMask = localPlayer.ground.layerMask;
				num = ((LayerMask)(ref layerMask)).value;
			}
			int num2 = num;
			object obj;
			if (localPlayer == null)
			{
				obj = null;
			}
			else
			{
				PlayerGround ground = localPlayer.ground;
				obj = ((ground != null) ? ground.groundCollider : null);
			}
			if ((Object)obj != (Object)null)
			{
				source = "current ground '" + ((Object)((Component)localPlayer.ground.groundCollider).gameObject).name + "'";
				return ((Component)localPlayer.ground.groundCollider).gameObject.layer;
			}
			TrainCar[] array = Il2CppArrayBase<TrainCar>.op_Implicit(Resources.FindObjectsOfTypeAll<TrainCar>());
			foreach (TrainCar val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && IsInLayerMask(((Component)val).gameObject.layer, num2))
				{
					source = "train '" + ((Object)((Component)val).gameObject).name + "'";
					return ((Component)val).gameObject.layer;
				}
			}
			Terrain[] array2 = Il2CppArrayBase<Terrain>.op_Implicit(Resources.FindObjectsOfTypeAll<Terrain>());
			foreach (Terrain val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Object)((Component)val2).gameObject).name.StartsWith("Terrain_", StringComparison.Ordinal) && IsInLayerMask(((Component)val2).gameObject.layer, num2))
				{
					source = "terrain '" + ((Object)((Component)val2).gameObject).name + "'";
					return ((Component)val2).gameObject.layer;
				}
			}
			if (num2 != 0)
			{
				for (int j = 0; j < 32; j++)
				{
					if ((num2 & (1 << j)) != 0)
					{
						source = "first player ground-mask layer";
						return j;
					}
				}
			}
			source = "default fallback";
			return 0;
		}

		private static bool IsInLayerMask(int layer, int mask)
		{
			if (mask != -1)
			{
				return (mask & (1 << layer)) != 0;
			}
			return true;
		}

		private static bool IslandTerrainLoaded()
		{
			Terrain[] array = Il2CppArrayBase<Terrain>.op_Implicit(Resources.FindObjectsOfTypeAll<Terrain>());
			int num = 0;
			Terrain[] array2 = array;
			foreach (Terrain val in array2)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null && ((Object)((Component)val).gameObject).name.StartsWith("Terrain_", StringComparison.Ordinal))
				{
					num++;
				}
			}
			return num >= 4;
		}

		private PlayerCharacter GetLocalPlayer()
		{
			if ((Object)(object)_localPlayer != (Object)null && ((Behaviour)_localPlayer).isActiveAndEnabled && ((NetworkBehaviour)_localPlayer).isLocalPlayer)
			{
				return _localPlayer;
			}
			if (Time.unscaledTime < _nextPlayerSearch)
			{
				return null;
			}
			_nextPlayerSearch = Time.unscaledTime + 1f;
			PlayerCharacter[] array = Il2CppArrayBase<PlayerCharacter>.op_Implicit(Resources.FindObjectsOfTypeAll<PlayerCharacter>());
			foreach (PlayerCharacter val in array)
			{
				if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled && ((NetworkBehaviour)val).isLocalPlayer)
				{
					_localPlayer = val;
					return _localPlayer;
				}
			}
			_localPlayer = null;
			return null;
		}
	}
	[BepInPlugin("charl.bigwalk.coastalcarrack", "Big Walk Coastal Carrack", "0.5.4")]
	public sealed class Plugin : BasePlugin
	{
		public const string PluginGuid = "charl.bigwalk.coastalcarrack";

		public const string PluginName = "Big Walk Coastal Carrack";

		public const string PluginVersion = "0.5.4";

		internal static Plugin Instance { get; private set; }

		internal static ConfigEntry<bool> Enabled { get; private set; }

		internal static ConfigEntry<float> ShipSpeed { get; private set; }

		internal static ConfigEntry<float> SeaLevel { get; private set; }

		internal static ConfigEntry<KeyCode> DiagnosticKey { get; private set; }

		public override void Load()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			Instance = this;
			Enabled = ((BasePlugin)this).Config.Bind<bool>("Ship", "Enabled", true, "Creates the coastal carrack when the island scene is loaded.");
			ShipSpeed = ((BasePlugin)this).Config.Bind<float>("Ship", "Maximum helm speed metres per second", 4f, "Speed at the top of the physical helm throttle. Ships start at 50 percent (2 m/s).");
			SeaLevel = ((BasePlugin)this).Config.Bind<float>("Ship", "Sea level", 0f, "World Y position used as the ship waterline.");
			DiagnosticKey = ((BasePlugin)this).Config.Bind<KeyCode>("Diagnostics", "Status key", (KeyCode)291, "Logs ship position, route state and player distance.");
			((BasePlugin)this).AddComponent<CoastalShipController>();
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(62, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Big Walk Coastal Carrack");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.5.4");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. All players need the mod to see and board the ship.");
			}
			log.LogInfo(val);
		}
	}
	internal sealed class BuiltShip
	{
		internal GameObject Root { get; init; }

		internal Rigidbody Body { get; init; }

		internal PlatformingBody PlatformingBody { get; init; }

		internal StickyPlatform StickyPlatform { get; init; }

		internal Transform Helm { get; init; }

		internal Transform Wheel { get; init; }

		internal Transform ThrottleLever { get; init; }

		internal Renderer[] Renderers { get; init; }

		internal Collider[] ActiveColliders { get; init; }

		internal bool RenderersEnabled { get; set; } = true;

		internal bool CollidersEnabled { get; set; } = true;
	}
	internal static class ShipBuilder
	{
		private sealed class CombinedGeometry
		{
			internal readonly List<Vector3> Vertices = new List<Vector3>();

			internal readonly List<Color> Colors = new List<Color>();

			internal readonly List<int> Triangles = new List<int>();
		}

		private static Material _wood;

		private static Material _darkWood;

		private static Material _ochre;

		private static Material _teal;

		private static Material _sail;

		private static Material _rope;

		private static Material _lantern;

		private static Mesh _trainBrakeLeverMesh;

		private static Material _trainBrakeLeverMaterial;

		private static bool _loggedTrainLeverAsset;

		private static readonly Dictionary<long, Mesh> ColoredMeshCache = new Dictionary<long, Mesh>();

		internal static BuiltShip Build(Vector3 position, Quaternion rotation, int layer)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			EnsureMaterials();
			GameObject val = new GameObject("BigWalkCoastalCarrack");
			val.SetActive(false);
			val.transform.SetPositionAndRotation(position, rotation);
			val.layer = layer;
			Rigidbody val2 = val.AddComponent<Rigidbody>();
			val2.isKinematic = true;
			val2.useGravity = false;
			val2.interpolation = (RigidbodyInterpolation)1;
			val2.collisionDetectionMode = (CollisionDetectionMode)0;
			PlatformingBody val3 = val.AddComponent<PlatformingBody>();
			StickyPlatform val4 = val.AddComponent<StickyPlatform>();
			val4.platformingBody = val3;
			val3.hasPlatform = val4;
			Transform transform = new GameObject("CarrackVisuals").transform;
			transform.SetParent(val.transform, false);
			BuildHull(transform);
			BuildDecks(transform);
			BuildCastlesAndStairs(transform);
			BuildRails(transform);
			BuildMast(transform, -8.5f, 15.5f, 10.5f);
			BuildMast(transform, 10f, 14f, 9f);
			Transform val5 = BuildWheel(transform);
			Transform val6 = BuildThrottleControl(transform);
			BuildGangplanks(transform);
			BuildLanterns(transform);
			BuildColliders(val.transform);
			CombineStaticGeometry(transform, val5, val6);
			SetLayerRecursively(val, layer);
			val.SetActive(true);
			Renderer[] renderers = ((IEnumerable<Renderer>)val.GetComponentsInChildren<Renderer>(true)).Where((Renderer renderer) => (Object)(object)renderer != (Object)null && renderer.enabled).ToArray();
			Collider[] activeColliders = ((IEnumerable<Collider>)val.GetComponentsInChildren<Collider>(true)).Where((Collider collider) => (Object)(object)collider != (Object)null && collider.enabled).ToArray();
			return new BuiltShip
			{
				Root = val,
				Body = val2,
				PlatformingBody = val3,
				StickyPlatform = val4,
				Helm = val5,
				Wheel = val5,
				ThrottleLever = val6,
				Renderers = renderers,
				ActiveColliders = activeColliders
			};
		}

		private static void BuildHull(Transform parent)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b4: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: 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_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Expected O, but got Unknown
			float[] array = new float[9] { -27f, -23f, -17f, -9f, 0f, 9f, 17f, 23f, 27f };
			float[] array2 = new float[9] { 1.2f, 4.7f, 7.2f, 8.5f, 9f, 8.5f, 7.1f, 4.2f, 0.8f };
			Vector3[] array3 = (Vector3[])(object)new Vector3[array.Length * 5 + 2];
			for (int i = 0; i < array.Length; i++)
			{
				float num = array2[i];
				int num2 = i * 5;
				array3[num2] = new Vector3(0f - num, 2.2f, array[i]);
				array3[num2 + 1] = new Vector3((0f - num) * 0.88f, -0.1f, array[i]);
				array3[num2 + 2] = new Vector3(0f, -5.2f, array[i]);
				array3[num2 + 3] = new Vector3(num * 0.88f, -0.1f, array[i]);
				array3[num2 + 4] = new Vector3(num, 2.2f, array[i]);
			}
			List<int> list = new List<int>();
			for (int j = 0; j < array.Length - 1; j++)
			{
				for (int k = 0; k < 4; k++)
				{
					int num3 = j * 5 + k;
					int num4 = num3 + 5;
					int c = num4 + 1;
					int b = num3 + 1;
					AddQuad(list, num3, b, c, num4);
				}
			}
			int num5 = array.Length * 5;
			int num6 = num5 + 1;
			array3[num5] = new Vector3(0f, -0.4f, array[0]);
			array3[num6] = new Vector3(0f, -0.4f, array[^1]);
			for (int l = 0; l < 4; l++)
			{
				AddTriangle(list, num5, l, l + 1);
				int num7 = (array.Length - 1) * 5;
				AddTriangle(list, num6, num7 + l + 1, num7 + l);
			}
			Mesh val = new Mesh();
			((Object)val).name = "CoastalCarrackHullMesh";
			val.vertices = Il2CppStructArray<Vector3>.op_Implicit(array3);
			val.triangles = Il2CppStructArray<int>.op_Implicit(list.ToArray());
			val.RecalculateNormals();
			val.RecalculateBounds();
			GameObject val2 = new GameObject("CurvedHull");
			val2.transform.SetParent(parent, false);
			val2.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = _darkWood;
			SetVertexColors(val2, _darkWood);
			List<int> list2 = new List<int>(list.Count);
			for (int m = 0; m < list.Count; m += 3)
			{
				list2.Add(list[m]);
				list2.Add(list[m + 2]);
				list2.Add(list[m + 1]);
			}
			CreateMeshObject(parent, "CurvedHullInterior", array3, list2, _wood);
			BuildHullBands(parent, array, array2);
		}

		private static void BuildDecks(Transform parent)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			BuildClosedTaperedPlatform(parent, "WatertightMainDeck", new float[6] { -18f, -13f, -6f, 6f, 13f, 18f }, new float[6] { 6.2f, 7.7f, 8.25f, 8.25f, 7.7f, 6.2f }, 2.18f, 2.55f);
			BuildClosedTaperedPlatform(parent, "WatertightForecastle", new float[6] { 16f, 19f, 22f, 24f, 26f, 27f }, new float[6] { 6.4f, 6f, 5.1f, 4f, 1.8f, 0.8f }, 2.2f, 4.65f);
			BuildClosedTaperedPlatform(parent, "WatertightSterncastle", new float[6] { -27f, -26f, -24f, -22f, -19f, -16f }, new float[6] { 1.2f, 2.1f, 4.2f, 5.2f, 6.1f, 6.6f }, 2.2f, 4.65f);
			CreateCube(parent, "ForeDeckTrim", new Vector3(0f, 3.9f, 16.2f), new Vector3(12.8f, 0.55f, 0.55f), _ochre);
			CreateCube(parent, "SternDeckTrim", new Vector3(0f, 3.9f, -16.2f), new Vector3(13.8f, 0.55f, 0.55f), _ochre);
		}

		private static void BuildClosedTaperedPlatform(Transform parent, string name, float[] stations, float[] widths, float bottomY, float topY)
		{
			//IL_00b2: 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_00b6: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<int> triangles = new List<int>();
			Vector3 val = default(Vector3);
			Vector3 val2 = default(Vector3);
			Vector3 val3 = default(Vector3);
			Vector3 c = default(Vector3);
			Vector3 a = default(Vector3);
			Vector3 val4 = default(Vector3);
			Vector3 val5 = default(Vector3);
			Vector3 val6 = default(Vector3);
			for (int i = 0; i < stations.Length - 1; i++)
			{
				((Vector3)(ref val))..ctor(0f - widths[i], topY, stations[i]);
				((Vector3)(ref val2))..ctor(0f - widths[i + 1], topY, stations[i + 1]);
				((Vector3)(ref val3))..ctor(widths[i], topY, stations[i]);
				((Vector3)(ref c))..ctor(widths[i + 1], topY, stations[i + 1]);
				((Vector3)(ref a))..ctor(0f - widths[i], bottomY, stations[i]);
				((Vector3)(ref val4))..ctor(0f - widths[i + 1], bottomY, stations[i + 1]);
				((Vector3)(ref val5))..ctor(widths[i], bottomY, stations[i]);
				((Vector3)(ref val6))..ctor(widths[i + 1], bottomY, stations[i + 1]);
				AddIndependentQuad(list, triangles, val, val2, c, val3);
				AddIndependentQuad(list, triangles, a, val5, val6, val4);
				AddIndependentQuad(list, triangles, a, val4, val2, val);
				AddIndependentQuad(list, triangles, val5, val3, c, val6);
			}
			int num = stations.Length - 1;
			AddIndependentQuad(list, triangles, new Vector3(0f - widths[0], bottomY, stations[0]), new Vector3(0f - widths[0], topY, stations[0]), new Vector3(widths[0], topY, stations[0]), new Vector3(widths[0], bottomY, stations[0]));
			AddIndependentQuad(list, triangles, new Vector3(0f - widths[num], bottomY, stations[num]), new Vector3(widths[num], bottomY, stations[num]), new Vector3(widths[num], topY, stations[num]), new Vector3(0f - widths[num], topY, stations[num]));
			GameObject val7 = CreateMeshObject(parent, name, list.ToArray(), triangles, _wood);
			MeshCollider obj = val7.AddComponent<MeshCollider>();
			obj.sharedMesh = val7.GetComponent<MeshFilter>().sharedMesh;
			obj.convex = true;
		}

		private static void AddIndependentQuad(List<Vector3> vertices, List<int> triangles, Vector3 a, Vector3 b, Vector3 c, Vector3 d)
		{
			//IL_0008: 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_0016: 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)
			int count = vertices.Count;
			vertices.Add(a);
			vertices.Add(b);
			vertices.Add(c);
			vertices.Add(d);
			AddQuad(triangles, count, count + 1, count + 2, count + 3);
		}

		private static void BuildCastlesAndStairs(Transform parent)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00f9: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			CreateCube(parent, "SternCabin", new Vector3(0f, 5.35f, -22.2f), new Vector3(10.5f, 2.2f, 4.5f), _darkWood);
			CreateCube(parent, "SternCabinTeal", new Vector3(0f, 5.45f, -19.9f), new Vector3(8.5f, 0.8f, 0.2f), _teal);
			CreateCube(parent, "ForecastleCenterBulkhead", new Vector3(0f, 3.25f, 17.1f), new Vector3(6f, 1.8f, 0.6f), _darkWood);
			BuildStaircase(parent, new Vector3(-5.3f, 2.55f, 12.55f), 1f);
			BuildStaircase(parent, new Vector3(5.3f, 2.55f, 12.55f), 1f);
			BuildStaircase(parent, new Vector3(-5.7f, 2.55f, -12.55f), -1f);
			BuildStaircase(parent, new Vector3(5.7f, 2.55f, -12.55f), -1f);
			BuildRoofStaircase(parent, new Vector3(5.75f, 4.65f, -18.2f));
		}

		private static void BuildStaircase(Transform parent, Vector3 origin, float direction)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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)
			for (int i = 0; i < 6; i++)
			{
				Vector3 position = origin + new Vector3(0f, (float)i * 0.38f, direction * (float)i * 0.65f);
				CreateCube(parent, "DeckStep", position, new Vector3(2.1f, 0.38f, 1.15f), _wood);
			}
		}

		private static void BuildRoofStaircase(Transform parent, Vector3 origin)
		{
			//IL_0004: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 5; i++)
			{
				Vector3 position = origin + new Vector3(0f, (float)i * 0.38f, (float)(-i) * 0.65f);
				CreateCube(parent, "SternRoofStep", position, new Vector3(1.2f, 0.38f, 1.15f), _wood);
			}
			CreateCube(parent, "SternCabinRoofTrim", new Vector3(0f, 6.52f, -22.2f), new Vector3(10.8f, 0.28f, 4.8f), _ochre);
		}

		private static void BuildRails(Transform parent)
		{
			//IL_00a5: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[2] { -1f, 1f };
			Vector3 start = default(Vector3);
			Vector3 end = default(Vector3);
			foreach (float num in array)
			{
				(float, float)[] array2 = new(float, float)[2]
				{
					(-14f, -3f),
					(3f, 14f)
				};
				for (int j = 0; j < array2.Length; j++)
				{
					var (num2, num3) = array2[j];
					((Vector3)(ref start))..ctor(num * DeckHalfWidthAt(num2), 3.65f, num2);
					((Vector3)(ref end))..ctor(num * DeckHalfWidthAt(num3), 3.65f, num3);
					CreateBeamBetween(parent, "TaperedMainRail", start, end, 0.28f, 0.28f, _ochre);
				}
				float[] array3 = new float[8] { -14f, -11f, -8f, -5f, 5f, 8f, 11f, 14f };
				foreach (float num4 in array3)
				{
					float num5 = num * DeckHalfWidthAt(num4);
					CreateCube(parent, "MainRailPost", new Vector3(num5, 3.2f, num4), new Vector3(0.35f, 2f, 0.35f), _darkWood);
				}
			}
			BuildTaperedUpperRails(parent, "Forecastle", new float[6] { 16f, 19f, 22f, 24f, 26f, 27f }, new float[6] { 6.4f, 6f, 5.1f, 4f, 1.8f, 0.8f });
			BuildTaperedUpperRails(parent, "Sterncastle", new float[6] { -27f, -26f, -24f, -22f, -19f, -16f }, new float[6] { 1.2f, 2.1f, 4.2f, 5.2f, 6.1f, 6.6f });
		}

		private static void BuildTaperedUpperRails(Transform parent, string prefix, float[] stations, float[] widths)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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)
			float[] array = new float[2] { -1f, 1f };
			foreach (float num in array)
			{
				for (int j = 0; j < stations.Length - 1; j++)
				{
					CreateBeamBetween(parent, prefix + "SideRail", new Vector3(num * widths[j], 5.72f, stations[j]), new Vector3(num * widths[j + 1], 5.72f, stations[j + 1]), 0.28f, 0.28f, _ochre);
				}
				for (int k = 0; k < stations.Length; k++)
				{
					CreateCube(parent, prefix + "RailPost", new Vector3(num * widths[k], 5.2f, stations[k]), new Vector3(0.35f, 1.8f, 0.35f), _darkWood);
				}
			}
			CreateCube(parent, prefix + "EndRail", new Vector3(0f, 5.72f, stations[0]), new Vector3(widths[0] * 2f, 0.3f, 0.3f), _ochre);
			CreateCube(parent, prefix + "EndRail", new Vector3(0f, 5.72f, stations[^1]), new Vector3(widths[^1] * 2f, 0.3f, 0.3f), _ochre);
		}

		private static float DeckHalfWidthAt(float z)
		{
			float num = Mathf.Abs(z);
			if (num <= 6f)
			{
				return 8.25f;
			}
			if (num <= 13f)
			{
				return Mathf.Lerp(8.25f, 7.7f, (num - 6f) / 7f);
			}
			return Mathf.Lerp(7.7f, 6.2f, Mathf.Clamp01((num - 13f) / 5f));
		}

		private static void BuildMast(Transform parent, float z, float mastHeight, float sailWidth)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			CreateCylinder(parent, "Mast", new Vector3(0f, 2.6f + mastHeight * 0.5f, z), new Vector3(0.7f, mastHeight * 0.5f, 0.7f), _darkWood);
			CreateCylinder(parent, "Yard", new Vector3(0f, 13.8f, z), new Vector3(0.35f, sailWidth * 0.5f, 0.35f), _darkWood, Quaternion.Euler(0f, 0f, 90f));
			BuildBillowedSail(parent, z + 0.15f, sailWidth);
			CreateCube(parent, "SailBottomTrim", new Vector3(0f, 7.1f, z), new Vector3(sailWidth * 0.92f, 0.16f, 0.2f), _rope);
		}

		private static Transform BuildWheel(Transform parent)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = default(Vector3);
			((Vector3)(ref localPosition))..ctor(0f, 4.3f, -10.5f);
			Transform transform = new GameObject("HelmWheelControl").transform;
			transform.SetParent(parent, false);
			transform.localPosition = localPosition;
			CreateCylinder(transform, "WheelHub", Vector3.zero, new Vector3(0.45f, 0.35f, 0.45f), _ochre, Quaternion.Euler(90f, 0f, 0f));
			for (int i = 0; i < 8; i++)
			{
				float num = (float)i * 45f;
				CreateCube(transform, "WheelSpoke", Vector3.zero, new Vector3(0.22f, 3.6f, 0.22f), _ochre).transform.localRotation = Quaternion.Euler(0f, 0f, num);
			}
			CreateCube(parent, "HelmPedestal", new Vector3(0f, 3.25f, -10.5f), new Vector3(1.2f, 2.1f, 1.2f), _darkWood);
			return transform;
		}

		private static Transform BuildThrottleControl(Transform parent)
		{
			//IL_0017: 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_0035: 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_0076: 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)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(3.2f, 3.38f, -9.2f);
			BuildThrottlePedestal(parent, val);
			Transform transform = new GameObject("TrainStyleThrottleLever").transform;
			transform.SetParent(parent, false);
			transform.localPosition = val;
			transform.localRotation = Quaternion.Euler(-15f, 0f, 0f);
			BuildExactTrainLever(transform);
			BoxCollider obj = ((Component)transform).gameObject.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, 0.25f, 0.5f);
			obj.size = new Vector3(1.5f, 1.35f, 1.7f);
			((Collider)obj).isTrigger = true;
			return transform;
		}

		private static void BuildThrottlePedestal(Transform parent, Vector3 pivot)
		{
			//IL_0006: 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_001d: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_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_0142: 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_014d: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			CreateCube(parent, "ThrottleFootPlate", new Vector3(pivot.x, 2.64f, pivot.z - 0.3f), new Vector3(1.9f, 0.18f, 1.75f), _ochre);
			CreateCube(parent, "ThrottlePedestal", new Vector3(pivot.x, 2.94f, pivot.z - 0.32f), new Vector3(1.55f, 0.58f, 1.35f), _teal);
			CreateCube(parent, "ThrottlePedestalTop", new Vector3(pivot.x, 3.23f, pivot.z - 0.14f), new Vector3(1.38f, 0.22f, 0.96f), _darkWood);
			CreateCylinder(parent, "ThrottlePivotAxle", pivot, new Vector3(0.38f, 0.82f, 0.38f), _ochre, Quaternion.Euler(0f, 0f, 90f));
			CreateSphere(parent, "ThrottlePivotCapPort", pivot + Vector3.left * 0.84f, new Vector3(0.42f, 0.42f, 0.42f), _ochre);
			CreateSphere(parent, "ThrottlePivotCapStarboard", pivot + Vector3.right * 0.84f, new Vector3(0.42f, 0.42f, 0.42f), _ochre);
		}

		private static void BuildExactTrainLever(Transform parent)
		{
			//IL_00a1: 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_00b3: 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_00c3: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0052: 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_008b: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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)
			ResolveTrainControlAssets();
			if ((Object)(object)_trainBrakeLeverMesh == (Object)null)
			{
				((BasePlugin)Plugin.Instance).Log.LogWarning((object)"Exact train brake lever mesh was not loaded; using a temporary visible fallback lever.");
				CreateCube(parent, "TrainLeverFallback", new Vector3(0f, 1f, 0f), new Vector3(0.35f, 2.2f, 0.4f), _ochre);
				CreateSphere(parent, "TrainLeverFallbackHandle", new Vector3(0f, 2.15f, 0f), new Vector3(0.8f, 0.65f, 0.55f), _ochre);
				return;
			}
			GameObject val = new GameObject("Carriage_front_dashboard_brakelever");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.Euler(-20f, 0f, 0f);
			val.transform.localScale = Vector3.one * 2.5f;
			val.AddComponent<MeshFilter>().sharedMesh = _trainBrakeLeverMesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = _trainBrakeLeverMaterial ?? _ochre;
			BoxCollider obj = val.AddComponent<BoxCollider>();
			Bounds bounds = _trainBrakeLeverMesh.bounds;
			obj.center = ((Bounds)(ref bounds)).center;
			obj.size = ((Bounds)(ref bounds)).size + new Vector3(0.12f, 0.12f, 0.08f);
			((Collider)obj).isTrigger = true;
		}

		private static void ResolveTrainControlAssets()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			if ((Object)(object)_trainBrakeLeverMesh != (Object)null)
			{
				return;
			}
			Mesh[] source = Il2CppArrayBase<Mesh>.op_Implicit(Resources.FindObjectsOfTypeAll<Mesh>());
			if (_trainBrakeLeverMesh == null)
			{
				_trainBrakeLeverMesh = ((IEnumerable<Mesh>)source).FirstOrDefault((Func<Mesh, bool>)((Mesh mesh) => (Object)(object)mesh != (Object)null && ((Object)mesh).name.Equals("Carriage_front_dashboard_brakelever", StringComparison.Ordinal)));
			}
			if ((Object)(object)_trainBrakeLeverMesh == (Object)null)
			{
				return;
			}
			MeshFilter[] source2 = Il2CppArrayBase<MeshFilter>.op_Implicit(Resources.FindObjectsOfTypeAll<MeshFilter>());
			if ((Object)(object)_trainBrakeLeverMesh != (Object)null && (Object)(object)_trainBrakeLeverMaterial == (Object)null)
			{
				MeshFilter? obj = ((IEnumerable<MeshFilter>)source2).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter filter) => (Object)(object)filter != (Object)null && (Object)(object)filter.sharedMesh == (Object)(object)_trainBrakeLeverMesh));
				object trainBrakeLeverMaterial;
				if (obj == null)
				{
					trainBrakeLeverMaterial = null;
				}
				else
				{
					MeshRenderer component = ((Component)obj).gameObject.GetComponent<MeshRenderer>();
					trainBrakeLeverMaterial = ((component != null) ? ((Renderer)component).sharedMaterial : null);
				}
				_trainBrakeLeverMaterial = (Material)trainBrakeLeverMaterial;
			}
			if (!_loggedTrainLeverAsset)
			{
				_loggedTrainLeverAsset = true;
				ManualLogSource log = ((BasePlugin)Plugin.Instance).Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(90, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mounted exact train lever mesh '");
					Mesh trainBrakeLeverMesh = _trainBrakeLeverMesh;
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((trainBrakeLeverMesh != null) ? ((Object)trainBrakeLeverMesh).name : null) ?? "missing");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' with material ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
					Material trainBrakeLeverMaterial2 = _trainBrakeLeverMaterial;
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((trainBrakeLeverMaterial2 != null) ? ((Object)trainBrakeLeverMaterial2).name : null) ?? ((Object)_ochre).name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' on the solid carrack throttle pedestal.");
				}
				log.LogInfo(val);
			}
		}

		private static void BuildHullBands(Transform parent, float[] stations, float[] widths)
		{
			//IL_00f8: 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_0125: 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_015e: 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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			Vector3 start = default(Vector3);
			Vector3 end = default(Vector3);
			Vector3 start2 = default(Vector3);
			Vector3 end2 = default(Vector3);
			for (int i = 0; i < 2; i++)
			{
				float num = ((i == 0) ? (-1f) : 1f);
				for (int j = 0; j < stations.Length - 1; j++)
				{
					((Vector3)(ref start))..ctor(num * widths[j] * 0.96f, 1.12f, stations[j]);
					((Vector3)(ref end))..ctor(num * widths[j + 1] * 0.96f, 1.12f, stations[j + 1]);
					CreateBeamBetween(parent, "OchreHullStripe", start, end, 0.32f, 0.45f, _ochre);
					((Vector3)(ref start2))..ctor(num * widths[j] * 0.82f, 0.15f, stations[j]);
					((Vector3)(ref end2))..ctor(num * widths[j + 1] * 0.82f, 0.15f, stations[j + 1]);
					CreateBeamBetween(parent, "TealHullStripe", start2, end2, 0.26f, 0.62f, _teal);
				}
			}
			CreateCylinder(parent, "Bowsprit", new Vector3(0f, 4.3f, 30.8f), new Vector3(0.35f, 5.2f, 0.35f), _darkWood, Quaternion.Euler(72f, 0f, 0f));
			CreateCube(parent, "Keel", new Vector3(0f, -3.75f, -1f), new Vector3(0.5f, 2.7f, 42f), _darkWood);
			CreateCube(parent, "SternRudder", new Vector3(0f, -0.7f, -27.6f), new Vector3(2.2f, 5.8f, 0.45f), _darkWood);
		}

		private static void BuildBillowedSail(Transform parent, float z, float width)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[30];
			for (int i = 0; i < 5; i++)
			{
				float num = (float)i / 4f;
				float num2 = Mathf.Lerp(7.1f, 13.55f, num);
				float num3 = width * Mathf.Lerp(0.88f, 1f, num);
				for (int j = 0; j < 6; j++)
				{
					float num4 = (float)j / 5f;
					float num5 = Mathf.Lerp((0f - num3) * 0.5f, num3 * 0.5f, num4);
					float num6 = Mathf.Sin(num4 * (float)Math.PI) * Mathf.Sin(num * (float)Math.PI) * 0.9f;
					array[i * 6 + j] = new Vector3(num5, num2, z + num6);
				}
			}
			List<int> list = new List<int>();
			for (int k = 0; k < 4; k++)
			{
				for (int l = 0; l < 5; l++)
				{
					int num7 = k * 6 + l;
					AddQuad(list, num7, num7 + 1, num7 + 6 + 1, num7 + 6);
				}
			}
			CreateMeshObject(parent, "BillowedCreamSailFront", array, list, _sail);
			List<int> list2 = new List<int>(list.Count);
			for (int m = 0; m < list.Count; m += 3)
			{
				list2.Add(list[m]);
				list2.Add(list[m + 2]);
				list2.Add(list[m + 1]);
			}
			CreateMeshObject(parent, "BillowedCreamSailBack", array, list2, _sail);
		}

		private static void CreateBeamBetween(Transform parent, string name, Vector3 start, Vector3 end, float thickness, float height, Material material)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = end - start;
			Vector3 position = (start + end) * 0.5f;
			CreateCube(parent, name, position, new Vector3(thickness, height, ((Vector3)(ref val)).magnitude), material).transform.localRotation = Quaternion.Euler(0f, Mathf.Atan2(val.x, val.z) * 57.29578f, 0f);
		}

		private static GameObject CreateMeshObject(Transform parent, string name, Vector3[] vertices, List<int> triangles, Material material)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_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 mis