Decompiled source of More Vanilla Build Prefabs v1.3.5

MoreVanillaBuildPrefabs.dll

Decompiled 2 days 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.Models;
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.3.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.5.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 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)
		{
			if (!Object.op_Implicit((Object)(object)compo))
			{
				return string.Empty;
			}
			return GetPrefabName(compo.gameObject);
		}

		internal static string GetPrefabName(GameObject gameObject, Piece piece = null)
		{
			if (!Object.op_Implicit((Object)(object)gameObject))
			{
				return string.Empty;
			}
			string prefabName = gameObject.GetPrefabName();
			if (PrefabRefs.ContainsKey(prefabName))
			{
				return prefabName;
			}
			if (piece == null)
			{
				piece = gameObject.GetComponent<Piece>();
			}
			if (Object.op_Implicit((Object)(object)piece) && PieceToPrefabMap.ContainsKey(piece.m_name))
			{
				return PieceToPrefabMap[piece.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)
			{
				Log.LogInfo("Configuring: " + value2.name, LogLevel.High);
				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(false, true);
			}
		}

		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 || MorePrefabs.UpdateModSettings))
			{
				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 || MorePrefabs.UpdateSeasonalSettings)
				{
					ModCompat.UpdateExtraSnaps();
					ModCompat.UpdatePlanBuild();
				}
				MorePrefabs.UpdatePieceSettings = false;
				MorePrefabs.UpdatePlacementSettings = false;
				MorePrefabs.UpdateSeasonalSettings = false;
				MorePrefabs.UpdateModSettings = false;
				if (saveConfig)
				{
					ConfigManager.Save();
				}
			}
		}
	}
	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.3.5")]
	[BepInDependency("com.jotunn.jotunn", "2.22.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*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.3.5";

		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, PrefabDBConfigEntries> PrefabDBConfigsMap = new Dictionary<string, PrefabDBConfigEntries>();

		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.OnConfigFileReloaded += delegate
			{
				InitManager.UpdatePlugin("Configuration file changed, re-initializing", saveConfig: false);
			};
			SynchronizationManager.OnConfigurationWindowClosed += 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 PrefabDBConfigEntries BindNewPrefabDBConfig(GameObject prefab)
		{
			PrefabDBConfigEntries prefabDBConfigEntries = new PrefabDBConfigEntries(PrefabDefaults.GetDefaultPrefabDB(((Object)prefab).name));
			prefabDBConfigEntries.enabled.SettingChanged += PieceSettingChanged;
			prefabDBConfigEntries.allowedInDungeons.SettingChanged += PieceSettingChanged;
			prefabDBConfigEntries.category.SettingChanged += PieceSettingChanged;
			prefabDBConfigEntries.craftingStation.SettingChanged += PieceSettingChanged;
			prefabDBConfigEntries.requirements.SettingChanged += PieceSettingChanged;
			if (prefabDBConfigEntries.placementPatch != null)
			{
				prefabDBConfigEntries.placementPatch.SettingChanged += PlacementSettingChanged;
			}
			if (prefabDBConfigEntries.clipEverything != null)
			{
				prefabDBConfigEntries.clipEverything.SettingChanged += PieceSettingChanged;
			}
			if (prefabDBConfigEntries.clipGround != null)
			{
				prefabDBConfigEntries.clipGround.SettingChanged += PieceSettingChanged;
			}
			PrefabDBConfigsMap[((Object)prefab).name] = prefabDBConfigEntries;
			return prefabDBConfigEntries;
		}

		public bool IsPieceAddedByMVBP(GameObject prefab, Piece piece = null)
		{
			return PieceHelper.IsPieceAddedByMVBP(prefab, piece);
		}
	}
	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;
				if (Object.op_Implicit((Object)(object)val))
				{
					LogInfo(" - " + ((Object)val).name);
					components = ((Component)val).GetComponents<Component>();
					for (int i = 0; i < components.Length; i++)
					{
						LogComponent(components[i]);
					}
				}
			}
		}

		internal static void LogComponent(Component compo)
		{
			if (!Object.op_Implicit((Object)(object)compo))
			{
				return;
			}
			try
			{
				LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---");
			}
			catch (Exception ex)
			{
				LogError(ex.ToString());
				LogWarning("Could not get type name for component!");
				return;
			}
			try
			{
				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)
				{
					try
					{
						LogInfo($" - {propertyInfo.Name} = {propertyInfo.GetValue(compo)}");
					}
					catch (Exception ex2)
					{
						LogError(ex2.ToString());
						LogWarning("Could not get property: " + propertyInfo.Name + " for component!");
					}
				}
			}
			catch (Exception ex3)
			{
				LogError(ex3.ToString());
				LogWarning("Could not get properties for component!");
			}
			try
			{
				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)
				{
					try
					{
						LogInfo($" - {fieldInfo.Name} = {fieldInfo.GetValue(compo)}");
					}
					catch (Exception ex4)
					{
						LogError(ex4.ToString());
						LogWarning("Could not get field: " + fieldInfo.Name + " for component!");
					}
				}
			}
			catch (Exception ex5)
			{
				LogError(ex5.ToString());
				LogWarning("Could not get fields for component!");
			}
		}
	}
}
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(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(FejdStartup))]
	internal static class FejdStartupPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		public static void FejdStartup_Awakex_Prefix()
		{
			Log.LogInfo("FejdStartup.Awake");
		}
	}
	[HarmonyPatch(typeof(MineRock))]
	internal static class MineRockPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateVisability")]
		private static bool UpdateVisabilityPrefix(MineRock __instance)
		{
			Log.LogInfo("MineRock.UpdateVisability patch applied", LogLevel.High);
			if (Object.op_Implicit((Object)(object)__instance))
			{
				return (Object)(object)__instance.m_nview != (Object)null;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Door))]
	internal static class SecretDoorPatch
	{
		[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.GetValueOrDefault() == -1 || __state.GetValueOrDefault() == 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(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(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.Models
{
	internal sealed class NamedSnapPoint
	{
		public Vector3 LocalPosition { get; }

		public string Name { get; }

		public NamedSnapPoint(Vector3 localPosition, string name)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			LocalPosition = localPosition;
			Name = name;
		}

		public NamedSnapPoint(float x, float y, float z, string name)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			LocalPosition = new Vector3(x, y, z);
			Name = name;
		}

		public override string ToString()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return $"{LocalPosition} [{Name}]";
		}
	}
}
namespace MVBP.Helpers
{
	internal static class CollisionHelper
	{
		internal static void AddBoxCollider(GameObject prefab, Vector3 center, Vector3 size, bool local = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider val = prefab.AddComponent<BoxCollider>();
			if (local)
			{
				val.center = center;
				val.size = size;
			}
			else
			{
				val.center = prefab.transform.InverseTransformPoint(center);
				val.size = prefab.transform.InverseTransformPoint(size);
			}
		}

		internal static void PatchCollider(GameObject prefab)
		{
			//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_000a: 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)
			Bounds meshBounds = GetMeshBounds(prefab);
			AddBoxCollider(prefab, ((Bounds)(ref meshBounds)).center, ((Bounds)(ref meshBounds)).size);
		}

		internal static Bounds GetRendererBounds(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_002e: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				((Bounds)(ref result)).Encapsulate(val.bounds);
			}
			return result;
		}

		internal static Bounds GetMeshBounds(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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val in componentsInChildren)
			{
				((Bounds)(ref result)).Encapsulate(((Renderer)val).bounds);
			}
			SkinnedMeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer obj in componentsInChildren2)
			{
				Bounds bounds = obj.sharedMesh.bounds;
				Transform transform = ((Component)obj).transform;
				Vector3 val2 = transform.TransformPoint(((Bounds)(ref bounds)).max);
				Vector3 val3 = transform.TransformPoint(((Bounds)(ref bounds)).min);
				((Bounds)(ref result)).Encapsulate(val2);
				((Bounds)(ref result)).Encapsulate(val3);
			}
			return result;
		}

		internal static Bounds GetColliderBounds(GameObject prefab)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			foreach (Collider allCollider in GetAllColliders(prefab))
			{
				((Bounds)(ref result)).Encapsulate(allCollider.bounds);
			}
			return result;
		}

		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 = PrefabDefaults.ShouldCacheIcon(((Object)obj).name)
			};
			return RenderManager.Instance.Render(val);
		}
	}
	internal static class NameMaker
	{
		private static TextInfo EngTextInfo = new CultureInfo("en-US", useUserOverride: false).TextInfo;

		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 AltToEndRegex = new Regex("(.+?)( alt )(.*)");

		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)";
			}
			if (s.EndsWithAny("26", "45"))
			{
				s += "°";
			}
			s = IsLastCharDigit.Replace(s, " ($1)");
			s = WhiteSpaceRegex.Replace(s, " ");
			s = EngTextInfo.ToTitleCase(s);
			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)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return string.Empty;
			}
			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) && Object.op_Implicit((Object)(object)component8.m_creaturePrefab))
			{
				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 string.Empty;
		}
	}
	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_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Invalid comparison between Unknown and I4
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Invalid comparison between Unknown and I4
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Invalid comparison between Unknown and I4
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Invalid comparison between Unknown and I4
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: 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.Contains("ashwood"))
				{
					return PieceGroup.Ashwood;
				}
				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 bool IsPieceAddedByMVBP(GameObject prefab, Piece piece = null)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return false;
			}
			return AddedPieceComponent.Contains(InitManager.GetPrefabName(prefab, piece));
		}

		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.Medium);
			}
			return val;
		}

		internal static Piece ConfigurePiece(PieceDB pieceDB)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Piece piece = pieceDB.piece;
			string name = NameMaker.FormatPieceName(pieceDB);
			string pieceDescription = NameMaker.GetPieceDescription(pieceDB);
			PieceCategory pieceCategory = GetPieceCategory(pieceDB.category);
			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 = pieceCategory;
			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 PieceCategory GetPieceCategory(string name)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return PieceManager.Instance.GetPieceCategory(name).Value;
			}
			catch (InvalidOperationException)
			{
				Log.LogWarning("Could not find value for Piece Category: " + name);
				return (PieceCategory)0;
			}
		}

		private static Requirement[] ConfigurePieceRequirements(PieceDB pieceDB)
		{
			Requirement[] array = RequirementsEntry.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 PlayerPiecePatcher
	{
		private static readonly int PieceLayer = LayerMask.NameToLayer("piece");

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

		private const float timeout = 1E+30f;

		internal static void PatchPlayerBuiltPieceIfNeed(Piece piece)
		{
			if (Object.op_Implicit((Object)(object)piece) && Object.op_Implicit((Object)(object)((Component)piece).gameObject) && piece.IsPlacedByPlayer() && InitManager.IsPatchedByMod((Component)(object)piece))
			{
				string prefabName = InitManager.GetPrefabName((Component)(object)piece);
				ApplyDoorPatches(prefabName, ((Component)piece).gameObject);
				ApplyTimedDestructionPatch(((Component)piece).gameObject);
				ApplyContainerPatches(prefabName, ((Component)piece).gameObject);
				Destructible destructible = default(Destructible);
				if (((Component)piece).TryGetComponent<Destructible>(ref destructible))
				{
					EditDestructibleSpawn(prefabName, destructible);
				}
				if (MorePrefabs.IsEnablePlayerBasePatches)
				{
					ApplyPlayerBasePatches(prefabName, ((Component)piece).gameObject);
				}
				if (MorePrefabs.IsEnableBedPatches)
				{
					ApplyBedPatches(prefabName, ((Component)piece).gameObject);
				}
				if (MorePrefabs.IsEnableFermenterPatches)
				{
					ApplyFermenterPatches(prefabName, ((Component)piece).gameObject);
				}
				if (MorePrefabs.PatchDvergrWoodTexture)
				{
					ApplyNewDvergrTexture(prefabName, ((Component)piece).gameObject);
				}
			}
		}

		private static void ApplyContainerPatches(string prefabName, GameObject gameObject)
		{
			Container componentInChildren = gameObject.GetComponentInChildren<Container>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				return;
			}
			ZDO zDO = componentInChildren.m_nview.GetZDO();
			if (zDO == null)
			{
				return;
			}
			Piece componentInChildren2 = gameObject.GetComponentInChildren<Piece>();
			if (Object.op_Implicit((Object)(object)componentInChildren2) && componentInChildren2.IsPlacedByPlayer())
			{
				zDO.Set("HasFields", true);
				zDO.Set("HasFieldsContainer", true);
				zDO.Set("Container.m_checkGuardStone", true);
			}
			PrefabDB defaultPrefabDB = PrefabDefaults.GetDefaultPrefabDB(prefabName);
			if (defaultPrefabDB.invWidth.HasValue && defaultPrefabDB.invHeight.HasValue)
			{
				Inventory inventory = componentInChildren.GetInventory();
				if (inventory != null)
				{
					int value = (int)defaultPrefabDB.invWidth.Value;
					int value2 = (int)defaultPrefabDB.invHeight.Value;
					zDO.Set("HasFields", true);
					zDO.Set("HasFieldsContainer", true);
					zDO.Set("Container.m_width", value);
					zDO.Set("Container.m_height", value2);
					zDO.Set("HasFieldsInventory", true);
					zDO.Set("Inventory.m_width", value);
					zDO.Set("Inventory.m_height", value2);
					componentInChildren.m_width = value;
					componentInChildren.m_height = value2;
					inventory.m_width = value;
					inventory.m_height = value2;
				}
			}
		}

		private static void ApplyTimedDestructionPatch(GameObject gameObject)
		{
			TimedDestruction val = default(TimedDestruction);
			if (gameObject.TryGetComponent<TimedDestruction>(ref val))
			{
				ZDO zDO = val.m_nview.GetZDO();
				if (zDO != null)
				{
					zDO.Set("HasFields", true);
					zDO.Set("HasFieldsTimedDestruction", true);
					zDO.Set("TimedDestruction.m_timeout", 1E+30f);
					val.m_timeout = 1E+30f;
				}
			}
		}

		private static void EditDestructibleSpawn(string name, Destructible destructible)
		{
			if (!Object.op_Implicit((Object)(object)destructible) || !PrefabDefaults.DefaultConfigValues.TryGetValue(name, out var value) || string.IsNullOrEmpty(value.spawnOnDestroyed))
			{
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(value.spawnOnDestroyed);
			if (Object.op_Implicit((Object)(object)prefab))
			{
				ZDO zDO = destructible.m_nview.GetZDO();
				if (zDO != null)
				{
					zDO.Set("HasFields", true);
					zDO.Set("HasFieldsDestructible", true);
					zDO.Set("Destructible.m_spawnWhenDestroyed", "fx_crystal_destruction");
					destructible.m_spawnWhenDestroyed = prefab;
				}
			}
		}

		private static void ApplyNewDvergrTexture(string name, GameObject gameObject)
		{
			if (PrefabDefaults.DvergrWoodPieces.Contains(name))
			{
				Renderer[] componentsInChildren = ((Component)gameObject.transform.Find("New")).GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].material.mainTexture = TextureHelper.GetNewDvergrTexture();
				}
			}
		}

		private static void ApplyPlayerBasePatches(string name, GameObject gameObject)
		{
			if (InitManager.TryGetPieceDB(name, out var pieceDB) && pieceDB.playerBasePatch)
			{
				AddPlayerBase(gameObject);
			}
		}

		private static void AddPlayerBase(GameObject gameObject)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PlayerBase");
			val.transform.parent = gameObject.transform;
			val.transform.localScale = Vector3.one;
			val.transform.localPosition = Vector3.zero;
			val.layer = CharacterTriggerLayer;
			SphereCollider obj = val.AddComponent<SphereCollider>();
			obj.center = Vector3.zero;
			obj.radius = 20f;
			((Collider)obj).enabled = true;
			((Collider)obj).isTrigger = true;
			EffectArea obj2 = val.AddComponent<EffectArea>();
			((Behaviour)obj2).enabled = true;
			obj2.m_type = (Type)4;
		}

		private static void ApplyDoorPatches(string name, GameObject gameObject)
		{
			Door val = default(Door);
			if ((!(name == "dvergrtown_slidingdoor") && !(name == "dvergrtown_secretdoor")) || !gameObject.TryGetComponent<Door>(ref val))
			{
				return;
			}
			val.m_canNotBeClosed = false;
			val.m_checkGuardStone = true;
			ZNetView val2 = default(ZNetView);
			if (gameObject.TryGetComponent<ZNetView>(ref val2))
			{
				ZDO zDO = val2.GetZDO();
				if (zDO != null)
				{
					zDO.Set("HasFields", true);
					zDO.Set("HasFieldsDoor", true);
					zDO.Set("Door.m_canNotBeClosed", false);
					zDO.Set("Door.m_checkGuardStone", true);
				}
			}
		}

		private static void ApplyBedPatches(string name, GameObject gameObject)
		{
			//IL_002b: 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)
			if (!(name == "goblin_bed"))
			{
				if (name == "dvergrprops_bed")
				{
					AddBed(gameObject, new Vector3(0f, 0.45f, 0f));
				}
			}
			else
			{
				AddBed(gameObject, new Vector3(0f, 0.45f, 0f));
			}
		}

		private static void AddBed(GameObject gameObject, Vector3 spawnPosition)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("spawnpoint");
			val.transform.parent = gameObject.transform;
			val.transform.localPosition = spawnPosition;
			val.layer = PieceLayer;
			gameObject.AddComponent<Bed>().m_spawnPoint = val.transform;
		}

		private static void ApplyFermenterPatches(string name, GameObject gameObject)
		{
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			if (name == "dvergrprops_barrel")
			{
				ZNetScene instance = ZNetScene.instance;
				GameObject obj = ((instance != null) ? instance.GetPrefab("fermenter") : null);
				GameObject val = ((Component)obj.transform.Find("add_button")).gameObject.DeepCopy();
				GameObject val2 = ((Component)obj.transform.Find("tap_button")).gameObject.DeepCopy();
				GameObject val3 = ((Component)obj.transform.Find("roofcheckpoint")).gameObject.DeepCopy();
				GameObject val4 = ((Component)obj.transform.Find("output")).gameObject.DeepCopy();
				GameObject val5 = ((Component)obj.transform.Find("_ready")).gameObject.DeepCopy();
				GameObject val6 = ((Component)obj.transform.Find("_fermenting")).gameObject.DeepCopy();
				Fermenter component = obj.GetComponent<Fermenter>();
				val.transform.parent = gameObject.transform;
				val2.transform.parent = gameObject.transform;
				val3.transform.parent = gameObject.transform;
				val4.transform.parent = gameObject.transform;
				val5.transform.parent = gameObject.transform;
				val6.transform.parent = gameObject.transform;
				val.transform.localScale = Vector3.one;
				val.transform.localPosition = new Vector3(0f, 0.75f, 0f);
				val2.transform.localPosition = new Vector3(0f, 0.5f, 0.9f);
				val4.transform.localPosition = new Vector3(0f, 0.5f, 1.2f);
				val3.transform.localPosition = new Vector3(0f, 1.5f, 0f);
				val5.transform.localPosition = new Vector3(0f, 0.75f, 0f);
				val6.transform.localPosition = new Vector3(0f, 0.75f, 0f);
				GameObject val7 = new GameObject("_top");
				val7.transform.parent = gameObject.transform;
				bool activeSelf = gameObject.activeSelf;
				gameObject.SetActive(false);
				Fermenter obj2 = gameObject.AddComponent<Fermenter>();
				obj2.m_addSwitch = val.GetComponent<Switch>();
				obj2.m_tapSwitch = val2.GetComponent<Switch>();
				obj2.m_roofCheckPoint = val3.transform;
				obj2.m_topObject = val7;
				obj2.m_readyObject = val5;
				obj2.m_fermentingObject = val6;
				obj2.m_outputPoint = val4.transform;
				obj2.m_tapDelay = component.m_tapDelay;
				obj2.m_updateCoverTimer = component.m_updateCoverTimer;
				obj2.m_fermentationDuration = component.m_fermentationDuration * 0.7f;
				obj2.m_name = component.m_name;
				obj2.m_addedEffects = component.m_addedEffects;
				obj2.m_tapEffects = component.m_tapEffects;
				obj2.m_spawnEffects = component.m_spawnEffects;
				obj2.m_conversion = component.m_conversion;
				gameObject.SetActive(activeSelf);
				AddPlayerBase(gameObject);
			}
		}
	}
	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", "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", "dvergrprops_crate_ashlands",
			"Charredfortress_LOD"
		};

		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 (PrefabDefaults.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<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
	{
		internal static void PatchPrefabIfNeeded(GameObject prefab)
		{
			//IL_2c77: Unknown result type (might be due to invalid IL or missing references)
			//IL_2c7c: Unknown result type (might be due to invalid IL or missing references)
			//IL_25ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_25f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_2608: Unknown result type (might be due to invalid IL or missing references)
			//IL_260d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2623: Unknown result type (might be due to invalid IL or missing references)
			//IL_2628: Unknown result type (might be due to invalid IL or missing references)
			//IL_263e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2643: Unknown result type (might be due to invalid IL or missing references)
			//IL_2659: Unknown result type (might be due to invalid IL or missing references)
			//IL_265e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2674: Unknown result type (might be due to invalid IL or missing references)
			//IL_2679: Unknown result type (might be due to invalid IL or missing references)
			//IL_268f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2694: Unknown result type (might be due to invalid IL or missing references)
			//IL_26aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_26af: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a54: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a6a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a6f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a85: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2aa0: Unknown result type (might be due to invalid IL or missing references)
			//IL_2aa5: Unknown result type (might be due to invalid IL or missing references)
			//IL_2abb: Unknown result type (might be due to invalid IL or missing references)
			//IL_2ac0: Unknown result type (might be due to invalid IL or missing references)
			//IL_271d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2722: Unknown result type (might be due to invalid IL or missing references)
			//IL_2738: Unknown result type (might be due to invalid IL or missing references)
			//IL_273d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2753: Unknown result type (might be due to invalid IL or missing references)
			//IL_2758: Unknown result type (might be due to invalid IL or missing references)
			//IL_276e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2773: Unknown result type (might be due to invalid IL or missing references)
			//IL_2789: Unknown result type (might be due to invalid IL or missing references)
			//IL_278e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d97: Unknown result type (might be due to invalid IL or missing references)
			//IL_1d9c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1db2: Unknown result type (might be due to invalid IL or missing references)
			//IL_1db7: Unknown result type (might be due to invalid IL or missing references)
			//IL_2056: Unknown result type (might be due to invalid IL or missing references)
			//IL_205b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2071: Unknown result type (might be due to invalid IL or missing references)
			//IL_2076: Unknown result type (might be due to invalid IL or missing references)
			//IL_208c: Unknown result type (might be due to invalid IL or missing references)
			//IL_2091: Unknown result type (might be due to invalid IL or missing references)
			//IL_20a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_20ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_20c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_20c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_20dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_20e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_20f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_20fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_2ae5: Unknown result type (might be due to invalid IL or missing references)
			//IL_2af9: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b05: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b19: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b3c: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b41: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b57: Unknown result type (might be due to invalid IL or missing references)
			//IL_2b5c: Unknown result type (might be due to invalid IL or missing references)
			//IL_28ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_28b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_28c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_28ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_28e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_28e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_28ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_2904: Unknown result type (might be due to invalid IL or missing references)
			//IL_291a: Unknown result type (might be due to invalid IL or missing references)
			//IL_291f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2935: Unknown result type (might be due to invalid IL or missing references)
			//IL_293a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2950: Unknown result type (might be due to invalid IL or missing references)
			//IL_2955: Unknown result type (might be due to invalid IL or missing references)
			//IL_296b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2970: Unknown result type (might be due to invalid IL or missing references)
			//IL_2986: Unknown result type (might be due to invalid IL or missing references)
			//IL_298b: Unknown result type (might be due to invalid IL or missing references)
			//IL_29a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_29a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_24f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_24f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_250e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2513: Unknown result type (might be due to invalid IL or missing references)
			//IL_2529: Unknown result type (might be due to invalid IL or missing references)
			//IL_252e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2544: Unknown result type (might be due to invalid IL or missing references)
			//IL_2549: Unknown result type (might be due to invalid IL or missing references)
			//IL_2570: Unknown result type (might be due to invalid IL or missing references)
			//IL_2575: Unknown result type (might be due to invalid IL or missing references)
			//IL_258b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2590: Unknown result type (might be due to invalid IL or missing references)
			//IL_25a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_25ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_25c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_25c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_2260: Unknown result type (might be due to invalid IL or missing references)
			//IL_2282: Unknown result type (might be due to invalid IL or missing references)
			//IL_2287: Unknown result type (might be due to invalid IL or missing references)
			//IL_229d: Unknown result type (might be due to invalid IL or missing references)
			//IL_22a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_22b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_22bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_22d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_22d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_155b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1560: Unknown