Decompiled source of PersonalChestHeeler v1.0.1

PersonalChestHeeler.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using PersonalChestHeeler.Configuration;
using PersonalChestHeeler.Localization;
using PersonalChestHeeler.Pieces;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PersonalChestHeeler")]
[assembly: AssemblyDescription("Tiered personal locked storage chests scaled across Valheim progression ages with server-synced configurable capacity, crafting recipes, and subtle emissive lock indicators.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("dreamwraith (https://github.com/dreamwraith)")]
[assembly: AssemblyProduct("PersonalChestHeeler")]
[assembly: AssemblyCopyright("Copyright © 2026 dreamwraith")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ac7f1b48-fbf2-4536-ba7f-40eea4556f3f")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PersonalChestHeeler
{
	[BepInPlugin("dreamwraith.PersonalChestHeeler", "PersonalChestHeeler", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "dreamwraith.PersonalChestHeeler";

		public const string ModName = "PersonalChestHeeler";

		public const string ModVersion = "1.0.1";

		internal static ManualLogSource Log;

		private Harmony? _harmony;

		internal static Plugin? Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Initialize(((BaseUnityPlugin)this).Config);
			ModLocalization.Initialize();
			ChestAudioEffectManager.Initialize();
			ChestPieceManager.Initialize();
			if (!ModConfig.EnableMod.Value)
			{
				Log.LogInfo((object)"PersonalChestHeeler is disabled in configuration.");
				return;
			}
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "dreamwraith.PersonalChestHeeler");
			Log.LogInfo((object)"PersonalChestHeeler v1.0.1 loaded successfully.");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static void LogDebug(string message)
		{
			if (ModConfig.EnableDebugLogs != null && ModConfig.EnableDebugLogs.Value)
			{
				Log.LogInfo((object)("[DEBUG] " + message));
			}
		}
	}
	internal static class VersionInfo
	{
		public const string Version = "1.0.1";
	}
}
namespace PersonalChestHeeler.Pieces
{
	public static class ChestAudioEffectManager
	{
		private enum SfxCategory
		{
			Base,
			Ambient,
			Magic
		}

		private static bool _initialized;

		private static GameObject? _sfxGlobalMagicBuild;

		private static GameObject? _sfxGlobalMagicHit;

		private static GameObject? _sfxGlobalMagicDestroy;

		private static GameObject? _sfxGlobalMagicOpen;

		private static GameObject? _sfxGlobalMagicClose;

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

		public static void Initialize()
		{
			if (!_initialized)
			{
				_initialized = true;
				PrefabManager.OnVanillaPrefabsAvailable += RegisterAllCustomAudioPrefabs;
				Plugin.LogDebug("[AudioEffectManager] Subscribed to PrefabManager.OnVanillaPrefabsAvailable.");
			}
		}

		private static void RegisterAllCustomAudioPrefabs()
		{
			try
			{
				_sfxGlobalMagicBuild = CreateCustomSfxPrefab("sfx_pch_magic_build", new string[1] { "Magic_CrystalBlast7" }, 1f, 1f, SfxCategory.Magic);
				_sfxGlobalMagicHit = CreateCustomSfxPrefab("sfx_pch_magic_hit", new string[1] { "magic_spell_electro_23" }, 0.85f, 1f, SfxCategory.Magic);
				_sfxGlobalMagicDestroy = CreateCustomSfxPrefab("sfx_pch_magic_destroy", new string[1] { "Magic_Spell16" }, 1f, 1f, SfxCategory.Magic);
				_sfxGlobalMagicOpen = CreateCustomSfxPrefab("sfx_pch_magic_open", new string[1] { "Magic_EnergyRingPass8" }, 0.9f, 1f, SfxCategory.Magic);
				_sfxGlobalMagicClose = CreateCustomSfxPrefab("sfx_pch_magic_close", new string[1] { "Magic_Poof3" }, 0.9f, 1f, SfxCategory.Magic);
				CreateTierPrefabs("piece_chest_chained_personal", new string[5] { "UI_Build_Wood_01", "UI_Build_Wood_02", "UI_Build_Wood_03", "UI_Build_Wood_04", "UI_Build_Wood_05" }, new string[8] { "Enemy_TrainingDummy_Melee_Attack_Heavy_Impact_01", "Enemy_TrainingDummy_Melee_Attack_Heavy_Impact_02", "Enemy_TrainingDummy_Melee_Attack_Heavy_Impact_03", "Enemy_TrainingDummy_Melee_Attack_Heavy_Impact_04", "Enemy_TrainingDummy_Melee_Attack_Light_Impact_01", "Enemy_TrainingDummy_Melee_Attack_Light_Impact_02", "Enemy_TrainingDummy_Melee_Attack_Light_Impact_03", "Enemy_TrainingDummy_Melee_Attack_Light_Impact_04" }, new string[4] { "UI_Build_Wood_Break_M_01", "UI_Build_Wood_Break_M_02", "UI_Build_Wood_Break_M_03", "UI_Build_Wood_Break_M_04" }, new string[5] { "Enemy_TrainingDummy_Idle_01", "Enemy_TrainingDummy_Idle_02", "Enemy_TrainingDummy_Idle_03", "Enemy_TrainingDummy_Idle_04", "Enemy_TrainingDummy_Idle_05" }, new string[5] { "Enemy_TrainingDummy_Idle_06", "Enemy_TrainingDummy_Idle_07", "Enemy_TrainingDummy_Idle_08", "Enemy_TrainingDummy_Idle_09", "Enemy_TrainingDummy_Idle_10" }, new string[1] { "Enemy_FrozenKing_PunchAOE_Chain_End_03" });
				CreateAmbientOverlayPrefab("piece_chest_finewood_personal", new string[1] { "Obliterator_Lever_Pull" }, 1f);
				CreateAmbientOverlayPrefab("piece_chest_reinforced_personal", new string[1] { "Obliterator_Lever_Pull" }, 1f);
				CreateTierPrefabs("piece_chest_dvergr_sm_personal", new string[6] { "Weapons_ArbalestCrossbow_Shot_01", "Weapons_ArbalestCrossbow_Shot_02", "Weapons_ArbalestCrossbow_Shot_03", "Weapons_ArbalestCrossbow_Shot_04", "Weapons_ArbalestCrossbow_Shot_05", "Weapons_ArbalestCrossbow_Shot_06" }, new string[4] { "Branch_Hit_01", "Branch_Hit_02", "Branch_Hit_03", "Branch_Hit_04" }, new string[4] { "UI_Build_TreasureChest_Break_01", "UI_Build_TreasureChest_Break_02", "UI_Build_TreasureChest_Break_03", "UI_Build_TreasureChest_Break_04" }, new string[3] { "Objects_Gate_Darkwood_Open_01", "Objects_Gate_Darkwood_Open_02", "Objects_Gate_Darkwood_Open_03" }, new string[3] { "Objects_StoneOven_Door_Close_01", "Objects_StoneOven_Door_Close_02", "Objects_StoneOven_Door_Close_03" }, new string[1] { "Items_Trap_Open" }, 1f, 1.25f);
				CreateTierPrefabs("piece_chest_dvergr_lg_personal", new string[6] { "Battering_Ram_Piston_Impact_01", "Battering_Ram_Piston_Impact_02", "Battering_Ram_Piston_Impact_03", "Battering_Ram_Piston_Impact_04", "Battering_Ram_Piston_Impact_05", "Battering_Ram_Piston_Impact_06" }, new string[6] { "Player_Block_MetalShield_M_01", "Player_Block_MetalShield_M_02", "Player_Block_MetalShield_M_03", "Player_Block_MetalShield_Overlay_A_M_01", "Player_Block_MetalShield_Overlay_A_M_02", "Player_Block_MetalShield_Overlay_A_M_03" }, new string[4] { "UI_Build_TreasureChest_Break_01", "UI_Build_TreasureChest_Break_02", "UI_Build_TreasureChest_Break_03", "UI_Build_TreasureChest_Break_04" }, new string[2] { "Siege_Catapult_Legs_Up_02", "Siege_Catapult_Legs_Up_03" }, new string[4] { "Enemy_TrainingDummy_Heavy_Attack_01", "Enemy_TrainingDummy_Heavy_Attack_02", "Enemy_TrainingDummy_Heavy_Attack_03", "Enemy_TrainingDummy_Heavy_Attack_04" }, new string[1] { "Items_Trap_Open" }, 1f, 1.5f, 1.5f);
				CreateTierPrefabs("piece_chest_charred_personal", new string[5] { "Enemy_CharredArcher_BowRelease_01", "Enemy_CharredArcher_BowRelease_02", "Enemy_CharredArcher_BowRelease_03", "Enemy_CharredArcher_BowRelease_04", "Enemy_CharredArcher_BowRelease_05" }, new string[5] { "Enemy_Father_Fissure_Pillar_01", "Enemy_Father_Fissure_Pillar_02", "Enemy_Father_Fissure_Pillar_03", "Enemy_Father_Fissure_Pillar_04", "Enemy_Father_Fissure_Pillar_05" }, new string[6] { "LavaBomb_Rocks_01", "LavaBomb_Rocks_02", "LavaBomb_Rocks_03", "LavaBomb_Rocks_04", "LavaBomb_Rocks_05", "LavaBomb_Rocks_06" }, new string[5] { "Enemy_CharredArcher_BowDraw_01", "Enemy_CharredArcher_BowDraw_02", "Enemy_CharredArcher_BowDraw_03", "Enemy_CharredArcher_BowDraw_04", "Enemy_CharredArcher_BowDraw_05" }, new string[4] { "Enemy_Firetroll_Attack_Club_SwingDown_01", "Enemy_Firetroll_Attack_Club_SwingDown_02", "Enemy_Firetroll_Attack_Club_SwingDown_03", "Enemy_Firetroll_Attack_Club_SwingDown_04" }, new string[1] { "Enemy_Father_FireWall_FireBurst_05" }, 0.8f, 0.75f, 0.75f);
				CreateTierPrefabs("piece_chest_ancient_personal", new string[3] { "Weapons_IronSledge_Impact_S_01", "Weapons_IronSledge_Impact_S_02", "Weapons_IronSledge_Impact_S_03" }, new string[5] { "Player_Weapons_Ice_Hit_01", "Player_Weapons_Ice_Hit_02", "Player_Weapons_Ice_Hit_03", "Player_Weapons_Ice_Hit_04", "Player_Weapons_Ice_Hit_05" }, new string[2] { "Smash_HugeRockRip1", "Smash_HugeRockRip2" }, new string[4] { "Enemy_FrozenKing_Tendril_Grow_01", "Enemy_FrozenKing_Tendril_Grow_02", "Enemy_FrozenKing_Tendril_Grow_03", "Enemy_FrozenKing_Tendril_Grow_04" }, new string[4] { "Battering_Ram_Piston_Impact_Rock_01", "Battering_Ram_Piston_Impact_Rock_03", "Battering_Ram_Piston_Impact_Rock_04", "Battering_Ram_Piston_Impact_Rock_05" }, new string[1] { "Scrape_Stone_Loop" }, 0.55f, 1.25f, 1.1f);
				Plugin.LogDebug("[AudioEffectManager] Successfully created and registered all custom chest SFX prefabs via Jotunn.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[AudioEffectManager] Failed to register custom audio prefabs: {arg}");
			}
		}

		private static void CreateTierPrefabs(string tierKey, string[] buildClips, string[] hitClips, string[] destroyClips, string[] openClips, string[] closeClips, string[] ambientOverlayClips, float ambientBaseline = 1f, float openPitch = 1f, float closePitch = 1f)
		{
			GameObject val = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_build", buildClips, 1f, 1f, SfxCategory.Base);
			GameObject val2 = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_hit", hitClips, 1f, 1f, SfxCategory.Base);
			GameObject val3 = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_destroy", destroyClips, 1f, 1f, SfxCategory.Base);
			GameObject val4 = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_open", openClips, 1f, openPitch, SfxCategory.Base);
			GameObject val5 = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_close", closeClips, 1f, closePitch, SfxCategory.Base);
			GameObject val6 = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_amb", ambientOverlayClips, ambientBaseline, 1f, SfxCategory.Ambient);
			if ((Object)(object)val != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_build"] = val;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_hit"] = val2;
			}
			if ((Object)(object)val3 != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_destroy"] = val3;
			}
			if ((Object)(object)val4 != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_open"] = val4;
			}
			if ((Object)(object)val5 != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_close"] = val5;
			}
			if ((Object)(object)val6 != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_amb"] = val6;
			}
		}

		private static void CreateAmbientOverlayPrefab(string tierKey, string[] ambientClips, float baseline)
		{
			GameObject val = CreateCustomSfxPrefab("sfx_pch_" + tierKey + "_amb", ambientClips, baseline, 1f, SfxCategory.Ambient);
			if ((Object)(object)val != (Object)null)
			{
				_customSfxPrefabs[tierKey + "_amb"] = val;
			}
		}

		private static GameObject? CreateCustomSfxPrefab(string customName, string[] clipNames, float baselineVolume, float pitch, SfxCategory category)
		{
			try
			{
				List<AudioClip> list = new List<AudioClip>();
				float num = 1.5f;
				foreach (string text in clipNames)
				{
					if (string.IsNullOrWhiteSpace(text))
					{
						continue;
					}
					AudioClip prefab = Cache.GetPrefab<AudioClip>(text.Trim());
					if ((Object)(object)prefab != (Object)null)
					{
						list.Add(prefab);
						if (prefab.length > num)
						{
							num = prefab.length;
						}
					}
					else
					{
						Plugin.Log.LogWarning((object)("[AudioEffectManager] Failed to find AudioClip '" + text + "' via Jotunn Cache."));
					}
				}
				if (list.Count == 0)
				{
					Plugin.Log.LogError((object)("[AudioEffectManager] No audio clips resolved for custom SFX '" + customName + "'."));
					return null;
				}
				GameObject val = PrefabManager.Instance.CreateClonedPrefab(customName, "sfx_chest_open");
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogError((object)("[AudioEffectManager] Failed to clone 'sfx_chest_open' for '" + customName + "'."));
					return null;
				}
				for (int num2 = val.transform.childCount - 1; num2 >= 0; num2--)
				{
					Object.Destroy((Object)(object)((Component)val.transform.GetChild(num2)).gameObject);
				}
				ZSFX val2 = val.GetComponent<ZSFX>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = val.AddComponent<ZSFX>();
				}
				float num3 = baselineVolume * category switch
				{
					SfxCategory.Base => 1.25f, 
					SfxCategory.Ambient => 0.85f, 
					SfxCategory.Magic => 0.1f, 
					_ => 1f, 
				};
				val2.m_audioClips = list.ToArray();
				val2.m_minVol = num3 * 0.95f;
				val2.m_maxVol = num3 * 1.05f;
				val2.m_minPitch = pitch * 0.97f;
				val2.m_maxPitch = pitch * 1.03f;
				val2.m_playOnAwake = true;
				TimedDestruction component = val.GetComponent<TimedDestruction>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_timeout = Mathf.Max(2.5f, num / Mathf.Max(0.1f, pitch) + 0.6f);
					component.m_triggerOnAwake = true;
				}
				Plugin.LogDebug($"[AudioEffectManager] Created custom SFX prefab '{customName}' with {list.Count} clip(s) (Pitch: {pitch:F2}, Baseline: {baselineVolume:F2}).");
				return val;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[AudioEffectManager] Exception creating SFX prefab '{customName}': {arg}");
				return null;
			}
		}

		public static EffectList GetPlaceEffects(string tierPrefabName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_build", out GameObject value))
			{
				list.Add(new EffectData
				{
					m_prefab = value,
					m_enabled = true
				});
			}
			else
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_private");
				object obj = ((prefab != null) ? prefab.GetComponent<Piece>() : null);
				if (obj == null)
				{
					GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_chest");
					obj = ((prefab2 != null) ? prefab2.GetComponent<Piece>() : null);
				}
				Piece val = (Piece)obj;
				if ((Object)(object)val != (Object)null && val.m_placeEffect != null && val.m_placeEffect.m_effectPrefabs != null)
				{
					EffectData[] effectPrefabs = val.m_placeEffect.m_effectPrefabs;
					foreach (EffectData val2 in effectPrefabs)
					{
						if ((Object)(object)val2?.m_prefab != (Object)null)
						{
							list.Add(val2);
						}
					}
				}
			}
			if ((Object)(object)_sfxGlobalMagicBuild != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = _sfxGlobalMagicBuild,
					m_enabled = true
				});
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}

		public static EffectList GetHitEffects(string tierPrefabName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_hit", out GameObject value))
			{
				list.Add(new EffectData
				{
					m_prefab = value,
					m_enabled = true
				});
			}
			else
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_private");
				object obj = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null);
				if (obj == null)
				{
					GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_chest");
					obj = ((prefab2 != null) ? prefab2.GetComponent<WearNTear>() : null);
				}
				WearNTear val = (WearNTear)obj;
				if ((Object)(object)val != (Object)null && val.m_hitEffect != null && val.m_hitEffect.m_effectPrefabs != null)
				{
					EffectData[] effectPrefabs = val.m_hitEffect.m_effectPrefabs;
					foreach (EffectData val2 in effectPrefabs)
					{
						if ((Object)(object)val2?.m_prefab != (Object)null)
						{
							list.Add(val2);
						}
					}
				}
			}
			if ((Object)(object)_sfxGlobalMagicHit != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = _sfxGlobalMagicHit,
					m_enabled = true
				});
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}

		public static EffectList GetDestroyEffects(string tierPrefabName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_destroy", out GameObject value))
			{
				list.Add(new EffectData
				{
					m_prefab = value,
					m_enabled = true
				});
			}
			else
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_private");
				object obj = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null);
				if (obj == null)
				{
					GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_chest");
					obj = ((prefab2 != null) ? prefab2.GetComponent<WearNTear>() : null);
				}
				WearNTear val = (WearNTear)obj;
				if ((Object)(object)val != (Object)null && val.m_destroyedEffect != null && val.m_destroyedEffect.m_effectPrefabs != null)
				{
					EffectData[] effectPrefabs = val.m_destroyedEffect.m_effectPrefabs;
					foreach (EffectData val2 in effectPrefabs)
					{
						if ((Object)(object)val2?.m_prefab != (Object)null)
						{
							list.Add(val2);
						}
					}
				}
			}
			if ((Object)(object)_sfxGlobalMagicDestroy != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = _sfxGlobalMagicDestroy,
					m_enabled = true
				});
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}

		public static EffectList GetOpenEffects(string tierPrefabName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_open", out GameObject value))
			{
				list.Add(new EffectData
				{
					m_prefab = value,
					m_enabled = true
				});
			}
			else
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("sfx_chest_open");
				if ((Object)(object)prefab != (Object)null)
				{
					list.Add(new EffectData
					{
						m_prefab = prefab,
						m_enabled = true
					});
				}
			}
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_amb", out GameObject value2))
			{
				list.Add(new EffectData
				{
					m_prefab = value2,
					m_enabled = true
				});
			}
			if ((Object)(object)_sfxGlobalMagicOpen != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = _sfxGlobalMagicOpen,
					m_enabled = true
				});
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}

		public static EffectList GetCloseEffects(string tierPrefabName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_close", out GameObject value))
			{
				list.Add(new EffectData
				{
					m_prefab = value,
					m_enabled = true
				});
			}
			else
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("sfx_chest_close");
				if ((Object)(object)prefab != (Object)null)
				{
					list.Add(new EffectData
					{
						m_prefab = prefab,
						m_enabled = true
					});
				}
			}
			if (_customSfxPrefabs.TryGetValue(tierPrefabName + "_amb", out GameObject value2))
			{
				list.Add(new EffectData
				{
					m_prefab = value2,
					m_enabled = true
				});
			}
			if ((Object)(object)_sfxGlobalMagicClose != (Object)null)
			{
				list.Add(new EffectData
				{
					m_prefab = _sfxGlobalMagicClose,
					m_enabled = true
				});
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}
	}
	public class ChestGlowController : MonoBehaviour
	{
		private static readonly HashSet<ChestGlowController> _activeControllers = new HashSet<ChestGlowController>();

		private static Material? _demisterBallMaterialTemplate;

		private static GameObject? _flareTemplate;

		private static bool _templatesResolved;

		[SerializeField]
		public string TierPrefabName = string.Empty;

		[SerializeField]
		public Color GlowColor = Color.white;

		private Light? _pointLight;

		private ParticleSystem? _flareParticles;

		private Material? _gemMaterial;

		private GameObject? _gemObject;

		private Transform? _lockRoot;

		private bool _initialized;

		public static IReadOnlyCollection<ChestGlowController> ActiveControllers => _activeControllers;

		public static void EnsureVisualTemplates()
		{
			if (_templatesResolved && (Object)(object)_demisterBallMaterialTemplate != (Object)null && (Object)(object)_flareTemplate != (Object)null)
			{
				return;
			}
			PrefabManager instance = PrefabManager.Instance;
			GameObject val = ((instance != null) ? instance.GetPrefab("piece_groundtorch_mist") : null);
			if ((Object)(object)val != (Object)null)
			{
				Transform obj = val.transform.Find("_enabled/demister_ball (1)");
				Renderer val2 = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMaterial != (Object)null)
				{
					_demisterBallMaterialTemplate = val2.sharedMaterial;
				}
				Transform val3 = val.transform.Find("_enabled/flare");
				if ((Object)(object)val3 != (Object)null)
				{
					_flareTemplate = ((Component)val3).gameObject;
				}
			}
			_templatesResolved = true;
		}

		private void OnEnable()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			_activeControllers.Add(this);
			if (!string.IsNullOrEmpty(TierPrefabName))
			{
				GlowColor = GetLockColor(TierPrefabName);
			}
			if (!_initialized)
			{
				InitializeGlow();
			}
			else
			{
				ApplyCurrentSettings();
			}
		}

		private void OnDisable()
		{
			_activeControllers.Remove(this);
		}

		private void OnDestroy()
		{
			_activeControllers.Remove(this);
			if ((Object)(object)_gemMaterial != (Object)null)
			{
				Object.Destroy((Object)(object)_gemMaterial);
				_gemMaterial = null;
			}
		}

		public void Configure(string prefabName, Color color)
		{
			//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)
			TierPrefabName = prefabName;
			GlowColor = GetLockColor(prefabName);
			if (_initialized)
			{
				ApplyCurrentSettings();
			}
		}

		public static Vector3 GetLockLocalOffset(string prefabName)
		{
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			return (Vector3)(prefabName switch
			{
				"piece_chest_chained_personal" => new Vector3(0f, 0.743f, 0.596f), 
				"piece_chest_finewood_personal" => new Vector3(0f, 0.38f, 0.25f), 
				"piece_chest_reinforced_personal" => new Vector3(0f, 0.746f, 0.476f), 
				"piece_chest_dvergr_sm_personal" => new Vector3(0f, 0.59f, 0.36f), 
				"piece_chest_dvergr_lg_personal" => new Vector3(0f, 0.6f, 0.36f), 
				"piece_chest_charred_personal" => new Vector3(0f, 1.35f, 0.63f), 
				"piece_chest_ancient_personal" => new Vector3(0f, 1.3f, 0.92f), 
				_ => new Vector3(0f, 0.5f, 0.5f), 
			});
		}

		public static Color GetLockColor(string prefabName)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(prefabName switch
			{
				"piece_chest_chained_personal" => ChestPieceManager.ColorChained, 
				"piece_chest_finewood_personal" => ChestPieceManager.ColorBronze, 
				"piece_chest_reinforced_personal" => ChestPieceManager.ColorIronbound, 
				"piece_chest_dvergr_sm_personal" => ChestPieceManager.ColorSilver, 
				"piece_chest_dvergr_lg_personal" => ChestPieceManager.ColorClockwork, 
				"piece_chest_charred_personal" => ChestPieceManager.ColorFlametal, 
				"piece_chest_ancient_personal" => ChestPieceManager.ColorReliquary, 
				_ => Color.white, 
			});
		}

		private void InitializeGlow()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			_initialized = true;
			EnsureVisualTemplates();
			Transform val = ((Component)this).transform.Find("LockRoot") ?? ((Component)this).transform.Find("LockGlowLight");
			GameObject val2;
			if ((Object)(object)val == (Object)null)
			{
				val2 = new GameObject("LockRoot");
				val2.transform.SetParent(((Component)this).transform, false);
			}
			else
			{
				val2 = ((Component)val).gameObject;
				((Object)val2).name = "LockRoot";
			}
			_lockRoot = val2.transform;
			_lockRoot.localPosition = GetLockLocalOffset(TierPrefabName);
			_lockRoot.localRotation = Quaternion.identity;
			UpdateLockRootScale();
			Transform val3 = val2.transform.Find("LockGem");
			if ((Object)(object)val3 == (Object)null)
			{
				_gemObject = GameObject.CreatePrimitive((PrimitiveType)0);
				((Object)_gemObject).name = "LockGem";
				_gemObject.transform.SetParent(val2.transform, false);
				_gemObject.transform.localPosition = Vector3.zero;
				_gemObject.transform.localRotation = Quaternion.identity;
				_gemObject.transform.localScale = new Vector3(0.065f, 0.065f, 0.035f);
				Collider component = _gemObject.GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
			}
			else
			{
				_gemObject = ((Component)val3).gameObject;
			}
			MeshRenderer component2 = _gemObject.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)_demisterBallMaterialTemplate != (Object)null)
			{
				if ((Object)(object)_gemMaterial == (Object)null)
				{
					_gemMaterial = new Material(_demisterBallMaterialTemplate);
					((Object)_gemMaterial).name = "LockGemMat_" + TierPrefabName;
				}
				((Renderer)component2).sharedMaterial = _gemMaterial;
			}
			Transform val4 = val2.transform.Find("LockFlare");
			GameObject val5 = null;
			if ((Object)(object)val4 == (Object)null && (Object)(object)_flareTemplate != (Object)null)
			{
				val5 = Object.Instantiate<GameObject>(_flareTemplate, val2.transform, false);
				((Object)val5).name = "LockFlare";
				val5.transform.localPosition = Vector3.zero;
				val5.transform.localRotation = Quaternion.identity;
				Light[] componentsInChildren = val5.GetComponentsInChildren<Light>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren[i]);
				}
				AudioSource[] componentsInChildren2 = val5.GetComponentsInChildren<AudioSource>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren2[i]);
				}
			}
			else if ((Object)(object)val4 != (Object)null)
			{
				val5 = ((Component)val4).gameObject;
			}
			if ((Object)(object)val5 != (Object)null)
			{
				_flareParticles = val5.GetComponent<ParticleSystem>();
				if ((Object)(object)_flareParticles != (Object)null)
				{
					MainModule main = _flareParticles.main;
					((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0;
					((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.22f);
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).playOnAwake = true;
				}
			}
			_pointLight = val2.GetComponent<Light>();
			if ((Object)(object)_pointLight == (Object)null)
			{
				_pointLight = val2.AddComponent<Light>();
			}
			_pointLight.type = (LightType)2;
			_pointLight.renderMode = (LightRenderMode)1;
			_pointLight.shadows = (LightShadows)0;
			_pointLight.range = 2.4f;
			_pointLight.intensity = 1.6f;
			_pointLight.color = GlowColor;
			ApplyCurrentSettings();
		}

		private void UpdateLockRootScale()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_lockRoot == (Object)null))
			{
				Vector3 localScale = ((Component)this).transform.localScale;
				if (Mathf.Abs(localScale.x) > 0.0001f && Mathf.Abs(localScale.y) > 0.0001f && Mathf.Abs(localScale.z) > 0.0001f)
				{
					_lockRoot.localScale = new Vector3(1f / localScale.x, 1f / localScale.y, 1f / localScale.z);
				}
			}
		}

		public void ApplyCurrentSettings()
		{
			//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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_lockRoot == (Object)null)
			{
				Transform val = ((Component)this).transform.Find("LockRoot") ?? ((Component)this).transform.Find("LockGlowLight");
				if ((Object)(object)val != (Object)null)
				{
					_lockRoot = val;
				}
			}
			if ((Object)(object)_lockRoot != (Object)null && !string.IsNullOrEmpty(TierPrefabName))
			{
				GlowColor = GetLockColor(TierPrefabName);
				_lockRoot.localPosition = GetLockLocalOffset(TierPrefabName);
				UpdateLockRootScale();
			}
			bool num = ModConfig.EnableChestGlow != null && ModConfig.EnableChestGlow.Value;
			float num2 = ((ModConfig.ChestGlowIntensity != null) ? ModConfig.ChestGlowIntensity.Value : 1f);
			bool flag = num && num2 > 0.01f;
			if ((Object)(object)_pointLight != (Object)null)
			{
				_pointLight.color = GlowColor;
				_pointLight.range = 2.4f;
				_pointLight.intensity = 1.6f * num2;
				((Behaviour)_pointLight).enabled = flag;
			}
			if ((Object)(object)_gemMaterial != (Object)null)
			{
				_gemMaterial.SetColor("_Color", GlowColor);
				if (flag)
				{
					_gemMaterial.EnableKeyword("_EMISSION");
					_gemMaterial.SetColor("_EmissionColor", GlowColor * (2.2f * num2));
				}
				else
				{
					_gemMaterial.DisableKeyword("_EMISSION");
					_gemMaterial.SetColor("_EmissionColor", Color.black);
				}
			}
			if ((Object)(object)_gemObject != (Object)null)
			{
				_gemObject.SetActive(flag);
			}
			if ((Object)(object)_flareParticles != (Object)null)
			{
				if (flag)
				{
					MainModule main = _flareParticles.main;
					float num3 = ((GlowColor.a > 0.01f) ? (GlowColor.a * 0.8f) : 0.8f);
					((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(GlowColor.r, GlowColor.g, GlowColor.b, num3 * num2));
					_flareParticles.Stop(true, (ParticleSystemStopBehavior)0);
					_flareParticles.Play();
				}
				else if (_flareParticles.isPlaying)
				{
					_flareParticles.Stop(true, (ParticleSystemStopBehavior)0);
				}
			}
		}

		public static void RefreshAll()
		{
			foreach (ChestGlowController activeController in _activeControllers)
			{
				if ((Object)(object)activeController != (Object)null)
				{
					activeController.ApplyCurrentSettings();
				}
			}
		}
	}
	public static class ChestPieceManager
	{
		public const string Tier1ChainedPrefab = "piece_chest_chained_personal";

		public const string Tier2BronzePrefab = "piece_chest_finewood_personal";

		public const string Tier3IronboundPrefab = "piece_chest_reinforced_personal";

		public const string Tier4SilverPrefab = "piece_chest_dvergr_sm_personal";

		public const string Tier5ClockworkPrefab = "piece_chest_dvergr_lg_personal";

		public const string Tier6FlametalPrefab = "piece_chest_charred_personal";

		public const string Tier7ReliquaryPrefab = "piece_chest_ancient_personal";

		public const string DefaultCategoryName = "Personal Chests";

		public const string NativePersonalChestDonor = "piece_chest_private";

		public const string NativeChainedDonor = "TreasureChest_morkhalla";

		public const string NativeReinforcedDonor = "piece_chest";

		public const string NativeSmallDvergrDonor = "TreasureChest_dvergrtower";

		public const string NativeLargeDvergrDonor = "TreasureChest_dvergrtown";

		public const string NativeCharredDonor = "TreasureChest_charredfortress";

		public const string NativeAncientDonor = "Morkhalla_ChestAncient";

		public static readonly Color ColorChained = new Color(0.824f, 0.655f, 0f);

		public static readonly Color ColorBronze = new Color(0f, 0.667f, 0.224f);

		public static readonly Color ColorIronbound = new Color(1f, 0.475f, 0f);

		public static readonly Color ColorSilver = new Color(0.89f, 0.376f, 0.906f);

		public static readonly Color ColorClockwork = new Color(0.137f, 0.349f, 1f);

		public static readonly Color ColorFlametal = new Color(1f, 0f, 0f);

		public static readonly Color ColorReliquary = new Color(0.792f, 1f, 1f);

		private static bool _piecesRegistered;

		private static Sprite? _cachedContainerBkg;

		public static string GetConfiguredCategoryName()
		{
			string text = ModConfig.PieceCategory?.Value?.Trim() ?? string.Empty;
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return "Personal Chests";
		}

		public static PieceCategory GetConfiguredPieceCategory()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return PieceManager.Instance.AddPieceCategory(GetConfiguredCategoryName());
		}

		public static float GetTierScaleMultiplier(string prefabName)
		{
			return prefabName switch
			{
				"piece_chest_chained_personal" => 0.3f, 
				"piece_chest_finewood_personal" => 0.9f, 
				"piece_chest_reinforced_personal" => 0.6f, 
				"piece_chest_dvergr_sm_personal" => 1.1f, 
				"piece_chest_dvergr_lg_personal" => 1.2f, 
				"piece_chest_charred_personal" => 0.95f, 
				"piece_chest_ancient_personal" => 0.9f, 
				_ => 1f, 
			};
		}

		public static Color GetDefaultTierColor(string prefabName)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(prefabName switch
			{
				"piece_chest_chained_personal" => ColorChained, 
				"piece_chest_finewood_personal" => ColorBronze, 
				"piece_chest_reinforced_personal" => ColorIronbound, 
				"piece_chest_dvergr_sm_personal" => ColorSilver, 
				"piece_chest_dvergr_lg_personal" => ColorClockwork, 
				"piece_chest_charred_personal" => ColorFlametal, 
				"piece_chest_ancient_personal" => ColorReliquary, 
				_ => Color.white, 
			});
		}

		public static void Initialize()
		{
			PrefabManager.OnVanillaPrefabsAvailable += RegisterCustomPieces;
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
			ModConfig.ChainedRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_chained_personal");
			};
			ModConfig.ChainedCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_chained_personal");
			};
			ModConfig.ChainedHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_chained_personal");
			};
			ModConfig.ChainedWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_chained_personal");
			};
			ModConfig.ChainedHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_chained_personal");
			};
			ModConfig.BronzeRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_finewood_personal");
			};
			ModConfig.BronzeCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_finewood_personal");
			};
			ModConfig.BronzeHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_finewood_personal");
			};
			ModConfig.BronzeWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_finewood_personal");
			};
			ModConfig.BronzeHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_finewood_personal");
			};
			ModConfig.IronboundRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_reinforced_personal");
			};
			ModConfig.IronboundCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_reinforced_personal");
			};
			ModConfig.IronboundHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_reinforced_personal");
			};
			ModConfig.IronboundWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_reinforced_personal");
			};
			ModConfig.IronboundHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_reinforced_personal");
			};
			ModConfig.SilverRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			};
			ModConfig.SilverCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			};
			ModConfig.SilverHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			};
			ModConfig.SilverWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			};
			ModConfig.SilverHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			};
			ModConfig.ClockworkRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			};
			ModConfig.ClockworkCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			};
			ModConfig.ClockworkHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			};
			ModConfig.ClockworkWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			};
			ModConfig.ClockworkHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			};
			ModConfig.FlametalRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_charred_personal");
			};
			ModConfig.FlametalCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_charred_personal");
			};
			ModConfig.FlametalHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_charred_personal");
			};
			ModConfig.FlametalWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_charred_personal");
			};
			ModConfig.FlametalHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_charred_personal");
			};
			ModConfig.ReliquaryRecipe.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_ancient_personal");
			};
			ModConfig.ReliquaryCraftingStation.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_ancient_personal");
			};
			ModConfig.ReliquaryHealth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_ancient_personal");
			};
			ModConfig.ReliquaryWidth.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_ancient_personal");
			};
			ModConfig.ReliquaryHeight.SettingChanged += delegate
			{
				UpdatePieceConfiguration("piece_chest_ancient_personal");
			};
			ModConfig.PieceCategory.SettingChanged += delegate
			{
				UpdateAllPieceCategories();
			};
			ModConfig.EnableChestGlow.SettingChanged += delegate
			{
				ChestGlowController.RefreshAll();
			};
			ModConfig.ChestGlowIntensity.SettingChanged += delegate
			{
				ChestGlowController.RefreshAll();
			};
			Plugin.LogDebug("[PieceManager] Subscribed to vanilla prefab events and config change listeners.");
		}

		private static void RegisterCustomPieces()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			if (!_piecesRegistered)
			{
				_piecesRegistered = true;
				Plugin.LogDebug("[PieceManager] RegisterCustomPieces triggered.");
				RegisterChestPiece("piece_chest_chained_personal", "TreasureChest_morkhalla", "$piece_chest_chained_personal", "$piece_chest_chained_personal_desc", ColorChained, ModConfig.ChainedRecipe.Value, (string)((ConfigEntryBase)ModConfig.ChainedRecipe).DefaultValue, ModConfig.ChainedCraftingStation.Value, ModConfig.ChainedWidth.Value, ModConfig.ChainedHeight.Value, ModConfig.ChainedHealth.Value);
				RegisterChestPiece("piece_chest_finewood_personal", "piece_chest_private", "$piece_chest_finewood_personal", "$piece_chest_finewood_personal_desc", ColorBronze, ModConfig.BronzeRecipe.Value, (string)((ConfigEntryBase)ModConfig.BronzeRecipe).DefaultValue, ModConfig.BronzeCraftingStation.Value, ModConfig.BronzeWidth.Value, ModConfig.BronzeHeight.Value, ModConfig.BronzeHealth.Value);
				RegisterChestPiece("piece_chest_reinforced_personal", "piece_chest", "$piece_chest_reinforced_personal", "$piece_chest_reinforced_personal_desc", ColorIronbound, ModConfig.IronboundRecipe.Value, (string)((ConfigEntryBase)ModConfig.IronboundRecipe).DefaultValue, ModConfig.IronboundCraftingStation.Value, ModConfig.IronboundWidth.Value, ModConfig.IronboundHeight.Value, ModConfig.IronboundHealth.Value);
				RegisterChestPiece("piece_chest_dvergr_sm_personal", "TreasureChest_dvergrtower", "$piece_chest_dvergr_sm_personal", "$piece_chest_dvergr_sm_personal_desc", ColorSilver, ModConfig.SilverRecipe.Value, (string)((ConfigEntryBase)ModConfig.SilverRecipe).DefaultValue, ModConfig.SilverCraftingStation.Value, ModConfig.SilverWidth.Value, ModConfig.SilverHeight.Value, ModConfig.SilverHealth.Value);
				RegisterChestPiece("piece_chest_dvergr_lg_personal", "TreasureChest_dvergrtown", "$piece_chest_dvergr_lg_personal", "$piece_chest_dvergr_lg_personal_desc", ColorClockwork, ModConfig.ClockworkRecipe.Value, (string)((ConfigEntryBase)ModConfig.ClockworkRecipe).DefaultValue, ModConfig.ClockworkCraftingStation.Value, ModConfig.ClockworkWidth.Value, ModConfig.ClockworkHeight.Value, ModConfig.ClockworkHealth.Value);
				RegisterChestPiece("piece_chest_charred_personal", "TreasureChest_charredfortress", "$piece_chest_charred_personal", "$piece_chest_charred_personal_desc", ColorFlametal, ModConfig.FlametalRecipe.Value, (string)((ConfigEntryBase)ModConfig.FlametalRecipe).DefaultValue, ModConfig.FlametalCraftingStation.Value, ModConfig.FlametalWidth.Value, ModConfig.FlametalHeight.Value, ModConfig.FlametalHealth.Value);
				RegisterChestPiece("piece_chest_ancient_personal", "Morkhalla_ChestAncient", "$piece_chest_ancient_personal", "$piece_chest_ancient_personal_desc", ColorReliquary, ModConfig.ReliquaryRecipe.Value, (string)((ConfigEntryBase)ModConfig.ReliquaryRecipe).DefaultValue, ModConfig.ReliquaryCraftingStation.Value, ModConfig.ReliquaryWidth.Value, ModConfig.ReliquaryHeight.Value, ModConfig.ReliquaryHealth.Value);
				PrefabManager.OnVanillaPrefabsAvailable -= RegisterCustomPieces;
			}
		}

		private static void RegisterChestPiece(string customPrefabName, string donorPrefabName, string nameToken, string descToken, Color glowColor, string recipeString, string defaultRecipeString, string stationString, int width, int height, float health)
		{
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Expected O, but got Unknown
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			if (!TryParseAndValidateRecipe(recipeString, customPrefabName, out RequirementConfig[] requirements))
			{
				Plugin.Log.LogError((object)("[PieceManager] Recipe for '" + customPrefabName + "' is invalid ('" + recipeString + "'). Falling back to default: '" + defaultRecipeString + "'."));
				if (!TryParseAndValidateRecipe(defaultRecipeString, customPrefabName, out requirements))
				{
					Plugin.Log.LogError((object)("[PieceManager] Default recipe for '" + customPrefabName + "' is also invalid. Aborting piece registration."));
					return;
				}
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(customPrefabName, donorPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)("[PieceManager] Failed to clone donor prefab '" + donorPrefabName + "' as '" + customPrefabName + "'."));
				return;
			}
			if (customPrefabName == "piece_chest_dvergr_lg_personal" || customPrefabName == "piece_chest_ancient_personal")
			{
				RotateChildren180(val);
			}
			float tierScaleMultiplier = GetTierScaleMultiplier(customPrefabName);
			Transform transform = val.transform;
			transform.localScale *= tierScaleMultiplier;
			Plugin.LogDebug($"[PieceManager] Scaled '{customPrefabName}' by {tierScaleMultiplier:F3}x.");
			ZNetView val2 = val.GetComponent<ZNetView>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<ZNetView>();
			}
			val2.m_syncInitialScale = true;
			Piece val3 = val.GetComponent<Piece>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = val.AddComponent<Piece>();
			}
			val3.m_name = nameToken;
			val3.m_description = descToken;
			val3.m_canBeRemoved = true;
			string configuredCategoryName = GetConfiguredCategoryName();
			val3.m_category = PieceManager.Instance.AddPieceCategory(configuredCategoryName);
			val3.m_placeEffect = ChestAudioEffectManager.GetPlaceEffects(customPrefabName);
			Container val4 = val.GetComponentInChildren<Container>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val.AddComponent<Container>();
			}
			val4.m_name = nameToken;
			val4.m_privacy = (PrivacySetting)0;
			val4.m_checkGuardStone = false;
			val4.m_autoDestroyEmpty = false;
			val4.m_defaultItems = new DropTable();
			val4.m_width = width;
			val4.m_height = height;
			if ((Object)(object)_cachedContainerBkg == (Object)null)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_private");
				_cachedContainerBkg = ((prefab == null) ? null : prefab.GetComponentInChildren<Container>()?.m_bkg);
			}
			if ((Object)(object)_cachedContainerBkg != (Object)null)
			{
				val4.m_bkg = _cachedContainerBkg;
			}
			RebindContainerVisuals(val, val4);
			val4.m_openEffects = ChestAudioEffectManager.GetOpenEffects(customPrefabName);
			val4.m_closeEffects = ChestAudioEffectManager.GetCloseEffects(customPrefabName);
			if (customPrefabName == "piece_chest_charred_personal")
			{
				FixTier6Materials(val);
			}
			WearNTear obj = val.GetComponent<WearNTear>() ?? val.GetComponentInChildren<WearNTear>() ?? val.AddComponent<WearNTear>();
			obj.m_health = health;
			obj.m_noRoofWear = true;
			obj.m_noSupportWear = true;
			obj.m_hitEffect = ChestAudioEffectManager.GetHitEffects(customPrefabName);
			obj.m_destroyedEffect = ChestAudioEffectManager.GetDestroyEffects(customPrefabName);
			FixPieceLayers(val);
			ChestGlowController chestGlowController = val.GetComponent<ChestGlowController>();
			if ((Object)(object)chestGlowController == (Object)null)
			{
				chestGlowController = val.AddComponent<ChestGlowController>();
			}
			chestGlowController.Configure(customPrefabName, glowColor);
			try
			{
				Sprite val5 = RenderManager.Instance.Render(val);
				if ((Object)(object)val5 != (Object)null)
				{
					val3.m_icon = val5;
					Plugin.LogDebug("[PieceManager] Generated 3D snapshot icon for '" + customPrefabName + "'.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[PieceManager] Failed to render 3D icon for '" + customPrefabName + "': " + ex.Message));
			}
			PieceConfig val6 = new PieceConfig();
			val6.Name = nameToken;
			val6.Description = descToken;
			val6.PieceTable = PieceTables.Hammer;
			val6.Category = configuredCategoryName;
			val6.Usage = new string[2]
			{
				PieceUsages.Storage,
				PieceUsages.Furniture
			};
			val6.CraftingStation = stationString;
			val6.Requirements = requirements;
			PieceConfig val7 = val6;
			CustomPiece val8 = new CustomPiece(val, true, val7);
			PieceManager.Instance.AddPiece(val8);
			Plugin.LogDebug("[PieceManager] Successfully registered CustomPiece '" + customPrefabName + "' in Hammer.");
		}

		private static void FixPieceLayers(GameObject prefab)
		{
			int num = LayerMask.NameToLayer("piece");
			if (num < 0)
			{
				num = 0;
			}
			prefab.layer = num;
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!val.isTrigger)
				{
					((Component)val).gameObject.layer = num;
				}
			}
		}

		private static void RebindContainerVisuals(GameObject clonedGameObject, Container container)
		{
			if ((Object)(object)container.m_open != (Object)null && container.m_open.transform.IsChildOf(clonedGameObject.transform) && (Object)(object)container.m_closed != (Object)null && container.m_closed.transform.IsChildOf(clonedGameObject.transform))
			{
				return;
			}
			GameObject val = null;
			GameObject val2 = null;
			Transform[] componentsInChildren = clonedGameObject.GetComponentsInChildren<Transform>(true);
			foreach (Transform val3 in componentsInChildren)
			{
				if (!((Object)(object)((Component)val3).gameObject == (Object)(object)clonedGameObject))
				{
					string text = ((Object)val3).name.ToLowerInvariant();
					if ((Object)(object)val == (Object)null && (text.EndsWith("_open") || text == "open" || text.EndsWith("top_open")))
					{
						val = ((Component)val3).gameObject;
					}
					if ((Object)(object)val2 == (Object)null && (text.EndsWith("_closed") || text == "closed" || text.EndsWith("top_closed")))
					{
						val2 = ((Component)val3).gameObject;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				container.m_open = val;
				container.m_open.SetActive(false);
				Plugin.LogDebug("[PieceManager] Repaired container.m_open to '" + ((Object)val).name + "' on '" + ((Object)clonedGameObject).name + "'.");
			}
			else
			{
				Plugin.Log.LogWarning((object)("[PieceManager] Could not find open visual for '" + ((Object)clonedGameObject).name + "'."));
			}
			if ((Object)(object)val2 != (Object)null)
			{
				container.m_closed = val2;
				container.m_closed.SetActive(true);
				Plugin.LogDebug("[PieceManager] Repaired container.m_closed to '" + ((Object)val2).name + "' on '" + ((Object)clonedGameObject).name + "'.");
			}
			else
			{
				Plugin.Log.LogWarning((object)("[PieceManager] Could not find closed visual for '" + ((Object)clonedGameObject).name + "'."));
			}
		}

		public static Bounds GetRendererBounds(GameObject prefab)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			bool flag = false;
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (val is MeshRenderer || val is SkinnedMeshRenderer)
				{
					if (!flag)
					{
						result = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val.bounds);
					}
				}
			}
			return result;
		}

		private static void OnPiecesRegistered()
		{
			Plugin.LogDebug("[PieceManager] OnPiecesRegistered triggered. Updating piece recipes and stations.");
			UpdateAllPieceConfigurations();
		}

		public static void UpdateAllPieceConfigurations()
		{
			UpdatePieceConfiguration("piece_chest_chained_personal");
			UpdatePieceConfiguration("piece_chest_finewood_personal");
			UpdatePieceConfiguration("piece_chest_reinforced_personal");
			UpdatePieceConfiguration("piece_chest_dvergr_sm_personal");
			UpdatePieceConfiguration("piece_chest_dvergr_lg_personal");
			UpdatePieceConfiguration("piece_chest_charred_personal");
			UpdatePieceConfiguration("piece_chest_ancient_personal");
		}

		public static void UpdateAllPieceCategories()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			string configuredCategoryName = GetConfiguredCategoryName();
			PieceCategory category = PieceManager.Instance.AddPieceCategory(configuredCategoryName);
			string[] array = new string[7] { "piece_chest_chained_personal", "piece_chest_finewood_personal", "piece_chest_reinforced_personal", "piece_chest_dvergr_sm_personal", "piece_chest_dvergr_lg_personal", "piece_chest_charred_personal", "piece_chest_ancient_personal" };
			foreach (string text in array)
			{
				CustomPiece piece = PieceManager.Instance.GetPiece(text);
				if ((Object)(object)((piece != null) ? piece.PiecePrefab : null) != (Object)null)
				{
					Piece component = piece.PiecePrefab.GetComponent<Piece>();
					if ((Object)(object)component != (Object)null)
					{
						component.m_category = category;
					}
				}
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				Player.m_localPlayer.UpdateAvailablePiecesList();
			}
			Plugin.LogDebug("[PieceManager] Updated piece category to '" + configuredCategoryName + "' in real time.");
		}

		public static void UpdatePieceConfiguration(string prefabName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "main")
			{
				string[] obj = new string[5] { "[PieceManager] Active scene is '", null, null, null, null };
				activeScene = SceneManager.GetActiveScene();
				obj[1] = ((Scene)(ref activeScene)).name;
				obj[2] = "'. Deferring piece update for '";
				obj[3] = prefabName;
				obj[4] = "' until world loads.";
				Plugin.LogDebug(string.Concat(obj));
				return;
			}
			CustomPiece piece = PieceManager.Instance.GetPiece(prefabName);
			if (piece == null || (Object)(object)piece.PiecePrefab == (Object)null)
			{
				Plugin.LogDebug("[PieceManager] CustomPiece '" + prefabName + "' not found in registry for config update.");
			}
			else
			{
				if (!TryGetPieceConfig(prefabName, out string recipeString, out string stationString, out int width, out int height, out float health))
				{
					return;
				}
				Piece component = piece.PiecePrefab.GetComponent<Piece>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_category = GetConfiguredPieceCategory();
				}
				if (TryParseAndValidateRecipe(recipeString, prefabName, out RequirementConfig[] requirements))
				{
					List<Requirement> list = new List<Requirement>();
					RequirementConfig[] array = requirements;
					foreach (RequirementConfig val in array)
					{
						GameObject prefab = PrefabManager.Instance.GetPrefab(val.Item);
						ItemDrop val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
						if ((Object)(object)val2 != (Object)null)
						{
							list.Add(new Requirement
							{
								m_resItem = val2,
								m_amount = val.Amount,
								m_amountPerLevel = val.AmountPerLevel,
								m_recover = val.Recover
							});
						}
						else
						{
							Plugin.Log.LogError((object)("[PieceManager] Could not resolve ItemDrop for requirement '" + val.Item + "' on piece '" + prefabName + "'."));
						}
					}
					if ((Object)(object)component != (Object)null)
					{
						component.m_resources = list.ToArray();
					}
				}
				if ((Object)(object)component != (Object)null)
				{
					string internalName = CraftingStations.GetInternalName(stationString);
					if (string.IsNullOrEmpty(internalName) || internalName.Equals("None", StringComparison.OrdinalIgnoreCase))
					{
						component.m_craftingStation = null;
					}
					else
					{
						GameObject prefab2 = PrefabManager.Instance.GetPrefab(internalName);
						if ((Object)(object)prefab2 != (Object)null)
						{
							component.m_craftingStation = prefab2.GetComponent<CraftingStation>();
						}
						else
						{
							Plugin.Log.LogWarning((object)("[PieceManager] Station prefab '" + internalName + "' not found for piece '" + prefabName + "'."));
							component.m_craftingStation = null;
						}
					}
				}
				Container component2 = piece.PiecePrefab.GetComponent<Container>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.m_width = width;
					component2.m_height = height;
				}
				WearNTear component3 = piece.PiecePrefab.GetComponent<WearNTear>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.m_health = health;
				}
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					Player.m_localPlayer.UpdateKnownRecipesList();
					Player.m_localPlayer.UpdateAvailablePiecesList();
				}
				Plugin.LogDebug("[PieceManager] Updated '" + prefabName + "' configuration in real time.");
			}
		}

		public static bool TryGetPieceConfig(string prefabName, out string recipeString, out string stationString, out int width, out int height, out float health)
		{
			switch (prefabName)
			{
			case "piece_chest_chained_personal":
				recipeString = ModConfig.ChainedRecipe.Value;
				stationString = ModConfig.ChainedCraftingStation.Value;
				width = ModConfig.ChainedWidth.Value;
				height = ModConfig.ChainedHeight.Value;
				health = ModConfig.ChainedHealth.Value;
				return true;
			case "piece_chest_finewood_personal":
				recipeString = ModConfig.BronzeRecipe.Value;
				stationString = ModConfig.BronzeCraftingStation.Value;
				width = ModConfig.BronzeWidth.Value;
				height = ModConfig.BronzeHeight.Value;
				health = ModConfig.BronzeHealth.Value;
				return true;
			case "piece_chest_reinforced_personal":
				recipeString = ModConfig.IronboundRecipe.Value;
				stationString = ModConfig.IronboundCraftingStation.Value;
				width = ModConfig.IronboundWidth.Value;
				height = ModConfig.IronboundHeight.Value;
				health = ModConfig.IronboundHealth.Value;
				return true;
			case "piece_chest_dvergr_sm_personal":
				recipeString = ModConfig.SilverRecipe.Value;
				stationString = ModConfig.SilverCraftingStation.Value;
				width = ModConfig.SilverWidth.Value;
				height = ModConfig.SilverHeight.Value;
				health = ModConfig.SilverHealth.Value;
				return true;
			case "piece_chest_dvergr_lg_personal":
				recipeString = ModConfig.ClockworkRecipe.Value;
				stationString = ModConfig.ClockworkCraftingStation.Value;
				width = ModConfig.ClockworkWidth.Value;
				height = ModConfig.ClockworkHeight.Value;
				health = ModConfig.ClockworkHealth.Value;
				return true;
			case "piece_chest_charred_personal":
				recipeString = ModConfig.FlametalRecipe.Value;
				stationString = ModConfig.FlametalCraftingStation.Value;
				width = ModConfig.FlametalWidth.Value;
				height = ModConfig.FlametalHeight.Value;
				health = ModConfig.FlametalHealth.Value;
				return true;
			case "piece_chest_ancient_personal":
				recipeString = ModConfig.ReliquaryRecipe.Value;
				stationString = ModConfig.ReliquaryCraftingStation.Value;
				width = ModConfig.ReliquaryWidth.Value;
				height = ModConfig.ReliquaryHeight.Value;
				health = ModConfig.ReliquaryHealth.Value;
				return true;
			default:
				recipeString = string.Empty;
				stationString = string.Empty;
				width = 3;
				height = 2;
				health = 100f;
				return false;
			}
		}

		public static bool IsValidItemPrefab(string itemName)
		{
			if (string.IsNullOrWhiteSpace(itemName))
			{
				return false;
			}
			if (itemName.Equals("<PrefabName>", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			GameObject val = ((PrefabManager.Instance != null) ? PrefabManager.Instance.GetPrefab(itemName) : null);
			if ((Object)(object)val != (Object)null)
			{
				return (Object)(object)val.GetComponent<ItemDrop>() != (Object)null;
			}
			return false;
		}

		public static bool TryParseAndValidateRecipe(string recipeString, string pieceName, out RequirementConfig[] requirements)
		{
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			requirements = Array.Empty<RequirementConfig>();
			if (string.IsNullOrWhiteSpace(recipeString))
			{
				Plugin.Log.LogError((object)("[PieceManager] Recipe for piece '" + pieceName + "' is empty or whitespace."));
				return false;
			}
			List<RecipeConfigDrawer.RecipeItemEntry> list = RecipeConfigDrawer.Deserialize(recipeString);
			if (list.Count == 0)
			{
				Plugin.Log.LogError((object)("[PieceManager] Recipe for piece '" + pieceName + "' contained no requirement entries."));
				return false;
			}
			List<RequirementConfig> list2 = new List<RequirementConfig>();
			foreach (RecipeConfigDrawer.RecipeItemEntry item in list)
			{
				if (string.IsNullOrWhiteSpace(item.PrefabName))
				{
					Plugin.Log.LogError((object)("[PieceManager] Recipe for piece '" + pieceName + "' contains an empty prefab name."));
					return false;
				}
				if (item.PrefabName.Equals("<PrefabName>", StringComparison.OrdinalIgnoreCase))
				{
					Plugin.Log.LogError((object)("[PieceManager] Recipe for piece '" + pieceName + "' contains unconfigured placeholder '<PrefabName>'."));
					return false;
				}
				if (item.Amount <= 0)
				{
					Plugin.Log.LogError((object)$"[PieceManager] Requirement '{item.PrefabName}' for piece '{pieceName}' has invalid amount {item.Amount}.");
					return false;
				}
				if (PrefabManager.Instance != null && !IsValidItemPrefab(item.PrefabName))
				{
					Plugin.Log.LogError((object)("[PieceManager] Requirement '" + item.PrefabName + "' for piece '" + pieceName + "' does not exist in ObjectDB/PrefabManager."));
					return false;
				}
				list2.Add(new RequirementConfig(item.PrefabName, item.Amount, 0, true));
			}
			requirements = list2.ToArray();
			return true;
		}

		private static void RotateChildren180(GameObject prefab)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0030: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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)
			Quaternion val = Quaternion.Euler(0f, 180f, 0f);
			foreach (Transform item in prefab.transform)
			{
				Transform val2 = item;
				val2.localPosition = val * val2.localPosition;
				val2.localRotation = val * val2.localRotation;
			}
			Plugin.LogDebug("[PieceManager] Rotated child hierarchy 180 degrees around Y for '" + ((Object)prefab).name + "'.");
		}

		private static void FixTier6Materials(GameObject prefab)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			Shader shader = ((Renderer)PrefabManager.Instance.GetPrefab("piece_chest_private").GetComponentInChildren<MeshRenderer>()).sharedMaterial.shader;
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				Material sharedMaterial = ((Renderer)val).sharedMaterial;
				if (!((Object)(object)sharedMaterial == (Object)null))
				{
					Material val2 = new Material(sharedMaterial)
					{
						shader = shader
					};
					Texture texture = sharedMaterial.GetTexture("_EmissiveTex");
					val2.SetTexture("_EmissionMap", texture);
					val2.SetTexture("_EmissiveTex", texture);
					val2.SetColor("_EmissionColor", sharedMaterial.GetColor("_EmissionColor"));
					val2.EnableKeyword("_EMISSION");
					((Renderer)val).sharedMaterials = (Material[])(object)new Material[1] { val2 };
				}
			}
		}
	}
}
namespace PersonalChestHeeler.Patches
{
	public static class ContainerPatches
	{
		[HarmonyPatch(typeof(Container), "CheckAccess")]
		public static class Container_CheckAccess_Patch
		{
			[HarmonyPrefix]
			public static bool Prefix(Container __instance, long playerID, ref bool __result)
			{
				if (ModConfig.EnableMod == null || !ModConfig.EnableMod.Value)
				{
					return true;
				}
				if (ModConfig.AdminBypassesLock != null && ModConfig.AdminBypassesLock.Value && SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin)
				{
					__result = true;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		public static class Container_GetHoverText_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(Container __instance, ref string __result)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				if (ModConfig.EnableMod == null || !ModConfig.EnableMod.Value || (int)__instance.m_privacy != 0)
				{
					return;
				}
				Piece component = ((Component)__instance).GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				long creator = component.GetCreator();
				if (creator == 0L || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Game.instance == (Object)null)
				{
					return;
				}
				long playerID = Game.instance.GetPlayerProfile().GetPlayerID();
				bool num = creator == playerID;
				bool flag = SynchronizationManager.Instance != null && SynchronizationManager.Instance.PlayerIsAdmin;
				string text2;
				if (num)
				{
					string text = ModLocalization.Localize("$prompt_chest_owned_status");
					text2 = "\n[<color=#55FF55>" + text + "</color>]";
				}
				else
				{
					string text3 = ModLocalization.Localize("$prompt_chest_locked_status");
					text2 = "\n[<color=#FF5555>" + text3 + "</color>]";
					if (flag && ModConfig.AdminBypassesLock != null && ModConfig.AdminBypassesLock.Value)
					{
						text2 += " <color=#FFFF55>(Admin Bypass)</color>";
					}
				}
				__result += text2;
			}
		}
	}
}
namespace PersonalChestHeeler.Localization
{
	public static class ModLocalization
	{
		public const string TokenPieceChestChained = "$piece_chest_chained_personal";

