Decompiled source of BuildOnShip v4.0.12

BuildOnShip.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ShipBuildingMod
{
	internal static class ColliderGeometry
	{
		internal static bool SupportsClosestPoint(Collider collider)
		{
			if (!(collider is BoxCollider) && !(collider is SphereCollider) && !(collider is CapsuleCollider))
			{
				MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
				if (val != null)
				{
					return val.convex;
				}
				return false;
			}
			return true;
		}

		internal static Vector3 ClosestPointForProximity(Collider collider, Vector3 point)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!SupportsClosestPoint(collider))
			{
				Bounds bounds = collider.bounds;
				return ((Bounds)(ref bounds)).ClosestPoint(point);
			}
			return collider.ClosestPoint(point);
		}
	}
	public static class MaterialFixer
	{
		private static readonly int TriplanarLocalPos = Shader.PropertyToID("_TriplanarLocalPos");

		private static readonly int RippleDistance = Shader.PropertyToID("_RippleDistance");

		private static readonly int ValueNoise = Shader.PropertyToID("_ValueNoise");

		private static readonly Dictionary<Material, Material> s_fixedMaterialCache = new Dictionary<Material, Material>();

		public static void FixPieceMaterials(ZNetView netView)
		{
			if (ShipBuildPlugin.IsDedicatedServer || (Object)(object)netView == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)netView).GetComponentsInChildren<Renderer>(false);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent<Switch>() != (Object)null || (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer)))
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				if (sharedMaterials == null || sharedMaterials.Length == 0)
				{
					continue;
				}
				bool flag = false;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = FixMaterial(sharedMaterials[j]);
					if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)sharedMaterials[j])
					{
						sharedMaterials[j] = val2;
						flag = true;
					}
				}
				if (flag)
				{
					val.sharedMaterials = sharedMaterials;
				}
			}
		}

		private static Material FixMaterial(Material original)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			if ((Object)(object)original == (Object)null)
			{
				return null;
			}
			if (!original.HasProperty(RippleDistance) && !original.HasProperty(ValueNoise) && !original.HasProperty(TriplanarLocalPos))
			{
				return original;
			}
			string text = (((Object)(object)original.shader != (Object)null) ? ((Object)original.shader).name : "");
			if (text.Contains("Vegetation") || text.Contains("Rock") || text.Contains("Terrain"))
			{
				return original;
			}
			if (s_fixedMaterialCache.TryGetValue(original, out var value))
			{
				return value;
			}
			Material val = new Material(original);
			if (val.HasProperty(ValueNoise))
			{
				val.SetFloat(ValueNoise, 0f);
			}
			if (val.HasProperty(RippleDistance))
			{
				val.SetFloat(RippleDistance, 0f);
			}
			if (val.HasProperty(TriplanarLocalPos))
			{
				val.SetFloat(TriplanarLocalPos, 1f);
			}
			s_fixedMaterialCache[original] = val;
			return val;
		}
	}
	public static class BuildContext
	{
		public static Ship TargetShip;
	}
	[HarmonyPatch]
	public static class Player_Patches
	{
		private struct GhostOriginalFlags
		{
			public bool GroundPiece;

			public bool GroundOnly;

			public bool CultivatedGroundOnly;

			public bool VegetationGroundOnly;

			public bool NotOnWood;

			public bool NotOnTiltingSurface;

			public bool NoInWater;

			public bool NoClipping;

			public bool Active;
		}

		private static readonly FieldRef<Character, Vector3> MoveDirRef = AccessTools.FieldRefAccess<Character, Vector3>("m_moveDir");

		private static readonly FieldRef<Player, int> ManualSnapPointRef = AccessTools.FieldRefAccess<Player, int>("m_manualSnapPoint");

		private static readonly FieldRef<Player, int> PlaceRotationRef = AccessTools.FieldRefAccess<Player, int>("m_placeRotation");

		private static readonly FieldRef<Player, PlacementStatus> PlacementStatusRef = AccessTools.FieldRefAccess<Player, PlacementStatus>("m_placementStatus");

		private static readonly FieldRef<Player, GameObject> PlacementGhostRef = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost");

		private static readonly FieldRef<Player, int> PlaceRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask");

		private static readonly FieldRef<Player, int> PlaceWaterRayMaskRef = AccessTools.FieldRefAccess<Player, int>("m_placeWaterRayMask");

		private static readonly FieldRef<Player, RaycastHit[]> RaycastHoverHitsRef = AccessTools.FieldRefAccess<Player, RaycastHit[]>("m_raycastHoverHits");

		private static readonly MethodInfo s_eulerMethod = AccessTools.Method(typeof(Quaternion), "Euler", new Type[3]
		{
			typeof(float),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo s_getGhostRotationMethod = AccessTools.Method(typeof(Player_Patches), "GetGhostRotation", (Type[])null, (Type[])null);

		private static readonly FieldInfo s_placeRotationField = AccessTools.Field(typeof(Player), "m_placeRotation");

		private static Vector3 s_lockedLocalPos = Vector3.zero;

		private static Quaternion s_lockedLocalRot = Quaternion.identity;

		private static Ship s_lastShip = null;

		private static string s_lastGhostPrefabName = "";

		private static int s_lastPlaceRot = -1;

		private static int s_lastSnapIndex = -2;

		private static bool s_hasLockedPosition = false;

		private static Piece s_hoveredTargetPiece = null;

		private static GhostOriginalFlags s_originalGhostFlags;

		[HarmonyPatch(typeof(Player), "CreateTombStone")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CreateTombStone_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo setup = AccessTools.Method(typeof(TombStone), "Setup", (Type[])null, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(Player_Patches), "SetupShipTombStone", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, setup))
				{
					yield return CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Ldarg_0, (object)null), instruction);
					instruction.opcode = OpCodes.Call;
					instruction.operand = replacement;
				}
				yield return instruction;
			}
		}

		private static void SetupShipTombStone(TombStone stone, string ownerName, long ownerID, Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			stone.Setup(ownerName, ownerID);
			if (!ShipAttachmentPhysics.TryFindSurface(((Component)player).transform.position + Vector3.up * 0.5f, ((Component)player).transform, 3f, out var surface, out var container))
			{
				return;
			}
			Ship shipComponent = container.ShipComponent;
			if (!((Object)(object)shipComponent == (Object)null))
			{
				ZNetView component = ((Component)stone).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner() && !((Object)(object)container == (Object)null))
				{
					Vector3 localPos = ((Component)shipComponent).transform.InverseTransformPoint(((RaycastHit)(ref surface)).point + Vector3.up * 0.1f);
					Quaternion localRot = Quaternion.Inverse(((Component)shipComponent).transform.rotation) * ((Component)stone).transform.rotation;
					container.RegisterPiece(component, localPos, localRot);
					component.GetZDO().Set(ZDOVars.s_spawnPoint, ((Component)stone).transform.position);
					component.GetZDO().Set(ZDOVars.s_inWater, false);
				}
			}
		}

		[HarmonyPatch(typeof(Piece), "GetSnapPoints", new Type[]
		{
			typeof(Vector3),
			typeof(float),
			typeof(List<Transform>),
			typeof(List<Piece>)
		})]
		[HarmonyPostfix]
		private static void Piece_GetSnapPoints_Postfix(Vector3 point, float radius, List<Transform> points, List<Piece> pieces)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (ShipBuildPlugin.IsDedicatedServer)
			{
				return;
			}
			Ship targetShip = BuildContext.TargetShip;
			if (!((Object)(object)targetShip != (Object)null))
			{
				return;
			}
			ShipPiecesContainer component = ((Component)targetShip).GetComponent<ShipPiecesContainer>();
			if (!((Object)(object)component != (Object)null) || component.DeckSnapPoints.Count <= 0)
			{
				return;
			}
			for (int i = 0; i < component.DeckSnapPoints.Count; i++)
			{
				Transform val = component.DeckSnapPoints[i];
				if ((Object)(object)val != (Object)null && Vector3.Distance(point, val.position) <= radius)
				{
					points.Add(val);
				}
			}
			Piece component2 = ((Component)targetShip).GetComponent<Piece>();
			if ((Object)(object)component2 != (Object)null && !pieces.Contains(component2))
			{
				pieces.Add(component2);
			}
		}

		[HarmonyPatch(typeof(Player), "TestGhostClipping")]
		[HarmonyPrefix]
		private static bool TestGhostClipping_Prefix(Player __instance, GameObject ghost, float maxPenetration, ref bool __result)
		{
			if ((Object)(object)BuildContext.TargetShip != (Object)null)
			{
				__result = false;
				return false;
			}
			return true;
		}

		public static Quaternion GetGhostRotation(float x, float y, float z)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.Euler(x, y, z);
			Ship targetShip = BuildContext.TargetShip;
			if ((Object)(object)targetShip != (Object)null)
			{
				return ((Component)targetShip).transform.rotation * val;
			}
			return val;
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> UpdatePlacementGhost_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Ldfld) || !(list[i].operand is FieldInfo { Name: "m_placeRotation" }))
				{
					continue;
				}
				for (int j = i + 1; j < Math.Min(i + 8, list.Count); j++)
				{
					if (list[j].opcode == OpCodes.Call && list[j].operand is MethodInfo { Name: "Euler" })
					{
						list[j] = new CodeInstruction(OpCodes.Call, (object)s_getGhostRotationMethod);
						return list;
					}
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(Player), "PieceRayTest")]
		[HarmonyPrefix]
		private static bool PieceRayTest_Prefix(Player __instance, ref bool __result, out Vector3 point, out Vector3 normal, out Piece piece, out Heightmap heightmap, out Collider waterSurface, bool water)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			point = Vector3.zero;
			normal = Vector3.zero;
			piece = null;
			heightmap = null;
			waterSurface = null;
			BuildContext.TargetShip = null;
			s_hoveredTargetPiece = null;
			if (ShipBuildPlugin.IsDedicatedServer || (Object)(object)GameCamera.instance == (Object)null)
			{
				__result = false;
				return false;
			}
			GameObject val = ((PlacementGhostRef != null) ? PlacementGhostRef.Invoke(__instance) : null);
			bool flag = false;
			if ((Object)(object)val != (Object)null)
			{
				Piece component = val.GetComponent<Piece>();
				if ((Object)(object)component != (Object)null && ((Object)(object)val.GetComponent<Ship>() != (Object)null || component.m_waterPiece))
				{
					flag = true;
				}
			}
			int num = ((!(water || flag)) ? ((PlaceRayMaskRef != null) ? PlaceRayMaskRef.Invoke(__instance) : 0) : ((PlaceWaterRayMaskRef != null) ? PlaceWaterRayMaskRef.Invoke(__instance) : 0));
			if (!water && !flag)
			{
				num &= ~LayerMask.GetMask(new string[1] { "Water" });
			}
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val2, 50f, num))
			{
				float num2 = __instance.m_maxPlaceDistance;
				if ((Object)(object)val != (Object)null)
				{
					Piece component2 = val.GetComponent<Piece>();
					if ((Object)(object)component2 != (Object)null)
					{
						num2 += (float)component2.m_extraPlacementDistance;
					}
				}
				Transform eye = ((Character)__instance).m_eye;
				if ((Object)(object)eye != (Object)null && Vector3.Distance(eye.position, ((RaycastHit)(ref val2)).point) < num2)
				{
					if (((Component)((RaycastHit)(ref val2)).collider).gameObject.layer == LayerMask.NameToLayer("Water"))
					{
						waterSurface = ((RaycastHit)(ref val2)).collider;
					}
					Ship val3 = null;
					if (!flag)
					{
						val3 = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Ship>();
						if ((Object)(object)val3 == (Object)null)
						{
							ShipPieceTag componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<ShipPieceTag>();
							if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.Container != (Object)null)
							{
								val3 = componentInParent.Container.ShipComponent;
							}
						}
					}
					if ((Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody == (Object)null || ((Object)(object)val3 != (Object)null && !flag))
					{
						point = ((RaycastHit)(ref val2)).point;
						piece = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Piece>();
						heightmap = ((Component)((RaycastHit)(ref val2)).collider).GetComponent<Heightmap>();
						s_hoveredTargetPiece = piece;
						if ((Object)(object)val3 != (Object)null && !flag)
						{
							BuildContext.TargetShip = val3;
						}
						normal = ((RaycastHit)(ref val2)).normal;
						__result = true;
						return false;
					}
				}
			}
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyPrefix]
		private static void UpdatePlacementGhost_Prefix(Player __instance)
		{
			if (ShipBuildPlugin.IsDedicatedServer)
			{
				return;
			}
			GameObject val = ((PlacementGhostRef != null) ? PlacementGhostRef.Invoke(__instance) : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Piece component = val.GetComponent<Piece>();
			if (!((Object)(object)component == (Object)null))
			{
				s_originalGhostFlags.Active = false;
				if ((Object)(object)BuildContext.TargetShip != (Object)null)
				{
					s_originalGhostFlags.GroundPiece = component.m_groundPiece;
					s_originalGhostFlags.GroundOnly = component.m_groundOnly;
					s_originalGhostFlags.CultivatedGroundOnly = component.m_cultivatedGroundOnly;
					s_originalGhostFlags.VegetationGroundOnly = component.m_vegetationGroundOnly;
					s_originalGhostFlags.NotOnWood = component.m_notOnWood;
					s_originalGhostFlags.NotOnTiltingSurface = component.m_notOnTiltingSurface;
					s_originalGhostFlags.NoInWater = component.m_noInWater;
					s_originalGhostFlags.NoClipping = component.m_noClipping;
					s_originalGhostFlags.Active = true;
					component.m_groundPiece = false;
					component.m_groundOnly = false;
					component.m_cultivatedGroundOnly = false;
					component.m_vegetationGroundOnly = false;
					component.m_notOnWood = false;
					component.m_notOnTiltingSurface = false;
					component.m_noInWater = false;
					component.m_noClipping = false;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		[HarmonyPostfix]
		private static void UpdatePlacementGhost_Postfix(Player __instance)
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: 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_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Invalid comparison between Unknown and I4
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Invalid comparison between Unknown and I4
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Invalid comparison between Unknown and I4
			if (ShipBuildPlugin.IsDedicatedServer)
			{
				return;
			}
			GameObject val = ((PlacementGhostRef != null) ? PlacementGhostRef.Invoke(__instance) : null);
			if ((Object)(object)val != (Object)null && s_originalGhostFlags.Active)
			{
				Piece component = val.GetComponent<Piece>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_groundPiece = s_originalGhostFlags.GroundPiece;
					component.m_groundOnly = s_originalGhostFlags.GroundOnly;
					component.m_cultivatedGroundOnly = s_originalGhostFlags.CultivatedGroundOnly;
					component.m_vegetationGroundOnly = s_originalGhostFlags.VegetationGroundOnly;
					component.m_notOnWood = s_originalGhostFlags.NotOnWood;
					component.m_notOnTiltingSurface = s_originalGhostFlags.NotOnTiltingSurface;
					component.m_noInWater = s_originalGhostFlags.NoInWater;
					component.m_noClipping = s_originalGhostFlags.NoClipping;
				}
				s_originalGhostFlags.Active = false;
			}
			Ship targetShip = BuildContext.TargetShip;
			if ((Object)(object)targetShip == (Object)null || (Object)(object)val == (Object)null)
			{
				s_hasLockedPosition = false;
				s_lastShip = null;
				return;
			}
			if (!val.activeInHierarchy)
			{
				val.SetActive(true);
			}
			int num = ((PlaceRotationRef != null) ? PlaceRotationRef.Invoke(__instance) : 0);
			Vector2 mouseDelta = ZInput.GetMouseDelta();
			bool flag = ((Vector2)(ref mouseDelta)).sqrMagnitude > 0.0001f;
			bool flag2 = Mathf.Abs(ZInput.GetJoyRightStickX()) > 0.05f || Mathf.Abs(ZInput.GetJoyRightStickY()) > 0.05f;
			bool flag3 = Mathf.Abs(ZInput.GetMouseScrollWheel()) > 0f;
			bool flag4 = MoveDirRef != null && ((Vector3)(ref MoveDirRef.Invoke((Character)(object)__instance))).sqrMagnitude > 0.001f;
			bool flag5 = num != s_lastPlaceRot;
			int num2 = ((ManualSnapPointRef != null) ? ManualSnapPointRef.Invoke(__instance) : (-1));
			bool flag6 = num2 != s_lastSnapIndex;
			bool flag7 = (Object)(object)s_lastShip != (Object)(object)targetShip || s_lastGhostPrefabName != ((Object)val).name;
			bool num3 = flag || flag2 || flag4 || flag3 || flag5 || flag6 || flag7 || !s_hasLockedPosition;
			Vector3 val2 = ((Component)targetShip).transform.InverseTransformPoint(val.transform.position);
			Quaternion val3 = Quaternion.Inverse(((Component)targetShip).transform.rotation) * val.transform.rotation;
			Vector3 val4 = val2 - s_lockedLocalPos;
			bool flag8 = ((Vector3)(ref val4)).sqrMagnitude > 0.0004f || Quaternion.Angle(val3, s_lockedLocalRot) > 0.5f;
			if (num3 || flag8)
			{
				s_lockedLocalPos = val2;
				s_lockedLocalRot = val3;
				s_lastPlaceRot = num;
				s_lastSnapIndex = num2;
				s_lastShip = targetShip;
				s_lastGhostPrefabName = ((Object)val).name;
				s_hasLockedPosition = true;
			}
			val.transform.position = ((Component)targetShip).transform.TransformPoint(s_lockedLocalPos);
			val.transform.rotation = ((Component)targetShip).transform.rotation * s_lockedLocalRot;
			if ((Object)(object)s_hoveredTargetPiece != (Object)null)
			{
				WearNTear component2 = ((Component)s_hoveredTargetPiece).GetComponent<WearNTear>();
				if ((Object)(object)component2 != (Object)null && !component2.m_supports)
				{
					if (PlacementStatusRef != null)
					{
						PlacementStatusRef.Invoke(__instance) = (PlacementStatus)1;
					}
					val.GetComponent<Piece>().SetInvalidPlacementHeightlight(true);
					return;
				}
			}
			if (PlacementStatusRef != null)
			{
				PlacementStatus val5 = PlacementStatusRef.Invoke(__instance);
				if ((int)val5 != 4 && (int)val5 != 3 && (int)val5 != 1)
				{
					PlacementStatusRef.Invoke(__instance) = (PlacementStatus)0;
					val.GetComponent<Piece>().SetInvalidPlacementHeightlight(false);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "FindHoverObject")]
		[HarmonyPostfix]
		private static void FindHoverObject_Postfix(Player __instance, ref GameObject hover, ref Character hoverCreature)
		{
			if (ShipBuildPlugin.IsDedicatedServer || !((Object)(object)hover != (Object)null) || !((Object)(object)hover.GetComponent<Ship>() != (Object)null))
			{
				return;
			}
			RaycastHit[] array = ((RaycastHoverHitsRef != null) ? RaycastHoverHitsRef.Invoke(__instance) : null);
			if (array == null)
			{
				return;
			}
			for (int i = 0; i < array.Length; i++)
			{
				Collider collider = ((RaycastHit)(ref array[i])).collider;
				if (!((Object)(object)collider == (Object)null))
				{
					Hoverable componentInParent = ((Component)collider).GetComponentInParent<Hoverable>();
					if (componentInParent != null && !(componentInParent is Ship))
					{
						hover = ((Component)((componentInParent is MonoBehaviour) ? componentInParent : null)).gameObject;
						break;
					}
					Interactable componentInParent2 = ((Component)collider).GetComponentInParent<Interactable>();
					if (componentInParent2 != null && !(componentInParent2 is Ship))
					{
						hover = ((Component)((componentInParent2 is MonoBehaviour) ? componentInParent2 : null)).gameObject;
						break;
					}
					continue;
				}
				break;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPostfix]
		private static void PlacePiece_Postfix(Player __instance, Piece piece, Vector3 pos, Quaternion rot)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			Ship targetShip = BuildContext.TargetShip;
			if ((Object)(object)targetShip == (Object)null)
			{
				return;
			}
			BoxCollider floatCollider = targetShip.m_floatCollider;
			float num = (Object.op_Implicit((Object)(object)floatCollider) ? (Mathf.Max(floatCollider.size.x, floatCollider.size.z) + 3f) : 15f);
			if (Vector3.Distance(pos, ((Component)targetShip).transform.position) > num)
			{
				BuildContext.TargetShip = null;
				return;
			}
			ShipPiecesContainer shipPiecesContainer = ((Component)targetShip).GetComponent<ShipPiecesContainer>() ?? ((Component)targetShip).gameObject.AddComponent<ShipPiecesContainer>();
			shipPiecesContainer.InitUUID();
			Piece val = null;
			List<IPlaced> list = AccessTools.StaticFieldRefAccess<List<IPlaced>>(typeof(Player), "m_placed");
			if (list != null && list.Count > 0)
			{
				foreach (IPlaced item in list)
				{
					Piece val2 = (Piece)(object)((item is Piece) ? item : null);
					if (val2 != null && !Player.IsPlacementGhost(((Component)val2).gameObject))
					{
						val = val2;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Collider[] array = Physics.OverlapSphere(pos, 2.5f);
				float num2 = 999f;
				Collider[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					Piece componentInParent = ((Component)array2[i]).GetComponentInParent<Piece>();
					if ((Object)(object)componentInParent != (Object)null && !Player.IsPlacementGhost(((Component)componentInParent).gameObject) && ((Object)((Component)componentInParent).gameObject).name.StartsWith(((Object)((Component)piece).gameObject).name))
					{
						float num3 = Vector3.Distance(((Component)componentInParent).transform.position, pos);
						if (num3 < num2)
						{
							num2 = num3;
							val = componentInParent;
						}
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				ZNetView component = ((Component)val).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid())
				{
					Vector3 val3 = ((Component)targetShip).transform.InverseTransformPoint(((Component)val).transform.position);
					Quaternion localRot = Quaternion.Inverse(((Component)targetShip).transform.rotation) * ((Component)val).transform.rotation;
					string text = shipPiecesContainer.ShipUUID;
					if (string.IsNullOrEmpty(text))
					{
						text = (shipPiecesContainer.ShipUUID = ShipRegistry.GetOrCreateShipUUID(((Component)targetShip).GetComponent<ZNetView>().GetZDO()));
					}
					component.GetZDO().Set(ShipBuildPlugin.HashShipParent, text);
					component.GetZDO().Set(ShipBuildPlugin.HashLocalPos, val3);
					component.GetZDO().Set(ShipBuildPlugin.HashLocalRot, ((Quaternion)(ref localRot)).eulerAngles);
					shipPiecesContainer.RegisterPiece(component, val3, localRot);
				}
			}
			s_hasLockedPosition = false;
			BuildContext.TargetShip = null;
		}
	}
	internal static class PortalSectorIndex
	{
		internal static bool Move(Dictionary<SectorIndex, List<ZDO>> portals, ZDO portal, SectorIndex sector)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!Remove(portals, portal))
			{
				return false;
			}
			if (!portals.TryGetValue(sector, out var value))
			{
				value = (portals[sector] = new List<ZDO>());
			}
			value.Add(portal);
			return true;
		}

		internal static bool Remove(Dictionary<SectorIndex, List<ZDO>> portals, ZDO portal)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			List<SectorIndex> list = new List<SectorIndex>();
			foreach (KeyValuePair<SectorIndex, List<ZDO>> portal2 in portals)
			{
				if (portal2.Value.RemoveAll((ZDO zdo) => zdo.m_uid == portal.m_uid) > 0)
				{
					result = true;
				}
				if (portal2.Value.Count == 0)
				{
					list.Add(portal2.Key);
				}
			}
			foreach (SectorIndex item in list)
			{
				portals.Remove(item);
			}
			return result;
		}
	}
	[HarmonyPatch]
	public static class ShieldGenerator_Patches
	{
		private static readonly Dictionary<ShieldGenerator, Vector3> s_lastSentPositions = new Dictionary<ShieldGenerator, Vector3>();

		private static readonly FieldInfo s_shieldDomeEffectField = AccessTools.Field(typeof(ShieldGenerator), "m_shieldDomeEffect");

		private static readonly FieldInfo s_instanceChangeIDField = AccessTools.Field(typeof(ShieldGenerator), "m_instanceChangeID");

		private static readonly FieldRef<ShieldGenerator, float> s_lastFuelRef = AccessTools.FieldRefAccess<ShieldGenerator, float>("m_lastFuel");

		private static readonly FieldRef<ShieldGenerator, float> s_radiusRef = AccessTools.FieldRefAccess<ShieldGenerator, float>("m_radius");

		private static readonly FieldRef<ShieldGenerator, float> s_lastHitTimeRef = AccessTools.FieldRefAccess<ShieldGenerator, float>("m_lastHitTime");

		[HarmonyPatch(typeof(ShieldGenerator), "Update")]
		[HarmonyPostfix]
		private static void ShieldGenerator_Update_Postfix(ShieldGenerator __instance)
		{
			//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_0057: 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_0039: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_shieldDome == (Object)null)
			{
				return;
			}
			Vector3 position = __instance.m_shieldDome.transform.position;
			if (s_lastSentPositions.TryGetValue(__instance, out var value))
			{
				Vector3 val = position - value;
				if (!(((Vector3)(ref val)).sqrMagnitude > 0.0004f))
				{
					return;
				}
			}
			s_lastSentPositions[__instance] = position;
			if (!ShipBuildPlugin.IsDedicatedServer)
			{
				object? obj = s_shieldDomeEffectField?.GetValue(null);
				ShieldDomeImageEffect val2 = (ShieldDomeImageEffect)((obj is ShieldDomeImageEffect) ? obj : null);
				if ((Object)(object)val2 == (Object)null)
				{
					if ((Object)(object)Camera.main != (Object)null)
					{
						val2 = ((Component)Camera.main).GetComponent<ShieldDomeImageEffect>();
					}
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = Object.FindFirstObjectByType<ShieldDomeImageEffect>();
					}
					s_shieldDomeEffectField?.SetValue(null, val2);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					float num = ((s_lastFuelRef != null) ? s_lastFuelRef.Invoke(__instance) : 0f);
					float num2 = ((s_radiusRef != null) ? s_radiusRef.Invoke(__instance) : 0f);
					float num3 = ((s_lastHitTimeRef != null) ? s_lastHitTimeRef.Invoke(__instance) : 0f);
					val2.SetShieldData(__instance, position, num2, num, num3);
				}
			}
			if (s_instanceChangeIDField != null)
			{
				int num4 = (int)s_instanceChangeIDField.GetValue(null);
				s_instanceChangeIDField.SetValue(null, num4 + 1);
			}
		}

		[HarmonyPatch(typeof(ShieldGenerator), "OnDestroy")]
		[HarmonyPostfix]
		private static void ShieldGenerator_OnDestroy_Postfix(ShieldGenerator __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				s_lastSentPositions.Remove(__instance);
			}
		}
	}
	internal static class ShipAttachmentPhysics
	{
		internal static bool IsLooseItem(ItemDrop item)
		{
			ZNetView component = ((Component)item).GetComponent<ZNetView>();
			if (!((Object)(object)component != (Object)null) || !component.IsValid())
			{
				return !item.IsPiece();
			}
			return !component.GetZDO().GetBool(ZDOVars.s_piece, false);
		}

		internal static GameObject ColliderObject(Collider collider)
		{
			FloatingTerrainDummy componentInParent = ((Component)collider).GetComponentInParent<FloatingTerrainDummy>();
			if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent.m_parent != (Object)null))
			{
				return ((Component)collider).gameObject;
			}
			return ((Component)componentInParent.m_parent).gameObject;
		}

		internal static Rigidbody GetBody(GameObject target)
		{
			Rigidbody component = target.GetComponent<Rigidbody>();
			if (!((Object)(object)component != (Object)null))
			{
				return FloatingTerrain.GetBody(target);
			}
			return component;
		}

		internal static bool TryFindSurface(Vector3 origin, Transform ignoredRoot, float distance, out RaycastHit surface, out ShipPiecesContainer container)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			int mask = LayerMask.GetMask(new string[7] { "piece", "piece_nonsolid", "vehicle", "Default", "Default_small", "static_solid", "terrain" });
			RaycastHit[] array = Physics.RaycastAll(origin, Vector3.down, distance, mask, (QueryTriggerInteraction)1);
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			surface = default(RaycastHit);
			container = null;
			RaycastHit[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val = array2[num];
				GameObject val2 = ColliderObject(((RaycastHit)(ref val)).collider);
				if (val2.transform.IsChildOf(ignoredRoot) || (Object)(object)val2.GetComponentInParent<Character>() != (Object)null)
				{
					continue;
				}
				ItemDrop componentInParent = val2.GetComponentInParent<ItemDrop>();
				if ((componentInParent == null || !IsLooseItem(componentInParent)) && !((Object)(object)val2.GetComponentInParent<TombStone>() != (Object)null))
				{
					surface = val;
					ShipPieceTag componentInParent2 = val2.GetComponentInParent<ShipPieceTag>();
					if ((Object)(object)componentInParent2 != (Object)null)
					{
						container = componentInParent2.Container;
					}
					if ((Object)(object)container == (Object)null)
					{
						container = val2.GetComponentInParent<ShipPiecesContainer>();
					}
					return (Object)(object)container != (Object)null;
				}
			}
			return false;
		}

		internal static void Freeze(GameObject target)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			FloatingTerrain component = target.GetComponent<FloatingTerrain>();
			if ((Object)(object)component != (Object)null)
			{
				((MonoBehaviour)component).CancelInvoke("UpdateTerrain");
				((Behaviour)component).enabled = false;
				if ((Object)(object)component.m_dummy != (Object)null)
				{
					Collider[] componentsInChildren = ((Component)component.m_dummy).GetComponentsInChildren<Collider>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].enabled = false;
					}
				}
			}
			Rigidbody body = GetBody(target);
			if (!((Object)(object)body == (Object)null))
			{
				if (!body.isKinematic)
				{
					body.linearVelocity = Vector3.zero;
					body.angularVelocity = Vector3.zero;
				}
				body.isKinematic = true;
				body.useGravity = false;
			}
		}

		internal static void Resume(GameObject target)
		{
			//IL_0017: 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)
			Rigidbody body = GetBody(target);
			if ((Object)(object)body != (Object)null)
			{
				body.position = target.transform.position;
				body.rotation = target.transform.rotation;
				body.isKinematic = false;
				body.useGravity = true;
			}
			FloatingTerrain component = target.GetComponent<FloatingTerrain>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if ((Object)(object)component.m_dummy != (Object)null)
			{
				BoxCollider componentInChildren = target.GetComponentInChildren<BoxCollider>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Collider)componentInChildren).isTrigger = true;
				}
				Collider[] componentsInChildren = ((Component)component.m_dummy).GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = true;
				}
			}
			((Behaviour)component).enabled = true;
			((MonoBehaviour)component).CancelInvoke("UpdateTerrain");
			((MonoBehaviour)component).InvokeRepeating("UpdateTerrain", 0f, 0.24f);
		}
	}
	[BepInPlugin("com.Skarif.shipbuildmod", "ShipBuildMod", "4.0.10")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ShipBuildPlugin : BaseUnityPlugin
	{
		public const string ModGUID = "com.Skarif.shipbuildmod";

		public const string ModName = "ShipBuildMod";

		public const string ModVersion = "4.0.10";

		public const string KeyShipUUID = "ShipBuild_ShipUUID";

		public const string KeyShipParent = "ShipBuild_ParentUUID";

		public const string KeyLocalPos = "ShipBuild_LocalPos";

		public const string KeyLocalRot = "ShipBuild_LocalRot";

		public static readonly int HashShipParent = StringExtensionMethods.GetStableHashCode("ShipBuild_ParentUUID");

		public static readonly int HashShipUUID = StringExtensionMethods.GetStableHashCode("ShipBuild_ShipUUID");

		public static readonly int HashLocalPos = StringExtensionMethods.GetStableHashCode("ShipBuild_LocalPos");

		public static readonly int HashLocalRot = StringExtensionMethods.GetStableHashCode("ShipBuild_LocalRot");

		public static readonly int HashParentZDOID = StringExtensionMethods.GetStableHashCode("ShipBuild_ParentZDOID");

		public const string KeySpawnShipUUID = "ShipBuild_SpawnShipUUID";

		public const string KeySpawnShipZDOID = "ShipBuild_SpawnShipZDOID";

		public const string KeySpawnBedLocalPos = "ShipBuild_SpawnBedLocalPos";

		public const string KeySpawnBedZDOID = "ShipBuild_SpawnBedZDOID";

		public const string KeySpawnWorld = "ShipBuild_SpawnWorld";

		private Harmony m_harmony;

		public static bool IsDedicatedServer => (int)SystemInfo.graphicsDeviceType == 4;

		private void Awake()
		{
			m_harmony = Harmony.CreateAndPatchAll(typeof(ShipBuildPlugin).Assembly, "com.Skarif.shipbuildmod");
			ComfyGizmoCompat.TryPatch(m_harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ShipBuildMod v4.0.10 loaded successfully.");
		}

		private void OnDestroy()
		{
			Harmony harmony = m_harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class ComfyGizmoCompat
	{
		public static void TryPatch(Harmony harmony)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			try
			{
				Type type = AccessTools.TypeByName("ComfyGizmo.PlayerPatch");
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "PlaceRotationDelegate", (Type[])null, (Type[])null);
					MethodInfo methodInfo2 = AccessTools.Method(typeof(ComfyGizmoCompat), "PlaceRotationDelegate_Postfix", (Type[])null, (Type[])null);
					if (methodInfo != null && methodInfo2 != null)
					{
						harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[ShipBuildMod] Soft-patch for ComfyGizmo was skipped or failed: " + ex.Message));
			}
		}

		private static void PlaceRotationDelegate_Postfix(Quaternion rotation, ref Quaternion __result)
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Ship targetShip = BuildContext.TargetShip;
			if (!((Object)(object)targetShip == (Object)null) && __result != rotation)
			{
				__result = ((Component)targetShip).transform.rotation * __result;
			}
		}
	}
	[HarmonyPatch]
	public static class ShipFire_Patches
	{
		private static readonly List<KeyValuePair<Bounds, EffectArea>> BurningAreas = AccessTools.StaticFieldRefAccess<List<KeyValuePair<Bounds, EffectArea>>>(typeof(EffectArea), "s_BurningAreas");

		internal static EffectArea FindBurningArea(Vector3 point)
		{
			//IL_002e: 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_00a6: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Bounds, EffectArea> burningArea in BurningAreas)
			{
				EffectArea value = burningArea.Value;
				if ((Object)(object)value == (Object)null)
				{
					continue;
				}
				Bounds val = burningArea.Key;
				if ((Object)(object)((Component)value).GetComponentInParent<Ship>() != (Object)null || (Object)(object)((Component)value).GetComponentInParent<ShipPieceTag>() != (Object)null)
				{
					if (!((Behaviour)value).isActiveAndEnabled)
					{
						continue;
					}
					Collider component = ((Component)value).GetComponent<Collider>();
					if ((Object)(object)component == (Object)null || !component.enabled || !((Component)component).gameObject.activeInHierarchy)
					{
						continue;
					}
					val = component.bounds;
					((Bounds)(ref val)).Expand(new Vector3(0.25f, 0.25f, 0.25f));
				}
				if (((Bounds)(ref val)).Contains(point))
				{
					return value;
				}
			}
			return null;
		}

		[HarmonyPatch(typeof(EffectArea), "IsPointPlus025InsideBurningArea")]
		[HarmonyPrefix]
		private static bool BurningArea_Prefix(Vector3 p, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			__result = (Object)(object)FindBurningArea(p) != (Object)null;
			return false;
		}

		[HarmonyPatch(typeof(EffectArea), "GetBurningAreaPointPlus025")]
		[HarmonyPrefix]
		private static bool BurningAreaObject_Prefix(Vector3 p, ref EffectArea __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			__result = FindBurningArea(p);
			return false;
		}
	}
	public sealed class ShipMechanismPhysics : MonoBehaviour
	{
		private ShipPiecesContainer m_container;

		private Collider[] m_colliders = Array.Empty<Collider>();

		private Collider[] m_targets = Array.Empty<Collider>();

		private bool[] m_activeColliders = Array.Empty<bool>();

		private bool[] m_activeTargets = Array.Empty<bool>();

		private bool m_refreshRequired;

		public void Initialize(ShipPiecesContainer container)
		{
			//IL_0026: 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)
			m_container = container;
			Rigidbody val = ((Component)this).GetComponent<Rigidbody>() ?? ((Component)this).gameObject.AddComponent<Rigidbody>();
			if (!val.isKinematic)
			{
				val.linearVelocity = Vector3.zero;
				val.angularVelocity = Vector3.zero;
			}
			val.isKinematic = true;
			val.useGravity = false;
			RefreshCollisionPairs();
		}

		public void RefreshCollisionPairs()
		{
			if ((Object)(object)m_container == (Object)null)
			{
				return;
			}
			m_colliders = ((Component)this).GetComponentsInChildren<Collider>(true);
			Rigidbody component = ((Component)m_container).GetComponent<Rigidbody>();
			List<Collider> list = new List<Collider>();
			Collider[] componentsInChildren = ((Component)m_container).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)component != (Object)null && (Object)(object)val.attachedRigidbody == (Object)(object)component)
				{
					list.Add(val);
				}
			}
			m_targets = list.ToArray();
			m_activeColliders = new bool[m_colliders.Length];
			m_activeTargets = new bool[m_targets.Length];
			m_refreshRequired = true;
			RestoreCollisionIgnores();
		}

		private void OnEnable()
		{
			m_refreshRequired = true;
		}

		private void FixedUpdate()
		{
			RestoreCollisionIgnores();
		}

		private void LateUpdate()
		{
			RestoreCollisionIgnores();
		}

		private void RestoreCollisionIgnores()
		{
			if ((Object)(object)m_container == (Object)null || (Object)(object)((Component)this).transform.parent != (Object)(object)((Component)m_container).transform)
			{
				return;
			}
			bool refreshRequired = m_refreshRequired;
			m_refreshRequired = false;
			if (!(refreshRequired | UpdateActiveStates(m_colliders, m_activeColliders) | UpdateActiveStates(m_targets, m_activeTargets)))
			{
				return;
			}
			for (int i = 0; i < m_colliders.Length; i++)
			{
				if (!m_activeColliders[i])
				{
					continue;
				}
				for (int j = 0; j < m_targets.Length; j++)
				{
					if (m_activeTargets[j] && (Object)(object)m_colliders[i] != (Object)(object)m_targets[j] && !Physics.GetIgnoreCollision(m_colliders[i], m_targets[j]))
					{
						Physics.IgnoreCollision(m_colliders[i], m_targets[j], true);
					}
				}
			}
		}

		private static bool UpdateActiveStates(Collider[] colliders, bool[] states)
		{
			bool result = false;
			for (int i = 0; i < colliders.Length; i++)
			{
				Collider val = colliders[i];
				bool flag = (Object)(object)val != (Object)null && val.enabled && ((Component)val).gameObject.activeInHierarchy;
				if (states[i] != flag)
				{
					states[i] = flag;
					result = true;
				}
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(Door), "SetState")]
	public static class ShipDoorPhysics_Patch
	{
		[HarmonyPostfix]
		private static void Postfix(Door __instance)
		{
			ShipMechanismPhysics component = ((Component)__instance).GetComponent<ShipMechanismPhysics>();
			if ((Object)(object)component != (Object)null)
			{
				component.RefreshCollisionPairs();
			}
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateGroundContact")]
	public static class ShipMechanismGround_Patch
	{
		private static readonly FieldRef<Character, Rigidbody> s_groundBody = AccessTools.FieldRefAccess<Character, Rigidbody>("m_lastGroundBody");

		[HarmonyPostfix]
		private static void Postfix(Character __instance)
		{
			Collider lastGroundCollider = __instance.GetLastGroundCollider();
			if (__instance.IsOnGround() && !((Object)(object)lastGroundCollider == (Object)null) && !((Object)(object)((Component)lastGroundCollider).GetComponentInParent<ShipMechanismPhysics>() == (Object)null))
			{
				ShipPieceTag componentInParent = ((Component)lastGroundCollider).GetComponentInParent<ShipPieceTag>();
				if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.Container == (Object)null) && ((Component)lastGroundCollider).transform.IsChildOf(((Component)componentInParent.Container).transform))
				{
					s_groundBody.Invoke(__instance) = ((Component)componentInParent.Container).GetComponent<Rigidbody>();
				}
			}
		}
	}
	public static class ShipNavigationManager
	{
		public static string CurrentSpawnShipUUID = "";

		public static string CurrentSpawnShipZDOIDStr = "";

		public static string CurrentSpawnBedZDOIDStr = "";

		public static Vector3 CurrentSpawnBedLocalPos = Vector3.zero;

		private static float s_lastShipSearchTime = 0f;

		private static float s_lastSpawnRequest = -10f;

		private static readonly FieldRef<ZDOMan, Dictionary<ZDOID, ZDO>> s_objectsByIDRef = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID");

		public static string FormatVector3(Vector3 v)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return string.Format(CultureInfo.InvariantCulture, "{0}:{1}:{2}", v.x, v.y, v.z);
		}

		public static Vector3 ParseVector3(string s)
		{
			//IL_0008: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(s))
			{
				return Vector3.zero;
			}
			string[] array = s.Split(':');
			if (array.Length == 3 && float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return new Vector3(result, result2, result3);
			}
			return Vector3.zero;
		}

		public unsafe static void SetShipSpawnBed(string shipUUID, ZDOID shipZdoid, Vector3 bedLocalPos, Vector3 worldSpawnPos, ZDOID bedID)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			CurrentSpawnShipUUID = shipUUID;
			CurrentSpawnShipZDOIDStr = ((shipZdoid != ZDOID.None) ? ((object)(*(ZDOID*)(&shipZdoid))/*cast due to .constrained prefix*/).ToString() : "");
			CurrentSpawnBedLocalPos = bedLocalPos;
			CurrentSpawnBedZDOIDStr = ((object)(*(ZDOID*)(&bedID))/*cast due to .constrained prefix*/).ToString();
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				Player.m_localPlayer.m_customData["ShipBuild_SpawnShipUUID"] = shipUUID;
				Player.m_localPlayer.m_customData["ShipBuild_SpawnBedLocalPos"] = FormatVector3(bedLocalPos);
				Player.m_localPlayer.m_customData["ShipBuild_SpawnBedZDOID"] = CurrentSpawnBedZDOIDStr;
				if (!string.IsNullOrEmpty(CurrentSpawnShipZDOIDStr))
				{
					Player.m_localPlayer.m_customData["ShipBuild_SpawnShipZDOID"] = CurrentSpawnShipZDOIDStr;
				}
			}
			if ((Object)(object)Game.instance != (Object)null)
			{
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				if (playerProfile != null)
				{
					playerProfile.SetCustomSpawnPoint(worldSpawnPos);
				}
			}
		}

		public static void ClearShipSpawnBed()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			CurrentSpawnShipUUID = "";
			CurrentSpawnShipZDOIDStr = "";
			CurrentSpawnBedLocalPos = Vector3.zero;
			CurrentSpawnBedZDOIDStr = "";
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				Player.m_localPlayer.m_customData.Remove("ShipBuild_SpawnShipUUID");
				Player.m_localPlayer.m_customData.Remove("ShipBuild_SpawnBedLocalPos");
				Player.m_localPlayer.m_customData.Remove("ShipBuild_SpawnShipZDOID");
				Player.m_localPlayer.m_customData.Remove("ShipBuild_SpawnBedZDOID");
			}
		}

		public static bool TryGetShipSpawnPoint(out Vector3 spawnPoint)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_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_00db: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			spawnPoint = Vector3.zero;
			if (string.IsNullOrEmpty(CurrentSpawnShipUUID))
			{
				return false;
			}
			if (ShipRegistry.ShipsByUUID.TryGetValue(CurrentSpawnShipUUID, out var value) && (Object)(object)value != (Object)null)
			{
				spawnPoint = ((Component)value).transform.TransformPoint(CurrentSpawnBedLocalPos) + Vector3.up * 0.5f;
				return true;
			}
			if (Time.time - s_lastShipSearchTime > 1f)
			{
				s_lastShipSearchTime = Time.time;
				Ship[] array = Object.FindObjectsByType<Ship>((FindObjectsSortMode)0);
				foreach (Ship val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						ShipPiecesContainer component = ((Component)val).GetComponent<ShipPiecesContainer>();
						if ((Object)(object)component != (Object)null && component.ShipUUID == CurrentSpawnShipUUID)
						{
							ShipRegistry.RegisterShip(component.ShipUUID, val);
							spawnPoint = ((Component)val).transform.TransformPoint(CurrentSpawnBedLocalPos) + Vector3.up * 0.5f;
							return true;
						}
					}
				}
			}
			if (ZDOMan.instance != null && !string.IsNullOrEmpty(CurrentSpawnShipZDOIDStr) && ShipRegistry.TryParseZDOID(CurrentSpawnShipZDOIDStr, out var zdoid) && zdoid != ZDOID.None)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(zdoid);
				if (zDO == null && Time.realtimeSinceStartup - s_lastSpawnRequest > 1f)
				{
					s_lastSpawnRequest = Time.realtimeSinceStartup;
					ZDOMan.instance.RequestZDO(zdoid);
				}
				if (zDO != null && zDO.IsValid())
				{
					Vector3 position = zDO.GetPosition();
					Quaternion rotation = zDO.GetRotation();
					spawnPoint = position + rotation * CurrentSpawnBedLocalPos + Vector3.up * 0.5f;
					return true;
				}
			}
			if (ZDOMan.instance != null && s_objectsByIDRef != null)
			{
				Dictionary<ZDOID, ZDO> dictionary = s_objectsByIDRef.Invoke(ZDOMan.instance);
				if (dictionary != null)
				{
					int hashShipUUID = ShipBuildPlugin.HashShipUUID;
					foreach (KeyValuePair<ZDOID, ZDO> item in dictionary)
					{
						ZDO value2 = item.Value;
						if (value2 != null && value2.GetString(hashShipUUID, "") == CurrentSpawnShipUUID)
						{
							Vector3 position2 = value2.GetPosition();
							Quaternion rotation2 = value2.GetRotation();
							spawnPoint = position2 + rotation2 * CurrentSpawnBedLocalPos + Vector3.up * 0.5f;
							return true;
						}
					}
				}
			}
			return false;
		}

		public static Vector3 GetDynamicTeleportPosition(GameObject go)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0016: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			TeleportWorld component = go.GetComponent<TeleportWorld>();
			if ((Object)(object)component != (Object)null)
			{
				return ((Component)component).transform.position + ((Component)component).transform.forward * component.m_exitDistance + Vector3.up * 0.5f;
			}
			return go.transform.position + Vector3.up * 0.5f;
		}
	}
	[HarmonyPatch]
	public static class ShipSpawnAndPortal_Patches
	{
		private static readonly FieldRef<Game, float> RespawnWaitRef = AccessTools.FieldRefAccess<Game, float>("m_respawnWait");

		private static readonly FieldRef<Game, float> RespawnLoadDurationRef = AccessTools.FieldRefAccess<Game, float>("m_respawnLoadDuration");

		private static readonly FieldRef<Game, bool> RespawnAfterDeathRef = AccessTools.FieldRefAccess<Game, bool>("m_respawnAfterDeath");

		private static readonly FieldRef<Minimap, PinData> SpawnPointPinRef = AccessTools.FieldRefAccess<Minimap, PinData>("m_spawnPointPin");

		private static readonly MethodInfo s_pokeLocalZone = AccessTools.Method(typeof(ZoneSystem), "PokeLocalZone", (Type[])null, (Type[])null);

		private static PlayerProfile s_spawnProfile;

		private static long s_spawnWorld;

		private static bool s_useVanillaSpawn;

		private static void PokeZone(Vector2s zone)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)ZoneSystem.instance != (Object)null && s_pokeLocalZone != null)
				{
					s_pokeLocalZone.Invoke(ZoneSystem.instance, new object[1] { zone });
				}
			}
			catch (Exception)
			{
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "FindFloor")]
		[HarmonyPrefix]
		private static bool ZoneSystem_FindFloor_Prefix(Vector3 p, ref float height, ref bool __result)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			int mask = LayerMask.GetMask(new string[4] { "piece", "vehicle", "Default", "static_solid" });
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(p + Vector3.up * 3f, Vector3.down, ref val, 20f, mask))
			{
				Ship val2 = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Ship>();
				if ((Object)(object)val2 == (Object)null)
				{
					ShipPieceTag componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<ShipPieceTag>();
					if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.Container != (Object)null)
					{
						val2 = componentInParent.Container.ShipComponent;
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					height = ((RaycastHit)(ref val)).point.y;
					__result = true;
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Bed), "IsCurrent")]
		[HarmonyPrefix]
		private static bool Bed_IsCurrent_Prefix(Bed __instance, ref bool __result)
		{
			Ship componentInParent = ((Component)__instance).GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				long num = (((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null) ? Game.instance.GetPlayerProfile().GetPlayerID() : 0);
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				long num2 = (((Object)(object)component != (Object)null && component.GetZDO() != null) ? component.GetZDO().GetLong(ZDOVars.s_owner, 0L) : 0);
				if (num2 != 0L && num2 == num)
				{
					ShipPiecesContainer component2 = ((Component)componentInParent).GetComponent<ShipPiecesContainer>();
					if ((Object)(object)component2 != (Object)null && !string.IsNullOrEmpty(component2.ShipUUID) && component2.ShipUUID == ShipNavigationManager.CurrentSpawnShipUUID)
					{
						if (!string.IsNullOrEmpty(ShipNavigationManager.CurrentSpawnBedZDOIDStr) && ((object)Unsafe.As<ZDOID, ZDOID>(ref component.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString() != ShipNavigationManager.CurrentSpawnBedZDOIDStr)
						{
							return true;
						}
						__result = true;
						return false;
					}
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Bed), "Interact")]
		[HarmonyPostfix]
		private static void Bed_Interact_Postfix(Bed __instance, Humanoid human, bool repeat, bool alt)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)human != (Object)(object)Player.m_localPlayer || repeat)
			{
				return;
			}
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			if (!playerProfile.HaveCustomSpawnPoint() || Vector3.Distance(playerProfile.GetCustomSpawnPoint(), __instance.GetSpawnPoint()) > 0.1f)
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return;
			}
			long num = (((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null) ? Game.instance.GetPlayerProfile().GetPlayerID() : 0);
			long num2 = component.GetZDO().GetLong(ZDOVars.s_owner, 0L);
			if (num2 != 0L && num2 != num)
			{
				return;
			}
			Ship componentInParent = ((Component)__instance).GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				ShipPiecesContainer shipPiecesContainer = ((Component)componentInParent).GetComponent<ShipPiecesContainer>() ?? ((Component)componentInParent).gameObject.AddComponent<ShipPiecesContainer>();
				shipPiecesContainer.InitUUID();
				if (!string.IsNullOrEmpty(shipPiecesContainer.ShipUUID))
				{
					Vector3 spawnPoint = __instance.GetSpawnPoint();
					Vector3 bedLocalPos = ((Component)componentInParent).transform.InverseTransformPoint(spawnPoint);
					ShipNavigationManager.SetShipSpawnBed(shipPiecesContainer.ShipUUID, shipPiecesContainer.ShipZDOID, bedLocalPos, spawnPoint, component.GetZDO().m_uid);
					Game.instance.SavePlayerProfile(false, false);
				}
			}
			else
			{
				ShipNavigationManager.ClearShipSpawnBed();
				if ((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null)
				{
					Game.instance.SavePlayerProfile(false, false);
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdateProfilePins")]
		[HarmonyPostfix]
		private static void Minimap_UpdateProfilePins_Postfix(Minimap __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (SpawnPointPinRef != null)
			{
				PinData val = SpawnPointPinRef.Invoke(__instance);
				if (val != null && ShipNavigationManager.TryGetShipSpawnPoint(out var spawnPoint))
				{
					val.m_pos = spawnPoint;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		[HarmonyPostfix]
		private static void Player_Load_Postfix(Player __instance)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				string value2;
				string value3;
				if (__instance.m_customData.TryGetValue("ShipBuild_SpawnWorld", out var value) && value != ZNet.instance.GetWorldUID().ToString(CultureInfo.InvariantCulture))
				{
					ShipNavigationManager.ClearShipSpawnBed();
				}
				else if (__instance.m_customData.TryGetValue("ShipBuild_SpawnShipUUID", out value2) && __instance.m_customData.TryGetValue("ShipBuild_SpawnBedLocalPos", out value3))
				{
					ShipNavigationManager.CurrentSpawnShipUUID = value2;
					ShipNavigationManager.CurrentSpawnBedLocalPos = ShipNavigationManager.ParseVector3(value3);
					__instance.m_customData.TryGetValue("ShipBuild_SpawnShipZDOID", out ShipNavigationManager.CurrentSpawnShipZDOIDStr);
					__instance.m_customData.TryGetValue("ShipBuild_SpawnBedZDOID", out ShipNavigationManager.CurrentSpawnBedZDOIDStr);
				}
				else
				{
					ShipNavigationManager.CurrentSpawnShipUUID = "";
					ShipNavigationManager.CurrentSpawnShipZDOIDStr = "";
					ShipNavigationManager.CurrentSpawnBedLocalPos = Vector3.zero;
					ShipNavigationManager.CurrentSpawnBedZDOIDStr = "";
				}
			}
		}

		[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
		[HarmonyPostfix]
		private static void Player_SetLocalPlayer_Postfix(Player __instance)
		{
			//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)
			if (__instance.m_customData.TryGetValue("ShipBuild_SpawnShipUUID", out var value) && __instance.m_customData.TryGetValue("ShipBuild_SpawnBedLocalPos", out var value2))
			{
				ShipNavigationManager.CurrentSpawnShipUUID = value;
				ShipNavigationManager.CurrentSpawnBedLocalPos = ShipNavigationManager.ParseVector3(value2);
				__instance.m_customData.TryGetValue("ShipBuild_SpawnShipZDOID", out ShipNavigationManager.CurrentSpawnShipZDOIDStr);
			}
		}

		[HarmonyPatch(typeof(Player), "Save")]
		[HarmonyPrefix]
		private static void Player_Save_Prefix(Player __instance)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			__instance.m_customData["ShipBuild_SpawnWorld"] = ZNet.instance.GetWorldUID().ToString(CultureInfo.InvariantCulture);
			if (!string.IsNullOrEmpty(ShipNavigationManager.CurrentSpawnShipUUID))
			{
				__instance.m_customData["ShipBuild_SpawnShipUUID"] = ShipNavigationManager.CurrentSpawnShipUUID;
				__instance.m_customData["ShipBuild_SpawnBedLocalPos"] = ShipNavigationManager.FormatVector3(ShipNavigationManager.CurrentSpawnBedLocalPos);
				__instance.m_customData["ShipBuild_SpawnBedZDOID"] = ShipNavigationManager.CurrentSpawnBedZDOIDStr ?? "";
				if (!string.IsNullOrEmpty(ShipNavigationManager.CurrentSpawnShipZDOIDStr))
				{
					__instance.m_customData["ShipBuild_SpawnShipZDOID"] = ShipNavigationManager.CurrentSpawnShipZDOIDStr;
				}
			}
			else
			{
				__instance.m_customData.Remove("ShipBuild_SpawnShipUUID");
				__instance.m_customData.Remove("ShipBuild_SpawnBedLocalPos");
				__instance.m_customData.Remove("ShipBuild_SpawnShipZDOID");
				__instance.m_customData.Remove("ShipBuild_SpawnBedZDOID");
			}
		}

		[HarmonyPatch(typeof(Game), "_RequestRespawn")]
		[HarmonyPostfix]
		private static void ResetSpawnAttempt_Postfix()
		{
			s_useVanillaSpawn = false;
		}

		private static bool FallBackToVanillaSpawn(Game game)
		{
			s_useVanillaSpawn = true;
			RespawnWaitRef.Invoke(game) = 0f;
			Debug.LogWarning((object)"[ShipBuildMod] Ship spawn bed unavailable after loading timeout; using vanilla spawn.");
			return true;
		}

		[HarmonyPatch(typeof(Player), "Save")]
		[HarmonyPostfix]
		private static void SaveShipSpawnTrailer_Postfix(Player __instance, ZPackage pkg)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)ZNet.instance == (Object)null))
			{
				byte[] array = new ShipSpawnData
				{
					World = ZNet.instance.GetWorldUID(),
					ShipUUID = (ShipNavigationManager.CurrentSpawnShipUUID ?? ""),
					ShipID = (ShipNavigationManager.CurrentSpawnShipZDOIDStr ?? ""),
					BedID = (ShipNavigationManager.CurrentSpawnBedZDOIDStr ?? ""),
					LocalPos = ShipNavigationManager.FormatVector3(ShipNavigationManager.CurrentSpawnBedLocalPos)
				}.Serialize();
				pkg.Write(array);
				pkg.Write(array.Length);
				pkg.Write(1112754225);
			}
		}

		private static void RestoreSpawnBeforePlayerLoad(PlayerProfile profile)
		{
			//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)
			long worldUID = ZNet.instance.GetWorldUID();
			if (s_spawnProfile != profile || s_spawnWorld != worldUID)
			{
				s_spawnProfile = profile;
				s_spawnWorld = worldUID;
				s_useVanillaSpawn = false;
				ShipNavigationManager.ClearShipSpawnBed();
				ShipSpawnData shipSpawnData = ShipSpawnData.Read((byte[])AccessTools.Field(typeof(PlayerProfile), "m_playerData").GetValue(profile), worldUID);
				if (shipSpawnData != null)
				{
					ShipNavigationManager.CurrentSpawnShipUUID = shipSpawnData.ShipUUID;
					ShipNavigationManager.CurrentSpawnShipZDOIDStr = shipSpawnData.ShipID;
					ShipNavigationManager.CurrentSpawnBedZDOIDStr = shipSpawnData.BedID;
					ShipNavigationManager.CurrentSpawnBedLocalPos = ShipNavigationManager.ParseVector3(shipSpawnData.LocalPos);
				}
			}
		}

		[HarmonyPatch(typeof(Game), "FindSpawnPoint")]
		[HarmonyPrefix]
		private static bool Game_FindSpawnPoint_Prefix(Game __instance, out Vector3 point, out bool usedLogoutPoint, float dt, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			point = Vector3.zero;
			usedLogoutPoint = false;
			PlayerProfile playerProfile = __instance.GetPlayerProfile();
			RestoreSpawnBeforePlayerLoad(playerProfile);
			if (s_useVanillaSpawn)
			{
				return true;
			}
			if (string.IsNullOrEmpty(ShipNavigationManager.CurrentSpawnShipUUID))
			{
				return true;
			}
			if ((RespawnAfterDeathRef == null || !RespawnAfterDeathRef.Invoke(__instance)) && playerProfile != null && playerProfile.HaveLogoutPoint())
			{
				return true;
			}
			if (RespawnWaitRef != null)
			{
				RespawnWaitRef.Invoke(__instance) += dt;
			}
			float num = ((RespawnWaitRef != null) ? RespawnWaitRef.Invoke(__instance) : 0f);
			float num2 = ((RespawnLoadDurationRef != null) ? RespawnLoadDurationRef.Invoke(__instance) : 8f);
			if (num > num2 + 60f)
			{
				return FallBackToVanillaSpawn(__instance);
			}
			if (ShipNavigationManager.TryGetShipSpawnPoint(out var spawnPoint))
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					ZNet.instance.SetReferencePosition(spawnPoint);
				}
				if ((Object)(object)ZoneSystem.instance != (Object)null)
				{
					PokeZone(ZoneSystem.GetZone(spawnPoint));
				}
				if (num <= num2 || ((Object)(object)ZNetScene.instance != (Object)null && !ZNetScene.instance.IsAreaReady(spawnPoint)))
				{
					point = Vector3.zero;
					__result = false;
					return false;
				}
				Bed val = null;
				if (ShipRegistry.TryParseZDOID(ShipNavigationManager.CurrentSpawnBedZDOIDStr, out var zdoid))
				{
					GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zdoid) : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val = val2.GetComponent<Bed>();
					}
				}
				else
				{
					Bed[] array = Object.FindObjectsByType<Bed>((FindObjectsSortMode)0);
					foreach (Bed val3 in array)
					{
						ZNetView component = ((Component)val3).GetComponent<ZNetView>();
						if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetLong(ZDOVars.s_owner, 0L) == playerProfile.GetPlayerID() && Vector3.Distance(val3.GetSpawnPoint(), spawnPoint) < 2f)
						{
							val = val3;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent<Ship>() == (Object)null)
				{
					__result = false;
					return false;
				}
				ZNetView component2 = ((Component)val).GetComponent<ZNetView>();
				if ((Object)(object)component2 == (Object)null || !component2.IsValid() || component2.GetZDO().GetLong(ZDOVars.s_owner, 0L) != playerProfile.GetPlayerID())
				{
					ShipNavigationManager.ClearShipSpawnBed();
					playerProfile.ClearCustomSpawnPoint();
					return true;
				}
				point = val.GetSpawnPoint();
				playerProfile.SetCustomSpawnPoint(point);
				usedLogoutPoint = false;
				__result = true;
				return false;
			}
			point = Vector3.zero;
			__result = false;
			return false;
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		[HarmonyPrefix]
		private static void InventoryGui_UpdateContainer_Prefix(InventoryGui __instance)
		{
			if (__instance.IsContainerOpen())
			{
				object? value = AccessTools.Field(typeof(InventoryGui), "m_currentContainer").GetValue(__instance);
				Container val = (Container)((value is Container) ? value : null);
				if ((Object)(object)val != (Object)null && ((Object)(object)((Component)val).GetComponent<ShipPieceTag>() != (Object)null || (Object)(object)((Component)val).GetComponentInParent<Ship>() != (Object)null))
				{
					__instance.m_autoCloseDistance = 8f;
				}
				else
				{
					__instance.m_autoCloseDistance = 4f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class Character_ShipStanding_Patches
	{
		[HarmonyPatch("GetStandingOnShip")]
		[HarmonyPrefix]
		private static bool GetStandingOnShip_Prefix(Character __instance, ref Ship __result)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.IsTeleporting())
			{
				__result = null;
				return false;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				Ship controlledShip = val.GetControlledShip();
				if ((Object)(object)controlledShip != (Object)null)
				{
					__result = controlledShip;
					return false;
				}
			}
			if (!__instance.IsOnGround())
			{
				__result = null;
				return false;
			}
			Collider lastGroundCollider = __instance.GetLastGroundCollider();
			if ((Object)(object)lastGroundCollider != (Object)null)
			{
				ShipPieceTag componentInParent = ((Component)lastGroundCollider).GetComponentInParent<ShipPieceTag>();
				Ship val2 = (((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.Container != (Object)null) ? componentInParent.Container.ShipComponent : ((Component)lastGroundCollider).GetComponentInParent<Ship>());
				if ((Object)(object)val2 != (Object)null)
				{
					Vector3 val3 = ColliderGeometry.ClosestPointForProximity(lastGroundCollider, ((Component)__instance).transform.position) - ((Component)__instance).transform.position;
					if (((Vector3)(ref val3)).sqrMagnitude < 2.25f)
					{
						__result = val2;
						return false;
					}
				}
			}
			__result = null;
			return false;
		}
	}
	[HarmonyPatch(typeof(Ship))]
	public static class Ship_Players_Patches
	{
		private static readonly FieldRef<Ship, List<Player>> ShipPlayersRef = AccessTools.FieldRefAccess<Ship, List<Player>>("m_players");

		[HarmonyPatch("CustomFixedUpdate")]
		[HarmonyPrefix]
		private static void CustomFixedUpdate_Prefix(Ship __instance)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if (ShipBuildPlugin.IsDedicatedServer || ShipPlayersRef == null)
			{
				return;
			}
			List<Player> list = ShipPlayersRef.Invoke(__instance);
			if (list == null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return;
			}
			if (((Character)localPlayer).IsTeleporting())
			{
				list.Remove(localPlayer);
				return;
			}
			Ship standingOnShip = ((Character)localPlayer).GetStandingOnShip();
			Ship controlledShip = localPlayer.GetControlledShip();
			bool flag = (Object)(object)standingOnShip == (Object)(object)__instance;
			bool flag2 = (Object)(object)controlledShip == (Object)(object)__instance;
			if (flag || flag2)
			{
				if (!list.Contains(localPlayer))
				{
					list.Add(localPlayer);
					List<Ship> list2 = AccessTools.StaticFieldRefAccess<List<Ship>>(typeof(Ship), "s_currentShips");
					if (list2 != null && !list2.Contains(__instance))
					{
						list2.Add(__instance);
					}
				}
				return;
			}
			bool num = ((Character)localPlayer).IsOnGround() && !flag;
			bool flag3 = ((Character)localPlayer).IsSwimming();
			BoxCollider floatCollider = __instance.m_floatCollider;
			float num2 = (Object.op_Implicit((Object)(object)floatCollider) ? (Mathf.Max(floatCollider.size.x, floatCollider.size.z) * 0.75f + 3f) : 15f);
			bool flag4 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)__instance).transform.position) > num2;
			if (num || flag3 || flag4)
			{
				list.Remove(localPlayer);
			}
		}
	}
	[HarmonyPatch(typeof(ZSyncTransform))]
	public static class ZSyncTransform_Patches
	{
		[HarmonyPatch("ClientSync")]
		[HarmonyPrefix]
		private static bool ClientSync_Prefix(ZSyncTransform __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<Ship>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)__instance).GetComponent<ShipPieceTag>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)__instance).transform.parent != (Object)null && (Object)(object)((Component)((Component)__instance).transform.parent).GetComponentInParent<Ship>() != (Object)null)
			{
				return false;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null)
			{
				string text = component.GetZDO().GetString(ShipBuildPlugin.HashShipParent, "");
				if (!string.IsNullOrEmpty(text) && ShipPiecePrefabValidator.IsShipPieceZDO(component.GetZDO()))
				{
					if (ShipRegistry.ShipsByUUID.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
					{
						PieceAttachmentQueue.AttachToShip(value, component);
					}
					else
					{
						PieceAttachmentQueue.Enqueue(text, component);
					}
					return false;
				}
			}
			Rigidbody component2 = ((Component)__instance).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null && component2.isKinematic)
			{
				return false;
			}
			return true;
		}
	}
	public class ShipPieceTag : MonoBehaviour
	{
		public ShipPiecesContainer Container;
	}
	public class ShipPiecesContainer : MonoBehaviour
	{
		private static readonly MethodInfo s_createObject = AccessTools.Method(typeof(ZNetScene), "CreateObject", new Type[1] { typeof(ZDO) }, (Type[])null);

		private static readonly MethodInfo s_loadContainer = AccessTools.Method(typeof(Container), "Load", (Type[])null, (Type[])null);

		private static readonly MethodInfo s_destroyContainer = AccessTools.Method(typeof(Container), "OnDestroyed", (Type[])null, (Type[])null);

		private static readonly MethodInfo s_destroyPiece = AccessTools.Method(typeof(WearNTear), "Destroy", (Type[])null, (Type[])null);

		public Ship ShipComponent;

		public string ShipUUID = "";

		public ZDOID ShipZDOID = ZDOID.None;

		private readonly List<ZNetView> m_attachedPieces = new List<ZNetView>();

		public readonly List<Transform> DeckSnapPoints = new List<Transform>();

		public float DeckY = 0.35f;

		private Vector2s m_lastSector = new Vector2s(short.MinValue, short.MinValue);

		private Vector3 m_lastSyncedPos = Vector3.zero;

		private Quaternion m_lastSyncedRot = Quaternion.identity;

		private float m_syncTimer;

		private bool m_wasMoving;

		private float m_lastRecoverCheck = -30f;

		private bool m_isDestroyingPieces;

		private bool m_isRecheckingSupport;

		private Collider[] m_cargoBuffer = (Collider[])(object)new Collider[64];

		private readonly HashSet<ZNetView> m_seenCargo = new HashSet<ZNetView>();

		private float m_cargoScanTimer;

		private Collider[] m_cachedShipColliders = Array.Empty<Collider>();

		public List<ZNetView> AttachedPieces => m_attachedPieces;

		public bool HasMovedRecently { get; private set; } = true;

		private void Awake()
		{
			//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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			ShipComponent = ((Component)this).GetComponent<Ship>();
			m_lastSyncedPos = ((Component)this).transform.position;
			m_lastSyncedRot = ((Component)this).transform.rotation;
			CacheShipColliders();
			Rigidbody component2 = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.centerOfMass = component2.centerOfMass;
				if (component2.inertiaTensor != Vector3.zero)
				{
					component2.inertiaTensor = component2.inertiaTensor;
					component2.inertiaTensorRotation = component2.inertiaTensorRotation;
				}
			}
			Transform val = ((Component)this).transform.Find("_CargoCatchFloor");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			InitUUID();
			CreateDeckSnapPoints();
		}

		public void CacheShipColliders()
		{
			if (!((Object)(object)ShipComponent != (Object)null))
			{
				return;
			}
			ZNetView component = ((Component)ShipComponent).GetComponent<ZNetView>();
			List<Collider> list = new List<Collider>();
			Collider[] componentsInChildren = ((Component)ShipComponent).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)((Component)val).GetComponentInParent<ZNetView>() == (Object)(object)component)
				{
					list.Add(val);
				}
			}
			m_cachedShipColliders = list.ToArray();
		}

		public Collider[] GetCachedShipColliders()
		{
			if (m_cachedShipColliders == null || m_cachedShipColliders.Length == 0)
			{
				CacheShipColliders();
			}
			return m_cachedShipColliders;
		}

		private void Start()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			InitUUID();
			CacheShipColliders();
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				m_lastSector = ZoneSystem.GetZone(((Component)this).transform.position);
			}
			if (!string.IsNullOrEmpty(ShipUUID))
			{
				PieceAttachmentQueue.CheckPending(ShipUUID, ShipComponent);
			}
		}

		public void InitUUID()
		{
			//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)
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.GetZDO() != null)
			{
				ShipZDOID = component.GetZDO().m_uid;
				string text = component.GetZDO().GetString(ShipBuildPlugin.HashShipUUID, "");
				if (string.IsNullOrEmpty(ShipUUID) || (!string.IsNullOrEmpty(text) && text != ShipUUID))
				{
					ShipUUID = ShipRegistry.GetOrCreateShipUUID(component.GetZDO());
				}
				ShipRegistry.RegisterShip(ShipUUID, ShipComponent);
			}
		}

		private void OnDestroy()
		{
			if (ShipRegistry.ShipsByUUID.TryGetValue(ShipUUID, out var value) && (Object)(object)value == (Object)(object)ShipComponent)
			{
				ShipRegistry.UnregisterShip(ShipUUID);
			}
			if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner() && component.GetZDO().GetFloat(ZDOVars.s_health, 100f) <= 0f)
			{
				DestroyAllAttachedPieces();
				return;
			}
			SyncZDOPositions();
			for (int i = 0; i < m_attachedPieces.Count; i++)
			{
				ZNetView val = m_attachedPieces[i];
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).transform.SetParent((Transform)null);
				}
			}
		}

		public void DestroyAllAttachedPieces()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0593: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			if (m_isDestroyingPieces)
			{
				return;
			}
			m_isDestroyingPieces = true;
			HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
			string[] array = new string[2]
			{
				ShipUUID,
				((object)Unsafe.As<ZDOID, ZDOID>(ref ShipZDOID)/*cast due to .constrained prefix*/).ToString()
			};
			for (int i = 0; i < array.Length; i++)
			{
				HashSet<ZDOID> pieces = ShipPieceZdoIndex.GetPieces(array[i]);
				if (pieces != null)
				{
					hashSet.UnionWith(pieces);
				}
			}
			foreach (ZDOID item in hashSet)
			{
				ZDO zDO = ZDOMan.instance.GetZDO(item);
				if (zDO != null && ShipPiecePrefabValidator.IsShipPieceZDO(zDO))
				{
					ZNetView val = ZNetScene.instance.FindInstance(zDO);
					if ((Object)(object)val == (Object)null)
					{
						zDO.SetOwner(ZDOMan.GetSessionID());
						ShipPieceZdoHelper.MovePieceZDO(zDO, ((Component)this).transform.TransformPoint(zDO.GetVec3(ShipBuildPlugin.HashLocalPos, Vector3.zero)), ((Component)this).transform.rotation * Quaternion.Euler(zDO.GetVec3(ShipBuildPlugin.HashLocalRot, Vector3.zero)));
						GameObject val2 = (GameObject)s_createObject.Invoke(ZNetScene.instance, new object[1] { zDO });
						val = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<ZNetView>() : null);
					}
					if ((Object)(object)val != (Object)null && !m_attachedPieces.Contains(val))
					{
						m_attachedPieces.Add(val);
					}
				}
			}
			if (ShipNavigationManager.CurrentSpawnShipUUID == ShipUUID)
			{
				ShipNavigationManager.ClearShipSpawnBed();
			}
			ItemDrop[] componentsInChildren = ((Component)this).GetComponentsInChildren<ItemDrop>(true);
			Collider[] cachedShipColliders = GetCachedShipColliders();
			ItemDrop[] array2 = componentsInChildren;
			foreach (ItemDrop val3 in array2)
			{
				if (!((Object)(object)val3 != (Object)null))
				{
					continue;
				}
				((Component)val3).transform.SetParent((Transform)null);
				Collider[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren<Collider>(true);
				foreach (Collider val4 in componentsInChildren2)
				{
					if (!((Object)(object)val4 != (Object)null))
					{
						continue;
					}
					if (val4.isTrigger)
					{
						val4.isTrigger = false;
					}
					Collider[] array3 = cachedShipColliders;
					foreach (Collider val5 in array3)
					{
						if (Object.op_Implicit((Object)(object)val5) && (Object)(object)val5 != (Object)(object)val4)
						{
							Physics.IgnoreCollision(val5, val4, false);
						}
					}
				}
				Rigidbody component = ((Component)val3).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = false;
					component.useGravity = true;
				}
				Fl