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 MegingjordExtended v2.2.0
Gafteds.UpgradeableMegingjord.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSyncAPI; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Gafteds.UpgradeableMegingjord")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Megingjord Extended - upgrade the vanilla Megingjord through 7 quality levels at the forge.")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyProduct("Gafteds.UpgradeableMegingjord")] [assembly: AssemblyTitle("Gafteds.UpgradeableMegingjord")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 ConditionalConfigSyncAPI { public enum SyncMode { AlwaysServerControlled, Conditional, AlwaysClientControlled } public enum RequirementMode { Fixed, Conditional } public sealed class ConfigSync { public const string PluginGuid = "_shudnal.ConditionalConfigSync"; public const string MinimumCcsVersion = "1.0.10"; private static readonly Version MinimumSupportedCcsVersion = new Version("1.0.10"); private const string BridgeTypeName = "ConditionalConfigSync.SoftDependencyBridge"; private const int MinimumBridgeApiVersion = 1; private readonly string _name; private readonly string _displayName; private readonly string _currentVersion; private readonly string _minimumRequiredVersion; private readonly bool _modRequired; private readonly RequirementMode _requirementMode; private readonly bool _allowClientConfigUpdatesWhenUnlocked; private readonly ManualLogSource _logger; private Type _bridgeType; private PropertyInfo _apiVersionProperty; private PropertyInfo _runtimeReadyProperty; private MethodInfo _createConfigSyncMethod; private MethodInfo _registerConfigEntryMethod; private MethodInfo _registerLockingConfigEntryMethod; private object _configSyncInstance; private bool _permanentFailure; private bool _permanentFailureLogged; private string _failureReason; public bool IsAvailable { get { if (EnsureBridge()) { return IsRuntimeReady(); } return false; } } public bool IsActive => _configSyncInstance != null; public string FailureReason => _failureReason; public ConfigSync(string name, string displayName, string currentVersion, string minimumRequiredVersion = null, bool modRequired = false, RequirementMode requirementMode = RequirementMode.Fixed, bool allowClientConfigUpdatesWhenUnlocked = false, ManualLogSource logger = null) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("A stable mod GUID is required.", "name"); } _name = name; _displayName = (string.IsNullOrWhiteSpace(displayName) ? name : displayName); _currentVersion = currentVersion; _minimumRequiredVersion = minimumRequiredVersion; _modRequired = modRequired; _requirementMode = requirementMode; _allowClientConfigUpdatesWhenUnlocked = allowClientConfigUpdatesWhenUnlocked; _logger = logger; } public bool TryActivate() { return EnsureContext(); } public ConfigEntry<T> Bind<T>(ConfigFile configFile, string section, string key, T defaultValue, string description, SyncMode syncMode = SyncMode.Conditional, bool serverControlledByDefault = true) { if (configFile == null) { throw new ArgumentNullException("configFile"); } ConfigEntry<T> val = configFile.Bind<T>(section, key, defaultValue, description); RegisterConfigEntry<T>(val, syncMode, serverControlledByDefault); return val; } public ConfigEntry<T> Bind<T>(ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription description, SyncMode syncMode = SyncMode.Conditional, bool serverControlledByDefault = true) { if (configFile == null) { throw new ArgumentNullException("configFile"); } ConfigEntry<T> val = configFile.Bind<T>(section, key, defaultValue, description); RegisterConfigEntry<T>(val, syncMode, serverControlledByDefault); return val; } public bool RegisterConfigEntry<T>(ConfigEntry<T> entry, SyncMode syncMode = SyncMode.Conditional, bool serverControlledByDefault = true) { if (entry == null) { throw new ArgumentNullException("entry"); } if (!EnsureContext()) { return false; } try { Invoke(_registerConfigEntryMethod, null, new object[4] { _configSyncInstance, entry, syncMode.ToString(), serverControlledByDefault }); return true; } catch (Exception exception) { LogWarning("Failed to register config entry '" + ((ConfigEntryBase)entry).Definition.Section + " -> " + ((ConfigEntryBase)entry).Definition.Key + "' with Conditional Config Sync. The entry remains a normal local BepInEx setting. " + GetInnermostMessage(exception)); return false; } } public bool RegisterLockingConfigEntry<T>(ConfigEntry<T> entry) where T : IConvertible { if (entry == null) { throw new ArgumentNullException("entry"); } if (!EnsureContext()) { return false; } try { Invoke(_registerLockingConfigEntryMethod, null, new object[2] { _configSyncInstance, entry }); return true; } catch (Exception exception) { LogWarning("Failed to register locking config entry '" + ((ConfigEntryBase)entry).Definition.Section + " -> " + ((ConfigEntryBase)entry).Definition.Key + "' with Conditional Config Sync. The entry remains a normal local BepInEx setting. " + GetInnermostMessage(exception)); return false; } } public ConfigEntry<T> BindLocking<T>(ConfigFile configFile, string section, string key, T defaultValue, string description) where T : IConvertible { if (configFile == null) { throw new ArgumentNullException("configFile"); } ConfigEntry<T> val = configFile.Bind<T>(section, key, defaultValue, description); RegisterLockingConfigEntry<T>(val); return val; } public ConfigEntry<T> BindLocking<T>(ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription description) where T : IConvertible { if (configFile == null) { throw new ArgumentNullException("configFile"); } ConfigEntry<T> val = configFile.Bind<T>(section, key, defaultValue, description); RegisterLockingConfigEntry<T>(val); return val; } private bool EnsureContext() { if (_configSyncInstance != null) { return true; } if (_permanentFailure || !EnsureBridge() || !IsRuntimeReady()) { return false; } try { _configSyncInstance = Invoke(_createConfigSyncMethod, null, new object[7] { _name, _displayName, _currentVersion, _minimumRequiredVersion, _modRequired, _requirementMode.ToString(), _allowClientConfigUpdatesWhenUnlocked }); if (_configSyncInstance == null) { SetPermanentFailure("Conditional Config Sync returned no consumer context.", null); return false; } return true; } catch (Exception exception) { SetPermanentFailure("Failed to create the Conditional Config Sync consumer context.", exception); return false; } } private bool EnsureBridge() { if (_bridgeType != null) { return true; } if (_permanentFailure) { return false; } try { if (!Chainloader.PluginInfos.TryGetValue("_shudnal.ConditionalConfigSync", out var value) || value == null || (Object)(object)value.Instance == (Object)null) { return false; } if (value.Metadata == null || value.Metadata.Version == null || value.Metadata.Version.CompareTo(MinimumSupportedCcsVersion) < 0) { return false; } Type type = ((object)value.Instance).GetType().Assembly.GetType("ConditionalConfigSync.SoftDependencyBridge", throwOnError: false); if (type == null) { SetPermanentFailure("The installed Conditional Config Sync version does not expose the optional soft-dependency bridge.", null); return false; } PropertyInfo property = type.GetProperty("ApiVersion", BindingFlags.Static | BindingFlags.Public); PropertyInfo property2 = type.GetProperty("IsRuntimeReady", BindingFlags.Static | BindingFlags.Public); MethodInfo method = type.GetMethod("CreateConfigSync", BindingFlags.Static | BindingFlags.Public, null, new Type[7] { typeof(string), typeof(string), typeof(string), typeof(string), typeof(bool), typeof(string), typeof(bool) }, null); MethodInfo method2 = type.GetMethod("RegisterConfigEntry", BindingFlags.Static | BindingFlags.Public, null, new Type[4] { typeof(object), typeof(ConfigEntryBase), typeof(string), typeof(bool) }, null); MethodInfo method3 = type.GetMethod("RegisterLockingConfigEntry", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(object), typeof(ConfigEntryBase) }, null); if (property == null || property2 == null || method == null || method2 == null || method3 == null) { SetPermanentFailure("The installed Conditional Config Sync soft-dependency bridge is incomplete or incompatible.", null); return false; } if (!(property.GetValue(null, null) is int num) || num < 1) { SetPermanentFailure("The installed Conditional Config Sync soft-dependency bridge version is not supported.", null); return false; } _bridgeType = type; _apiVersionProperty = property; _runtimeReadyProperty = property2; _createConfigSyncMethod = method; _registerConfigEntryMethod = method2; _registerLockingConfigEntryMethod = method3; return true; } catch (Exception exception) { SetPermanentFailure("Failed to resolve the Conditional Config Sync soft-dependency bridge.", exception); return false; } } private bool IsRuntimeReady() { try { object value = _runtimeReadyProperty.GetValue(null, null); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch (Exception exception) { SetPermanentFailure("Failed to query the Conditional Config Sync runtime state.", exception); return false; } } private static object Invoke(MethodInfo method, object target, object[] arguments) { try { return method.Invoke(target, arguments); } catch (TargetInvocationException ex) when (ex.InnerException != null) { ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); throw; } } private void SetPermanentFailure(string message, Exception exception) { _permanentFailure = true; _failureReason = ((exception == null) ? message : (message + " " + GetInnermostMessage(exception))); if (!_permanentFailureLogged) { _permanentFailureLogged = true; LogWarning(_failureReason); } } private void LogWarning(string message) { if (_logger != null) { _logger.LogWarning((object)message); } } private static string GetInnermostMessage(Exception exception) { Exception ex = exception; while (ex.InnerException != null) { ex = ex.InnerException; } return ex.Message; } } } namespace Gafteds.UpgradeableMegingjord { [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] internal static class GetMaxCarryWeight_Patch { private static void Postfix(Player __instance, ref float __result) { Inventory val = (((Object)(object)__instance != (Object)null) ? ((Humanoid)__instance).GetInventory() : null); if (val == null) { return; } int num = 0; foreach (ItemData allItem in val.GetAllItems()) { if (allItem == null || !allItem.m_equipped) { continue; } GameObject dropPrefab = allItem.m_dropPrefab; if (!((Object)(object)dropPrefab == (Object)null) && !(((Object)dropPrefab).name != "BeltStrength")) { int num2 = BeltUpgrades.CarryForQuality(allItem.m_quality) - 150; if (num2 > num) { num = num2; } } } if (num > 0) { __result += num; } } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(int) })] internal static class BeltTooltip_Patch { private static readonly Regex s_carryRegex = new Regex("\\+150\\b", RegexOptions.Compiled); private static void Postfix(ItemData __instance, ref string __result) { if (__instance == null || string.IsNullOrEmpty(__result)) { return; } GameObject dropPrefab = __instance.m_dropPrefab; if (!((Object)(object)dropPrefab == (Object)null) && !(((Object)dropPrefab).name != "BeltStrength")) { int num = BeltUpgrades.CarryForQuality(__instance.m_quality); if (num != 150) { __result = s_carryRegex.Replace(__result, "+" + num); } } } } public static class BeltUpgrades { public struct SwapState { public bool applied; public Recipe recipe; public Requirement[] oldResources; public int oldMinLevel; } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Patch { private static void Postfix(ObjectDB __instance) { Register(__instance); } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirementList")] private static class SetupRequirementList_Patch { private static readonly FieldInfo s_selectedRecipeField = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe"); private static readonly MethodInfo s_getRecipe = ((s_selectedRecipeField != null) ? AccessTools.Method(s_selectedRecipeField.FieldType, "get_Recipe", (Type[])null, (Type[])null) : null); [HarmonyPriority(800)] private static void Prefix(InventoryGui __instance, int quality, Player player, out SwapState __state) { Recipe recipe = null; if ((Object)(object)__instance != (Object)null && s_selectedRecipeField != null && s_getRecipe != null) { object value = s_selectedRecipeField.GetValue(__instance); if (value != null) { object? obj = s_getRecipe.Invoke(value, null); recipe = (Recipe)((obj is Recipe) ? obj : null); } } __state = TryApplyFiltered(recipe, quality, player); } [HarmonyPriority(0)] private static void Postfix(SwapState __state) { Restore(__state); } [HarmonyPriority(0)] private static void Finalizer(SwapState __state) { Restore(__state); } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] private static class DoCrafting_Patch { [HarmonyPriority(800)] private static void Prefix(out SwapState __state, ItemData ___m_craftUpgradeItem, Recipe ___m_craftRecipe) { int targetQuality = ((___m_craftUpgradeItem == null) ? 1 : (___m_craftUpgradeItem.m_quality + 1)); __state = TryApply(___m_craftRecipe, targetQuality); } [HarmonyPriority(0)] private static void Postfix(SwapState __state) { Restore(__state); } [HarmonyPriority(0)] private static void Finalizer(SwapState __state) { Restore(__state); } } [HarmonyPatch(typeof(Player), "HaveRequirementItems")] private static class HaveRequirementItems_Patch { [HarmonyPriority(800)] private static void Prefix(Recipe piece, bool discover, int qualityLevel, out SwapState __state) { __state = default(SwapState); if (!discover) { __state = TryApply(piece, qualityLevel); } } [HarmonyPriority(0)] private static void Postfix(SwapState __state) { Restore(__state); } [HarmonyPriority(0)] private static void Finalizer(SwapState __state) { Restore(__state); } } [HarmonyPatch(typeof(Player), "HaveRequirementItems")] private static class HaveRequirementItems_DiscoveryBlock_Patch { private static void Postfix(Player __instance, Recipe piece, bool discover, int qualityLevel, ref bool __result) { if (!__result) { return; } if (discover && qualityLevel <= 1 && (Object)(object)piece != (Object)null && (Object)(object)piece.m_item != (Object)null && ((Object)piece.m_item).name == "BeltStrength" && !EnableBaseCraft) { __result = false; } else if (!discover && !((Object)(object)piece == (Object)null) && !((Object)(object)piece.m_item == (Object)null) && !(((Object)piece.m_item).name != "BeltStrength")) { if (qualityLevel <= 1 && !EnableBaseCraft) { __result = false; } else if (qualityLevel > 1 && !HasDiscoveredAll(__instance, qualityLevel)) { __result = false; } } } } [HarmonyPatch(typeof(Requirement), "GetAmount")] private static class Requirement_GetAmount_Patch { private static void Postfix(Requirement __instance, int qualityLevel, ref int __result) { if (IsOurRequirement(__instance)) { __result = __instance.m_amount; } } } [HarmonyPatch(typeof(Recipe), "GetRequiredStationLevel")] private static class GetRequiredStationLevel_Patch { private static void Postfix(Recipe __instance, int quality, ref int __result) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_item == (Object)null) && !(((Object)__instance.m_item).name != "BeltStrength")) { __result = GetForgeForQuality(quality); } } } [HarmonyPatch(typeof(InventoryGui), "OnTabUpgradePressed")] private static class OnTabUpgradePressed_Patch { private static void Prefix() { IsUpgradeTab = true; } } [HarmonyPatch(typeof(InventoryGui), "OnTabCraftPressed")] private static class OnTabCraftPressed_Patch { private static void Prefix() { IsUpgradeTab = false; } } [HarmonyPatch(typeof(Player), "GetAvailableRecipes")] private static class GetAvailableRecipes_HideBaseCraft_Patch { private static void Postfix(Player __instance, ref List<Recipe> available) { if ((Object)(object)__instance != (Object)null && PlayerHasBelt(__instance)) { EnsureRecipeKnown(__instance); } if (!EnableBaseCraft && available != null && !IsUpgradeTab) { available.RemoveAll((Recipe rec) => (Object)(object)rec != (Object)null && (Object)(object)rec.m_item != (Object)null && ((Object)rec.m_item).name == "BeltStrength"); } } } [HarmonyPatch(typeof(Player), "AddKnownItem")] private static class AddKnownItem_Patch { private static readonly MethodInfo s_addKnownRecipe = AccessTools.Method(typeof(Player), "AddKnownRecipe", (Type[])null, (Type[])null); private static void Postfix(Player __instance, ItemData item) { if (!((Object)(object)__instance == (Object)null) && item != null && !((Object)(object)item.m_dropPrefab == (Object)null) && !(((Object)item.m_dropPrefab).name != "BeltStrength")) { Recipe beltRecipe = BeltRecipe; if (!((Object)(object)beltRecipe == (Object)null) && !(s_addKnownRecipe == null)) { s_addKnownRecipe.Invoke(__instance, new object[1] { beltRecipe }); } } } } public const string BeltPrefabName = "BeltStrength"; public const int MaxQuality = 7; public const int VanillaCarryBonus = 150; internal static ManualLogSource Log; private static ConfigEntry<string>[] s_recipes; private static ConfigEntry<int>[] s_carry; private static ConfigEntry<int>[] s_forge; private static ConfigEntry<bool> s_enableBaseCraft; private static ConfigEntry<bool> s_configLocked; internal static Recipe BeltRecipe; public static bool IsUpgradeTab; private static Dictionary<int, Requirement[]> s_requirements; private static HashSet<Requirement> s_ourRequirements; public static bool EnableBaseCraft { get { if (s_enableBaseCraft != null) { return s_enableBaseCraft.Value; } return false; } } public static void BindConfig(ConfigFile config, ConfigSync configSync) { s_recipes = new ConfigEntry<string>[8]; s_carry = new ConfigEntry<int>[8]; s_forge = new ConfigEntry<int>[8]; string[] array = new string[8] { null, "Q1 Base belt (craft)", "Q2 Swamp upgrade", "Q3 Mountain upgrade", "Q4 Plains upgrade", "Q5 Mistlands upgrade", "Q6 Ashlands upgrade", "Q7 Deep North upgrade" }; string[] array2 = new string[8] { null, "Iron:10,Coins:100,Guck:20,BjornHide:15,Chain:3", "Iron:30,Chain:5,TrophyWrithan:1", "Silver:30,Crystal:30,TrophySGolem:1", "BlackMetal:30,LoxPelt:15,TrophyGoblinBrute:1", "BlackMarble:50,ScaleHide:30,TrophyGjall:1", "FlametalNew:30,MoltenCore:2,TrophyMorgen:1", "Gold:30,AncientCoin:15,TrophyMole:1" }; int[] array3 = new int[8] { 0, 150, 200, 250, 300, 350, 400, 450 }; int[] array4 = new int[8] { 0, 1, 2, 3, 4, 5, 6, 7 }; s_configLocked = configSync.BindLocking(config, "General", "Lock Configuration", defaultValue: true, "Whether the configuration is locked to the server's values. When locked, clients cannot override synced settings; server admins can always edit them."); s_enableBaseCraft = configSync.Bind(config, "General", "Enable Base Belt Crafting", defaultValue: false, "Whether the base Megingjord (Q1) can be crafted at the forge. Default OFF: buy the belt from Haldor, then upgrade it at the forge. When disabled, the base craft recipe is hidden.", SyncMode.AlwaysServerControlled); for (int i = 1; i <= 7; i++) { s_recipes[i] = configSync.Bind(config, "Recipes", array[i], array2[i], "Materials for " + array[i] + ". Format: \"PrefabName:amount,PrefabName:amount,...\".", SyncMode.AlwaysServerControlled); s_recipes[i].SettingChanged += delegate { Rebuild(); }; s_carry[i] = configSync.Bind(config, "Carry Weight", array[i], array3[i], $"Total carry bonus while a quality {i} belt is equipped. (Vanilla already grants {150}; only the difference is added.)", SyncMode.AlwaysServerControlled); s_forge[i] = configSync.Bind(config, "Forge Levels", array[i], array4[i], "Forge level required for " + array[i] + ".", SyncMode.AlwaysServerControlled); s_forge[i].SettingChanged += delegate { Rebuild(); }; } } public static int CarryForQuality(int quality) { if (quality < 1) { quality = 1; } if (quality > 7) { quality = 7; } return s_carry[quality].Value; } public static int GetForgeForQuality(int quality) { if (quality < 1) { quality = 1; } if (quality > 7) { quality = 7; } return s_forge[quality].Value; } internal static bool IsOurRequirement(Requirement req) { if (req != null && s_ourRequirements != null) { return s_ourRequirements.Contains(req); } return false; } internal static Requirement[] GetRequirements(int quality) { if (s_requirements != null && s_requirements.TryGetValue(quality, out var value)) { return value; } return null; } public static bool HasDiscoveredAll(Player player, int quality) { if ((Object)(object)player == (Object)null) { return false; } Requirement[] requirements = GetRequirements(quality); if (requirements == null) { return false; } Requirement[] array = requirements; for (int i = 0; i < array.Length; i++) { string text = array[i]?.m_resItem?.m_itemData?.m_shared?.m_name; if (string.IsNullOrEmpty(text)) { continue; } try { if (!player.IsKnownMaterial(text)) { return false; } } catch { return false; } } return true; } public static SwapState TryApplyFiltered(Recipe recipe, int targetQuality, Player player) { SwapState result = default(SwapState); if ((Object)(object)recipe == (Object)null || (Object)(object)recipe != (Object)(object)BeltRecipe) { return result; } if (targetQuality < 1 || targetQuality > 7) { return result; } if (s_requirements == null || !s_requirements.TryGetValue(targetQuality, out var value)) { return result; } Requirement[] resources = value; if ((Object)(object)player != (Object)null) { List<Requirement> list = new List<Requirement>(); Requirement[] array = value; foreach (Requirement val in array) { string text = val?.m_resItem?.m_itemData?.m_shared?.m_name; bool flag = string.IsNullOrEmpty(text); if (!flag) { try { flag = player.IsKnownMaterial(text); } catch { flag = false; } } if (flag) { list.Add(val); } } resources = list.ToArray(); } result.applied = true; result.recipe = recipe; result.oldResources = recipe.m_resources; result.oldMinLevel = recipe.m_minStationLevel; recipe.m_resources = resources; int value2 = s_forge[targetQuality].Value; recipe.m_minStationLevel = Math.Max(1, value2 - (targetQuality - 1)); return result; } public static bool PlayerHasBelt(Player player) { if ((Object)(object)player == (Object)null) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } string text = null; if ((Object)(object)BeltRecipe != (Object)null && (Object)(object)BeltRecipe.m_item != (Object)null && BeltRecipe.m_item.m_itemData != null && BeltRecipe.m_item.m_itemData.m_shared != null) { text = BeltRecipe.m_item.m_itemData.m_shared.m_name; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem != null) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "BeltStrength") { return true; } if (text != null && allItem.m_shared != null && allItem.m_shared.m_name == text) { return true; } } } foreach (ItemData equippedItem in inventory.GetEquippedItems()) { if (equippedItem != null) { if ((Object)(object)equippedItem.m_dropPrefab != (Object)null && ((Object)equippedItem.m_dropPrefab).name == "BeltStrength") { return true; } if (text != null && equippedItem.m_shared != null && equippedItem.m_shared.m_name == text) { return true; } } } return false; } public static void EnsureRecipeKnown(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)BeltRecipe == (Object)null) { return; } try { MethodInfo methodInfo = AccessTools.Method(typeof(Player), "AddKnownRecipe", (Type[])null, (Type[])null); if (!(methodInfo == null) && !player.IsRecipeKnown(((Object)BeltRecipe).name)) { methodInfo.Invoke(player, new object[1] { BeltRecipe }); } } catch { } } public static void Register(ObjectDB objectDB) { if ((Object)(object)BeltRecipe != (Object)null) { Rebuild(); return; } GameObject itemPrefab = objectDB.GetItemPrefab("BeltStrength"); if ((Object)(object)itemPrefab == (Object)null) { Log.LogInfo((object)"Vanilla belt prefab 'BeltStrength' not yet available (ObjectDB still loading) - will retry on next Awake."); return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { Log.LogError((object)"Vanilla belt prefab has no ItemDrop/SharedData - Megingjord Extended disabled."); return; } component.m_itemData.m_shared.m_maxQuality = 7; CraftingStation val = FindForgeStation(objectDB); if ((Object)(object)val == (Object)null) { Log.LogError((object)"Could not find the forge crafting station - Megingjord Extended disabled."); return; } RebuildTables(); objectDB.m_recipes.RemoveAll((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == "BeltStrength"); Recipe val2 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val2).name = "BeltStrength"; val2.m_item = component; val2.m_craftingStation = val; val2.m_amount = 1; val2.m_enabled = true; ApplyTables(val2); objectDB.m_recipes.Add(val2); BeltRecipe = val2; Log.LogInfo((object)$"Registered upgradeable vanilla Megingjord: qualities 1-{7} at the forge."); } private static void Rebuild() { if (!((Object)(object)BeltRecipe == (Object)null) && !((Object)(object)ObjectDB.instance == (Object)null)) { RebuildTables(); ApplyTables(BeltRecipe); Log.LogInfo((object)"Megingjord Extended config reloaded."); } } private static void ApplyTables(Recipe recipe) { recipe.m_resources = s_requirements[1]; recipe.m_minStationLevel = s_forge[1].Value; } private static void RebuildTables() { Dictionary<int, Requirement[]> dictionary = new Dictionary<int, Requirement[]>(); HashSet<Requirement> hashSet = new HashSet<Requirement>(); for (int i = 1; i <= 7; i++) { List<Requirement> list = ParseRequirements(s_recipes[i].Value, i); dictionary[i] = list.ToArray(); foreach (Requirement item in list) { hashSet.Add(item); } } s_requirements = dictionary; s_ourRequirements = hashSet; } private static List<Requirement> ParseRequirements(string text, int quality) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown List<Requirement> list = new List<Requirement>(); if (string.IsNullOrWhiteSpace(text)) { return list; } string[] array = text.Split(','); foreach (string text2 in array) { string[] array2 = text2.Split(':'); if (array2.Length != 2) { Log.LogWarning((object)$"Bad recipe entry '{text2}' for quality {quality} - expected \"PrefabName:amount\". Skipped."); continue; } string text3 = array2[0].Trim(); if (!int.TryParse(array2[1].Trim(), out var result) || result <= 0) { Log.LogWarning((object)$"Bad amount in '{text2}' for quality {quality} - skipped."); continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text3); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)$"Unknown item '{text3}' in quality {quality} recipe - skipped."); continue; } list.Add(new Requirement { m_resItem = val, m_amount = result }); } return list; } private static CraftingStation FindForgeStation(ObjectDB objectDB) { foreach (Recipe recipe in objectDB.m_recipes) { CraftingStation val = (((Object)(object)recipe != (Object)null) ? recipe.m_craftingStation : null); if ((Object)(object)val != (Object)null && val.m_name == "$piece_forge") { return val; } } foreach (Recipe recipe2 in objectDB.m_recipes) { CraftingStation val2 = (((Object)(object)recipe2 != (Object)null) ? recipe2.m_craftingStation : null); if ((Object)(object)val2 != (Object)null && val2.m_name != null && val2.m_name.ToLowerInvariant().Contains("forge")) { return val2; } } return null; } public static SwapState TryApply(Recipe recipe, int targetQuality) { SwapState result = default(SwapState); if ((Object)(object)recipe == (Object)null || (Object)(object)recipe != (Object)(object)BeltRecipe) { return result; } if (targetQuality < 1 || targetQuality > 7) { return result; } if (s_requirements == null || !s_requirements.TryGetValue(targetQuality, out var value)) { return result; } result.applied = true; result.recipe = recipe; result.oldResources = recipe.m_resources; result.oldMinLevel = recipe.m_minStationLevel; recipe.m_resources = value; int value2 = s_forge[targetQuality].Value; recipe.m_minStationLevel = Math.Max(1, value2 - (targetQuality - 1)); return result; } public static void Restore(SwapState state) { if (state.applied && !((Object)(object)state.recipe == (Object)null)) { state.recipe.m_resources = state.oldResources; state.recipe.m_minStationLevel = state.oldMinLevel; } } } [BepInPlugin("gafteds.upgradeablemegingjord", "Megingjord Extended", "2.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class UpgradeableMegingjordPlugin : BaseUnityPlugin { public const string PluginGuid = "gafteds.upgradeablemegingjord"; public const string PluginName = "Megingjord Extended"; public const string PluginVersion = "2.2.0"; internal static UpgradeableMegingjordPlugin Instance; internal static ConfigSync ConfigSync; private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) Instance = this; BeltUpgrades.Log = ((BaseUnityPlugin)this).Logger; ConfigSync = new ConfigSync("gafteds.upgradeablemegingjord", "Megingjord Extended", "2.2.0", "2.2.0", modRequired: false, RequirementMode.Fixed, allowClientConfigUpdatesWhenUnlocked: false, ((BaseUnityPlugin)this).Logger); BeltUpgrades.BindConfig(((BaseUnityPlugin)this).Config, ConfigSync); new Harmony("gafteds.upgradeablemegingjord").PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Megingjord Extended v2.2.0 loaded."); } } }