		public const string TokenPieceChestChainedDesc = "$piece_chest_chained_personal_desc";

		public const string TokenPieceChestBronze = "$piece_chest_finewood_personal";

		public const string TokenPieceChestBronzeDesc = "$piece_chest_finewood_personal_desc";

		public const string TokenPieceChestIronbound = "$piece_chest_reinforced_personal";

		public const string TokenPieceChestIronboundDesc = "$piece_chest_reinforced_personal_desc";

		public const string TokenPieceChestSilver = "$piece_chest_dvergr_sm_personal";

		public const string TokenPieceChestSilverDesc = "$piece_chest_dvergr_sm_personal_desc";

		public const string TokenPieceChestClockwork = "$piece_chest_dvergr_lg_personal";

		public const string TokenPieceChestClockworkDesc = "$piece_chest_dvergr_lg_personal_desc";

		public const string TokenPieceChestFlametal = "$piece_chest_charred_personal";

		public const string TokenPieceChestFlametalDesc = "$piece_chest_charred_personal_desc";

		public const string TokenPieceChestReliquary = "$piece_chest_ancient_personal";

		public const string TokenPieceChestReliquaryDesc = "$piece_chest_ancient_personal_desc";

		public const string TokenPromptChestOwnerStatus = "$prompt_chest_owner_status";

