Decompiled source of CustomShips v0.4.1

CustomShips.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using CustomShips.Helper;
using CustomShips.Pieces;
using CustomShips.ZProperties;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CustomShips")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomShips")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.4.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.1.0")]
namespace CustomShips
{
	[BepInPlugin("com.maxsch.valheim.CustomShips", "CustomShips", "0.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "com.maxsch.valheim.CustomShips";

		public const string PluginName = "CustomShips";

		public const string PluginVersion = "0.4.1";

		private static AssetBundle assetBundle;

		private static List<CustomPiece> pieces = new List<CustomPiece>();

		private static HashSet<string> shipPieceNames = new HashSet<string>();

		private static HashSet<int> shipPieceHashes = new HashSet<int>();

		public static CustomPiece customShip;

		private static int shipPrefabHash;

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			new Harmony("com.maxsch.valheim.CustomShips").PatchAll();
			Localization.AddJsonFile("English", AssetUtils.LoadTextFromResources("Localization.English.json"));
			assetBundle = AssetUtils.LoadAssetBundleFromResources("customships");
			customShip = new CustomPiece(assetBundle, "MS_CustomShip", false, ShipPartConfig(enabled: false));
			PieceManager.Instance.AddPiece(customShip);
			shipPrefabHash = StringExtensionMethods.GetStableHashCode(((Object)customShip.PiecePrefab).name);
			AddShipPiece("MS_Keel_2m", "RoundLog", 4, "BronzeNails", 2);
			AddShipPiece("MS_Keel_4m", "RoundLog", 8, "BronzeNails", 4);
			AddShipPiece("MS_Keel_Bow_1", "RoundLog", 6, "BronzeNails", 4);
			AddShipPiece("MS_Keel_Bow_2", "RoundLog", 4, "BronzeNails", 2);
			AddShipPiece("MS_Rib_1.0m", "RoundLog", 4, "BronzeNails", 2);
			AddShipPiece("MS_Rib_1.2m", "RoundLog", 4, "BronzeNails", 2);
			AddShipPiece("MS_Rib_1.4m", "RoundLog", 5, "BronzeNails", 2);
			AddShipPiece("MS_Rib_1.6m", "RoundLog", 5, "BronzeNails", 2);
			AddShipPiece("MS_Rib_1.8m", "RoundLog", 6, "BronzeNails", 2);
			AddShipPiece("MS_Rib_2.0m", "RoundLog", 6, "BronzeNails", 2);
			AddShipPiece("MS_Rib_2.2m", "RoundLog", 7, "BronzeNails", 2);
			AddShipPiece("MS_Rib_2.4m", "RoundLog", 7, "BronzeNails", 2);
			AddShipPiece("MS_Rib_2.6m", "RoundLog", 8, "BronzeNails", 2);
			AddShipPiece("MS_Hull_Dynamic", "Wood", 6, "BronzeNails", 2, "Resin", 10);
			AddShipPiece("MS_Deck_Dynamic", "Wood", 4, "BronzeNails", 2, "Resin", 6);
			AddShipPiece("MS_Hull_Side_Dynamic", "Wood", 4, "BronzeNails", 2, "Resin", 6);
			AddShipPiece("MS_Rudder_1", "Wood", 12, "BronzeNails", 8);
			AddShipPiece("MS_Crate_1", "FineWood", 8, "BronzeNails", 6);
			AddShipPiece("MS_Barrel_1", "FineWood", 8, "BronzeNails", 6);
			AddShipPiece("MS_Ladder_1", "Wood", 4, "BronzeNails", 2);
			AddShipPiece("MS_Shield_Round_1_Style_1", "FineWood", 6, "BronzeNails", 4);
			AddShipPiece("MS_Shield_Round_1_Style_2", "FineWood", 6, "BronzeNails", 4);
			AddShipPiece("MS_Shield_Round_1_Style_3", "FineWood", 6, "BronzeNails", 4);
			AddShipPiece("MS_Shield_Round_1_Style_4", "FineWood", 6, "BronzeNails", 4);
			AddShipPiece("MS_Sail_2_White", "FineWood", 20, "LeatherScraps", 12, "Resin", 8);
			AddShipPiece("MS_Sail_2_Red_1", "FineWood", 20, "LeatherScraps", 12, "Resin", 8, "Raspberry", 4);
			AddShipPiece("MS_Sail_2_Hide_1", "FineWood", 20, "DeerHide", 12, "Resin", 8);
			AddShipPiece("MS_Sail_1_White", "FineWood", 30, "LeatherScraps", 20, "Resin", 12);
			AddShipPiece("MS_Sail_1_Red_1", "FineWood", 30, "LeatherScraps", 20, "Resin", 12, "Raspberry", 8);
			AddShipPiece("MS_Sail_1_Hide_1", "FineWood", 30, "DeerHide", 20, "Resin", 12);
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
		}

		private void OnPiecesRegistered()
		{
			PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
			((MonoBehaviour)this).StartCoroutine(RenderSprites());
		}

		private static IEnumerator RenderSprites()
		{
			yield return null;
			foreach (CustomPiece piece in pieces)
			{
				piece.Piece.m_icon = RenderManager.Instance.Render(new RenderRequest(piece.PiecePrefab)
				{
					Width = 64,
					Height = 64,
					Rotation = RenderManager.IsometricRotation * Quaternion.Euler(0f, -90f, 0f)
				});
			}
		}

		private void AddShipPiece(string pieceName, string ingredient1 = "", int amount1 = 0, string ingredient2 = "", int amount2 = 0, string ingredient3 = "", int amount3 = 0, string ingredient4 = "", int amount4 = 0)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			PieceConfig val = ShipPartConfig(enabled: true, ingredient1, amount1, ingredient2, amount2, ingredient3, amount3, ingredient4, amount4);
			CustomPiece val2 = new CustomPiece(assetBundle, pieceName, true, val);
			PieceManager.Instance.AddPiece(val2);
			pieces.Add(val2);
			shipPieceNames.Add(pieceName);
			shipPieceHashes.Add(StringExtensionMethods.GetStableHashCode(pieceName));
		}

		public static bool IsShipPiece(GameObject piece)
		{
			return shipPieceNames.Contains(Utils.GetPrefabName(piece));
		}

		public static bool IsShipPiece(ZDO zdo)
		{
			return shipPieceHashes.Contains(zdo.GetPrefab());
		}

		public static bool IsCustomShip(GameObject piece)
		{
			return StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(piece)) == shipPrefabHash;
		}

		public static bool IsCustomShip(ZDO zdo)
		{
			return zdo.GetPrefab() == shipPrefabHash;
		}

		private PieceConfig ShipPartConfig(bool enabled, string ingredient1 = "", int amount1 = 0, string ingredient2 = "", int amount2 = 0, string ingredient3 = "", int amount3 = 0, string ingredient4 = "", int amount4 = 0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.PieceTable = PieceTables.Hammer;
			val.CraftingStation = CraftingStations.Workbench;
			val.Category = "Ship";
			val.Enabled = enabled;
			val.AddRequirement(new RequirementConfig(ingredient1, amount1, 0, true));
			val.AddRequirement(new RequirementConfig(ingredient2, amount2, 0, true));
			val.AddRequirement(new RequirementConfig(ingredient3, amount3, 0, true));
			val.AddRequirement(new RequirementConfig(ingredient4, amount4, 0, true));
			if (val.Requirements.Length == 0)
			{
				val.AddRequirement(new RequirementConfig("Wood", 3, 0, true));
			}
			return val;
		}
	}
}
namespace CustomShips.ZProperties
{
	public class ZBool : ZProperty<bool>
	{
		public ZBool(string key, bool defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}

