Decompiled source of More Vanilla Build Prefabs v1.1.0

MoreVanillaBuildPrefabs.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Managers;
using Jotunn.Utils;
using MVBP.Configs;
using MVBP.Extensions;
using MVBP.Helpers;
using MVBP.Properties;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MoreVanillaBuildPrefabs")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreVanillaBuildPrefabs")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("08a6f7d7-cf93-4931-aecd-abf2ce6ed34c")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace MVBP
{
	internal static class ModCompat
	{
		public const string ExtraSnapsGUID = "Searica.Valheim.ExtraSnapPointsMadeEasy";

		public const string PlanBuildGUID = "marcopogo.PlanBuild";

		public const string WackysDBGUID = "WackyMole.WackysDatabase";

		public const string PlantEverythingGUID = "advize.PlantEverything";

		private static bool? _ExtraSnapsInstalled;

		private static bool? _PlanBuildInstalled;

		private static bool? _WackysDBInstalled;

		private static bool? _PlantEverythingInstalled;

		private static MethodInfo ReInitExtraSnapPoints;

		private static MethodInfo PlanBuildScanTables;

		internal static bool IsPlantEverythingInstalled()
		{
			bool valueOrDefault = _PlantEverythingInstalled.GetValueOrDefault();
			if (!_PlantEverythingInstalled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("advize.PlantEverything");
				_PlantEverythingInstalled = valueOrDefault;
			}
			return _PlantEverythingInstalled.Value;
		}

		internal static bool IsWackysDBInstalled()
		{
			bool valueOrDefault = _WackysDBInstalled.GetValueOrDefault();
			if (!_WackysDBInstalled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("WackyMole.WackysDatabase");
				_WackysDBInstalled = valueOrDefault;
			}
			return _WackysDBInstalled.Value;
		}

		internal static bool IsPlanBuildInstalled()
		{
			bool valueOrDefault = _PlanBuildInstalled.GetValueOrDefault();
			if (!_PlanBuildInstalled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("marcopogo.PlanBuild");
				_PlanBuildInstalled = valueOrDefault;
			}
			return _PlanBuildInstalled.Value;
		}

		internal static bool IsExtraSnapsInstalled()
		{
			bool valueOrDefault = _ExtraSnapsInstalled.GetValueOrDefault();
			if (!_ExtraSnapsInstalled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("Searica.Valheim.ExtraSnapPointsMadeEasy");
				_ExtraSnapsInstalled = valueOrDefault;
			}
			return _ExtraSnapsInstalled.Value;
		}

		internal static bool UpdateExtraSnaps()
		{
			if (!IsExtraSnapsInstalled())
			{
				return false;
			}
			BaseUnityPlugin instance = Chainloader.PluginInfos["Searica.Valheim.ExtraSnapPointsMadeEasy"].Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (ReInitExtraSnapPoints == null)
			{
				try
				{
					ReInitExtraSnapPoints = ReflectionUtils.GetMethod(((object)instance).GetType(), "ReInitExtraSnapPoints", Type.EmptyTypes);
				}
				catch (Exception data)
				{
					Log.LogWarning(data);
				}
			}
			try
			{
				ReInitExtraSnapPoints?.Invoke(instance, Array.Empty<object>());
			}
			catch
			{
				Log.LogWarning("Could not re-init ExtraSnapPointsMadeEasy");
				return false;
			}
			return true;
		}

		internal static bool UpdatePlanBuild()
		{
			if (!IsPlanBuildInstalled())
			{
				return false;
			}
			BaseUnityPlugin instance = Chainloader.PluginInfos["marcopogo.PlanBuild"].Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			Log.LogInfo("PlanBuild is installed", LogLevel.Medium);
			try
			{
				MethodInfo planBuildUpdateScanPieces = GetPlanBuildUpdateScanPieces();
				Log.LogInfo("Triggering PlanBuild.UpdateScanPieces", LogLevel.Medium);
				planBuildUpdateScanPieces?.Invoke(instance, Array.Empty<object>());
				return true;
			}
			catch (Exception arg)
			{
				Log.LogWarning($"Failed to update PlanBuild:\n {arg}");
			}
			return false;
		}

		private static MethodInfo GetPlanBuildUpdateScanPieces()
		{
			if (PlanBuildScanTables == null)
			{
				PlanBuildScanTables = AccessTools.Method("PlanBuild.PlanBuildPlugin:UpdateScanPieces", Type.EmptyTypes, (Type[])null);
			}
			return PlanBuildScanTables;
		}

		internal static bool IsWackyDBClone(string name)
		{
			if (!IsWackysDBInstalled())
			{
				return false;
			}
			_ = (Object)(object)Chainloader.PluginInfos["WackyMole.WackysDatabase"].Instance == (Object)null;
			return false;
		}
	}
	[BepInPlugin("Searica.Valheim.MoreVanillaBuildPrefabs", "MoreVanillaBuildPrefabs", "1.1.0")]
	[BepInDependency("com.jotunn.jotunn", "2.19.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class MorePrefabs : BaseUnityPlugin
	{
		public const string PluginName = "MoreVanillaBuildPrefabs";

		internal const string Author = "Searica";

		public const string PluginGUID = "Searica.Valheim.MoreVanillaBuildPrefabs";

		public const string PluginVersion = "1.1.0";

		private const string MainSection = "1 - Global";

		private const string AdminSection = "2 - Admin";

		private const string CustomizationSection = "3 - Customization";

		private const string TextureSection = "4 - Textures";

		private static ConfigEntry<bool> PortalTexture;

		private static ConfigEntry<bool> DvergrWoodTexture;

		private const string UnsafeSection = "5 - Unsafe Patches";

		private static readonly Dictionary<string, PrefabDBConfig> PrefabDBConfigsMap = new Dictionary<string, PrefabDBConfig>();

		private static ConfigEntry<bool> CreativeMode { get; set; }

		private static ConfigEntry<bool> ForceAllPrefabs { get; set; }

		internal static bool IsCreativeMode => CreativeMode.Value;

		internal static bool IsForceAllPrefabs => ForceAllPrefabs.Value;

		private static ConfigEntry<bool> CreatorShopAdminOnly { get; set; }

		private static ConfigEntry<bool> AdminDeconstructOtherPlayers { get; set; }

		internal static bool IsCreatorShopAdminOnly => CreatorShopAdminOnly.Value;

		internal static bool IsAdminDeconstructOtherPlayers => AdminDeconstructOtherPlayers.Value;

		private static ConfigEntry<bool> EnableHammerCrops { get; set; }

		private static ConfigEntry<bool> EnableComfortPatches { get; set; }

		private static ConfigEntry<bool> EnableSeasonalPieces { get; set; }

		private static ConfigEntry<bool> EnablePlayerBasePatches { get; set; }

		private static ConfigEntry<bool> EnablePortalPatch { get; set; }

		internal static bool IsEnableHammerCrops => EnableHammerCrops.Value;

		internal static bool IsEnableComfortPatches => EnableComfortPatches.Value;

		internal static bool IsEnableSeasonalPieces => EnableSeasonalPieces.Value;

		internal static bool IsEnablePlayerBasePatches => EnablePlayerBasePatches.Value;

		internal static bool IsEnablePortalPatch => EnablePortalPatch.Value;

		internal static bool PatchPortalTexture => PortalTexture.Value;

		internal static bool PatchDvergrWoodTexture => DvergrWoodTexture.Value;

		private static ConfigEntry<bool> EnableBedPatches { get; set; }

		private static ConfigEntry<bool> EnableFermenterPatches { get; set; }

		internal static bool IsEnableBedPatches => EnableBedPatches.Value;

		internal static bool IsEnableFermenterPatches => EnableFermenterPatches.Value;

		internal static bool UpdatePieceSettings { get; set; } = false;


		internal static bool UpdatePlacementSettings { get; set; } = false;


		internal static bool UpdateModSettings { get; set; } = false;


		internal static bool UpdateSeasonalSettings { get; set; } = false;


		internal static bool IsPrefabConfigEnabled(string prefabName)
		{
			if (PrefabDBConfigsMap.ContainsKey(prefabName) && PrefabDBConfigsMap[prefabName].enabled != null)
			{
				return PrefabDBConfigsMap[prefabName].enabled.Value;
			}
			return false;
		}

		internal static void PieceSettingChanged(object obj, EventArgs args)
		{
			if (!UpdatePieceSettings)
			{
				UpdatePieceSettings = true;
			}
		}

		internal static void PlacementSettingChanged(object obj, EventArgs args)
		{
			if (!UpdatePlacementSettings)
			{
				UpdatePlacementSettings = true;
			}
		}

		internal static void ModSettingChanged(object obj, EventArgs args)
		{
			if (!UpdateModSettings)
			{
				UpdateModSettings = true;
			}
		}

		internal static void SeasonalSettingChanged(object obj, EventArgs args)
		{
			if (!UpdateSeasonalSettings)
			{
				UpdateSeasonalSettings = true;
			}
		}

		internal static bool NeedsCollisionPatchForGhost(string prefabName)
		{
			if (PrefabDBConfigsMap.TryGetValue(prefabName, out var value))
			{
				return value.ApplyPlacementPatch;
			}
			return false;
		}

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			ConfigManager.Init("Searica.Valheim.MoreVanillaBuildPrefabs", ((BaseUnityPlugin)this).Config);
			Initialize();
			ConfigManager.Save();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.MoreVanillaBuildPrefabs");
			Game.isModded = true;
			ConfigManager.SetupWatcher();
			ConfigManager.CheckForConfigManager();
			ConfigManager.OnConfigFileReloaded += delegate
			{
				InitManager.UpdatePlugin("Configuration file changed, re-initializing", saveConfig: false);
			};
			ConfigManager.OnConfigWindowClosed += delegate
			{
				InitManager.UpdatePlugin("Configuration changed in-game, re-initializing");
			};
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				InitManager.UpdatePlugin("Configuration synced, re-initializing");
			};
		}

		public void OnDestroy()
		{
			ConfigManager.Save();
		}

		internal static void Initialize()
		{
			CreativeMode = ConfigManager.BindConfig("1 - Global", "CreativeMode", value: false, "Set to true/enabled to enable pieces from the CreatorShop or Nature piece categories. By default, pieces set to those categories are not standard build pieces.");
			ForceAllPrefabs = ConfigManager.BindConfig("1 - Global", "ForceAllPrefabs", value: false, "If true/enabled, adds all prefabs to the hammer for building. Unless CreativeMode is also enabled it will not add pieces set to the CreatorShop or Nature category though.");
			Log.Verbosity = ConfigManager.BindConfig("1 - Global", "Verbosity", LogLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow down your game.", null, synced: false);
			CreatorShopAdminOnly = ConfigManager.BindConfig("2 - Admin", "CreatorShopAdminOnly", value: false, "Set to true/enabled to restrict placement and deconstruction of CreatorShop pieces to players with Admin status.");
			AdminDeconstructOtherPlayers = ConfigManager.BindConfig("2 - Admin", "AdminDeconstructOtherPlayers", value: true, "Set to true/enabled to allow admin players to deconstruct any pieces built by other players, even if doing so would normally be prevented (such as for CreatorShop or Nature pieces). Intended to prevent griefing via placement of indestructible objects.");
			EnableHammerCrops = ConfigManager.BindConfig("3 - Customization", "HammerCrops", value: false, "Set to true/enabled to enable placing vanilla crops with the hammer. Unless this setting is true Vanilla crops will not be available for placing with the hammer.");
			EnableComfortPatches = ConfigManager.BindConfig("3 - Customization", "ComfortPatches (Requires Restart)", value: true, "Set to true/enabled to patch new pieces to have comfort values like their vanilla counterparts.");
			EnablePlayerBasePatches = ConfigManager.BindConfig("3 - Customization", "PlayerBasePatches (Requires Restart)", value: true, "Set to true/enabled to patch player-built instances of new torches, fires, and beds so they suppress monster spawning just like their vanilla counterparts.");
			EnableSeasonalPieces = ConfigManager.BindConfig("3 - Customization", "SeasonalPieces", value: true, "Set to true/enabled to add all currently disabled seasonal pieces to the hammer build table.");
			EnablePortalPatch = ConfigManager.BindConfig("3 - Customization", "PortalPatch", value: true, "Set to true/enabled to have the new portal allow unrestricted teleporting. Set to false/disabled to have the new portal work the same as the vanilla portal.");
			PortalTexture = ConfigManager.BindConfig("4 - Textures", "PortalTexturePatch (Requires Restart)", value: false, "Set to true/enabled to change the texture of the new portal to appear as if it was created by those who dwell in the Mistlands. \nNote: change in appearance will not work for users without this mod.");
			DvergrWoodTexture = ConfigManager.BindConfig("4 - Textures", "DvergrWoodPatch (Requires Restart)", value: false, "Set to true/enabled to change the texture of the player built instances of of Dvergr wood floors and stairs to appear as if they were brand new. \nNote: change in appearance will not work for users without this mod.");
			EnableBedPatches = ConfigManager.BindConfig("5 - Unsafe Patches", "BedPatches (Requires Restart, Unsafe)", value: false, "Set to true/enabled to patch player-built instances of new beds so you can sleep in them.\nWARNING: enabling this setting can result in you losing your spawn point if had set your spawn using a patched bed and log in without this mod.");
			EnableFermenterPatches = ConfigManager.BindConfig("5 - Unsafe Patches", "FermenterPatches (Requires Restart, Unsafe)", value: false, "Set to true/enabled to patch player-built instances of fermenting barrels to function as a fermenter that are 30% faster than the vanilla fermenter.\nWARNING: enabling this setting can result in you losing the mead base that is fermenting if you load the area without this mod.");
			CreativeMode.SettingChanged += PieceSettingChanged;
			ForceAllPrefabs.SettingChanged += PieceSettingChanged;
			CreatorShopAdminOnly.SettingChanged += PieceSettingChanged;
			EnableHammerCrops.SettingChanged += PieceSettingChanged;
			AdminDeconstructOtherPlayers.SettingChanged += ModSettingChanged;
			Log.Verbosity.SettingChanged += ModSettingChanged;
			EnableSeasonalPieces.SettingChanged += SeasonalSettingChanged;
		}

		internal static PrefabDB GetPrefabDB(GameObject prefab)
		{
			if (PrefabDBConfigsMap.ContainsKey(((Object)prefab).name))
			{
				return PrefabDBConfigsMap[((Object)prefab).name].AsPrefabDB();
			}
			return BindNewPrefabDBConfig(prefab).AsPrefabDB();
		}

		private static PrefabDBConfig BindNewPrefabDBConfig(GameObject prefab)
		{
			PrefabDBConfig prefabDBConfig = new PrefabDBConfig(PrefabConfigs.GetDefaultPrefabDB(((Object)prefab).name));
			prefabDBConfig.enabled.SettingChanged += PieceSettingChanged;
			prefabDBConfig.allowedInDungeons.SettingChanged += PieceSettingChanged;
			prefabDBConfig.category.SettingChanged += PieceSettingChanged;
			prefabDBConfig.craftingStation.SettingChanged += PieceSettingChanged;
			prefabDBConfig.requirements.SettingChanged += PieceSettingChanged;
			if (prefabDBConfig.placementPatch != null)
			{
				prefabDBConfig.placementPatch.SettingChanged += PlacementSettingChanged;
			}
			if (prefabDBConfig.clipEverything != null)
			{
				prefabDBConfig.clipEverything.SettingChanged += PieceSettingChanged;
			}
			if (prefabDBConfig.clipGround != null)
			{
				prefabDBConfig.clipGround.SettingChanged += PieceSettingChanged;
			}
			PrefabDBConfigsMap[((Object)prefab).name] = prefabDBConfig;
			return prefabDBConfig;
		}
	}
	internal enum LogLevel
	{
		Low,
		Medium,
		High
	}
	internal static class Log
	{
		private static ManualLogSource logSource;

		internal static ConfigEntry<LogLevel> Verbosity { get; set; }

		internal static LogLevel VerbosityLevel => Verbosity.Value;

		internal static bool IsVerbosityLow => Verbosity.Value >= LogLevel.Low;

		internal static bool IsVerbosityMedium => Verbosity.Value >= LogLevel.Medium;

		internal static bool IsVerbosityHigh => Verbosity.Value >= LogLevel.High;

		internal static void Init(ManualLogSource logSource)
		{
			Log.logSource = logSource;
		}

		internal static void LogDebug(object data)
		{
			logSource.LogDebug(data);
		}

		internal static void LogError(object data)
		{
			logSource.LogError(data);
		}

		internal static void LogFatal(object data)
		{
			logSource.LogFatal(data);
		}

		internal static void LogMessage(object data)
		{
			logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			logSource.LogWarning(data);
		}

		internal static void LogInfo(object data, LogLevel level = LogLevel.Low)
		{
			if (Verbosity == null || VerbosityLevel >= level)
			{
				logSource.LogInfo(data);
			}
		}

		internal static void LogGameObject(GameObject prefab, bool includeChildren = false)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			LogInfo("***** " + ((Object)prefab).name + " *****");
			Component[] components = prefab.GetComponents<Component>();
			for (int i = 0; i < components.Length; i++)
			{
				LogComponent(components[i]);
			}
			if (!includeChildren)
			{
				return;
			}
			LogInfo("***** " + ((Object)prefab).name + " (children) *****");
			foreach (Transform item in prefab.transform)
			{
				Transform val = item;
				LogInfo(" - " + ((Object)((Component)val).gameObject).name);
				components = ((Component)val).gameObject.GetComponents<Component>();
				for (int i = 0; i < components.Length; i++)
				{
					LogComponent(components[i]);
				}
			}
		}

		internal static void LogComponent(Component compo)
		{
			LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---");
			PropertyInfo[] properties = ((object)compo).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (PropertyInfo propertyInfo in properties)
			{
				LogInfo($" - {propertyInfo.Name} = {propertyInfo.GetValue(compo)}");
			}
			FieldInfo[] fields = ((object)compo).GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
			foreach (FieldInfo fieldInfo in fields)
			{
				LogInfo($" - {fieldInfo.Name} = {fieldInfo.GetValue(compo)}");
			}
		}
	}
	[HarmonyPatch(typeof(DropOnDestroyed))]
	internal static class DropOnDestroyedPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("OnDestroyed")]
		private static bool OnDestroyedPrefix(DropOnDestroyed __instance)
		{
			Piece val = default(Piece);
			if (Object.op_Implicit((Object)(object)__instance) && InitManager.IsPatchedByMod((Component)(object)__instance) && ((Component)__instance).TryGetComponent<Piece>(ref val) && val.IsPlacedByPlayer())
			{
				Log.LogInfo("Disabling on destroyed drops for player-built object", LogLevel.Medium);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Piece))]
	internal static class PiecePatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(700)]
		[HarmonyPatch("Awake")]
		private static void PieceAwakePostfix(Piece __instance)
		{
			PrefabPatcher.PatchPlayerBuiltPieceIfNeed(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPriority(700)]
		[HarmonyPatch("SetCreator")]
		private static void PieceSetCreatorPostfix(Piece __instance)
		{
			PrefabPatcher.PatchPlayerBuiltPieceIfNeed(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetCreator")]
		private static void PieceSetCreatorPrefix(Piece __instance)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && !component.m_persistent)
			{
				component.m_persistent = true;
				ZSyncTransform val = ((Component)__instance).gameObject.GetComponent<ZSyncTransform>();
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = ((Component)__instance).gameObject.AddComponent<ZSyncTransform>();
				}
				val.m_syncPosition = true;
				val.m_syncRotation = true;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch("DropResources")]
		private static IEnumerable<CodeInstruction> DropResourcesTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0035: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(Piece), "m_resources"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Stloc_1, (object)null, (string)null)
			}).SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<Piece, Requirement[]>>((Func<Piece, Requirement[]>)DropResources_m_resources_Delegate)).InstructionEnumeration();
		}

		private static Requirement[] DropResources_m_resources_Delegate(Piece piece)
		{
			if (!Object.op_Implicit((Object)(object)piece))
			{
				return Array.Empty<Requirement>();
			}
			if (!InitManager.IsPatchedByMod((Component)(object)piece))
			{
				return piece.m_resources;
			}
			Log.LogInfo("Dropping resources for MVBP piece", LogLevel.Medium);
			if (!piece.IsPlacedByPlayer() && InitManager.TryGetDefaultPieceResources(((Component)piece).gameObject, out var defaultResources) && defaultResources != null)
			{
				return defaultResources;
			}
			Requirement[] array = piece.m_resources;
			if (!Object.op_Implicit((Object)(object)((Component)piece).gameObject))
			{
				return array;
			}
			MineRock5 mineRock = default(MineRock5);
			if (((Component)piece).gameObject.TryGetComponent<MineRock5>(ref mineRock))
			{
				array = RequirementsHelper.RemoveMineRock5DropsFromRequirements(array, mineRock);
			}
			MineRock mineRock2 = default(MineRock);
			if (((Component)piece).gameObject.TryGetComponent<MineRock>(ref mineRock2))
			{
				array = RequirementsHelper.RemoveMineRockDropsFromRequirements(array, mineRock2);
			}
			ZNetView val = default(ZNetView);
			if (!((Component)piece).gameObject.TryGetComponent<ZNetView>(ref val))
			{
				return array;
			}
			ItemStand val2 = default(ItemStand);
			if (((Component)piece).gameObject.TryGetComponent<ItemStand>(ref val2))
			{
				bool canBeRemoved = val2.m_canBeRemoved;
				val2.m_canBeRemoved = true;
				val.InvokeRPC("DropItem", Array.Empty<object>());
				val2.m_canBeRemoved = canBeRemoved;
			}
			Pickable pickable = default(Pickable);
			if (((Component)piece).gameObject.TryGetComponent<Pickable>(ref pickable))
			{
				val.InvokeRPC("Pick", Array.Empty<object>());
				array = RequirementsHelper.RemovePickableFromRequirements(array, pickable);
			}
			return array;
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatch
	{
		private static readonly int PieceRemovalMask = LayerMask.GetMask(new string[10] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "vehicle", "item", "piece_nonsolid", "Default_small" });

		[HarmonyTranspiler]
		[HarmonyPatch("PlacePiece")]
		private static IEnumerable<CodeInstruction> PlacePieceTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo methodInfo = ReflectionUtils.GetGenericMethod(typeof(Object), "Instantiate", 1, new Type[3]
			{
				typeof(Type),
				typeof(Vector3),
				typeof(Quaternion)
			}).MakeGenericMethod(typeof(GameObject));
			CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null)
			};
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, array).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)EmptyInventoryOnPlacement) })
				.InstructionEnumeration();
		}

		private static GameObject EmptyInventoryOnPlacement(GameObject gameObject)
		{
			Log.LogInfo("EmptyInventoryOnPlacement()", LogLevel.Medium);
			Container val = default(Container);
			if (InitManager.IsPrefabEnabled(gameObject) && gameObject.TryGetComponent<Container>(ref val))
			{
				val.m_inventory.RemoveAll();
				Log.LogInfo("Emptied inventory for: " + ((Object)gameObject).name, LogLevel.Medium);
			}
			return gameObject;
		}

		[HarmonyTranspiler]
		[HarmonyPatch("SetupPlacementGhost")]
		private static IEnumerable<CodeInstruction> SetupPlacementGhostTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			MethodInfo methodInfo = ReflectionUtils.GetGenericMethod(typeof(Object), "Instantiate", 1, new Type[1] { typeof(Type) }).MakeGenericMethod(typeof(GameObject));
			CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(Player), "m_placementGhost"), (string)null)
			};
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, array).SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)SetupPlacementGhostInstantiateDelegate)).InstructionEnumeration();
		}

		private static GameObject SetupPlacementGhostInstantiateDelegate(GameObject selectedPrefab)
		{
			if (!InitManager.IsPatchedByMod(selectedPrefab))
			{
				return Object.Instantiate<GameObject>(selectedPrefab);
			}
			bool flag = false;
			if (Object.op_Implicit((Object)(object)selectedPrefab.GetComponent<MonsterAI>()) || Object.op_Implicit((Object)(object)selectedPrefab.GetComponent<AnimalAI>()) || Object.op_Implicit((Object)(object)selectedPrefab.GetComponent<Tameable>()) || Object.op_Implicit((Object)(object)selectedPrefab.GetComponent<Ragdoll>()) || Object.op_Implicit((Object)(object)selectedPrefab.GetComponent<Humanoid>()))
			{
				flag = selectedPrefab.activeSelf;
				selectedPrefab.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(selectedPrefab);
			string name = ((Object)selectedPrefab).name;
			if (PieceHelper.AddedPrefabs.Contains(name) && MorePrefabs.NeedsCollisionPatchForGhost(name))
			{
				CollisionHelper.PatchCollider(val);
			}
			if (!flag)
			{
				return val;
			}
			selectedPrefab.SetActive(true);
			MonsterAI val2 = default(MonsterAI);
			if (val.TryGetComponent<MonsterAI>(ref val2))
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
			AnimalAI val3 = default(AnimalAI);
			if (val.TryGetComponent<AnimalAI>(ref val3))
			{
				Object.DestroyImmediate((Object)(object)val3);
			}
			Tameable val4 = default(Tameable);
			if (val.TryGetComponent<Tameable>(ref val4))
			{
				Object.DestroyImmediate((Object)(object)val4);
			}
			Ragdoll val5 = default(Ragdoll);
			if (val.TryGetComponent<Ragdoll>(ref val5))
			{
				Object.DestroyImmediate((Object)(object)val5);
			}
			Humanoid val6 = default(Humanoid);
			if (val.TryGetComponent<Humanoid>(ref val6))
			{
				val6.m_defaultItems = Array.Empty<GameObject>();
				val6.m_randomWeapon = Array.Empty<GameObject>();
				Humanoid val7 = val6;
				if (val7.m_randomArmor == null)
				{
					val7.m_randomArmor = Array.Empty<GameObject>();
				}
				val7 = val6;
				if (val7.m_randomShield == null)
				{
					val7.m_randomShield = Array.Empty<GameObject>();
				}
				val7 = val6;
				if (val7.m_randomSets == null)
				{
					val7.m_randomSets = Array.Empty<ItemSet>();
				}
			}
			val.SetActive(true);
			return val;
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdatePlacementGhost")]
		private static void UpdatePlacementGhostPostfix(Player __instance)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			PieceDB pieceDB;
			if ((Object)(object)__instance.m_placementGhost == (Object)null)
			{
				if (Object.op_Implicit((Object)(object)__instance.m_placementMarkerInstance))
				{
					__instance.m_placementMarkerInstance.SetActive(false);
				}
			}
			else if (InitManager.TryGetPieceDB(__instance.m_placementGhost, out pieceDB) && pieceDB.placementOffset.HasValue)
			{
				Quaternion rotation = __instance.m_placementGhost.transform.rotation;
				Vector3 position = __instance.m_placementGhost.transform.position;
				__instance.m_placementGhost.transform.position = position + rotation * pieceDB.placementOffset.Value;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("RemovePiece")]
		internal static bool RemovePiecePrefix(Player __instance, ref bool __result)
		{
			//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)
			//IL_0048: 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)
			if (((Humanoid)__instance).GetRightItem().m_shared.m_name == "$item_hammer")
			{
				Transform transform = ((Component)GameCamera.instance).transform;
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(transform.position, transform.forward, ref val, 50f, PieceRemovalMask) && Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)__instance).m_eye.position) < __instance.m_maxPlaceDistance)
				{
					Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
					if (Object.op_Implicit((Object)(object)componentInParent) && InitManager.IsPatchedByMod((Component)(object)componentInParent))
					{
						__result = RemoveCustomPiece(__instance, componentInParent);
						return false;
					}
				}
			}
			return true;
		}

		private static bool RemoveCustomPiece(Player player, Piece piece)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)piece))
			{
				if (!Check_m_canBeRemoved(piece))
				{
					return false;
				}
				if (Location.IsInsideNoBuildLocation(((Component)piece).transform.position))
				{
					((Character)player).Message((MessageType)2, "$msg_nobuildzone", 0, (Sprite)null);
					return false;
				}
				if (!PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false))
				{
					((Character)player).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null);
					return false;
				}
				if (!player.CheckCanRemovePiece(piece))
				{
					return false;
				}
				ZNetView component = ((Component)piece).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null)
				{
					return false;
				}
				if (!piece.CanBeRemoved())
				{
					((Character)player).Message((MessageType)2, "$msg_cantremovenow", 0, (Sprite)null);
					return false;
				}
				WearNTear component2 = ((Component)piece).GetComponent<WearNTear>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.Remove();
				}
				else
				{
					Log.LogInfo("Removing non WNT object with hammer " + ((Object)piece).name);
					component.ClaimOwnership();
					if (!RemoveDestructiblePiece(piece) && !RemoveMineRock5Piece(piece) && !RemoveMineRockPiece(piece))
					{
						piece.DropResources();
						piece.m_placeEffect.Create(((Component)piece).transform.position, ((Component)piece).transform.rotation, ((Component)piece).gameObject.transform, 1f, -1);
						player.m_removeEffects.Create(((Component)piece).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
						ZNetScene.instance.Destroy(((Component)piece).gameObject);
					}
				}
				ItemData rightItem = ((Humanoid)player).GetRightItem();
				if (rightItem != null)
				{
					player.FaceLookDirection();
					((Character)player).m_zanim.SetTrigger(rightItem.m_shared.m_attack.m_attackAnimation);
				}
				return true;
			}
			return false;
		}

		private static bool Check_m_canBeRemoved(Piece piece)
		{
			if (InitManager.IsPrefabEnabled(((Component)piece).gameObject) && PieceCategoryHelper.IsCreativeModePiece(piece) && piece.IsPlacedByPlayer())
			{
				if (piece.IsCreator())
				{
					return true;
				}
				if (MorePrefabs.IsAdminDeconstructOtherPlayers && SynchronizationManager.Instance.PlayerIsAdmin)
				{
					return true;
				}
			}
			return piece.m_canBeRemoved;
		}

		private static bool RemoveDestructiblePiece(Piece piece)
		{
			Destructible val = default(Destructible);
			if (((Component)piece).gameObject.TryGetComponent<Destructible>(ref val))
			{
				Log.LogInfo("Removing destructible piece", LogLevel.Medium);
				if (!CreateHitEffects(val) && !SfxHelper.HasSfx(val.m_destroyedEffect))
				{
					SfxHelper.CreateRemovalSfx(piece);
				}
				val.DestroyNow();
				return true;
			}
			return false;
		}

		private static bool CreateHitEffects(Destructible destructible)
		{
			//IL_0036: 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.LogInfo("Creating hit effects", LogLevel.Medium);
			EffectData[] array = destructible.m_hitEffect?.m_effectPrefabs;
			if (array != null && array.Length != 0)
			{
				destructible.m_hitEffect.Create(((Component)destructible).gameObject.transform.position, ((Component)destructible).gameObject.transform.rotation, ((Component)destructible).gameObject.transform, 1f, -1);
				EffectData[] array2 = array;
				foreach (EffectData val in array2)
				{
					if (val != null && ((Object)val.m_prefab).name.StartsWith("sfx_"))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool RemoveMineRock5Piece(Piece piece)
		{
			MineRock5 mineRock = default(MineRock5);
			if (((Component)piece).gameObject.TryGetComponent<MineRock5>(ref mineRock))
			{
				Log.LogInfo("Removing MineRock5 piece", LogLevel.Medium);
				mineRock.DestroyMineRock5Piece();
				return true;
			}
			return false;
		}

		private static bool RemoveMineRockPiece(Piece piece)
		{
			MineRock mineRock = default(MineRock);
			if (((Component)piece).gameObject.TryGetComponent<MineRock>(ref mineRock))
			{
				Log.LogInfo("Removing MineRock5 piece", LogLevel.Medium);
				mineRock.DestroyMineRockPiece();
				return true;
			}
			return false;
		}
	}
}
namespace MVBP.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("MVBP.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static Bitmap texture_portal_MainTex => (Bitmap)ResourceManager.GetObject("texture_portal_MainTex", resourceCulture);

		internal static Bitmap texture_portal_n_BumpMap => (Bitmap)ResourceManager.GetObject("texture_portal_n_BumpMap", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace MVBP.Patches
{
	[HarmonyPatch(typeof(Destructible))]
	internal static class DestructiblePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Destroy")]
		private static bool DestroyPrefix(Destructible __instance)
		{
			if (InitManager.IsPatchedByMod(((Component)__instance).gameObject))
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? gameObject.GetComponent<Piece>() : null);
				}
				Piece val = (Piece)obj;
				if ((Object)(object)val != (Object)null && val.IsPlacedByPlayer())
				{
					val.DropResources();
					ZNetView nview = __instance.m_nview;
					if (!nview.IsValid() || !nview.IsOwner())
					{
						Log.LogInfo("Piece nview was destroyed during DropResources()", LogLevel.Medium);
						return false;
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Door))]
	internal static class DoorPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("RPC_UseDoor")]
		private static void UseDoorPrefix(Door __instance, out int? __state)
		{
			__state = GetDoorState(ref __instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("RPC_UseDoor")]
		private static void UseDoorPostfix(Door __instance, int? __state)
		{
			int? doorState = GetDoorState(ref __instance);
			ZNetView val = default(ZNetView);
			if (doorState.HasValue && __state.HasValue && InitManager.GetPrefabName((Component)(object)__instance) == "dvergrtown_secretdoor" && (__state == -1 || __state == 1) && doorState == 0 && ((Component)__instance).gameObject.TryGetComponent<ZNetView>(ref val) && (Object)(object)val != (Object)null && val.IsValid())
			{
				if (!val.IsOwner())
				{
					val.ClaimOwnership();
				}
				__instance.m_animator.Rebind();
				__instance.m_animator.Update(0f);
			}
		}

		private static int? GetDoorState(ref Door door)
		{
			if (door.m_nview.IsValid())
			{
				return door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0);
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(EffectList))]
	internal static class EffectListPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Create")]
		private static void CreatePrefix(ref EffectList __instance)
		{
			EffectData[] effectPrefabs = __instance.m_effectPrefabs;
			foreach (EffectData val in effectPrefabs)
			{
				if (val != null && val.m_enabled && !Object.op_Implicit((Object)(object)val.m_prefab))
				{
					val.m_enabled = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MineRock5))]
	internal static class MineRock5Patch
	{
		[HarmonyPostfix]
		[HarmonyPatch("AllDestroyed")]
		private static void AllDestroyedPostfix(MineRock5 __instance, ref bool __result)
		{
			Piece val = default(Piece);
			if (__result && Object.op_Implicit((Object)(object)__instance) && ((Component)__instance).TryGetComponent<Piece>(ref val))
			{
				val.DropResources();
			}
		}
	}
	[HarmonyPatch(typeof(MineRock))]
	internal static class MineRockPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateVisability")]
		private static bool UpdateVisabilityPrefix(MineRock __instance)
		{
			Log.LogInfo("MineRock.UpdateVisability patch applied", LogLevel.Medium);
			return (Object)(object)__instance.m_nview != (Object)null;
		}

		[HarmonyPostfix]
		[HarmonyPatch("AllDestroyed")]
		private static void AllDestroyed(MineRock __instance, ref bool __result)
		{
			Piece val = default(Piece);
			if (__result && Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).gameObject) && ((Component)__instance).gameObject.TryGetComponent<Piece>(ref val))
			{
				val.DropResources();
			}
		}
	}
	[HarmonyPatch(typeof(Pickable))]
	internal static class PickablePatch
	{
		private static readonly DropTable emptyDrops = new DropTable();

		[HarmonyPrefix]
		[HarmonyPatch("RPC_Pick")]
		private static void RPC_PickPrefix(Pickable __instance, out DropTable __state)
		{
			Piece val = default(Piece);
			if (InitManager.IsPatchedByMod((Component)(object)__instance) && ((Component)__instance).TryGetComponent<Piece>(ref val) && val.IsPlacedByPlayer())
			{
				__state = __instance.m_extraDrops;
				__instance.m_extraDrops = emptyDrops;
			}
			else
			{
				__state = null;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("RPC_Pick")]
		private static void RPC_PickPostfix(Pickable __instance, DropTable __state)
		{
			if (__state != null)
			{
				__instance.m_extraDrops = __state;
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld))]
	internal static class TeleportWorldPatch
	{
		private static string PrefabName;

		[HarmonyPrefix]
		[HarmonyPatch("UpdatePortal")]
		private static void UpdatePortalPrefix(TeleportWorld __instance)
		{
			PrefabName = InitManager.GetPrefabName((Component)(object)__instance);
		}

		[HarmonyTranspiler]
		[HarmonyPatch("UpdatePortal")]
		private static IEnumerable<CodeInstruction> UpdatePortalTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0037: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Humanoid), "IsTeleportable", (Type[])null, (Type[])null), (string)null)
			}).SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<Player, bool>>((Func<Player, bool>)IsTeleportable_Delegate)).InstructionEnumeration();
		}

		[HarmonyPrefix]
		[HarmonyPatch("Teleport")]
		private static void TeleportPrefix(TeleportWorld __instance)
		{
			PrefabName = InitManager.GetPrefabName((Component)(object)__instance);
		}

		[HarmonyTranspiler]
		[HarmonyPatch("Teleport")]
		private static IEnumerable<CodeInstruction> TeleportWorldTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: 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_0037: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Humanoid), "IsTeleportable", (Type[])null, (Type[])null), (string)null)
			}).SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<Player, bool>>((Func<Player, bool>)IsTeleportable_Delegate)).InstructionEnumeration();
		}

		private static bool IsTeleportable_Delegate(Player player)
		{
			if (MorePrefabs.IsEnablePortalPatch && !string.IsNullOrEmpty(PrefabName) && PrefabName == "portal")
			{
				PrefabName = null;
				return true;
			}
			PrefabName = null;
			return ((Humanoid)player).IsTeleportable();
		}
	}
	[HarmonyPatch(typeof(WearNTear))]
	internal static class WearNTearPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Destroy")]
		private static void DestroyPrefix(WearNTear __instance, out EffectList __state)
		{
			if (InitManager.IsPatchedByMod((Component)(object)__instance) && !SfxHelper.HasSfx(__instance.m_destroyedEffect))
			{
				__state = __instance.m_destroyedEffect;
				__instance.m_destroyedEffect = SfxHelper.FixRemovalSfx(__instance);
			}
			else
			{
				__state = null;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Destroy")]
		private static void DestroyPostfix(WearNTear __instance, EffectList __state)
		{
			if (__state != null)
			{
				__instance.m_destroyedEffect = __state;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet))]
	internal static class ZNetPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void ZNetStartPostfix()
		{
			//IL_000b: 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)
			Log.LogInfo("Checking world modifiers", LogLevel.Medium);
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "main" && Game.m_resourceRate != 1f)
			{
				Log.LogInfo("World modifiers for resource rate are active, re-initializing");
				Stopwatch stopwatch = new Stopwatch();
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Start();
				}
				InitManager.UpdatePieces();
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Stop();
					Log.LogInfo($"Time to re-initialize: {stopwatch.ElapsedMilliseconds} ms");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem))]
	internal static class ZoneSystemPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(600)]
		[HarmonyPatch("Start")]
		public static void ZoneSystemStartPrefix()
		{
			//IL_000b: 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)
			Log.LogInfo("ZoneSystemStartPrefix()", LogLevel.Medium);
			Scene activeScene = SceneManager.GetActiveScene();
			if (!(((Scene)(ref activeScene)).name != "main"))
			{
				Log.LogInfo("Performing mod initialization");
				Stopwatch stopwatch = new Stopwatch();
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Start();
				}
				InitManager.InitPlugin();
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Stop();
					Log.LogInfo($"Time to initialize: {stopwatch.ElapsedMilliseconds} ms");
				}
			}
		}
	}
}
namespace MVBP.Helpers
{
	internal static class CollisionHelper
	{
		internal static void AddBoxCollider(GameObject prefab, Vector3 center, Vector3 size)
		{
			//IL_0007: 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)
			BoxCollider obj = prefab.AddComponent<BoxCollider>();
			obj.center = center;
			obj.size = size;
		}