		public const string TokenPromptChestLockedStatus = "$prompt_chest_locked_status";

		public const string TokenPromptChestOwnedStatus = "$prompt_chest_owned_status";

		public static void Initialize()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "$piece_chest_chained_personal", "Chained Lockbox" },
				{ "$piece_chest_chained_personal_desc", "A rustic lockbox hewn from raw timber, sealed with pine resin and locked behind primitive copper and tin latches with a watchful Greydwarf eye." },
				{ "$piece_chest_finewood_personal", "Bronze Trussed Chest" },
				{ "$piece_chest_finewood_personal_desc", "A sturdy chest built from split core wood logs and trussed with forged bronze bands, caulked with swamp ooze, pegged with carved bone tumblers, and chilled by an ethereal ectoplasm ward." },
				{ "$piece_chest_reinforced_personal", "Ironbound Strongbox" },
				{ "$piece_chest_reinforced_personal_desc", "A heavy strongbox crafted from rot-resistant ancient bark and reinforced with wrought iron bands, sealed with glowing guck, locked behind serrated wolf-fang catches, and stoked by a smoldering surtling core." },
				{ "$piece_chest_dvergr_sm_personal", "Ornate Silver Coffer" },
				{ "$piece_chest_dvergr_sm_personal_desc", "An ornate coffer crafted from polished fine wood and chased with silver bands, weather-sealed in dark tar, cushioned with woven linen, and snapped shut with a spring-loaded wolf claw catch." },
				{ "$piece_chest_dvergr_lg_personal", "Dvergr Clockwork Vault" },
				{ "$piece_chest_dvergr_lg_personal_desc", "A complex mechanical vault built from sacred Yggdrasil timber and armored in black metal, preserved in tree sap, driven by clockwork springs, and energized by pulsing eitr." },
				{ "$piece_chest_charred_personal", "Charred Flametal Safehold" },
				{ "$piece_chest_charred_personal_desc", "A scorching safehold framed with dense blackwood beams and plated in forged flametal, insulated by ceramic tiles, sealed with charcoal resin, and guided by a trapped wisp." },
				{ "$piece_chest_ancient_personal", "Ancient Morkhalla Reliquary" },
				{ "$piece_chest_ancient_personal_desc", "A monumental reliquary sculpted from heavy Grausten slabs and glacial frostwood, inlaid with gleaming gold, mortared with caustic Morkhalla bile, and consecrated around an ancient memorial coal." },
				{ "$prompt_chest_owner_status", "Owner: {0}" },
				{ "$prompt_chest_locked_status", "Personal Lock (Restricted)" },
				{ "$prompt_chest_owned_status", "Personal Lock (Owned)" }
			});
			Plugin.LogDebug("[ModLocalization] Default English localizations registered.");
		}

		public static string Localize(string token, params string[] arguments)
		{
			string text = LocalizationManager.Instance.GetLocalization().TryTranslate(token);
			if (arguments != null && arguments.Length != 0)
			{
				text = string.Format(text, arguments);
			}
			return text;
		}
	}
}
namespace PersonalChestHeeler.Configuration
{
	public class ConfigurationManagerAttributes
	{
		public string? DispName { get; set; }

