Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PersonalChestHeeler v1.0.1
PersonalChestHeeler.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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