Decompiled source of ZenRedecorate v1.1.2

plugins\ZenRedecorate.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Zen.Config;
using Zen.Controls;
using Zen.Lib;
using Zen.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZenRedecorate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZenRedecorate")]
[assembly: AssemblyCopyright("Copyright \ufffd  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 ZenRedecorate
{
	public static class Configs
	{
		public static readonly ConfigEntry<bool> IsEncumberedWhenMovingPiece;

		public static readonly ConfigEntry<bool> IsProvidesSupportImmovable;

		public static readonly ConfigEntry<bool> ProvidesSupportWarning;

		public static readonly ConfigEntry<KeyCode> InputHoldKey;

		public static readonly ConfigEntry<KeyCode> InputPickup;

		public static readonly ConfigEntry<float> MaxCarryRange;

		public static readonly ConfigEntry<StringList> AllowedPrefabs;

		public static readonly ConfigEntry<StringList> DeniedPrefabs;

		static Configs()
		{
			//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)
			//IL_0071: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_009c: Expected O, but got Unknown
			//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_00c1: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_00ec: Expected O, but got Unknown
			IsEncumberedWhenMovingPiece = Config.Define<bool>(true, "General", "Encumbered When Redecorating", true, "Player is encumbered when moving things.\nThis protects against making it too easy to transport chests full of stuff over long distances.\nThat's what carts are for.");
			IsProvidesSupportImmovable = Config.Define<bool>(true, "General", "Provides Support Is Immovable", true, "Can not move anything that provides support, except furniture.");
			ProvidesSupportWarning = Config.Define<bool>(false, "General", "Provides Support Warning", false, "Display a warning before trying to move an object that provides support.\nThis setting ignores the IsProvidesSupportImmovable settings because\nthings like beds and tables also provide support as they are furniture.");
			StringList val = new StringList(Array.Empty<IEnumerable<string>>());
			((List<string>)val).Add("wood_fine_stack");
			((List<string>)val).Add("blackwood_stack");
			((List<string>)val).Add("bone_stack");
			((List<string>)val).Add("piece_beehive");
			AllowedPrefabs = Config.Define<StringList>(true, "General", "Allowed Prefabs", val, "These prefabs are always allowed to be moved.");
			StringList val2 = new StringList(Array.Empty<IEnumerable<string>>());
			((List<string>)val2).Add("fire_pit");
			((List<string>)val2).Add("bonfire");
			((List<string>)val2).Add("hearth");
			((List<string>)val2).Add("windmill");
			DeniedPrefabs = Config.Define<StringList>(true, "General", "Denied Prefabs", val2, "These prefabs are never allowed to be moved.");
			MaxCarryRange = Config.Define<float>(true, "General", "Max Carry Range", 35f, Config.AcceptRange<float>(5f, 50f), "Maximum distance that a piece can be carried before automatic abort.");
			InputHoldKey = Config.Define<KeyCode>(false, "Input", "Mode Select Modifier Key", (KeyCode)306, "Modifier Key to hold down to switch into move mode.");
			InputPickup = Config.Define<KeyCode>(false, "Input", "Pickup", (KeyCode)323, "Button to press to pickup.");
		}
	}
	internal static class Inputs
	{
		public static readonly ActionString Pickup = new ActionString("Pickup", "$inventory_pickup", true);

		public static readonly ActionString HoldKey = new ActionString("Modifier", "$inventory_move", true);

		internal static void RegisterInputs()
		{
			//IL_0022: 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)
			Pickup.AddButton((GamepadInput)7, false, true, false, 0f, 0f);
			Pickup.AddButton(Configs.InputPickup.Value, false, false, false, 0f, 0f);
			HoldKey.AddButton(Configs.InputHoldKey.Value, false, false, false, 0f, 0f);
		}

		internal static void CreateKeyHints()
		{
			KeyHint.Create((HintType)0, Pickup, 1, false);
			KeyHint.Create((HintType)0, HoldKey, 1, false);
			KeyHint.SetEvent((HintType)0, (Action)UpdateHints);
		}

		private static void UpdateHints()
		{
			if (Hud.IsPieceSelectionVisible())
			{
				KeyHint.SetVisible(HoldKey, false);
				KeyHint.SetVisible(Pickup, false);
			}
			else
			{
				KeyHint.SetVisible(HoldKey, !ZInput.IsGamepadActive() && !Redecorate.IsMoving && !ZInput.GetButton(ActionString.op_Implicit(HoldKey)));
				KeyHint.SetVisible(Pickup, (ZInput.IsGamepadActive() && !Redecorate.IsMoving) || (!ZInput.IsGamepadActive() && !Redecorate.IsMoving && ZInput.GetButton(ActionString.op_Implicit(HoldKey))));
			}
			KeyHint.SetVisible("Place", !ZInput.GetButton(ActionString.op_Implicit(HoldKey)) || Redecorate.IsMoving);
			KeyHint.SetVisible("BuildMenu", !Redecorate.IsMoving);
			KeyHint.SetVisible("Copy", !Redecorate.IsMoving);
		}
	}
	[HarmonyPatch]
	public static class Patch
	{
		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Piece),
			typeof(RequirementMode)
		})]
		private static class Player_HaveRequirements
		{
			[UsedImplicitly]
			private static void Prefix(Piece piece, ref Requirement[] __state)
			{
				if (Redecorate.IsMoving)
				{
					__state = piece.m_resources;
					piece.m_resources = Array.Empty<Requirement>();
				}
			}

			[UsedImplicitly]
			private static void Postfix(Piece piece, Requirement[] __state)
			{
				if (Redecorate.IsMoving)
				{
					piece.m_resources = __state;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "TryPlacePiece")]
		private static class Player_TryPlacePiece
		{
			private static bool _isMoving;

			[UsedImplicitly]
			private static void Prefix()
			{
				_isMoving = Redecorate.IsMoving;
			}

			[UsedImplicitly]
			private static void Postfix(ref bool __result)
			{
				if (_isMoving)
				{
					__result = false;
				}
			}

			[UsedImplicitly]
			[HarmonyTranspiler]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Player), "PlacePiece", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(Player_TryPlacePiece), "PlacePieceIntercept", (Type[])null, (Type[])null);
				return Transpilers.MethodReplacer(instructions, (MethodBase)methodInfo, (MethodBase)methodInfo2);
			}

			private static void PlacePieceIntercept(Player __instance, Piece piece, Vector3 position, Quaternion rotation, bool doAttack)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//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)
				if (_isMoving)
				{
					Redecorate.PlacePiece(position, rotation);
				}
				else
				{
					__instance.PlacePiece(piece, position, rotation, doAttack);
				}
			}
		}

		[HarmonyPatch]
		internal static class SerializeRotation
		{
			public static readonly HashSet<ZDO> ForceSyncRotation = new HashSet<ZDO>();

			private static Vector3 SyncRotation(ZDO zdo)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: 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_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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_001a: Unknown result type (might be due to invalid IL or missing references)
				Vector3 one = Vector3.one;
				Vector3 rotation = zdo.m_rotation;
				if (!ForceSyncRotation.Contains(zdo))
				{
					return rotation;
				}
				ForceSyncRotation.Remove(zdo);
				Log.Info((object)$"Force ZDO sync rotation: {zdo.m_rotation}", (ushort)0);
				return one;
			}

			[HarmonyTranspiler]
			[HarmonyPatch(typeof(ZDO), "Serialize")]
			private static IEnumerable<CodeInstruction> ZDO_Serialize(IEnumerable<CodeInstruction> codes)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(codes, (ILGenerator)null);
				FieldInfo fieldInfo = AccessTools.Field(typeof(ZDO), "m_rotation");
				MethodInfo methodInfo = AccessTools.Method(typeof(SerializeRotation), "SyncRotation", (Type[])null, (Type[])null);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)fieldInfo, (string)null)
				}).ThrowIfInvalid("Unable to find IL: Ldfld ZDO.m_rotation").Set(OpCodes.Call, (object)methodInfo);
				return val.Instructions();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "IsEncumbered")]
		private static void Player_IsEncumbered(Player __instance, ref bool __result)
		{
			if (!((Object)(object)Player.m_localPlayer != (Object)(object)__instance) && Redecorate.IsMoving && Configs.IsEncumberedWhenMovingPiece.Value)
			{
				__result = true;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StatusEffect), "Setup")]
		private static void StatusEffect_Encumbered_Setup(StatusEffect __instance, ref bool __runOriginal, Character character)
		{
			if (__instance.NameHash() == SEMan.s_statusEffectEncumbered && Redecorate.IsMoving && !((Object)(object)character != (Object)(object)Player.m_localPlayer))
			{
				__instance.m_startMessage = string.Empty;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "SetupPieceInfo")]
		private static void Hud_SetupPieceInfo(Hud __instance, Piece piece)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if (Redecorate.IsMoving)
			{
				GameObject[] requirementItems = __instance.m_requirementItems;
				for (int i = 0; i < requirementItems.Length; i++)
				{
					requirementItems[i].SetActive(false);
				}
				__instance.m_requirementItems[0].SetActive(true);
				((Component)__instance.m_requirementItems[0].transform.Find("res_icon")).GetComponent<Image>().sprite = Redecorate.EncumberedIcon;
				((Component)__instance.m_requirementItems[0].transform.Find("res_name")).GetComponent<TMP_Text>().text = "";
				((Component)__instance.m_requirementItems[0].transform.Find("res_amount")).GetComponent<TMP_Text>().text = "";
				if (Object.op_Implicit((Object)(object)piece.m_craftingStation))
				{
					GameObject val = __instance.m_requirementItems[1];
					GameObject val2 = __instance.m_requirementItems[piece.m_resources.Length];
					Image component = ((Component)val.transform.Find("res_icon")).GetComponent<Image>();
					Image component2 = ((Component)val2.transform.Find("res_icon")).GetComponent<Image>();
					component.sprite = component2.sprite;
					((Graphic)component).color = ((Graphic)component2).color;
					TMP_Text component3 = ((Component)val.transform.Find("res_name")).GetComponent<TMP_Text>();
					TMP_Text component4 = ((Component)val2.transform.Find("res_name")).GetComponent<TMP_Text>();
					component3.text = component4.text;
					((Graphic)component3).color = ((Graphic)component4).color;
					TMP_Text component5 = ((Component)val.transform.Find("res_amount")).GetComponent<TMP_Text>();
					TMP_Text component6 = ((Component)val2.transform.Find("res_amount")).GetComponent<TMP_Text>();
					component5.text = component6.text;
					((Graphic)component5).color = ((Graphic)component6).color;
					val.GetComponent<UITooltip>().m_text = val2.GetComponent<UITooltip>().m_text;
					val.SetActive(true);
				}
			}
			else if (Redecorate.IsPickupModifierPressed())
			{
				__instance.m_buildIcon.sprite = Redecorate.EncumberedIcon;
				__instance.m_buildSelection.text = Localization.instance.Localize("$inventory_move");
				__instance.m_pieceDescription.text = "";
				GameObject[] requirementItems = __instance.m_requirementItems;
				for (int i = 0; i < requirementItems.Length; i++)
				{
					requirementItems[i].SetActive(false);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Character), "Damage")]
		private static void Character_Damage(Character __instance)
		{
			if (!((Object)(object)Player.m_localPlayer != (Object)(object)__instance) && Redecorate.IsMoving)
			{
				Redecorate.AbortMove(hideHandItems: true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "TeleportTo")]
		private static void Player_TeleportTo(Player __instance)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)(object)__instance && Redecorate.IsMoving)
			{
				Redecorate.AbortMove(hideHandItems: true);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Hud), "TogglePieceSelection")]
		private static void Hud_TogglePieceSelection(Hud __instance, ref bool __runOriginal)
		{
			if (Redecorate.IsMoving)
			{
				__runOriginal = false;
				Redecorate.AbortMove(hideHandItems: false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "UpdateBuild")]
		private static void Hud_UpdateBuild(Hud __instance)
		{
			if ((!Object.op_Implicit((Object)(object)__instance.m_buildHud) || !__instance.m_buildHud.activeSelf) && Redecorate.IsMoving)
			{
				Redecorate.AbortMove(hideHandItems: false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
		private static void Hud_UpdateCrosshair(Hud __instance)
		{
			if (!Redecorate.IsMoving && Redecorate.IsPickupModifierPressed())
			{
				((Component)__instance.m_pieceHealthRoot).gameObject.SetActive(false);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PieceTable), "GetSelectedPiece")]
		private static void PieceTable_GetSelectedPiece(PieceTable __instance, ref bool __runOriginal, ref Piece __result)
		{
			if (Redecorate.IsMoving)
			{
				__runOriginal = false;
				__result = Redecorate.PlacementGhostPiece;
			}
			else if (Object.op_Implicit((Object)(object)Redecorate.CachedBuildPiece))
			{
				__runOriginal = false;
				__result = Redecorate.CachedBuildPiece;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PieceTable), "GetSelectedPrefab")]
		private static void PieceTable_GetSelectedPrefab(PieceTable __instance, ref bool __runOriginal, ref GameObject __result)
		{
			if (Redecorate.IsMoving)
			{
				__runOriginal = false;
				__result = Redecorate.GetSelected();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "CopyPiece")]
		private static void Player_CopyPiece(Player __instance, ref bool __runOriginal, ref bool __result)
		{
			if (Redecorate.IsMoving)
			{
				__runOriginal = false;
				__result = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "AutoPickup")]
		private static void Player_AutoPickup(ref bool __runOriginal)
		{
			if (Redecorate.IsMoving)
			{
				__runOriginal = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "UpdateAvailablePiecesList")]
		private static void Player_UpdateAvailablePiecesList(Player __instance)
		{
			Log.Debug((object)"Build pieces list updated", (ushort)0);
			if (Redecorate.IsMoving)
			{
				Redecorate.AbortMove(hideHandItems: false);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "SetPlacementGhostValid")]
		private static void Player_SetPlacementGhostValid(Player __instance, ref bool valid)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (Redecorate.IsMoving && valid)
			{
				valid = MathExt.DistanceTo(__instance.m_placementGhost, Redecorate.GetSelected()) < Configs.MaxCarryRange.Value;
				if (!valid)
				{
					__instance.m_placementStatus = (PlacementStatus)1;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
		private static void Player_UpdatePlacementGhost(Player __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			if (!Redecorate.IsMoving && Object.op_Implicit((Object)(object)__instance.m_placementGhost) && (int)__instance.m_placementStatus != 12)
			{
				bool flag = Redecorate.IsPickupModifierPressed();
				__instance.m_placementGhost.SetActive(!flag);
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					__instance.m_placementMarkerInstance.SetActive(!flag);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		private static void Player_UpdatePlacement(Player __instance, ref bool __runOriginal, bool takeInput)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!takeInput)
			{
				return;
			}
			if (Redecorate.IsMoving)
			{
				if (ZInput.IsGamepadActive() && (int)ZInput.InputLayout == 0 && ZInput.GetButtonDown("JoyButtonB"))
				{
					__runOriginal = false;
					PlayerController.SetTakeInputDelay(0.2f);
					Redecorate.AbortMove(hideHandItems: false);
				}
			}
			else if (Redecorate.IsPickupButtonPressed())
			{
				__runOriginal = false;
				Piece hoveringPiece = __instance.GetHoveringPiece();
				if (Object.op_Implicit((Object)(object)hoveringPiece))
				{
					Redecorate.PickupPiece(hoveringPiece);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "UpdateWearNTearHover")]
		private static void Player_UpdateWearNTearHover(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || Redecorate.IsMoving || !Redecorate.IsPickupModifierPressed())
			{
				return;
			}
			Piece hoveringPiece = __instance.GetHoveringPiece();
			if (Object.op_Implicit((Object)(object)hoveringPiece))
			{
				WearNTear component = ((Component)hoveringPiece).GetComponent<WearNTear>();
				if (Object.op_Implicit((Object)(object)component) && !Redecorate.CanMove(hoveringPiece))
				{
					component.ResetHighlight();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MaterialMan), "UnregisterRenderers")]
		private static void MaterialMan_UnregisterRenderers(MaterialMan __instance, GameObject gameObject, ref bool __runOriginal)
		{
			__runOriginal = __instance.m_blocks.ContainsKey(((Object)gameObject).GetInstanceID());
		}
	}
	[BepInPlugin("ZenDragon.ZenRedecorate", "ZenRedecorate", "1.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : ZenMod<Plugin>
	{
		public const string PluginName = "ZenRedecorate";

		public const string PluginVersion = "1.1.2";

		public const string PluginGUID = "ZenDragon.ZenRedecorate";

		protected override void Setup()
		{
			((ZenMod)this).RegisterInputs += Inputs.RegisterInputs;
		}

		protected override void TitleScene(bool isFirstBoot)
		{
		}

		private void Update()
		{
			if (ZenMod<Plugin>.Initialized && Redecorate.IsMoving)
			{
				Redecorate.LimitCarryDistance();
			}
		}

		protected override void WorldStart()
		{
			Redecorate.Init();
			Inputs.CreateKeyHints();
		}

		protected override void Shutdown()
		{
			Redecorate.Shutdown();
		}
	}
	internal static class Redecorate
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static PopupButtonCallback <>9__23_2;

			internal void <PickupPiece>b__23_2()
			{
				UnifiedPopup.instance.Hide();
			}
		}

		private static Piece? _movingPiece;

		public static bool IsMoving
		{
			get
			{
				if (Object.op_Implicit((Object)(object)_movingPiece))
				{
					return Object.op_Implicit((Object)(object)Player.m_localPlayer);
				}
				return false;
			}
		}

		public static Piece PlacementGhostPiece => Player.m_localPlayer.m_placementGhost.GetComponent<Piece>();

		public static Piece? CachedBuildPiece { get; private set; }

		public static Sprite? EncumberedIcon { get; private set; }

		public static GameObject GetSelected()
		{
			return ((Component)_movingPiece).gameObject;
		}

		public static void Init()
		{
			EncumberedIcon = ObjectDB.instance.GetStatusEffect(SEMan.s_statusEffectEncumbered).m_icon;
			RegisterRPC();
			_movingPiece = null;
		}

		public static void Shutdown()
		{
			AbortMove(hideHandItems: false);
			UnregisterRPC();
		}

		private static void RegisterRPC()
		{
			if (!ZNet.instance.IsDedicated())
			{
				ZRoutedRpc.instance.Register<ZDOID, Vector3, Quaternion>("RPC_MovePiece", (Action<long, ZDOID, Vector3, Quaternion>)RPC_MovePiece);
			}
		}

		private static void UnregisterRPC()
		{
			ZRoutedRpcExt.Unregister(ZRoutedRpc.instance, "RPC_MovePiece");
		}

		private static void MovePiece(Piece piece, Vector3 position, Quaternion rotation)
		{
			//IL_0024: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = piece.m_nview.GetZDO();
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_MovePiece", new object[3] { zDO.m_uid, position, rotation });
		}

		private static void RPC_MovePiece(long sender, ZDOID zdoID, Vector3 position, Quaternion rotation)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0074: 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)
			Log.Debug((object)string.Format("{0}: sender: {1}", "RPC_MovePiece", sender), (ushort)0);
			ZDO zDO = ZDOMan.instance.GetZDO(zdoID);
			if (zDO == null)
			{
				return;
			}
			if (!zDO.IsValid())
			{
				Log.Error((object)$"ZDO invalid: {zdoID}", (ushort)0);
				return;
			}
			if (zDO.IsOwner())
			{
				zDO.SetPositionAndRotation(position, rotation);
			}
			ZNetView val = ZNetScene.instance.FindInstance(zDO);
			if (Object.op_Implicit((Object)(object)val))
			{
				UpdateOrientation(((Component)val).gameObject, position, rotation);
			}
			else
			{
				Log.Info((object)"ZDO not found in ZNetScene. Probably too far away from piece being moved.", (ushort)0);
			}
		}

		private static void SetPositionAndRotation(this ZDO zdo, Vector3 position, Quaternion rotation)
		{
			//IL_0005: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			Log.Info((object)$"New ZDO position: {position} rotation: {((Quaternion)(ref rotation)).eulerAngles}", (ushort)0);
			uint dataRevision = zdo.DataRevision;
			zdo.SetRotation(rotation);
			if (zdo.DataRevision != dataRevision)
			{
				Patch.SerializeRotation.ForceSyncRotation.Add(zdo);
			}
			zdo.SetPosition(position);
		}

		public static void AbortMove(bool hideHandItems)
		{
			if (IsMoving)
			{
				Log.Info((object)"Abort Move Piece", (ushort)0);
				ShowMovedPiece(canShow: true);
				RestoreCachedBuildPiece();
				if (hideHandItems)
				{
					((Humanoid)Player.m_localPlayer).HideHandItems(false, true);
				}
			}
		}

		public static void LimitCarryDistance()
		{
			if (!MathExt.InRange((MonoBehaviour)(object)Player.m_localPlayer, GetSelected(), Configs.MaxCarryRange.Value))
			{
				AbortMove(hideHandItems: true);
			}
		}

		public static void PickupPiece(Piece piece)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			Piece piece2 = piece;
			Log.Info((object)("Start Move Piece " + piece2.m_name), (ushort)0);
			if (!CanMove(piece2, flashWard: true))
			{
				Log.Info((object)("Can not move " + piece2.m_name), (ushort)0);
				((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_cantpickup", 0, (Sprite)null);
				return;
			}
			Player player = Player.m_localPlayer;
			WearNTear wnt = ((Component)piece2).GetComponent<WearNTear>();
			if (wnt.m_supports && Configs.ProvidesSupportWarning.Value)
			{
				string text = Localization.instance.Localize(piece2.m_name);
				string text2 = "The " + text.ToLower() + " provides support for anything on it.  Are you sure you want to pick it up?";
				PopupButtonCallback val = delegate
				{
					Pickup();
					UnifiedPopup.instance.Hide();
				};
				object obj = <>c.<>9__23_2;
				if (obj == null)
				{
					PopupButtonCallback val2 = delegate
					{
						UnifiedPopup.instance.Hide();
					};
					<>c.<>9__23_2 = val2;
					obj = (object)val2;
				}
				YesNoPopup val3 = new YesNoPopup("Caution", text2, val, (PopupButtonCallback)obj, true);
				UnifiedPopup.instance.Show((PopupBase)(object)val3);
			}
			else
			{
				Pickup();
			}
			void Pickup()
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				CachedBuildPiece = player.GetSelectedPiece();
				_movingPiece = piece2;
				wnt.ResetHighlight();
				Player obj2 = player;
				Quaternion rotation = ((Component)_movingPiece).transform.rotation;
				obj2.m_placeRotation = AngleToRotationInterval(((Quaternion)(ref rotation)).eulerAngles.y);
				player.SetupPlacementGhost();
				ShowMovedPiece(canShow: false);
			}
		}

		public static void PlacePiece(Vector3 position, Quaternion rotation)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Piece movingPiece = _movingPiece;
			DestroyPlacementGhost();
			ShowMovedPiece(canShow: true);
			RestoreCachedBuildPiece();
			MovePiece(movingPiece, position, rotation);
			ApplyFX(movingPiece);
			Log.Info((object)("Finish Move Piece: " + movingPiece.m_name), (ushort)0);
		}

		private static void RefreshArmorStand(GameObject obj)
		{
			ArmorStand component = obj.GetComponent<ArmorStand>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_nview.InvokeRPC("RPC_SetPose", new object[1] { component.m_pose });
			}
		}

		private static void MoveWearNTear(WearNTear wnt)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			wnt.OnPlaced();
			wnt.ClearCachedSupport();
			wnt.m_colliders = null;
			wnt.m_connectedHeightMap.m_clearConnectedWearNTearCache -= wnt.ClearCachedSupport;
			wnt.m_connectedHeightMap = Heightmap.FindHeightmap(((Component)wnt).transform.position);
			wnt.m_connectedHeightMap.m_clearConnectedWearNTearCache += wnt.ClearCachedSupport;
		}

		private static Bed? GetBedIfSpawnPoint(GameObject obj)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Bed val = default(Bed);
			if (!obj.TryGetComponent<Bed>(ref val))
			{
				return null;
			}
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			if (val.GetOwner() != playerProfile.GetPlayerID())
			{
				return null;
			}
			if (playerProfile.GetCustomSpawnPoint() != val.GetSpawnPoint())
			{
				return null;
			}
			return val;
		}

		private static void UpdateBedSpawnPoint(Bed bed)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Game.instance.GetPlayerProfile().SetCustomSpawnPoint(bed.GetSpawnPoint());
		}

		private static void UpdateOrientation(GameObject movedObject, Vector3 position, Quaternion rotation)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			movedObject.BroadcastMessage("OnRedecorateBefore", (SendMessageOptions)1);
			(Vector3, Quaternion) tuple = (movedObject.transform.position, movedObject.transform.rotation);
			movedObject.transform.SetPositionAndRotation(position, rotation);
			Bed bedIfSpawnPoint = GetBedIfSpawnPoint(movedObject);
			if (Object.op_Implicit((Object)(object)bedIfSpawnPoint))
			{
				UpdateBedSpawnPoint(bedIfSpawnPoint);
			}
			WearNTear wnt = default(WearNTear);
			if (movedObject.TryGetComponent<WearNTear>(ref wnt))
			{
				MoveWearNTear(wnt);
			}
			movedObject.BroadcastMessage("OnRedecorateAfter", (object)tuple, (SendMessageOptions)1);
		}

		private static void ApplyFX(Piece piece, bool disableVisualFX = false, bool disableSoundFX = false)
		{
			//IL_0036: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || piece.m_placeEffect?.m_effectPrefabs == null)
			{
				return;
			}
			if (!disableVisualFX && !disableSoundFX)
			{
				Transform transform = ((Component)piece).transform;
				piece.m_placeEffect.Create(transform.position, transform.rotation, transform, 1f, -1);
				return;
			}
			List<EffectData> list = new List<EffectData>();
			EffectData[] effectPrefabs = piece.m_placeEffect.m_effectPrefabs;
			foreach (EffectData val in effectPrefabs)
			{
				if (!Object.op_Implicit((Object)(object)val.m_prefab) || (disableSoundFX && Object.op_Implicit((Object)(object)val.m_prefab.GetComponent<ZSFX>())) || (disableVisualFX && !Object.op_Implicit((Object)(object)val.m_prefab.GetComponent<ZSFX>())))
				{
					val.m_enabled = false;
					list.Add(val);
				}
			}
			if (piece.m_placeEffect.m_effectPrefabs.Length - list.Count > 0)
			{
				Transform transform2 = ((Component)piece).transform;
				piece.m_placeEffect.Create(transform2.position, transform2.rotation, transform2, 1f, -1);
				if (!disableSoundFX)
				{
					((Character)Player.m_localPlayer).AddNoise(50f);
				}
			}
			foreach (EffectData item in list)
			{
				item.m_enabled = true;
			}
		}

		private static int AngleToRotationInterval(float angle)
		{
			float num = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Player.m_localPlayer.m_placeRotationDegrees : 22.5f);
			return Mathf.RoundToInt(angle / num);
		}

		private static void DestroyPlacementGhost()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer.m_placementGhost))
			{
				Object.Destroy((Object)(object)localPlayer.m_placementGhost);
			}
			localPlayer.m_placementGhost = null;
		}

		private static void RestoreCachedBuildPiece()
		{
			if (Object.op_Implicit((Object)(object)CachedBuildPiece))
			{
				Player localPlayer = Player.m_localPlayer;
				if (Object.op_Implicit((Object)(object)localPlayer.m_buildPieces) && !localPlayer.SetSelectedPiece(CachedBuildPiece))
				{
					PlayerExt.SelectRepairTool(localPlayer);
				}
				CachedBuildPiece = null;
			}
		}

		private static void ShowMovedPiece(bool canShow)
		{
			if (Object.op_Implicit((Object)(object)_movingPiece))
			{
				((Component)_movingPiece).gameObject.SetActive(canShow);
			}
			if (canShow)
			{
				if (Object.op_Implicit((Object)(object)_movingPiece))
				{
					RefreshArmorStand(((Component)_movingPiece).gameObject);
				}
				_movingPiece = null;
				DestroyPlacementGhost();
			}
		}

		public static bool CanMove(Piece piece, bool flashWard = false)
		{
			//IL_008b: 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_0092: 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_0097: Invalid comparison between Unknown and I4
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			string prefabName = Utils.GetPrefabName(((Object)((Component)piece).gameObject).name);
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead())
			{
				Log.Info((object)"Deny: Player dead or missing", (ushort)0);
				return false;
			}
			if (!piece.IsPlacedByPlayer())
			{
				return false;
			}
			if (Configs.AllowedPrefabs.Value.Contains(prefabName, true))
			{
				Log.Debug((object)("Allow: Explicitly allowed prefab defined in config: " + prefabName), (ushort)0);
				return true;
			}
			if (Configs.DeniedPrefabs.Value.Contains(prefabName, true))
			{
				Log.Debug((object)("Deny: Explicitly excluded prefab defined in config: " + prefabName), (ushort)0);
				return false;
			}
			PieceCategory category = piece.m_category;
			if (category - 2 <= 1)
			{
				Log.Info((object)"Deny: All building pieces", (ushort)0);
				return false;
			}
			if (!WardAccessExt.CanAccessWard(((Component)piece).transform.position, flashWard))
			{
				Log.Info((object)"Deny: Warded", (ushort)0);
				return false;
			}
			if (Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Vagon>()))
			{
				Log.Info((object)"Deny: Vagons", (ushort)0);
				return false;
			}
			if (Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Ship>()))
			{
				Log.Info((object)"Deny: Ships", (ushort)0);
				return false;
			}
			if (piece.m_inCeilingOnly)
			{
				Log.Info((object)"Allow: Ceiling piece", (ushort)0);
				return true;
			}
			if (Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Plant>()))
			{
				Log.Info((object)"Deny: Plants", (ushort)0);
				return false;
			}
			Bed val = default(Bed);
			if (((Component)piece).TryGetComponent<Bed>(ref val) && (val.GetOwner() == 0L || val.GetOwner() == localPlayer.GetPlayerID()))
			{
				Log.Info((object)"Allow: My bed or vacant bed", (ushort)0);
				return true;
			}
			PrivateArea val2 = default(PrivateArea);
			if (((Component)piece).TryGetComponent<PrivateArea>(ref val2) && val2.IsEnabled())
			{
				Log.Info((object)"Deny: Warded", (ushort)0);
				return false;
			}
			Trap val3 = default(Trap);
			if (((Component)piece).TryGetComponent<Trap>(ref val3) && val3.IsArmed())
			{
				Log.Info((object)"Deny: Trap armed", (ushort)0);
				return false;
			}
			ShieldGenerator val4 = default(ShieldGenerator);
			if (((Component)piece).TryGetComponent<ShieldGenerator>(ref val4) && val4.m_radius > 0f)
			{
				Log.Info((object)"Deny: ShieldGen active", (ushort)0);
				return false;
			}
			Aoe componentInChildren = ((Component)piece).GetComponentInChildren<Aoe>();
			if (Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.m_useAttackSettings && !Object.op_Implicit((Object)(object)((Component)piece).GetComponent<Fireplace>()))
			{
				Log.Info((object)"Deny: Stake", (ushort)0);
				return false;
			}
			Container val5 = default(Container);
			if (((Component)piece).TryGetComponent<Container>(ref val5))
			{
				if (!val5.CheckAccess(localPlayer.GetPlayerID()))
				{
					Log.Info((object)"Deny: Private chest", (ushort)0);
					return false;
				}
				if (val5.IsInUse() || (Object.op_Implicit((Object)(object)val5.m_open) && val5.m_open.activeSelf))
				{
					Log.Info((object)"Deny: Container in use", (ushort)0);
					return false;
				}
			}
			WearNTear val6 = default(WearNTear);
			if (Configs.IsProvidesSupportImmovable.Value && (int)piece.m_category != 4 && ((Component)piece).TryGetComponent<WearNTear>(ref val6) && val6.m_supports)
			{
				Log.Info((object)"Deny: Supporting piece, not furniture", (ushort)0);
				return false;
			}
			Log.Debug((object)("Allow: " + prefabName), (ushort)0);
			return true;
		}

		public static bool IsPickupButtonPressed()
		{
			if (IsPickupModifierPressed())
			{
				return ZInput.GetButton(ActionString.op_Implicit(Inputs.Pickup));
			}
			return false;
		}

		public static bool IsPickupModifierPressed()
		{
			return ZInput.GetButton(ActionString.op_Implicit(ZInput.IsGamepadActive() ? Inputs.Pickup : Inputs.HoldKey));
		}
	}
}