		public bool? IsAdvanced { get; set; }

		public int? Order { get; set; }

		public bool? Browsable { get; set; }

		public bool? ReadOnly { get; set; }

		public Action<ConfigEntryBase>? CustomDrawer { get; set; }
	}
	public static class ModConfig
	{
		public static ConfigSync ConfigSync;

		public static ConfigEntry<bool> EnableMod;

		public static ConfigEntry<bool> AdminBypassesLock;

		public static ConfigEntry<string> PieceCategory;

		public static ConfigEntry<bool> EnableChestGlow;

		public static ConfigEntry<float> ChestGlowIntensity;

		public static ConfigEntry<bool> EnableDebugLogs;

		public static ConfigEntry<bool> EnableChainedChest;

		public static ConfigEntry<int> ChainedWidth;

		public static ConfigEntry<int> ChainedHeight;

		public static ConfigEntry<string> ChainedRecipe;

		public static ConfigEntry<string> ChainedCraftingStation;

		public static ConfigEntry<float> ChainedHealth;

		public static ConfigEntry<bool> EnableBronzeChest;

		public static ConfigEntry<int> BronzeWidth;

		public static ConfigEntry<int> BronzeHeight;

		public static ConfigEntry<string> BronzeRecipe;

		public static ConfigEntry<string> BronzeCraftingStation;

