Decompiled source of SupermarketTogetherObjectTools v0.1.0

BepInEx\plugins\SupermarketTogetherObjectTools\SupermarketTogetherObjectTools.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using SupermarketTogetherAnyPlaceBuilder;
using SupermarketTogetherObjectManipulator;
using SupermarketTogetherObjectSpawner;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SupermarketTogetherObjectTools")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SupermarketTogetherObjectTools")]
[assembly: AssemblyTitle("SupermarketTogetherObjectTools")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SupermarketTogetherObjectTools
{
	internal sealed class ObjectToolsMenu : MonoBehaviour
	{
		private const int BuilderTab = 0;

		private const int SpawnerTab = 1;

		private const int ManipulatorTab = 2;

		private const float ButtonHeight = 28f;

		private const float TabHeight = 32f;

		private readonly string[] tabs = new string[3] { "Builder", "Spawner", "Manipulator" };

		private ObjectToolsMenuSettings? menuSettings;

		private AnyPlaceBuilderSettings? builderSettings;

		private ObjectSpawnerSettings? spawnerSettings;

		private ObjectManipulatorSettings? manipulatorSettings;

		private ObjectSpawnerMenu? spawnerMenu;

		private ObjectManipulatorMenu? manipulatorMenu;

		private Rect windowRect = new Rect(60f, 80f, 760f, 680f);

		private bool visible;

		private int selectedTab;

		private bool pendingBuilderKeyBinding;

		private string statusMessage = "Select a tab, then choose an action.";

		public void Initialize(ManualLogSource logger, ObjectToolsMenuSettings settings, AnyPlaceBuilderSettings builder, ObjectSpawnerSettings spawner, ObjectManipulatorSettings manipulator, ObjectSpawnerMenu objectSpawnerMenu, ObjectManipulatorMenu objectManipulatorMenu)
		{
			menuSettings = settings;
			builderSettings = builder;
			spawnerSettings = spawner;
			manipulatorSettings = manipulator;
			spawnerMenu = objectSpawnerMenu;
			manipulatorMenu = objectManipulatorMenu;
		}

		private void Update()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (!pendingBuilderKeyBinding && menuSettings != null && Input.GetKeyDown(menuSettings.ToggleMenuKey.Value))
			{
				visible = !visible;
			}
		}

		private void OnGUI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0027: 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)
			if (visible)
			{
				windowRect = GUI.Window(((Object)this).GetInstanceID(), windowRect, new WindowFunction(DrawWindow), "Object Tools");
			}
		}

		private void DrawWindow(int windowId)
		{
			//IL_0042: 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)
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Object Tools", Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Menu key: {menuSettings?.ToggleMenuKey.Value}", Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(6f);
			DrawMainTabs();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label(tabs[selectedTab], Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			switch (selectedTab)
			{
			case 0:
				DrawBuilderTab();
				break;
			case 1:
				spawnerMenu?.DrawPanelContent();
				break;
			default:
				manipulatorMenu?.DrawPanelContent();
				break;
			}
			GUILayout.EndVertical();
			GUILayout.FlexibleSpace();
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				visible = false;
				ClearBuilderKeyBinding();
				manipulatorMenu?.HidePanel();
			}
			GUILayout.EndVertical();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void DrawMainTabs()
		{
			GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
			for (int i = 0; i < tabs.Length; i++)
			{
				if (GUILayout.Toggle(selectedTab == i, tabs[i], GUIStyle.op_Implicit("Button"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }) && selectedTab != i)
				{
					ClearBuilderKeyBinding();
					selectedTab = i;
					ActivateSelectedTab();
				}
			}
			GUILayout.EndHorizontal();
		}

		private void ActivateSelectedTab()
		{
			if (selectedTab == 1)
			{
				spawnerMenu?.ShowPanel();
			}
			else if (selectedTab == 2)
			{
				manipulatorMenu?.ShowPanel();
			}
		}

		private void DrawBuilderTab()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			CaptureBuilderKey(Event.current);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("状態", Array.Empty<GUILayoutOption>());
			GUILayout.Label("Place the current builder preview even when the base game blocks placement.", Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Any-place build key: {builderSettings?.PlacePreviewKey.Value}", Array.Empty<GUILayoutOption>());
			GUILayout.Label("Open the game's build preview first, then press the key above.", Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("キー設定", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(GetBuilderBindingButtonLabel(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				pendingBuilderKeyBinding = true;
				if (builderSettings != null)
				{
					builderSettings.SuppressPlacePreviewInput = true;
				}
				statusMessage = "Press a key for any-place build. Escape cancels.";
			}
			if (GUILayout.Button("Reset V", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				if (builderSettings != null)
				{
					builderSettings.PlacePreviewKey.Value = (KeyCode)118;
					((ConfigEntryBase)builderSettings.PlacePreviewKey).ConfigFile.Save();
				}
				ClearBuilderKeyBinding();
				statusMessage = "Any-place build key reset to V.";
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.Label("Use the tabs above to open Spawner and Manipulator.", Array.Empty<GUILayoutOption>());
		}

		private string GetBuilderBindingButtonLabel()
		{
			if (!pendingBuilderKeyBinding)
			{
				return "Change Build Key";
			}
			return "Press key...";
		}

		private void CaptureBuilderKey(Event currentEvent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_005e: 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)
			if (builderSettings == null || !pendingBuilderKeyBinding || (int)currentEvent.type != 4)
			{
				return;
			}
			if ((int)currentEvent.keyCode == 27)
			{
				ClearBuilderKeyBinding();
				statusMessage = "Any-place build key change canceled.";
				currentEvent.Use();
			}
			else if ((int)currentEvent.keyCode != 0)
			{
				if (menuSettings != null && currentEvent.keyCode == menuSettings.ToggleMenuKey.Value)
				{
					statusMessage = $"{currentEvent.keyCode} is reserved for the object tools menu.";
					currentEvent.Use();
					return;
				}
				builderSettings.PlacePreviewKey.Value = currentEvent.keyCode;
				((ConfigEntryBase)builderSettings.PlacePreviewKey).ConfigFile.Save();
				ClearBuilderKeyBinding();
				statusMessage = $"Any-place build key set to {currentEvent.keyCode}.";
				currentEvent.Use();
			}
		}

		private void ClearBuilderKeyBinding()
		{
			pendingBuilderKeyBinding = false;
			if (builderSettings != null)
			{
				builderSettings.SuppressPlacePreviewInput = false;
			}
		}
	}
	[BepInPlugin("uta_a.supermarkettogether.objecttools", "Supermarket Together Object Tools", "0.1.0")]
	public sealed class ObjectToolsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "uta_a.supermarkettogether.objecttools";

		public const string PluginName = "Supermarket Together Object Tools";

		public const string PluginVersion = "0.1.0";

		private Harmony? harmony;

		private void Awake()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			ObjectToolsMenuSettings objectToolsMenuSettings = new ObjectToolsMenuSettings(((BaseUnityPlugin)this).Config.Bind<KeyCode>("Menu", "ToggleMenuKey", (KeyCode)286, "Key used to show or hide the object tools menu."));
			AnyPlaceBuilderSettings anyPlaceBuilderSettings = new AnyPlaceBuilderSettings(((BaseUnityPlugin)this).Config.Bind<KeyCode>("Builder", "PlacePreviewKey", (KeyCode)118, "Key used to place the current translucent builder preview without placement validation."));
			ObjectSpawnerSettings objectSpawnerSettings = new ObjectSpawnerSettings(((BaseUnityPlugin)this).Config.Bind<float>("Spawner", "SpawnDistance", 3.5f, "Distance in front of the camera used when no surface is hit."));
			ObjectManipulatorSettings objectManipulatorSettings = new ObjectManipulatorSettings(((BaseUnityPlugin)this).Config.Bind<KeyCode>("Manipulator", "DuplicateHeldItemKey", (KeyCode)118, "Key used to spawn a copy of the currently held item."), ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Manipulator", "DeleteObjectKey", (KeyCode)98, "Key used to delete the networked object you are looking at."));
			harmony = new Harmony("uta_a.supermarkettogether.objecttools");
			harmony.PatchAll();
			AnyPlaceBuilderController anyPlaceBuilderController = ((Component)this).gameObject.AddComponent<AnyPlaceBuilderController>();
			ObjectSpawnerMenu objectSpawnerMenu = ((Component)this).gameObject.AddComponent<ObjectSpawnerMenu>();
			ObjectManipulatorMenu objectManipulatorMenu = ((Component)this).gameObject.AddComponent<ObjectManipulatorMenu>();
			anyPlaceBuilderController.Initialize(((BaseUnityPlugin)this).Logger, anyPlaceBuilderSettings);
			objectSpawnerMenu.Initialize(((BaseUnityPlugin)this).Logger, objectSpawnerSettings);
			objectManipulatorMenu.Initialize(((BaseUnityPlugin)this).Logger, objectManipulatorSettings);
			((Component)this).gameObject.AddComponent<ObjectToolsMenu>().Initialize(((BaseUnityPlugin)this).Logger, objectToolsMenuSettings, anyPlaceBuilderSettings, objectSpawnerSettings, objectManipulatorSettings, objectSpawnerMenu, objectManipulatorMenu);
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to open the category menu.", "Supermarket Together Object Tools", "0.1.0", objectToolsMenuSettings.ToggleMenuKey.Value));
		}

		private void OnDestroy()
		{
			Harmony? obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			harmony = null;
		}
	}
	internal sealed class ObjectToolsMenuSettings
	{
		public ConfigEntry<KeyCode> ToggleMenuKey { get; }

		public ObjectToolsMenuSettings(ConfigEntry<KeyCode> toggleMenuKey)
		{
			ToggleMenuKey = toggleMenuKey;
		}
	}
}
namespace SupermarketTogetherObjectManipulator
{
	internal sealed class ObjectManipulatorMenu : MonoBehaviour
	{
		private enum PendingKeyBinding
		{
			None,
			Duplicate,
			Delete
		}

		private const float SpawnDistance = 3.5f;

		private const float DefaultObjectGrabReach = 4f;

		private const float ButtonHeight = 28f;

		private ManualLogSource? logger;

		private ObjectManipulatorSettings? settings;

		private PendingKeyBinding pendingKeyBinding;

		private string statusMessage = "Ready.";

		public void Initialize(ManualLogSource pluginLogger, ObjectManipulatorSettings manipulatorSettings)
		{
			logger = pluginLogger;
			settings = manipulatorSettings;
		}

		internal void ShowPanel()
		{
			pendingKeyBinding = PendingKeyBinding.None;
		}

		internal void HidePanel()
		{
			pendingKeyBinding = PendingKeyBinding.None;
		}

		private void Update()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (settings != null && pendingKeyBinding == PendingKeyBinding.None)
			{
				if (Input.GetKeyDown(settings.DuplicateHeldItemKey.Value))
				{
					DuplicateHeldItem();
				}
				if (Input.GetKeyDown(settings.DeleteObjectKey.Value))
				{
					DeleteLookTarget();
				}
			}
		}

		internal void DrawPanelContent()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			CapturePendingKey(Event.current);
			if (settings != null)
			{
				GUILayout.Space(8f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label("現在のキー", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Copy held item: {settings.DuplicateHeldItemKey.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Delete look target: {settings.DeleteObjectKey.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
				GUILayout.Space(10f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label("キー設定", Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(GetBindingButtonLabel(PendingKeyBinding.Duplicate), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					pendingKeyBinding = PendingKeyBinding.Duplicate;
					statusMessage = "Press a key for copy. Escape cancels.";
				}
				if (GUILayout.Button(GetBindingButtonLabel(PendingKeyBinding.Delete), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					pendingKeyBinding = PendingKeyBinding.Delete;
					statusMessage = "Press a key for delete. Escape cancels.";
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Reset V / B", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
				{
					settings.DuplicateHeldItemKey.Value = (KeyCode)118;
					settings.DeleteObjectKey.Value = (KeyCode)98;
					((ConfigEntryBase)settings.DuplicateHeldItemKey).ConfigFile.Save();
					statusMessage = "Reset copy to V and delete to B.";
				}
				GUILayout.EndHorizontal();
				GUILayout.EndVertical();
				GUILayout.Space(8f);
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
			}
		}

		private string GetBindingButtonLabel(PendingKeyBinding binding)
		{
			if (pendingKeyBinding != binding)
			{
				if (binding != PendingKeyBinding.Duplicate)
				{
					return "Change Delete Key";
				}
				return "Change Copy Key";
			}
			return "Press key...";
		}

		private void CapturePendingKey(Event currentEvent)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_003e: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (settings == null || pendingKeyBinding == PendingKeyBinding.None || (int)currentEvent.type != 4)
			{
				return;
			}
			if ((int)currentEvent.keyCode == 27)
			{
				pendingKeyBinding = PendingKeyBinding.None;
				statusMessage = "Key change canceled.";
				currentEvent.Use();
			}
			else
			{
				if ((int)currentEvent.keyCode == 0)
				{
					return;
				}
				KeyCode val = ((pendingKeyBinding == PendingKeyBinding.Duplicate) ? settings.DeleteObjectKey.Value : settings.DuplicateHeldItemKey.Value);
				if (currentEvent.keyCode == val)
				{
					statusMessage = $"{currentEvent.keyCode} is already used by the other action.";
					currentEvent.Use();
					return;
				}
				if (pendingKeyBinding == PendingKeyBinding.Duplicate)
				{
					settings.DuplicateHeldItemKey.Value = currentEvent.keyCode;
					statusMessage = $"Copy key set to {currentEvent.keyCode}.";
				}
				else
				{
					settings.DeleteObjectKey.Value = currentEvent.keyCode;
					statusMessage = $"Delete key set to {currentEvent.keyCode}.";
				}
				((ConfigEntryBase)settings.DuplicateHeldItemKey).ConfigFile.Save();
				pendingKeyBinding = PendingKeyBinding.None;
				currentEvent.Use();
			}
		}

		private void DuplicateHeldItem()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_0197: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			PlayerNetwork localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer == (Object)null)
			{
				SetStatus("Local player was not found.", warning: true);
				return;
			}
			if (localPlayer.equippedItem <= 0 || localPlayer.equippedItem == 4)
			{
				SetStatus("No supported held item to copy.", warning: true);
				return;
			}
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				SetStatus("GameData was not found.", warning: true);
				return;
			}
			Vector3 spawnPosition = GetSpawnPosition(localPlayer);
			Quaternion rotation = ((Component)localPlayer).transform.rotation;
			float y = ((Quaternion)(ref rotation)).eulerAngles.y;
			NetworkSpawner component = ((Component)instance).GetComponent<NetworkSpawner>();
			ManagerBlackboard component2 = ((Component)instance).GetComponent<ManagerBlackboard>();
			switch (localPlayer.equippedItem)
			{
			case 16:
				component2.CmdSpawnManufacturingBoxFromPlayer(spawnPosition, localPlayer.extraParameter1, localPlayer.extraParameter2, y, localPlayer.extraParameter3);
				break;
			case 13:
			case 14:
			case 15:
				component.CmdSpawnProp(localPlayer.equippedItem, spawnPosition, Vector3.zero);
				break;
			case 12:
				component.CmdSpawnOrderBoxFromPlayer(spawnPosition, y, localPlayer.orderNumberData, localPlayer.orderCustomerNameData, localPlayer.orderItemsInBoxData);
				break;
			case 11:
				component.CmdSpawnProp(11, spawnPosition, new Vector3(0f, y, 0f));
				break;
			case 10:
				component.CmdSpawnProp(10, spawnPosition, new Vector3(180f, y, 0f));
				break;
			case 9:
				component.CmdSpawnTrayFromPlayer(spawnPosition, localPlayer.trayData, y);
				break;
			case 8:
				component.CmdSpawnProp(8, spawnPosition, new Vector3(15f, y, 0f));
				break;
			case 7:
				component.CmdSpawnProp(7, spawnPosition, new Vector3(0f, y, 0f));
				break;
			case 6:
				component.CmdSpawnProp(6, spawnPosition, new Vector3(180f, y, 0f));
				break;
			case 5:
				component.CmdSpawnProp(5, spawnPosition, new Vector3(270f, y, 0f));
				break;
			case 3:
				component.CmdSpawnProp(3, spawnPosition, new Vector3(270f, y, 0f));
				break;
			case 2:
				component.CmdSpawnProp(2, spawnPosition, new Vector3(0f, y, 90f));
				break;
			case 1:
				component2.CmdSpawnBoxFromPlayer(spawnPosition, localPlayer.extraParameter1, localPlayer.extraParameter2, y);
				break;
			default:
				SetStatus($"Held item #{localPlayer.equippedItem} is not supported.", warning: true);
				return;
			}
			SetStatus($"Copied held item #{localPlayer.equippedItem}.", warning: false);
		}

		private void DeleteLookTarget()
		{
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				SetStatus("GameData was not found.", warning: true);
				return;
			}
			if (!TryGetLookTarget(out GameObject target))
			{
				SetStatus("No deletable network object in sight.", warning: true);
				return;
			}
			((Component)instance).GetComponent<NetworkSpawner>().CmdDestroyBox(target);
			SetStatus("Deleted " + CleanPrefabName(((Object)target).name) + ".", warning: false);
		}

		private static bool TryGetLookTarget(out GameObject target)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val.position, val.forward, ref val2, GetObjectGrabReach(), -1, (QueryTriggerInteraction)1))
			{
				return false;
			}
			NetworkIdentity componentInParent = ((Component)((RaycastHit)(ref val2)).transform).GetComponentInParent<NetworkIdentity>();
			if ((Object)(object)componentInParent == (Object)null || IsProtectedDeleteTarget(((Component)componentInParent).gameObject))
			{
				return false;
			}
			target = ((Component)componentInParent).gameObject;
			return true;
		}

		private static float GetObjectGrabReach()
		{
			if ((Type.GetType("SupermarketTogetherMODMENU.PlayerReachPatch, SupermarketTogetherMODMENU")?.GetProperty("ReachDistance", BindingFlags.Static | BindingFlags.Public))?.GetValue(null) is float num)
			{
				return Mathf.Clamp(num, 0.5f, 100f);
			}
			return 4f;
		}

		private static bool IsProtectedDeleteTarget(GameObject target)
		{
			if (!((Object)(object)target.GetComponent<PlayerNetwork>() != (Object)null) && !((Object)(object)target.GetComponent<PlayerObjectController>() != (Object)null) && !((Object)(object)target.GetComponent<GameData>() != (Object)null))
			{
				return (Object)(object)target.GetComponent<NetworkSpawner>() != (Object)null;
			}
			return true;
		}

		private static Vector3 GetSpawnPosition(PlayerNetwork player)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0047: 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_0055: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((Component)player).transform.position);
			Vector3 val3 = (((Object)(object)val != (Object)null) ? val.forward : ((Component)player).transform.forward);
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val2, val3, ref val4, 3.5f, -1, (QueryTriggerInteraction)1))
			{
				Vector3 point = ((RaycastHit)(ref val4)).point;
				Vector3 normal = ((RaycastHit)(ref val4)).normal;
				return point + ((Vector3)(ref normal)).normalized * 0.5f;
			}
			return val2 + val3 * 3.5f;
		}

		private static PlayerNetwork? GetLocalPlayer()
		{
			PlayerNetwork[] array = Object.FindObjectsByType<PlayerNetwork>((FindObjectsSortMode)0);
			foreach (PlayerNetwork val in array)
			{
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
			return null;
		}

		private static string CleanPrefabName(string prefabName)
		{
			return prefabName.Replace("(Clone)", "").Trim();
		}

		private void SetStatus(string message, bool warning)
		{
			statusMessage = message;
			if (warning)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)message);
				}
			}
			else
			{
				ManualLogSource? obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogInfo((object)message);
				}
			}
		}
	}
	internal sealed class ObjectManipulatorSettings
	{
		public ConfigEntry<KeyCode> DuplicateHeldItemKey { get; }

		public ConfigEntry<KeyCode> DeleteObjectKey { get; }

		public ObjectManipulatorSettings(ConfigEntry<KeyCode> duplicateHeldItemKey, ConfigEntry<KeyCode> deleteObjectKey)
		{
			DuplicateHeldItemKey = duplicateHeldItemKey;
			DeleteObjectKey = deleteObjectKey;
		}
	}
}
namespace SupermarketTogetherObjectSpawner
{
	internal static class NoCostPlaceableSpawnPatch
	{
		[HarmonyPatch(typeof(NetworkSpawner), "UserCode_CmdSpawn__Int32__Vector3__Vector3")]
		[HarmonyPrefix]
		private static bool SpawnBuildableWithoutCost(NetworkSpawner __instance, int prefabID, Vector3 pos, Vector3 rot)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.buildables == null || prefabID < 0 || prefabID >= __instance.buildables.Length)
			{
				return false;
			}
			GameObject val = __instance.buildables[prefabID];
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Data_Container component = val.GetComponent<Data_Container>();
			int num = (((Object)(object)component != (Object)null) ? component.parentIndex : 0);
			GameObject obj = Object.Instantiate<GameObject>(val, pos, Quaternion.Euler(rot));
			obj.transform.SetParent(__instance.levelPropsOBJ.transform.GetChild(num));
			NetworkServer.Spawn(obj, (NetworkConnection)null);
			return false;
		}

		[HarmonyPatch(typeof(NetworkSpawner), "UserCode_CmdSpawnManufacturing__Int32__Vector3__Vector3")]
		[HarmonyPrefix]
		private static bool SpawnManufacturingWithoutCost(NetworkSpawner __instance, int prefabID, Vector3 pos, Vector3 rot)
		{
			//IL_0049: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.manufacturingBuildables == null || prefabID < 0 || prefabID >= __instance.manufacturingBuildables.Length)
			{
				return false;
			}
			GameObject val = __instance.manufacturingBuildables[prefabID];
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			ManufacturingContainer component = val.GetComponent<ManufacturingContainer>();
			int num = (((Object)(object)component != (Object)null) ? component.parentIndex : 10);
			GameObject obj = Object.Instantiate<GameObject>(val, pos, Quaternion.Euler(rot));
			obj.transform.SetParent(__instance.levelPropsOBJ.transform.GetChild(num));
			NetworkServer.Spawn(obj, (NetworkConnection)null);
			return false;
		}
	}
	internal sealed class ObjectSpawnCatalog
	{
		public bool TryBuildEntries(out List<ObjectSpawnEntry> entries)
		{
			entries = new List<ObjectSpawnEntry>();
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				return false;
			}
			AddProductBoxEntries(entries);
			AddHeldItemEntries(entries, networkSpawner.props);
			AddPlaceableObjectEntries(entries, "Buildable", networkSpawner.buildables);
			AddPlaceableObjectEntries(entries, "Manufacturing", networkSpawner.manufacturingBuildables);
			AddPlaceableObjectEntries(entries, "Decoration", networkSpawner.decorationProps);
			AddSceneOutdoorTrashCanEntries(entries);
			AddNpcEntries(entries);
			return true;
		}

		private static void AddProductBoxEntries(List<ObjectSpawnEntry> entries)
		{
			ProductListing instance = ProductListing.Instance;
			if (instance?.productsData == null)
			{
				return;
			}
			for (int i = 0; i < instance.productsData.Length; i++)
			{
				ProductData val = instance.productsData[i];
				if (val != null)
				{
					string localizedText = GetLocalizedText($"product{i}");
					string displayName = (string.IsNullOrWhiteSpace(localizedText) ? $"Product {i}" : localizedText);
					entries.Add(ObjectSpawnEntry.ProductBox(i, displayName, val.maxItemsPerBox));
				}
			}
		}

		private static void AddHeldItemEntries(List<ObjectSpawnEntry> entries, GameObject[]? prefabs)
		{
			if (prefabs == null)
			{
				return;
			}
			for (int i = 0; i < prefabs.Length; i++)
			{
				GameObject val = prefabs[i];
				if (!((Object)(object)val == (Object)null))
				{
					entries.Add(ObjectSpawnEntry.HeldItem(i, CleanPrefabName(((Object)val).name)));
				}
			}
		}

		private static void AddPlaceableObjectEntries(List<ObjectSpawnEntry> entries, string source, GameObject[]? prefabs)
		{
			if (prefabs == null)
			{
				return;
			}
			for (int i = 0; i < prefabs.Length; i++)
			{
				GameObject val = prefabs[i];
				if (!((Object)(object)val == (Object)null))
				{
					string placeableDisplayName = GetPlaceableDisplayName(val, source);
					entries.Add(ObjectSpawnEntry.PlaceableObject(i, placeableDisplayName, source, val));
					if ((Object)(object)val.GetComponent<TrashPlace>() != (Object)null)
					{
						entries.Add(ObjectSpawnEntry.OutdoorTrashCan(i, placeableDisplayName, source, val));
					}
				}
			}
		}

		private static void AddSceneOutdoorTrashCanEntries(List<ObjectSpawnEntry> entries)
		{
			TrashPlace[] array = Object.FindObjectsByType<TrashPlace>((FindObjectsSortMode)0);
			int num = 0;
			TrashPlace[] array2 = array;
			foreach (TrashPlace val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent<TrashSpawn>() != (Object)null))
				{
					GameObject gameObject = ((Component)val).gameObject;
					entries.Add(ObjectSpawnEntry.SceneOutdoorTrashCan(num, CleanPrefabName(((Object)gameObject).name) + " [Scene]", gameObject));
					num++;
				}
			}
		}

		private static void AddNpcEntries(List<ObjectSpawnEntry> entries)
		{
			entries.Add(ObjectSpawnEntry.Npc(0, "客", ObjectSpawnNpcKind.Customer));
			entries.Add(ObjectSpawnEntry.Npc(1, "通行人", ObjectSpawnNpcKind.Bystander));
			entries.Add(ObjectSpawnEntry.Npc(2, "泥棒客", ObjectSpawnNpcKind.ThiefCustomer));
			entries.Add(ObjectSpawnEntry.Npc(3, "Mister Grusch", ObjectSpawnNpcKind.MisterGrusch));
		}

		private static string GetPlaceableDisplayName(GameObject prefab, string source)
		{
			string text = source switch
			{
				"Buildable" => GetBuildableLocalizedName(prefab), 
				"Manufacturing" => GetManufacturingLocalizedName(prefab), 
				"Decoration" => GetDecorationLocalizedName(prefab), 
				_ => "", 
			};
			return (string.IsNullOrWhiteSpace(text) ? CleanPrefabName(((Object)prefab).name) : text) + " [" + GetPlaceableSourceLabel(source) + "]";
		}

		private static string GetBuildableLocalizedName(GameObject prefab)
		{
			Data_Container component = prefab.GetComponent<Data_Container>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText(component.buildableTag, $"buildable{component.containerID}", $"container{component.containerID}", $"furniture{component.containerID}");
		}

		private static string GetManufacturingLocalizedName(GameObject prefab)
		{
			ManufacturingContainer component = prefab.GetComponent<ManufacturingContainer>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText($"manufacturing{component.containerID}", $"manufacturingcontainer{component.containerID}", $"mcontainer{component.containerID}", $"buildable{component.containerID}");
		}

		private static string GetDecorationLocalizedName(GameObject prefab)
		{
			BuildableInfo component = prefab.GetComponent<BuildableInfo>();
			if ((Object)(object)component == (Object)null)
			{
				return "";
			}
			return FirstLocalizedText($"decoration{component.decorationID}", $"decoprop{component.decorationID}", $"deco{component.decorationID}", $"buildable{component.decorationID}");
		}

		private static string FirstLocalizedText(params string[] keys)
		{
			for (int i = 0; i < keys.Length; i++)
			{
				string localizedTextOrEmpty = GetLocalizedTextOrEmpty(keys[i]);
				if (!string.IsNullOrWhiteSpace(localizedTextOrEmpty))
				{
					return localizedTextOrEmpty;
				}
			}
			return "";
		}

		private static string GetPlaceableSourceLabel(string source)
		{
			return source switch
			{
				"Buildable" => "設置物", 
				"Manufacturing" => "製造", 
				"Decoration" => "装飾", 
				_ => source, 
			};
		}

		private static string GetLocalizedText(string key)
		{
			if ((Object)(object)LocalizationManager.instance == (Object)null)
			{
				return "";
			}
			return LocalizationManager.instance.GetLocalizationString(key);
		}

		private static string GetLocalizedTextOrEmpty(string key)
		{
			if (string.IsNullOrWhiteSpace(key) || (Object)(object)LocalizationManager.instance == (Object)null)
			{
				return "";
			}
			string localizationString = LocalizationManager.instance.GetLocalizationString(key);
			if (string.IsNullOrWhiteSpace(localizationString) || localizationString == key || localizationString.Equals("locError", StringComparison.OrdinalIgnoreCase))
			{
				return "";
			}
			return localizationString;
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindFirstObjectByType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static string CleanPrefabName(string prefabName)
		{
			return prefabName.Replace("(Clone)", "").Trim();
		}
	}
	internal enum ObjectSpawnEntryKind
	{
		ProductBox,
		HeldItem,
		PlaceableObject,
		OutdoorTrashCan,
		Npc
	}
	internal enum ObjectSpawnNpcKind
	{
		None,
		Customer,
		Bystander,
		ThiefCustomer,
		MisterGrusch
	}
	internal enum ObjectSpawnPlaceableSource
	{
		None,
		Buildable,
		Manufacturing,
		Decoration,
		SceneClone
	}
	internal sealed class ObjectSpawnEntry
	{
		public ObjectSpawnEntryKind Kind { get; }

		public int Id { get; }

		public string DisplayName { get; }

		public int Quantity { get; }

		public ObjectSpawnPlaceableSource PlaceableSource { get; }

		public ObjectSpawnNpcKind NpcKind { get; }

		public GameObject? Prefab { get; }

		private ObjectSpawnEntry(ObjectSpawnEntryKind kind, int id, string displayName, int quantity, ObjectSpawnPlaceableSource placeableSource, ObjectSpawnNpcKind npcKind, GameObject? prefab)
		{
			Kind = kind;
			Id = id;
			DisplayName = displayName;
			Quantity = quantity;
			PlaceableSource = placeableSource;
			NpcKind = npcKind;
			Prefab = prefab;
		}

		public static ObjectSpawnEntry ProductBox(int productId, string displayName, int quantity)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.ProductBox, productId, displayName, quantity, ObjectSpawnPlaceableSource.None, ObjectSpawnNpcKind.None, null);
		}

		public static ObjectSpawnEntry HeldItem(int itemId, string displayName)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.HeldItem, itemId, displayName, 1, ObjectSpawnPlaceableSource.None, ObjectSpawnNpcKind.None, null);
		}

		public static ObjectSpawnEntry PlaceableObject(int objectId, string displayName, string source, GameObject prefab)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.PlaceableObject, objectId, displayName, 0, ParsePlaceableSource(source), ObjectSpawnNpcKind.None, prefab);
		}

		public static ObjectSpawnEntry OutdoorTrashCan(int objectId, string displayName, string source, GameObject prefab)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.OutdoorTrashCan, objectId, displayName, 0, ParsePlaceableSource(source), ObjectSpawnNpcKind.None, prefab);
		}

		public static ObjectSpawnEntry SceneOutdoorTrashCan(int objectId, string displayName, GameObject template)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.OutdoorTrashCan, objectId, displayName, 0, ObjectSpawnPlaceableSource.SceneClone, ObjectSpawnNpcKind.None, template);
		}

		public static ObjectSpawnEntry Npc(int npcId, string displayName, ObjectSpawnNpcKind npcKind)
		{
			return new ObjectSpawnEntry(ObjectSpawnEntryKind.Npc, npcId, displayName, 0, ObjectSpawnPlaceableSource.None, npcKind, null);
		}

		private static ObjectSpawnPlaceableSource ParsePlaceableSource(string source)
		{
			return source switch
			{
				"Buildable" => ObjectSpawnPlaceableSource.Buildable, 
				"Manufacturing" => ObjectSpawnPlaceableSource.Manufacturing, 
				"Decoration" => ObjectSpawnPlaceableSource.Decoration, 
				_ => ObjectSpawnPlaceableSource.None, 
			};
		}
	}
	internal sealed class ObjectSpawnerMenu : MonoBehaviour
	{
		private readonly struct CategoryTab
		{
			public ObjectSpawnEntryKind Kind { get; }

			public string Label { get; }

			public CategoryTab(ObjectSpawnEntryKind kind, string label)
			{
				Kind = kind;
				Label = label;
			}
		}

		private const float ButtonHeight = 28f;

		private const float CategoryButtonWidth = 142f;

		private const float EntryRowHeight = 30f;

		private const float EntryListHeight = 430f;

		private readonly List<ObjectSpawnEntry> entries = new List<ObjectSpawnEntry>();

		private readonly CategoryTab[] categories = new CategoryTab[5]
		{
			new CategoryTab(ObjectSpawnEntryKind.ProductBox, "商品箱"),
			new CategoryTab(ObjectSpawnEntryKind.HeldItem, "手持ちアイテム"),
			new CategoryTab(ObjectSpawnEntryKind.PlaceableObject, "設置オブジェクト"),
			new CategoryTab(ObjectSpawnEntryKind.OutdoorTrashCan, "店外ゴミ箱"),
			new CategoryTab(ObjectSpawnEntryKind.Npc, "NPC")
		};

		private ManualLogSource? logger;

		private ObjectSpawnCatalog? catalog;

		private ObjectSpawnExecutor? executor;

		private Font? japaneseFont;

		private Vector2 scrollPosition;

		private ObjectSpawnEntryKind selectedCategory;

		private string searchText = "";

		private string statusMessage = "ゲームに入ってから「更新」を押してください。";

		private bool hasLoadedEntries;

		private readonly List<ObjectSpawnEntry> visibleEntries = new List<ObjectSpawnEntry>();

		private ObjectSpawnEntryKind cachedCategory;

		private string cachedSearchText = "";

		private int entriesVersion;

		private int cachedEntriesVersion = -1;

		public void Initialize(ManualLogSource pluginLogger, ObjectSpawnerSettings objectSpawnerSettings)
		{
			logger = pluginLogger;
			catalog = new ObjectSpawnCatalog();
			executor = new ObjectSpawnExecutor(pluginLogger, objectSpawnerSettings);
		}

		internal void ShowPanel()
		{
			if (!hasLoadedEntries)
			{
				RefreshEntries();
			}
		}

		internal void DrawPanelContent()
		{
			ApplyJapaneseFont();
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("カテゴリ", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			CategoryTab[] array = categories;
			for (int i = 0; i < array.Length; i++)
			{
				CategoryTab categoryTab = array[i];
				bool num = selectedCategory == categoryTab.Kind;
				string text = $"{categoryTab.Label} ({CountEntries(categoryTab.Kind)})";
				if (GUILayout.Toggle(num, text, GUIStyle.op_Implicit("Button"), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(142f),
					GUILayout.Height(28f)
				}))
				{
					selectedCategory = categoryTab.Kind;
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(8f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label("検索と更新", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("検索", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) });
			searchText = GUILayout.TextField(searchText, 64, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("クリア", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(72f),
				GUILayout.Height(28f)
			}))
			{
				searchText = "";
			}
			if (GUILayout.Button("更新", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(96f),
				GUILayout.Height(28f)
			}))
			{
				RefreshEntries();
			}
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
			GUILayout.Space(6f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			DrawEntries();
			GUILayout.EndVertical();
			GUILayout.Space(6f);
			GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
			GUILayout.Label(statusMessage, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
		}

		private void DrawEntries()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			RebuildVisibleEntriesIfNeeded();
			GUILayout.Label($"{GetCategoryLabel(selectedCategory)}: {visibleEntries.Count}", Array.Empty<GUILayoutOption>());
			if (visibleEntries.Count == 0)
			{
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(430f) });
				GUILayout.Space(16f);
				GUILayout.Label(string.IsNullOrWhiteSpace(searchText) ? "表示できる項目がありません。必要なら「更新」を押してください。" : "検索条件に一致する項目がありません。", Array.Empty<GUILayoutOption>());
				GUILayout.EndVertical();
				return;
			}
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(430f) });
			int num = Mathf.Clamp((int)(scrollPosition.y / 30f), 0, visibleEntries.Count - 1);
			int num2 = Mathf.CeilToInt(14.333333f) + 2;
			int num3 = Mathf.Min(visibleEntries.Count, num + num2);
			GUILayout.Space((float)num * 30f);
			for (int i = num; i < num3; i++)
			{
				ObjectSpawnEntry objectSpawnEntry = visibleEntries[i];
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label($"#{objectSpawnEntry.Id}", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(48f),
					GUILayout.Height(30f)
				});
				GUILayout.Label(objectSpawnEntry.DisplayName, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.MinWidth(260f),
					GUILayout.Height(30f)
				});
				if (GUILayout.Button("召喚", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(96f),
					GUILayout.Height(28f)
				}))
				{
					SpawnSelectedEntry(objectSpawnEntry);
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Space((float)(visibleEntries.Count - num3) * 30f);
			GUILayout.EndScrollView();
		}

		private void RefreshEntries()
		{
			if (catalog == null)
			{
				return;
			}
			entries.Clear();
			if (!catalog.TryBuildEntries(out List<ObjectSpawnEntry> collection))
			{
				hasLoadedEntries = false;
				statusMessage = "NetworkSpawner が見つかりません。セーブデータに入ってから実行してください。";
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
				return;
			}
			entries.AddRange(collection);
			entriesVersion++;
			hasLoadedEntries = true;
			statusMessage = $"{entries.Count} 件を読み込みました。";
			ManualLogSource? obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogInfo((object)statusMessage);
			}
		}

		private void RebuildVisibleEntriesIfNeeded()
		{
			if (cachedEntriesVersion == entriesVersion && cachedCategory == selectedCategory && string.Equals(cachedSearchText, searchText, StringComparison.Ordinal))
			{
				return;
			}
			visibleEntries.Clear();
			foreach (ObjectSpawnEntry entry in entries)
			{
				if (entry.Kind == selectedCategory && (string.IsNullOrWhiteSpace(searchText) || entry.DisplayName.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					visibleEntries.Add(entry);
				}
			}
			cachedEntriesVersion = entriesVersion;
			cachedCategory = selectedCategory;
			cachedSearchText = searchText;
		}

		private void SpawnSelectedEntry(ObjectSpawnEntry entry)
		{
			if (executor == null)
			{
				return;
			}
			statusMessage = executor.Spawn(entry);
			if (!statusMessage.StartsWith("召喚しました:", StringComparison.Ordinal))
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)statusMessage);
				}
			}
		}

		private int CountEntries(ObjectSpawnEntryKind kind)
		{
			int num = 0;
			foreach (ObjectSpawnEntry entry in entries)
			{
				if (entry.Kind == kind)
				{
					num++;
				}
			}
			return num;
		}

		private void ApplyJapaneseFont()
		{
			if (japaneseFont == null)
			{
				japaneseFont = Font.CreateDynamicFontFromOSFont(new string[4] { "Yu Gothic UI", "Yu Gothic", "Meiryo", "MS Gothic" }, 14);
			}
			if (!((Object)(object)japaneseFont == (Object)null) && !((Object)(object)GUI.skin.font == (Object)(object)japaneseFont))
			{
				GUI.skin.font = japaneseFont;
				GUI.skin.label.font = japaneseFont;
				GUI.skin.button.font = japaneseFont;
				GUI.skin.toggle.font = japaneseFont;
				GUI.skin.textField.font = japaneseFont;
				GUI.skin.window.font = japaneseFont;
			}
		}

		private string GetCategoryLabel(ObjectSpawnEntryKind kind)
		{
			CategoryTab[] array = categories;
			for (int i = 0; i < array.Length; i++)
			{
				CategoryTab categoryTab = array[i];
				if (categoryTab.Kind == kind)
				{
					return categoryTab.Label;
				}
			}
			return kind.ToString();
		}
	}
	internal sealed class ObjectSpawnerSettings
	{
		public ConfigEntry<float> SpawnDistance { get; }

		public ObjectSpawnerSettings(ConfigEntry<float> spawnDistance)
		{
			SpawnDistance = spawnDistance;
		}
	}
	internal sealed class ObjectSpawnExecutor
	{
		private readonly ManualLogSource logger;

		private readonly ObjectSpawnerSettings settings;

		public ObjectSpawnExecutor(ManualLogSource logger, ObjectSpawnerSettings settings)
		{
			this.logger = logger;
			this.settings = settings;
		}

		public string Spawn(ObjectSpawnEntry entry)
		{
			//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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "GameData が見つかりません。";
			}
			Vector3 spawnPosition = GetSpawnPosition(GetLocalPlayer());
			float spawnYRotation = GetSpawnYRotation();
			switch (entry.Kind)
			{
			case ObjectSpawnEntryKind.ProductBox:
				((Component)instance).GetComponent<ManagerBlackboard>().CmdSpawnBoxFromPlayer(spawnPosition, entry.Id, entry.Quantity, spawnYRotation);
				break;
			case ObjectSpawnEntryKind.HeldItem:
				((Component)instance).GetComponent<NetworkSpawner>().CmdSpawnProp(entry.Id, spawnPosition, GetHeldItemRotation(entry.Id, spawnYRotation));
				break;
			case ObjectSpawnEntryKind.PlaceableObject:
			case ObjectSpawnEntryKind.OutdoorTrashCan:
			{
				string text2 = SpawnPlaceableObject(((Component)instance).GetComponent<NetworkSpawner>(), entry, spawnPosition, spawnYRotation);
				if (!string.IsNullOrWhiteSpace(text2))
				{
					return text2;
				}
				break;
			}
			case ObjectSpawnEntryKind.Npc:
			{
				string text = SpawnNpc(entry, spawnPosition);
				if (!string.IsNullOrWhiteSpace(text))
				{
					return text;
				}
				break;
			}
			}
			string text3 = "召喚しました: " + entry.DisplayName;
			logger.LogInfo((object)text3);
			return text3;
		}

		private static string SpawnPlaceableObject(NetworkSpawner spawner, ObjectSpawnEntry entry, Vector3 spawnPosition, float yRotation)
		{
			//IL_000a: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (entry.PlaceableSource == ObjectSpawnPlaceableSource.SceneClone)
			{
				return SpawnSceneClone(entry, spawnPosition, yRotation);
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, yRotation, 0f);
			switch (entry.PlaceableSource)
			{
			case ObjectSpawnPlaceableSource.Buildable:
				spawner.CmdSpawn(entry.Id, spawnPosition, val);
				return "";
			case ObjectSpawnPlaceableSource.Manufacturing:
				spawner.CmdSpawnManufacturing(entry.Id, spawnPosition, val);
				return "";
			case ObjectSpawnPlaceableSource.Decoration:
				spawner.CmdSpawnDecoration(entry.Id, spawnPosition, val);
				return "";
			default:
				return "未対応の設置オブジェクトです。";
			}
		}

		private static string SpawnSceneClone(ObjectSpawnEntry entry, Vector3 spawnPosition, float yRotation)
		{
			//IL_001a: 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)
			if ((Object)(object)entry.Prefab == (Object)null)
			{
				return "複製元の店外ゴミ箱が見つかりません。";
			}
			GameObject val = Object.Instantiate<GameObject>(entry.Prefab, spawnPosition, Quaternion.Euler(0f, yRotation, 0f));
			if ((Object)(object)entry.Prefab.transform.parent != (Object)null)
			{
				val.transform.SetParent(entry.Prefab.transform.parent);
			}
			if (NetworkServer.active && (Object)(object)val.GetComponent<NetworkIdentity>() != (Object)null)
			{
				NetworkServer.Spawn(val, (NetworkConnection)null);
			}
			return "";
		}

		private static string SpawnNpc(ObjectSpawnEntry entry, Vector3 spawnPosition)
		{
			//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_005f: 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)
			if (!NetworkServer.active)
			{
				return "NPC召喚はホスト/サーバーでのみ実行できます。";
			}
			NPC_Manager instance = NPC_Manager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return "NPC_Manager が見つかりません。";
			}
			switch (entry.NpcKind)
			{
			case ObjectSpawnNpcKind.Customer:
				SpawnCustomerNpc(instance, spawnPosition, isThief: false);
				return "";
			case ObjectSpawnNpcKind.Bystander:
				SpawnBystanderNpc(instance, spawnPosition);
				return "";
			case ObjectSpawnNpcKind.ThiefCustomer:
				SpawnCustomerNpc(instance, spawnPosition, isThief: true);
				return "";
			case ObjectSpawnNpcKind.MisterGrusch:
				SpawnMisterGrusch(spawnPosition);
				return "";
			default:
				return "未対応のNPCです。";
			}
		}

		private static void SpawnCustomerNpc(NPC_Manager npcManager, Vector3 spawnPosition, bool isThief)
		{
			//IL_0001: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = InstantiateNpcAgent(npcManager, spawnPosition, npcManager.customersnpcParentOBJ.transform);
			NPC_Info component = val.GetComponent<NPC_Info>();
			component.NetworkNPCID = GetRandomNpcId(npcManager);
			component.NetworkisCustomer = true;
			component.isAThief = isThief;
			component.productItemPlaceWait = 0.5f;
			AddRandomProductsToBuy(component);
			NavMeshAgent component2 = val.GetComponent<NavMeshAgent>();
			ConfigureNpcAgent(component2);
			component2.destination = GetCustomerDestination(npcManager, spawnPosition);
			component.state = 0;
			NetworkServer.Spawn(val, (NetworkConnection)null);
		}

		private static void SpawnBystanderNpc(NPC_Manager npcManager, Vector3 spawnPosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = InstantiateNpcAgent(npcManager, spawnPosition, npcManager.dummynpcParentOBJ.transform);
			NPC_Info component = obj.GetComponent<NPC_Info>();
			component.NetworkNPCID = GetRandomNpcId(npcManager);
			component.isBystander = true;
			NavMeshAgent component2 = obj.GetComponent<NavMeshAgent>();
			ConfigureNpcAgent(component2);
			component2.destination = GetRandomChildPosition(npcManager.randomPointsOBJ, spawnPosition);
			NetworkServer.Spawn(obj, (NetworkConnection)null);
		}

		private static void SpawnMisterGrusch(Vector3 spawnPosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if (!((Object)(object)networkSpawner == (Object)null) && !((Object)(object)networkSpawner.misterGruschPrefabOBJ == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(networkSpawner.misterGruschPrefabOBJ, spawnPosition, Quaternion.identity);
				if ((Object)(object)networkSpawner.gruschesParentOBJ != (Object)null)
				{
					val.transform.SetParent(networkSpawner.gruschesParentOBJ.transform);
				}
				InitializeMisterGruschFields(val);
				NetworkServer.Spawn(val, (NetworkConnection)null);
			}
		}

		private static void InitializeMisterGruschFields(GameObject grusch)
		{
			MisterGrusch component = grusch.GetComponent<MisterGrusch>();
			if (!((Object)(object)component == (Object)null))
			{
				Transform obj = grusch.transform.Find("Pivot_MisterGrusch");
				SetPrivateField(component, "pivotAnimator", (obj != null) ? ((Component)obj).GetComponent<Animator>() : null);
				SetPrivateField(component, "speedComponent", grusch.GetComponent<NPC_Speed>());
				Transform obj2 = grusch.transform.Find("BoinkAudio");
				SetPrivateField(component, "boinkAudioOBJ", (obj2 != null) ? ((Component)obj2).gameObject : null);
				Transform obj3 = grusch.transform.Find("OtherScreams");
				SetPrivateField(component, "screamAudioSource", (obj3 != null) ? ((Component)obj3).GetComponent<AudioSource>() : null);
				Transform obj4 = grusch.transform.Find("Pivot_MisterGrusch/NumberCanvas/Number");
				SetPrivateField(component, "numberField", (obj4 != null) ? ((Component)obj4).GetComponent("TextMeshProUGUI") : null);
				SetPrivateField(component, "shelvesOBJ", NPC_Manager.Instance?.shelvesOBJ);
				SetPrivateField(component, "storageOBJ", NPC_Manager.Instance?.storageOBJ);
				NavMeshAgent component2 = grusch.GetComponent<NavMeshAgent>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = true;
					SetPrivateField(component, "agent", component2);
				}
			}
		}

		private static void SetPrivateField(object target, string fieldName, object? value)
		{
			if (value != null)
			{
				target.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(target, value);
			}
		}

		private static GameObject InstantiateNpcAgent(NPC_Manager npcManager, Vector3 spawnPosition, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(npcManager.npcAgentPrefab, spawnPosition, Quaternion.identity);
			obj.transform.SetParent(parent);
			return obj;
		}

		private static int GetRandomNpcId(NPC_Manager npcManager)
		{
			if (npcManager.NPCsArray == null || npcManager.NPCsArray.Length == 0)
			{
				return 0;
			}
			return Random.Range(0, npcManager.NPCsArray.Length);
		}

		private static void AddRandomProductsToBuy(NPC_Info npcInfo)
		{
			List<int> list = ProductListing.Instance?.availableProducts;
			if (list != null && list.Count != 0)
			{
				int num = Mathf.Clamp(Random.Range(1, 4), 1, list.Count);
				for (int i = 0; i < num; i++)
				{
					npcInfo.productsIDToBuy.Add(list[Random.Range(0, list.Count)]);
				}
				npcInfo.productsIDToBuy.Sort();
			}
		}

		private static void ConfigureNpcAgent(NavMeshAgent agent)
		{
			((Behaviour)agent).enabled = true;
			agent.stoppingDistance = 1f;
			agent.speed = 2.2f;
			agent.angularSpeed = 140f;
			agent.acceleration = 10f;
		}

		private static Vector3 GetCustomerDestination(NPC_Manager npcManager, Vector3 fallback)
		{
			//IL_0071: 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_0065: 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)
			if ((Object)(object)npcManager.shelvesOBJ != (Object)null && npcManager.shelvesOBJ.transform.childCount > 0)
			{
				Transform child = npcManager.shelvesOBJ.transform.GetChild(Random.Range(0, npcManager.shelvesOBJ.transform.childCount));
				Transform val = child.Find("Standspot");
				if (!((Object)(object)val != (Object)null))
				{
					return child.position;
				}
				return val.position;
			}
			return GetRandomChildPosition(npcManager.randomPointsOBJ, fallback);
		}

		private static Vector3 GetRandomChildPosition(GameObject parentObject, Vector3 fallback)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parentObject == (Object)null || parentObject.transform.childCount == 0)
			{
				return fallback;
			}
			return parentObject.transform.GetChild(Random.Range(0, parentObject.transform.childCount)).position;
		}

		private Vector3 GetSpawnPosition(PlayerNetwork? player)
		{
			//IL_005c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007b: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(settings.SpawnDistance.Value, 1f, 20f);
			Transform val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((player != null) ? ((Component)player).transform.position : Vector3.zero));
			Vector3 val3 = (((Object)(object)val != (Object)null) ? val.forward : ((player != null) ? ((Component)player).transform.forward : Vector3.forward));
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val2, val3, ref val4, num, -1, (QueryTriggerInteraction)1))
			{
				Vector3 point = ((RaycastHit)(ref val4)).point;
				Vector3 normal = ((RaycastHit)(ref val4)).normal;
				return point + ((Vector3)(ref normal)).normalized * 0.5f;
			}
			return val2 + val3 * num;
		}

		private static float GetSpawnYRotation()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			PlayerNetwork localPlayer = GetLocalPlayer();
			Quaternion rotation;
			if ((Object)(object)localPlayer != (Object)null)
			{
				rotation = ((Component)localPlayer).transform.rotation;
				return ((Quaternion)(ref rotation)).eulerAngles.y;
			}
			if (!((Object)(object)Camera.main != (Object)null))
			{
				return 0f;
			}
			rotation = ((Component)Camera.main).transform.rotation;
			return ((Quaternion)(ref rotation)).eulerAngles.y;
		}

		private static Vector3 GetHeldItemRotation(int itemId, float yRotation)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_005e: 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)
			switch (itemId)
			{
			case 6:
			case 10:
				return new Vector3(180f, yRotation, 0f);
			case 8:
				return new Vector3(15f, yRotation, 0f);
			case 3:
			case 5:
				return new Vector3(270f, yRotation, 0f);
			case 2:
				return new Vector3(0f, yRotation, 90f);
			case 13:
			case 14:
			case 15:
				return Vector3.zero;
			default:
				return new Vector3(0f, yRotation, 0f);
			}
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindFirstObjectByType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static PlayerNetwork? GetLocalPlayer()
		{
			PlayerNetwork[] array = Object.FindObjectsByType<PlayerNetwork>((FindObjectsSortMode)0);
			foreach (PlayerNetwork val in array)
			{
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).isLocalPlayer)
				{
					return val;
				}
			}
			return null;
		}
	}
}
namespace SupermarketTogetherAnyPlaceBuilder
{
	internal sealed class AnyPlaceBuilderController : MonoBehaviour
	{
		private static readonly FieldInfo? MainDummyField = Field(typeof(Builder_Main), "dummyOBJ");

