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 MagneticWishbone v1.1.1
MagneticWishbone.dll
Decompiled 2 years agousing 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using VNEI.Logic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("MagneticWishbone")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Riintouge")] [assembly: AssemblyProduct("MagneticWishbone")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4533b312-0061-4916-b569-170707a29c8f")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.1.1.0")] namespace MagneticWishbone; public class Common { public const string WishbonePrefabName = "Wishbone"; public const string WishboneUnlocalizedName = "$item_wishbone"; public const string NoneCraftingStationName = "NoneCraftingStation"; public const float DefaultMaxAutoPickupDistance = 2f; public const float DefaultMaxInteractDistance = 5f; public const float MaxAutoPickupDistance = 50f; public static InvalidatableLazy<CraftingStation> NoneCraftingStation = new InvalidatableLazy<CraftingStation>(delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) CraftingStation obj = new GameObject().AddComponent<CraftingStation>(); ((Object)obj).name = "NoneCraftingStation"; obj.m_name = "NoneCraftingStation"; obj.m_discoverRange = 0f; return obj; }); public static CraftingStation FindCraftingStationByUnlocalizedName(string unlocalizedName) { if (!Utility.IsNullOrWhiteSpace(unlocalizedName)) { foreach (CraftingStation item in Traverse.Create(typeof(CraftingStation)).Field("m_allStations").GetValue() as List<CraftingStation>) { if (item.m_name.Equals(unlocalizedName)) { return item; } } } return NoneCraftingStation.Value; } } public abstract class CustomRecipe : Recipe { public virtual bool IsCraftable() { return IsCraftableAt(GetCustomRequiredStation(1)); } public abstract bool IsCraftableAt(CraftingStation station); public virtual bool IsUpgradable(int currentQuality) { return IsUpgradableAt(currentQuality, GetCustomRequiredStation(currentQuality)); } public abstract bool IsUpgradableAt(int currentQuality, CraftingStation station); public virtual bool AppliesTo(ItemDrop itemDrop) { return AppliesTo(itemDrop.m_itemData); } public virtual bool AppliesTo(ItemData itemData) { return AppliesTo(itemData.m_shared.m_name); } public virtual bool AppliesTo(string unlocalizedItemNameOrPrefabName) { if (!base.m_item.m_itemData.m_shared.m_name.Equals(unlocalizedItemNameOrPrefabName)) { return ((Object)base.m_item).name.Equals(unlocalizedItemNameOrPrefabName); } return true; } public virtual bool RegisterWithVNEI() { if (Chainloader.PluginInfos.ContainsKey("com.maxsch.valheim.vnei")) { RegisterWithVNEICore(); return true; } return false; } protected virtual void RegisterWithVNEICore() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown for (int i = 1; i <= base.m_item.m_itemData.m_shared.m_maxQuality; i++) { if ((i == 1) ? IsCraftable() : IsUpgradable(i - 1)) { Indexing.AddRecipeToItems((RecipeInfo)RegisterWithVNEICore(i)); } } } protected virtual object RegisterWithVNEICore(int quality) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown RecipeInfo val = new RecipeInfo((Recipe)(object)this, quality); val.AddStation(GetCustomRequiredStation(quality).m_name, GetCustomRequiredStationLevel(quality)); return (object)val; } public virtual int GetCustomAmount(int quality, out int need, out ItemData singleReqItem) { return ((Recipe)this).GetAmount(quality, ref need, ref singleReqItem, 1); } public virtual CraftingStation GetCustomRequiredStation(int quality) { return ((Recipe)this).GetRequiredStation(quality); } public virtual int GetCustomRequiredStationLevel(int quality) { return ((Recipe)this).GetRequiredStationLevel(quality); } public static Tuple<string, int> ParseItemCountPair(string rawPair) { if (rawPair == null) { throw new ArgumentNullException("rawPair"); } int result = 0; string[] array = rawPair.Split(new char[1] { ',' }); if (array.Length < 2) { throw new ArgumentException("Item count does not name an item!"); } if (array.Length > 2) { throw new ArgumentException("Item count lists more than an item and a count!"); } if (Utility.IsNullOrWhiteSpace(array[0])) { throw new ArgumentException("Item name is null or whitespace!"); } if (Utility.IsNullOrWhiteSpace(array[1])) { throw new ArgumentException("Count is null or whitespace!"); } if (!int.TryParse(array[1], out result)) { throw new NullReferenceException("Cannot parse \"" + array[1] + "\" as an integer!"); } return new Tuple<string, int>(array[0], result); } public static Dictionary<string, int> ParseRequirementString(string requirementsString) { if (requirementsString == null) { return null; } Dictionary<string, int> dictionary = new Dictionary<string, int>(); if (Utility.IsNullOrWhiteSpace(requirementsString)) { return dictionary; } try { string[] array = requirementsString.Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { Tuple<string, int> tuple = ParseItemCountPair(array[i]); if (tuple.Item2 > 0) { if (dictionary.ContainsKey(tuple.Item1)) { dictionary[tuple.Item1] += tuple.Item2; } else { dictionary.Add(tuple.Item1, tuple.Item2); } } } return dictionary; } catch (Exception value) { Console.WriteLine(value); return null; } } public static List<T> CreateRequirements<T>(string requirementsString) where T : CustomRequirement, new() { Dictionary<string, int> dictionary = ParseRequirementString(requirementsString); if (dictionary == null) { return null; } List<T> list = new List<T>(); foreach (string key in dictionary.Keys) { list.Add(new T { m_resItem = ObjectDB.instance.GetItemPrefab(key).GetComponent<ItemDrop>(), m_amount = dictionary[key], m_extraAmountOnlyOneIngredient = 0, m_amountPerLevel = 0, m_recover = true }); } return list; } } public class CustomRequirement : Requirement { public int m_applicableLevel; public virtual int GetCustomAmount(int qualityLevel) { if (m_applicableLevel == 0) { return ((Requirement)this).GetAmount(qualityLevel); } if (m_applicableLevel != qualityLevel) { return 0; } return base.m_amount; } } [BepInPlugin("com.riintouge.magneticwishbone", "Magnetic Wishbone", "1.1.1")] [BepInProcess("valheim.exe")] public class MagneticWishbone : BaseUnityPlugin { [HarmonyPatch(typeof(Humanoid))] private class HumanoidPatch { internal static float MaxMagneticRange(Player player) { float num = 2f; if (!IsEnabled.Value) { return num; } foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems()) { if (equippedItem.m_shared.m_name.Equals("$item_wishbone")) { int num2 = Mathf.Min(equippedItem.m_quality, MaxAllowedQuality()); if (num2 >= 2) { num = Mathf.Max(num, Tier2PickupRadius.Value); } if (num2 >= 3) { num = Mathf.Max(num, Tier3PickupRadius.Value); } if (num2 >= 4) { num = Mathf.Max(num, Tier4PickupRadius.Value); } } } return num; } [HarmonyPatch("EquipItem")] [HarmonyPostfix] private static void EquipItemPostfix(ref bool __result, ref Humanoid __instance, ref ItemData item, ref bool triggerEquipEffects) { if (__result && item != null && item.m_equipped && item.m_shared.m_name.Equals("$item_wishbone")) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer == (Object)(object)__instance) { localPlayer.m_autoPickupRange = MaxMagneticRange(localPlayer); } } } [HarmonyPatch("UnequipItem")] [HarmonyPostfix] private static void UnequipItemPostfix(ref Humanoid __instance, ref ItemData item, ref bool triggerEquipEffects) { if (item != null && !item.m_equipped && item.m_shared.m_name.Equals("$item_wishbone")) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer == (Object)(object)__instance) { localPlayer.m_autoPickupRange = MaxMagneticRange(localPlayer); } } } } [HarmonyPatch(typeof(InventoryGui))] private class InventoryGuiPatch { [HarmonyPatch("AddRecipeToList")] [HarmonyPrefix] private static bool AddRecipeToListPrefix(ref InventoryGui __instance, ref Player player, ref Recipe recipe, ref ItemData item, ref bool canCraft) { if (IsEnabled.Value && !canCraft && recipe is CustomRecipe) { CustomRecipe customRecipe = (CustomRecipe)(object)recipe; CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); if ((__instance.InCraftTab() && !customRecipe.IsCraftableAt(currentCraftingStation)) || (!__instance.InCraftTab() && !customRecipe.IsUpgradableAt(item.m_quality, currentCraftingStation))) { return false; } } return true; } [HarmonyPatch("UpdateRecipeList")] [HarmonyPrefix] private static void UpdateRecipeListPrefix(ref InventoryGui __instance, ref List<Recipe> recipes) { Player localPlayer = Player.m_localPlayer; if (!IsEnabled.Value || (Object)(object)localPlayer == (Object)null) { return; } MagneticWishboneRecipe[] source = new MagneticWishboneRecipe[1] { MagneticWishboneRecipe.Instance.Value }; List<ItemData> list = (from x in ((Humanoid)localPlayer).GetInventory().GetAllItems() where x != null select x).ToList(); CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); foreach (CustomRecipe item in source.Where((CustomRecipe x) => ((Recipe)x).m_enabled)) { if (__instance.InCraftTab()) { if (item.IsCraftableAt(currentCraftingStation)) { recipes.Add((Recipe)(object)item); } continue; } foreach (ItemData item2 in list) { if (item.AppliesTo(item2) && item.IsUpgradableAt(item2.m_quality, currentCraftingStation)) { recipes.Add((Recipe)(object)item); break; } } } } } internal class MagneticWishboneRecipe : CustomRecipe { public static InvalidatableLazy<MagneticWishboneRecipe> Instance = new InvalidatableLazy<MagneticWishboneRecipe>(() => (MagneticWishboneRecipe)(object)ScriptableObject.CreateInstance(typeof(MagneticWishboneRecipe))); protected MagneticWishboneRecipe() { ((Recipe)this).m_item = ObjectDB.instance.GetItemPrefab("Wishbone").GetComponent<ItemDrop>(); ((Recipe)this).m_amount = 1; ((Recipe)this).m_enabled = true; ((Recipe)this).m_qualityResultAmountMultiplier = 1f; ((Recipe)this).m_craftingStation = Common.NoneCraftingStation.Value; ((Recipe)this).m_repairStation = Common.NoneCraftingStation.Value; ((Recipe)this).m_minStationLevel = 1; ((Recipe)this).m_requireOnlyOneIngredient = false; try { List<Requirement> list = new List<Requirement>(); if (AllowTier4.Value || AllowTier3.Value || AllowTier2.Value) { List<CustomRequirement> list2 = CustomRecipe.CreateRequirements<CustomRequirement>(Tier2Ingredients.Value); list2.ForEach(delegate(CustomRequirement x) { x.m_applicableLevel = 2; }); list.AddRange((IEnumerable<Requirement>)list2); } if (AllowTier4.Value || AllowTier3.Value) { List<CustomRequirement> list3 = CustomRecipe.CreateRequirements<CustomRequirement>(Tier3Ingredients.Value); list3.ForEach(delegate(CustomRequirement x) { x.m_applicableLevel = 3; }); list.AddRange((IEnumerable<Requirement>)list3); } if (AllowTier4.Value) { List<CustomRequirement> list4 = CustomRecipe.CreateRequirements<CustomRequirement>(Tier4Ingredients.Value); list4.ForEach(delegate(CustomRequirement x) { x.m_applicableLevel = 4; }); list.AddRange((IEnumerable<Requirement>)list4); } ((Recipe)this).m_resources = list.ToArray(); } catch (Exception value) { ((Recipe)this).m_enabled = false; Console.WriteLine(value); } RegisterWithVNEI(); } public override bool IsCraftable() { return false; } public override bool IsCraftableAt(CraftingStation station) { return false; } public override bool IsUpgradable(int currentQuality) { return currentQuality < MaxAllowedQuality(); } public override bool IsUpgradableAt(int currentQuality, CraftingStation station) { CraftingStation customRequiredStation = GetCustomRequiredStation(currentQuality + 1); if ((station == null || station.m_name == null) && (customRequiredStation == null || customRequiredStation.m_name == null)) { return true; } if (station == null || station.m_name == null || customRequiredStation == null || customRequiredStation.m_name == null) { return false; } if (!customRequiredStation.m_name.Equals(station.m_name)) { return false; } if (GetCustomRequiredStationLevel(currentQuality + 1) > station.GetLevel(true)) { return false; } return true; } public override CraftingStation GetCustomRequiredStation(int quality) { switch (quality) { case 2: if (!AllowTier2.Value) { return Common.NoneCraftingStation.Value; } return Common.FindCraftingStationByUnlocalizedName(Tier2CraftingStation.Value.Split(new char[1] { ',' })[0]); case 3: if (!AllowTier3.Value) { return Common.NoneCraftingStation.Value; } return Common.FindCraftingStationByUnlocalizedName(Tier3CraftingStation.Value.Split(new char[1] { ',' })[0]); case 4: if (!AllowTier4.Value) { return Common.NoneCraftingStation.Value; } return Common.FindCraftingStationByUnlocalizedName(Tier4CraftingStation.Value.Split(new char[1] { ',' })[0]); default: return Common.NoneCraftingStation.Value; } } public override int GetCustomRequiredStationLevel(int quality) { try { switch (quality) { case 2: return AllowTier2.Value ? int.Parse(Tier2CraftingStation.Value.Split(new char[1] { ',' })[1]) : 999; case 3: return AllowTier3.Value ? int.Parse(Tier3CraftingStation.Value.Split(new char[1] { ',' })[1]) : 999; case 4: return AllowTier4.Value ? int.Parse(Tier4CraftingStation.Value.Split(new char[1] { ',' })[1]) : 999; } } catch (Exception) { } return 999; } } [HarmonyPatch(typeof(ObjectDB))] private class ObjectDBPatch { public static void UpdateWishboneMaxQuality() { ObjectDB instance = ObjectDB.instance; object obj; if (instance == null) { obj = null; } else { GameObject itemPrefab = instance.GetItemPrefab("Wishbone"); obj = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared); } SharedData val = (SharedData)obj; if (val != null) { val.m_maxQuality = MaxAllowedQuality(); } } [HarmonyPatch("Awake")] [HarmonyPrefix] private static void AwakePrefix() { MagneticWishboneRecipe.Instance.Value = null; } [HarmonyPatch("UpdateRegisters")] [HarmonyPostfix] private static void UpdateRegistersPostfix() { UpdateWishboneMaxQuality(); } } [HarmonyPatch(typeof(Requirement))] private class PieceRequirementPatch { [HarmonyPatch("GetAmount")] [HarmonyPrefix] private static bool GetAmountPrefix(ref int __result, ref Requirement __instance, ref int qualityLevel) { if (__instance is CustomRequirement) { __result = ((CustomRequirement)(object)__instance).GetCustomAmount(qualityLevel); return false; } return true; } } [HarmonyPatch(typeof(Recipe))] private class RecipePatch { [HarmonyPatch("GetRequiredStation")] [HarmonyPrefix] private static bool GetRequiredStationPrefix(ref CraftingStation __result, ref Recipe __instance, ref int quality) { if (__instance is CustomRecipe) { __result = ((CustomRecipe)(object)__instance).GetCustomRequiredStation(quality); return false; } return true; } [HarmonyPatch("GetRequiredStationLevel")] [HarmonyPrefix] private static bool GetRequiredStationLevelPrefix(ref int __result, ref Recipe __instance, ref int quality) { if (__instance is CustomRecipe) { __result = ((CustomRecipe)(object)__instance).GetCustomRequiredStationLevel(quality); return false; } return true; } } public static ConfigEntry<bool> IsEnabled; public static ConfigEntry<bool> AllowTier2; public static ConfigEntry<string> Tier2CraftingStation; public static ConfigEntry<string> Tier2Ingredients; public static ConfigEntry<float> Tier2PickupRadius; public static ConfigEntry<bool> AllowTier3; public static ConfigEntry<string> Tier3CraftingStation; public static ConfigEntry<string> Tier3Ingredients; public static ConfigEntry<float> Tier3PickupRadius; public static ConfigEntry<bool> AllowTier4; public static ConfigEntry<string> Tier4CraftingStation; public static ConfigEntry<string> Tier4Ingredients; public static ConfigEntry<float> Tier4PickupRadius; private readonly Harmony Harmony = new Harmony("com.riintouge.magneticwishbone"); private readonly ConfigurationManagerAttributes AdminOnlyAttribute = new ConfigurationManagerAttributes { IsAdminOnly = true }; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Expected O, but got Unknown //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "Enable", true, new ConfigDescription("Whether this plugin has any effect when loaded.", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); AllowTier2 = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Basic", "AllowTier2", true, new ConfigDescription("Whether the Wishbone can be upgraded to quality level 2, and functions as such.", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier2CraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Basic", "Tier2CraftingStation", "$piece_forge,1", new ConfigDescription("A string of the form \"UnlocalizedName,StationLevel\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier2Ingredients = ((BaseUnityPlugin)this).Config.Bind<string>("2 - Basic", "Tier2Ingredients", "IronScrap,20;Root,5", new ConfigDescription("A string of the form \"ItemName1,Amount;...;ItemNameN,Amount\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier2PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Basic", "Tier2PickupRadius", 5f, new ConfigDescription("The auto-pickup range of the player, in meters, when a once-upgraded Wishbone is equipped.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), new object[1] { AdminOnlyAttribute })); AllowTier3 = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Improved", "AllowTier3", true, new ConfigDescription("Whether the Wishbone can be upgraded to quality level 3, and functions as such.", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier3CraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Improved", "Tier3CraftingStation", "$piece_artisanstation,1", new ConfigDescription("A string of the form \"UnlocalizedName,StationLevel\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier3Ingredients = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Improved", "Tier3Ingredients", "MechanicalSpring,1;Thunderstone,1;Resin,5", new ConfigDescription("A string of the form \"ItemName1,Amount;...;ItemNameN,Amount\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier3PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Improved", "Tier3PickupRadius", 10f, new ConfigDescription("The auto-pickup range of the player, in meters, when a twice-upgraded Wishbone is equipped.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), new object[1] { AdminOnlyAttribute })); AllowTier4 = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Advanced", "AllowTier4", false, new ConfigDescription("Whether the Wishbone can be upgraded to quality level 4, and functions as such.", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier4CraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Advanced", "Tier4CraftingStation", "$piece_magetable,4", new ConfigDescription("A string of the form \"UnlocalizedName,StationLevel\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier4Ingredients = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Advanced", "Tier4Ingredients", "DarkCore,1;Wisp,1;SilverNecklace,1;LinenThread,5", new ConfigDescription("A string of the form \"ItemName1,Amount;...;ItemNameN,Amount\".", (AcceptableValueBase)null, new object[1] { AdminOnlyAttribute })); Tier4PickupRadius = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Advanced", "Tier4PickupRadius", 15f, new ConfigDescription("The auto-pickup range of the player, in meters, when a thrice-upgraded Wishbone is equipped.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), new object[1] { AdminOnlyAttribute })); Harmony.PatchAll(); ((BaseUnityPlugin)this).Config.SettingChanged += Config_SettingChanged; SynchronizationManager.OnConfigurationSynchronized += SynchronizationManager_OnConfigurationSynchronized; } private void Config_SettingChanged(object sender, SettingChangedEventArgs e) { if (e.ChangedSetting == IsEnabled) { ((Recipe)MagneticWishboneRecipe.Instance.Value).m_enabled = IsEnabled.Value; } else if (e.ChangedSetting == AllowTier2) { if (!AllowTier2.Value) { AllowTier3.Value = false; } ObjectDBPatch.UpdateWishboneMaxQuality(); MagneticWishboneRecipe.Instance.Value = null; } else if (e.ChangedSetting == AllowTier3) { if (AllowTier3.Value) { AllowTier2.Value = true; } else { AllowTier4.Value = false; } ObjectDBPatch.UpdateWishboneMaxQuality(); MagneticWishboneRecipe.Instance.Value = null; } else if (e.ChangedSetting == AllowTier4) { if (AllowTier4.Value) { AllowTier3.Value = true; } ObjectDBPatch.UpdateWishboneMaxQuality(); MagneticWishboneRecipe.Instance.Value = null; } else if (e.ChangedSetting == Tier2Ingredients || e.ChangedSetting == Tier3Ingredients || e.ChangedSetting == Tier4Ingredients) { MagneticWishboneRecipe.Instance.Value = null; } else if (e.ChangedSetting == Tier2PickupRadius || e.ChangedSetting == Tier3PickupRadius || e.ChangedSetting == Tier4PickupRadius) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { localPlayer.m_autoPickupRange = HumanoidPatch.MaxMagneticRange(localPlayer); } } } private void SynchronizationManager_OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs e) { ObjectDBPatch.UpdateWishboneMaxQuality(); MagneticWishboneRecipe.Instance.Value = null; } public static int MaxAllowedQuality() { if (!AllowTier4.Value) { if (!AllowTier3.Value) { if (!AllowTier2.Value) { return 1; } return 2; } return 3; } return 4; } } public class InvalidatableLazy<T> { private Func<T> producer; private T value; public T Value { get { lock (producer) { if (value == null) { value = producer(); } return value; } } set { lock (producer) { if (value != null) { throw new ArgumentException("value"); } this.value = default(T); } } } public InvalidatableLazy(Func<T> producer) { if (producer == null) { throw new ArgumentNullException("producer"); } this.producer = producer; } }