Decompiled source of MoreBettererUpgrades v1.1.2

MoreUpgrades.dll

Decompiled 37 minutes ago
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<Recipe, ItemData> ___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<Recipe> patchedRecipes = new List<Recipe>();

		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<int> maxAllowedItemLevel;

	private static ConfigEntry<int> forgeLevelLock;

	private static ConfigEntry<int> workbenchLevelLock;

	private static ConfigEntry<int> anyTableLevelLock;

	private static ConfigEntry<float> requiredResPerLevelReduce;

	private static ConfigEntry<float> statsIncrease;

	private void Awake()
	{
		maxAllowedItemLevel = ((BaseUnityPlugin)this).Config.Bind<int>("MoreUpgrades", "Max item level", 10, "Max item upgrade level");
		forgeLevelLock = ((BaseUnityPlugin)this).Config.Bind<int>("MoreUpgrades", "Forge level lock", 7, "Max forge level recipe can have");
		workbenchLevelLock = ((BaseUnityPlugin)this).Config.Bind<int>("MoreUpgrades", "Workbench level lock", 5, "Max workbench level recipe can have");
		anyTableLevelLock = ((BaseUnityPlugin)this).Config.Bind<int>("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<float>("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<float>("MoreUpgrades", "Stats per level increase", 1f, "How many times multiply stats per level");
		harmony.PatchAll();
	}
}
internal class StatsUpdator
{
	private IList<SharedData> patchedItemsData = new List<SharedData>();

	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<string> TierZeroCappedPrefabs = new List<string>
	{
		"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<string, string[]> FamilyTierChains = new Dictionary<string, string[]>
	{
		{
			"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<string, (string family, int tier)> ItemBaseTier = new Dictionary<string, (string, int)>
	{
		{
			"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<Requirement, ThresholdInfo> RequirementInfo = new Dictionary<Requirement, ThresholdInfo>();

	private static readonly Dictionary<string, Dictionary<int, string>> FamilyMaterialOverride = new Dictionary<string, Dictionary<int, string>>
	{
		{
			"Staff",
			new Dictionary<int, string>
			{
				{ 5, "Eitr" },
				{ 6, "Blackwood" },
				{ 7, "NornThread" }
			}
		},
		{
			"HeavyChest",
			new Dictionary<int, string>
			{
				{ 1, "Bronze" },
				{ 2, "Iron" },
				{ 3, "Silver" },
				{ 4, "LinenThread" },
				{ 5, "Carapace" },
				{ 6, "FlametalNew" },
				{ 7, "Gold" }
			}
		},
		{
			"HeavyHelmet",
			new Dictionary<int, string>
			{
				{ 1, "Bronze" },
				{ 2, "Iron" },
				{ 3, "Silver" },
				{ 4, "LinenThread" },
				{ 5, "Carapace" },
				{ 6, "FlametalNew" },
				{ 7, "Gold" }
			}
		},
		{
			"HeavyLegs",
			new Dictionary<int, string>
			{
				{ 1, "Bronze" },
				{ 2, "Iron" },
				{ 3, "Silver" },
				{ 4, "LinenThread" },
				{ 5, "Carapace" },
				{ 6, "FlametalNew" },
				{ 7, "Gold" }
			}
		},
		{
			"LightChest",
			new Dictionary<int, string>
			{
				{ 1, "TrollHide" },
				{ 2, "Guck" },
				{ 3, "WolfPelt" },
				{ 4, "LoxPelt" },
				{ 5, "ScaleHide" },
				{ 6, "AskHide" },
				{ 7, "ElakingHairBundle" }
			}
		},
		{
			"LightHelmet",
			new Dictionary<int, string>
			{
				{ 1, "TrollHide" },
				{ 2, "Guck" },
				{ 3, "WolfPelt" },
				{ 4, "LoxPelt" },
				{ 5, "ScaleHide" },
				{ 6, "AskHide" },
				{ 7, "ElakingHairBundle" }
			}
		},
		{
			"LightLegs",
			new Dictionary<int, string>
			{
				{ 1, "TrollHide" },
				{ 2, "Guck" },
				{ 3, "WolfPelt" },
				{ 4, "LoxPelt" },
				{ 5, "ScaleHide" },
				{ 6, "AskHide" },
				{ 7, "ElakingHairBundle" }
			}
		},
		{
			"MediumChest",
			new Dictionary<int, string>
			{
				{ 2, "Ooze" },
				{ 3, "Obsidian" },
				{ 4, "Tar" },
				{ 5, "Eitr" },
				{ 6, "MorgenSinew" },
				{ 7, "MooseHide" }
			}
		},
		{
			"MediumHelmet",
			new Dictionary<int, string>
			{
				{ 2, "Ooze" },
				{ 3, "Obsidian" },
				{ 4, "Tar" },
				{ 5, "Eitr" },
				{ 6, "MorgenSinew" },
				{ 7, "MooseHide" }
			}
		},
		{
			"MediumLegs",
			new Dictionary<int, string>
			{
				{ 2, "Ooze" },
				{ 3, "Obsidian" },
				{ 4, "Tar" },
				{ 5, "Eitr" },
				{ 6, "MorgenSinew" },
				{ 7, "MooseHide" }
			}
		},
		{
			"UniqueChest",
			new Dictionary<int, string>
			{
				{ 1, "BjornHide" },
				{ 2, "Root" },
				{ 3, "WolfHairBundle" },
				{ 4, "UndeadBjornRibcage" },
				{ 5, "Bilebag" },
				{ 6, "Charredskull" }
			}
		},
		{
			"UniqueHelmet",
			new Dictionary<int, string>
			{
				{ 1, "BjornHide" },
				{ 2, "Root" },
				{ 3, "WolfHairBundle" },
				{ 4, "UndeadBjornRibcage" },
				{ 5, "Bilebag" },
				{ 6, "Charredskull" }
			}
		},
		{
			"UniqueLegs",
			new Dictionary<int, string>
			{
				{ 1, "BjornHide" },
				{ 2, "Root" },
				{ 3, "WolfHairBundle" },
				{ 4, "UndeadBjornRibcage" },
				{ 5, "Bilebag" },
				{ 6, "Charredskull" }
			}
		},
		{
			"Cape",
			new Dictionary<int, string>
			{
				{ 1, "TrollHide" },
				{ 2, "ElderBark" },
				{ 3, "WolfPelt" },
				{ 4, "LoxPelt" },
				{ 5, "ScaleHide" },
				{ 6, "AskHide" }
			}
		}
	};

	private static readonly Dictionary<string, string> BaseMaterialOverride = new Dictionary<string, string>
	{
		{ "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<Requirement, (int, int)> dictionary = new Dictionary<Requirement, (int, int)>();
		if (val != null)
		{
			list.Add((val, 1));
		}
		List<Requirement> list2 = new List<Requirement>(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<ItemDrop>() : 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();
	}
}