		protected override bool GetValue()
		{
			return base.NetView.GetZDO().GetBool(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(bool value)
		{
			base.NetView.GetZDO().Set(base.KeyHash, value);
		}
	}
	public class ZFloat : ZProperty<float>
	{
		public ZFloat(string key, float defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}

		protected override float GetValue()
		{
			return base.NetView.GetZDO().GetFloat(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(float value)
		{
			base.NetView.GetZDO().Set(base.KeyHash, value);
		}
	}
	public class ZInt : ZProperty<int>
	{
		public ZInt(string key, int defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}

		protected override int GetValue()
		{
			return base.NetView.GetZDO().GetInt(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(int value)
		{
			base.NetView.GetZDO().Set(base.KeyHash, value, false);
		}
	}
	public abstract class ZProperty<T>
	{
		private T editorValue;

		public string Key { get; }

		public T DefaultValue { get; }

		protected ZNetView NetView { get; }

		protected int KeyHash { get; }

		private string RPCName { get; }

		protected ZProperty(string key, T defaultValue, ZNetView netView)
		{
			Key = key;
			RPCName = "RPC_" + key;
			KeyHash = StringExtensionMethods.GetStableHashCode(Key);
			DefaultValue = defaultValue;
			NetView = netView;
			NetView.Register<T>(RPCName, (Action<long, T>)RPCSet);
		}

		public void Set(T value)
		{
			if (Application.isEditor && !Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				editorValue = value;
				return;
			}
			if (NetView.IsValid() && NetView.IsOwner())
			{
				SetValue(value);
				return;
			}
			NetView.InvokeRPC(RPCName, new object[1] { value });
		}

		public T Get()
		{
			if (Application.isEditor && !Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return editorValue;
			}
			return GetValue();
		}

		public void Reset()
		{
			Set(DefaultValue);
		}

		protected abstract T GetValue();

		protected abstract void SetValue(T value);

		private void RPCSet(long sender, T value)
		{
			SetValue(value);
		}
	}
	public class ZQuaternion : ZProperty<Quaternion>
	{
		public ZQuaternion(string key, Quaternion defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)


		protected override Quaternion GetValue()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return base.NetView.GetZDO().GetQuaternion(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(Quaternion value)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			base.NetView.GetZDO().Set(base.KeyHash, value);
		}
	}
	public class ZVector3 : ZProperty<Vector3>
	{
		public ZVector3(string key, Vector3 defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)


		protected override Vector3 GetValue()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return base.NetView.GetZDO().GetVec3(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(Vector3 value)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			base.NetView.GetZDO().Set(base.KeyHash, value);
		}
	}
}
namespace CustomShips.Pieces
{
	public class Crate : ShipPart
	{
	}
	public class CustomShip : MonoBehaviour, IDestructible
	{
		public ShipControlls shipControls;

		public Transform partParent;

		public BoxCollider onboardTrigger;

		public ZInt uniqueID;

		[HideInInspector]
		public Ship ship;

		private static List<CustomShip> ships = new List<CustomShip>();

		private List<ShipPart> shipParts = new List<ShipPart>();

		private ZNetView nview;

		private Rigidbody rigidbody;

		private Rudder currentRudder;

		private ZQuaternion localPartRotation;

		private void Awake()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			nview = ((Component)this).gameObject.GetComponent<ZNetView>();
			if (Application.isEditor || (Object.op_Implicit((Object)(object)nview) && nview.GetZDO() != null))
			{
				ships.Add(this);
				ship = ((Component)this).gameObject.GetComponent<Ship>();
				rigidbody = ((Component)this).gameObject.GetComponent<Rigidbody>();
				uniqueID = new ZInt("MS_UniqueID", 0, nview);
				localPartRotation = new ZQuaternion("MS_LocalPartRotation", Quaternion.identity, nview);
				if (uniqueID.Get() == 0)
				{
					uniqueID.Set(StringExtensionMethods.GetStableHashCode(Guid.NewGuid().ToString()));
				}
				((MonoBehaviour)this).InvokeRepeating("UpdatePieces", 1f, 1f);
			}
		}

		public void AddPart(ShipPart shipPart)
		{
			if (!shipParts.Contains(shipPart))
			{
				shipParts.Add(shipPart);
				((Component)shipPart).transform.SetParent(partParent);
			}
		}

		private void UpdatePieces()
		{
			shipParts.RemoveAll((ShipPart i) => !Object.op_Implicit((Object)(object)i));
			UpdateRudder();
			UpdateSails();
			UpdateCollider();
			UpdateWeight();
		}

		public void UpdateRudder()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (!Application.isEditor && !nview.IsOwner())
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)currentRudder))
			{
				currentRudder.SetShipControls(shipControls);
				return;
			}
			List<Rudder> partsOfType = GetPartsOfType<Rudder>();
			if (partsOfType.Count == 1)
			{
				currentRudder = partsOfType[0];
				Quaternion rotation = partParent.rotation;
				((Component)this).transform.rotation = Quaternion.LookRotation(((Component)currentRudder).transform.forward, ((Component)currentRudder).transform.up);
				partParent.rotation = rotation;
				localPartRotation.Set(partParent.localRotation);
				currentRudder.SetShipControls(shipControls);
			}
		}

		private void UpdateSails()
		{
			float num = GetPartsOfType<Sail>().Sum((Sail sail) => sail.force);
			float sailForceFactor = Mathf.Round(1000f * (Mathf.Log(1f + num * 4f) / 4f)) / 1000f;
			ship.m_sailForceFactor = sailForceFactor;
		}

		public List<T> GetPartsOfType<T>() where T : ShipPart
		{
			return (from part in shipParts
				select part as T into part
				where Object.op_Implicit((Object)(object)part)
				select part).ToList();
		}

		public Vector3 ToLocalPosition(Vector3 global)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.InverseTransformPoint(global);
		}

		public Vector3 ToLocalPosition(ShipPart part)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return ToLocalPosition(((Component)part).transform.position);
		}