		internal static void PatchCollider(GameObject prefab)
		{
			//IL_0002: 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_0031: 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)
			Bounds val = default(Bounds);
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>();
			foreach (Renderer val2 in componentsInChildren)
			{
				((Bounds)(ref val)).Encapsulate(val2.bounds);
			}
			AddBoxCollider(prefab, ((Bounds)(ref val)).center, ((Bounds)(ref val)).size);
		}

		internal static void RemoveColliders(GameObject prefab)
		{
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
		}

		internal static Vector3 GetCenter(GameObject prefab)
		{
			//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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			List<Collider> allColliders = GetAllColliders(prefab);
			Vector3 val = Vector3.zero;
			foreach (Collider item in allColliders)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Vector3 val2 = val;
					Bounds bounds = item.bounds;
					val = val2 + ((Bounds)(ref bounds)).center;
				}
			}
			return val / (float)allColliders.Count;
		}

		internal static List<Collider> GetAllColliders(GameObject prefab)
		{
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>();
			List<Collider> list = new List<Collider>
			{
				Capacity = componentsInChildren.Length
			};
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if (val.enabled && ((Component)val).gameObject.activeInHierarchy && !val.isTrigger)
				{
					list.Add(val);
				}
			}
			return list;
		}
	}
	internal class IconHelper : MonoBehaviour
	{
		private static GameObject _gameObject;

		private static IconHelper _instance;

		internal static IconHelper Instance => CreateInstance();

		private static IconHelper CreateInstance()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if ((Object)(object)_gameObject == (Object)null)
			{
				_gameObject = new GameObject();
				Object.DontDestroyOnLoad((Object)(object)_gameObject);
			}
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = _gameObject.AddComponent<IconHelper>();
			}
			return _instance;
		}

		private IconHelper()
		{
		}

		public void GeneratePrefabIcons(IEnumerable<GameObject> prefabs)
		{
			((MonoBehaviour)this).StartCoroutine(RenderCoroutine(prefabs));
		}

		private IEnumerator RenderCoroutine(IEnumerable<GameObject> gameObjects)
		{
			foreach (GameObject gameObject in gameObjects)
			{
				if ((Object)(object)gameObject == (Object)null)
				{
					Log.LogWarning("Null prefab, cannot render icon");
					continue;
				}
				Piece piece = gameObject.GetComponent<Piece>();
				if ((Object)(object)piece == (Object)null)
				{
					Log.LogWarning("Null piece, cannot render icon");
					continue;
				}
				Sprite result = GenerateObjectIcon(gameObject);
				yield return (object)new WaitForEndOfFrame();
				if ((Object)(object)result == (Object)null)
				{
					RandomItem[] array = ((Component)piece).GetComponent<PickableItem>()?.m_randomItemPrefabs;
					if (array != null && array.Length != 0)
					{
						ItemDrop itemPrefab = array[0].m_itemPrefab;
						GameObject val = ((itemPrefab != null) ? ((Component)itemPrefab).gameObject : null);
						if ((Object)(object)val != (Object)null)
						{
							result = GenerateObjectIcon(val);
							yield return (object)new WaitForEndOfFrame();
						}
					}
				}
				piece.m_icon = result;
			}
			ModCompat.UpdatePlanBuild();
		}

		private static Sprite GenerateObjectIcon(GameObject obj)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			RenderRequest val = new RenderRequest(obj)
			{
				Rotation = RenderManager.IsometricRotation,
				UseCache = PrefabConfigs.ShouldCacheIcon(((Object)obj).name)
			};
			return RenderManager.Instance.Render(val);
		}
	}
	internal static class InitManager
	{
		internal static readonly Dictionary<string, GameObject> PrefabRefs = new Dictionary<string, GameObject>();

		internal static readonly Dictionary<string, Requirement[]> DefaultResources = new Dictionary<string, Requirement[]>();

		private static Dictionary<string, PieceDB> PieceRefs = new Dictionary<string, PieceDB>();

		private static readonly Dictionary<string, string> PieceToPrefabMap = new Dictionary<string, string>();

		internal static readonly Dictionary<string, GameObject> SeasonalPieceRefs = new Dictionary<string, GameObject>
		{
			{ "piece_maypole", null },
			{ "piece_jackoturnip", null },
			{ "piece_gift1", null },
			{ "piece_gift2", null },
			{ "piece_gift3", null },
			{ "piece_mistletoe", null },
			{ "piece_xmascrown", null },
			{ "piece_xmasgarland", null },
			{ "piece_xmastree", null }
		};

		internal static bool HasInitializedPlugin => PrefabRefs.Count > 0;

		internal static bool TryGetDefaultPieceResources(GameObject gameObject, out Requirement[] defaultResources)
		{
			string prefabName = GetPrefabName(gameObject);
			if (DefaultResources.ContainsKey(prefabName))
			{
				defaultResources = DefaultResources[prefabName];
				return true;
			}
			defaultResources = null;
			return false;
		}

		internal static bool TryGetPieceDB(string name, out PieceDB pieceDB)
		{
			if (!string.IsNullOrEmpty(name) && PieceRefs.TryGetValue(name, out pieceDB))
			{
				return true;
			}
			pieceDB = null;
			return false;
		}

		internal static bool TryGetPieceDB(GameObject gameObject, out PieceDB pieceDB)
		{
			return TryGetPieceDB(GetPrefabName(gameObject), out pieceDB);
		}

		internal static bool TryGetPieceDB(Piece piece, out PieceDB pieceDB)
		{
			return TryGetPieceDB(GetPrefabName((Component)(object)piece), out pieceDB);
		}

		internal static bool IsPatchedByMod(GameObject gameObject)
		{
			string prefabName = GetPrefabName(gameObject);
			return PrefabRefs.ContainsKey(prefabName);
		}

		internal static bool IsPatchedByMod(Component compo)
		{
			string prefabName = GetPrefabName(compo);
			return PrefabRefs.ContainsKey(prefabName);
		}

		internal static bool IsPatchedByMod(string name)
		{
			return PrefabRefs.ContainsKey(name);
		}

		internal static bool IsPrefabEnabled(GameObject gameObject)
		{
			string prefabName = GetPrefabName(gameObject);
			if (IsPatchedByMod(prefabName))
			{
				if (!MorePrefabs.IsPrefabConfigEnabled(prefabName))
				{
					return MorePrefabs.IsForceAllPrefabs;
				}
				return true;
			}
			return false;
		}

		internal static string GetPrefabName(Component compo)
		{
			return GetPrefabName((compo != null) ? compo.gameObject : null);
		}

		internal static string GetPrefabName(GameObject gameObject)
		{
			if (!Object.op_Implicit((Object)(object)gameObject))
			{
				return string.Empty;
			}
			string prefabName = gameObject.GetPrefabName();
			if (PrefabRefs.ContainsKey(prefabName))
			{
				return prefabName;
			}
			Piece val = default(Piece);
			if (gameObject.TryGetComponent<Piece>(ref val) && PieceToPrefabMap.ContainsKey(val.m_name))
			{
				return PieceToPrefabMap[val.m_name];
			}
			return prefabName;
		}

		private static void InitPrefabRefs()
		{
			if (PrefabRefs.Count > 0)
			{
				return;
			}
			Log.LogInfo("Initializing prefabs");
			InitSeasonalPieceRefs();
			HashSet<string> existingPieceNames = PieceHelper.GetExistingPieceNames();
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
			foreach (GameObject prefab2 in ZNetScene.instance.m_prefabs)
			{
				if (!Object.op_Implicit((Object)(object)prefab2.transform.parent) && !existingPieceNames.Contains(((Object)prefab2).name) && PrefabFilter.GetEligiblePrefab(prefab2, out var result) && !dictionary.ContainsKey(((Object)result).name))
				{
					dictionary.Add(((Object)result).name, result);
				}
			}
			foreach (GameObject value in dictionary.Values)
			{
				if (PieceHelper.EnsureNoDuplicateZNetView(value))
				{
					if (Log.IsVerbosityHigh)
					{
						Log.LogGameObject(value);
					}
					try
					{
						PrefabPatcher.PatchPrefabIfNeeded(value);
					}
					catch (Exception arg)
					{
						Log.LogWarning($"Failed to patch prefab {((Object)value).name}: {arg}");
					}
					PrefabRefs.Add(((Object)value).name, value);
					UpdateDefaultResources(value);
				}
			}
			Log.LogInfo($"Found {PrefabRefs.Count} prefabs");
			Log.LogInfo("Initializing default pieces");
			Sprite prefab = Cache.GetPrefab<Sprite>("mapicon_hildir1");
			foreach (GameObject value2 in PrefabRefs.Values)
			{
				Piece val = PieceHelper.InitPieceComponent(value2);
				if ((Object)(object)val.m_icon == (Object)null)
				{
					val.m_icon = prefab;
				}
			}
			Log.LogInfo("Initializing default icons", LogLevel.Medium);
			IconHelper.Instance.GeneratePrefabIcons(PrefabRefs.Values);
		}

		private static void UpdateDefaultResources(GameObject prefab)
		{
			Piece val = default(Piece);
			if (prefab.TryGetComponent<Piece>(ref val) && val.m_resources != null)
			{
				DefaultResources.Add(((Object)prefab).name, val.m_resources);
			}
			else
			{
				DefaultResources.Add(((Object)prefab).name, Array.Empty<Requirement>());
			}
		}

		private static void InitSeasonalPieceRefs()
		{
			List<string> list = SeasonalPieceRefs.Keys.ToList();
			List<string> list2 = new List<string>();
			Piece val = default(Piece);
			foreach (string item in list)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(item);
				if (Object.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent<Piece>(ref val))
				{
					if (!val.m_enabled)
					{
						SeasonalPieceRefs[item] = prefab;
						continue;
					}
					Log.LogInfo("Seasonal Piece: " + item + " already enabled", LogLevel.Medium);
					list2.Add(item);
				}
				else
				{
					Log.LogWarning("Seasonal piece: " + item + " could not be found");
				}
			}
			foreach (string item2 in list2)
			{
				SeasonalPieceRefs.Remove(item2);
			}
		}

		private static void InitPieces()
		{
			Log.LogInfo("Initializing piece refs");
			if (PieceRefs.Count > 0)
			{
				PieceTable pieceTable = PieceManager.Instance.GetPieceTable(PieceTables.Hammer);
				foreach (PieceDB value in PieceRefs.Values)
				{
					PieceHelper.RemovePieceFromPieceTable(value.Prefab, pieceTable);
					ForceUnequipHammer();
				}
				PieceRefs.Clear();
			}
			PieceRefs = GeneratePieceRefs();
			Log.LogInfo("Initializing pieces");
			foreach (PieceDB value2 in PieceRefs.Values)
			{
				Piece val = PieceHelper.ConfigurePiece(value2);
				SfxHelper.FixPlacementSfx(val);
				PieceToPrefabMap[val.m_name] = value2.name;
			}
		}

		private static void ForceUnequipHammer()
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).GetRightItem()?.m_shared.m_name == "$item_hammer")
			{
				Log.LogWarning("Hammer updated through config change, unequipping hammer");
				((Humanoid)Player.m_localPlayer).HideHandItems();
			}
		}

		private static Dictionary<string, PieceDB> GeneratePieceRefs()
		{
			Dictionary<string, PieceDB> dictionary = new Dictionary<string, PieceDB>();
			Piece piece = default(Piece);
			foreach (string key in PrefabRefs.Keys)
			{
				if (PrefabRefs.TryGetValue(key, out var value))
				{
					if (!Object.op_Implicit((Object)(object)value))
					{
						Log.LogWarning("Prefab: " + key + " has been destroyed");
					}
					else if (value.TryGetComponent<Piece>(ref piece))
					{
						dictionary.Add(((Object)value).name, new PieceDB(MorePrefabs.GetPrefabDB(value), piece));
					}
					else
					{
						Log.LogWarning("Prefab: " + key + " is missing piece component");
					}
				}
				else
				{
					Log.LogWarning("Could not find Prefab: " + key);
				}
			}
			return dictionary;
		}

		private static void InitHammer()
		{
			Log.LogInfo("Initializing hammer");
			SortedPieceGroups sortedPieceGroups = new SortedPieceGroups();
			foreach (PieceDB value in PieceRefs.Values)
			{
				if ((value.enabled || MorePrefabs.IsForceAllPrefabs) && (MorePrefabs.IsCreativeMode || !PieceCategoryHelper.IsCreativeModePiece(value.piece)) && (MorePrefabs.IsEnableHammerCrops || value.pieceGroup != PieceGroup.VanillaCrop) && (!MorePrefabs.IsCreatorShopAdminOnly || !PieceCategoryHelper.IsCreatorShopPiece(value.piece) || SynchronizationManager.Instance.PlayerIsAdmin))
				{
					sortedPieceGroups.Add(value);
				}
			}
			PieceTable pieceTable = PieceManager.Instance.GetPieceTable(PieceTables.Hammer);
			foreach (List<GameObject> item in sortedPieceGroups)
			{
				foreach (GameObject item2 in item)
				{
					PieceHelper.AddPieceToPieceTable(item2, pieceTable);
				}
			}
		}

		private static void InitSeasonalPieces()
		{
			if (!HasInitializedPlugin)
			{
				return;
			}
			Piece val = default(Piece);
			foreach (string key in SeasonalPieceRefs.Keys)
			{
				if (SeasonalPieceRefs.TryGetValue(key, out var value) && Object.op_Implicit((Object)(object)value))
				{
					if (value.TryGetComponent<Piece>(ref val))
					{
						val.m_enabled = MorePrefabs.IsEnableSeasonalPieces;
					}
				}
				else
				{
					Log.LogWarning("Seasonal piece: " + key + " could not be found");
				}
			}
		}

		internal static void InitPlugin()
		{
			if (!HasInitializedPlugin)
			{
				PieceCategoryHelper.AddCreatorShopPieceCategory();
				SfxHelper.Init();
				InitPrefabRefs();
				InitSeasonalPieces();
				InitPieces();
				InitHammer();
				ConfigManager.Save();
			}
		}

		internal static void UpdatePieces()
		{
			if (HasInitializedPlugin)
			{
				InitPieces();
				InitHammer();
			}
		}

		internal static void UpdatePlugin(string msg, bool saveConfig = true)
		{
			if (HasInitializedPlugin && (MorePrefabs.UpdatePieceSettings || MorePrefabs.UpdatePlacementSettings || MorePrefabs.UpdateSeasonalSettings))
			{
				Stopwatch stopwatch = new Stopwatch();
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Start();
				}
				Log.LogInfo(msg);
				if (MorePrefabs.UpdatePieceSettings)
				{
					UpdatePieces();
				}
				if (MorePrefabs.UpdateSeasonalSettings)
				{
					InitSeasonalPieces();
				}
				if (MorePrefabs.UpdatePlacementSettings)
				{
					ForceUnequipHammer();
				}
				if (Log.IsVerbosityMedium)
				{
					stopwatch.Stop();
					Log.LogInfo($"Time to re-initialize: {stopwatch.ElapsedMilliseconds} ms");
				}
				else
				{
					Log.LogInfo("Re-initializing complete");
				}
				if (MorePrefabs.UpdatePieceSettings)
				{
					ModCompat.UpdateExtraSnaps();
					ModCompat.UpdatePlanBuild();
				}
				MorePrefabs.UpdatePieceSettings = false;
				MorePrefabs.UpdatePlacementSettings = false;
				MorePrefabs.UpdateSeasonalSettings = false;
				if (saveConfig)
				{
					ConfigManager.Save();
				}
			}
		}
	}
	internal static class NameMaker
	{
		private static readonly Regex DigitsToEndRegex = new Regex("(.+?)((?<!x)\\d+(?![xm\\°]))(.*)");

		private static readonly Regex SplitCapitalsRegex = new Regex("([a-z])([A-Z])");

		private static readonly Regex CreepToEndRegex = new Regex("(.+?)(creep)(.*)");

		private static readonly Regex WhiteSpaceRegex = new Regex(" +");

		private static readonly Regex UnitSpaceRegex = new Regex("(\\d+)(m)");

		private static readonly Regex IsLastCharDigit = new Regex("((?<!x)\\d+$)");

		private static readonly Dictionary<string, string> NameCache = new Dictionary<string, string>();

		private static readonly Dictionary<string, string> DescCache = new Dictionary<string, string>();

		internal static bool IsNameCached(string name)
		{
			return NameCache.ContainsValue(name);
		}

		internal static void ClearNameCache()
		{
			NameCache.Clear();
		}

		internal static void ClearDescCache()
		{
			DescCache.Clear();
		}

		internal static string FormatPieceName(PieceDB pieceDB)
		{
			if (NameCache.ContainsKey(pieceDB.name))
			{
				return NameCache[pieceDB.name];
			}
			if (pieceDB.pieceName != null)
			{
				NameCache[pieceDB.name] = pieceDB.pieceName;
				return pieceDB.pieceName;
			}
			string s = pieceDB.name.RemoveSuffix("_frac");
			s = s.RemoveSuffix("_destruction");
			s = CreepToEndRegex.Replace(s, "$1$3 ($2)");
			s = DigitsToEndRegex.Replace(s, "$1$3 $2");
			s = UnitSpaceRegex.Replace(s, "$1 $2");
			s = SplitCapitalsRegex.Replace(s, "$1 $2");
			s = s.Replace('_', ' ').ToLower().Replace("dverger", "dvergr")
				.Replace("dvergrtown", "dvergr")
				.Replace("dvergrprops", "dvergr")
				.Replace("destructable", "destructible")
				.Replace("rockdolmen", "rock dolmen")
				.Replace("blackmarble", "black marble")
				.Replace("sunkencrypt", "sunken crypt")
				.Replace("irongate", "iron gate")
				.Replace("goblin", "fuling")
				.Replace("hugeroot", "ancient root")
				.Replace("stubbe", "stump")
				.Replace("stub", "stump")
				.Replace("swamptree", "Ancient tree")
				.Replace("swamp tree", "Ancient tree")
				.Replace("ygga", "yggdrasil ")
				.Replace("guardstone", "ward")
				.Replace("woodwall", "wood wall")
				.Trim();
			s = s.RemovePrefix("piece").TrimStart(Array.Empty<char>());
			s = s.RemovePrefix("dungeon").TrimStart(Array.Empty<char>());
			if (s.EndsWith("destructible"))
			{
				s = s.RemoveSuffix("destructible");
				s += " (destructible)";
			}
			if (s.StartsWith("pickable"))
			{
				s = s.RemovePrefix("pickable").TrimStart(Array.Empty<char>());
				s += " (pickable)";
			}
			if (s.StartsWithAny("mountainkit", "mountain kit"))
			{
				s = s.RemovePrefix("mountainkit");
				s = s.RemovePrefix("mountain kit").TrimStart(Array.Empty<char>());
				s += " (cave)";
			}
			if (s.StartsWithAny("sunkencrypt", "sunken crypt"))
			{
				s = s.RemovePrefix("sunkencrypt");
				s = s.RemovePrefix("sunken crypt").TrimStart(Array.Empty<char>());
				s += " (crypt)";
			}
			if (s.StartsWithAny("forestcrypt", "forest crypt"))
			{
				s = s.RemovePrefix("forestcrypt");
				s = s.RemovePrefix("forest crypt").TrimStart(Array.Empty<char>());
				s += " (tomb)";
			}
			s = IsLastCharDigit.Replace(s, " ($1)");
			s = WhiteSpaceRegex.Replace(s, " ");
			s = s.CapitalizeFirstLetter();
			NameCache[pieceDB.name] = s;
			return s;
		}

		internal static string GetPieceDescription(PieceDB pieceDB)
		{
			if (DescCache.ContainsKey(pieceDB.name))
			{
				return DescCache[pieceDB.name];
			}
			if (pieceDB.pieceDesc != null)
			{
				DescCache[pieceDB.name] = pieceDB.pieceDesc;
				return pieceDB.pieceDesc;
			}
			pieceDB.pieceDesc = FindPieceDescription(pieceDB.Prefab);
			DescCache[pieceDB.name] = pieceDB.pieceDesc;
			return pieceDB.pieceDesc;
		}

		private static string FindPieceDescription(GameObject prefab)
		{
			HoverText component = prefab.GetComponent<HoverText>();
			if (Object.op_Implicit((Object)(object)component) && !string.IsNullOrEmpty(component.m_text))
			{
				DescCache[((Object)prefab).name] = component.m_text;
				return component.m_text;
			}
			ItemDrop component2 = prefab.GetComponent<ItemDrop>();
			if (Object.op_Implicit((Object)(object)component2) && !string.IsNullOrEmpty(component2.m_itemData.m_shared.m_name))
			{
				DescCache[((Object)prefab).name] = component2.m_itemData.m_shared.m_name;
				return component2.m_itemData.m_shared.m_name;
			}
			Character component3 = prefab.GetComponent<Character>();
			if (Object.op_Implicit((Object)(object)component3) && !string.IsNullOrEmpty(component3.m_name))
			{
				DescCache[((Object)prefab).name] = component3.m_name;
				return component3.m_name;
			}
			RuneStone component4 = prefab.GetComponent<RuneStone>();
			if (Object.op_Implicit((Object)(object)component4) && !string.IsNullOrEmpty(component4.m_name))
			{
				DescCache[((Object)prefab).name] = component4.m_name;
				return component4.m_name;
			}
			ItemStand component5 = prefab.GetComponent<ItemStand>();
			if (Object.op_Implicit((Object)(object)component5) && !string.IsNullOrEmpty(component5.m_name))
			{
				DescCache[((Object)prefab).name] = component5.m_name;
				return component5.m_name;
			}
			MineRock component6 = prefab.GetComponent<MineRock>();
			if (Object.op_Implicit((Object)(object)component6) && !string.IsNullOrEmpty(component6.m_name))
			{
				DescCache[((Object)prefab).name] = component6.m_name;
				return component6.m_name;
			}
			Pickable component7 = prefab.GetComponent<Pickable>();
			if (Object.op_Implicit((Object)(object)component7))
			{
				return FindPieceDescription(component7.m_itemPrefab);
			}
			CreatureSpawner component8 = prefab.GetComponent<CreatureSpawner>();
			if (Object.op_Implicit((Object)(object)component8))
			{
				return FindPieceDescription(component8.m_creaturePrefab);
			}
			SpawnArea component9 = prefab.GetComponent<SpawnArea>();
			if (Object.op_Implicit((Object)(object)component9) && component9.m_prefabs.Count > 0)
			{
				return FindPieceDescription(component9.m_prefabs[0].m_prefab);
			}
			return "";
		}
	}
	internal static class PieceCategoryHelper
	{
		private static PieceCategory Nature;

		private static PieceCategory CreatorShop;

		internal static void AddCreatorShopPieceCategory()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!PieceManager.Instance.GetPieceCategory("Nature").HasValue || !PieceManager.Instance.GetPieceCategory("CreatorShop").HasValue)
			{
				Log.LogInfo("Adding custom piece categories", LogLevel.Medium);
				Nature = PieceManager.Instance.AddPieceCategory(PieceTables.Hammer, "Nature");
				CreatorShop = PieceManager.Instance.AddPieceCategory(PieceTables.Hammer, "CreatorShop");
			}
		}

		internal static void RemoveCreatorShopPieceCategory()
		{
			Log.LogInfo("Removing custom piece categories", LogLevel.Medium);
			PieceManager.Instance.RemovePieceCategory(PieceTables.Hammer, "CreatorShop");
		}

		internal static bool IsCreativeModePiece(Piece piece)
		{
			if (!IsCreatorShopPiece(piece))
			{
				return IsNaturePiece(piece);
			}
			return true;
		}

		internal static bool IsCreatorShopPiece(Piece piece)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (InitManager.IsPatchedByMod((Component)(object)piece) && piece.m_category == CreatorShop)
			{
				return true;
			}
			return false;
		}

		internal static bool IsNaturePiece(Piece piece)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (InitManager.IsPatchedByMod((Component)(object)piece) && piece.m_category == Nature)
			{
				return true;
			}
			return false;
		}
	}
	internal class SortedPieceGroups : IEnumerable
	{
		private class SortedPieceGroupsEnumerator : IEnumerator
		{
			private int position = -1;

			private readonly Dictionary<PieceGroup, List<GameObject>> pieceGroupLists;

			public object Current
			{
				get
				{
					try
					{
						return pieceGroupLists[PieceGroupOrder[position]];
					}
					catch (IndexOutOfRangeException)
					{
						throw new InvalidOperationException();
					}
				}
			}

			public SortedPieceGroupsEnumerator(Dictionary<PieceGroup, List<GameObject>> pieceGroupLists)
			{
				this.pieceGroupLists = pieceGroupLists;
			}

			public bool MoveNext()
			{
				position++;
				return position < PieceGroupOrder.Count;
			}

			public void Reset()
			{
				position = -1;
			}
		}

		private readonly Dictionary<PieceGroup, List<GameObject>> pieceGroupLists;

		private static readonly List<PieceGroup> _pieceGroupOrder = new List<PieceGroup>();

		private static List<PieceGroup> PieceGroupOrder => GetPieceGroupOrder();

		private static List<PieceGroup> GetPieceGroupOrder()
		{
			if (_pieceGroupOrder.Count > 0)
			{
				return _pieceGroupOrder;
			}
			foreach (PieceGroup value in Enum.GetValues(typeof(PieceGroup)))
			{
				if (value != 0)
				{
					_pieceGroupOrder.Add(value);
				}
			}
			return _pieceGroupOrder;
		}

		public SortedPieceGroups()
		{
			pieceGroupLists = new Dictionary<PieceGroup, List<GameObject>>();
			foreach (PieceGroup item in PieceGroupOrder)
			{
				pieceGroupLists[item] = new List<GameObject>();
			}
		}

		public void Add(PieceDB pieceDB)
		{
			PieceGroup pieceGroup = PieceClassifier.GetPieceGroup(pieceDB);
			pieceGroupLists[pieceGroup].Add(pieceDB.Prefab);
		}

		public IEnumerator GetEnumerator()
		{
			return new SortedPieceGroupsEnumerator(pieceGroupLists);
		}
	}
	internal class PieceClassifier
	{
		private static readonly Dictionary<string, PieceGroup> Cache = new Dictionary<string, PieceGroup>();

		internal static PieceGroup GetPieceGroup(PieceDB pieceDB)
		{
			if (Cache.ContainsKey(pieceDB.name))
			{
				return Cache[pieceDB.name];
			}
			if (pieceDB.pieceGroup != 0)
			{
				Cache[pieceDB.name] = pieceDB.pieceGroup;
				return pieceDB.pieceGroup;
			}
			PieceGroup pieceGroup = DetectPieceGroup(pieceDB.Prefab);
			Cache[pieceDB.name] = pieceGroup;
			return pieceGroup;
		}

		internal static PieceGroup GetPieceGroup(GameObject prefab)
		{
			if (Cache.ContainsKey(((Object)prefab).name))
			{
				return Cache[((Object)prefab).name];
			}
			PieceGroup pieceGroup = DetectPieceGroup(prefab);
			Cache[((Object)prefab).name] = pieceGroup;
			return pieceGroup;
		}

		private static PieceGroup DetectPieceGroup(GameObject prefab)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Invalid comparison between Unknown and I4
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Invalid comparison between Unknown and I4
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Invalid comparison between Unknown and I4
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Invalid comparison between Unknown and I4
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Invalid comparison between Unknown and I4
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Invalid comparison between Unknown and I4
			string text = ((Object)prefab).name.ToLower();
			Piece component = prefab.GetComponent<Piece>();
			Destructible component2 = prefab.GetComponent<Destructible>();
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<PrivateArea>()))
			{
				return PieceGroup.Ward;
			}
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<Ship>()))
			{
				return PieceGroup.Ship;
			}
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<Vagon>()))
			{
				return PieceGroup.Cart;
			}
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<TeleportWorld>()))
			{
				return PieceGroup.Portal;
			}
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<Bed>()) || text.Contains("bed"))
			{
				return PieceGroup.Bed;
			}
			if (prefab.HasAnyComponent("CreatureSpawner", "SpawnArea", "TriggerSpawner"))
			{
				return PieceGroup.Spawner;
			}
			if (prefab.HasAnyComponent("CraftingStation", "StationExtension", "CookingStation", "Smelter", "WispSpawner"))
			{
				return PieceGroup.Crafting;
			}
			if (text.Contains("chest") && Object.op_Implicit((Object)(object)prefab.GetComponent<Container>()))
			{
				return PieceGroup.Chest;
			}
			if ((component != null && (int)component.m_comfortGroup == 1) || (Object)(object)prefab.transform.FindDeepChild("FireWarmth", (IterativeSearchType)1) != (Object)null || Object.op_Implicit((Object)(object)prefab.GetComponentInChildren<Demister>(true)))
			{
				if (text.Contains("brazier"))
				{
					return PieceGroup.Brazier;
				}
				if (text.ContainsAny("torch", "demister"))
				{
					return PieceGroup.Torch;
				}
				if (text.Contains("fire") || Object.op_Implicit((Object)(object)prefab.GetComponent<Fireplace>()))
				{
					return PieceGroup.Fire;
				}
			}
			if (text.Contains("armorstand") || Object.op_Implicit((Object)(object)prefab.GetComponent<ArmorStand>()))
			{
				return PieceGroup.ArmorStand;
			}
			if (text.EndsWith("pile") || text.EndsWith("stack"))
			{
				return PieceGroup.Stack;
			}
			if (text.ContainsAny("iron", "rusty") && !Object.op_Implicit((Object)(object)prefab.GetComponent<CookingStation>()))
			{
				return PieceGroup.Iron;
			}
			if (text.ContainsAny("dvergr", "dverger"))
			{
				return PieceGroup.Dvergr;
			}
			if (prefab.HasAnyComponent(typeof(WearNTear), typeof(Door)))
			{
				if (text.Contains("darkwood"))
				{
					return PieceGroup.Darkwood;
				}
				if (text.ContainsAny("wood", "turf"))
				{
					return PieceGroup.Wood;
				}
				if (text.Contains("stone"))
				{
					return PieceGroup.Stone;
				}
			}
			if ((Object.op_Implicit((Object)(object)prefab.GetComponent<Chair>()) || text.ContainsAny("chair", "throne", "bench", "stool") || (int)component.m_comfortGroup == 4) && !prefab.HasAnyComponent("CraftingStation", "StationExtension", "Barber"))
			{
				return PieceGroup.Chair;
			}
			if ((component != null && (int)component.m_comfortGroup == 3) || text.ContainsAny("banner", "curtain", "drape", "cloth_hanging"))
			{
				return PieceGroup.Banner;
			}
			if (text.ContainsAny("minerock") || Object.op_Implicit((Object)(object)prefab.GetComponent<MineRock>()))
			{
				return PieceGroup.Ore;
			}
			if ((component != null && (int)component.m_comfortGroup == 5) || (text.Contains("table") && !prefab.HasAnyComponent("CraftingStation", "StationExtension", "MapTable")))
			{
				return PieceGroup.Table;
			}
			if (text.ContainsAny("onion", "carrot", "turnip", "mushroom", "barley", "flax", "berry", "thistle", "dandelion") && Object.op_Implicit((Object)(object)prefab.GetComponent<Pickable>()))
			{
				return PieceGroup.Plant;
			}
			if ((component != null && (int)component.m_comfortGroup == 6) || text.ContainsAny("rug", "carpet"))
			{
				return PieceGroup.Rug;
			}
			if (text.ContainsAny("bush", "root", "shrub", "stubbe", "vines", "tree") || prefab.HasAnyComponent("TreeBase", "TreeLog") || (component2 != null && (int)component2.m_destructibleType == 2))
			{
				return PieceGroup.Flora;
			}
			if (text.Contains("ice"))
			{
				return PieceGroup.Ice;
			}
			if (text.ContainsAny("rock", "cliff"))
			{
				return PieceGroup.Rock;
			}
			if (text.Contains("blackmarble"))
			{
				return PieceGroup.BlackMarble;
			}
			if (text.Contains("goblin"))
			{
				return PieceGroup.Goblin;
			}
			if (text.Contains("statue"))
			{
				return PieceGroup.Statue;
			}
			return PieceGroup.Misc;
		}
	}
	internal static class PieceHelper
	{
		internal static readonly HashSet<string> AddedPrefabs = new HashSet<string>();

		private static readonly HashSet<string> AddedPieceComponent = new HashSet<string>();

		internal static CraftingStation GetCraftingStation(string name)
		{
			string internalName = CraftingStations.GetInternalName(name);
			ZNetScene instance = ZNetScene.instance;
			if (instance == null)
			{
				return null;
			}
			GameObject prefab = instance.GetPrefab(internalName);
			if (prefab == null)
			{
				return null;
			}
			return prefab.GetComponent<CraftingStation>();
		}

		internal static IEnumerable<PieceTable> GetPieceTables()
		{
			return Resources.FindObjectsOfTypeAll<PieceTable>();
		}

		internal static HashSet<string> GetExistingPieceNames()
		{
			return new HashSet<string>(from piece in GetPieceTables().SelectMany((PieceTable pieceTable) => pieceTable.m_pieces)
				select ((Object)piece).name);
		}

		internal static bool EnsureNoDuplicateZNetView(GameObject prefab)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return false;
			}
			ZNetView[] components = prefab.GetComponents<ZNetView>();
			if (components == null)
			{
				return true;
			}
			for (int i = 1; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			return components.Length <= 1;
		}

		internal static Piece InitPieceComponent(GameObject prefab)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			Piece val = prefab.GetComponent<Piece>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = prefab.AddComponent<Piece>();
				((Behaviour)val).enabled = false;
				val.m_enabled = false;
				val.m_name = ((Object)prefab).name;
				val.m_groundOnly = false;
				val.m_groundPiece = false;
				val.m_cultivatedGroundOnly = false;
				val.m_waterPiece = false;
				val.m_noInWater = false;
				val.m_notOnWood = false;
				val.m_notOnTiltingSurface = false;
				val.m_inCeilingOnly = false;
				val.m_notOnFloor = false;
				val.m_onlyInTeleportArea = false;
				val.m_allowedInDungeons = false;
				val.m_clipEverything = false;
				val.m_clipGround = false;
				val.m_allowRotatedOverlap = true;
				val.m_repairPiece = false;
				val.m_onlyInBiome = (Biome)0;
				((StaticTarget)val).m_randomTarget = false;
				val.m_canBeRemoved = false;
				AddedPieceComponent.Add(((Object)prefab).name);
				Log.LogInfo("Created Piece component for: " + ((Object)prefab).name, LogLevel.High);
			}
			return val;
		}

		internal static Piece ConfigurePiece(PieceDB pieceDB)
		{
			//IL_0029: 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_008f: 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)
			Piece piece = pieceDB.piece;
			string name = NameMaker.FormatPieceName(pieceDB);
			string pieceDescription = NameMaker.GetPieceDescription(pieceDB);
			PieceCategory value = PieceManager.Instance.GetPieceCategory(pieceDB.category).Value;
			if (AddedPieceComponent.Contains(pieceDB.name))
			{
				((Behaviour)piece).enabled = pieceDB.enabled || MorePrefabs.IsForceAllPrefabs;
				piece.m_enabled = pieceDB.enabled;
				pieceDB.piece.m_canBeRemoved = pieceDB.enabled;
			}
			piece.m_name = name;
			piece.m_description = pieceDescription;
			piece.m_allowedInDungeons = pieceDB.allowedInDungeons;
			piece.m_category = value;
			piece.m_craftingStation = GetCraftingStation(pieceDB.craftingStation);
			piece.m_resources = ConfigurePieceRequirements(pieceDB);
			piece.m_clipEverything = pieceDB.clipEverything;
			piece.m_clipGround = pieceDB.clipGround;
			if (PieceCategoryHelper.IsCreativeModePiece(pieceDB.piece) || Object.op_Implicit((Object)(object)pieceDB.Prefab.GetComponent<Ship>()) || Object.op_Implicit((Object)(object)pieceDB.Prefab.GetComponent<Vagon>()))
			{
				pieceDB.piece.m_canBeRemoved = false;
			}
			return piece;
		}

		private static Requirement[] ConfigurePieceRequirements(PieceDB pieceDB)
		{
			Requirement[] array = RequirementsHelper.CreateRequirementsArray(pieceDB.requirements);
			MineRock mineRock = default(MineRock);
			if (((Component)pieceDB.piece).TryGetComponent<MineRock>(ref mineRock))
			{
				array = RequirementsHelper.AddMineRockDropsToRequirements(array, mineRock);
			}
			MineRock5 mineRock2 = default(MineRock5);
			if (((Component)pieceDB.piece).TryGetComponent<MineRock5>(ref mineRock2))
			{
				array = RequirementsHelper.AddMineRock5DropsToRequirements(array, mineRock2);
			}
			Pickable pickable = default(Pickable);
			if (((Component)pieceDB.piece).TryGetComponent<Pickable>(ref pickable))
			{
				array = RequirementsHelper.AddPickableToRequirements(array, pickable);
			}
			return array;
		}

		internal static void AddPiecesListToPieceTable(IEnumerable<Piece> pieces, string pieceTableName)
		{
			PieceTable pieceTable = PieceManager.Instance.GetPieceTable(pieceTableName);
			foreach (Piece piece in pieces)
			{
				AddPieceToPieceTable(piece, pieceTable);
			}
			Log.LogInfo($"Added {AddedPrefabs.Count} custom pieces");
		}

		internal static bool AddPieceToPieceTable(GameObject prefab, PieceTable pieceTable)
		{
			return AddPieceToPieceTable(prefab.GetComponent<Piece>() ?? throw new Exception("Prefab " + ((Object)prefab).name + " has no Piece component."), pieceTable);
		}

		internal static bool AddPieceToPieceTable(Piece piece, PieceTable pieceTable)
		{
			if (!Object.op_Implicit((Object)(object)piece) || !Object.op_Implicit((Object)(object)pieceTable) || pieceTable.m_pieces == null || pieceTable.m_pieces.Contains(((Component)piece).gameObject))
			{
				return false;
			}
			GameObject gameObject = ((Component)piece).gameObject;
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)gameObject).name);
			if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !ZNetScene.instance.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				RegisterToZNetScene(gameObject);
			}
			pieceTable.m_pieces.Add(gameObject);
			AddedPrefabs.Add(((Object)gameObject).name);
			Log.LogInfo("Added Piece " + piece.m_name + " to PieceTable " + ((Object)pieceTable).name, LogLevel.High);
			return true;
		}

		internal static void RegisterToZNetScene(GameObject gameObject)
		{
			ZNetScene instance = ZNetScene.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			string name = ((Object)gameObject).name;
			int stableHashCode = StringExtensionMethods.GetStableHashCode(name);
			if (instance.m_namedPrefabs.ContainsKey(stableHashCode))
			{
				Log.LogDebug("Prefab " + name + " already in ZNetScene");
				return;
			}
			if ((Object)(object)gameObject.GetComponent<ZNetView>() != (Object)null)
			{
				instance.m_prefabs.Add(gameObject);
			}
			else
			{
				instance.m_nonNetViewPrefabs.Add(gameObject);
			}
			instance.m_namedPrefabs.Add(stableHashCode, gameObject);
			Log.LogDebug("Added prefab " + name);
		}

		internal static void RemoveAllCustomPiecesFromPieceTable(string pieceTableName)
		{
			Log.LogInfo("RemoveAllCustomPiecesFromPieceTable()", LogLevel.Medium);
			int count = AddedPrefabs.Count;
			List<string> list = AddedPrefabs.ToList();
			PieceTable pieceTable = PieceManager.Instance.GetPieceTable(pieceTableName);
			if ((Object)(object)pieceTable == (Object)null)
			{
				Log.LogError("Could not find piece table: " + pieceTableName);
			}
			foreach (string item in list)
			{
				RemovePieceFromPieceTable(item, pieceTable);
			}
			Log.LogInfo($"Removed {count - AddedPrefabs.Count} custom pieces", LogLevel.Medium);
		}

		internal static bool RemovePieceFromPieceTable(string name, PieceTable pieceTable)
		{
			try
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(name);
				if (pieceTable.m_pieces.Contains(prefab))
				{
					pieceTable.m_pieces.Remove(prefab);
					AddedPrefabs.Remove(((Object)prefab).name);
					return true;
				}
				return false;
			}
			catch (Exception arg)
			{
				Log.LogInfo($"{name}: {arg}");
				return false;
			}
		}

		internal static bool RemovePieceFromPieceTable(GameObject prefab, PieceTable pieceTable)
		{
			try
			{
				if (pieceTable.m_pieces.Contains(prefab))
				{
					pieceTable.m_pieces.Remove(prefab);
					AddedPrefabs.Remove(((Object)prefab).name);
					return true;
				}
				return false;
			}
			catch (Exception arg)
			{
				Log.LogInfo($"{((Object)prefab).name}: {arg}", LogLevel.Medium);
				return false;
			}
		}
	}
	internal static class PrefabFilter
	{
		private static HashSet<string> IgnorePlantEverything = new HashSet<string> { "Pickable_Branch", "Pickable_Flint", "Pickable_Stone" };

		private static readonly HashSet<string> _IgnoredPrefabs = new HashSet<string>
		{
			"Player", "Valkyrie", "HelmetOdin", "CapeOdin", "CastleKit_pot03", "Ravens", "TERRAIN_TEST", "PlaceMarker", "Circle_section", "guard_stone_test",
			"odin", "dvergrprops_wood_stake", "Flies", "Pickable_DvergerThing", "demister_ball", "CargoCrate", "SunkenKit_int_towerwall_LOD", "fuling_turret", "dragoneggcup", "FishingRodFloat",
			"Pickable_RandomFood", "horizontal_web", "tolroko_flyer", "turf_roof_wall", "IceBlocker", "Pickable_Item", "Pickable_Barley_Wild", "Pickable_Flax_Wild", "Pickable_DolmenTreasure", "fenrirhide_hanging_door",
			"TreasureChest_blackforest", "TreasureChest_heath", "TreasureChest_heath_hildir", "TreasureChest_heath_hildir", "TreasureChest_meadows", "TreasureChest_meadows_buried", "TreasureChest_mountains", "TreasureChest_swamp", "shipwreck_karve_chest", "loot_chest_wood",
			"TreasureChest_forestcrypt", "stonechest", "TreasureChest_plains_stone", "TreasureChest_mountaincave_hildir", "TreasureChest_plainsfortress_hildir", "TreasureChest_forestcrypt_hildir", "CastleKit_brazier", "CastleKit_groundtorch_unlit", "CastleKit_metal_groundtorch_unlit", "dvergrprops_lantern"
		};

		internal static bool GetEligiblePrefab(GameObject prefab, out GameObject result)
		{
			if (ShouldIgnorePrefab(prefab))
			{
				result = null;
				return false;
			}
			if (ModCompat.IsPlantEverythingInstalled() && IgnorePlantEverything.Contains(((Object)prefab).name))
			{
				result = null;
				return false;
			}
			Destructible val = default(Destructible);
			if (prefab.TryGetComponent<Destructible>(ref val))
			{
				if (PrefabConfigs.DefaultConfigValues.TryGetValue(((Object)prefab).name, out var value) && !string.IsNullOrEmpty(value.spawnOnDestroyed))
				{
					result = prefab;
					return true;
				}
				if (Object.op_Implicit((Object)(object)val.m_spawnWhenDestroyed) && (Object)(object)val.m_spawnWhenDestroyed.transform.parent == (Object)null && Object.op_Implicit((Object)(object)val.m_spawnWhenDestroyed.GetComponent<MineRock5>()))
				{
					result = val.m_spawnWhenDestroyed;
					return true;
				}
			}
			result = prefab;
			return true;
		}

		private static bool ShouldIgnorePrefab(GameObject prefab)
		{
			if (_IgnoredPrefabs.Contains(((Object)prefab).name))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)prefab.GetComponent<Projectile>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Humanoid>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<AnimalAI>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Character>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<CreatureSpawner>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<SpawnArea>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Fish>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<RandomFlyingBird>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<MusicLocation>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Aoe>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<ItemDrop>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<DungeonGenerator>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<TerrainModifier>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<EventZone>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<LocationProxy>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<LootSpawner>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Mister>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Ragdoll>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<MineRock5>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<TombStone>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<LiquidVolume>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Gibber>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<TimedDestruction>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<ShipConstructor>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<TriggerSpawner>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<TeleportAbility>()) || Object.op_Implicit((Object)(object)prefab.GetComponent<Trader>()) || ((Object)prefab).name.StartsWith("_") || ((Object)prefab).name.StartsWith("OLD_") || ((Object)prefab).name.EndsWith("OLD") || ((Object)prefab).name.EndsWith("_old") || ((Object)prefab).name.StartsWith("vfx_") || ((Object)prefab).name.StartsWith("sfx_") || ((Object)prefab).name.StartsWith("fx_") || ((Object)prefab).name.Contains("Random") || ((Object)prefab).name.Contains("random") || ((Object)prefab).name.EndsWith("_test"))
			{
				return true;
			}
			if (((Object)prefab).name.StartsWith("BBH_") || ((Object)prefab).name.StartsWith("rrr_") || ((Object)prefab).name.StartsWith("CLLC_"))
			{
				return true;
			}
			return false;
		}
	}
	internal static class PrefabPatcher
	{
		private static readonly int PieceLayer = LayerMask.NameToLayer("piece");

		private static readonly int CharacterTriggerLayer = LayerMask.NameToLayer("character_trigger");

		internal static void PatchPrefabIfNeeded(GameObject prefab)
		{
			//IL_2ae4: Unknown result type (might be due to invalid IL or missing references)
			//IL_2ae9: Unknown result type (might be due to invalid IL or missing references)
			//IL_2474: Unknown result type (might be due to invalid IL or missing references)
			//IL_2479: Unknown result type (might be due to invalid IL or missing references)
			//IL_248f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2494: Unknown result type (might be due to invalid IL or missing references)
			//IL_24aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_24af: Unknown result type (might be due to invalid IL or missing references)
			//IL_24c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_24ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_24e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_24e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_24fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_2500: Unknown result type (might be due to invalid IL or missing references)
			//IL_2516: Unknown result type (might be due to invalid IL or missing references)
			//IL_251b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2531: Unknown result type (might be due to invalid IL or missing references)
			//IL_2536: Unknown result type (might be due to invalid IL or missing references)
			//IL_28d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_28da: Unknown result type (might be due to invalid IL or missing references)
			//IL_28f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_28f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_290b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2910: Unknown result type (might be due to invalid IL or missing references)
			//IL_2926: Unknown result type (might be due to invalid IL or missing references)
			//IL_292b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2941: Unknown result type (might be due to invalid IL or missing references)
			//IL_2946: Unknown result type (might be due to invalid IL or missing references)
			//IL_25a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_25ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_25c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_25c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_25de: Unknown result type (might be due to invalid IL or missing references)
			//IL_25e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_25f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_25fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_2614: Unknown result type (might be due to invalid IL or missing references)
			//IL_2619: Unknown result type (might be due to invalid IL or missing references)
			//IL_255f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2564: Unknown result type (might be due to invalid IL or missing references)
			//IL_257a: Unknown result type (might be due to invalid IL or missing references)
			//IL_257f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1bf4: Unknown result type (might be due to invalid IL or missing references)
			//IL_1bf9: Unknown result type (might be due to invalid IL or missing references)
			//IL_1c0f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1c14: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ec3: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ec8: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ede: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ee3: Unknown result type (might be due to invalid IL or missing references)
			//IL_1ef9: Unknown result type (might be due to invalid IL or missing references)
			//IL_1efe: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f14: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f19: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f2f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f34: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f4a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f65: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f6a: Unknown result type (might be due to invalid IL or missing references)
			//IL_296d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2981: Unknown result type (might be due to invalid IL or missing references)
			//IL_298c: Unknown result type (might be due to invalid IL or missing references)
			//IL_29a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_29c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_29c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_29dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_29e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_2732: Unknown result type (might be due to invalid IL or missing references)
			//IL_2737: Unknown result type (might be due to invalid IL or missing references)
			//IL_274d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2752: Unknown result type (might be due to invalid IL or missing references)
			//IL_2768: Unknown result type (might be due to invalid IL or missing references)
			//IL_276d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2783: Unknown result type (might be due to invalid IL or missing references)
			//IL_2788: Unknown result type (might be due to invalid IL or missing references)
			//IL_279e: Unknown result type (might be due to invalid IL or missing references)
			//IL_27a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_27b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_27be: Unknown result type (might be due to invalid IL or missing references)
			//IL_27d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_27d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_27ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_27f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_280a: Unknown result type (might be due to invalid