using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("MoreUpgrades")] [assembly: AssemblyDescription("MoreUpgrades mod for Valheim BepInEx")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("renair")] [assembly: AssemblyProduct("MoreUpgrades")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4ad833eb-3e07-4781-9829-a760d335648a")] [assembly: AssemblyFileVersion("0.0.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: AssemblyVersion("0.0.2.0")] namespace MoreUpgrades; [BepInPlugin("SaltyCypher.MoreBettererUpgrades", "MoreBettererUpgrades", "1.0.0")] [BepInProcess("valheim.exe")] internal class MoreUpgrades : BaseUnityPlugin { [HarmonyPatch(typeof(InventoryGui), "SetRecipe")] private class InventoryGuiPatch { private static void Postfix(KeyValuePair ___m_selectedRecipe) { if (!((Object)(object)___m_selectedRecipe.Key == (Object)null) && !TieredRequirements.TierZeroCappedPrefabs.Contains(((Object)___m_selectedRecipe.Key.m_item).name) && ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_maxQuality > 1) { ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_maxQuality = maxAllowedItemLevel.Value; } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private class ItemDropPatch { public static void Postfix(ItemDrop __instance) { if (ShouldIncrease(__instance.m_itemData)) { SharedData shared = __instance.m_itemData.m_shared; float value = statsIncrease.Value; shared.m_armorPerLevel = Mathf.Max(shared.m_armorPerLevel * value, 1f); shared.m_blockPowerPerLevel = Mathf.Max(shared.m_blockPowerPerLevel * value, 1f); shared.m_deflectionForcePerLevel = Mathf.Max(shared.m_deflectionForcePerLevel * value, 1f); shared.m_durabilityPerLevel = Mathf.Max(shared.m_durabilityPerLevel * value, 1f); ((DamageTypes)(ref shared.m_damagesPerLevel)).Modify(value); } } private static bool ShouldIncrease(ItemData d) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 return (int)d.m_shared.m_itemType != 9 && (int)d.m_shared.m_itemType != 15 && (int)d.m_shared.m_itemType != 18 && d.IsEquipable(); } } [HarmonyPatch(typeof(ObjectDB), "GetRecipe")] private class ObjectDBGetRecipePatch { public static IList patchedRecipes = new List(); public static void Postfix(Recipe __result) { ProcessRecipe(__result); } public static void ProcessRecipe(Recipe recipe) { if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || recipe.m_item.m_itemData.m_shared.m_maxQuality <= 1 || patchedRecipes.Contains(recipe)) { return; } float value = requiredResPerLevelReduce.Value; Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (val.m_amountPerLevel != 0) { float num = Mathf.Max((float)val.m_amountPerLevel / value, 1f); val.m_amountPerLevel = Mathf.FloorToInt(num); } } try { TieredRequirements.ApplyTieredMaterials(recipe); } catch (Exception arg) { Debug.LogError((object)$"[MoreUpgrades] EXCEPTION in ApplyTieredMaterials for '{((Object)recipe.m_item).name}': {arg}"); } patchedRecipes.Add(recipe); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private class ObjectDBAwakePatch { public static void Postfix(ObjectDB __instance) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected I4, but got Unknown if (__instance.m_recipes == null) { return; } foreach (Recipe recipe in __instance.m_recipes) { try { ObjectDBGetRecipePatch.ProcessRecipe(recipe); } catch (Exception arg) { Debug.LogError((object)$"[MoreUpgrades] EXCEPTION processing a recipe in ObjectDBAwakePatch: {arg}"); } } foreach (Recipe recipe2 in __instance.m_recipes) { try { if (!((Object)(object)recipe2 == (Object)null) && !((Object)(object)recipe2.m_item == (Object)null)) { SharedData shared = recipe2.m_item.m_itemData.m_shared; if (!(shared.m_armor <= 0f) || !(shared.m_armorPerLevel <= 0f)) { Debug.Log((object)$"[MoreUpgrades] ARMOR STAT DUMP: item='{((Object)recipe2.m_item).name}' itemType={(int)shared.m_itemType} armor={shared.m_armor} armorPerLevel={shared.m_armorPerLevel} movementModifier={shared.m_movementModifier} maxQuality={shared.m_maxQuality}"); } } } catch (Exception arg2) { Debug.LogError((object)$"[MoreUpgrades] EXCEPTION in armor stat dump for a recipe: {arg2}"); } } } } [HarmonyPatch(typeof(Recipe), "GetRequiredStationLevel")] private class RecipePatch { private static void Postfix(ref int __result, CraftingStation ___m_craftingStation) { if ((Object)(object)___m_craftingStation == (Object)null) { __result = Mathf.Min(__result, Mathf.Min(forgeLevelLock.Value, workbenchLevelLock.Value)); return; } string name = ___m_craftingStation.m_name; if (name == "$piece_forge") { __result = Mathf.Min(__result, forgeLevelLock.Value); } else if (!(name == "$piece_workbench")) { __result = Mathf.Min(__result, anyTableLevelLock.Value); } else { __result = Mathf.Min(__result, workbenchLevelLock.Value); } } } private const string modUUID = "SaltyCypher.MoreBettererUpgrades"; private const string modName = "MoreBettererUpgrades"; private const string modVersion = "1.0.0"; private readonly Harmony harmony = new Harmony("SaltyCypher.MoreBettererUpgrades"); private static ConfigEntry maxAllowedItemLevel; private static ConfigEntry forgeLevelLock; private static ConfigEntry workbenchLevelLock; private static ConfigEntry anyTableLevelLock; private static ConfigEntry requiredResPerLevelReduce; private static ConfigEntry statsIncrease; private void Awake() { maxAllowedItemLevel = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Max item level", 10, "Max item upgrade level"); forgeLevelLock = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Forge level lock", 7, "Max forge level recipe can have"); workbenchLevelLock = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Workbench level lock", 5, "Max workbench level recipe can have"); anyTableLevelLock = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Any table level lock", 1, "Max crafting table level recipe can have. Use it for locking any crafting table added by other mods, e.g. Terraheim"); requiredResPerLevelReduce = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Resource per level reduce", 1f, "Reduce per-level resource requirement (i.e. for 5 Iron per level and upgrade to 6 lvl: (6 - 1) * 5 = 25 Iron on upgarde, with reduce 2: 5 / 2 = 2.5 ~ 2 and total: (6 - 1) * 2 = 10)"); statsIncrease = ((BaseUnityPlugin)this).Config.Bind("MoreUpgrades", "Stats per level increase", 1f, "How many times multiply stats per level"); harmony.PatchAll(); } } internal class StatsUpdator { private IList patchedItemsData = new List(); public int CachedItemsCount => patchedItemsData.Count; public void UpdateStats(ItemData itemData, float multiplier) { if (CouldBePatched(itemData) && !patchedItemsData.Contains(itemData.m_shared)) { ApplyPatch(itemData.m_shared, multiplier); patchedItemsData.Add(itemData.m_shared); } } private void ApplyPatch(SharedData item, float multiplier) { item.m_armorPerLevel = Mathf.Max(item.m_armorPerLevel * multiplier, 1f); item.m_blockPowerPerLevel = Mathf.Max(item.m_blockPowerPerLevel * multiplier, 1f); item.m_deflectionForcePerLevel = Mathf.Max(item.m_deflectionForcePerLevel * multiplier, 1f); item.m_durabilityPerLevel = Mathf.Max(item.m_durabilityPerLevel * multiplier, 1f); ((DamageTypes)(ref item.m_damagesPerLevel)).Modify(multiplier); } private bool CouldBePatched(ItemData d) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 return (int)d.m_shared.m_itemType != 9 && (int)d.m_shared.m_itemType != 15 && (int)d.m_shared.m_itemType != 18 && d.IsEquipable(); } } internal static class TieredRequirements { private struct ThresholdInfo { public int IntroLevel; public int FreezeLevel; public int DropLevel; public int RealAmount; public int RealPerLevel; } [HarmonyPatch(typeof(Requirement), "GetAmount")] private static class RequirementGetAmountPatch { private static void Postfix(Requirement __instance, int qualityLevel, ref int __result) { if (RequirementInfo.TryGetValue(__instance, out var value)) { if (qualityLevel < value.IntroLevel || qualityLevel >= value.DropLevel) { __result = 0; return; } if (qualityLevel >= value.FreezeLevel) { __result = value.RealPerLevel; return; } int num = qualityLevel - value.IntroLevel + 1; __result = ((num <= 1) ? value.RealAmount : ((num - 1) * value.RealPerLevel)); } } } public static readonly List TierZeroCappedPrefabs = new List { "SwordWood", "AxeWood", "AxeFlint", "AxeStone", "AtgeirWood", "BattleaxeWood", "MaceWood", "SpearWood", "SpearFlint", "KnifeWood", "KnifeFlint", "KnifeCopper", "Bow", "BowFineWood", "SledgeWood", "SledgeStagbreaker", "ShieldWood", "ShieldWoodTower", "ShieldBoneTower", "THSwordWood", "FistBjornClaw", "Club", "ArmorRagsChest", "ArmorRagsLegs", "HelmetLeather", "ArmorLeatherChest", "ArmorLeatherLegs", "CapeDeerHide" }; private static readonly string[] TierMaterialPrefabs = new string[8] { null, "Bronze", "Iron", "Silver", "BlackMetal", "Carapace", "FlametalNew", "Gold" }; private static readonly Dictionary FamilyTierChains = new Dictionary { { "Sword", new string[8] { null, "SwordBronze", "SwordIron", "SwordSilver", "SwordBlackmetal", "SwordMistwalker", "SwordNiedhogg", "SwordGold" } }, { "Mace", new string[8] { null, "MaceBronze", "MaceIron", "MaceSilver", "MaceNeedle", null, "MaceEldner", "MaceGold" } }, { "Axe", new string[8] { null, "AxeBronze", "AxeIron", null, "AxeBlackMetal", "AxeJotunBane", "AxeBerzerkr", "AxeGold" } }, { "Atgeir", new string[8] { null, "AtgeirBronze", "AtgeirIron", null, "AtgeirBlackmetal", "AtgeirHimminAfl", null, "AtgeirGold" } }, { "Battleaxe", new string[8] { null, null, "Battleaxe", "BattleaxeCrystal", "BattleaxeBlackmetal", "BattleaxeSkullSplittur", null, "BattleaxeGold" } }, { "Pickaxe", new string[8] { null, "PickaxeBronze", "PickaxeIron", null, "PickaxeBlackMetal", null, null, null } }, { "Shield", new string[8] { null, "ShieldBronzeBuckler", "ShieldIronSquare", "ShieldSilver", "ShieldBlackmetal", "ShieldCarapace", "ShieldFlametal", "ShieldGold" } }, { "Spear", new string[8] { null, "SpearBronze", "SpearElderbark", "SpearWolfFang", null, "SpearCarapace", "SpearSplitner", "SpearGold" } }, { "Knife", new string[8] { null, null, null, "KnifeSilver", "KnifeBlackMetal", null, null, "KnifeGold" } }, { "Bow", new string[8] { null, null, "BowHuntsman", "BowDraugrFang", null, "BowSpineSnap", "BowAshlands", "BowGold" } }, { "Crossbow", new string[8] { null, null, "CrossbowArbalest", null, null, null, "CrossbowRipper", "CrossbowGold" } }, { "Fist", new string[8] { null, null, null, "FistFenrirClaw", "FistBjornUndeadClaw", null, null, "FistGold" } }, { "Sledge", new string[8] { null, null, "SledgeIron", null, null, "SledgeDemolisher", null, "SledgeGold" } }, { "THSword", new string[8] { null, null, null, null, null, "THSwordKrom", "THSwordSlayer", "THSwordGold" } }, { "Staff", new string[8] { null, null, null, null, null, "StaffFireball", "StaffLightning", "StaffOrbofAhri" } }, { "HeavyChest", new string[8] { null, "ArmorBronzeChest", "ArmorIronChest", "ArmorWolfChest", "ArmorPaddedCuirass", "ArmorCarapaceChest", "ArmorFlametalChest", null } }, { "HeavyHelmet", new string[8] { null, "HelmetBronze", "HelmetIron", "HelmetDrake", "HelmetPadded", "HelmetCarapace", "HelmetFlametal", null } }, { "HeavyLegs", new string[8] { null, "ArmorBronzeLegs", "ArmorIronLegs", "ArmorWolfLegs", "ArmorPaddedGreaves", "ArmorCarapaceLegs", "ArmorFlametalLegs", null } }, { "LightChest", new string[8] { "ArmorLeatherChest", "ArmorTrollLeatherChest", null, null, "ArmorLoxChest", null, "ArmorAshlandsMediumChest", "ArmorDeepNorthMediumChest" } }, { "LightHelmet", new string[8] { "HelmetLeather", "HelmetTrollLeather", null, null, "HelmetLox", null, "HelmetAshlandsMediumHood", "HelmetDNMediumHood" } }, { "LightLegs", new string[8] { "ArmorLeatherLegs", "ArmorTrollLeatherLegs", null, null, "ArmorLoxLegs", null, "ArmorAshlandsMediumlegs", "ArmorDeepNorthMediumlegs" } }, { "MediumChest", new string[8] { null, null, "ArmorRootChest", null, null, "ArmorMageChest", "ArmorMageChest_Ashlands", "ArmorDeepNorthMageChest" } }, { "MediumHelmet", new string[8] { null, null, "HelmetRoot", null, null, "HelmetMage", "HelmetMage_Ashlands", "HelmetDNMage" } }, { "MediumLegs", new string[8] { null, null, "ArmorRootLegs", null, null, "ArmorMageLegs", "ArmorMageLegs_Ashlands", "ArmorDeepNorthMagelegs" } }, { "UniqueChest", new string[8] { null, "ArmorBerserkerChest", null, "ArmorFenringChest", "ArmorBerserkerUndeadChest", null, null, null } }, { "UniqueHelmet", new string[8] { null, "HelmetBerserkerHood", null, "HelmetFenring", "HelmetBerserkerUndead", null, null, null } }, { "UniqueLegs", new string[8] { null, "ArmorBerserkerLegs", null, "ArmorFenringLegs", "ArmorBerserkerUndeadLegs", null, null, null } }, { "Cape", new string[8] { "CapeDeerHide", "CapeTrollHide", null, "CapeWolf", "CapeLinen", "CapeFeather", "CapeAsh", null } } }; private static readonly Dictionary ItemBaseTier = new Dictionary { { "SwordBronze", ("Sword", 1) }, { "SwordIron", ("Sword", 2) }, { "SwordSilver", ("Sword", 3) }, { "SwordBlackmetal", ("Sword", 4) }, { "SwordMistwalker", ("Sword", 5) }, { "SwordDyrnwyn", ("Sword", 6) }, { "SwordNiedhogg", ("Sword", 6) }, { "SwordNiedhoggBlood", ("Sword", 6) }, { "SwordNiedhoggLightning", ("Sword", 6) }, { "SwordNiedhoggNature", ("Sword", 6) }, { "MaceBronze", ("Mace", 1) }, { "MaceIron", ("Mace", 2) }, { "MaceSilver", ("Mace", 3) }, { "MaceNeedle", ("Mace", 4) }, { "MaceEldner", ("Mace", 6) }, { "MaceEldnerBlood", ("Mace", 6) }, { "MaceEldnerLightning", ("Mace", 6) }, { "MaceEldnerNature", ("Mace", 6) }, { "AxeBronze", ("Axe", 1) }, { "AxeEarly", ("Axe", 1) }, { "AxeIron", ("Axe", 2) }, { "AxeBlackMetal", ("Axe", 4) }, { "AxeJotunBane", ("Axe", 5) }, { "AxeBerzerkr", ("Axe", 6) }, { "AxeBerzerkrBlood", ("Axe", 6) }, { "AxeBerzerkrLightning", ("Axe", 6) }, { "AxeBerzerkrNature", ("Axe", 6) }, { "AtgeirBronze", ("Atgeir", 1) }, { "AtgeirIron", ("Atgeir", 2) }, { "AtgeirHimminAfl", ("Atgeir", 5) }, { "AtgeirBlackmetal", ("Atgeir", 4) }, { "Battleaxe", ("Battleaxe", 2) }, { "BattleaxeCrystal", ("Battleaxe", 3) }, { "BattleaxeBlackmetal", ("Battleaxe", 4) }, { "BattleaxeSkullSplittur", ("Battleaxe", 5) }, { "PickaxeBronze", ("Pickaxe", 1) }, { "PickaxeIron", ("Pickaxe", 2) }, { "PickaxeBlackMetal", ("Pickaxe", 4) }, { "ShieldBronzeBuckler", ("Shield", 1) }, { "ShieldBanded", ("Shield", 2) }, { "ShieldIronSquare", ("Shield", 2) }, { "ShieldRoots", ("Shield", 2) }, { "ShieldIronTower", ("Shield", 2) }, { "ShieldIronBuckler", ("Shield", 2) }, { "ShieldSerpentscale", ("Shield", 2) }, { "ShieldSilver", ("Shield", 3) }, { "ShieldBlackmetal", ("Shield", 4) }, { "ShieldBlackmetalTower", ("Shield", 4) }, { "ShieldCarapace", ("Shield", 5) }, { "ShieldCarapaceBuckler", ("Shield", 5) }, { "ShieldFlametal", ("Shield", 6) }, { "ShieldFlametalTower", ("Shield", 6) }, { "SpearBronze", ("Spear", 1) }, { "SpearElderbark", ("Spear", 2) }, { "SpearWolfFang", ("Spear", 3) }, { "SpearCarapace", ("Spear", 5) }, { "SpearSplitner", ("Spear", 6) }, { "SpearSplitner_Blood", ("Spear", 6) }, { "SpearSplitner_Nature", ("Spear", 6) }, { "SpearSplitner_Lightning", ("Spear", 6) }, { "KnifeSilver", ("Knife", 3) }, { "KnifeChitin", ("Knife", 1) }, { "KnifeBlackMetal", ("Knife", 4) }, { "KnifeSkollAndHati", ("Knife", 4) }, { "BowHuntsman", ("Bow", 2) }, { "BowDraugrFang", ("Bow", 3) }, { "BowSpineSnap", ("Bow", 5) }, { "BowAshlands", ("Bow", 6) }, { "BowAshlandsBlood", ("Bow", 6) }, { "BowAshlandsStorm", ("Bow", 6) }, { "BowAshlandsRoot", ("Bow", 6) }, { "CrossbowArbalest", ("Crossbow", 2) }, { "CrossbowRipper", ("Crossbow", 6) }, { "CrossbowRipperBlood", ("Crossbow", 6) }, { "CrossbowRipperLightning", ("Crossbow", 6) }, { "CrossbowRipperNature", ("Crossbow", 6) }, { "FistFenrirClaw", ("Fist", 3) }, { "FistBjornUndeadClaw", ("Fist", 4) }, { "SledgeIron", ("Sledge", 2) }, { "SledgeDemolisher", ("Sledge", 5) }, { "SwordGold", ("Sword", 7) }, { "SwordGold_BloodLightning", ("Sword", 7) }, { "SwordGold_FrostFire", ("Sword", 7) }, { "AxeGold", ("Axe", 7) }, { "AxeGold_BloodLightning", ("Axe", 7) }, { "AxeGold_FrostFire", ("Axe", 7) }, { "AtgeirGold", ("Atgeir", 7) }, { "AtgeirGold_BloodLightning", ("Atgeir", 7) }, { "AtgeirGold_FrostFire", ("Atgeir", 7) }, { "BattleaxeGold", ("Battleaxe", 7) }, { "BattleaxeGold_BloodLightning", ("Battleaxe", 7) }, { "BattleaxeGold_FrostFire", ("Battleaxe", 7) }, { "MaceGold", ("Mace", 7) }, { "MaceGold_BloodLightning", ("Mace", 7) }, { "MaceGold_FrostFire", ("Mace", 7) }, { "SpearGold", ("Spear", 7) }, { "SpearGold_BloodLightning", ("Spear", 7) }, { "SpearGold_FrostFire", ("Spear", 7) }, { "BowGold", ("Bow", 7) }, { "BowGold_BloodLightning", ("Bow", 7) }, { "BowGold_FrostFire", ("Bow", 7) }, { "CrossbowGold", ("Crossbow", 7) }, { "CrossbowGold_BloodLightning", ("Crossbow", 7) }, { "CrossbowGold_FrostFire", ("Crossbow", 7) }, { "KnifeGold", ("Knife", 7) }, { "KnifeVoid", ("Knife", 7) }, { "KnifeGold_BloodLightning", ("Knife", 7) }, { "KnifeGold_FrostFire", ("Knife", 7) }, { "FistGold", ("Fist", 7) }, { "FistGold_BloodLightning", ("Fist", 7) }, { "FistGold_FrostFire", ("Fist", 7) }, { "SledgeGold", ("Sledge", 7) }, { "SledgeGold_BloodLightning", ("Sledge", 7) }, { "SledgeGold_FrostFire", ("Sledge", 7) }, { "ShieldGold", ("Shield", 7) }, { "ShieldGoldTower", ("Shield", 7) }, { "ShieldGoldBuckler", ("Shield", 7) }, { "THSwordSlayer", ("THSword", 6) }, { "THSwordKrom", ("THSword", 5) }, { "THSwordSlayerBlood", ("THSword", 6) }, { "THSwordSlayerLightning", ("THSword", 6) }, { "THSwordSlayerNature", ("THSword", 6) }, { "THSwordGold", ("THSword", 7) }, { "THSwordGold_BloodLightning", ("THSword", 7) }, { "THSwordGold_FrostFire", ("THSword", 7) }, { "StaffFireball", ("Staff", 5) }, { "StaffIceShards", ("Staff", 5) }, { "StaffShield", ("Staff", 5) }, { "StaffSkeleton", ("Staff", 5) }, { "StaffClusterbomb", ("Staff", 6) }, { "StaffGreenRoots", ("Staff", 6) }, { "StaffLightning", ("Staff", 6) }, { "StaffRedTroll", ("Staff", 6) }, { "StaffFrostOrbs", ("Staff", 7) }, { "StaffOrbofAhri", ("Staff", 7) }, { "StaffSpiritCaller", ("Staff", 7) }, { "StaffThunderBlood", ("Staff", 7) }, { "ArmorRagsChest", ("LightChest", 0) }, { "ArmorRagsLegs", ("LightLegs", 0) }, { "HelmetLeather", ("LightHelmet", 0) }, { "ArmorLeatherChest", ("LightChest", 0) }, { "ArmorLeatherLegs", ("LightLegs", 0) }, { "HelmetTrollLeather", ("LightHelmet", 1) }, { "ArmorTrollLeatherChest", ("LightChest", 1) }, { "ArmorTrollLeatherLegs", ("LightLegs", 1) }, { "HelmetBronze", ("HeavyHelmet", 1) }, { "ArmorBronzeChest", ("HeavyChest", 1) }, { "ArmorBronzeLegs", ("HeavyLegs", 1) }, { "HelmetBerserkerHood", ("UniqueHelmet", 1) }, { "ArmorBerserkerChest", ("UniqueChest", 1) }, { "ArmorBerserkerLegs", ("UniqueLegs", 1) }, { "HelmetRoot", ("MediumHelmet", 2) }, { "ArmorRootChest", ("MediumChest", 2) }, { "ArmorRootLegs", ("MediumLegs", 2) }, { "HelmetIron", ("HeavyHelmet", 2) }, { "ArmorIronChest", ("HeavyChest", 2) }, { "ArmorIronLegs", ("HeavyLegs", 2) }, { "HelmetDrake", ("HeavyHelmet", 3) }, { "ArmorWolfChest", ("HeavyChest", 3) }, { "ArmorWolfLegs", ("HeavyLegs", 3) }, { "HelmetFenring", ("UniqueHelmet", 3) }, { "ArmorFenringChest", ("UniqueChest", 3) }, { "ArmorFenringLegs", ("UniqueLegs", 3) }, { "HelmetLox", ("LightHelmet", 4) }, { "ArmorLoxChest", ("LightChest", 4) }, { "ArmorLoxLegs", ("LightLegs", 4) }, { "HelmetPadded", ("HeavyHelmet", 4) }, { "ArmorPaddedCuirass", ("HeavyChest", 4) }, { "ArmorPaddedGreaves", ("HeavyLegs", 4) }, { "HelmetBerserkerUndead", ("UniqueHelmet", 4) }, { "ArmorBerserkerUndeadChest", ("UniqueChest", 4) }, { "ArmorBerserkerUndeadLegs", ("UniqueLegs", 4) }, { "HelmetMage", ("MediumHelmet", 5) }, { "ArmorMageChest", ("MediumChest", 5) }, { "ArmorMageLegs", ("MediumLegs", 5) }, { "HelmetCarapace", ("HeavyHelmet", 5) }, { "ArmorCarapaceChest", ("HeavyChest", 5) }, { "ArmorCarapaceLegs", ("HeavyLegs", 5) }, { "HelmetFlametal", ("HeavyHelmet", 6) }, { "ArmorFlametalChest", ("HeavyChest", 6) }, { "ArmorFlametalLegs", ("HeavyLegs", 6) }, { "HelmetMage_Ashlands", ("MediumHelmet", 6) }, { "ArmorMageChest_Ashlands", ("MediumChest", 6) }, { "ArmorMageLegs_Ashlands", ("MediumLegs", 6) }, { "HelmetAshlandsMediumHood", ("LightHelmet", 6) }, { "ArmorAshlandsMediumChest", ("LightChest", 6) }, { "ArmorAshlandsMediumlegs", ("LightLegs", 6) }, { "HelmetDNMage", ("MediumHelmet", 7) }, { "ArmorDeepNorthMageChest", ("MediumChest", 7) }, { "ArmorDeepNorthMagelegs", ("MediumLegs", 7) }, { "HelmetDNMediumHood", ("LightHelmet", 7) }, { "ArmorDeepNorthMediumChest", ("LightChest", 7) }, { "ArmorDeepNorthMediumlegs", ("LightLegs", 7) }, { "CapeDeerHide", ("Cape", 0) }, { "CapeTrollHide", ("Cape", 1) }, { "CapeWolf", ("Cape", 3) }, { "CapeLinen", ("Cape", 4) }, { "CapeLox", ("Cape", 4) }, { "CapeFeather", ("Cape", 5) }, { "CapeAsh", ("Cape", 6) }, { "CapeAsksvin", ("Cape", 6) } }; private static readonly (int level, int tiersAhead)[] Thresholds = new(int, int)[2] { (5, 1), (8, 2) }; private static readonly Dictionary RequirementInfo = new Dictionary(); private static readonly Dictionary> FamilyMaterialOverride = new Dictionary> { { "Staff", new Dictionary { { 5, "Eitr" }, { 6, "Blackwood" }, { 7, "NornThread" } } }, { "HeavyChest", new Dictionary { { 1, "Bronze" }, { 2, "Iron" }, { 3, "Silver" }, { 4, "LinenThread" }, { 5, "Carapace" }, { 6, "FlametalNew" }, { 7, "Gold" } } }, { "HeavyHelmet", new Dictionary { { 1, "Bronze" }, { 2, "Iron" }, { 3, "Silver" }, { 4, "LinenThread" }, { 5, "Carapace" }, { 6, "FlametalNew" }, { 7, "Gold" } } }, { "HeavyLegs", new Dictionary { { 1, "Bronze" }, { 2, "Iron" }, { 3, "Silver" }, { 4, "LinenThread" }, { 5, "Carapace" }, { 6, "FlametalNew" }, { 7, "Gold" } } }, { "LightChest", new Dictionary { { 1, "TrollHide" }, { 2, "Guck" }, { 3, "WolfPelt" }, { 4, "LoxPelt" }, { 5, "ScaleHide" }, { 6, "AskHide" }, { 7, "ElakingHairBundle" } } }, { "LightHelmet", new Dictionary { { 1, "TrollHide" }, { 2, "Guck" }, { 3, "WolfPelt" }, { 4, "LoxPelt" }, { 5, "ScaleHide" }, { 6, "AskHide" }, { 7, "ElakingHairBundle" } } }, { "LightLegs", new Dictionary { { 1, "TrollHide" }, { 2, "Guck" }, { 3, "WolfPelt" }, { 4, "LoxPelt" }, { 5, "ScaleHide" }, { 6, "AskHide" }, { 7, "ElakingHairBundle" } } }, { "MediumChest", new Dictionary { { 2, "Ooze" }, { 3, "Obsidian" }, { 4, "Tar" }, { 5, "Eitr" }, { 6, "MorgenSinew" }, { 7, "MooseHide" } } }, { "MediumHelmet", new Dictionary { { 2, "Ooze" }, { 3, "Obsidian" }, { 4, "Tar" }, { 5, "Eitr" }, { 6, "MorgenSinew" }, { 7, "MooseHide" } } }, { "MediumLegs", new Dictionary { { 2, "Ooze" }, { 3, "Obsidian" }, { 4, "Tar" }, { 5, "Eitr" }, { 6, "MorgenSinew" }, { 7, "MooseHide" } } }, { "UniqueChest", new Dictionary { { 1, "BjornHide" }, { 2, "Root" }, { 3, "WolfHairBundle" }, { 4, "UndeadBjornRibcage" }, { 5, "Bilebag" }, { 6, "Charredskull" } } }, { "UniqueHelmet", new Dictionary { { 1, "BjornHide" }, { 2, "Root" }, { 3, "WolfHairBundle" }, { 4, "UndeadBjornRibcage" }, { 5, "Bilebag" }, { 6, "Charredskull" } } }, { "UniqueLegs", new Dictionary { { 1, "BjornHide" }, { 2, "Root" }, { 3, "WolfHairBundle" }, { 4, "UndeadBjornRibcage" }, { 5, "Bilebag" }, { 6, "Charredskull" } } }, { "Cape", new Dictionary { { 1, "TrollHide" }, { 2, "ElderBark" }, { 3, "WolfPelt" }, { 4, "LoxPelt" }, { 5, "ScaleHide" }, { 6, "AskHide" } } } }; private static readonly Dictionary BaseMaterialOverride = new Dictionary { { "StaffRedTroll", "FlametalNew" }, { "THSwordKrom", "Iron" }, { "AtgeirHimminAfl", "Silver" }, { "BattleaxeSkullSplittur", "Iron" }, { "AxeJotunBane", "Iron" }, { "SwordMistwalker", "Iron" }, { "SledgeDemolisher", "Iron" }, { "MaceNeedle", "Iron" }, { "KnifeChitin", "Chitin" }, { "BowSpineSnap", "Eitr" }, { "ArmorRagsChest", "LeatherScraps" }, { "ArmorRagsLegs", "LeatherScraps" }, { "HelmetLeather", "DeerHide" }, { "ArmorLeatherChest", "DeerHide" }, { "ArmorLeatherLegs", "DeerHide" }, { "HelmetTrollLeather", "TrollHide" }, { "ArmorTrollLeatherChest", "TrollHide" }, { "ArmorTrollLeatherLegs", "TrollHide" }, { "HelmetBronze", "Bronze" }, { "ArmorBronzeChest", "Bronze" }, { "ArmorBronzeLegs", "Bronze" }, { "HelmetBerserkerHood", "BjornHide" }, { "ArmorBerserkerChest", "BjornHide" }, { "ArmorBerserkerLegs", "BjornHide" }, { "HelmetRoot", "Root" }, { "ArmorRootChest", "Root" }, { "ArmorRootLegs", "Root" }, { "HelmetIron", "Iron" }, { "ArmorIronChest", "Iron" }, { "ArmorIronLegs", "Iron" }, { "HelmetDrake", "Silver" }, { "ArmorWolfChest", "Silver" }, { "ArmorWolfLegs", "Silver" }, { "HelmetFenring", "WolfHairBundle" }, { "ArmorFenringChest", "WolfHairBundle" }, { "ArmorFenringLegs", "WolfHairBundle" }, { "HelmetLox", "LoxPelt" }, { "ArmorLoxChest", "LoxPelt" }, { "ArmorLoxLegs", "LoxPelt" }, { "HelmetPadded", "LinenThread" }, { "ArmorPaddedCuirass", "LinenThread" }, { "ArmorPaddedGreaves", "LinenThread" }, { "HelmetBerserkerUndead", "UndeadBjornRibcage" }, { "ArmorBerserkerUndeadChest", "UndeadBjornRibcage" }, { "ArmorBerserkerUndeadLegs", "UndeadBjornRibcage" }, { "HelmetMage", "Eitr" }, { "ArmorMageChest", "Eitr" }, { "ArmorMageLegs", "Eitr" }, { "HelmetCarapace", "Carapace" }, { "ArmorCarapaceChest", "Carapace" }, { "ArmorCarapaceLegs", "Carapace" }, { "HelmetFlametal", "FlametalNew" }, { "ArmorFlametalChest", "FlametalNew" }, { "ArmorFlametalLegs", "FlametalNew" }, { "HelmetMage_Ashlands", "AskHide" }, { "ArmorMageChest_Ashlands", "AskHide" }, { "ArmorMageLegs_Ashlands", "AskHide" }, { "HelmetAshlandsMediumHood", "AskHide" }, { "ArmorAshlandsMediumChest", "AskHide" }, { "ArmorAshlandsMediumlegs", "AskHide" }, { "HelmetDNMage", "MooseHide" }, { "ArmorDeepNorthMageChest", "MooseHide" }, { "ArmorDeepNorthMagelegs", "MooseHide" }, { "HelmetDNMediumHood", "ElakingHairBundle" }, { "ArmorDeepNorthMediumChest", "ElakingHairBundle" }, { "ArmorDeepNorthMediumlegs", "ElakingHairBundle" }, { "CapeDeerHide", "DeerHide" }, { "CapeTrollHide", "TrollHide" }, { "CapeWolf", "WolfPelt" }, { "CapeLinen", "LinenThread" }, { "CapeLox", "LoxPelt" }, { "CapeFeather", "ScaleHide" }, { "CapeAsh", "AskHide" }, { "CapeAsksvin", "AskHide" }, { "AxeEarly", "LeatherScraps" }, { "ShieldRoots", "WrithanRoots" } }; private static string GetMaterialForTier(string family, int tier) { if (FamilyMaterialOverride.TryGetValue(family, out var value) && value.TryGetValue(tier, out var value2)) { return value2; } return (tier >= 0 && tier < TierMaterialPrefabs.Length) ? TierMaterialPrefabs[tier] : null; } public static void ApplyTieredMaterials(Recipe recipe) { //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown string name = ((Object)recipe.m_item).name; if (!ItemBaseTier.TryGetValue(name, out (string, int) value) || TierZeroCappedPrefabs.Contains(name) || !FamilyTierChains.TryGetValue(value.Item1, out var value2)) { return; } string value3; string text = (BaseMaterialOverride.TryGetValue(name, out value3) ? value3 : GetMaterialForTier(value.Item1, value.Item2)); Requirement val = null; Requirement[] resources = recipe.m_resources; foreach (Requirement val2 in resources) { if ((Object)(object)val2.m_resItem != (Object)null && ((Object)val2.m_resItem).name == text) { val = val2; break; } } List<(Requirement, int)> list = new List<(Requirement, int)>(); Dictionary dictionary = new Dictionary(); if (val != null) { list.Add((val, 1)); } List list2 = new List(recipe.m_resources); (int, int)[] thresholds = Thresholds; for (int j = 0; j < thresholds.Length; j++) { (int, int) tuple = thresholds[j]; int item = tuple.Item1; int item2 = tuple.Item2; int num = value.Item2 + item2; if (num >= TierMaterialPrefabs.Length) { break; } string materialForTier = GetMaterialForTier(value.Item1, num); string siblingItemPrefab = ((num < value2.Length) ? value2[num] : null); int amount; int amountPerLevel; if (siblingItemPrefab != null) { Recipe val3 = ObjectDB.instance.m_recipes.Find((Recipe r) => (Object)(object)r.m_item != (Object)null && ((Object)r.m_item).name == siblingItemPrefab); if ((Object)(object)val3 == (Object)null) { Debug.LogWarning((object)("[MoreUpgrades] Could not find a recipe that crafts '" + siblingItemPrefab + "' while tiering " + name + ".")); break; } Requirement val4 = null; Requirement[] resources2 = val3.m_resources; foreach (Requirement val5 in resources2) { if ((Object)(object)val5.m_resItem != (Object)null && ((Object)val5.m_resItem).name == materialForTier) { val4 = val5; break; } } if (val4 == null) { Debug.LogWarning((object)("[MoreUpgrades] Recipe for '" + siblingItemPrefab + "' has no '" + materialForTier + "' requirement.")); break; } amount = val4.m_amount; amountPerLevel = val4.m_amountPerLevel; } else { if (list.Count == 0) { break; } Requirement item3 = list[list.Count - 1].Item1; amount = item3.m_amount; amountPerLevel = item3.m_amountPerLevel; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(materialForTier); ItemDrop val6 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val6 == (Object)null) { Debug.LogWarning((object)("[MoreUpgrades] Could not find material prefab '" + materialForTier + "'.")); break; } Requirement val7 = new Requirement { m_resItem = val6, m_amount = 0, m_amountPerLevel = 0, m_recover = true }; list2.Add(val7); list.Add((val7, item)); dictionary[val7] = (amount, amountPerLevel); } for (int num3 = 0; num3 < list.Count; num3++) { int freezeLevel = ((num3 + 1 < list.Count) ? list[num3 + 1].Item2 : int.MaxValue); int dropLevel = ((num3 + 2 < list.Count) ? list[num3 + 2].Item2 : int.MaxValue); Requirement item4 = list[num3].Item1; int num4; if (!dictionary.TryGetValue(item4, out var value4)) { num4 = item4.m_amount; } else { (num4, _) = value4; } int realAmount = num4; int realPerLevel = (dictionary.TryGetValue(item4, out value4) ? value4.Item2 : item4.m_amountPerLevel); RequirementInfo[item4] = new ThresholdInfo { IntroLevel = list[num3].Item2, FreezeLevel = freezeLevel, DropLevel = dropLevel, RealAmount = realAmount, RealPerLevel = realPerLevel }; } recipe.m_resources = list2.ToArray(); } }