		private void Update()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (localPartRotation != null)
			{
				partParent.localRotation = localPartRotation.Get();
			}
		}

		private void OnDestroy()
		{
			if (Application.isEditor)
			{
				return;
			}
			foreach (ShipPart shipPart in shipParts)
			{
				if (Object.op_Implicit((Object)(object)shipPart))
				{
					((Component)shipPart).transform.SetParent((Transform)null);
				}
			}
		}

		private void UpdateCollider()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_009d: 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_00af: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00e5: 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_00f7: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0110: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(1000f, 1000f, 1000f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(-1000f, -1000f, -1000f);
			Vector3 val3 = Vector3.zero;
			int num = 0;
			Vector3 val4 = Vector3.zero;
			float num2 = 0f;
			bool flag = false;
			foreach (ShipPart shipPart in shipParts)
			{
				if (Object.op_Implicit((Object)(object)shipPart))
				{
					flag = true;
					Vector3 val5 = ((!(shipPart is Rib rib)) ? ToLocalPosition(shipPart) : ToLocalPosition(rib.EndPosition));
					val = new Vector3(Mathf.Min(val.x, val5.x), Mathf.Min(val.y, val5.y), Mathf.Min(val.z, val5.z));
					val2 = new Vector3(Mathf.Max(val2.x, val5.x), Mathf.Max(val2.y, val5.y), Mathf.Max(val2.z, val5.z));
					val3 += val5;
					num++;
					val4 += val5 * shipPart.buoyancy;
					num2 += shipPart.buoyancy;
				}
			}
			if (flag)
			{
				Vector3 val6 = new Vector3(Mathf.Abs(val.x - val2.x), Mathf.Abs(val.y - val2.y), Mathf.Abs(val.z - val2.z)) + Vector3.one;
				ship.m_floatCollider.size = new Vector3(val6.x, 0.2f, val6.z);
				((Component)ship.m_floatCollider).transform.localPosition = val4 / num2;
				rigidbody.centerOfMass = val3 / (float)num;
				onboardTrigger.size = new Vector3(val6.x + 1f, val6.y + 3f, val6.z + 1f);
				((Component)onboardTrigger).transform.position = rigidbody.worldCenterOfMass + new Vector3(0f, 1f, 0f);
				UpdateSteerForce(val6.z);
			}
		}

		private void UpdateWeight()
		{
			rigidbody.mass = Mathf.Max(100f, shipParts.Sum((ShipPart part) => part.Weight));
		}

		private void UpdateSteerForce(float sizeZ)
		{
			float num = (sizeZ - 4f) / 16f;
			ship.m_stearForce = Mathf.Lerp(0.2f, 1f, num);
			ship.m_stearVelForceFactor = Mathf.Lerp(0.2f, 0.8f, num);
			ship.m_backwardForce = Mathf.Lerp(0.5f, 0.2f, num);
			ship.m_angularDamping = Mathf.Lerp(0.05f, 0.3f, num);
		}

		public static CustomShip FindCustomShip(int uniqueID)
		{
			return ships.FirstOrDefault((CustomShip ship) => Object.op_Implicit((Object)(object)ship) && ship.uniqueID.Get() == uniqueID);
		}

		public void Damage(HitData hit)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (shipParts.Count != 0)
			{
				if ((int)hit.m_hitType == 21)
				{
					int index = Random.Range(0, shipParts.Count);
					ShipPart shipPart = shipParts[index];
					TryDamage(shipPart, hit);
				}
				else
				{
					ShipPart shipPart2 = ShipPart.FindNearest(this, hit.m_point);
					TryDamage(shipPart2, hit);
				}
			}
		}

		private bool TryDamage(ShipPart shipPart, HitData hit)
		{
			if (!Object.op_Implicit((Object)(object)shipPart))
			{
				return false;
			}
			WearNTear val = default(WearNTear);
			if (!((Component)shipPart).TryGetComponent<WearNTear>(ref val))
			{
				Logger.LogWarning((object)("Ship part " + ((Object)shipPart).name + " has no WearNTear component"));
				return false;
			}
			val.Damage(hit);
			return true;
		}

		public DestructibleType GetDestructibleType()
		{
			return (DestructibleType)1;
		}
	}
	public class DynamicMesh : MonoBehaviour
	{
		public int segments = 2;

		public int splits = 1;

		public float width = 0.2f;

		public float height = 1f;

		public float sideWidthInceaseOffset;

		public bool rotateMesh = true;

		public bool useCurve = true;

		public Vector3 meshOffset;

		public Vector3 colliderOffset;

		public Rect uvRect = new Rect(0.54f, 0.04f, 0.08f, 0.1f);

		public bool fixedUV;

		private AnimationCurve curve = new AnimationCurve();

		private Hull hull;

		private float sideWidthIncease = 7f;

		private float relY;

		private void Awake()
		{
			hull = ((Component)this).GetComponentInParent<Hull>();
			hull.OnChange += delegate
			{
				//IL_0133: 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_008f: 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_00ba: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				UpdateCurve();
				bool flag = false;
				float left = 2f;
				float right = 2f;
				float num = 0f;
				float num2 = 0f;
				if (Object.op_Implicit((Object)(object)hull.leftRib) && Object.op_Implicit((Object)(object)hull.rightRib))
				{
					flag = true;
					left = hull.leftRib.size + 0.1f;
					right = hull.rightRib.size + 0.1f;
					num = 0f;
					num2 = 0f;
					relY = Mathf.Min(((Component)this).transform.position.y - ((Component)hull.leftRib).transform.position.y, ((Component)this).transform.position.y - ((Component)hull.rightRib).transform.position.y);
				}
				else if (Object.op_Implicit((Object)(object)hull.leftRib))
				{
					flag = true;
					left = hull.leftRib.size + 0.1f;
					right = -0.1f;
					num = 0f;
					num2 = 0.4f;
					relY = ((Component)this).transform.position.y - ((Component)hull.leftRib).transform.position.y;
				}
				else if (Object.op_Implicit((Object)(object)hull.rightRib))
				{
					flag = true;
					left = -0.1f;
					right = hull.rightRib.size + 0.1f;
					num = 0.4f;
					num2 = 0f;
					relY = ((Component)this).transform.position.y - ((Component)hull.rightRib).transform.position.y;
				}
				if (flag)
				{
					RegenerateMesh(left, right, (Mathf.Abs(relY) < 0.1f) ? num : 0f, (Mathf.Abs(relY) < 0.1f) ? num2 : 0f);
				}
			};
		}

		private void UpdateCurve()
		{
			float num = 0f;
			float num2 = (Object.op_Implicit((Object)(object)hull.leftRib) ? hull.leftRib.size : (-0.1f));
			float num3 = (Object.op_Implicit((Object)(object)hull.rightRib) ? hull.rightRib.size : (-0.1f));
			float num4 = 0f;
			if (Object.op_Implicit((Object)(object)hull.leftRib))
			{
				num = (Object.op_Implicit((Object)(object)hull.leftRib.leftRib) ? hull.leftRib.leftRib.size : ((!Object.op_Implicit((Object)(object)hull.rightRib)) ? (-0.1f) : (Mathf.Min(hull.leftRib.size, hull.rightRib.size) - Mathf.Clamp(Mathf.Abs(hull.leftRib.size - hull.rightRib.size), 0.1f, 0.6f))));
			}
			else if (Object.op_Implicit((Object)(object)hull.rightRib))
			{
				num = (0f - hull.rightRib.size) * 2f;
			}
			if (Object.op_Implicit((Object)(object)hull.rightRib))
			{
				num4 = (Object.op_Implicit((Object)(object)hull.rightRib.rightRib) ? hull.rightRib.rightRib.size : ((!Object.op_Implicit((Object)(object)hull.leftRib)) ? (-0.1f) : (Mathf.Min(hull.leftRib.size, hull.rightRib.size) - Mathf.Clamp(Mathf.Abs(hull.leftRib.size - hull.rightRib.size), 0.1f, 0.6f))));
			}
			else if (Object.op_Implicit((Object)(object)hull.leftRib))
			{
				num4 = (0f - hull.leftRib.size) * 2f;
			}
			curve.ClearKeys();
			curve.AddKey(-3f, num);
			curve.AddKey(-1f, num2);
			curve.AddKey(1f, num3);
			curve.AddKey(3f, num4);
		}

		public void UpdateCurve(float preLeft, float left, float right, float preRight)
		{
			curve.ClearKeys();
			curve.AddKey(-3f, preLeft);
			curve.AddKey(-1f, left);
			curve.AddKey(1f, right);
			curve.AddKey(3f, preRight);
		}

		private void MakeTriangle(int index, int[] triangles, int a, int b, int c)
		{
			if (index > triangles.Length - 3)
			{
				Debug.Log((object)("Index " + index + " out of bounds " + triangles.Length));
				return;
			}
			triangles[index] = a;
			triangles[index + 1] = b;
			triangles[index + 2] = c;
		}

		private void MakeFace(ref int index, int[] triangles, int a, int b, int c, int d)
		{
			MakeTriangle(index, triangles, a, c, b);
			MakeTriangle(index + 3, triangles, b, c, d);
			index += 6;
		}

		private int GetTopVertice(int segment, int split)
		{
			return segment * (splits + 2) * 2 + split * 2;
		}

		private int GetBottomVertice(int segment, int split)
		{
			return segment * (splits + 2) * 2 + split * 2 + 1;
		}

		public void RegenerateMesh(float left, float right, float startLeft, float startRight)
		{
			//IL_0707: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Expected O, but got Unknown
			//IL_077e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_0644: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0662: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			int num = (segments + 1) * (splits + 2);
			int num2 = (segments + 1) * (splits + 2);
			int num3 = (splits + 2) * 4;
			int num4 = (splits + 2) * 4;
			int num5 = (segments + 1) * 4;
			int num6 = (segments + 1) * 4;
			int num7 = num + num2;
			int num8 = num7 + num3 + num4;
			Vector3[] array = (Vector3[])(object)new Vector3[num + num2 + num3 + num4 + num5 + num6];
			int[] triangles = new int[segments * (splits + 1) * 6 * 2 + (splits + 1) * 6 * 2 + segments * 6 * 2];
			Vector2[] array2 = (Vector2[])(object)new Vector2[array.Length];
			int index = 0;
			for (int i = 0; i <= splits; i++)
			{
				MakeFace(ref index, triangles, num7 + i * 2 + 1, num7 + (i + 1) * 2 + 1, num7 + i * 2, num7 + (i + 1) * 2);
			}
			for (int j = 0; j <= splits; j++)
			{
				MakeFace(ref index, triangles, num7 + num3 + j * 2, num7 + num3 + (j + 1) * 2, num7 + num3 + j * 2 + 1, num7 + num3 + (j + 1) * 2 + 1);
			}
			for (int k = 0; k <= segments; k++)
			{
				float num9 = (float)k / (float)segments;
				float num10 = width / 2f;
				float num11 = 0.2f * num9 + 0.6f * Mathf.Pow(num9, 3f) + 0.2f * Mathf.Pow(num9, 10f);
				float num12 = (height - meshOffset.y) * num11;
				float num13 = Mathf.Lerp(0f, (float)Math.PI / 2f, num12);
				if (!rotateMesh)
				{
					num13 = (float)Math.PI / 2f;
				}
				float num14 = Mathf.Sin(num13) * num10;
				float num15 = Mathf.Cos(num13) * num10;
				if (k < segments)
				{
					MakeFace(ref index, triangles, num8 + k * 2, num8 + (k + 1) * 2, num8 + k * 2 + 1, num8 + (k + 1) * 2 + 1);
					MakeFace(ref index, triangles, num8 + num5 + k * 2 + 1, num8 + num5 + (k + 1) * 2 + 1, num8 + num5 + k * 2, num8 + num5 + (k + 1) * 2);
				}
				for (int l = 0; l <= splits + 1; l++)
				{
					float num16 = (float)l / (float)(splits + 1);
					float num17 = startLeft * (1f - num16) + startRight * num16;
					float num18 = 0f - curve.Evaluate(num16 * 2f - 1f) - width;
					float num19 = Mathf.Max(0f, num12 - num17) + num17;
					float num20 = Mathf.Lerp(-1f, 1f, num16);
					Vector3 val;
					Vector3 val2;
					if (useCurve)
					{
						float num21 = (relY + sideWidthInceaseOffset) * num9 / sideWidthIncease;
						val = new Vector3(num18 * (num9 + num21) + num14, num19 + num15, num20) + meshOffset;
						val2 = new Vector3(num18 * (num9 + num21) - num14, num19 - num15, num20) + meshOffset;
					}
					else
					{
						float num21 = (relY - 1f + height * num9) / sideWidthIncease;
						val = new Vector3(num18 * (1f + num21) + num14, num19 + num15, num20) + meshOffset;
						val2 = new Vector3(num18 * (1f + num21) - num14, num19 - num15, num20) + meshOffset;
					}
					array[GetTopVertice(k, l)] = val;
					array[GetBottomVertice(k, l)] = val2;
					if (k < segments && l < splits + 1)
					{
						MakeFace(ref index, triangles, GetTopVertice(k, l), GetTopVertice(k, l + 1), GetTopVertice(k + 1, l), GetTopVertice(k + 1, l + 1));
						MakeFace(ref index, triangles, GetBottomVertice(k, l), GetBottomVertice(k + 1, l), GetBottomVertice(k, l + 1), GetBottomVertice(k + 1, l + 1));
					}
					float num22;
					float num23;
					if (fixedUV)
					{
						num22 = Mathf.LerpUnclamped(((Rect)(ref uvRect)).xMin, ((Rect)(ref uvRect)).xMax, num16);
						num23 = Mathf.LerpUnclamped(((Rect)(ref uvRect)).yMin, ((Rect)(ref uvRect)).yMax, num9 * val.x);
					}
					else
					{
						num22 = Mathf.LerpUnclamped(((Rect)(ref uvRect)).xMin, ((Rect)(ref uvRect)).xMax, num16);
						num23 = Mathf.LerpUnclamped(((Rect)(ref uvRect)).yMin, ((Rect)(ref uvRect)).yMax, num9);
					}
					array2[GetTopVertice(k, l)] = new Vector2(num22, num23 + ((Rect)(ref uvRect)).height / 10f);
					array2[GetBottomVertice(k, l)] = new Vector2(num22, num23);
					if (k == 0)
					{
						array[num7 + l * 2] = val;
						array[num7 + l * 2 + 1] = val2;
						array2[num7 + l * 2] = new Vector2(num22, num23 + ((Rect)(ref uvRect)).height / 10f);
						array2[num7 + l * 2 + 1] = new Vector2(num22, num23);
					}
					if (k == segments)
					{
						array[num7 + num3 + l * 2] = val;
						array[num7 + num3 + l * 2 + 1] = val2;
						array2[num7 + num3 + l * 2] = new Vector2(num22, num23 + ((Rect)(ref uvRect)).height / 10f);
						array2[num7 + num3 + l * 2 + 1] = new Vector2(num22, num23);
					}
					if (l == 0)
					{
						array[num8 + k * 2] = val;
						array[num8 + k * 2 + 1] = val2;
						array2[num8 + k * 2] = new Vector2(num22 + ((Rect)(ref uvRect)).height / 10f, num23);
						array2[num8 + k * 2 + 1] = new Vector2(num22, num23);
					}
					if (l == splits + 1)
					{
						array[num8 + num5 + k * 2] = val;
						array[num8 + num5 + k * 2 + 1] = val2;
						array2[num8 + num5 + k * 2] = new Vector2(num22 + ((Rect)(ref uvRect)).height / 10f, num23);
						array2[num8 + num5 + k * 2 + 1] = new Vector2(num22, num23);
					}
				}
			}
			Mesh val3 = new Mesh();
			val3.vertices = array;
			val3.triangles = triangles;
			val3.uv = array2;
			val3.RecalculateNormals();
			((Component)this).GetComponent<MeshFilter>().mesh = val3;
			if (!Object.op_Implicit((Object)(object)hull))
			{
				hull = ((Component)this).GetComponent<Hull>();
			}
			Collider mainCollider = hull.mainCollider;
			MeshCollider val4 = (MeshCollider)(object)((mainCollider is MeshCollider) ? mainCollider : null);
			if (val4 != null)
			{
				val4.sharedMesh = GenerateBottomCollider(left + 0.1f, right + 0.1f, colliderOffset);
			}
			if (Object.op_Implicit((Object)(object)hull.sideCollider))
			{
				hull.sideCollider.sharedMesh = GenerateSideCollider(left, right, 0f, height);
			}
			if (Object.op_Implicit((Object)(object)hull.watermask))
			{
				hull.watermask.mesh = GenerateWatermask(left, right);
			}
		}

		private Mesh GenerateWatermask(float left, float right)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00d6: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int[] triangles = new int[18];
			int index = 0;
			float num;
			if (useCurve)
			{
				_ = (relY - 0.25f + height) / sideWidthIncease;
				num = (relY - 0.25f + height) / sideWidthIncease * 2f;
			}
			else
			{
				_ = (relY - 0.25f + height) / sideWidthIncease;
				num = (relY - 0.25f) / sideWidthIncease * 2f;
			}
			array[0] = new Vector3(0f, height, -1f);
			array[1] = new Vector3(0f, height, -0.333f);
			array[2] = new Vector3(0f, height, 0.333f);
			array[3] = new Vector3(0f, height, 1f);
			array[4] = new Vector3(0f - left - width / 2f - num, height, -1f);
			array[5] = new Vector3(0f - curve.Evaluate(-0.333f) - width - num, height, -0.333f);
			array[6] = new Vector3(0f - curve.Evaluate(0.333f) - width - num, height, 0.333f);
			array[7] = new Vector3(0f - right - width / 2f - num, height, 1f);
			MakeFace(ref index, triangles, 0, 1, 4, 5);
			MakeFace(ref index, triangles, 1, 2, 5, 6);
			MakeFace(ref index, triangles, 2, 3, 6, 7);
			Mesh val = new Mesh
			{
				vertices = array,
				triangles = triangles
			};
			val.RecalculateNormals();
			return val;
		}

		private Mesh GenerateBottomCollider(float left, float right, Vector3 offset)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00da: 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_00e0: 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_0101: 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_0107: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int[] triangles = new int[12];
			int index = 0;
			float num;
			float num2;
			if (useCurve)
			{
				num = (relY - 0.25f + height) / sideWidthIncease * 2f;
				num2 = (relY - 0.25f + height) / sideWidthIncease * 2f;
			}
			else
			{
				num = (relY - 0.25f + height) / sideWidthIncease * 2f;
				num2 = (relY - 0.25f) / sideWidthIncease * 2f;
			}
			array[0] = new Vector3(0f, width / 2f, -1f) + offset;
			array[1] = new Vector3(0f, width / 2f, 1f) + offset;
			array[2] = new Vector3(0f - left - num, width / 2f, -1f) + offset;
			array[3] = new Vector3(0f - right - num, width / 2f, 1f) + offset;
			array[4] = new Vector3(0f, (0f - width) / 2f, -1f) + offset;
			array[5] = new Vector3(0f, (0f - width) / 2f, 1f) + offset;
			array[6] = new Vector3(0f - left - num2, (0f - width) / 2f, -1f) + offset;
			array[7] = new Vector3(0f - right - num2, (0f - width) / 2f, 1f) + offset;
			MakeFace(ref index, triangles, 0, 1, 2, 3);
			MakeFace(ref index, triangles, 4, 5, 6, 7);
			Mesh val = new Mesh
			{
				vertices = array,
				triangles = triangles
			};
			val.RecalculateNormals();
			return val;
		}

		private Mesh GenerateSideCollider(float left, float right, float startHeight, float endHeight)
		{
			//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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			int[] triangles = new int[12];
			int index = 0;
			float num = width / 2f;
			float num2;
			float num3;
			if (useCurve)
			{
				num2 = (relY - 0.25f + height) / sideWidthIncease * 2f;
				num3 = (relY - 0.25f + height) / sideWidthIncease * 2f;
			}
			else
			{
				num2 = (relY - 0.25f + height) / sideWidthIncease * 2f;
				num3 = (relY - 0.25f) / sideWidthIncease * 2f;
			}
			array[0] = new Vector3(0f - num3 + num - left, startHeight, -1f);
			array[1] = new Vector3(0f - num3 + num - right, startHeight, 1f);
			array[2] = new Vector3(0f - num2 + num - left, endHeight, -1f);
			array[3] = new Vector3(0f - num2 + num - right, endHeight, 1f);
			array[4] = new Vector3(0f - num3 - num - left, startHeight, -1f);
			array[5] = new Vector3(0f - num3 - num - right, startHeight, 1f);
			array[6] = new Vector3(0f - num2 - num - left, endHeight, -1f);
			array[7] = new Vector3(0f - num2 - num - right, endHeight, 1f);
			MakeFace(ref index, triangles, 0, 1, 2, 3);
			MakeFace(ref index, triangles, 4, 5, 6, 7);
			Mesh val = new Mesh
			{
				vertices = array,
				triangles = triangles
			};
			val.RecalculateNormals();
			return val;
		}
	}
	public class Hull : ShipPart
	{
		public MeshCollider sideCollider;

		public MeshFilter watermask;

		public Rib leftRib;

		public Rib rightRib;

		public Transform outerSnappoint;

		public float height = 0.9f;

		public override float Weight => weight * Size;

		public float Size
		{
			get
			{
				if (Object.op_Implicit((Object)(object)leftRib) && Object.op_Implicit((Object)(object)rightRib))
				{
					return (leftRib.size + rightRib.size) / 2f;
				}
				if (Object.op_Implicit((Object)(object)leftRib))
				{
					return (leftRib.size + 1f) / 2f;
				}
				if (Object.op_Implicit((Object)(object)rightRib))
				{
					return (1f + rightRib.size) / 2f;
				}
				return 2f;
			}
		}

		public event Action OnChange;

		protected override void Start()
		{
			base.Start();
			((MonoBehaviour)this).InvokeRepeating("UpdateHull", 0f, 3f);
		}

		private void UpdateHull()
		{
			//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_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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: 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_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			Vector3 forward = ((Component)this).transform.forward;
			Rib rib = Rib.FindRib(position + forward * -1f - base.Forward * 0.5f);
			Rib rib2 = Rib.FindRib(position + forward * 1f - base.Forward * 0.5f);
			if (!((Object)(object)rib != (Object)(object)leftRib) && !((Object)(object)rib2 != (Object)(object)rightRib))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)leftRib))
			{
				leftRib.OnChange -= this.OnChange;
			}
			if (Object.op_Implicit((Object)(object)rightRib))
			{
				rightRib.OnChange -= this.OnChange;
			}
			if (Object.op_Implicit((Object)(object)nview) && !nview.GetZDO().GetBool("MS_HasCheckedRotation", false))
			{
				nview.GetZDO().Set("MS_HasCheckedRotation", true);
				if (WrongDirection(rib, rib2))
				{
					leftRib = rib2;
					rightRib = rib;
					Transform transform = ((Component)this).transform;
					transform.rotation *= Quaternion.Euler(0f, 180f, 0f);
					Transform transform2 = ((Component)this).transform;
					transform2.position += base.Forward * Size;
					if (Object.op_Implicit((Object)(object)base.CustomShip))
					{
						nview.GetZDO().Set(ZDOVars.s_relPosHash, ((Component)this).transform.localPosition);
						nview.GetZDO().Set(ZDOVars.s_relRotHash, ((Component)this).transform.localRotation);
					}
				}
				else
				{
					leftRib = rib;
					rightRib = rib2;
				}
			}
			else
			{
				leftRib = rib;
				rightRib = rib2;
			}
			if (Object.op_Implicit((Object)(object)leftRib))
			{
				leftRib.OnChange += this.OnChange;
			}
			if (Object.op_Implicit((Object)(object)rightRib))
			{
				rightRib.OnChange += this.OnChange;
			}
			outerSnappoint.localPosition = new Vector3(0f - Size, height, 0f);
			this.OnChange?.Invoke();
		}

		private bool WrongDirection(Rib newLeftRib, Rib newRightRib)
		{
			if (!Object.op_Implicit((Object)(object)newLeftRib) && !Object.op_Implicit((Object)(object)newRightRib))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)newLeftRib) || newLeftRib.SameDirection(this))
			{
				if (Object.op_Implicit((Object)(object)newRightRib))
				{
					return !newRightRib.SameDirection(this);
				}
				return false;
			}
			return true;
		}

		private void OnDrawGizmos()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			Vector3 position = ((Component)this).transform.position;
			Vector3 forward = ((Component)this).transform.forward;
			Vector3 val = -((Component)this).transform.right;
			Gizmos.DrawSphere(position + forward * -1f + val * 0.5f, 0.1f);
			Gizmos.DrawSphere(position + forward * 1f + val * 0.5f, 0.1f);
		}

		private void UpdateCollider()
		{
			//IL_00b4: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_013d: 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_014c: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val;
			float num;
			float num2;
			if (Object.op_Implicit((Object)(object)leftRib) && Object.op_Implicit((Object)(object)rightRib))
			{
				val = (GetRibCenter(leftRib, 0f) + GetRibCenter(rightRib, 0f)) / 2f;
				num = (leftRib.size + rightRib.size) / 2f;
				num2 = Mathf.Atan((leftRib.size - rightRib.size) / 2f) * 57.29578f;
			}
			else if (Object.op_Implicit((Object)(object)leftRib))
			{
				val = (GetRibCenter(leftRib, 0f) + GetRibCenter(leftRib, 2f)) / 2f;
				num = leftRib.size;
				num2 = Mathf.Atan((leftRib.size - 0f) / 2f) * 57.29578f;
			}
			else if (Object.op_Implicit((Object)(object)rightRib))
			{
				val = (GetRibCenter(rightRib, 0f) + GetRibCenter(rightRib, -2f)) / 2f;
				num = rightRib.size;
				num2 = Mathf.Atan((0f - rightRib.size) / 2f) * 57.29578f;
			}
			else
			{
				val = ((Component)this).transform.position;
				num = 2f;
				num2 = 0f;
			}
			float num3 = Mathf.Atan(num / height) * 57.29578f - 90f;
			((Component)mainCollider).transform.position = val + Vector3.up * 0.35f;
			((Component)mainCollider).transform.localScale = new Vector3(num, 1f, 1f);
			((Component)mainCollider).transform.localRotation = Quaternion.Euler(0f, num2, num3);
		}

		private Vector3 GetRibCenter(Rib rib, float offsetZ)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)rib).transform.TransformPoint((0f - rib.size) / 2f, 0f, offsetZ);
		}
	}
	public class Keel : ShipPart
	{
	}
	public class Rib : ShipPart
	{
		public float size = 2f;

		public Rib leftRib;

		public Rib rightRib;

		private static List<Rib> ribs = new List<Rib>();

		public Vector3 EndPosition => ((Component)this).transform.position - ((Component)this).transform.right * size;

		public override float Weight => weight * size;

		public event Action OnChange;

		protected override void Awake()
		{
			base.Awake();
			ribs.Add(this);
			((MonoBehaviour)this).InvokeRepeating("UpdateRib", 0f, 3f);
		}

		private void OnDestroy()
		{
			ribs.Remove(this);
		}

		private void UpdateRib()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			Vector3 forward = ((Component)this).transform.forward;
			Vector3 val = -((Component)this).transform.right;
			Rib rib = FindRib(position + forward * -2f + val * 0.5f);
			Rib rib2 = FindRib(position + forward * 2f + val * 0.5f);
			if ((Object)(object)rib != (Object)(object)leftRib || (Object)(object)rib2 != (Object)(object)rightRib)
			{
				leftRib = rib;
				rightRib = rib2;
				this.OnChange?.Invoke();
			}
		}

		public static Rib FindRib(Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0049: Unknown result type (might be due to invalid IL or missing references)
			List<Rib> list = new List<Rib>();
			foreach (Rib rib in ribs)
			{
				Vector3 val = ((Component)rib).transform.InverseTransformPoint(position);
				if (val.x <= 0f && Mathf.Abs(val.z) <= 0.2f)
				{
					list.Add(rib);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			list.Sort(delegate(Rib a, Rib b)
			{
				//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)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: 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_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = ((Component)a).transform.position - a.Forward;
				Vector3 val3 = ((Component)b).transform.position - b.Forward;
				Vector3 val4 = val2 - position;
				float magnitude = ((Vector3)(ref val4)).magnitude;
				val4 = val3 - position;
				float magnitude2 = ((Vector3)(ref val4)).magnitude;
				return magnitude.CompareTo(magnitude2);
			});
			return list[0];
		}

		private void OnDrawGizmos()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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 = -((Component)this).transform.right;
			Gizmos.color = Color.green;
			Gizmos.DrawSphere(((Component)this).transform.position + val * 0.5f, 0.1f);
			Gizmos.color = Color.cyan;
			Gizmos.DrawSphere(((Component)this).transform.position - val * 0.5f + val * size, 0.1f);
		}

		public bool SameDirection(Hull hull)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Dot(hull.Forward, base.Forward) >= 0.9f;
		}
	}
	public class Rudder : ShipPart, Interactable, Hoverable
	{
		public Transform rudder;

		public Transform attachPoint;

		private Rib rightRib;

		protected override void Start()
		{
			base.Start();
			((MonoBehaviour)this).InvokeRepeating("UpdateRudder", 0f, 3f);
		}

		private void Update()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)base.CustomShip))
			{
				rudder.localRotation = base.CustomShip.ship.m_rudderObject.transform.localRotation;
			}
		}

		private void UpdateRudder()
		{
			//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_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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Rib rib = Rib.FindRib(((Component)this).transform.position + ((Component)this).transform.right * 1f);
			if ((Object)(object)rib != (Object)(object)rightRib)
			{
				rightRib = rib;
				if (Object.op_Implicit((Object)(object)rudder) && Object.op_Implicit((Object)(object)rightRib))
				{
					Vector3 localPosition = ((Component)rudder).transform.localPosition;
					localPosition.x = rightRib.size + 0.2f;
					((Component)rudder).transform.localPosition = localPosition;
				}
			}
		}

		public void SetShipControls(ShipControlls shipControls)
		{
			//IL_000c: 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_003d: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			((Component)shipControls).transform.position = ((Component)this).transform.position;
			((Component)shipControls).transform.rotation = ((Component)this).transform.rotation;
			((Component)shipControls.m_attachPoint).transform.position = attachPoint.position;
			((Component)shipControls.m_attachPoint).transform.rotation = attachPoint.rotation;
			shipControls.m_ship.m_stearForceOffset = base.CustomShip.ToLocalPosition((ShipPart)this).z;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (base.CustomShip.GetPartsOfType<Rudder>().Count > 1)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$MS_CustomShips_MultipleRudder", 0, (Sprite)null);
				return false;
			}
			return base.CustomShip.shipControls.Interact(user, hold, alt);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			if (base.CustomShip.GetPartsOfType<Rudder>().Count > 1)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$MS_CustomShips_MultipleRudder", 0, (Sprite)null);
				return false;
			}
			return base.CustomShip.shipControls.UseItem(user, item);
		}

		public string GetHoverText()
		{
			return base.CustomShip.shipControls.GetHoverText();
		}

		public string GetHoverName()
		{
			return base.CustomShip.shipControls.GetHoverName();
		}
	}
	public class Sail : ShipPart
	{
		public float force = 0.03f;

		public Transform mast;

		public Transform sail;

		public Cloth sailCloth;

		private bool sailWasInPosition;

		private void Update()
		{
			//IL_002e: 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)
			if (Object.op_Implicit((Object)(object)base.CustomShip))
			{
				((Component)mast).transform.rotation = base.CustomShip.ship.m_mastObject.transform.rotation;
				((Component)sail).transform.localScale = base.CustomShip.ship.m_sailObject.transform.localScale;
				sailCloth.enabled = base.CustomShip.ship.m_sailCloth.enabled;
				bool flag = base.CustomShip.ship.m_sailWasInPosition;
				if (!sailWasInPosition && flag)
				{
					Utils.RecreateComponent(ref sailCloth);
				}
				sailWasInPosition = flag;
			}
		}
	}
	public abstract class ShipPart : MonoBehaviour
	{
		public float weight = 5f;

		public float buoyancy = 1f;

		private CustomShip customShip;

		protected ZNetView nview;

		private ZInt connectedShip;

		public Collider mainCollider;

		protected List<Transform> snapPoints = new List<Transform>();

		private static Collider[] tmpColliders = (Collider[])(object)new Collider[1000];

		public CustomShip CustomShip
		{
			get
			{
				return customShip;
			}
			set
			{
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: 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)
				customShip = value;
				if (Object.op_Implicit((Object)(object)customShip))
				{
					customShip.AddPart(this);
					connectedShip.Set(customShip.uniqueID.Get());
					if (Application.isEditor)
					{
						Debug.LogWarning((object)"Application running in Editor, skipping setting CustomShip");
					}
					else if (!nview.GetZDO().GetBool("MS_HasRelativePosition", false))
					{
						nview.GetZDO().Set(ZDOVars.s_relPosHash, ((Component)this).transform.localPosition);
						nview.GetZDO().Set(ZDOVars.s_relRotHash, ((Component)this).transform.localRotation);
						nview.GetZDO().Set("MS_HasRelativePosition", true);
					}
					else
					{
						Vector3 localPosition = default(Vector3);
						nview.GetZDO().GetVec3(ZDOVars.s_relPosHash, ref localPosition);
						Quaternion localRotation = default(Quaternion);
						nview.GetZDO().GetQuaternion(ZDOVars.s_relRotHash, ref localRotation);
						((Component)this).transform.localPosition = localPosition;
						((Component)this).transform.localRotation = localRotation;
					}
				}
			}
		}

		public Vector3 Forward => ((Component)this).transform.right;

		public virtual float Weight => weight;

		protected virtual void Awake()
		{
			((Component)this).GetComponent<Piece>().GetSnapPoints(snapPoints);
			nview = ((Component)this).GetComponent<ZNetView>();
			connectedShip = new ZInt("MS_ConnectedShip", 0, nview);
		}

		protected virtual void Start()
		{
			((MonoBehaviour)this).InvokeRepeating("SearchShip", 0f, 3f);
			((MonoBehaviour)this).InvokeRepeating("SetPosition", 0f, 5f);
		}

		private void SearchShip()
		{
			if (Object.op_Implicit((Object)(object)CustomShip))
			{
				return;
			}
			CustomShip = ((Component)((Component)this).transform).GetComponentInParent<CustomShip>();
			if (!Object.op_Implicit((Object)(object)CustomShip))
			{
				CustomShip customShip = CustomShip.FindCustomShip(connectedShip.Get());
				if (Object.op_Implicit((Object)(object)customShip))
				{
					CustomShip = customShip;
				}
			}
		}

		private void SetPosition()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (nview.IsOwner())
			{
				nview.GetZDO().SetPosition(((Component)this).transform.position);
			}
		}

		public void CreateCustomShip()
		{
			//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)
			GameObject val = Object.Instantiate<GameObject>(Main.customShip.PiecePrefab, ((Component)this).transform.position, Quaternion.identity);
			CustomShip = val.GetComponent<CustomShip>();
		}

		public static ShipPart FindNearest(CustomShip ship, Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(position, 4f, tmpColliders, LayerMask.GetMask(new string[1] { "piece" }));
			float num2 = float.MaxValue;
			ShipPart result = null;
			for (int i = 0; i < num; i++)
			{
				ShipPart componentInParent = ((Component)tmpColliders[i]).GetComponentInParent<ShipPart>();
				if (Object.op_Implicit((Object)(object)componentInParent) && Object.op_Implicit((Object)(object)componentInParent.CustomShip) && (!Object.op_Implicit((Object)(object)ship) || !((Object)(object)componentInParent.CustomShip != (Object)(object)ship)))
				{
					float num3 = Vector3.Distance(((Component)componentInParent).transform.position, position);
					if (num3 < num2)
					{
						num2 = num3;
						result = componentInParent;
					}
				}
			}
			return result;
		}
	}
}
namespace CustomShips.Patches
{
	[HarmonyPatch]
	public static class ZDOManPatch
	{
		private static Dictionary<int, ZDO> ships = new Dictionary<int, ZDO>();