		public static ConfigEntry<float> BronzeHealth;

		public static ConfigEntry<bool> EnableIronboundChest;

		public static ConfigEntry<int> IronboundWidth;

		public static ConfigEntry<int> IronboundHeight;

		public static ConfigEntry<string> IronboundRecipe;

		public static ConfigEntry<string> IronboundCraftingStation;

		public static ConfigEntry<float> IronboundHealth;

		public static ConfigEntry<bool> EnableSilverChest;

		public static ConfigEntry<int> SilverWidth;

		public static ConfigEntry<int> SilverHeight;

		public static ConfigEntry<string> SilverRecipe;

		public static ConfigEntry<string> SilverCraftingStation;

		public static ConfigEntry<float> SilverHealth;

		public static ConfigEntry<bool> EnableClockworkChest;

		public static ConfigEntry<int> ClockworkWidth;

		public static ConfigEntry<int> ClockworkHeight;

		public static ConfigEntry<string> ClockworkRecipe;

		public static ConfigEntry<string> ClockworkCraftingStation;

		public static ConfigEntry<float> ClockworkHealth;

		public static ConfigEntry<bool> EnableFlametalChest;

		public static ConfigEntry<int> FlametalWidth;

		public static ConfigEntry<int> FlametalHeight;

		public static ConfigEntry<string> FlametalRecipe;

