Decompiled source of MovePosters v1.0.4

plugins/bobabulker.moveposters.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[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("bobabulker.moveposters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: AssemblyInformationalVersion("1.0.4+41092e55e62218fa40a3c81dec4bf51250428922")]
[assembly: AssemblyProduct("moveposters")]
[assembly: AssemblyTitle("bobabulker.moveposters")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 moveposters
{
	internal static class PosterConfig
	{
		private const float PixelsPerUnityUnit = 1000f;

		private static ConfigEntry<int>[] _widthPixels = null;

		private static ConfigEntry<int>[] _heightPixels = null;

		private static ConfigEntry<float>[] _tiltX = null;

		private static ConfigEntry<float>[] _tiltZ = null;

		private static bool _initialized;

		private static readonly int[] DefaultWidths = new int[4] { 639, 730, 749, 729 };

		private static readonly int[] DefaultHeights = new int[4] { 488, 490, 1054, 999 };

		private static readonly float[] DefaultTiltX = new float[4];

		private static readonly float[] DefaultTiltZ = new float[4] { 0f, 0f, -3.67f, 2.68f };

		internal static ConfigEntry<bool> LogErrors { get; private set; } = null;

		internal static ConfigEntry<bool> LogWarnings { get; private set; } = null;

		internal static ConfigEntry<bool> LogInfo { get; private set; } = null;

		internal static ConfigEntry<bool> LogDebugs { get; private set; } = null;

		public static void Initialize(ConfigFile config)
		{
			if (_initialized)
			{
				return;
			}
			_widthPixels = new ConfigEntry<int>[4];
			_heightPixels = new ConfigEntry<int>[4];
			_tiltX = new ConfigEntry<float>[4];
			_tiltZ = new ConfigEntry<float>[4];
			LogErrors = config.Bind<bool>("Logging", "LogErrors", true, "Enable error logging.");
			LogWarnings = config.Bind<bool>("Logging", "LogWarnings", true, "Enable warning logging.");
			LogDebugs = config.Bind<bool>("Logging", "LogDebugs", false, "Enable debug logging.");
			LogInfo = config.Bind<bool>("Logging", "LogInfo", false, "Enable informational logging.");
			for (int i = 0; i < 4; i++)
			{
				int num = i + 1;
				int capturedIndex = i;
				_widthPixels[i] = config.Bind<int>("Poster Shell Dimensions", $"Poster{num} Width", DefaultWidths[i], $"Poster {num} vanilla shell width in pixels.");
				_heightPixels[i] = config.Bind<int>("Poster Shell Dimensions", $"Poster{num} Height", DefaultHeights[i], $"Poster {num} vanilla shell height in pixels.");
				_tiltX[i] = config.Bind<float>("Poster Original Tilt", $"Poster{num} Tilt X", DefaultTiltX[i], $"Poster {num} original/default X tilt in degrees. " + "This is the starting tilt and does not control manual rotation.");
				_tiltZ[i] = config.Bind<float>("Poster Original Tilt", $"Poster{num} Tilt Z", DefaultTiltZ[i], $"Poster {num} original/default Z tilt in degrees. " + "This is the starting tilt and does not control manual rotation.");
				_widthPixels[i].SettingChanged += delegate
				{
					OnDimensionChanged(capturedIndex);
				};
				_heightPixels[i].SettingChanged += delegate
				{
					OnDimensionChanged(capturedIndex);
				};
				_tiltX[i].SettingChanged += delegate
				{
					OnTiltChanged(capturedIndex);
				};
				_tiltZ[i].SettingChanged += delegate
				{
					OnTiltChanged(capturedIndex);
				};
			}
			_initialized = true;
			Plugin.LogInfo("Poster shell configuration initialized.");
			for (int num2 = 0; num2 < 4; num2++)
			{
				Plugin.LogInfo($"Poster {num2 + 1} shell config: " + $"{GetWidthPixels(num2)}x{GetHeightPixels(num2)} px -> " + $"{PixelsToUnity(GetWidthPixels(num2)):0.###}x" + $"{PixelsToUnity(GetHeightPixels(num2)):0.###} Unity units");
				Plugin.LogInfo($"Poster {num2 + 1} original tilt: " + $"X={GetTiltX(num2):0.##}°, " + $"Z={GetTiltZ(num2):0.##}°");
			}
		}

		private static void OnDimensionChanged(int index)
		{
			if (_initialized)
			{
				Plugin.LogInfo($"Poster {index + 1} config changed: " + $"{GetWidthPixels(index)}x{GetHeightPixels(index)} px -> " + $"{PixelsToUnity(GetWidthPixels(index)):0.###}x" + $"{PixelsToUnity(GetHeightPixels(index)):0.###} Unity units");
				PosterFeature.ApplyConfigToShell(index);
			}
		}

		private static void OnTiltChanged(int index)
		{
			if (_initialized)
			{
				Plugin.LogInfo($"Poster {index + 1} tilt changed: " + $"X={GetTiltX(index):0.###}, " + $"Z={GetTiltZ(index):0.###}");
				PosterFeature.ApplyTiltToShell(index);
			}
		}

		public static int GetWidthPixels(int index)
		{
			if (index < 0 || index >= 4)
			{
				return 0;
			}
			return _widthPixels[index].Value;
		}

		public static int GetHeightPixels(int index)
		{
			if (index < 0 || index >= 4)
			{
				return 0;
			}
			return _heightPixels[index].Value;
		}

		public static float GetTiltX(int index)
		{
			if (index < 0 || index >= 4)
			{
				return 0f;
			}
			return _tiltX[index].Value;
		}

		public static float GetTiltZ(int index)
		{
			if (index < 0 || index >= 4)
			{
				return 0f;
			}
			return _tiltZ[index].Value;
		}

		public static Vector3 GetOriginalTilt(int index)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= 4)
			{
				return Vector3.zero;
			}
			return new Vector3(GetTiltX(index), 0f, GetTiltZ(index));
		}

		public static float PixelsToUnity(int pixels)
		{
			return (float)pixels / 1000f;
		}

		public static Vector3 GetShellSize(int index, Vector3 fallback)
		{
			//IL_0008: 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)
			if (index < 0 || index >= 4)
			{
				return fallback;
			}
			return new Vector3(PixelsToUnity(GetWidthPixels(index)), PixelsToUnity(GetHeightPixels(index)), 0.01f);
		}

		public static Vector3 GetShellVisualScale(int index, Vector3 meshBoundsSize)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= 4)
			{
				return Vector3.one;
			}
			float num = PixelsToUnity(GetWidthPixels(index));
			float num2 = PixelsToUnity(GetHeightPixels(index));
			float num3 = ((meshBoundsSize.x > 0.0001f) ? (num / meshBoundsSize.x) : 1f);
			float num4 = ((meshBoundsSize.y > 0.0001f) ? (num2 / meshBoundsSize.y) : 1f);
			return new Vector3(num3, num4, 1f);
		}
	}
	internal static class PosterFeature
	{
		private sealed class PosterEntry
		{
			public GameObject Poster { get; }

			public int Index { get; }

			public int UnlockableId { get; set; } = -1;

			public GameObject? Shell { get; set; }

			public GameObject? PosterVisual { get; set; }

			public PosterEntry(GameObject poster, int index)
			{
				Poster = poster;
				Index = index;
			}
		}

		private static readonly List<PosterEntry> Entries = new List<PosterEntry>();

		public static IReadOnlyList<GameObject> AllPosters
		{
			get
			{
				List<GameObject> list = new List<GameObject>(Entries.Count);
				foreach (PosterEntry entry in Entries)
				{
					if ((Object)(object)entry.Poster != (Object)null)
					{
						list.Add(entry.Poster);
					}
				}
				return list;
			}
		}

		public static void RegisterPoster(GameObject poster)
		{
			if ((Object)(object)poster == (Object)null)
			{
				return;
			}
			foreach (PosterEntry entry in Entries)
			{
				if ((Object)(object)entry.Poster == (Object)(object)poster)
				{
					return;
				}
			}
			int count = Entries.Count;
			PosterEntry posterEntry = new PosterEntry(poster, count);
			Entries.Add(posterEntry);
			Plugin.LogInfo(string.Format(arg1: posterEntry.UnlockableId = PosterUnlockables.GetId(count), format: "Poster {0} assigned unlockable ID {1}", arg0: count));
			Plugin.LogInfo($"Registered poster: {((Object)poster).name} (index={count})");
			LogPosterDiagnostics(poster);
		}

		public static int GetPosterIndex(GameObject poster)
		{
			if ((Object)(object)poster == (Object)null)
			{
				return -1;
			}
			foreach (PosterEntry entry in Entries)
			{
				if ((Object)(object)entry.Poster == (Object)(object)poster)
				{
					return entry.Index;
				}
			}
			return -1;
		}

		public static GameObject? GetPoster(int index)
		{
			if (index < 0 || index >= Entries.Count)
			{
				return null;
			}
			return Entries[index].Poster;
		}

		public static int GetUnlockableId(int index)
		{
			if (index < 0 || index >= Entries.Count)
			{
				return -1;
			}
			return Entries[index].UnlockableId;
		}

		public static void SetUnlockableId(int index, int unlockableId)
		{
			if (index < 0 || index >= Entries.Count)
			{
				Plugin.LogWarning("Cannot assign unlockable ID. " + $"Invalid poster index: {index}");
				return;
			}
			Entries[index].UnlockableId = unlockableId;
			Plugin.LogInfo($"Poster {index} assigned synthetic unlockable ID " + $"{unlockableId}");
		}

		public static GameObject? GetShell(int index)
		{
			if (index < 0 || index >= Entries.Count)
			{
				return null;
			}
			return Entries[index].Shell;
		}

		public static void SetShell(int index, GameObject shell)
		{
			if (index < 0 || index >= Entries.Count)
			{
				Plugin.LogWarning("Cannot assign shell. " + $"Invalid poster index: {index}");
				return;
			}
			Entries[index].Shell = shell;
			Plugin.LogInfo($"Poster {index} assigned shell: {((Object)shell).name}");
		}

		public static int GetPosterIndexByUnlockableId(int unlockableId)
		{
			foreach (PosterEntry entry in Entries)
			{
				if (entry.UnlockableId == unlockableId)
				{
					return entry.Index;
				}
			}
			return -1;
		}

		public static void SyncPosterToTransform(int index, Vector3 position, Quaternion rotation)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 0 && index < Entries.Count)
			{
				GameObject poster = Entries[index].Poster;
				if (!((Object)(object)poster == (Object)null))
				{
					poster.transform.SetPositionAndRotation(position, rotation);
				}
			}
		}

		public static void SyncPosterToShell(int index)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 0 && index < Entries.Count)
			{
				PosterEntry posterEntry = Entries[index];
				if (!((Object)(object)posterEntry.Poster == (Object)null) && !((Object)(object)posterEntry.Shell == (Object)null))
				{
					posterEntry.Poster.transform.SetPositionAndRotation(posterEntry.Shell.transform.position, posterEntry.Shell.transform.rotation);
				}
			}
		}

		public static void CreateShells()
		{
			if (Entries.Count == 0)
			{
				Plugin.LogWarning("Cannot create poster shells: no posters registered.");
				return;
			}
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer)
			{
				Plugin.LogInfo("Skipping poster shell creation on client. Shells are created by the host/server.");
				return;
			}
			GameObject val = FindClassicPaintingPrefab();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogError("Could not find ClassicPaintingContainer prefab.");
				return;
			}
			int num = Mathf.Min(4, Entries.Count);
			Plugin.LogInfo("Creating vanilla-build-mode shells for " + $"{num} posters...");
			for (int i = 0; i < num; i++)
			{
				CreateShell(i, val);
			}
			Plugin.LogInfo("Finished creating poster shells. " + $"Created {num} independent shells.");
		}

		private static void CreateShell(int index, GameObject classicPaintingPrefab)
		{
			if (index < 0 || index >= Entries.Count)
			{
				Plugin.LogWarning("Cannot create poster shell: " + $"invalid poster index {index}.");
				return;
			}
			PosterEntry posterEntry = Entries[index];
			GameObject poster = posterEntry.Poster;
			if ((Object)(object)poster == (Object)null)
			{
				Plugin.LogWarning("Cannot create shell: " + $"Poster {index + 1} is null.");
				return;
			}
			if ((Object)(object)posterEntry.Shell != (Object)null)
			{
				Plugin.LogInfo($"Poster {index + 1} shell already exists.");
				return;
			}
			int unlockableId = posterEntry.UnlockableId;
			if (unlockableId < 0)
			{
				Plugin.LogWarning($"Cannot create shell: Poster {index + 1} " + "has no unlockable ID.");
				return;
			}
			Plugin.LogInfo("Creating ClassicPaintingContainer shell for " + $"Poster {index + 1} " + $"(unlockable ID {unlockableId})...");
			GameObject val = Object.Instantiate<GameObject>(classicPaintingPrefab);
			((Object)val).name = $"MovePosters_Poster{index + 1}_Shell";
			if (!ConfigureShell(index, val, poster))
			{
				Object.Destroy((Object)(object)val);
				return;
			}
			posterEntry.Shell = val;
			NetworkObject component = val.GetComponent<NetworkObject>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.LogError($"Poster {index + 1} shell has no NetworkObject.");
				Object.Destroy((Object)(object)val);
				posterEntry.Shell = null;
				posterEntry.PosterVisual = null;
				return;
			}
			if (!component.IsSpawned)
			{
				component.Spawn(false);
				Plugin.LogInfo($"Spawned Poster {index + 1} shell as " + "network object. NetworkObjectId=" + $"{component.NetworkObjectId}");
			}
			Plugin.LogInfo($"Created Poster {index + 1} vanilla-build-mode shell " + $"with unlockable ID {unlockableId}.");
		}

		private static bool ConfigureShell(int index, GameObject shell, GameObject poster)
		{
			//IL_0212: 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_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: 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_025b: 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_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: 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_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)shell == (Object)null || (Object)(object)poster == (Object)null)
			{
				return false;
			}
			if (index < 0 || index >= Entries.Count)
			{
				Plugin.LogWarning("Cannot configure poster shell: " + $"invalid index {index}");
				return false;
			}
			int unlockableId = Entries[index].UnlockableId;
			if (unlockableId < 0)
			{
				Plugin.LogWarning($"Cannot configure Poster {index + 1} shell: " + "no unlockable ID.");
				return false;
			}
			AutoParentToShip component = shell.GetComponent<AutoParentToShip>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
				Plugin.LogInfo("Disabled AutoParentToShip while configuring " + $"Poster {index + 1} shell.");
			}
			shell.SetActive(true);
			PlaceableShipObject componentInChildren = shell.GetComponentInChildren<PlaceableShipObject>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.LogError($"Poster {index + 1} shell has no " + "PlaceableShipObject.");
				return false;
			}
			componentInChildren.unlockableID = unlockableId;
			componentInChildren.AllowPlacementOnWalls = true;
			componentInChildren.AllowPlacementOnCounters = true;
			componentInChildren.overrideWallOffset = true;
			componentInChildren.wallOffset = 0.01f;
			Collider placeObjectCollider = componentInChildren.placeObjectCollider;
			BoxCollider val = (BoxCollider)(object)((placeObjectCollider is BoxCollider) ? placeObjectCollider : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogError($"Poster {index + 1} shell " + "PlaceableShipObject has no BoxCollider placement collider.");
				return false;
			}
			MeshRenderer[] componentsInChildren = shell.GetComponentsInChildren<MeshRenderer>(true);
			MeshRenderer[] array = componentsInChildren;
			foreach (MeshRenderer val2 in array)
			{
				((Renderer)val2).enabled = false;
			}
			GameObject val3 = CreatePosterVisual(shell, poster);
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.LogError($"Could not create Poster {index + 1} visual.");
				return false;
			}
			Entries[index].PosterVisual = val3;
			MeshFilter component2 = val3.GetComponent<MeshFilter>();
			if ((Object)(object)component2 == (Object)null || (Object)(object)component2.sharedMesh == (Object)null)
			{
				Plugin.LogError($"Poster {index + 1} visual has no usable MeshFilter.");
				return false;
			}
			componentInChildren.mainMesh = component2;
			componentInChildren.mainTransform = val3.transform;
			((Component)val).transform.localPosition = Vector3.zero;
			((Component)val).transform.localRotation = Quaternion.identity;
			Bounds bounds = component2.sharedMesh.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			bounds = component2.sharedMesh.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			Vector3 shellSize = PosterConfig.GetShellSize(index, new Vector3(Mathf.Max(size.x, 0.05f), Mathf.Max(size.y, 0.05f), 0.01f));
			Vector3 shellVisualScale = PosterConfig.GetShellVisualScale(index, size);
			val3.transform.localScale = shellVisualScale;
			Vector3 center2 = Vector3.Scale(center, shellVisualScale);
			val.size = shellSize;
			val.center = center2;
			int num = LayerMask.NameToLayer("PlaceableObject");
			if (num < 0)
			{
				num = 26;
			}
			((Component)val).gameObject.layer = num;
			((Component)val).gameObject.tag = "PlaceableObject";
			((Collider)val).enabled = true;
			Collider[] componentsInChildren2 = shell.GetComponentsInChildren<Collider>(true);
			foreach (Collider val4 in componentsInChildren2)
			{
				if ((Object)(object)val4 != (Object)(object)val)
				{
					val4.enabled = false;
				}
			}
			shell.transform.position = poster.transform.position;
			Vector3 eulerAngles = poster.transform.eulerAngles;
			shell.transform.rotation = Quaternion.Euler(eulerAngles.x + PosterConfig.GetTiltX(index), eulerAngles.y, eulerAngles.z + PosterConfig.GetTiltZ(index));
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.identity;
			Plugin.LogInfo("POSTER SHELL CONFIG: " + $"Poster {index + 1} | " + "pixels=" + $"{PosterConfig.GetWidthPixels(index)}x" + $"{PosterConfig.GetHeightPixels(index)} | " + $"unitySize={shellSize} | " + $"visualScale={shellVisualScale}");
			string text = $"FINAL Poster {index + 1} shell: ";
			string text2 = $"position={shell.transform.position}, ";
			Quaternion rotation = shell.transform.rotation;
			Plugin.LogInfo(text + text2 + $"rotation={((Quaternion)(ref rotation)).eulerAngles}");
			string[] obj = new string[7]
			{
				$"FINAL Poster {index + 1} visual: ",
				"mesh=",
				((Object)component2.sharedMesh).name,
				", ",
				$"position={val3.transform.position}, ",
				null,
				null
			};
			rotation = val3.transform.rotation;
			obj[5] = $"rotation={((Quaternion)(ref rotation)).eulerAngles}, ";
			obj[6] = $"scale={val3.transform.localScale}";
			Plugin.LogInfo(string.Concat(obj));
			Plugin.LogInfo($"FINAL Poster {index + 1} placement collider: " + $"position={((Component)val).transform.position}, " + $"rotation={((Component)val).transform.eulerAngles}, " + $"center={val.center}, " + $"size={val.size}, " + $"layer={((Component)val).gameObject.layer}, " + "tag=" + ((Component)val).gameObject.tag);
			return true;
		}

		private static GameObject? CreatePosterVisual(GameObject shell, GameObject poster)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: 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)
			if ((Object)(object)shell == (Object)null || (Object)(object)poster == (Object)null)
			{
				return null;
			}
			MeshFilter component = poster.GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.LogWarning("Poster " + ((Object)poster).name + " has no MeshFilter.");
				return null;
			}
			if ((Object)(object)component.sharedMesh == (Object)null)
			{
				Plugin.LogWarning("Poster " + ((Object)poster).name + " has no mesh.");
				return null;
			}
			MeshRenderer component2 = poster.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 == (Object)null)
			{
				Plugin.LogWarning("Poster " + ((Object)poster).name + " has no MeshRenderer.");
				return null;
			}
			GameObject val = new GameObject("PosterVisual");
			val.transform.SetParent(shell.transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			Mesh val3 = Object.Instantiate<Mesh>(component.sharedMesh);
			int[] triangles = val3.triangles;
			for (int i = 0; i + 2 < triangles.Length; i += 3)
			{
				int num = triangles[i];
				triangles[i] = triangles[i + 2];
				triangles[i + 2] = num;
			}
			val3.triangles = triangles;
			val3.RecalculateNormals();
			val3.RecalculateBounds();
			val2.sharedMesh = val3;
			MeshRenderer val4 = val.AddComponent<MeshRenderer>();
			((Renderer)val4).sharedMaterials = ((Renderer)component2).sharedMaterials;
			((Renderer)val4).enabled = false;
			((Renderer)val4).shadowCastingMode = ((Renderer)component2).shadowCastingMode;
			((Renderer)val4).receiveShadows = ((Renderer)component2).receiveShadows;
			((Renderer)val4).lightProbeUsage = ((Renderer)component2).lightProbeUsage;
			((Renderer)val4).reflectionProbeUsage = ((Renderer)component2).reflectionProbeUsage;
			Plugin.LogInfo("Created PosterVisual from " + ((Object)poster).name + ": mesh=" + ((Object)val2.sharedMesh).name + ", " + $"materials={((Renderer)val4).sharedMaterials.Length}");
			return val;
		}

		private static GameObject? FindClassicPaintingPrefab()
		{
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				if ((Object)(object)val == (Object)null || ((Object)val).name != "ClassicPaintingContainer")
				{
					continue;
				}
				NetworkObject component = val.GetComponent<NetworkObject>();
				if (!((Object)(object)component == (Object)null))
				{
					PlaceableShipObject componentInChildren = val.GetComponentInChildren<PlaceableShipObject>();
					if (!((Object)(object)componentInChildren == (Object)null))
					{
						Plugin.LogInfo("Found ClassicPaintingContainer prefab.");
						return val;
					}
				}
			}
			return null;
		}

		public static void ClearPosters()
		{
			foreach (PosterEntry entry in Entries)
			{
				if ((Object)(object)entry.Shell != (Object)null)
				{
					Object.Destroy((Object)(object)entry.Shell);
				}
			}
			Entries.Clear();
			Plugin.LogDebug("Cleared registered posters.");
		}

		private static void LogPosterDiagnostics(GameObject poster)
		{
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			Component[] components = poster.GetComponents<Component>();
			Component[] array = components;
			foreach (Component val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Plugin.LogInfo("  Component: " + ((object)val).GetType().FullName);
				}
			}
			Collider[] componentsInChildren = poster.GetComponentsInChildren<Collider>(true);
			if (componentsInChildren.Length == 0)
			{
				Plugin.LogInfo("  Collider: NONE");
			}
			else
			{
				Collider[] array2 = componentsInChildren;
				foreach (Collider val2 in array2)
				{
					Plugin.LogInfo("  Collider: " + ((object)val2).GetType().FullName + ", " + $"enabled={val2.enabled}, " + $"isTrigger={val2.isTrigger}");
				}
			}
			MeshFilter component = poster.GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				Mesh sharedMesh = component.sharedMesh;
				string[] obj = new string[6]
				{
					"  Mesh: ",
					((Object)sharedMesh).name,
					", ",
					$"vertices={sharedMesh.vertexCount}, ",
					null,
					null
				};
				Bounds bounds = sharedMesh.bounds;
				obj[4] = $"boundsCenter={((Bounds)(ref bounds)).center}, ";
				bounds = sharedMesh.bounds;
				obj[5] = $"boundsSize={((Bounds)(ref bounds)).size}";
				Plugin.LogInfo(string.Concat(obj));
			}
			else
			{
				Plugin.LogInfo("  Mesh: NONE");
			}
			Transform transform = poster.transform;
			Plugin.LogInfo($"Position: {transform.position}, " + $"Rotation: {transform.rotation}, " + $"Forward: {transform.forward}, " + $"Up: {transform.up}, " + $"Right: {transform.right}");
			int posterIndex = GetPosterIndex(poster);
			if (posterIndex >= 0 && posterIndex < 4)
			{
				Plugin.LogInfo($"POSTER GEOMETRY CONFIG: Poster{posterIndex + 1} | " + $"pixels={PosterConfig.GetWidthPixels(posterIndex)}x{PosterConfig.GetHeightPixels(posterIndex)} | " + "unity=" + $"{PosterConfig.PixelsToUnity(PosterConfig.GetWidthPixels(posterIndex)):0.###}x" + $"{PosterConfig.PixelsToUnity(PosterConfig.GetHeightPixels(posterIndex)):0.###}");
			}
		}

		public static void LogBuildModeState()
		{
			ShipBuildModeManager instance = ShipBuildModeManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.LogWarning("ShipBuildModeManager.Instance is null.");
				return;
			}
			Plugin.LogInfo("ShipBuildModeManager found: " + $"InBuildMode={instance.InBuildMode}");
			if (Entries.Count == 0)
			{
				Plugin.LogWarning("No poster entries exist.");
				return;
			}
			for (int i = 0; i < Entries.Count; i++)
			{
				GameObject shell = Entries[i].Shell;
				if ((Object)(object)shell == (Object)null)
				{
					Plugin.LogWarning($"Poster {i + 1} shell is null.");
					continue;
				}
				PlaceableShipObject componentInChildren = shell.GetComponentInChildren<PlaceableShipObject>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					Plugin.LogWarning($"Poster {i + 1} shell has no " + "PlaceableShipObject.");
					continue;
				}
				Plugin.LogInfo($"Poster {i + 1} shell " + "PlaceableShipObject: " + ((Object)((Component)componentInChildren).gameObject).name);
				Plugin.LogInfo($"Poster {i + 1} shell layer=" + $"{((Component)componentInChildren).gameObject.layer}");
				if ((Object)(object)componentInChildren.placeObjectCollider != (Object)null)
				{
					Plugin.LogInfo($"Poster {i + 1} shell collider layer=" + $"{((Component)componentInChildren.placeObjectCollider).gameObject.layer}");
					Plugin.LogInfo($"Poster {i + 1} shell collider tag=" + ((Component)componentInChildren.placeObjectCollider).gameObject.tag);
				}
				string text = $"Poster {i + 1} shell mainMesh=";
				MeshFilter mainMesh = componentInChildren.mainMesh;
				Plugin.LogInfo(text + (((mainMesh != null) ? ((Object)((Component)mainMesh).gameObject).name : null) ?? "NULL"));
				string text2 = $"Poster {i + 1} shell mainMesh.mesh=";
				MeshFilter mainMesh2 = componentInChildren.mainMesh;
				object obj;
				if (mainMesh2 == null)
				{
					obj = null;
				}
				else
				{
					Mesh sharedMesh = mainMesh2.sharedMesh;
					obj = ((sharedMesh != null) ? ((Object)sharedMesh).name : null);
				}
				if (obj == null)
				{
					obj = "NULL";
				}
				Plugin.LogInfo(text2 + (string?)obj);
			}
		}

		public static void TestShellRaycast()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (Entries.Count == 0)
			{
				Plugin.LogWarning("Cannot test shell raycast: no posters.");
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null)
			{
				Plugin.LogWarning("Cannot test shell raycast: local player is null.");
				return;
			}
			Camera gameplayCamera = localPlayerController.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null)
			{
				Plugin.LogWarning("Cannot test shell raycast: gameplay camera is null.");
				return;
			}
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)gameplayCamera).transform.position, ((Component)gameplayCamera).transform.forward);
			RaycastHit val2 = default(RaycastHit);
			for (int i = 0; i < Entries.Count; i++)
			{
				GameObject shell = Entries[i].Shell;
				if ((Object)(object)shell == (Object)null)
				{
					continue;
				}
				PlaceableShipObject componentInChildren = shell.GetComponentInChildren<PlaceableShipObject>();
				if ((Object)(object)componentInChildren == (Object)null)
				{
					continue;
				}
				Collider placeObjectCollider = componentInChildren.placeObjectCollider;
				if (!((Object)(object)placeObjectCollider == (Object)null))
				{
					int layer = ((Component)placeObjectCollider).gameObject.layer;
					int num = 1 << layer;
					if (Physics.Raycast(val, ref val2, 4f, num, (QueryTriggerInteraction)1))
					{
						Plugin.LogInfo($"POSTER {i + 1} TEST RAY HIT: " + "object=" + ((Object)((Component)((RaycastHit)(ref val2)).collider).gameObject).name + ", tag=" + ((Component)((RaycastHit)(ref val2)).collider).gameObject.tag + ", " + $"layer={((Component)((RaycastHit)(ref val2)).collider).gameObject.layer}, " + $"distance={((RaycastHit)(ref val2)).distance}");
					}
				}
			}
		}

		public static void LogTestShellTransform()
		{
			//IL_003b: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Entries.Count; i++)
			{
				GameObject shell = Entries[i].Shell;
				if (!((Object)(object)shell == (Object)null))
				{
					string text = $"POSTER {i + 1} SHELL TRANSFORM: ";
					string text2 = $"position={shell.transform.position}, ";
					Quaternion rotation = shell.transform.rotation;
					Plugin.LogInfo(text + text2 + $"rotation={((Quaternion)(ref rotation)).eulerAngles}");
				}
			}
		}

		public static void ApplyConfigToShell(int index)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= Entries.Count)
			{
				return;
			}
			PosterEntry posterEntry = Entries[index];
			if ((Object)(object)posterEntry.Shell == (Object)null)
			{
				Plugin.LogDebug($"Poster {index + 1} config changed, " + "but its shell does not exist yet.");
				return;
			}
			PlaceableShipObject componentInChildren = posterEntry.Shell.GetComponentInChildren<PlaceableShipObject>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				Plugin.LogWarning($"Poster {index + 1} shell has no " + "PlaceableShipObject.");
				return;
			}
			Collider placeObjectCollider = componentInChildren.placeObjectCollider;
			BoxCollider val = (BoxCollider)(object)((placeObjectCollider is BoxCollider) ? placeObjectCollider : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogWarning($"Poster {index + 1} shell has no BoxCollider.");
				return;
			}
			Vector3 shellSize = PosterConfig.GetShellSize(index, val.size);
			val.size = shellSize;
			if ((Object)(object)posterEntry.PosterVisual != (Object)null)
			{
				MeshFilter component = posterEntry.PosterVisual.GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
				{
					Bounds bounds = component.sharedMesh.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					posterEntry.PosterVisual.transform.localScale = PosterConfig.GetShellVisualScale(index, size);
				}
			}
			Plugin.LogInfo($"Applied live config to Poster {index + 1}: " + "pixels=" + $"{PosterConfig.GetWidthPixels(index)}x" + $"{PosterConfig.GetHeightPixels(index)} | " + $"collider={val.size}");
		}

		public static void ApplyTiltToShell(int index)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 0 && index < Entries.Count)
			{
				PosterEntry posterEntry = Entries[index];
				if ((Object)(object)posterEntry.Shell == (Object)null)
				{
					Plugin.LogWarning($"Cannot apply tilt to Poster {index + 1}: " + "shell does not exist.");
					return;
				}
				GameObject shell = posterEntry.Shell;
				Vector3 eulerAngles = shell.transform.eulerAngles;
				float tiltX = PosterConfig.GetTiltX(index);
				float tiltZ = PosterConfig.GetTiltZ(index);
				shell.transform.rotation = Quaternion.Euler(tiltX, eulerAngles.y, tiltZ);
				SyncPosterToTransform(index, shell.transform.position, shell.transform.rotation);
				Plugin.LogInfo($"Applied live tilt to Poster {index + 1}: " + $"X={tiltX:0.###}, " + $"Y={eulerAngles.y:0.###}, " + $"Z={tiltZ:0.###}");
			}
		}
	}
	internal static class PosterSelector
	{
		private static InputAction? _rotateAction;

		private static bool _isMoving;

		private static GameObject? _movingPoster;

		private static GameObject? _selectedPoster;

		public static GameObject? SelectedPoster => _selectedPoster;

		public static void CheckSelection(PlayerControllerB player)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			Camera gameplayCamera = player.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null || !((Behaviour)gameplayCamera).enabled)
			{
				return;
			}
			Ray ray = default(Ray);
			((Ray)(ref ray))..ctor(((Component)gameplayCamera).transform.position, ((Component)gameplayCamera).transform.forward);
			GameObject selectedPoster = null;
			float num = float.MaxValue;
			foreach (GameObject allPoster in PosterFeature.AllPosters)
			{
				if (!((Object)(object)allPoster == (Object)null) && allPoster.activeInHierarchy && TryIntersectPoster(ray, allPoster, out var distance) && distance < num)
				{
					selectedPoster = allPoster;
					num = distance;
				}
			}
			SetSelectedPoster(selectedPoster);
		}

		private static void SetSelectedPoster(GameObject? poster)
		{
			if (!((Object)(object)_selectedPoster == (Object)(object)poster))
			{
				_selectedPoster = poster;
				if ((Object)(object)_selectedPoster != (Object)null)
				{
					Plugin.LogInfo("Selected poster: " + ((Object)_selectedPoster).name);
				}
				else
				{
					Plugin.LogInfo("Selected poster: NONE");
				}
			}
		}

		private static bool TryIntersectPoster(Ray ray, GameObject poster, out float distance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			distance = 0f;
			MeshFilter component = poster.GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				return false;
			}
			Mesh sharedMesh = component.sharedMesh;
			Bounds bounds = sharedMesh.bounds;
			Transform transform = poster.transform;
			Vector3 forward = transform.forward;
			float num = Vector3.Dot(((Ray)(ref ray)).direction, forward);
			if (Mathf.Abs(num) < 0.0001f)
			{
				return false;
			}
			Vector3 val = transform.TransformPoint(((Bounds)(ref bounds)).center);
			float num2 = Vector3.Dot(val - ((Ray)(ref ray)).origin, forward) / num;
			if (num2 < 0f)
			{
				return false;
			}
			Vector3 point = ((Ray)(ref ray)).GetPoint(num2);
			Vector3 val2 = transform.InverseTransformPoint(point);
			((Bounds)(ref bounds)).Expand(0.05f);
			if (!((Bounds)(ref bounds)).Contains(val2))
			{
				return false;
			}
			distance = num2;
			return true;
		}

		public static void TryMoveSelectedPoster()
		{
			if (_isMoving)
			{
				if ((Object)(object)_movingPoster != (Object)null)
				{
					Plugin.LogInfo("Stopped moving poster: " + ((Object)_movingPoster).name);
				}
				else
				{
					Plugin.LogInfo("Stopped moving poster: NONE");
				}
				_isMoving = false;
				_movingPoster = null;
			}
			else if (!((Object)(object)_selectedPoster == (Object)null))
			{
				_movingPoster = _selectedPoster;
				_isMoving = true;
				Plugin.LogInfo("Started moving poster: " + ((Object)_movingPoster).name);
			}
		}

		public static void UpdateMovingPoster(Camera camera)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_00a0: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!_isMoving || (Object)(object)_movingPoster == (Object)null)
			{
				return;
			}
			BoxCollider component = _movingPoster.GetComponent<BoxCollider>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			bool enabled = ((Collider)component).enabled;
			((Collider)component).enabled = false;
			try
			{
				Ray val = default(Ray);
				((Ray)(ref val))..ctor(((Component)camera).transform.position, ((Component)camera).transform.forward);
				RaycastHit val2 = default(RaycastHit);
				if (Physics.Raycast(val, ref val2, 20f, 2305, (QueryTriggerInteraction)1))
				{
					float num = (component.size.z / 2f + component.size.x / 2f) / 20f;
					Vector3 position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * (num + 0.01f);
					_movingPoster.transform.position = position;
				}
			}
			finally
			{
				((Collider)component).enabled = enabled;
			}
		}

		public static void SubscribeToRotate()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (_rotateAction == null)
			{
				_rotateAction = new InputAction("MovePosterRotate", (InputActionType)1, "<Keyboard>/r", (string)null, (string)null, (string)null);
				_rotateAction.performed += OnRotatePerformed;
				_rotateAction.Enable();
				Plugin.LogInfo("Subscribed to poster rotation input.");
			}
		}

		private static void OnRotatePerformed(CallbackContext context)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (_isMoving && !((Object)(object)_movingPoster == (Object)null))
			{
				Transform transform = _movingPoster.transform;
				transform.Rotate(Vector3.up, 15f, (Space)0);
			}
		}
	}
	internal static class PosterShellTest
	{
		public static void ApplyPosterVisual(GameObject shell, GameObject poster)
		{
			if ((Object)(object)shell == (Object)null || (Object)(object)poster == (Object)null)
			{
				Plugin.LogWarning("Cannot apply poster visual: shell or poster is null.");
				return;
			}
			MeshFilter component = poster.GetComponent<MeshFilter>();
			MeshRenderer component2 = poster.GetComponent<MeshRenderer>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Plugin.LogWarning("Poster " + ((Object)poster).name + " is missing MeshFilter or MeshRenderer.");
				return;
			}
			Transform val = shell.transform.Find("Cube");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogWarning("Classic Painting shell has no Cube child.");
				return;
			}
			MeshFilter component3 = ((Component)val).GetComponent<MeshFilter>();
			MeshRenderer component4 = ((Component)val).GetComponent<MeshRenderer>();
			if ((Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null)
			{
				Plugin.LogWarning("Classic Painting Cube is missing MeshFilter or MeshRenderer.");
				return;
			}
			component3.sharedMesh = component.sharedMesh;
			((Renderer)component4).sharedMaterials = ((Renderer)component2).sharedMaterials;
			((Renderer)component4).enabled = ((Renderer)component2).enabled;
			Plugin.LogInfo("Applied " + ((Object)poster).name + " visual to shell.");
			Plugin.LogInfo($"  Mesh: {component.sharedMesh}");
			Plugin.LogInfo("  Material count: " + $"{((Renderer)component2).sharedMaterials.Length}");
		}
	}
	internal static class PosterUnlockables
	{
		private static readonly List<int> _posterIds = new List<int>();

		public static IReadOnlyList<int> PosterIds => _posterIds;

		public static bool Initialized { get; private set; }

		public static void Initialize(StartOfRound round, int posterCount)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if (Initialized)
			{
				return;
			}
			if ((Object)(object)round.unlockablesList == (Object)null)
			{
				Plugin.LogError("Cannot initialize poster unlockables: UnlockablesList is null.");
				return;
			}
			List<UnlockableItem> unlockables = round.unlockablesList.unlockables;
			_posterIds.Clear();
			int count = unlockables.Count;
			Plugin.LogInfo($"Allocating {posterCount} synthetic poster unlockables starting at ID {count}");
			for (int i = 0; i < posterCount; i++)
			{
				int count2 = unlockables.Count;
				UnlockableItem item = new UnlockableItem
				{
					unlockableName = $"MovePosters Poster {i + 1}",
					unlockableType = 1,
					IsPlaceable = true,
					spawnPrefab = false,
					hasBeenUnlockedByPlayer = false,
					alreadyUnlocked = false,
					canBeStored = false,
					inStorage = false,
					hasBeenMoved = false,
					placedPosition = Vector3.zero,
					placedRotation = Vector3.zero,
					maxNumber = 1
				};
				unlockables.Add(item);
				_posterIds.Add(count2);
				Plugin.LogInfo($"Poster {i + 1}: synthetic unlockable ID={count2}");
			}
			Initialized = true;
			Plugin.LogInfo($"Allocated poster unlockables: {count} through {unlockables.Count - 1}");
		}

		public static int GetId(int posterIndex)
		{
			if (!Initialized)
			{
				Plugin.LogError("Poster unlockables have not been initialized.");
				return -1;
			}
			if (posterIndex < 0 || posterIndex >= _posterIds.Count)
			{
				Plugin.LogError($"Invalid poster index: {posterIndex}");
				return -1;
			}
			return _posterIds[posterIndex];
		}

		public static bool IsPosterId(int id)
		{
			return _posterIds.Contains(id);
		}
	}
	[BepInPlugin("bobabulker.moveposters", "moveposters", "1.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			PosterConfig.Initialize(((BaseUnityPlugin)this).Config);
			LogInfo("Plugin Awake.");
			Patch();
			LogInfo("bobabulker.moveposters v1.0.4 has loaded!");
		}

		internal static void LogError(object data)
		{
			if (PosterConfig.LogErrors.Value)
			{
				Logger.LogError(data);
			}
		}

		internal static void LogWarning(object data)
		{
			if (PosterConfig.LogWarnings.Value)
			{
				Logger.LogWarning(data);
			}
		}

		internal static void LogInfo(object data)
		{
			if (PosterConfig.LogInfo.Value)
			{
				Logger.LogInfo(data);
			}
		}

		internal static void LogDebug(object data)
		{
			if (PosterConfig.LogDebugs.Value)
			{
				Logger.LogDebug(data);
			}
		}

		internal static void Patch()
		{
			//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_0017: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("bobabulker.moveposters");
			}
			LogDebug("Patching...");
			Harmony.PatchAll();
			LogDebug("Finished patching!");
		}

		internal static void Unpatch()
		{
			LogDebug("Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			LogDebug("Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "bobabulker.moveposters";

		public const string PLUGIN_NAME = "moveposters";

		public const string PLUGIN_VERSION = "1.0.4";
	}
}
namespace moveposters.Patches
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class PosterPatches
	{
		private static bool _customPostersPatched;

		private static bool _posterUnlockablesInitialized;

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void OnRoundStart(StartOfRound __instance)
		{
			InitializePosterUnlockables(__instance);
			TryPatchCustomPosters();
		}

		private static void InitializePosterUnlockables(StartOfRound round)
		{
			if (!_posterUnlockablesInitialized)
			{
				if ((Object)(object)round.unlockablesList == (Object)null)
				{
					Plugin.LogWarning("UnlockablesList is null. Cannot initialize poster unlockables");
					return;
				}
				PosterUnlockables.Initialize(round, 4);
				_posterUnlockablesInitialized = true;
			}
		}

		private static void TryPatchCustomPosters()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (_customPostersPatched)
			{
				return;
			}
			Type type = AccessTools.TypeByName("CustomPosters.PosterManager");
			if (type == null)
			{
				Plugin.LogDebug("CustomPosters not detected. Skipping CustomPosters integration.");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "ApplyPosterTransform", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Plugin.LogWarning("CustomPosters detected, but ApplyPosterTransform was not found.");
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(PosterPatches), "AfterApplyPosterTransform", (Type[])null);
			Plugin.Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_customPostersPatched = true;
			Plugin.LogInfo("CustomPosters detected. Poster transform integration enabled.");
		}

		private static void AfterApplyPosterTransform(GameObject poster)
		{
			if (!((Object)(object)poster == (Object)null))
			{
				PosterFeature.RegisterPoster(poster);
				if (PosterFeature.AllPosters.Count >= 4)
				{
					PosterFeature.CreateShells();
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class BuildModePatches
	{
		private static bool _lastBuildModeState;

		private static Vector3 _lastPosition;

		private static Vector3 _lastRotation;

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void LogBuildModeState(ShipBuildModeManager __instance)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.InBuildMode != _lastBuildModeState)
			{
				_lastBuildModeState = __instance.InBuildMode;
				Plugin.LogInfo("ShipBuildModeManager InBuildMode changed to " + $"{__instance.InBuildMode}");
				if (PosterFeature.AllPosters.Count > 0)
				{
					PosterFeature.LogTestShellTransform();
				}
			}
			if (!__instance.InBuildMode)
			{
				return;
			}
			IReadOnlyList<GameObject> allPosters = PosterFeature.AllPosters;
			if (allPosters.Count == 0)
			{
				return;
			}
			GameObject shell = PosterFeature.GetShell(0);
			if (!((Object)(object)shell == (Object)null))
			{
				Vector3 position = shell.transform.position;
				Quaternion rotation = shell.transform.rotation;
				Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
				if (position != _lastPosition || eulerAngles != _lastRotation)
				{
					_lastPosition = position;
					_lastRotation = eulerAngles;
					Plugin.LogInfo("TEST SHELL MOVED: " + $"position={position}, " + $"rotation={eulerAngles}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class BuildModeEnterPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EnterBuildMode")]
		private static void BeforeEnterBuildMode(ShipBuildModeManager __instance)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: 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_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null)
			{
				Plugin.LogWarning("EnterBuildMode called, but local player is null.");
				return;
			}
			if ((Object)(object)localPlayerController.gameplayCamera == (Object)null)
			{
				Plugin.LogWarning("EnterBuildMode called, but gameplay camera is null.");
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(typeof(ShipBuildModeManager), "placeableShipObjectsMask");
			if (fieldInfo == null)
			{
				Plugin.LogError("Could not find placeableShipObjectsMask field.");
				return;
			}
			int num = (int)fieldInfo.GetValue(__instance);
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(((Component)localPlayerController.gameplayCamera).transform.position, ((Component)localPlayerController.gameplayCamera).transform.forward);
			Plugin.LogInfo("EnterBuildMode pressed. " + $"InBuildMode={__instance.InBuildMode}, " + $"mask={num}, " + $"camera={((Ray)(ref val)).origin}, " + $"forward={((Ray)(ref val)).direction}");
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 10f, num, (QueryTriggerInteraction)1))
			{
				Plugin.LogInfo("BUILD RAY HIT: object=" + ((Object)((Component)((RaycastHit)(ref val2)).collider).gameObject).name + ", tag=" + ((Component)((RaycastHit)(ref val2)).collider).gameObject.tag + ", " + $"layer={((Component)((RaycastHit)(ref val2)).collider).gameObject.layer}, " + $"distance={((RaycastHit)(ref val2)).distance}");
				PlaceableShipObject component = ((Component)((RaycastHit)(ref val2)).collider).gameObject.GetComponent<PlaceableShipObject>();
				Plugin.LogInfo("BUILD RAY PlaceableShipObject=" + (((Object)(object)component != (Object)null) ? ((Object)((Component)component).gameObject).name : "NULL"));
				return;
			}
			Plugin.LogInfo("BUILD RAY HIT NOTHING.");
			GameObject shell = PosterFeature.GetShell(0);
			if ((Object)(object)shell != (Object)null)
			{
				PlaceableShipObject componentInChildren = shell.GetComponentInChildren<PlaceableShipObject>();
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.placeObjectCollider != (Object)null)
				{
					Collider placeObjectCollider = componentInChildren.placeObjectCollider;
					Bounds bounds = placeObjectCollider.bounds;
					Vector3 center = ((Bounds)(ref bounds)).center;
					Vector3 val3 = center - ((Ray)(ref val)).origin;
					Vector3 normalized = ((Vector3)(ref val3)).normalized;
					float num2 = Vector3.Distance(((Ray)(ref val)).origin, center);
					Plugin.LogInfo("DIRECT SHELL TEST: " + $"target={center}, " + $"distance={num2}, " + $"direction={normalized}");
					RaycastHit val4 = default(RaycastHit);
					if (Physics.Raycast(((Ray)(ref val)).origin, normalized, ref val4, num2 + 0.5f, num, (QueryTriggerInteraction)1))
					{
						Plugin.LogInfo("DIRECT SHELL RAY HIT: object=" + ((Object)((Component)((RaycastHit)(ref val4)).collider).gameObject).name + ", tag=" + ((Component)((RaycastHit)(ref val4)).collider).gameObject.tag + ", " + $"layer={((Component)((RaycastHit)(ref val4)).collider).gameObject.layer}, " + $"distance={((RaycastHit)(ref val4)).distance}");
					}
					else
					{
						Plugin.LogError("DIRECT SHELL RAY MISSED THE SHELL!");
					}
				}
			}
			Collider[] array = Physics.OverlapSphere(((Ray)(ref val)).origin + ((Ray)(ref val)).direction * 3f, 3f, num, (QueryTriggerInteraction)1);
			Plugin.LogInfo($"Found {array.Length} layer-{26} colliders " + "within 3m of ray.");
			Collider[] array2 = array;
			foreach (Collider val5 in array2)
			{
				Plugin.LogInfo("Nearby build collider: object=" + ((Object)((Component)val5).gameObject).name + ", tag=" + ((Component)val5).gameObject.tag + ", " + $"layer={((Component)val5).gameObject.layer}, " + $"position={((Component)val5).transform.position}");
			}
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class PosterLiveMovementPatch
	{
		private static int _activePosterIndex = -1;

		private static bool _hasOriginalPosterTransform;

		private static Vector3 _originalPosterPosition;

		private static Quaternion _originalPosterRotation;

		[HarmonyPostfix]
		[HarmonyPatch("EnterBuildMode")]
		private static void AfterEnterBuildMode(ShipBuildModeManager __instance)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			object? obj = AccessTools.Field(typeof(ShipBuildModeManager), "placingObject")?.GetValue(__instance);
			PlaceableShipObject val = (PlaceableShipObject)((obj is PlaceableShipObject) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int unlockableID = val.unlockableID;
			if (!PosterUnlockables.IsPosterId(unlockableID))
			{
				return;
			}
			int posterIndexByUnlockableId = PosterFeature.GetPosterIndexByUnlockableId(unlockableID);
			if (posterIndexByUnlockableId >= 0)
			{
				GameObject poster = PosterFeature.GetPoster(posterIndexByUnlockableId);
				if (!((Object)(object)poster == (Object)null))
				{
					_activePosterIndex = posterIndexByUnlockableId;
					_originalPosterPosition = poster.transform.position;
					_originalPosterRotation = poster.transform.rotation;
					_hasOriginalPosterTransform = true;
					Plugin.LogInfo($"Started live movement for Poster {posterIndexByUnlockableId + 1}. " + $"Original position={_originalPosterPosition}, " + $"rotation={((Quaternion)(ref _originalPosterRotation)).eulerAngles}");
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void FollowPosterGhost(ShipBuildModeManager __instance)
		{
			//IL_006d: 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)
			if (!__instance.InBuildMode || _activePosterIndex < 0)
			{
				return;
			}
			object? obj = AccessTools.Field(typeof(ShipBuildModeManager), "placingObject")?.GetValue(__instance);
			PlaceableShipObject val = (PlaceableShipObject)((obj is PlaceableShipObject) ? obj : null);
			if (!((Object)(object)val == (Object)null) && PosterUnlockables.IsPosterId(val.unlockableID))
			{
				Transform ghostObject = __instance.ghostObject;
				if (!((Object)(object)ghostObject == (Object)null))
				{
					PosterFeature.SyncPosterToTransform(_activePosterIndex, ((Component)ghostObject).transform.position, ((Component)ghostObject).transform.rotation);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("CancelBuildMode")]
		private static void AfterCancelBuildMode(ShipBuildModeManager __instance, bool cancelBeforePlacement)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (_activePosterIndex >= 0)
			{
				if (cancelBeforePlacement && _hasOriginalPosterTransform)
				{
					PosterFeature.SyncPosterToTransform(_activePosterIndex, _originalPosterPosition, _originalPosterRotation);
					Plugin.LogInfo($"Cancelled Poster {_activePosterIndex + 1} movement; " + "restored original transform.");
				}
				_activePosterIndex = -1;
				_hasOriginalPosterTransform = false;
			}
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class PosterPlacementPatch
	{
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(ShipBuildModeManager).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				if (!(methodInfo.Name != "PlaceShipObject"))
				{
					Plugin.LogInfo($"Found PlaceShipObject overload: {methodInfo}");
					yield return methodInfo;
				}
			}
		}

		[HarmonyPostfix]
		private static void AfterPlaceShipObject(object[] __args)
		{
			//IL_00c9: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			if (__args == null)
			{
				return;
			}
			PlaceableShipObject val = null;
			foreach (object obj in __args)
			{
				PlaceableShipObject val2 = (PlaceableShipObject)((obj is PlaceableShipObject) ? obj : null);
				if (val2 != null)
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogWarning("PlaceShipObject completed, but no PlaceableShipObject argument was found.");
				return;
			}
			int unlockableID = val.unlockableID;
			if (!PosterUnlockables.IsPosterId(unlockableID))
			{
				return;
			}
			Plugin.LogInfo("POSTER PLACED: " + $"id={unlockableID}, " + "placeable=" + ((Object)((Component)val).gameObject).name);
			AutoParentToShip parentObject = val.parentObject;
			if ((Object)(object)parentObject == (Object)null)
			{
				Plugin.LogError($"Poster id={unlockableID} has no AutoParentToShip.");
				return;
			}
			Plugin.LogInfo("Before MoveToOffset: " + $"shellPosition={((Component)parentObject).transform.position}, " + $"shellRotation={((Component)parentObject).transform.eulerAngles}, " + $"positionOffset={parentObject.positionOffset}, " + $"rotationOffset={parentObject.rotationOffset}");
			parentObject.MoveToOffset();
			int posterIndexByUnlockableId = PosterFeature.GetPosterIndexByUnlockableId(unlockableID);
			if (posterIndexByUnlockableId >= 0)
			{
				PosterFeature.SyncPosterToShell(posterIndexByUnlockableId);
				Plugin.LogInfo($"Synced actual Poster {posterIndexByUnlockableId + 1} to placed shell.");
			}
			Plugin.LogInfo("After MoveToOffset: " + $"shellPosition={((Component)parentObject).transform.position}, " + $"shellRotation={((Component)parentObject).transform.eulerAngles}");
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class PosterBuildCollisionPatch
	{
		[HarmonyPatch(typeof(ShipBuildModeManager))]
		internal static class WallPlacementDiagnostics
		{
			private static float _nextLogTime;

			[HarmonyPostfix]
			[HarmonyPatch("Update")]
			private static void DiagnoseWallPlacement(ShipBuildModeManager __instance)
			{
				//IL_00d5: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0210: Unknown result type (might be due to invalid IL or missing references)
				//IL_0233: Unknown result type (might be due to invalid IL or missing references)
				//IL_0238: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.InBuildMode || Time.time < _nextLogTime)
				{
					return;
				}
				_nextLogTime = Time.time + 0.5f;
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				if ((Object)(object)localPlayerController == (Object)null || (Object)(object)localPlayerController.gameplayCamera == (Object)null)
				{
					return;
				}
				object? obj = AccessTools.Field(typeof(ShipBuildModeManager), "placingObject")?.GetValue(__instance);
				PlaceableShipObject val = (PlaceableShipObject)((obj is PlaceableShipObject) ? obj : null);
				int num = (int)(AccessTools.Field(typeof(ShipBuildModeManager), "placementMask")?.GetValue(__instance) ?? ((object)0));
				object? obj2 = AccessTools.Field(typeof(ShipBuildModeManager), "currentCollider")?.GetValue(__instance);
				BoxCollider val2 = (BoxCollider)((obj2 is BoxCollider) ? obj2 : null);
				Ray val3 = default(Ray);
				((Ray)(ref val3))..ctor(((Component)localPlayerController.gameplayCamera).transform.position, ((Component)localPlayerController.gameplayCamera).transform.forward);
				RaycastHit val4 = default(RaycastHit);
				bool flag = Physics.Raycast(val3, ref val4, 4f, num, (QueryTriggerInteraction)1);
				Plugin.LogInfo("WALL DIAG: " + $"mask={num}, " + $"hit={flag}");
				if ((Object)(object)val != (Object)null)
				{
					Plugin.LogInfo("WALL DIAG placingObject=" + ((Object)((Component)val).gameObject).name + ", AllowPlacementOnWalls=" + $"{val.AllowPlacementOnWalls}, " + "overrideWallOffset=" + $"{val.overrideWallOffset}, " + "wallOffset=" + $"{val.wallOffset}");
				}
				if ((Object)(object)val2 != (Object)null)
				{
					Plugin.LogInfo("WALL DIAG currentCollider=" + ((Object)((Component)val2).gameObject).name + ", " + $"size={val2.size}, " + $"center={val2.center}");
				}
				if (flag)
				{
					float num2 = Vector3.Angle(((RaycastHit)(ref val4)).normal, Vector3.up);
					Plugin.LogInfo("WALL DIAG HIT: object=" + ((Object)((Component)((RaycastHit)(ref val4)).collider).gameObject).name + ", " + $"layer={((Component)((RaycastHit)(ref val4)).collider).gameObject.layer}, " + "tag=" + ((Component)((RaycastHit)(ref val4)).collider).gameObject.tag + ", " + $"point={((RaycastHit)(ref val4)).point}, " + $"normal={((RaycastHit)(ref val4)).normal}, " + $"angleFromUp={num2}");
					if ((Object)(object)val != (Object)null && num2 >= 45f)
					{
						Plugin.LogInfo("WALL DIAG: This is a WALL candidate. AllowPlacementOnWalls=" + $"{val.AllowPlacementOnWalls}");
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void HandlePosterBuildCollision(ShipBuildModeManager __instance)
		{
			IReadOnlyList<GameObject> allPosters = PosterFeature.AllPosters;
			if (allPosters.Count == 0)
			{
				return;
			}
			foreach (GameObject item in allPosters)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				Collider[] componentsInChildren = item.GetComponentsInChildren<Collider>(true);
				Collider[] array = componentsInChildren;
				foreach (Collider val in array)
				{
					if (__instance.InBuildMode)
					{
						if (val.enabled)
						{
							val.enabled = false;
							Plugin.LogInfo("Disabled collider on " + ((Object)item).name + ": " + ((Object)((Component)val).gameObject).name);
						}
					}
					else if (!val.enabled)
					{
						val.enabled = true;
						Plugin.LogInfo("Re-enabled collider on " + ((Object)item).name + ": " + ((Object)((Component)val).gameObject).name);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ShipBuildModeManager))]
	internal static class GhostDiagnostics
	{
		private static float _nextLogTime;

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void DiagnoseGhost(ShipBuildModeManager __instance)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.InBuildMode || Time.time < _nextLogTime)
			{
				return;
			}
			_nextLogTime = Time.time + 0.25f;
			object? obj = AccessTools.Field(typeof(ShipBuildModeManager), "placingObject")?.GetValue(__instance);
			PlaceableShipObject val = (PlaceableShipObject)((obj is PlaceableShipObject) ? obj : null);
			Transform ghostObject = __instance.ghostObject;
			string text = $"ghostPos={((ghostObject != null) ? new Vector3?(((Component)ghostObject).transform.position) : ((Vector3?)null))}, ";
			Transform ghostObject2 = __instance.ghostObject;
			Plugin.LogInfo("GHOST DIAG: " + text + $"ghostRot={((ghostObject2 != null) ? new Vector3?(((Component)ghostObject2).transform.eulerAngles) : ((Vector3?)null))}, " + $"CanConfirm={__instance.CanConfirmPosition}");
			if ((Object)(object)val != (Object)null)
			{
				Plugin.LogInfo("GHOST DIAG: placingObject=" + ((Object)((Component)val).gameObject).name + ", " + $"placingPos={((Component)val).transform.position}, " + $"placingRot={((Component)val).transform.eulerAngles}");
			}
			if ((Object)(object)__instance.ghostObject != (Object)null)
			{
				Collider[] componentsInChildren = ((Component)__instance.ghostObject).GetComponentsInChildren<Collider>(true);
				Collider[] array = componentsInChildren;
				Bounds bounds;
				foreach (Collider val2 in array)
				{
					string[] obj2 = new string[8]
					{
						"GHOST COLLIDER: object=",
						((Object)((Component)val2).gameObject).name,
						", ",
						$"enabled={val2.enabled}, ",
						$"layer={((Component)val2).gameObject.layer}, ",
						$"trigger={val2.isTrigger}, ",
						null,
						null
					};
					bounds = val2.bounds;
					obj2[6] = $"boundsCenter={((Bounds)(ref bounds)).center}, ";
					bounds = val2.bounds;
					obj2[7] = $"boundsSize={((Bounds)(ref bounds)).size}";
					Plugin.LogInfo(string.Concat(obj2));
				}
				Renderer[] componentsInChildren2 = ((Component)__instance.ghostObject).GetComponentsInChildren<Renderer>(true);
				Renderer[] array2 = componentsInChildren2;
				foreach (Renderer val3 in array2)
				{
					string[] obj3 = new string[6]
					{
						"GHOST RENDERER: object=",
						((Object)((Component)val3).gameObject).name,
						", ",
						$"enabled={val3.enabled}, ",
						null,
						null
					};
					bounds = val3.bounds;
					obj3[4] = $"boundsCenter={((Bounds)(ref bounds)).center}, ";
					bounds = val3.bounds;
					obj3[5] = $"boundsSize={((Bounds)(ref bounds)).size}";
					Plugin.LogInfo(string.Concat(obj3));
				}
			}
		}
	}
}