		private static Dictionary<int, List<ZDO>> shipPieces = new Dictionary<int, List<ZDO>>();

		private static Queue<ZDO> newZDOs = new Queue<ZDO>();

		[HarmonyPatch(typeof(ZDOMan), "Load")]
		[HarmonyPostfix]
		public static void Load(ZDOMan __instance)
		{
			foreach (ZDO value in __instance.m_objectsByID.Values)
			{
				RegisterZDO(value);
			}
			foreach (int key in ships.Keys)
			{
				CheckShip(key);
			}
			__instance.m_onZDODestroyed = (Action<ZDO>)Delegate.Combine(__instance.m_onZDODestroyed, new Action<ZDO>(OnZDODestroyed));
		}

		[HarmonyPatch(typeof(ZDOMan), "ShutDown")]
		[HarmonyPostfix]
		public static void OnShutDown()
		{
			ships.Clear();
			shipPieces.Clear();
			newZDOs.Clear();
		}

		[HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[]
		{
			typeof(ZDOID),
			typeof(Vector3),
			typeof(int)
		})]
		[HarmonyPostfix]
		public static void OnCreateNewZDO(ref ZDO __result)
		{
			if (ZNet.instance.IsServer())
			{
				newZDOs.Enqueue(__result);
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "Update")]
		[HarmonyPostfix]
		public static void ZDOManUpdate()
		{
			while (newZDOs.Count > 0)
			{
				RegisterZDO(newZDOs.Dequeue());
			}
		}