		private static readonly FieldInfo? MainCurrentElementIndexField = Field(typeof(Builder_Main), "currentElementIndex");

		private static readonly FieldInfo? MainCurrentPropIndexField = Field(typeof(Builder_Main), "currentPropIndex");

		private static readonly FieldInfo? MainCurrentTabIndexField = Field(typeof(Builder_Main), "currentTabIndex");

		private static readonly FieldInfo? DecorationDummyField = Field(typeof(Builder_Decoration), "dummyOBJ");

		private static readonly FieldInfo? DecorationCurrentIndexField = Field(typeof(Builder_Decoration), "currentIndex");

		private ManualLogSource? logger;

		private AnyPlaceBuilderSettings? settings;

		public void Initialize(ManualLogSource pluginLogger, AnyPlaceBuilderSettings anyPlaceBuilderSettings)
		{
			logger = pluginLogger;
			settings = anyPlaceBuilderSettings;
		}

		private void Update()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (settings != null && !settings.SuppressPlacePreviewInput && Input.GetKeyDown(settings.PlacePreviewKey.Value) && !TryPlaceFromMainBuilder() && !TryPlaceFromDecorationBuilder())
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"No active placeable preview was found. Open the builder and select an object first.");
				}
			}
		}

		private bool TryPlaceFromMainBuilder()
		{
			//IL_00af: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			Builder_Main val = Object.FindObjectOfType<Builder_Main>();
			if ((Object)(object)val == (Object)null || (Object)(object)val.canvasBuilderOBJ == (Object)null || !val.canvasBuilderOBJ.activeInHierarchy)
			{
				return false;
			}
			GameObject fieldValue = GetFieldValue<GameObject>(MainDummyField, val);
			if ((Object)(object)fieldValue == (Object)null)
			{
				return false;
			}
			if (GetFieldValue<int>(MainCurrentElementIndexField, val) <= 1)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"Current builder mode is move/delete, not a new object placement.");
				}
				return true;
			}
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				ManualLogSource? obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogWarning((object)"NetworkSpawner was not found. Load into a save before placing objects.");
				}
				return true;
			}
			int fieldValue2 = GetFieldValue<int>(MainCurrentPropIndexField, val);
			int fieldValue3 = GetFieldValue<int>(MainCurrentTabIndexField, val);
			Quaternion rotation = fieldValue.transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles;
			if (val.furnitureTabsIndexes != null && val.furnitureTabsIndexes.Contains(fieldValue3))
			{
				networkSpawner.CmdSpawn(fieldValue2, fieldValue.transform.position, eulerAngles);
				LogPlaced("Buildable", fieldValue2, fieldValue.transform);
				return true;
			}
			if (fieldValue3 == 2)
			{
				networkSpawner.CmdSpawnManufacturing(fieldValue2, fieldValue.transform.position, eulerAngles);
				LogPlaced("Manufacturing", fieldValue2, fieldValue.transform);
				return true;
			}
			networkSpawner.CmdSpawnDecoration(fieldValue2, fieldValue.transform.position, eulerAngles);
			LogPlaced("Decoration", fieldValue2, fieldValue.transform);
			return true;
		}

		private bool TryPlaceFromDecorationBuilder()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Builder_Decoration val = Object.FindObjectOfType<Builder_Decoration>();
			if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
			{
				return false;
			}
			GameObject fieldValue = GetFieldValue<GameObject>(DecorationDummyField, val);
			int fieldValue2 = GetFieldValue<int>(DecorationCurrentIndexField, val);
			if ((Object)(object)fieldValue == (Object)null || fieldValue2 <= 0)
			{
				return false;
			}
			NetworkSpawner networkSpawner = GetNetworkSpawner();
			if ((Object)(object)networkSpawner == (Object)null)
			{
				ManualLogSource? obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"NetworkSpawner was not found. Load into a save before placing objects.");
				}
				return true;
			}
			Vector3 position = fieldValue.transform.position;
			Quaternion rotation = fieldValue.transform.rotation;
			networkSpawner.CmdSpawnDecoration(fieldValue2, position, ((Quaternion)(ref rotation)).eulerAngles);
			LogPlaced("Decoration", fieldValue2, fieldValue.transform);
			return true;
		}

		private void LogPlaced(string source, int prefabId, Transform transform)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource? obj = logger;
			if (obj != null)
			{
				object[] obj2 = new object[4]
				{
					source,
					prefabId,
					FormatVector(transform.position),
					null
				};
				Quaternion rotation = transform.rotation;
				obj2[3] = FormatVector(((Quaternion)(ref rotation)).eulerAngles);
				obj.LogInfo((object)string.Format("Placed {0} #{1} at {2} rot {3}.", obj2));
			}
		}

		private static NetworkSpawner? GetNetworkSpawner()
		{
			if (!((Object)(object)GameData.Instance != (Object)null))
			{
				return Object.FindObjectOfType<NetworkSpawner>();
			}
			return ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
		}

		private static T GetFieldValue<T>(FieldInfo? field, object target)
		{
			if (field == null)
			{
				return default(T);
			}
			object value = field.GetValue(target);
			if (value is T)
			{
				return (T)value;
			}
			return default(T);
		}

		private static FieldInfo? Field(Type type, string name)
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
		}

		private static string FormatVector(Vector3 value)
		{
			//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 $"({value.x:0.###}, {value.y:0.###}, {value.z:0.###})";
		}
	}
	internal sealed class AnyPlaceBuilderSettings
	{
		public ConfigEntry<KeyCode> PlacePreviewKey { get; }

		public bool SuppressPlacePreviewInput { get; set; }

		public AnyPlaceBuilderSettings(ConfigEntry<KeyCode> placePreviewKey)
		{
			PlacePreviewKey = placePreviewKey;
		}
	}
}