Decompiled source of PlacementPlus v1.0.0

PlacementPlus.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PlacementPlus
{
	internal static class ApartmentShutters
	{
		internal static int SuppressLockdown;

		internal static bool Enabled => PlacementConfig.ApartmentShutters?.Value ?? true;

		internal static bool IsOurDoor(Interactable inter)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			try
			{
				if (inter == null || (SoCustomComparison)(object)inter.preset == (SoCustomComparison)null)
				{
					return false;
				}
				if ((int)inter.preset.specialCaseFlag != 5)
				{
					return false;
				}
				FurnitureLocation furnitureParent = inter.furnitureParent;
				return furnitureParent != null && furnitureParent.userPlaced;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsOurBreaker(Interactable inter)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			try
			{
				if (inter == null || (SoCustomComparison)(object)inter.preset == (SoCustomComparison)null)
				{
					return false;
				}
				SpecialCase specialCaseFlag = inter.preset.specialCaseFlag;
				if ((int)specialCaseFlag != 28 && (int)specialCaseFlag != 27 && (int)specialCaseFlag != 26)
				{
					return false;
				}
				FurnitureLocation furnitureParent = inter.furnitureParent;
				return furnitureParent != null && furnitureParent.userPlaced;
			}
			catch
			{
				return false;
			}
		}

		internal static NewAddress AddressOf(Interactable inter)
		{
			try
			{
				return (inter != null && inter.node != null && (Object)(object)inter.node.gameLocation != (Object)null) ? inter.node.gameLocation.thisAsAddress : null;
			}
			catch
			{
				return null;
			}
		}

		internal static void DriveDoors(Interactable breaker, bool sw0)
		{
			try
			{
				NewAddress val = AddressOf(breaker);
				if ((Object)(object)val == (Object)null || ((NewGameLocation)val).rooms == null)
				{
					return;
				}
				bool flag = true;
				try
				{
					flag = (Object)(object)SessionData.Instance != (Object)null && SessionData.Instance.startedGame;
				}
				catch
				{
				}
				List<NewRoom> rooms = ((NewGameLocation)val).rooms;
				for (int i = 0; i < rooms.Count; i++)
				{
					NewRoom val2 = rooms[i];
					if ((Object)(object)val2 == (Object)null || val2.specialCaseInteractables == null || !val2.specialCaseInteractables.ContainsKey((SpecialCase)5))
					{
						continue;
					}
					List<Interactable> val3 = val2.specialCaseInteractables[(SpecialCase)5];
					if (val3 == null)
					{
						continue;
					}
					for (int j = 0; j < val3.Count; j++)
					{
						Interactable val4 = val3[j];
						if (val4 == null || !IsOurDoor(val4))
						{
							continue;
						}
						try
						{
							if (val4.sw0 != sw0)
							{
								val4.SetSwitchState(sw0, (Actor)null, flag, false, false);
							}
						}
						catch
						{
						}
					}
				}
			}
			catch
			{
			}
		}

		internal static void ForEachHomeDoorsBreaker(Action<Interactable> act)
		{
			try
			{
				Player instance = Player.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				ProcessAddress(((Human)instance).home, act);
				List<NewAddress> apartmentsOwned = instance.apartmentsOwned;
				if (apartmentsOwned != null)
				{
					for (int i = 0; i < apartmentsOwned.Count; i++)
					{
						ProcessAddress(apartmentsOwned[i], act);
					}
				}
			}
			catch
			{
			}
		}

		private static void ProcessAddress(NewAddress addr, Action<Interactable> act)
		{
			try
			{
				if ((Object)(object)addr == (Object)null || ((NewGameLocation)addr).rooms == null)
				{
					return;
				}
				List<NewRoom> rooms = ((NewGameLocation)addr).rooms;
				for (int i = 0; i < rooms.Count; i++)
				{
					NewRoom val = rooms[i];
					if ((Object)(object)val == (Object)null || val.specialCaseInteractables == null || !val.specialCaseInteractables.ContainsKey((SpecialCase)28))
					{
						continue;
					}
					List<Interactable> val2 = val.specialCaseInteractables[(SpecialCase)28];
					if (val2 == null)
					{
						continue;
					}
					for (int j = 0; j < val2.Count; j++)
					{
						Interactable val3 = val2[j];
						if (val3 != null && IsOurBreaker(val3))
						{
							try
							{
								act(val3);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
		}

		internal static void ResyncAll()
		{
			if (!Enabled)
			{
				return;
			}
			ForEachHomeDoorsBreaker(delegate(Interactable b)
			{
				try
				{
					DriveDoors(b, b.sw0);
				}
				catch
				{
				}
			});
		}

		internal static void OpenSealedHomes()
		{
			ForEachHomeDoorsBreaker(delegate(Interactable b)
			{
				try
				{
					if (!b.sw0)
					{
						b.SetSwitchState(true, (Actor)null, true, false, false);
						DriveDoors(b, sw0: true);
					}
				}
				catch
				{
				}
			});
		}
	}
	public class DecorProbe : MonoBehaviour
	{
		public DecorProbe(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ConfigEntry<bool> enabled = PlacementConfig.Enabled;
				if (enabled != null && enabled.Value)
				{
					Player instance = Player.Instance;
					if ((!((Object)(object)instance != (Object)null) || instance.computerInteractable == null) && Input.GetKeyDown(PlacementConfig.ProbeKey.Value))
					{
						DumpAll();
					}
				}
			}
			catch
			{
			}
		}

		private void DumpAll()
		{
			StringBuilder stringBuilder = new StringBuilder(32768);
			List<string> list = new List<string>();
			stringBuilder.Append("===== PlacementPlus DecorProbe @ ").Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append(" =====\n");
			try
			{
				DumpFurnitureCensus(stringBuilder, list);
			}
			catch (Exception ex)
			{
				Line(stringBuilder, list, "[FURNITURE CENSUS FAILED: " + ex.Message + "]");
			}
			try
			{
				DumpItemPlacementCensus(stringBuilder, list);
			}
			catch (Exception ex2)
			{
				Line(stringBuilder, list, "[ITEM PLACEMENT CENSUS FAILED: " + ex2.Message + "]");
			}
			try
			{
				DumpCeilingMeasurements(stringBuilder, list);
			}
			catch (Exception ex3)
			{
				Line(stringBuilder, list, "[CEILING MEASUREMENT FAILED: " + ex3.Message + "]");
			}
			try
			{
				DumpSurfaceProbe(stringBuilder, list);
			}
			catch (Exception ex4)
			{
				Line(stringBuilder, list, "[SURFACE PROBE FAILED: " + ex4.Message + "]");
			}
			try
			{
				DumpSecurityFixtures(stringBuilder, list);
			}
			catch (Exception ex5)
			{
				Line(stringBuilder, list, "[SECURITY FIXTURE PROBE FAILED: " + ex5.Message + "]");
			}
			stringBuilder.Append("===== end DecorProbe =====");
			string text = stringBuilder.ToString();
			ConfigEntry<bool> writeFile = PlacementConfig.WriteFile;
			string text2 = ((writeFile == null || writeFile.Value) ? WriteToFile(text) : null);
			Plugin.Log2.LogMessage((object)"[PlacementPlus] DecorProbe dump:");
			foreach (string item in list)
			{
				Plugin.Log2.LogMessage((object)("  " + item));
			}
			if (text2 != null)
			{
				Plugin.Log2.LogMessage((object)("[PlacementPlus] full census written to: " + text2));
			}
		}

		private void DumpFurnitureCensus(StringBuilder sb, List<string> echo)
		{
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			Toolbox instance = Toolbox.Instance;
			List<FurniturePreset> val = (((Object)(object)instance != (Object)null) ? instance.allFurniture : null);
			sb.Append("\n--- FURNITURE CENSUS ---\n");
			if (val == null)
			{
				Line(sb, echo, "allFurniture is null (not loaded yet?)");
				return;
			}
			int count = val.Count;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			sb.Append("status | name | decorClass | purchasable | disableFromMenu | hasPrefab | cost | class0\n");
			Enumerator<FurniturePreset> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				FurniturePreset current = enumerator.Current;
				if ((SoCustomComparison)(object)current == (SoCustomComparison)null)
				{
					continue;
				}
				try
				{
					bool flag = (Object)(object)current.prefab != (Object)null;
					string value;
					if (!flag)
					{
						value = "UNPLACEABLE";
						num4++;
					}
					else if (current.disableFromDecorMenu)
					{
						value = "HIDDEN-MENU";
						num3++;
					}
					else if (!current.purchasable)
					{
						value = "HIDDEN-SHOP";
						num2++;
					}
					else
					{
						value = "VISIBLE";
						num++;
					}
					string value2 = "-";
					if (current.classes != null && current.classes.Count > 0 && (SoCustomComparison)(object)current.classes[0] != (SoCustomComparison)null)
					{
						FurnitureClass val2 = current.classes[0];
						StringBuilder stringBuilder = new StringBuilder();
						if (val2.ceilingPiece)
						{
							stringBuilder.Append("CEIL ");
						}
						if (val2.wallPiece)
						{
							stringBuilder.Append("WALL ");
						}
						if (val2.useWallSnappingInDecorMode)
						{
							stringBuilder.Append("WSNAP ");
						}
						value2 = stringBuilder.ToString() + val2.objectSize.x.ToString("0.#") + "x" + val2.objectSize.y.ToString("0.#");
					}
					sb.Append(value).Append(" | ").Append(SafeName((Object)(object)current))
						.Append(" | ")
						.Append(((object)current.decorClass/*cast due to .constrained prefix*/).ToString())
						.Append(" | p=")
						.Append(current.purchasable)
						.Append(" | dm=")
						.Append(current.disableFromDecorMenu)
						.Append(" | prefab=")
						.Append(flag)
						.Append(" | cost=")
						.Append(current.cost)
						.Append(" | ")
						.Append(value2)
						.Append('\n');
				}
				catch (Exception ex)
				{
					sb.Append("[row error: ").Append(ex.Message).Append("]\n");
				}
			}
			Line(sb, echo, $"furniture: {count} total | {num} visible | {num2} hidden-shop | {num3} hidden-menu | {num4} unplaceable");
		}

		private unsafe void DumpItemPlacementCensus(StringBuilder sb, List<string> echo)
		{
			//IL_0068: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Invalid comparison between Unknown and I4
			Il2CppArrayBase<InteractablePreset> val = Resources.FindObjectsOfTypeAll<InteractablePreset>();
			sb.Append("\n--- ITEM PLACEMENT-MODE CENSUS ---\n");
			if (val == null)
			{
				Line(sb, echo, "no InteractablePresets found");
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int length = val.Length;
			StringBuilder stringBuilder = new StringBuilder();
			sb.Append("name | apartmentPlacementMode | isInventoryItem | allowInStorage | mustTouchFurniture (non-physics rows only)\n");
			for (int i = 0; i < val.Length; i++)
			{
				InteractablePreset val2 = val[i];
				if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null)
				{
					continue;
				}
				try
				{
					ApartmentPlacementMode apartmentPlacementMode = val2.apartmentPlacementMode;
					bool isInventoryItem = val2.isInventoryItem;
					if ((int)apartmentPlacementMode == 2)
					{
						num3++;
					}
					else if ((int)apartmentPlacementMode == 1)
					{
						num2++;
					}
					else
					{
						num++;
					}
					if (isInventoryItem)
					{
						num4++;
					}
					if ((int)apartmentPlacementMode == 0)
					{
						continue;
					}
					int value = ((val2.mustTouchFurniture != null) ? val2.mustTouchFurniture.Count : 0);
					sb.Append(SafeName((Object)(object)val2)).Append(" | ").Append(((object)(*(ApartmentPlacementMode*)(&apartmentPlacementMode))/*cast due to .constrained prefix*/).ToString())
						.Append(" | inv=")
						.Append(isInventoryItem)
						.Append(" | storage=")
						.Append(val2.allowInApartmentStorage)
						.Append(" | mustTouch=")
						.Append(value)
						.Append('\n');
					if ((int)apartmentPlacementMode == 2)
					{
						if (stringBuilder.Length > 0)
						{
							stringBuilder.Append(", ");
						}
						stringBuilder.Append(SafeName((Object)(object)val2));
					}
				}
				catch
				{
				}
			}
			Line(sb, echo, $"items: {length} presets | physics={num} vertical(wall)={num2} ceiling={num3} | inventory={num4}");
			Line(sb, echo, "ceiling-mode items (Path C targets): " + ((stringBuilder.Length > 0) ? stringBuilder.ToString() : "(none)"));
		}

		private void DumpCeilingMeasurements(StringBuilder sb, List<string> echo)
		{
			//IL_0096: 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_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Invalid comparison between Unknown and I4
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			sb.Append("\n--- CEILING MEASUREMENTS (current room) ---\n");
			Player instance = Player.Instance;
			NewRoom val = (((Object)(object)instance != (Object)null) ? ((Actor)instance).currentRoom : null);
			if ((Object)(object)val == (Object)null)
			{
				Line(sb, echo, "no current room (stand inside a room and press again)");
				return;
			}
			sb.Append("room: ").Append(SafeRoomName(val)).Append('\n');
			List<Interactable> mainLights = val.mainLights;
			int num = 0;
			if (mainLights != null)
			{
				Enumerator<Interactable> enumerator = mainLights.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Interactable current = enumerator.Current;
					if (current != null)
					{
						try
						{
							float num2 = TrueCeilingY(current.node);
							float y = current.wPos.y;
							Line(sb, echo, $"mainLight '{InterName(current)}': y={y:0.###} trueCeiling={num2:0.###} gap={num2 - y:0.###}m (Path A)");
							num++;
						}
						catch (Exception ex)
						{
							sb.Append("  [light err: ").Append(ex.Message).Append("]\n");
						}
					}
				}
			}
			if (num == 0)
			{
				Line(sb, echo, "no main lights in this room");
			}
			List<FurnitureLocation> individualFurniture = val.individualFurniture;
			int num3 = 0;
			if (individualFurniture != null)
			{
				Enumerator<FurnitureLocation> enumerator2 = individualFurniture.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					FurnitureLocation current2 = enumerator2.Current;
					if (current2 == null)
					{
						continue;
					}
					try
					{
						if (current2.furnitureClasses != null && current2.furnitureClasses.Count != 0 && !((SoCustomComparison)(object)current2.furnitureClasses[0] == (SoCustomComparison)null) && current2.furnitureClasses[0].ceilingPiece)
						{
							GameObject spawnedObject = current2.spawnedObject;
							if (!((Object)(object)spawnedObject == (Object)null))
							{
								float num4 = TrueCeilingY(current2.anchorNode);
								float y2 = spawnedObject.transform.position.y;
								float num5 = TopY(spawnedObject, y2);
								Line(sb, echo, $"ceilFurniture '{SafeName((Object)(object)current2.furnitureClasses[0])}': objY={y2:0.###} top={num5:0.###} trueCeiling={num4:0.###} gap(top->ceil)={num4 - num5:0.###}m (Path B)");
								num3++;
							}
						}
					}
					catch (Exception ex2)
					{
						sb.Append("  [furn err: ").Append(ex2.Message).Append("]\n");
					}
				}
			}
			if (num3 == 0)
			{
				Line(sb, echo, "no ceiling furniture placed in this room");
			}
			try
			{
				InteractionController instance2 = InteractionController.Instance;
				InteractableController val2 = (((Object)(object)instance2 != (Object)null) ? instance2.carryingObject : null);
				if ((Object)(object)val2 != (Object)null && val2.interactable != null && (SoCustomComparison)(object)val2.interactable.preset != (SoCustomComparison)null && (int)val2.interactable.preset.apartmentPlacementMode == 2)
				{
					float num6 = TrueCeilingY(((Actor)instance).currentNode);
					float y3 = ((Component)val2).transform.position.y;
					float num7 = TopY(((Component)val2).gameObject, y3);
					Line(sb, echo, $"CARRIED ceiling item '{InterName(val2.interactable)}': objY={y3:0.###} top={num7:0.###} trueCeiling={num6:0.###} gap(top->ceil)={num6 - num7:0.###}m (Path C, while placing)");
				}
				else
				{
					Line(sb, echo, "no ceiling-mode item carried — to measure Path C, hold a hanging light in placement mode and press again");
				}
			}
			catch (Exception ex3)
			{
				sb.Append("  [carried err: ").Append(ex3.Message).Append("]\n");
			}
		}

		private void DumpSurfaceProbe(StringBuilder sb, List<string> echo)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//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_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			sb.Append("\n--- SURFACE PROBE (crosshair) ---\n");
			Player instance = Player.Instance;
			Transform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.cam != (Object)null) ? ((Component)instance.cam).transform : null);
			if ((Object)(object)val == (Object)null)
			{
				Line(sb, echo, "no camera");
				return;
			}
			Vector3 position = val.position;
			Vector3 forward = val.forward;
			ProbeMask(sb, echo, "layer29(wall/shell)", position, forward, 536870912);
			ProbeMask(sb, echo, "layer0(furniture) ", position, forward, 1);
			ProbeMask(sb, echo, "any-layer         ", position, forward, -1);
			try
			{
				InteractionController instance2 = InteractionController.Instance;
				Interactable val2 = (((Object)(object)instance2 != (Object)null && (Object)(object)instance2.carryingObject != (Object)null) ? instance2.carryingObject.interactable : null);
				if (val2 == null)
				{
					InventorySlot val3 = (((Object)(object)BioScreenController.Instance != (Object)null) ? BioScreenController.Instance.selectedSlot : null);
					val2 = ((val3 != null) ? val3.GetInteractable() : null);
				}
				GameObject val4 = ((val2 != null) ? val2.spawnedObject : null);
				if ((Object)(object)val4 == (Object)null)
				{
					Line(sb, echo, "no carried/held item to measure (hold the silenced pistol and press again)");
					return;
				}
				Line(sb, echo, "item renderers for '" + InterName(val2) + "':");
				Il2CppArrayBase<Renderer> componentsInChildren = val4.GetComponentsInChildren<Renderer>(true);
				int num = componentsInChildren?.Length ?? 0;
				for (int i = 0; i < num && i < 12; i++)
				{
					Renderer val5 = componentsInChildren[i];
					if (!((Object)(object)val5 == (Object)null))
					{
						Bounds localBounds = val5.localBounds;
						object[] obj = new object[5]
						{
							i,
							SafeName((Object)(object)val5),
							Fmt(((Bounds)(ref localBounds)).center),
							Fmt(((Bounds)(ref localBounds)).extents),
							null
						};
						Bounds bounds = val5.bounds;
						obj[4] = Fmt(((Bounds)(ref bounds)).center);
						Line(sb, echo, string.Format("  rend[{0}]={1} localCenter={2} localExtents={3} worldCenter={4}", obj));
					}
				}
			}
			catch (Exception ex)
			{
				Line(sb, echo, "[item measure err: " + ex.Message + "]");
			}
		}

		private static void ProbeMask(StringBuilder sb, List<string> echo, string label, Vector3 o, Vector3 d, int mask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(o, d, ref val, 10f, mask, (QueryTriggerInteraction)1))
				{
					Collider collider = ((RaycastHit)(ref val)).collider;
					GameObject val2 = (((Object)(object)collider != (Object)null) ? ((Component)collider).gameObject : null);
					int num = (((Object)(object)val2 != (Object)null) ? val2.layer : (-1));
					string text = "?";
					try
					{
						text = LayerMask.LayerToName(num);
					}
					catch
					{
					}
					Line(sb, echo, string.Format("{0}: hit='{1}' layer={2}({3}) tag={4} dist={5:0.###} point={6}", label, ((Object)(object)collider != (Object)null) ? SafeName((Object)(object)collider) : "?", num, text, SafeTag(val2), ((RaycastHit)(ref val)).distance, Fmt(((RaycastHit)(ref val)).point)));
				}
				else
				{
					Line(sb, echo, label + ": no hit");
				}
			}
			catch (Exception ex)
			{
				Line(sb, echo, label + ": err " + ex.Message);
			}
		}

		private static string SafeTag(GameObject go)
		{
			try
			{
				return ((Object)(object)go != (Object)null) ? go.tag : "-";
			}
			catch
			{
				return "?";
			}
		}

		private static string Fmt(Vector3 v)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return $"({v.x:0.##},{v.y:0.##},{v.z:0.##})";
		}

		private void DumpSecurityFixtures(StringBuilder sb, List<string> echo)
		{
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Invalid comparison between Unknown and I4
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Invalid comparison between Unknown and I4
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Invalid comparison between Unknown and I4
			sb.Append("\n--- SECURITY FIXTURE PRESETS (breaker/door integrated interactables) ---\n");
			Toolbox instance = Toolbox.Instance;
			List<FurniturePreset> val = (((Object)(object)instance != (Object)null) ? instance.allFurniture : null);
			if (val == null)
			{
				Line(sb, echo, "allFurniture null");
				return;
			}
			int num = 0;
			Enumerator<FurniturePreset> enumerator = val.GetEnumerator();
			while (enumerator.MoveNext())
			{
				FurniturePreset current = enumerator.Current;
				if ((SoCustomComparison)(object)current == (SoCustomComparison)null)
				{
					continue;
				}
				try
				{
					List<IntegratedInteractable> integratedInteractables = current.integratedInteractables;
					if (integratedInteractables == null || integratedInteractables.Count == 0)
					{
						continue;
					}
					bool flag = false;
					for (int i = 0; i < integratedInteractables.Count; i++)
					{
						InteractablePreset val2 = ((integratedInteractables[i] != null) ? integratedInteractables[i].preset : null);
						if (!((SoCustomComparison)(object)val2 == (SoCustomComparison)null))
						{
							SpecialCase specialCaseFlag = val2.specialCaseFlag;
							if ((int)specialCaseFlag == 5 || (int)specialCaseFlag == 28 || (int)specialCaseFlag == 27 || (int)specialCaseFlag == 26)
							{
								flag = true;
								break;
							}
						}
					}
					if (!flag)
					{
						continue;
					}
					num++;
					Line(sb, echo, "FURNITURE '" + SafeName((Object)(object)current) + "' (purchasable=" + current.purchasable + ")");
					for (int j = 0; j < integratedInteractables.Count; j++)
					{
						InteractablePreset val3 = ((integratedInteractables[j] != null) ? integratedInteractables[j].preset : null);
						if ((SoCustomComparison)(object)val3 == (SoCustomComparison)null)
						{
							continue;
						}
						string text = "";
						try
						{
							List<InteractionAction> actions = val3.GetActions(0);
							if (actions != null)
							{
								for (int k = 0; k < actions.Count && k < 8; k++)
								{
									InteractionAction val4 = actions[k];
									if (val4 != null)
									{
										if (text.Length > 0)
										{
											text += ", ";
										}
										text = text + (((SoCustomComparison)(object)val4.action != (SoCustomComparison)null) ? ((Object)val4.action).name : "?") + (string.IsNullOrEmpty(val4.interactionName) ? "" : ("[" + val4.interactionName + "]"));
									}
								}
							}
						}
						catch (Exception ex)
						{
							text = "(actions err: " + ex.Message + ")";
						}
						Line(sb, echo, "   inter '" + SafeName((Object)(object)val3) + "' flag=" + ((object)val3.specialCaseFlag/*cast due to .constrained prefix*/).ToString() + " startSwitch=" + val3.startingSwitchState + " startLock=" + val3.startingLockState + " reset=" + val3.resetSwitchStates + "/" + val3.resetTimer.ToString("0.##") + " padlock=" + (((SoCustomComparison)(object)val3.includeLock != (SoCustomComparison)null) ? SafeName((Object)(object)val3.includeLock) : "none"));
						Line(sb, echo, "      actions: " + ((text.Length > 0) ? text : "(none)"));
					}
				}
				catch (Exception ex2)
				{
					sb.Append("[fixture err: ").Append(ex2.Message).Append("]\n");
				}
			}
			Line(sb, echo, "security fixtures found: " + num);
		}

		private static float TrueCeilingY(NewNode node)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (node == null)
			{
				return float.NaN;
			}
			return node.position.y + (float)node.floor.defaultCeilingHeight * 0.1f - (float)node.floorHeight * 0.1f;
		}

		private static float TopY(GameObject go, float fallback)
		{
			//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_0019: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Renderer componentInChildren = go.GetComponentInChildren<Renderer>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Bounds bounds = componentInChildren.bounds;
					return ((Bounds)(ref bounds)).max.y;
				}
			}
			catch
			{
			}
			return fallback;
		}

		private static string SafeName(Object o)
		{
			try
			{
				return (o != (Object)null) ? o.name : "null";
			}
			catch
			{
				return "?";
			}
		}

		private static string InterName(Interactable inter)
		{
			try
			{
				if (inter != null && (SoCustomComparison)(object)inter.preset != (SoCustomComparison)null)
				{
					return ((Object)inter.preset).name;
				}
			}
			catch
			{
			}
			return "item";
		}

		private static string SafeRoomName(NewRoom room)
		{
			try
			{
				return room.name;
			}
			catch
			{
			}
			try
			{
				return ((SoCustomComparison)(object)room.preset != (SoCustomComparison)null) ? ((Object)room.preset).name : "room";
			}
			catch
			{
				return "room";
			}
		}

		private static void Line(StringBuilder sb, List<string> echo, string s)
		{
			sb.Append(s).Append('\n');
			echo.Add(s);
		}

		private string WriteToFile(string text)
		{
			try
			{
				string text2 = Path.Combine(Paths.BepInExRootPath, "PlacementPlus");
				Directory.CreateDirectory(text2);
				string text3 = Path.Combine(text2, "decor_census_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".txt");
				File.WriteAllText(text3, text);
				return text3;
			}
			catch (Exception ex)
			{
				Plugin.Log2.LogWarning((object)("[PlacementPlus] file write failed: " + ex.Message));
				return null;
			}
		}
	}
	internal static class Diag
	{
		internal static void DumpAnchors(string tag, Interactable inter)
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_0288: 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_0311: Expected O, but got Unknown
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!PlacementController.Verbose || inter == null)
				{
					return;
				}
				InteractableController controller = inter.controller;
				Transform val = (((Object)(object)inter.spawnedObject != (Object)null) ? inter.spawnedObject.transform : null);
				Transform val2 = (((Object)(object)controller != (Object)null) ? ((Component)controller).transform : null);
				Transform val3 = (((Object)(object)controller != (Object)null) ? controller.alternativePhysicsParent : null);
				Transform val4 = (((Object)(object)val3 != (Object)null) ? val3 : val2);
				string text = PlacementController.PresetName(inter);
				bool flag = (Object)(object)val3 == (Object)null;
				bool flag2 = (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && (Object)(object)val == (Object)(object)val2;
				bool flag3 = (Object)(object)val4 != (Object)null && (Object)(object)val != (Object)null && val4.IsChildOf(val);
				ManualLogSource log = Plugin.Log2;
				bool flag4 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(93, 8, ref flag4);
				if (flag4)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altNull=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootIsCtrl=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag2);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("tChildOfRoot=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag3);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootParent=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlParent=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val2));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altParent=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ParentName(val3));
				}
				log.LogWarning(val5);
				ManualLogSource log2 = Plugin.Log2;
				val5 = new BepInExWarningLogInterpolatedStringHandler(87, 9, ref flag4);
				if (flag4)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rootEul=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | ");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("ctrlPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val2));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlEul=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val2));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | altPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(P(val3));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" altEul=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(E(val3));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" | wPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(PlacementController.V(inter.wPos));
				}
				log2.LogWarning(val5);
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				Il2CppArrayBase<Renderer> componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
				int num = componentsInChildren?.Length ?? 0;
				for (int i = 0; i < num && i < 12; i++)
				{
					Renderer val6 = componentsInChildren[i];
					if (!((Object)(object)val6 == (Object)null))
					{
						bool flag5 = (Object)(object)val4 != (Object)null && ((Component)val6).transform.IsChildOf(val4);
						ManualLogSource log3 = Plugin.Log2;
						val5 = new BepInExWarningLogInterpolatedStringHandler(47, 6, ref flag4);
						if (flag4)
						{
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][DIAG ");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] ");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rend[");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(i);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("]=");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)val6).name);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" underT=");
							((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag5);
							((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" center=");
							BepInExWarningLogInterpolatedStringHandler obj = val5;
							Bounds bounds = val6.bounds;
							((BepInExLogInterpolatedStringHandler)obj).AppendFormatted<string>(PlacementController.V(((Bounds)(ref bounds)).center));
						}
						log3.LogWarning(val5);
					}
				}
			}
			catch
			{
			}
		}

		internal static void DumpPhysState(string tag, Interactable inter)
		{
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!PlacementController.Verbose || inter == null)
				{
					return;
				}
				InteractableController controller = inter.controller;
				Transform val = (((Object)(object)inter.spawnedObject != (Object)null) ? inter.spawnedObject.transform : null);
				string text = PlacementController.PresetName(inter);
				float num = -1f;
				Vector3 euler;
				try
				{
					if (FrozenMark.TryGetPose(inter, out var pos, out euler))
					{
						num = Vector3.Distance(inter.wPos, pos);
					}
				}
				catch
				{
				}
				bool flag = false;
				try
				{
					flag = FrozenMark.IsFrozen(inter);
				}
				catch
				{
				}
				string text2 = "rb=null";
				bool flag2 = false;
				string text3 = "coll=?";
				if ((Object)(object)controller != (Object)null)
				{
					try
					{
						flag2 = ((Behaviour)controller).enabled;
					}
					catch
					{
					}
					try
					{
						if ((Object)(object)controller.rb != (Object)null)
						{
							DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(27, 4);
							defaultInterpolatedStringHandler.AppendLiteral("rb[kin=");
							defaultInterpolatedStringHandler.AppendFormatted(controller.rb.isKinematic);
							defaultInterpolatedStringHandler.AppendLiteral(" grav=");
							defaultInterpolatedStringHandler.AppendFormatted(controller.rb.useGravity);
							defaultInterpolatedStringHandler.AppendLiteral(" vel=");
							euler = controller.rb.velocity;
							defaultInterpolatedStringHandler.AppendFormatted(((Vector3)(ref euler)).magnitude, "0.##");
							defaultInterpolatedStringHandler.AppendLiteral(" detect=");
							defaultInterpolatedStringHandler.AppendFormatted(controller.rb.detectCollisions);
							defaultInterpolatedStringHandler.AppendLiteral("]");
							text2 = defaultInterpolatedStringHandler.ToStringAndClear();
						}
					}
					catch
					{
					}
					try
					{
						if ((Object)(object)controller.coll != (Object)null)
						{
							text3 = $"coll[en={controller.coll.enabled} trig={controller.coll.isTrigger}]";
						}
					}
					catch
					{
					}
				}
				bool flag3 = false;
				int num2 = 0;
				int num3 = 0;
				bool flag4 = false;
				try
				{
					flag3 = (Object)(object)inter.spawnedObject != (Object)null && inter.spawnedObject.activeInHierarchy;
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)val != (Object)null)
					{
						Il2CppArrayBase<Renderer> componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
						num3 = componentsInChildren?.Length ?? 0;
						for (int i = 0; i < num3; i++)
						{
							Renderer val2 = componentsInChildren[i];
							if (!((Object)(object)val2 == (Object)null))
							{
								if (val2.enabled)
								{
									num2++;
								}
								if (val2.isVisible)
								{
									flag4 = true;
								}
							}
						}
					}
				}
				catch
				{
				}
				string text4 = "room=?";
				try
				{
					NewNode node = inter.node;
					NewRoom val3 = ((node != null) ? node.room : null);
					bool value = (Object)(object)val3 != (Object)null && (Object)(object)Player.Instance != (Object)null && (Object)(object)val3 == (Object)(object)((Actor)Player.Instance).currentRoom;
					text4 = $"room[{(((Object)(object)val3 != (Object)null) ? val3.name : "null")} isCur={value}]";
				}
				catch
				{
				}
				string text5 = "anc:";
				try
				{
					Transform val4 = val;
					int num4 = 0;
					while ((Object)(object)val4 != (Object)null && num4 < 7)
					{
						text5 += $" {((Object)val4).name}={((Component)val4).gameObject.activeSelf}";
						val4 = val4.parent;
						num4++;
					}
				}
				catch
				{
				}
				ManualLogSource log = Plugin.Log2;
				bool flag5 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(110, 15, ref flag5);
				if (flag5)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[PlacementPlus][WATCH ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(tag);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("] ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" wPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(PlacementController.V(inter.wPos));
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("rootPos=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)(object)val != (Object)null) ? PlacementController.V(val.position) : "-");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" distFromStored=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<float>(num, "0.###");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("active=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag3);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" rendersOn=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num2);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("/");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num3);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" onScreen=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag4);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" frozen=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ctrlEnabled=");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<bool>(flag2);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text2);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text3);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text4);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(text5);
				}
				log.LogWarning(val5);
			}
			catch
			{
			}
		}

		private static string ParentName(Transform tr)
		{
			try
			{
				return ((Object)(object)tr != (Object)null && (Object)(object)tr.parent != (Object)null) ? ((Object)tr.parent).name : "-";
			}
			catch
			{
				return "?";
			}
		}

		private static string P(Transform tr)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return ((Object)(object)tr != (Object)null) ? PlacementController.V(tr.position) : "-";
			}
			catch
			{
				return "?";
			}
		}

		private static string E(Transform tr)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return ((Object)(object)tr != (Object)null) ? PlacementController.V(tr.eulerAngles) : "-";
			}
			catch
			{
				return "?";
			}
		}
	}
	internal static class FrozenMark
	{
		private const int FrozenVarInt = 7777;

		internal static bool IsFrozen(Interactable inter)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			try
			{
				List<Passed> val = ((inter != null) ? inter.pv : null);
				if (val == null)
				{
					return false;
				}
				for (int i = 0; i < val.Count; i++)
				{
					if (val[i] != null && (int)val[i].varType == 7777)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		internal static void SetFrozen(Interactable inter, Vector3 pos, Vector3 euler)
		{
			//IL_0028: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			try
			{
				if (inter != null && inter.pv != null)
				{
					ClearFrozen(inter);
					string text = string.Format(CultureInfo.InvariantCulture, "{0},{1},{2},{3},{4},{5}", pos.x, pos.y, pos.z, euler.x, euler.y, euler.z);
					inter.pv.Add(new Passed((PassedVarType)7777, 0f, text));
				}
			}
			catch
			{
			}
		}

		internal static void ClearFrozen(Interactable inter)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			try
			{
				List<Passed> val = ((inter != null) ? inter.pv : null);
				if (val == null)
				{
					return;
				}
				for (int num = val.Count - 1; num >= 0; num--)
				{
					if (val[num] != null && (int)val[num].varType == 7777)
					{
						val.RemoveAt(num);
					}
				}
			}
			catch
			{
			}
		}

		internal static bool TryGetPose(Interactable inter, out Vector3 pos, out Vector3 euler)
		{
			//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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_0097: 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_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)
			pos = Vector3.zero;
			euler = Vector3.zero;
			try
			{
				List<Passed> val = ((inter != null) ? inter.pv : null);
				if (val == null)
				{
					return false;
				}
				for (int i = 0; i < val.Count; i++)
				{
					Passed val2 = val[i];
					if (val2 != null && (int)val2.varType == 7777)
					{
						string str = val2.str;
						if (string.IsNullOrEmpty(str))
						{
							return false;
						}
						string[] array = str.Split(',');
						if (array.Length < 6)
						{
							return false;
						}
						pos = new Vector3(F(array[0]), F(array[1]), F(array[2]));
						euler = new Vector3(F(array[3]), F(array[4]), F(array[5]));
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static float F(string s)
		{
			if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return 0f;
			}
			return result;
		}
	}
	internal static class Gate
	{
		internal static bool InPlay()
		{
			try
			{
				SessionData instance = SessionData.Instance;
				if ((Object)(object)instance == (Object)null || !instance.play)
				{
					return false;
				}
				Player instance2 = Player.Instance;
				if ((Object)(object)instance2 == (Object)null || ((Actor)instance2).isDead)
				{
					return false;
				}
				if (instance2.computerInteractable != null)
				{
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		internal static bool TextOrPopupActive()
		{
			try
			{
				InterfaceController instance = InterfaceController.Instance;
				if ((Object)(object)instance != (Object)null && instance.playerTextInputActive)
				{
					return true;
				}
				PopupMessageController instance2 = PopupMessageController.Instance;
				if ((Object)(object)instance2 != (Object)null && instance2.active)
				{
					return true;
				}
				return false;
			}
			catch
			{
				return true;
			}
		}

		internal static bool VanillaDecorActive()
		{
			try
			{
				SessionData instance = SessionData.Instance;
				if ((Object)(object)instance != (Object)null && instance.isDecorEdit)
				{
					return true;
				}
				PlayerApartmentController instance2 = PlayerApartmentController.Instance;
				if ((Object)(object)instance2 != (Object)null && (instance2.furniturePlacementMode || instance2.decoratingMode))
				{
					return true;
				}
				return false;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class PlacementConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyCode> ProbeKey;

		internal static ConfigEntry<bool> WriteFile;

		internal static ConfigEntry<bool> PrecisionPlacement;

		internal static ConfigEntry<float> MaxDistance;

		internal static ConfigEntry<bool> AllowPitchRoll;

		internal static ConfigEntry<bool> ShowOverlay;

		internal static ConfigEntry<bool> SurfaceClearance;

		internal static ConfigEntry<bool> FixtureMoveAway;

		internal static ConfigEntry<bool> SurfaceHidden;

		internal static ConfigEntry<string> Allowlist;

		internal static ConfigEntry<int> Price;

		internal static ConfigEntry<bool> HideUnplaceable;

		internal static ConfigEntry<bool> CeilingFixItems;

		internal static ConfigEntry<bool> ApartmentShutters;

		internal const string DefaultAllowlist = "VintageWallLampBallroom,FlowerBed,FlowerBedCorner,FlowerBedOld,BushBuddleia,BushMossy,Tree,TreeTall,BasketballHoop,PublicCorkboard,MagazineStand,Newsstand,HotelDeskLong,MoldedWaitingSeats,SyncBed,UnderDeskDrawers,LockersX6,HotelKeyRack,WashingMachines,Loudspeaker,TelevisionBillboard,SecurityCamera,SentryGun,ScoutLaser,CCTVTower,TelephoneBooth,AmusementRide,SupermarketFridge,SupermarketFreezer,SupermarketFreezerCorner,SupermarketShelving1,SupermarketShelving2,SupermarketEndShelf,SupermarketEmptyShelfLarge,SupermarketEmptyShelfSmall,SupermarketCounterLeft,SupermarketCounterRight,SupermarketScales,SupermarketSignSynthBeef,SupermarketSignStarch,ShopCounter,FruitStand,FruitStandApples,FruitStandBananas,FruitStandCabbages,NoodleStand,SynthFishStand,BasketStack,OpenSign,24HrSign,HotelWelcomeSign,FlowerBedOldCorner,HospitalBed,WalkInClosetItems,ClosetSlatDoors,TallJunkShelfDouble,IndustrialMachineShort,IndustrialMachineLong,IndustrialMachineLarge,IndustrialMachineCylinder,Loom,CableSpool,PowerBox,BreakerBox,RouterBox,NewspaperBox,ElGenSyncMachine,BurningBarrel,DinerWindowShelf,SecurityDoorDouble,SecurityDoorTriple,TelephoneBox,BathroomScales,TrousersOnFloor,ShirtOnFloor,DressOnFloor,ClothesPile,Graffiti,WallGrimeTop,WallGrimeBottom,LitterDecal,StaticCeilingRotLong,StaticCeilingRotShort,StaticCeilingRotCorner,Bollard,Hydrant,MooringPost";

		internal static ConfigEntry<bool> PutBackRestorePose;

		internal static ConfigEntry<KeyCode> EnterKey;

		internal static ConfigEntry<KeyCode> NudgeForward;

		internal static ConfigEntry<KeyCode> NudgeBack;

		internal static ConfigEntry<KeyCode> NudgeLeft;

		internal static ConfigEntry<KeyCode> NudgeRight;

		internal static ConfigEntry<KeyCode> NudgeUp;

		internal static ConfigEntry<KeyCode> NudgeDown;

		internal static ConfigEntry<KeyCode> RotateCCW;

		internal static ConfigEntry<KeyCode> RotateCW;

		internal static ConfigEntry<KeyCode> CycleAxis;

		internal static ConfigEntry<KeyCode> Confirm;

		internal static ConfigEntry<KeyCode> Reset;

		internal static ConfigEntry<KeyCode> CoarseMod;

		internal static ConfigEntry<KeyCode> FineMod;

		internal static ConfigEntry<KeyCode> CopyRot;

		internal static ConfigEntry<KeyCode> PasteRot;

		internal static void Init(ConfigFile cfg)
		{
			Enabled = cfg.Bind<bool>("Debug", "Enabled", false, "Enable the DecorProbe diagnostic (a dev tool that only reads and logs). Independent of the gameplay features.");
			ProbeKey = cfg.Bind<KeyCode>("Debug", "ProbeKey", (KeyCode)290, "Key to dump the decor census + item placement modes + ceiling measurements to the log (and a text file).");
			WriteFile = cfg.Bind<bool>("Debug", "WriteFile", true, "Also write each probe dump to BepInEx/PlacementPlus/decor_census_*.txt.");
			PrecisionPlacement = cfg.Bind<bool>("Items", "PrecisionPlacement", true, "Master switch for precision item placement (the enter-key mode that pins a held/carried object so you can move + rotate it freely, then place it).");
			MaxDistance = cfg.Bind<float>("Items", "MaxDistance", 10f, "Maximum distance (metres) you can push a pinned object away from yourself.");
			AllowPitchRoll = cfg.Bind<bool>("Items", "AllowPitchRoll", true, "Allow tilting items on all three axes (pitch/roll as well as yaw). Turn off for yaw-only.");
			ShowOverlay = cfg.Bind<bool>("Items", "ShowOverlay", true, "Show a small on-screen control hint while in placement mode.");
			SurfaceClearance = cfg.Bind<bool>("Items", "SurfaceClearance", true, "When placing an item, nudge it out of any wall/floor/ceiling its mesh is sunk into, so long or asymmetric items (silencers, barrels, scopes) can't clip behind a panel and become unpickable. Only pushes along the buried surface; never moves an item sitting clear of a wall, and never treats furniture (racks/shelves/doors) as an obstacle.");
			FixtureMoveAway = cfg.Bind<bool>("Fixtures", "MoveAway", true, "While placing furniture from the decor menu, use the same move keys (arrows) to push the preview further away or pull it closer/sideways, instead of it being stuck ~1m in front of you. Wall pieces keep their vanilla aim-at-wall behaviour. Height stays game-controlled.");
			SurfaceHidden = cfg.Bind<bool>("Fixtures", "SurfaceHidden", true, "Add a curated set of normally-hidden fixtures to the decor shop (see Allowlist). Session-only: turning this off and restarting fully reverts.");
			Allowlist = cfg.Bind<string>("Fixtures", "Allowlist", "VintageWallLampBallroom,FlowerBed,FlowerBedCorner,FlowerBedOld,BushBuddleia,BushMossy,Tree,TreeTall,BasketballHoop,PublicCorkboard,MagazineStand,Newsstand,HotelDeskLong,MoldedWaitingSeats,SyncBed,UnderDeskDrawers,LockersX6,HotelKeyRack,WashingMachines,Loudspeaker,TelevisionBillboard,SecurityCamera,SentryGun,ScoutLaser,CCTVTower,TelephoneBooth,AmusementRide,SupermarketFridge,SupermarketFreezer,SupermarketFreezerCorner,SupermarketShelving1,SupermarketShelving2,SupermarketEndShelf,SupermarketEmptyShelfLarge,SupermarketEmptyShelfSmall,SupermarketCounterLeft,SupermarketCounterRight,SupermarketScales,SupermarketSignSynthBeef,SupermarketSignStarch,ShopCounter,FruitStand,FruitStandApples,FruitStandBananas,FruitStandCabbages,NoodleStand,SynthFishStand,BasketStack,OpenSign,24HrSign,HotelWelcomeSign,FlowerBedOldCorner,HospitalBed,WalkInClosetItems,ClosetSlatDoors,TallJunkShelfDouble,IndustrialMachineShort,IndustrialMachineLong,IndustrialMachineLarge,IndustrialMachineCylinder,Loom,CableSpool,PowerBox,BreakerBox,RouterBox,NewspaperBox,ElGenSyncMachine,BurningBarrel,DinerWindowShelf,SecurityDoorDouble,SecurityDoorTriple,TelephoneBox,BathroomScales,TrousersOnFloor,ShirtOnFloor,DressOnFloor,ClothesPile,Graffiti,WallGrimeTop,WallGrimeBottom,LitterDecal,StaticCeilingRotLong,StaticCeilingRotShort,StaticCeilingRotCorner,Bollard,Hydrant,MooringPost", "Comma-separated FurniturePreset names to surface in the decor shop. Edit freely; run the DecorProbe (F9) to see every available name.");
			Price = cfg.Bind<int>("Fixtures", "Price", 50, "Flat price applied to every surfaced fixture (you pay for decor in-game).");
			HideUnplaceable = cfg.Bind<bool>("Fixtures", "HideUnplaceable", true, "Hide fixtures the apartment decor editor cannot actually place. Ceiling-mounted pieces are blocked by air ducts in almost every apartment tile, so they never place. Turn off to offer them anyway (they place only in rare duct-free spots).");
			CeilingFixItems = cfg.Bind<bool>("CeilingFix", "Items", true, "Fix player-placed ceiling lights that hang ~1m below the ceiling (the vanilla item-ceiling placement bug). Snaps the fixture's top to the ceiling. Does not touch vanilla room lights.");
			ApartmentShutters = cfg.Bind<bool>("Security", "ApartmentShutters", true, "Make a breaker box + security doors you place in your OWN apartment work as a self-contained privacy shutter: flipping the breaker's doors switch closes/opens only that apartment's doors, with no whole-floor lockdown. Fully isolated from the floor's security system and never affects vanilla alarms. Only affects fixtures you place yourself.");
			PutBackRestorePose = cfg.Bind<bool>("PutBack", "RestorePose", true, "When you drop an item near where it was, the game's native put-back returns its position but loses its rotation. This restores the exact placed rotation (and re-freezes display-placed items).");
			EnterKey = cfg.Bind<KeyCode>("Keys", "EnterPlacement", (KeyCode)118, "Enter precision placement for the held/carried item (press again to cancel).");
			NudgeForward = cfg.Bind<KeyCode>("Keys", "NudgeForward", (KeyCode)273, "Move the pinned object away from you.");
			NudgeBack = cfg.Bind<KeyCode>("Keys", "NudgeBack", (KeyCode)274, "Move the pinned object toward you.");
			NudgeLeft = cfg.Bind<KeyCode>("Keys", "NudgeLeft", (KeyCode)276, "Move the pinned object left.");
			NudgeRight = cfg.Bind<KeyCode>("Keys", "NudgeRight", (KeyCode)275, "Move the pinned object right.");
			NudgeUp = cfg.Bind<KeyCode>("Keys", "NudgeUp", (KeyCode)280, "Raise the pinned object (Home also works if you rebind).");
			NudgeDown = cfg.Bind<KeyCode>("Keys", "NudgeDown", (KeyCode)281, "Lower the pinned object.");
			RotateCCW = cfg.Bind<KeyCode>("Keys", "RotateCCW", (KeyCode)44, "Rotate the active axis counter-clockwise.");
			RotateCW = cfg.Bind<KeyCode>("Keys", "RotateCW", (KeyCode)46, "Rotate the active axis clockwise.");
			CycleAxis = cfg.Bind<KeyCode>("Keys", "CycleAxis", (KeyCode)116, "Cycle the rotation axis (yaw -> pitch -> roll).");
			Confirm = cfg.Bind<KeyCode>("Keys", "Confirm", (KeyCode)13, "Place the object statically at the previewed pose.");
			Reset = cfg.Bind<KeyCode>("Keys", "Reset", (KeyCode)8, "Reset tilt (pitch/roll to 0, yaw to the nearest 45 degrees).");
			CoarseMod = cfg.Bind<KeyCode>("Keys", "CoarseModifier", (KeyCode)304, "Hold for larger move/rotate steps.");
			FineMod = cfg.Bind<KeyCode>("Keys", "FineModifier", (KeyCode)308, "Hold for finer move/rotate steps (Alt, not Ctrl, to avoid the crouch/sprint keys).");
			CopyRot = cfg.Bind<KeyCode>("Keys", "CopyRotation", (KeyCode)111, "While placing, store the current rotation/orientation (not position) so you can apply it to other items. (O = copy Orientation; C is the game's crouch key.)");
			PasteRot = cfg.Bind<KeyCode>("Keys", "PasteRotation", (KeyCode)112, "While placing, apply the stored rotation/orientation to the current item, for lining several items up the same way.");
		}
	}
	public class PlacementController : MonoBehaviour
	{
		private sealed class Watch
		{
			public Interactable inter;

			public int start;

			public int stage;
		}

		internal static bool EntryBInProgress;

		internal static Interactable PendingDiag;

		private static bool _clearanceWarned;

		private static bool _shutterResyncDone;

		internal static Vector3? CopiedEuler;

		private static readonly List<Watch> _watch = new List<Watch>();

		internal static float FixtureOffsetX;

		internal static float FixtureOffsetZ;

		private static PlacementController _inst;

		private bool _active;

		private Interactable _target;

		private int _targetId = -1;

		private InteractableController _ctrl;

		private Vector3 _anchor;

		private Vector3 _euler;

		private int _axis;

		private bool _fromHand;

		private readonly Dictionary<KeyCode, float> _repeatAt = new Dictionary<KeyCode, float>();

		private Player _lastPlayer;

		private bool _fixtureWas;

		internal static bool ModeActive
		{
			get
			{
				if ((Object)(object)_inst != (Object)null)
				{
					return _inst._active;
				}
				return false;
			}
		}

		internal static bool Verbose => PlacementConfig.Enabled?.Value ?? false;

		public PlacementController(IntPtr ptr)
			: base(ptr)
		{
		}

		internal static void WatchAfterPutback(Interactable inter)
		{
			try
			{
				if (inter != null)
				{
					_watch.Add(new Watch
					{
						inter = inter,
						start = Time.frameCount,
						stage = 0
					});
				}
			}
			catch
			{
			}
		}

		private static void TickWatch()
		{
			try
			{
				int frameCount = Time.frameCount;
				int[] array = new int[3] { 15, 45, 90 };
				for (int num = _watch.Count - 1; num >= 0; num--)
				{
					Watch watch = _watch[num];
					if (watch.inter == null)
					{
						_watch.RemoveAt(num);
					}
					else
					{
						while (watch.stage < array.Length && frameCount - watch.start >= array[watch.stage])
						{
							Diag.DumpPhysState("PB+" + array[watch.stage] + "f", watch.inter);
							watch.stage++;
						}
						if (watch.stage >= array.Length)
						{
							_watch.RemoveAt(num);
						}
					}
				}
			}
			catch
			{
			}
		}

		internal static string V(Vector3 v)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			return $"({v.x:0.##},{v.y:0.##},{v.z:0.##})";
		}

		internal static string PresetName(Interactable inter)
		{
			try
			{
				return (inter != null && (SoCustomComparison)(object)inter.preset != (SoCustomComparison)null) ? ((Object)inter.preset).name : "?";
			}
			catch
			{
				return "?";
			}
		}

		private void Awake()
		{
			_inst = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_inst == (Object)(object)this)
			{
				_inst = null;
			}
		}

		private void Update()
		{
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (PendingDiag != null)
				{
					Interactable pendingDiag = PendingDiag;
					PendingDiag = null;
					Diag.DumpAnchors("PUTBACK-NEXTFRAME", pendingDiag);
				}
				if (_watch.Count > 0)
				{
					TickWatch();
				}
				Player instance = Player.Instance;
				if ((Object)(object)instance != (Object)(object)_lastPlayer)
				{
					_lastPlayer = instance;
					EntryBInProgress = false;
					_shutterResyncDone = false;
					if (_active)
					{
						Exit(placed: false);
					}
				}
				if (!_shutterResyncDone && (Object)(object)instance != (Object)null)
				{
					try
					{
						if ((Object)(object)SessionData.Instance != (Object)null && SessionData.Instance.startedGame && Gate.InPlay())
						{
							_shutterResyncDone = true;
							ApartmentShutters.ResyncAll();
						}
					}
					catch
					{
						_shutterResyncDone = true;
					}
				}
				PlayerApartmentController instance2 = PlayerApartmentController.Instance;
				if ((Object)(object)instance2 != (Object)null && instance2.furniturePlacementMode)
				{
					if (!_fixtureWas)
					{
						FixtureOffsetX = 0f;
						FixtureOffsetZ = 0f;
						_fixtureWas = true;
					}
					if (_active)
					{
						Exit(placed: false);
					}
					ConfigEntry<bool> fixtureMoveAway = PlacementConfig.FixtureMoveAway;
					if (fixtureMoveAway == null || fixtureMoveAway.Value)
					{
						HandleFixtureNudge();
					}
					return;
				}
				_fixtureWas = false;
				ConfigEntry<bool> precisionPlacement = PlacementConfig.PrecisionPlacement;
				if (precisionPlacement != null && !precisionPlacement.Value)
				{
					if (_active)
					{
						Exit(placed: false);
					}
					return;
				}
				if (!_active)
				{
					if (Input.GetKeyDown(PlacementConfig.EnterKey.Value))
					{
						TryEnter();
					}
					return;
				}
				if (!Gate.InPlay() || Gate.TextOrPopupActive())
				{
					Exit(placed: false);
					return;
				}
				InteractableController val = (((Object)(object)InteractionController.Instance != (Object)null) ? InteractionController.Instance.carryingObject : null);
				if ((Object)(object)val == (Object)null || (Object)(object)_ctrl == (Object)null || (Object)(object)val != (Object)(object)_ctrl)
				{
					Exit(placed: false);
				}
				else
				{
					HandleKeys();
				}
			}
			catch
			{
				try
				{
					Exit(placed: false);
				}
				catch
				{
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!_active || (Object)(object)_ctrl == (Object)null)
			{
				return;
			}
			try
			{
				(((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent : ((Component)_ctrl).transform).SetPositionAndRotation(_anchor, Quaternion.Euler(_euler));
			}
			catch
			{
				Exit(placed: false);
			}
		}

		private void TryEnter()
		{
			if (Gate.TextOrPopupActive() || Gate.VanillaDecorActive() || !Gate.InPlay())
			{
				return;
			}
			InteractionController instance = InteractionController.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)instance.carryingObject != (Object)null)
			{
				EnterFromCarry(instance.carryingObject);
				return;
			}
			InventorySlot val = (((Object)(object)BioScreenController.Instance != (Object)null) ? BioScreenController.Instance.selectedSlot : null);
			Interactable val2 = ((val != null) ? val.GetInteractable() : null);
			if (val2 != null)
			{
				EnterFromHand(val2);
			}
		}

		private void EnterFromCarry(InteractableController co)
		{
			//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_0061: 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)
			_ctrl = co;
			_target = co.interactable;
			_targetId = ((_target != null) ? _target.id : (-1));
			_fromHand = false;
			Transform val = (((Object)(object)co.alternativePhysicsParent != (Object)null) ? co.alternativePhysicsParent : ((Component)co).transform);
			_anchor = InitialAnchor(co);
			_euler = val.eulerAngles;
			_axis = 0;
			_active = true;
			Announce();
		}

		private void EnterFromHand(Interactable held)
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				InventorySlot selectedSlot = BioScreenController.Instance.selectedSlot;
				EntryBInProgress = true;
				bool flag = false;
				try
				{
					flag = held.IsSpawnPositionRelevent();
				}
				catch
				{
				}
				try
				{
					try
					{
						held.SetSpawnPositionRelevent(false);
					}
					catch
					{
					}
					FirstPersonItemController.Instance.EmptySlot(selectedSlot, false, false, false, false);
				}
				finally
				{
					EntryBInProgress = false;
					try
					{
						if (flag)
						{
							held.SetSpawnPositionRelevent(true);
						}
					}
					catch
					{
					}
				}
				ActionController.Instance.PickUp(held, ((Actor)Player.Instance).currentNode, (Actor)(object)Player.Instance);
				try
				{
					held.SetPhysicsPickupState(true, (Actor)(object)Player.Instance, true, false);
				}
				catch
				{
				}
				InteractableController carryingObject = InteractionController.Instance.carryingObject;
				if ((Object)(object)carryingObject == (Object)null || carryingObject.interactable == null)
				{
					Plugin.Log2.LogWarning((object)"[PlacementPlus] could not convert the held item to a carried object; returning it to the hand.");
					try
					{
						FirstPersonItemController.Instance.PickUpItem(held, true, false, true, true, true);
						return;
					}
					catch
					{
						return;
					}
				}
				_ctrl = carryingObject;
				_target = carryingObject.interactable;
				_targetId = _target.id;
				_fromHand = true;
				_anchor = InitialAnchor(carryingObject);
				Transform val = (((Object)(object)carryingObject.alternativePhysicsParent != (Object)null) ? carryingObject.alternativePhysicsParent : ((Component)carryingObject).transform);
				_euler = val.eulerAngles;
				_axis = 0;
				_active = true;
				Announce();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log2;
				bool flag2 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PlacementPlus] enter-from-hand failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}

		private void HandleKeys()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_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_005d: 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_006a: 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_00a0: 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_008a: 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_00c0: 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_00b0: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: 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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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_0267: Unknown result type (might be due to invalid IL or missing references)
			float num = 0.1f;
			float num2 = 15f;
			bool key = Input.GetKey(PlacementConfig.CoarseMod.Value);
			bool key2 = Input.GetKey(PlacementConfig.FineMod.Value);
			if (key)
			{
				num = 0.3f;
				num2 = 45f;
			}
			else if (key2)
			{
				num = 0.01f;
				num2 = 1f;
			}
			Vector3 val = FlatForward();
			Vector3 val2 = FlatRight();
			if (Repeat(PlacementConfig.NudgeForward.Value))
			{
				MoveAnchor(val * num);
			}
			if (Repeat(PlacementConfig.NudgeBack.Value))
			{
				MoveAnchor(-val * num);
			}
			if (Repeat(PlacementConfig.NudgeRight.Value))
			{
				MoveAnchor(val2 * num);
			}
			if (Repeat(PlacementConfig.NudgeLeft.Value))
			{
				MoveAnchor(-val2 * num);
			}
			if (Repeat(PlacementConfig.NudgeUp.Value))
			{
				MoveAnchor(Vector3.up * num);
			}
			if (Repeat(PlacementConfig.NudgeDown.Value))
			{
				MoveAnchor(Vector3.down * num);
			}
			if (Repeat(PlacementConfig.RotateCCW.Value))
			{
				RotateAxis(0f - num2);
			}
			if (Repeat(PlacementConfig.RotateCW.Value))
			{
				RotateAxis(num2);
			}
			if (Input.GetKeyDown(PlacementConfig.CycleAxis.Value))
			{
				_axis = (_axis + 1) % 3;
				ConfigEntry<bool> allowPitchRoll = PlacementConfig.AllowPitchRoll;
				if (allowPitchRoll != null && !allowPitchRoll.Value)
				{
					_axis = 0;
				}
				Plugin.Log2.LogInfo((object)("[PlacementPlus] rotation axis: " + AxisName()));
			}
			if (Input.GetKeyDown(PlacementConfig.Reset.Value))
			{
				_euler = new Vector3(0f, Mathf.Round(_euler.y / 45f) * 45f, 0f);
			}
			if (Input.GetKeyDown(PlacementConfig.CopyRot.Value))
			{
				CopiedEuler = _euler;
				Plugin.Log2.LogInfo((object)("[PlacementPlus] copied rotation " + V(_euler)));
			}
			if (Input.GetKeyDown(PlacementConfig.PasteRot.Value) && CopiedEuler.HasValue)
			{
				_euler = CopiedEuler.Value;
				Plugin.Log2.LogInfo((object)("[PlacementPlus] pasted rotation " + V(_euler)));
			}
			if (Input.GetKeyDown(PlacementConfig.Confirm.Value))
			{
				Confirm();
			}
			else if (Input.GetKeyDown(PlacementConfig.EnterKey.Value))
			{
				Exit(placed: false);
			}
		}

		private void HandleFixtureNudge()
		{
			//IL_000d: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (!Gate.TextOrPopupActive())
			{
				float num = (Input.GetKey(PlacementConfig.CoarseMod.Value) ? 0.9f : 0.3f);
				if (Repeat(PlacementConfig.NudgeForward.Value))
				{
					FixtureOffsetZ += num;
				}
				if (Repeat(PlacementConfig.NudgeBack.Value))
				{
					FixtureOffsetZ -= num;
				}
				if (Repeat(PlacementConfig.NudgeRight.Value))
				{
					FixtureOffsetX += num;
				}
				if (Repeat(PlacementConfig.NudgeLeft.Value))
				{
					FixtureOffsetX -= num;
				}
				if (Input.GetKeyDown(PlacementConfig.Reset.Value))
				{
					FixtureOffsetX = 0f;
					FixtureOffsetZ = 0f;
				}
				float num2 = Mathf.Max(1f, PlacementConfig.MaxDistance?.Value ?? 10f);
				FixtureOffsetZ = Mathf.Clamp(FixtureOffsetZ, -0.9f, num2);
				FixtureOffsetX = Mathf.Clamp(FixtureOffsetX, 0f - num2, num2);
			}
		}

		private void MoveAnchor(Vector3 delta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			_anchor += delta;
			try
			{
				Vector3 position = ((Component)Player.Instance.cam).transform.position;
				float num = Mathf.Max(1f, PlacementConfig.MaxDistance?.Value ?? 10f);
				Vector3 val = _anchor - position;
				if (((Vector3)(ref val)).magnitude > num)
				{
					_anchor = position + ((Vector3)(ref val)).normalized * num;
				}
			}
			catch
			{
			}
		}

		private void RotateAxis(float deg)
		{
			//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_0056: 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)
			Vector3 euler = _euler;
			bool flag = PlacementConfig.AllowPitchRoll?.Value ?? true;
			if (_axis == 0 || !flag)
			{
				euler.y += deg;
			}
			else if (_axis == 1)
			{
				euler.x += deg;
			}
			else
			{
				euler.z += deg;
			}
			_euler = euler;
		}

		private void Confirm()
		{
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: 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_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: 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_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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_00d3: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ctrl == (Object)null || _target == null)
			{
				Exit(placed: false);
				return;
			}
			bool flag = default(bool);
			try
			{
				Transform val = (((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent : ((Component)_ctrl).transform);
				Quaternion val2 = Quaternion.Euler(_euler);
				val.SetPositionAndRotation(_anchor, val2);
				ConfigEntry<bool> surfaceClearance = PlacementConfig.SurfaceClearance;
				if (surfaceClearance == null || surfaceClearance.Value)
				{
					Vector3 val3 = ComputeClearance(_ctrl, _anchor);
					if (val3 != Vector3.zero)
					{
						_anchor += val3;
						val.SetPositionAndRotation(_anchor, val2);
						if (Verbose)
						{
							ManualLogSource log = Plugin.Log2;
							BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(49, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] surface-clearance lifted ");
								((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(PresetName(_target));
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" by ");
								((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(val3));
								((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" -> ");
								((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_anchor));
							}
							log.LogWarning(val4);
						}
					}
				}
				ActionController.Instance.PutDown(_target, ((Actor)Player.Instance).currentNode, (Actor)(object)Player.Instance);
				val.SetPositionAndRotation(_anchor, val2);
				try
				{
					if ((Object)(object)_ctrl.rb != (Object)null)
					{
						_ctrl.rb.velocity = Vector3.zero;
						_ctrl.rb.angularVelocity = Vector3.zero;
					}
				}
				catch
				{
				}
				_ctrl.SetPhysics(false, (Actor)null);
				((Behaviour)_ctrl).enabled = false;
				_target.MoveInteractable(_anchor, _euler, true);
				_target.SetSpawnPositionRelevent(true);
				val.SetPositionAndRotation(_anchor, val2);
				FrozenMark.SetFrozen(_target, _anchor, _euler);
				if (Verbose)
				{
					Vector3 v = (((Object)(object)_ctrl.alternativePhysicsParent != (Object)null) ? _ctrl.alternativePhysicsParent.position : ((Component)_ctrl).transform.position);
					ManualLogSource log2 = Plugin.Log2;
					BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(64, 6, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] FROZE ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(PresetName(_target));
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": anchor=");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_anchor));
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" euler=");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_euler));
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ctrlPos=");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(((Component)_ctrl).transform.position));
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" altParent=");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(v));
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" wPos=");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(V(_target.wPos));
					}
					log2.LogWarning(val4);
				}
				Diag.DumpAnchors("FROZE", _target);
				Plugin.Log2.LogInfo((object)"[PlacementPlus] placed item at the previewed pose.");
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log2;
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(32, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[PlacementPlus] confirm failed: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
				}
				log3.LogWarning(val4);
			}
			Exit(placed: true);
		}

		private void Exit(bool placed)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			bool fromHand = _fromHand;
			Interactable target = _target;
			_active = false;
			_target = null;
			_ctrl = null;
			_fromHand = false;
			_axis = 0;
			_targetId = -1;
			if (!(!placed && fromHand) || target == null)
			{
				return;
			}
			try
			{
				InteractableController val = (((Object)(object)InteractionController.Instance != (Object)null) ? InteractionController.Instance.carryingObject : null);
				if ((Object)(object)val != (Object)null)
				{
					val.DropThis(false);
				}
				FirstPersonItemController.Instance.PickUpItem(target, true, false, true, true, true);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log2;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[PlacementPlus] return-to-hand failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val2);
			}
		}

		private bool Repeat(KeyCode k)
		{
			//IL_0006: 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_0014: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			if (Input.GetKeyDown(k))
			{
				_repeatAt[k] = unscaledTime + 0.35f;
				return true;
			}
			if (Input.GetKey(k))
			{
				if (!_repeatAt.TryGetValue(k, out var value))
				{
					value = unscaledTime + 0.35f;
				}
				if (unscaledTime >= value)
				{
					_repeatAt[k] = unscaledTime + 0.05f;
					return true;
				}
			}
			return false;
		}

		private static Vector3 FlatForward()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward = ((Component)Player.Instance.cam).transform.forward;
			forward.y = 0f;
			if (!(((Vector3)(ref forward)).sqrMagnitude > 0.0001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref forward)).normalized;
		}

		private static Vector3 FlatRight()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 right = ((Component)Player.Instance.cam).transform.right;
			right.y = 0f;
			if (!(((Vector3)(ref right)).sqrMagnitude > 0.0001f))
			{
				return Vector3.right;
			}
			return ((Vector3)(ref right)).normalized;
		}

		private static Vector3 InitialAnchor(InteractableController co)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0072: 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_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_008c: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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)
			try
			{
				Transform transform = ((Component)Player.Instance.cam).transform;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(transform.position, transform.forward, ref val, 4f, Toolbox.Instance.heldObjectsObjectsLayerMask))
				{
					float num = 0.05f;
					try
					{
						num = Mathf.Max(0.05f, co.colliderExtents.y);
					}
					catch
					{
					}
					return ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * num;
				}
				return transform.position + transform.forward * 1.5f;
			}
			catch
			{
				try
				{
					Transform transform2 = ((Component)Player.Instance.cam).transform;
					return transform2.position + transform2.forward * 1.5f;
				}
				catch
				{
					return Vector3.zero;
				}
			}
		}

		private Vector3 ComputeClearance(InteractableController ctrl, Vector3 anchor)
		{
			//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_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_0290: 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_029b: 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_02b4: 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_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: 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_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: 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_00fe: 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_0442: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Expected O, but got Unknown
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0