		private static void CheckShip(int targetShip)
		{
			if (!HasAnyPiece(targetShip) && ships.TryGetValue(targetShip, out var value))
			{
				Logger.LogInfo((object)$"Deleting empty ship {value}");
				if (!value.IsOwner())
				{
					value.SetOwner(ZDOMan.GetSessionID());
				}
				ZDOMan.instance.DestroyZDO(value);
			}
		}

		private static bool HasAnyPiece(int targetShip)
		{
			if (shipPieces.TryGetValue(targetShip, out var value))
			{
				return value.Count > 0;
			}
			return false;
		}

		private static void OnZDODestroyed(ZDO zdo)
		{
			if (Main.IsShipPiece(zdo))
			{
				int @int = zdo.GetInt("MS_UniqueID", 0);
				ships.Remove(@int);
			}
			if (Main.IsShipPiece(zdo))
			{
				int int2 = zdo.GetInt("MS_ConnectedShip", 0);
				if (shipPieces.TryGetValue(int2, out var value))
				{
					value.Remove(zdo);
				}
				else
				{
					Logger.LogWarning((object)$"ship {int2} for {zdo} not registered");
				}
				CheckShip(int2);
			}
		}

		private static void RegisterZDO(ZDO zdo)
		{
			if (Main.IsCustomShip(zdo))
			{
				ships.Add(zdo.GetInt("MS_UniqueID", 0), zdo);
			}
			if (Main.IsShipPiece(zdo))
			{
				int @int = zdo.GetInt("MS_ConnectedShip", 0);
				if (shipPieces.TryGetValue(@int, out var value))
				{
					value.Add(zdo);
					return;
				}
				shipPieces[@int] = new List<ZDO> { zdo };
			}
		}
	}
	[HarmonyPatch]
	public class PlacementPatch
	{
		private static CustomShip snapShip;

		private static ShipPart snapShipPart;

		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		[HarmonyPostfix]
		public static void SetupPlacementGhostPatch(Player __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_placementGhost))
			{
				DynamicMesh[] componentsInChildren = __instance.m_placementGhost.GetComponentsInChildren<DynamicMesh>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				ShipPart[] componentsInChildren2 = __instance.m_placementGhost.GetComponentsInChildren<ShipPart>();
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren2[i]);
				}
				CustomShip[] componentsInChildren3 = __instance.m_placementGhost.GetComponentsInChildren<CustomShip>();
				for (int i = 0; i < componentsInChildren3.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren3[i]);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> PlacePieceTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0036: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.IsCall("Object", "Instantiate")), (string)null)
			}).ThrowIfInvalid("Could not find Object.Instantiate call").InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlacementPatch), "BeforePlacePiece", (Type[])null, (Type[])null))
			})
				.Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlacementPatch), "AfterPlacePiece", (Type[])null, (Type[])null))
				})
				.Instructions();
		}

		private static void BeforePlacePiece()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Main.IsShipPiece(localPlayer.m_placementGhost))
			{
				if (Object.op_Implicit((Object)(object)localPlayer.m_hoveringPiece))
				{
					snapShip = ((Component)localPlayer.m_hoveringPiece).GetComponentInParent<CustomShip>();
				}
				Transform val = default(Transform);
				Transform val2 = default(Transform);
				localPlayer.FindClosestSnapPoints(localPlayer.m_placementGhost.transform, 0.5f, ref val, ref val2, localPlayer.m_tempPieces);
				ShipPart shipPart = default(ShipPart);
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.parent) && ((Component)val2.parent).TryGetComponent<ShipPart>(ref shipPart))
				{
					snapShipPart = shipPart;
					snapShip = shipPart.CustomShip;
				}
			}
		}

		private static GameObject AfterPlacePiece(GameObject piece)
		{
			ShipPart shipPart = default(ShipPart);
			if (Object.op_Implicit((Object)(object)piece) && Main.IsShipPiece(piece) && piece.TryGetComponent<ShipPart>(ref shipPart))
			{
				if (Object.op_Implicit((Object)(object)snapShip))
				{
					shipPart.CustomShip = snapShip;
				}
				else
				{
					shipPart.CreateCustomShip();
				}
			}
			snapShip = null;
			return piece;
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> UpdatePlacementGhostRotationTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 1], AccessTools.Field(typeof(Player), "m_placeRotationDegrees"), false) && list[i + 2].opcode == OpCodes.Ldarg_0 && CodeInstructionExtensions.LoadsField(list[i + 3], AccessTools.Field(typeof(Player), "m_placeRotation"), false) && list[i + 4].opcode == OpCodes.Conv_R4 && list[i + 5].opcode == OpCodes.Mul && list[i + 6].opcode == OpCodes.Ldc_R4 && list[i + 7].CallReturns(typeof(Quaternion)))
				{
					if (list[i + 8].opcode == OpCodes.Stloc_S)
					{
						num = i + 8;
						break;
					}
					if (list[i + 8].CallReturns(typeof(Quaternion)) && list[i + 9].opcode == OpCodes.Stloc_S)
					{
						num = i + 9;
						break;
					}
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("Could not find rotation calculation");
			}
			object operand;
			return new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null).Advance(num + 1).GetOperand(out operand).Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_S, operand),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlacementPatch), "PieceRotation", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Stloc_S, operand)
				})
				.Instructions();
		}

		private static Quaternion PieceRotation(Player player, Quaternion rotation)
		{
			//IL_0055: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject placementGhost = player.m_placementGhost;
			if (Object.op_Implicit((Object)(object)placementGhost) && Main.IsShipPiece(placementGhost))
			{
				Vector3 position = default(Vector3);
				Vector3 val = default(Vector3);
				Piece val2 = default(Piece);
				Heightmap val3 = default(Heightmap);
				Collider val4 = default(Collider);
				player.PieceRayTest(ref position, ref val, ref val2, ref val3, ref val4, false);
				ShipPart shipPart = ShipPart.FindNearest(null, position);
				if (Object.op_Implicit((Object)(object)shipPart))
				{
					return ((Component)shipPart.CustomShip).transform.rotation * rotation;
				}
				return rotation;
			}
			return rotation;
		}

		[HarmonyPatch(typeof(Player), "PieceRayTest")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> AllowShipRigidbodyTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(RaycastHit), "collider");
			MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(Collider), "attachedRigidbody");
			MethodInfo methodInfo3 = AccessTools.Method(typeof(Object), "op_Implicit", (Type[])null, (Type[])null);
			List<CodeInstruction> list = instructions.ToList();
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 1], methodInfo) && CodeInstructionExtensions.Calls(list[i + 2], methodInfo2) && CodeInstructionExtensions.Calls(list[i + 3], methodInfo3))
				{
					num = i;
					break;
				}
				if (list[i].opcode == OpCodes.Ldloca_S && CodeInstructionExtensions.Calls(list[i + 1], methodInfo) && list[i + 2].IsCall("ValheimRAFT_Patch", "AttachRigidbodyMovableBase") && CodeInstructionExtensions.Calls(list[i + 3], methodInfo3))
				{
					num = i;
					break;
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("Could not find rigidbody load");
			}
			object operand;
			return new CodeMatcher((IEnumerable<CodeInstruction>)list, (ILGenerator)null).Advance(num + 1).GetOperand(out operand).Advance(4)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
				{
					new CodeInstruction(OpCodes.Ldloca_S, operand),
					new CodeInstruction(OpCodes.Call, (object)methodInfo),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlacementPatch), "DenyPieceRay", (Type[])null, (Type[])null))
				})
				.Instructions();
		}

		private static bool DenyPieceRay(bool hasRigidbody, Collider hit)
		{
			if (!Main.IsShipPiece(Player.m_localPlayer.m_placementGhost))
			{
				return hasRigidbody;
			}
			Piece val = (Object.op_Implicit((Object)(object)hit) ? ((Component)hit).GetComponentInParent<Piece>() : null);
			if (Object.op_Implicit((Object)(object)val) && Main.IsShipPiece(((Component)val).gameObject))
			{
				return false;
			}
			return hasRigidbody;
		}
	}
}
namespace CustomShips.Helper
{
	public static class CodeMatcherExtensions
	{
		public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position)
		{
			position = codeMatcher.Pos;
			return codeMatcher;
		}

		public static CodeMatcher AddLabel(this CodeMatcher codeMatcher, out Label label)
		{
			label = default(Label);
			codeMatcher.AddLabels((IEnumerable<Label>)new Label[1] { label });
			return codeMatcher;
		}

		public static CodeMatcher GetOperand(this CodeMatcher codeMatcher, out object operand)
		{
			operand = codeMatcher.Operand;
			return codeMatcher;
		}

		public static bool IsCall(this CodeInstruction i, string declaringType, string name)
		{
			if ((i.opcode == OpCodes.Callvirt || i.opcode == OpCodes.Call) && i.operand is MethodInfo methodInfo && methodInfo.DeclaringType?.Name == declaringType)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		public static bool CallReturns(this CodeInstruction i, Type returnType)
		{
			if ((i.opcode == OpCodes.Callvirt || i.opcode == OpCodes.Call) && i.operand is MethodInfo methodInfo)
			{
				return methodInfo.ReturnType == returnType;
			}
			return false;
		}
	}
}