		public static ConfigEntry<string> FlametalCraftingStation;

		public static ConfigEntry<float> FlametalHealth;

		public static ConfigEntry<bool> EnableReliquaryChest;

		public static ConfigEntry<int> ReliquaryWidth;

		public static ConfigEntry<int> ReliquaryHeight;

		public static ConfigEntry<string> ReliquaryRecipe;

		public static ConfigEntry<string> ReliquaryCraftingStation;

		public static ConfigEntry<float> ReliquaryHealth;

		public static void Initialize(ConfigFile config)
		{
			//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_0015: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			ConfigSync = new ConfigSync("dreamwraith.PersonalChestHeeler")
			{
				DisplayName = "PersonalChestHeeler",
				CurrentVersion = "1.0.1",
				MinimumRequiredVersion = "1.0.1",
				ModRequired = true
			};
			EnableMod = BindSynced(config, "1 - General", "EnableMod", defaultValue: true, "Master switch to enable or disable the functionality of this mod.", 100);
			AdminBypassesLock = BindSynced(config, "1 - General", "AdminBypassesLock", defaultValue: true, "If true, server administrators bypass personal chest ownership and lock restrictions.", 90);
			PieceCategory = BindSynced(config, "1 - General", "PieceCategory", "Personal Chests", "Hammer build menu category name for all personal chests. Supports custom names or vanilla categories (Furniture, Misc, etc.).", 85);
			EnableChestGlow = BindSynced(config, "1 - General", "EnableChestGlow", defaultValue: true, "Enables subtle emissive material glow and lock point-light indicator on personal chests.", 80);
			ChestGlowIntensity = BindSynced(config, "1 - General", "ChestGlowIntensity", 1f, "Intensity multiplier for personal chest emissive glow and lock point lights (0.0 - 3.0).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(0f, 3f));
			EnableDebugLogs = BindClient(config, "1 - General", "EnableDebugLogs", defaultValue: false, "Enables verbose diagnostic logging in the BepInEx console.", 60);
			EnableChainedChest = BindSynced(config, "2 - Chest.Chained", "Chained Chest Enabled", defaultValue: true, "Enable Tier 1 Chained Lockbox (Wood/Tin/Copper/Resin/Greydwarf Eye).", 100);
			ChainedHealth = BindSynced(config, "2 - Chest.Chained", "Chained Chest Health", 250f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			ChainedHeight = BindSynced(config, "2 - Chest.Chained", "Chained Chest Inventory Height", 2, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ChainedWidth = BindSynced(config, "2 - Chest.Chained", "Chained Chest Inventory Width", 3, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ChainedCraftingStation = BindSynced(config, "2 - Chest.Chained", "Chained Chest Crafting Station", "piece_workbench", "Required crafting station (e.g. piece_workbench, forge, or empty string for hammer only).", 60);
			ChainedRecipe = BindSynced(config, "2 - Chest.Chained", "Chained Chest Recipe", "Wood:8,Tin:1,Copper:1,Resin:4,GreydwarfEye:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableBronzeChest = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Enabled", defaultValue: true, "Enable Tier 2 Bronze Trussed Chest (Core Wood/Bronze/Ooze/Withered Bone/Ectoplasm).", 100);
			BronzeHealth = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Health", 1000f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			BronzeHeight = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Inventory Height", 3, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			BronzeWidth = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Inventory Width", 4, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			BronzeCraftingStation = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Crafting Station", "forge", "Required crafting station (e.g. piece_workbench, forge, or empty string for hammer only).", 60);
			BronzeRecipe = BindSynced(config, "3 - Chest.FineWood", "Fine Wood Chest Recipe", "RoundLog:12,Bronze:4,Ooze:4,WitheredBone:2,Ectoplasm:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableIronboundChest = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Enabled", defaultValue: true, "Enable Tier 3 Ironbound Strongbox (Ancient Bark/Iron/Guck/Wolf Fang/Surtling Core).", 100);
			IronboundHealth = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Health", 1500f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			IronboundHeight = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Inventory Height", 3, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			IronboundWidth = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Inventory Width", 6, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			IronboundCraftingStation = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Crafting Station", "forge", "Required crafting station (e.g. piece_workbench, forge, or empty string for hammer only).", 60);
			IronboundRecipe = BindSynced(config, "4 - Chest.Reinforced", "Reinforced Chest Recipe", "ElderBark:16,Iron:6,Guck:4,WolfFang:4,SurtlingCore:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableSilverChest = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Enabled", defaultValue: true, "Enable Tier 4 Ornate Silver Coffer (Fine Wood/Silver/Tar/Linen Thread/Fenris Claw).", 100);
			SilverHealth = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Health", 2500f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			SilverHeight = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Inventory Height", 4, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			SilverWidth = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Inventory Width", 6, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			SilverCraftingStation = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Crafting Station", "piece_artisanstation", "Required crafting station (e.g. piece_artisanstation, blackforge, or empty string for hammer only).", 60);
			SilverRecipe = BindSynced(config, "5 - Chest.SmallDvergr", "Small Dvergr Chest Recipe", "FineWood:20,Silver:8,Tar:4,LinenThread:8,WolfClaw:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableClockworkChest = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Enabled", defaultValue: true, "Enable Tier 5 Dvergr Clockwork Vault (Yggdrasil Wood/Black Metal/Sap/Mechanical Springs/Refined Eitr).", 100);
			ClockworkHealth = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Health", 4000f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			ClockworkHeight = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Inventory Height", 5, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ClockworkWidth = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Inventory Width", 6, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ClockworkCraftingStation = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Crafting Station", "blackforge", "Required crafting station (e.g. blackforge, forge, or empty string for hammer only).", 60);
			ClockworkRecipe = BindSynced(config, "6 - Chest.LargeDvergr", "Large Dvergr Chest Recipe", "YggdrasilWood:24,BlackMetal:10,Sap:4,MechanicalSpring:2,Eitr:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableFlametalChest = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Enabled", defaultValue: true, "Enable Tier 6 Charred Flametal Safehold (Ashwood/Flametal/Charcoal Resin/Ceramic Plates/Wisp).", 100);
			FlametalHealth = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Health", 10000f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			FlametalHeight = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Inventory Height", 6, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			FlametalWidth = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Inventory Width", 6, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			FlametalCraftingStation = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Crafting Station", "blackforge", "Required crafting station (e.g. blackforge, piece_magetable, or empty string for hammer only).", 60);
			FlametalRecipe = BindSynced(config, "7 - Chest.CharredFortress", "Charred Fortress Chest Recipe", "Blackwood:28,FlametalNew:12,CharcoalResin:4,CeramicPlate:2,Wisp:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			EnableReliquaryChest = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Enabled", defaultValue: true, "Enable Tier 7 Ancient Morkhalla Reliquary (Grausten/Gold/Ooze Mork/Frostwood/Memorial Coal).", 100);
			ReliquaryHealth = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Health", 25000f, "Chest structural health points (50.0 - 50000.0).", 90, (AcceptableValueBase?)(object)new AcceptableValueRange<float>(50f, 50000f));
			ReliquaryHeight = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Inventory Height", 6, "Inventory grid row height (1 - 10).", 80, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ReliquaryWidth = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Inventory Width", 7, "Inventory grid column width (1 - 10).", 70, (AcceptableValueBase?)(object)new AcceptableValueRange<int>(1, 10));
			ReliquaryCraftingStation = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Crafting Station", "piece_magetable", "Required crafting station (e.g. piece_magetable, blackforge, or empty string for hammer only).", 60);
			ReliquaryRecipe = BindSynced(config, "8 - Chest.AncientMorkhalla", "Ancient Chest Recipe", "Grausten:32,Gold:14,OozeMork:4,Frostwood:8,MemorialCoal:1", "Crafting recipe string formatted as ItemPrefab:Amount,... parsed against ObjectDB.", 50, null, RecipeConfigDrawer.Draw);
			Plugin.LogDebug("Configuration initialized and bound with ConditionalConfigSync.");
		}

		private static ConfigEntry<T> BindSynced<T>(ConfigFile config, string section, string key, T defaultValue, string description, int order, AcceptableValueBase? acceptableValues = null, Action<ConfigEntryBase>? customDrawer = null)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
			{
				Order = order,
				CustomDrawer = customDrawer
			};
			ConfigDescription val = new ConfigDescription(description, acceptableValues, new object[1] { configurationManagerAttributes });
			ConfigEntry<T> val2 = config.Bind<T>(section, key, defaultValue, val);
			((ConditionalConfigSync)ConfigSync).AddConfigEntry<T>(val2);
			return val2;
		}

		private static ConfigEntry<T> BindClient<T>(ConfigFile config, string section, string key, T defaultValue, string description, int order, AcceptableValueBase? acceptab