Decompiled source of ValheimRarity v4.4.0

plugins/ValheimRarity/ValheimRarity.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ValheimRarity")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("4.4.0.0")]
[assembly: AssemblyInformationalVersion("4.4.0")]
[assembly: AssemblyProduct("ValheimRarity")]
[assembly: AssemblyTitle("ValheimRarity")]
[assembly: AssemblyVersion("4.4.0.0")]
[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 ValheimRarity
{
	internal static class Borders
	{
		private const string RootName = "RarityBorder";

		private static Sprite raritySprite;

		private static Sprite Sprite()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)raritySprite))
			{
				return raritySprite;
			}
			using Stream stream = typeof(Borders).Assembly.GetManifestResourceStream("ValheimRarity.RarityFrame.png");
			using MemoryStream memoryStream = new MemoryStream();
			if (stream == null)
			{
				throw new InvalidOperationException("Missing rarity frame resource.");
			}
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			MethodInfo method = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: true).GetMethod("LoadImage", new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			});
			if (method == null || !(bool)method.Invoke(null, new object[3]
			{
				val,
				memoryStream.ToArray(),
				false
			}))
			{
				throw new InvalidOperationException("Could not load the Epic Loot rarity frame.");
			}
			((Object)val).name = "ValheimRarity-RarityFrame";
			((Texture)val).wrapMode = (TextureWrapMode)1;
			raritySprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)raritySprite).name = "ValheimRarity-RarityFrame";
			return raritySprite;
		}

		internal static void Set(Transform parent, int tier)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Transform val = parent.Find("RarityBorder");
			if (tier < 0)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.SetActive(false);
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				GameObject val2 = new GameObject("RarityBorder", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val = val2.transform;
				val.SetParent(parent, false);
				RectTransform val3 = (RectTransform)val;
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				val3.offsetMin = Vector2.zero;
				val3.offsetMax = Vector2.zero;
				Image component = val2.GetComponent<Image>();
				component.sprite = Sprite();
				component.preserveAspect = true;
				((Graphic)component).raycastTarget = false;
			}
			Color color = default(Color);
			ColorUtility.TryParseHtmlString(Settings.RarityColor(tier), ref color);
			((Graphic)((Component)val).GetComponent<Image>()).color = color;
			((Component)val).gameObject.SetActive(true);
			Transform val4 = parent.Find("equiped");
			if (Object.op_Implicit((Object)(object)val4))
			{
				int num = val4.GetSiblingIndex();
				if (val.GetSiblingIndex() < num)
				{
					num--;
				}
				val.SetSiblingIndex(num);
			}
			else
			{
				val.SetAsFirstSibling();
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
	internal static class InventoryBorders
	{
		private static void Postfix(InventoryGrid __instance, List<InventoryElement> ___m_elements)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = __instance.GetInventory();
			List<ItemData> list = ((inventory != null) ? inventory.GetAllItems() : null);
			foreach (InventoryElement ___m_element in ___m_elements)
			{
				ItemData item = null;
				if (list != null)
				{
					foreach (ItemData item2 in list)
					{
						if (item2.m_gridPos.x == ___m_element.Position.x && item2.m_gridPos.y == ___m_element.Position.y)
						{
							item = item2;
							break;
						}
					}
				}
				Borders.Set(((Component)___m_element.m_button).transform, Plugin.Tier(item));
			}
		}
	}
	internal static class ItemNames
	{
		internal static string Decorate(ItemData item, string original)
		{
			int num = Plugin.Tier(item);
			if (num >= 0)
			{
				ConfigEntry<bool> prefixNames = Settings.PrefixNames;
				if ((prefixNames == null || prefixNames.Value) && !string.IsNullOrEmpty(original))
				{
					string text = "<color=" + Settings.RarityColor(num) + ">" + Settings.RarityName(num) + " ";
					if (original.StartsWith(text, StringComparison.Ordinal))
					{
						return original;
					}
					return text + original + "</color>";
				}
			}
			return original;
		}

		internal static string Localized(ItemData item)
		{
			return Decorate(item, Localization.instance.Localize(item.m_shared.m_name));
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")]
	internal static class NamedTooltips
	{
		[HarmonyPriority(0)]
		private static void Postfix(ItemData __0, UITooltip __1)
		{
			__1.m_topic = ItemNames.Decorate(__0, __1.m_topic);
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
	internal static class NamedDropText
	{
		[HarmonyPriority(0)]
		private static void Postfix(ItemDrop __instance, ref string __result)
		{
			ItemData itemData = __instance.m_itemData;
			if (Plugin.Tier(itemData) < 0)
			{
				return;
			}
			ConfigEntry<bool> prefixNames = Settings.PrefixNames;
			if (prefixNames == null || prefixNames.Value)
			{
				string text = Localization.instance.Localize(itemData.m_shared.m_name);
				string text2 = ItemNames.Decorate(itemData, text);
				__result = Localization.instance.Localize(__result);
				if (!__result.Contains(text2))
				{
					__result = __result.Replace(text, text2);
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")]
	internal static class NamedVanillaUpgrade
	{
		[HarmonyPriority(0)]
		private static void Postfix(InventoryGui __instance)
		{
			if (!Station.Active)
			{
				object value = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe").GetValue(__instance);
				object? value2 = AccessTools.Property(value.GetType(), "ItemData").GetValue(value);
				ItemData item = (ItemData)((value2 is ItemData) ? value2 : null);
				if (Plugin.Tier(item) >= 0)
				{
					__instance.m_recipeName.text = ItemNames.Decorate(item, __instance.m_recipeName.text);
					__instance.m_upgradeItemName.text = ItemNames.Decorate(item, __instance.m_upgradeItemName.text);
				}
			}
		}
	}
	[BepInPlugin("laugh.valheim.rarity", "Valheim Rarity", "4.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "laugh.valheim.rarity";

		internal const string RarityKey = "laugh.valheim.rarity.tier";

		internal const string ElementKey = "laugh.valheim.rarity.element";

		internal const string UpgradedKey = "laugh.valheim.rarity.stationUpgrade";

		internal static readonly string[] Names = new string[6] { "Uncommon", "Common", "Rare", "Epic", "Legendary", "Mythic" };

		internal static readonly string[] Colors = new string[6] { "#43C86B", "#E0E0E0", "#409EFF", "#B266FF", "#FFAA33", "#FF4568" };

		internal static readonly ConfigEntry<float>[] Multipliers = new ConfigEntry<float>[6];

		internal static ConfigEntry<float> ElementFraction;

		private Harmony harmony;

		internal static void InitializeConfig(ConfigFile config)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			for (int i = 0; i < 6; i++)
			{
				Multipliers[i] = ServerConfiguration.Bind(config, "Stats", Names[i], (float)i + 2f, new ConfigDescription("Legacy tier multiplier; initial default for new per-stat settings and version 1 migration.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			}
			ElementFraction = ServerConfiguration.Bind(config, "Effects", "ElementalDamageFraction", 0.25f, new ConfigDescription("Extra elemental damage as a fraction of boosted combat damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			Settings.Initialize(config);
		}

		private void Awake()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			InitializeConfig(((BaseUnityPlugin)this).Config);
			ServerConfiguration.Start(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			PrefabManager.OnVanillaPrefabsAvailable += Station.Register;
			harmony = new Harmony("laugh.valheim.rarity");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Valheim Rarity loaded.");
		}

		private void Update()
		{
			ServerConfiguration.Tick();
		}

		private void OnDestroy()
		{
			ServerConfiguration.Stop();
			PrefabManager.OnVanillaPrefabsAvailable -= Station.Register;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		internal static bool Eligible(ItemData item)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected I4, but got Unknown
			if (item?.m_shared == null)
			{
				return false;
			}
			string prefab = Settings.Prefab(item);
			if (Settings.Listed(Settings.ExcludedItems, prefab))
			{
				return false;
			}
			if (Settings.Listed(Settings.ExtraEquipment, prefab) || Settings.Listed(Settings.ExtraTools, prefab))
			{
				return true;
			}
			ItemType itemType = item.m_shared.m_itemType;
			switch (itemType - 3)
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 8:
			case 9:
			case 11:
			case 12:
			case 14:
			case 16:
			case 19:
				return true;
			default:
				return false;
			}
		}

		internal static int Tier(ItemData item)
		{
			if (!Eligible(item) || item.m_customData == null || !item.m_customData.TryGetValue("laugh.valheim.rarity.stationUpgrade", out var value) || value != "1")
			{
				return -1;
			}
			if (!item.m_customData.TryGetValue("laugh.valheim.rarity.tier", out var value2) || !int.TryParse(value2, out var result) || result < 0 || result >= 6)
			{
				return -1;
			}
			return result;
		}

		internal static bool IsTool(ItemData item)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			if (item?.m_shared != null)
			{
				if ((int)item.m_shared.m_itemType != 19 && (int)item.m_shared.m_itemType != 15 && !(item.m_shared.m_damages.m_chop > 0f) && !(item.m_shared.m_damages.m_pickaxe > 0f))
				{
					return Settings.Listed(Settings.ExtraTools, Settings.Prefab(item));
				}
				return true;
			}
			return false;
		}

		internal static void ApplyUpgrade(ItemData item, int tier, string element)
		{
			if (!Eligible(item) || tier != Tier(item) + 1 || tier < 0 || tier > 5)
			{
				throw new InvalidOperationException("Invalid rarity upgrade.");
			}
			float maxDurability = item.GetMaxDurability();
			if (item.m_customData == null)
			{
				item.m_customData = new Dictionary<string, string>();
			}
			item.m_customData["laugh.valheim.rarity.stationUpgrade"] = "1";
			item.m_customData["laugh.valheim.rarity.tier"] = tier.ToString();
			item.m_customData.Remove("laugh.valheim.rarity.element");
			if (tier >= 4 && Settings.CanEnchant(item))
			{
				switch (element)
				{
				case "Fire":
				case "Lightning":
				case "Poison":
					item.m_customData["laugh.valheim.rarity.element"] = element;
					break;
				}
			}
			if (maxDurability > 0f)
			{
				item.m_durability *= item.GetMaxDurability() / maxDurability;
			}
		}

		internal static float Multiplier(ItemData item)
		{
			int num = Tier(item);
			if (num >= 0)
			{
				return Multipliers[num].Value;
			}
			return 1f;
		}

		internal static string Element(ItemData item)
		{
			if (Tier(item) < 4 || !Settings.CanEnchant(item) || !item.m_customData.TryGetValue("laugh.valheim.rarity.element", out var value))
			{
				return "";
			}
			return value;
		}

		internal static string Label(ItemData item)
		{
			int num = Tier(item);
			if (num >= 0)
			{
				return "<color=" + Settings.RarityColor(num) + ">" + Settings.RarityName(num) + "</color>";
			}
			return "";
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "GetHoverName")]
	internal static class HoverName
	{
		private static void Postfix(ItemDrop __instance, ref string __result)
		{
			__result = ItemNames.Decorate(__instance.m_itemData, Localization.instance.Localize(__result));
		}
	}
	[HarmonyPatch]
	internal static class Stats
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(ItemData), "GetArmor", new Type[2]
			{
				typeof(int),
				typeof(float)
			}, (Type[])null);
			yield return AccessTools.Method(typeof(ItemData), "GetMaxDurability", new Type[1] { typeof(int) }, (Type[])null);
			yield return AccessTools.Method(typeof(ItemData), "GetBaseBlockPower", new Type[1] { typeof(int) }, (Type[])null);
		}

		[HarmonyPriority(0)]
		private static void Postfix(ItemData __instance, MethodBase __originalMethod, ref float __result)
		{
			string stat = ((__originalMethod.Name == "GetArmor") ? "Armor" : ((__originalMethod.Name == "GetMaxDurability") ? "Durability" : "Block"));
			__result *= Settings.Stat(__instance, stat);
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetDamage", new Type[]
	{
		typeof(int),
		typeof(float)
	})]
	internal static class Damage
	{
		[HarmonyPriority(0)]
		private static void Postfix(ItemData __instance, ref DamageTypes __result)
		{
			((DamageTypes)(ref __result)).Modify(Settings.Stat(__instance, "Damage"));
			float num = (((DamageTypes)(ref __result)).GetTotalPhysicalDamage() + ((DamageTypes)(ref __result)).GetTotalElementalDamage() + __result.m_damage) * Plugin.ElementFraction.Value;
			switch (Plugin.Element(__instance))
			{
			case "Fire":
				__result.m_fire += num;
				break;
			case "Lightning":
				__result.m_lightning += num;
				break;
			case "Poison":
				__result.m_poison += num;
				break;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetDamageModifiers")]
	internal static class ArmorEffects
	{
		private static void Postfix(Character __instance, ref DamageModifiers __result)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val == null)
			{
				return;
			}
			foreach (ItemData equippedItem in ((Humanoid)val).GetInventory().GetEquippedItems())
			{
				if (Settings.IsArmor(equippedItem))
				{
					switch (Plugin.Element(equippedItem))
					{
					case "Fire":
						((DamageModifiers)(ref __result)).Apply(new List<DamageModPair>
						{
							new DamageModPair
							{
								m_type = (DamageType)32,
								m_modifier = Settings.ResistanceValue
							}
						});
						break;
					case "Lightning":
						((DamageModifiers)(ref __result)).Apply(new List<DamageModPair>
						{
							new DamageModPair
							{
								m_type = (DamageType)128,
								m_modifier = Settings.ResistanceValue
							}
						});
						break;
					case "Poison":
						((DamageModifiers)(ref __result)).Apply(new List<DamageModPair>
						{
							new DamageModPair
							{
								m_type = (DamageType)256,
								m_modifier = Settings.ResistanceValue
							}
						});
						break;
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class Tooltip
	{
		private static MethodBase TargetMethod()
		{
			return typeof(ItemData).GetMethods().Single((MethodInfo m) => m.Name == "GetTooltip" && m.IsStatic && m.GetParameters().Length == 6);
		}

		private static void Postfix(object[] __args, ref string __result)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ItemData item = (ItemData)__args[0];
			if (Plugin.Tier(item) >= 0)
			{
				string text = Plugin.Element(item);
				__result = Plugin.Label(item) + string.Format(" · damage ×{0:0.##}, armor ×{1:0.##}, durability ×{2:0.##}, block ×{3:0.##}\n", Settings.Stat(item, "Damage"), Settings.Stat(item, "Armor"), Settings.Stat(item, "Durability"), Settings.Stat(item, "Block")) + ((text == "") ? "" : (text + " enchantment (damage on weapons; resistance on armor/shields)\n")) + __result;
			}
		}
	}
	internal static class ResourceCosts
	{
		internal sealed class Material
		{
			internal readonly string Name;

			internal readonly int Amount;

			internal readonly string Prefab;

			internal Material(string name, int amount)
				: this(name, amount, "")
			{
			}

			internal Material(string name, int amount, string prefab)
			{
				Name = name;
				Amount = amount;
				Prefab = prefab;
			}
		}

		internal sealed class Plan
		{
			internal List<Material> Materials = new List<Material>();

			internal int AlternativeCount;

			internal string Error = "";

			internal bool Valid
			{
				get
				{
					if (Error == "")
					{
						return Materials.Count > 0;
					}
					return false;
				}
			}
		}

		internal sealed class Payment
		{
			internal ItemData Item;

			internal int Amount;
		}

		internal static Plan Get(ItemData item, int option, bool allowOverrides = true)
		{
			if (item?.m_shared == null || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return new Plan
				{
					Error = "No crafting recipe exists for this item."
				};
			}
			float factor = (Settings.ResourceMultiplier?.Value ?? 3f) * (Settings.Cost[Math.Min(5, Plugin.Tier(item) + 1)]?.Value ?? 1f);
			string prefab = Settings.Prefab(item);
			string text = (Settings.RecipeOverrides?.Value ?? "").Split(new char[1] { ';' }).FirstOrDefault((string entry) => entry.Split(new char[1] { '=' })[0].Trim() == prefab && prefab != "");
			if (allowOverrides && text != null)
			{
				try
				{
					List<Material> list = new List<Material>();
					foreach (KeyValuePair<string, int> item2 in Settings.ParseAmounts(text.Substring(text.IndexOf('=') + 1)))
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item2.Key);
						ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
						if (!Object.op_Implicit((Object)(object)val))
						{
							return new Plan
							{
								Error = "Unknown override resource: " + item2.Key
							};
						}
						list.Add(new Material(val.m_itemData.m_shared.m_name, item2.Value, item2.Key));
					}
					return BuildScaled(list, alternatives: false, 0, factor);
				}
				catch (Exception ex) when (ex is FormatException || ex is OverflowException || ex is ArgumentException)
				{
					return new Plan
					{
						Error = "Invalid configured base recipe override."
					};
				}
			}
			List<Recipe> source = ObjectDB.instance.m_recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r) && r.m_enabled && !r.m_noCraftOnlyUpgrade && Object.op_Implicit((Object)(object)r.m_item)).ToList();
			Recipe val2 = ((IEnumerable<Recipe>)source).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => ((Component)r.m_item).gameObject == item.m_dropPrefab)) ?? ((IEnumerable<Recipe>)source).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => r.m_item.m_itemData.m_shared == item.m_shared));
			if (!Object.op_Implicit((Object)(object)val2))
			{
				List<Recipe> source2 = source.Where((Recipe r) => r.m_item.m_itemData.m_shared.m_name == item.m_shared.m_name).ToList();
				if (source2.Select((Recipe r) => r.m_item).Distinct().Count() > 1)
				{
					return new Plan
					{
						Error = "Ambiguous modded recipe; configure a base recipe override."
					};
				}
				val2 = source2.FirstOrDefault();
			}
			if (!Object.op_Implicit((Object)(object)val2) || val2.m_resources == null)
			{
				return new Plan
				{
					Error = "No crafting recipe exists for this item."
				};
			}
			List<Material> list2 = new List<Material>();
			Requirement[] resources = val2.m_resources;
			foreach (Requirement val3 in resources)
			{
				if (val3 == null)
				{
					continue;
				}
				int amount = val3.GetAmount(1);
				if (amount > 0)
				{
					if (!Object.op_Implicit((Object)(object)val3.m_resItem) || val3.m_resItem.m_itemData?.m_shared == null)
					{
						return new Plan
						{
							Error = "A crafting resource is missing; upgrade unavailable."
						};
					}
					list2.Add(new Material(val3.m_resItem.m_itemData.m_shared.m_name, amount, ((Object)val3.m_resItem).name));
				}
			}
			return BuildScaled(list2, val2.m_requireOnlyOneIngredient, option, factor);
		}

		internal static Plan Build(List<Material> baseMaterials, bool alternatives, int option)
		{
			return BuildScaled(baseMaterials, alternatives, option, Settings.ResourceMultiplier?.Value ?? 3f);
		}

		internal static Plan BuildScaled(List<Material> baseMaterials, bool alternatives, int option, float factor)
		{
			Plan plan = new Plan();
			if (float.IsNaN(factor) || float.IsInfinity(factor) || factor <= 0f)
			{
				plan.Error = "Invalid resource cost multiplier.";
				return plan;
			}
			List<Material> list = baseMaterials.Where((Material m) => m.Amount > 0).ToList();
			if (list.Count == 0)
			{
				plan.Error = "This item has no base crafting resource cost.";
				return plan;
			}
			if (list.Any((Material m) => string.IsNullOrEmpty(m.Name)))
			{
				plan.Error = "Invalid crafting resource.";
				return plan;
			}
			plan.AlternativeCount = (alternatives ? list.Count : 0);
			if (alternatives)
			{
				int index = (option % list.Count + list.Count) % list.Count;
				list = new List<Material> { list[index] };
			}
			checked
			{
				try
				{
					foreach (IGrouping<string, Material> item in list.GroupBy<Material, string>((Material m) => m.Name + "\0" + m.Prefab, StringComparer.Ordinal))
					{
						int num = 0;
						foreach (Material item2 in item)
						{
							num += item2.Amount;
						}
						int amount = (int)Math.Ceiling((double)num * (double)factor);
						plan.Materials.Add(new Material(item.First().Name, amount, item.First().Prefab));
					}
				}
				catch (OverflowException)
				{
					plan.Materials.Clear();
					plan.Error = "Crafting resource cost is too large.";
				}
				return plan;
			}
		}

		internal static long Owned(IEnumerable<ItemData> items, ItemData selected, string name)
		{
			return items.Where((ItemData i) => i != selected && i.m_shared?.m_name == name).Sum((Func<ItemData, long>)((ItemData i) => i.m_stack));
		}

		internal static long OwnedMaterial(IEnumerable<ItemData> items, ItemData selected, Material material)
		{
			return items.Where((ItemData i) => i != selected && Matches(i, material)).Sum((Func<ItemData, long>)((ItemData i) => i.m_stack));
		}

		private static bool Matches(ItemData item, Material material)
		{
			if (item.m_shared?.m_name == material.Name)
			{
				if (!(material.Prefab == ""))
				{
					return Settings.Prefab(item) == material.Prefab;
				}
				return true;
			}
			return false;
		}

		internal static bool Allocate(List<ItemData> items, ItemData selected, Plan plan, out List<Payment> payments)
		{
			payments = new List<Payment>();
			if (!plan.Valid)
			{
				return false;
			}
			foreach (Material material in plan.Materials)
			{
				int num = material.Amount;
				foreach (ItemData item in items)
				{
					if (item != selected && Matches(item, material) && item.m_stack > 0)
					{
						int num2 = Math.Min(num, item.m_stack);
						payments.Add(new Payment
						{
							Item = item,
							Amount = num2
						});
						num -= num2;
						if (num == 0)
						{
							break;
						}
					}
				}
				if (num > 0)
				{
					payments.Clear();
					return false;
				}
			}
			return true;
		}
	}
	internal static class ServerConfiguration
	{
		private sealed class ConfigCommand : ConsoleCommand
		{
			public override string Name => "rarity_config";

			public override string Help => "Admin config: rarity_config Section Key Value (use underscores for section spaces); rarity_config list; rarity_config reload (server file).";

			public override void Run(string[] args, Terminal context)
			{
				if (args.Length == 1 && args[0] == "list")
				{
					foreach (ConfigDefinition key in config.Keys)
					{
						context.AddString(key.Section.Replace(' ', '_') + " " + key.Key + " = " + TomlTypeConverter.ConvertToString(config[key].BoxedValue, config[key].SettingType));
					}
					return;
				}
				bool flag = !Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer();
				if (!CanEdit(flag, SynchronizationManager.Instance.PlayerIsAdmin))
				{
					context.AddString("Only server admins can change rarity configuration.");
					return;
				}
				if (args.Length == 1 && args[0] == "reload")
				{
					if (!flag)
					{
						context.AddString("Edit values with rarity_config Section Key Value; reload reads the host's local file only.");
						return;
					}
					Reload();
					context.AddString("Rarity configuration reloaded.");
					return;
				}
				if (args.Length < 3)
				{
					context.AddString(((ConsoleCommand)this).Help);
					return;
				}
				ConfigDefinition val = ((IEnumerable<ConfigDefinition>)config.Keys).FirstOrDefault((Func<ConfigDefinition, bool>)((ConfigDefinition k) => k.Section.Replace(' ', '_').Equals(args[0], StringComparison.OrdinalIgnoreCase) && k.Key.Equals(args[1], StringComparison.OrdinalIgnoreCase)));
				if (val == (ConfigDefinition)null)
				{
					context.AddString("Unknown setting. Use rarity_config list.");
					return;
				}
				ConfigEntryBase val2 = config[val];
				if (!TryValue(val2, string.Join(" ", args.Skip(2)), out var value, out var error))
				{
					context.AddString("Invalid value: " + error);
					return;
				}
				val2.BoxedValue = value;
				config.Save();
				Reload();
				context.AddString("Updated " + val.Section + "/" + val.Key + (flag ? " for the server." : "; sent to the server for admin authorization."));
			}
		}

		private static ConfigFile config;

		private static ManualLogSource log;

		private static bool refreshPending;

		private static float nextPoll;

		private static DateTime loadedWrite;

		private static DateTime observedWrite;

		private static long loadedLength;

		private static long observedLength;

		internal static ConfigEntry<T> Bind<T>(ConfigFile file, string section, string key, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(file, section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		internal static ConfigEntry<T> Bind<T>(ConfigFile file, string section, string key, T value, ConfigDescription description)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			object[] array = description.Tags.Concat(new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }).ToArray();
			return file.Bind<T>(section, key, value, new ConfigDescription(description.Description + " [Synced with Server; admin only]", description.AcceptableValues, array));
		}

		internal static void Start(ConfigFile file, ManualLogSource logger)
		{
			config = file;
			log = logger;
			config.SettingChanged += SettingChanged;
			SynchronizationManager.OnConfigurationSynchronized += Synchronized;
			ReadStamp(out loadedWrite, out loadedLength);
			observedWrite = loadedWrite;
			observedLength = loadedLength;
			refreshPending = true;
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ConfigCommand());
		}

		internal static void Stop()
		{
			if (config != null)
			{
				config.SettingChanged -= SettingChanged;
			}
			SynchronizationManager.OnConfigurationSynchronized -= Synchronized;
			config = null;
		}

		private static void SettingChanged(object sender, SettingChangedEventArgs e)
		{
			refreshPending = true;
		}

		private static void Synchronized(object sender, ConfigurationSynchronizationEventArgs e)
		{
			if (e.UpdatedPluginGUIDs.Contains("laugh.valheim.rarity"))
			{
				refreshPending = true;
			}
		}

		internal static bool CanEdit(bool server, bool admin)
		{
			return server || admin;
		}

		internal static bool TryValue(ConfigEntryBase entry, string text, out object value, out string error)
		{
			value = null;
			error = "";
			try
			{
				value = TomlTypeConverter.ConvertToValue(text, entry.SettingType);
				if (value is float f && (float.IsNaN(f) || float.IsInfinity(f)))
				{
					throw new FormatException("A finite number is required.");
				}
				if (entry.Description.AcceptableValues != null && !entry.Description.AcceptableValues.IsValid(value))
				{
					throw new FormatException("Value is outside the allowed range or choices.");
				}
				if (entry.Definition.Section == "Station" && entry.Definition.Key == "BuildResources")
				{
					Dictionary<string, int> dictionary = Settings.ParseAmounts((string)value);
					if (Object.op_Implicit((Object)(object)ObjectDB.instance))
					{
						foreach (KeyValuePair<string, int> item in dictionary)
						{
							GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Key);
							if (!Object.op_Implicit((Object)(object)((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null)))
							{
								throw new FormatException("Unknown construction resource: " + item.Key);
							}
						}
					}
				}
				return true;
			}
			catch (Exception ex) when (ex is FormatException || ex is OverflowException || ex is ArgumentException)
			{
				error = ex.Message;
				value = null;
				return false;
			}
		}

		internal static void Tick()
		{
			if (config == null)
			{
				return;
			}
			if (Time.unscaledTime >= nextPoll)
			{
				nextPoll = Time.unscaledTime + 0.5f;
				if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer())
				{
					ReadStamp(out var write, out var length);
					if (write != observedWrite || length != observedLength)
					{
						observedWrite = write;
						observedLength = length;
					}
					else if (write != loadedWrite || length != loadedLength)
					{
						Reload();
					}
				}
			}
			if (!refreshPending || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return;
			}
			try
			{
				Station.ApplySettings();
				Player localPlayer = Player.m_localPlayer;
				if (Object.op_Implicit((Object)(object)localPlayer))
				{
					bool flag = false;
					foreach (ItemData item in from i in ((Humanoid)localPlayer).GetInventory().GetAllItems()
						where Plugin.Tier(i) >= 0
						select i)
					{
						float num = Mathf.Min(item.m_durability, item.GetMaxDurability());
						if (num != item.m_durability)
						{
							item.m_durability = num;
							flag = true;
						}
					}
					if (flag)
					{
						AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null).Invoke(((Humanoid)localPlayer).GetInventory(), new object[2] { true, false });
					}
					AccessTools.Method(typeof(Humanoid), "SetupEquipment", (Type[])null, (Type[])null).Invoke(localPlayer, null);
					AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null).Invoke(localPlayer, null);
					AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null).Invoke(localPlayer, null);
					if (Object.op_Implicit((Object)(object)InventoryGui.instance))
					{
						((Component)InventoryGui.instance).GetComponent<StationWindow>()?.ConfigurationChanged();
					}
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)("Could not apply live station configuration: " + ex.Message));
			}
			refreshPending = false;
		}

		private static void ReadStamp(out DateTime write, out long length)
		{
			FileInfo fileInfo = new FileInfo(config.ConfigFilePath);
			write = (fileInfo.Exists ? fileInfo.LastWriteTimeUtc : DateTime.MinValue);
			length = (fileInfo.Exists ? fileInfo.Length : 0);
		}

		private static void Reload()
		{
			bool saveOnConfigSet = config.SaveOnConfigSet;
			try
			{
				config.SaveOnConfigSet = false;
				config.Reload();
				refreshPending = true;
				log.LogInfo((object)"Reloaded Valheim Rarity configuration; Jotunn synchronizes it with connected players.");
			}
			catch (IOException ex)
			{
				log.LogWarning((object)("Could not reload configuration: " + ex.Message));
			}
			finally
			{
				config.SaveOnConfigSet = saveOnConfigSet;
				ReadStamp(out loadedWrite, out loadedLength);
				observedWrite = loadedWrite;
				observedLength = loadedLength;
			}
		}
	}
	internal static class Settings
	{
		internal static readonly ConfigEntry<float>[] Armor = new ConfigEntry<float>[6];

		internal static readonly ConfigEntry<float>[] Damage = new ConfigEntry<float>[6];

		internal static readonly ConfigEntry<float>[] Durability = new ConfigEntry<float>[6];

		internal static readonly ConfigEntry<float>[] Block = new ConfigEntry<float>[6];

		internal static readonly ConfigEntry<float>[] Cost = new ConfigEntry<float>[6];

		internal static readonly ConfigEntry<string>[] Names = new ConfigEntry<string>[6];

		internal static readonly ConfigEntry<string>[] Colors = new ConfigEntry<string>[6];

		internal static ConfigEntry<float> ResourceMultiplier;

		internal static ConfigEntry<float> WindowWidth;

		internal static ConfigEntry<float> WindowHeight;

		internal static ConfigEntry<float> UseDistance;

		internal static ConfigEntry<bool> PrefixNames;

		internal static ConfigEntry<bool> RequireUnlock;

		internal static ConfigEntry<bool> RequireRoof;

		internal static ConfigEntry<bool> WeaponElements;

		internal static ConfigEntry<bool> ArmorElements;

		internal static ConfigEntry<bool> MatchCraftingPanel;

		internal static ConfigEntry<string> DefaultView;

		internal static ConfigEntry<string> UnlockItem;

		internal static ConfigEntry<string> BuildResources;

		internal static ConfigEntry<string> ExcludedItems;

		internal static ConfigEntry<string> ExtraEquipment;

		internal static ConfigEntry<string> ExtraTools;

		internal static ConfigEntry<string> RecipeOverrides;

		internal static ConfigEntry<string> Background;

		internal static ConfigEntry<string> Border;

		internal static ConfigEntry<string> Resistance;

		internal static DamageModifier ResistanceValue
		{
			get
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				if (!Enum.TryParse<DamageModifier>(Resistance?.Value ?? "Resistant", out DamageModifier result))
				{
					return (DamageModifier)1;
				}
				return result;
			}
		}

		internal static void Initialize(ConfigFile config)
		{
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			for (int i = 0; i < 6; i++)
			{
				string section = "Rarity " + Plugin.Names[i];
				float value = Plugin.Multipliers[i]?.Value ?? ((float)(i + 2));
				Armor[i] = Float(config, section, "ArmorMultiplier", value, 0f, 100f);
				Damage[i] = Float(config, section, "DamageMultiplier", value, 0f, 100f);
				Durability[i] = Float(config, section, "DurabilityMultiplier", value, 0.01f, 100f);
				Block[i] = Float(config, section, "BlockMultiplier", value, 0f, 100f);
				Cost[i] = Float(config, section, "ResourceCostScale", 1f, 0.01f, 100f);
				Names[i] = ServerConfiguration.Bind(config, section, "DisplayName", Plugin.Names[i], "Rarity prefix shown in item names.");
				Colors[i] = ServerConfiguration.Bind(config, section, "Color", Plugin.Colors[i], "HTML color #RRGGBB or #RRGGBBAA.");
			}
			ResourceMultiplier = Float(config, "Resources", "CraftingCostMultiplier", 3f, 0.01f, 100f);
			RecipeOverrides = ServerConfiguration.Bind(config, "Compatibility", "BaseRecipeOverrides", "", "Base cost overrides for items with usable crafting recipes; recipe-less items remain excluded. Format: ItemPrefab=Wood:10,Iron:4;OtherPrefab=Stone:5. Resource costs are multiplied as usual. Changes apply live and synchronize with the server.");
			ExcludedItems = ServerConfiguration.Bind(config, "Compatibility", "ExcludedPrefabs", "", "Comma-separated equipment prefab names to exclude from this mod.");
			ExtraEquipment = ServerConfiguration.Bind(config, "Compatibility", "ExtraEquipmentPrefabs", "", "Comma-separated custom equipment prefab names to include even if they use a nonstandard ItemType.");
			ExtraTools = ServerConfiguration.Bind(config, "Compatibility", "ExtraToolPrefabs", "", "Comma-separated modded tool prefab names. These never gain mod elemental effects.");
			PrefixNames = ServerConfiguration.Bind(config, "Display", "PrefixItemNames", value: true, "Prefix upgraded equipment names with rarity and color the full name.");
			RequireUnlock = ServerConfiguration.Bind(config, "Station", "RequireMaterialDiscovery", value: true, "Require the unlock material to have been discovered before building or using the station.");
			UnlockItem = ServerConfiguration.Bind(config, "Station", "UnlockMaterialPrefab", "Iron", "Material prefab that unlocks this station permanently per character.");
			BuildResources = ServerConfiguration.Bind(config, "Station", "BuildResources", "Wood:10,Stone:4,Coal:4,Iron:6", "Construction resources as Prefab:amount separated by commas. Changes apply live and synchronize with the server.");
			if (BuildResources.Value == "Wood:10,Stone:4,Coal:4,Copper:6")
			{
				BuildResources.Value = "Wood:10,Stone:4,Coal:4,Iron:6";
			}
			RequireRoof = ServerConfiguration.Bind(config, "Station", "RequireRoof", value: true, "Require shelter to use the station. Changes apply live and synchronize with the server.");
			UseDistance = Float(config, "Station", "UseDistance", 5f, 1f, 20f);
			MatchCraftingPanel = ServerConfiguration.Bind(config, "UI", "MatchCraftingPanel", value: true, "Use the character crafting panel's current position and size for the station's own window. When false, use the centered custom-size layout.");
			DefaultView = ServerConfiguration.Bind(config, "UI", "DefaultView", "Selector", new ConfigDescription("Initial window view on each station opening. Switch views using the button in the window.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Selector", "Traditional" }), Array.Empty<object>()));
			WindowWidth = Float(config, "UI", "WindowWidth", 700f, 400f, 1400f);
			WindowHeight = Float(config, "UI", "WindowHeight", 850f, 500f, 1500f);
			Background = ServerConfiguration.Bind(config, "UI", "BackgroundColor", "#17130FFA", "Station window background color.");
			Border = ServerConfiguration.Bind(config, "UI", "BorderColor", "#C69855", "Station window frame color.");
			WeaponElements = ServerConfiguration.Bind(config, "Effects", "EnableWeaponElements", value: true, "Enable legendary/mythic weapon elemental damage. Tools remain excluded.");
			ArmorElements = ServerConfiguration.Bind(config, "Effects", "EnableArmorElements", value: true, "Enable legendary/mythic armor and shield elemental resistance.");
			Resistance = ServerConfiguration.Bind(config, "Effects", "ArmorResistance", "Resistant", new ConfigDescription("Resistance granted by elemental armor/shields.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Resistant", "VeryResistant", "Immune" }), Array.Empty<object>()));
		}

		private static ConfigEntry<float> Float(ConfigFile config, string section, string key, float value, float min, float max)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			return ServerConfiguration.Bind(config, section, key, value, new ConfigDescription(key + ". Applied to upgraded equipment only where relevant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}

		internal static string RarityName(int tier)
		{
			return (Names[tier]?.Value ?? Plugin.Names[tier]).Replace("<", "").Replace(">", "").Replace("\n", " ")
				.Replace("\r", " ");
		}

		internal static string RarityColor(int tier)
		{
			string text = Colors[tier]?.Value ?? Plugin.Colors[tier];
			if (text == null || (text.Length != 7 && text.Length != 9) || text[0] != '#' || !text.Skip(1).All(Uri.IsHexDigit))
			{
				return Plugin.Colors[tier];
			}
			return text;
		}

		internal static bool Listed(ConfigEntry<string> setting, string prefab)
		{
			if (prefab != "")
			{
				return (setting?.Value ?? "").Split(new char[1] { ',' }).Any((string s) => s.Trim().Equals(prefab, StringComparison.Ordinal));
			}
			return false;
		}

		internal static string Prefab(ItemData item)
		{
			if (!Object.op_Implicit((Object)(object)item?.m_dropPrefab))
			{
				return "";
			}
			return ((Object)item.m_dropPrefab).name;
		}

		internal static float Stat(ItemData item, string stat)
		{
			int num = Plugin.Tier(item);
			if (num < 0)
			{
				return 1f;
			}
			return ((ConfigEntry<float>)((object[])(stat switch
			{
				"Durability" => Durability, 
				"Damage" => Damage, 
				"Armor" => Armor, 
				_ => Block, 
			}))[num])?.Value ?? Plugin.Multipliers[num].Value;
		}

		internal static bool IsArmor(ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType != 5 && (int)itemType != 6 && (int)itemType != 7 && (int)itemType != 11 && (int)itemType != 12 && (int)itemType != 17)
			{
				return item.m_shared.m_armor > 0f;
			}
			return true;
		}

		internal static bool CanEnchant(ItemData item)
		{
			if (!Plugin.IsTool(item))
			{
				if (!IsArmor(item))
				{
					return WeaponElements?.Value ?? true;
				}
				return ArmorElements?.Value ?? true;
			}
			return false;
		}

		internal static Dictionary<string, int> ParseAmounts(string text)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal);
			string[] array = text.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Trim().Split(new char[1] { ':' });
				if (array2.Length != 2 || string.IsNullOrWhiteSpace(array2[0]) || !int.TryParse(array2[1].Trim(), out var result) || result <= 0)
				{
					throw new FormatException("Expected ResourcePrefab:positiveAmount, separated by commas.");
				}
				string key = array2[0].Trim();
				dictionary[key] = checked((dictionary.TryGetValue(key, out var value) ? value : 0) + result);
			}
			return dictionary;
		}
	}
	internal static class Station
	{
		internal const string PrefabName = "laugh_rarity_upgrade_forge";

		internal const string DisplayName = "Rarity Forge";

		internal static bool Active
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					return IsRarityStation(Player.m_localPlayer.GetCurrentCraftingStation());
				}
				return false;
			}
		}

		internal static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				Name = "Rarity Forge",
				Description = "Upgrade tools, weapons and armor through six rarities. Costs 3x the original crafting resources; quality is unchanged.",
				PieceTable = "Hammer",
				Category = "Crafting",
				CraftingStation = "piece_workbench",
				Requirements = ((IEnumerable<KeyValuePair<string, int>>)Settings.ParseAmounts(Settings.BuildResources.Value)).Select((Func<KeyValuePair<string, int>, RequirementConfig>)((KeyValuePair<string, int> r) => new RequirementConfig(r.Key, r.Value, 0, true))).ToArray()
			};
			CustomPiece val2 = new CustomPiece("laugh_rarity_upgrade_forge", "forge", val);
			StationModel.Apply(val2.PiecePrefab);
			CraftingStation component = val2.PiecePrefab.GetComponent<CraftingStation>();
			component.m_name = "Rarity Forge";
			component.m_showBasicRecipies = false;
			component.m_canRepair = false;
			component.m_hasCraftTab = true;
			component.m_upgrader = false;
			component.m_useDistance = Settings.UseDistance.Value;
			component.m_craftRequireRoof = Settings.RequireRoof.Value;
			if (!PieceManager.Instance.AddPiece(val2))
			{
				throw new InvalidOperationException("Could not register the Rarity Forge.");
			}
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
		}

		internal static bool IsRarityStation(CraftingStation station)
		{
			if (Object.op_Implicit((Object)(object)station) && station.m_name == "Rarity Forge")
			{
				return ((Object)((Component)station).gameObject).name.StartsWith("laugh_rarity_upgrade_forge", StringComparison.Ordinal);
			}
			return false;
		}

		internal static void ApplySettings()
		{
			Requirement[] resources = ((IEnumerable<KeyValuePair<string, int>>)Settings.ParseAmounts(Settings.BuildResources.Value)).Select((Func<KeyValuePair<string, int>, Requirement>)delegate(KeyValuePair<string, int> resource)
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected O, but got Unknown
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(resource.Key);
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("Unknown construction resource: " + resource.Key);
				}
				return new Requirement
				{
					m_resItem = val,
					m_amount = resource.Value,
					m_recover = true
				};
			}).ToArray();
			foreach (CraftingStation item in Resources.FindObjectsOfTypeAll<CraftingStation>().Where(IsRarityStation))
			{
				item.m_useDistance = Settings.UseDistance.Value;
				item.m_craftRequireRoof = Settings.RequireRoof.Value;
				((Component)item).GetComponent<Piece>().m_resources = resources;
			}
		}

		internal static bool Unlocked(Player player)
		{
			ConfigEntry<bool> requireUnlock = Settings.RequireUnlock;
			if (requireUnlock != null && !requireUnlock.Value)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return false;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(Settings.UnlockItem?.Value ?? "Iron");
			ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)val))
			{
				return player.IsMaterialKnown(val.m_itemData.m_shared.m_name);
			}
			return false;
		}

		internal static bool Eligible(ItemData item)
		{
			if (Plugin.Eligible(item) && item.m_quality == 1)
			{
				return ResourceCosts.Get(item, 0, allowOverrides: false).Valid;
			}
			return false;
		}

		internal static bool Upgrade(Player player, ItemData item, string element, int materialOption, out string error)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			error = "";
			if (!Object.op_Implicit((Object)(object)player) || !IsRarityStation(player.GetCurrentCraftingStation()))
			{
				error = "Use the Rarity Forge to upgrade equipment.";
				return false;
			}
			if (!Unlocked(player))
			{
				error = "Discover the station's unlock material first.";
				return false;
			}
			CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
			if (Vector3.Distance(((Component)player).transform.position, ((Component)currentCraftingStation).transform.position) > currentCraftingStation.m_useDistance || !currentCraftingStation.CheckUsable(player, false))
			{
				error = "The station must be usable and within reach.";
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (!Plugin.Eligible(item) || !inventory.GetAllItems().Contains(item))
			{
				error = "Select equipment in your inventory.";
				return false;
			}
			if (item.m_quality != 1)
			{
				error = "Equipment upgraded at a vanilla crafting station cannot receive rarity upgrades.";
				return false;
			}
			ResourceCosts.Plan plan = ResourceCosts.Get(item, 0, allowOverrides: false);
			if (!plan.Valid)
			{
				error = plan.Error;
				return false;
			}
			int num = Plugin.Tier(item) + 1;
			if (num > 5)
			{
				error = "This item is already Mythic.";
				return false;
			}
			if (num >= 4 && Settings.CanEnchant(item) && element != "Fire" && element != "Lightning" && element != "Poison")
			{
				error = "Choose Fire, Lightning or Poison.";
				return false;
			}
			ResourceCosts.Plan plan2 = ResourceCosts.Get(item, materialOption);
			if (!plan2.Valid)
			{
				error = plan2.Error;
				return false;
			}
			if (!ResourceCosts.Allocate(inventory.GetAllItems(), item, plan2, out var payments))
			{
				error = "Not enough crafting resources.";
				return false;
			}
			ItemData val = Preview(item, element);
			foreach (ResourceCosts.Payment item3 in payments)
			{
				ItemData item2 = item3.Item;
				item2.m_stack -= item3.Amount;
				if (item3.Item.m_stack == 0)
				{
					if (item3.Item.m_equipped)
					{
						((Humanoid)player).UnequipItem(item3.Item, false);
					}
					inventory.GetAllItems().Remove(item3.Item);
				}
			}
			item.m_customData = val.m_customData;
			item.m_durability = val.m_durability;
			AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null).Invoke(inventory, new object[2] { true, false });
			if (item.m_equipped)
			{
				AccessTools.Method(typeof(Humanoid), "SetupEquipment", (Type[])null, (Type[])null).Invoke(player, null);
			}
			currentCraftingStation.m_craftItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, ((Component)currentCraftingStation).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
			return true;
		}

		internal static ItemData Preview(ItemData item, string element)
		{
			ItemData obj = item.Clone();
			Plugin.ApplyUpgrade(obj, Plugin.Tier(item) + 1, element);
			return obj;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	internal static class StationDiscovery
	{
		private static bool Prefix(Player __instance, Piece __0, RequirementMode __1, ref bool __result)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)__0) || !((Object)__0).name.StartsWith("laugh_rarity_upgrade_forge", StringComparison.Ordinal))
			{
				return true;
			}
			bool flag = Station.Unlocked(__instance);
			if ((int)__1 == 1 || !flag)
			{
				__result = flag;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CraftingStation), "Interact")]
	internal static class StationAccess
	{
		private static bool Prefix(CraftingStation __instance, Humanoid __0, ref bool __result)
		{
			if (Station.IsRarityStation(__instance))
			{
				Player val = (Player)(object)((__0 is Player) ? __0 : null);
				if (val != null && !Station.Unlocked(val))
				{
					((Character)val).Message((MessageType)2, "Discover " + (Settings.UnlockItem?.Value ?? "Iron") + " to unlock the Rarity Forge.", 0, (Sprite)null, false);
					__result = false;
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class LegacyMigration
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			return from m in typeof(Inventory).GetMethods()
				where m.Name == "AddItem" && m.GetParameters().Any((ParameterInfo p) => p.ParameterType == typeof(ItemData))
				select m;
		}

		private static void Prefix(object[] __args)
		{
			foreach (ItemData item in __args.OfType<ItemData>())
			{
				if (item.m_customData != null && !item.m_customData.ContainsKey("laugh.valheim.rarity.stationUpgrade") && item.m_customData.TryGetValue("laugh.valheim.rarity.tier", out var value))
				{
					if (int.TryParse(value, out var result) && result >= 0 && result < 6)
					{
						item.m_durability = Mathf.Min(item.GetMaxDurability(), item.m_durability / Plugin.Multipliers[result].Value);
					}
					item.m_customData.Remove("laugh.valheim.rarity.tier");
					item.m_customData.Remove("laugh.valheim.rarity.element");
				}
			}
		}
	}
	internal static class StationModel
	{
		private sealed class Part
		{
			internal string Name;

			internal int Material;

			internal Mesh Mesh;
		}

		private const string ResourcePrefix = "ValheimRarity.UpgradeStation.";

		private static Part[] parts;

		private static Material[] materials;

		internal static Vector2 StoneUV(Vector2 source)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2((2.5f + 55f * source.x) / 128f, (2.5f + 41f * source.y) / 128f);
		}

		internal static void Apply(GameObject prefab)
		{
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			if (parts == null)
			{
				parts = ReadParts();
			}
			if (materials == null)
			{
				materials = ReadMaterials(componentsInChildren);
			}
			LODGroup[] componentsInChildren2 = prefab.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			MeshRenderer[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				((Renderer)array[i]).enabled = false;
			}
			Transform[] array2 = (from t in ((IEnumerable<string>)new string[3] { "New", "Worn", "Broken" }).Select((Func<string, Transform>)prefab.transform.Find)
				where Object.op_Implicit((Object)(object)t)
				select t).ToArray();
			if (array2.Length == 0)
			{
				array2 = (Transform[])(object)new Transform[1] { prefab.transform };
			}
			Transform[] array3 = array2;
			Part[] array4;
			for (int i = 0; i < array3.Length; i++)
			{
				GameObject val = Child(array3[i], "UpgradeStationModel");
				array4 = parts;
				foreach (Part part in array4)
				{
					GameObject obj = Child(val.transform, part.Name);
					obj.AddComponent<MeshFilter>().sharedMesh = part.Mesh;
					((Renderer)obj.AddComponent<MeshRenderer>()).sharedMaterial = materials[part.Material];
				}
			}
			CraftingStation component = prefab.GetComponent<CraftingStation>();
			Collider[] componentsInChildren3 = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren3)
			{
				if (!val2.isTrigger && !((Object)(object)val2 == (Object)(object)component.m_effectAreaCollider))
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			GameObject val3 = Child(prefab.transform, "UpgradeStationCollision");
			array4 = parts;
			foreach (Part part2 in array4)
			{
				Child(val3.transform, part2.Name).AddComponent<MeshCollider>().sharedMesh = part2.Mesh;
			}
			Bounds bounds = parts.First((Part p) => p.Name == "coal").Mesh.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			Transform val4 = prefab.transform.Find("_enabled");
			if (Object.op_Implicit((Object)(object)val4))
			{
				val4.localPosition += center - new Vector3(0.421f, 0.909336f, 0.016f);
			}
			AddEmberFlames(prefab, val4);
			UpdateBuildIcon(prefab, ((Component)array2[0].Find("UpgradeStationModel")).gameObject);
		}

		internal static void PreparePlacementGhost(GameObject ghost)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ghost.transform.Find("UpgradeStationCollision");
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			MeshCollider[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshCollider>(true);
			foreach (MeshCollider val2 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val2.sharedMesh) && !Object.op_Implicit((Object)(object)((Component)val2).GetComponent<BoxCollider>()))
				{
					BoxCollider obj = ((Component)val2).gameObject.AddComponent<BoxCollider>();
					Bounds bounds = val2.sharedMesh.bounds;
					obj.center = ((Bounds)(ref bounds)).center;
					bounds = val2.sharedMesh.bounds;
					obj.size = ((Bounds)(ref bounds)).size;
				}
			}
		}

		private static void AddEmberFlames(GameObject prefab, Transform enabled)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: 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)
			Transform val = (Object.op_Implicit((Object)(object)enabled) ? enabled.Find("flames") : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("The forge flame template is missing.");
			}
			GameObject val2 = Child(prefab.transform, "UpgradeStationFire");
			ParticleSystem[] componentsInChildren;
			foreach (Part item in parts.Where((Part p) => p.Material == 2))
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, val2.transform, false);
				((Object)val3).name = "Flames_" + item.Name;
				Bounds bounds = item.Mesh.bounds;
				val3.transform.localPosition = new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y + 0.025f, ((Bounds)(ref bounds)).center.z);
				val3.transform.localScale = Vector3.one * ((item.Name == "coal") ? 0.4f : 0.6f);
				componentsInChildren = val3.GetComponentsInChildren<ParticleSystem>(true);
				for (int num = 0; num < componentsInChildren.Length; num++)
				{
					MainModule main = componentsInChildren[num].main;
					((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).playOnAwake = true;
				}
				val3.SetActive(true);
			}
			Bounds bounds2 = parts.First((Part p) => p.Name == "forgecoal").Mesh.bounds;
			Transform obj = enabled.Find("smoke");
			Transform val4 = enabled.Find("Point light");
			if (!Object.op_Implicit((Object)(object)obj) || !Object.op_Implicit((Object)(object)val4))
			{
				throw new InvalidOperationException("The forge smoke/light templates are missing.");
			}
			GameObject val5 = Object.Instantiate<GameObject>(((Component)obj).gameObject, val2.transform, false);
			((Object)val5).name = "Smoke_forgecoal";
			Bounds bounds3 = parts.First((Part p) => p.Name == "forge").Mesh.bounds;
			val5.transform.localPosition = new Vector3(((Bounds)(ref bounds3)).center.x, ((Bounds)(ref bounds3)).max.y + 0.025f, ((Bounds)(ref bounds3)).center.z);
			val5.transform.localScale = Vector3.one * 0.6f;
			componentsInChildren = val5.GetComponentsInChildren<ParticleSystem>(true);
			for (int num = 0; num < componentsInChildren.Length; num++)
			{
				MainModule main2 = componentsInChildren[num].main;
				((MainModule)(ref main2)).scalingMode = (ParticleSystemScalingMode)0;
				((MainModule)(ref main2)).loop = true;
				((MainModule)(ref main2)).playOnAwake = true;
			}
			val5.SetActive(true);
			GameObject inUseObject = prefab.GetComponent<CraftingStation>().m_inUseObject;
			Transform val6 = (Object.op_Implicit((Object)(object)inUseObject) ? inUseObject.transform : enabled);
			GameObject obj2 = Object.Instantiate<GameObject>(((Component)val4).gameObject, val6, false);
			((Object)obj2).name = "EmberLight_forgecoal";
			Vector3 val7 = default(Vector3);
			((Vector3)(ref val7))..ctor(((Bounds)(ref bounds2)).center.x, ((Bounds)(ref bounds2)).max.y + 0.15f, ((Bounds)(ref bounds2)).center.z);
			obj2.transform.localPosition = val6.InverseTransformPoint(prefab.transform.TransformPoint(val7));
			obj2.SetActive(true);
			((Component)val).gameObject.SetActive(false);
		}

		private static void UpdateBuildIcon(GameObject prefab, GameObject visual)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				Sprite val = RenderManager.Instance.Render(new RenderRequest(visual)
				{
					Width = 128,
					Height = 128,
					Rotation = RenderManager.IsometricRotation,
					UseCache = false
				});
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("Could not render the upgrade station build icon.");
				}
				prefab.GetComponent<Piece>().m_icon = val;
				prefab.GetComponent<CraftingStation>().m_icon = val;
			}
		}

		private static GameObject Child(Transform parent, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			GameObject val = new GameObject(name)
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			return val;
		}

		private static Stream Resource(string file)
		{
			return typeof(StationModel).Assembly.GetManifestResourceStream("ValheimRarity.UpgradeStation." + file) ?? throw new InvalidOperationException("Missing upgrade station asset: " + file);
		}

		private static Part[] ReadParts()
		{
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			using Stream stream = Resource("model.bin");
			using BinaryReader binaryReader = new BinaryReader(stream);
			if (binaryReader.ReadInt32() != 1448235853 || binaryReader.ReadInt32() != 1)
			{
				throw new InvalidDataException("Unsupported upgrade station mesh format.");
			}
			int num = binaryReader.ReadInt32();
			if (num != 11)
			{
				throw new InvalidDataException("The upgrade station must contain 11 mesh parts.");
			}
			Part[] array = new Part[num];
			for (int i = 0; i < num; i++)
			{
				int num2 = binaryReader.ReadInt32();
				if (num2 < 1 || num2 > 128)
				{
					throw new InvalidDataException("Invalid mesh name.");
				}
				string text = Encoding.UTF8.GetString(binaryReader.ReadBytes(num2));
				int num3 = binaryReader.ReadInt32();
				int num4 = binaryReader.ReadInt32();
				int num5 = binaryReader.ReadInt32();
				if (num3 < 0 || num3 > 3 || num4 < 3 || num4 > 65535 || num5 < 3 || num5 > 100000 || num5 % 3 != 0)
				{
					throw new InvalidDataException("Invalid upgrade station mesh.");
				}
				Vector3[] array2 = (Vector3[])(object)new Vector3[num4];
				Vector3[] array3 = (Vector3[])(object)new Vector3[num4];
				Vector2[] array4 = (Vector2[])(object)new Vector2[num4];
				for (int j = 0; j < num4; j++)
				{
					array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					array3[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					array4[j] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
					if (num3 == 3)
					{
						array4[j] = StoneUV(array4[j]);
					}
				}
				int[] array5 = new int[num5];
				for (int k = 0; k < num5; k++)
				{
					array5[k] = binaryReader.ReadInt32();
					if (array5[k] < 0 || array5[k] >= num4)
					{
						throw new InvalidDataException("Invalid mesh triangle.");
					}
				}
				Mesh val = new Mesh
				{
					name = "RarityStation_" + text,
					vertices = array2,
					normals = array3,
					uv = array4,
					triangles = array5
				};
				val.RecalculateBounds();
				val.RecalculateTangents();
				array[i] = new Part
				{
					Name = text,
					Material = num3,
					Mesh = val
				};
			}
			if (stream.Position != stream.Length)
			{
				throw new InvalidDataException("Unexpected trailing mesh data.");
			}
			return array;
		}

		private static Texture2D Texture(string file, bool linear = false, bool normal = false)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = "RarityStation_" + file,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)0
			};
			using (Stream stream = Resource(file))
			{
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				MethodInfo method = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: true).GetMethod("LoadImage", new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				});
				if (method == null || !(bool)method.Invoke(null, new object[3]
				{
					val,
					memoryStream.ToArray(),
					false
				}))
				{
					throw new InvalidDataException("Cannot decode " + file);
				}
			}
			if (normal)
			{
				Color32[] pixels = val.GetPixels32();
				for (int i = 0; i < pixels.Length; i++)
				{
					pixels[i] = new Color32(byte.MaxValue, pixels[i].g, pixels[i].b, pixels[i].r);
				}
				val.SetPixels32(pixels);
				val.Apply(false, false);
			}
			return val;
		}

		private static Material[] ReadMaterials(MeshRenderer[] renderers)
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			Material[] source = (from m in renderers.SelectMany((MeshRenderer r) => ((Renderer)r).sharedMaterials)
				where Object.op_Implicit((Object)(object)m)
				select m).ToArray();
			Material val = ((IEnumerable<Material>)source).FirstOrDefault((Func<Material, bool>)((Material m) => ((Object)m).name.StartsWith("Forge_mat", StringComparison.Ordinal))) ?? source.First((Material m) => m.HasProperty("_MainTex"));
			Material val2 = ((IEnumerable<Material>)source).FirstOrDefault((Func<Material, bool>)((Material m) => ((Object)m).name.StartsWith("ForgeCoals_mat", StringComparison.Ordinal))) ?? val;
			string[] array = new string[4] { "forge_wood", "forge_metal", "forge_coals", "station_stone" };
			Material[] array2 = (Material[])(object)new Material[4];
			for (int num = 0; num < array2.Length; num++)
			{
				Material val3 = new Material((num == 2) ? val2 : val)
				{
					name = "RarityStation_" + array[num]
				};
				val3.mainTexture = (Texture)(object)Texture(array[num] + "_color.png");
				if (val3.HasProperty("_Color"))
				{
					val3.SetColor("_Color", Color.white);
				}
				if (val3.HasProperty("_BumpMap"))
				{
					val3.SetTexture("_BumpMap", (Texture)(object)Texture(array[num] + "_normal.png", linear: true, normal: true));
					val3.EnableKeyword("_NORMALMAP");
				}
				if (val3.HasProperty("_BumpScale"))
				{
					val3.SetFloat("_BumpScale", 0.45f);
				}
				if (val3.HasProperty("_Metallic"))
				{
					val3.SetFloat("_Metallic", (num == 1) ? 1f : 0f);
				}
				if (val3.HasProperty("_Glossiness"))
				{
					val3.SetFloat("_Glossiness", (num == 1) ? 0.55f : 0.1f);
				}
				if (num == 1)
				{
					Texture2D val4 = Texture("forge_metal_metallic.png", linear: true);
					Texture2D obj = Texture("forge_metal_roughness.png", linear: true);
					Color32[] pixels = val4.GetPixels32();
					Color32[] pixels2 = obj.GetPixels32();
					for (int num2 = 0; num2 < pixels.Length; num2++)
					{
						pixels[num2] = new Color32(pixels[num2].r, (byte)0, (byte)0, (byte)(255 - pixels2[num2].r));
					}
					val4.SetPixels32(pixels);
					val4.Apply(false, false);
					if (val3.HasProperty("_MetallicTex"))
					{
						val3.SetTexture("_MetallicTex", (Texture)(object)val4);
					}
					if (val3.HasProperty("_MetallicGlossMap"))
					{
						val3.SetTexture("_MetallicGlossMap", (Texture)(object)val4);
						val3.EnableKeyword("_METALLICGLOSSMAP");
					}
				}
				else
				{
					if (val3.HasProperty("_MetallicTex"))
					{
						val3.SetTexture("_MetallicTex", (Texture)null);
					}
					if (val3.HasProperty("_MetallicGlossMap"))
					{
						val3.SetTexture("_MetallicGlossMap", (Texture)null);
					}
					val3.DisableKeyword("_METALLICGLOSSMAP");
				}
				if (val3.HasProperty("_EmissionMap"))
				{
					val3.SetTexture("_EmissionMap", (Texture)(object)((num == 2) ? Texture("forge_coals_emission.png") : null));
				}
				if (val3.HasProperty("_EmissionColor"))
				{
					val3.SetColor("_EmissionColor", (num == 2) ? (Color.white * 2.5f) : Color.black);
				}
				if (num == 2)
				{
					val3.EnableKeyword("_EMISSION");
				}
				else
				{
					val3.DisableKeyword("_EMISSION");
				}
				array2[num] = val3;
			}
			return array2;
		}
	}
	[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
	internal static class StationPlacementGhost
	{
		private static void Postfix(GameObject ___m_placementGhost)
		{
			if (Object.op_Implicit((Object)(object)___m_placementGhost) && Station.IsRarityStation(___m_placementGhost.GetComponent<CraftingStation>()))
			{
				StationModel.PreparePlacementGhost(___m_placementGhost);
			}
		}
	}
	internal sealed class StationWindow : MonoBehaviour
	{
		private sealed class ItemRow
		{
			internal ItemData Item;

			internal Button Button;

			internal TMP_Text Label;

			internal Image Icon;
		}

		private InventoryGui gui;

		private RectTransform panel;

		private RectTransform backdrop;

		private Image background;

		private Image backdropImage;

		private RectTransform details;

		private RectTransform itemList;

		private RectTransform listContent;

		private RectTransform listViewport;

		private ScrollRect itemScroll;

		private ScrollRect statsScroll;

		private Button viewToggle;

		private Button previous;

		private Button nextItem;

		private TMP_Text listCount;

		private bool traditional;

		private string configuredView;

		private readonly Vector3[] craftingCorners = (Vector3[])(object)new Vector3[4];

		private readonly List<ItemRow> rows = new List<ItemRow>();

		private readonly List<Image> frame = new List<Image>();

		private bool craftingWasVisible;

		private TMP_Text selection;

		private TMP_Text title;

		private TMP_Text stats;

		private TMP_Text status;

		private Button materialChoice;

		private Image icon;

		private RectTransform iconFrame;

		private Button upgrade;

		private readonly List<Button> elementButtons = new List<Button>();

		private ItemData selected;

		private string element = "Fire";

		private string message = "";

		private float refreshAt;

		private bool wasActive;

		private int materialOption;

		internal static void Tick(InventoryGui gui)
		{
			StationWindow stationWindow = ((Component)gui).GetComponent<StationWindow>();
			if (!Object.op_Implicit((Object)(object)stationWindow) && Station.Active)
			{
				stationWindow = ((Component)gui).gameObject.AddComponent<StationWindow>();
				stationWindow.Build(gui);
			}
			if (Object.op_Implicit((Object)(object)stationWindow))
			{
				stationWindow.RefreshVisibility();
			}
		}

		internal void ConfigurationChanged()
		{
			if (wasActive && configuredView != Settings.DefaultView.Value)
			{
				traditional = Settings.DefaultView.Value == "Traditional";
				ApplyViewLayout();
			}
			configuredView = Settings.DefaultView.Value;
			if (wasActive && Station.Active)
			{
				Refresh();
			}
		}

		private void Build(InventoryGui owner)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Expected O, but got Unknown
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Expected O, but got Unknown
			//IL_06b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Expected O, but got Unknown
			//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f7: Expected O, but got Unknown
			gui = owner;
			Canvas componentInParent = ((Component)gui.m_crafting).GetComponentInParent<Canvas>();
			backdrop = Rect("RarityStationModal", ((Component)componentInParent).transform, Vector2.zero, Vector2.one);
			backdropImage = ((Component)backdrop).gameObject.AddComponent<Image>();
			panel = Rect("RarityUpgradeWindow", (Transform)(object)backdrop, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f));
			panel.pivot = new Vector2(0.5f, 0.5f);
			background = ((Component)panel).gameObject.AddComponent<Image>();
			Frame("TopFrame", new Vector2(0f, 1f), Vector2.one, new Vector2(0f, -4f), Vector2.zero);
			Frame("BottomFrame", Vector2.zero, new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, 4f));
			Frame("LeftFrame", Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(4f, 0f));
			Frame("RightFrame", new Vector2(1f, 0f), Vector2.one, new Vector2(-4f, 0f), Vector2.zero);
			Button((Transform)(object)panel, "Close station", "×", 0.92f, 0.947f, 0.98f, 0.99f, (UnityAction)delegate
			{
				gui.Hide();
				Player.m_localPlayer.SetCraftingStation((CraftingStation)null);
			});
			TMP_Text obj = Text((Transform)(object)panel, "Header", "RARITY FORGE", 0.04f, 0.94f, 0.9f, 0.995f, 26, (TextAlignmentOptions)514);
			obj.enableAutoSizing = true;
			obj.fontSizeMin = 14f;
			obj.fontSizeMax = 26f;
			viewToggle = Button((Transform)(object)panel, "Change window view", "Use Traditional List", 0.05f, 0.885f, 0.95f, 0.935f, (UnityAction)delegate
			{
				traditional = !traditional;
				ApplyViewLayout();
				Refresh();
			});
			details = Rect("UpgradeDetails", (Transform)(object)panel, Vector2.zero, new Vector2(1f, 0.875f));
			selection = Text((Transform)(object)details, "Selection", "", 0.19f, 0.855f, 0.81f, 0.925f, 18, (TextAlignmentOptions)514);
			previous = Button((Transform)(object)details, "Previous item", "‹", 0.04f, 0.855f, 0.16f, 0.925f, (UnityAction)delegate
			{
				Select(-1);
			});
			nextItem = Button((Transform)(object)details, "Next item", "›", 0.84f, 0.855f, 0.96f, 0.925f, (UnityAction)delegate
			{
				Select(1);
			});
			iconFrame = Rect("PreviewIcon", (Transform)(object)details, new Vector2(0.07f, 0.69f), new Vector2(0.29f, 0.825f));
			RectTransform val = Rect("Icon", (Transform)(object)iconFrame, new Vector2(0.07f, 0.07f), new Vector2(0.93f, 0.93f));
			icon = ((Component)val).gameObject.AddComponent<Image>();
			icon.preserveAspect = true;
			((Graphic)icon).raycastTarget = false;
			title = Text((Transform)(object)details, "UpgradeTitle", "", 0.34f, 0.69f, 0.95f, 0.825f, 21, (TextAlignmentOptions)513);
			title.enableAutoSizing = true;
			title.fontSizeMin = 12f;
			title.fontSizeMax = 21f;
			selection.enableAutoSizing = true;
			selection.fontSizeMin = 12f;
			selection.fontSizeMax = 18f;
			TMP_Text obj2 = Text((Transform)(object)details, "StatsCaption", "CURRENT → AFTER UPGRADE\nBase values; combat skills and target resistance still apply.", 0.05f, 0.605f, 0.95f, 0.675f, 15, (TextAlignmentOptions)514);
			obj2.enableAutoSizing = true;
			obj2.fontSizeMin = 9f;
			obj2.fontSizeMax = 15f;
			RectTransform val2 = Rect("StatsScroll", (Transform)(object)details, new Vector2(0.05f, 0.245f), new Vector2(0.95f, 0.6f));
			RectTransform val3 = Rect("Viewport", (Transform)(object)val2, Vector2.zero, Vector2.one);
			((Component)val3).gameObject.AddComponent<RectMask2D>();
			RectTransform val4 = Rect("Content", (Transform)(object)val3, new Vector2(0f, 1f), Vector2.one);
			val4.pivot = new Vector2(0.5f, 1f);
			val4.sizeDelta = new Vector2(0f, 340f);
			stats = Text((Transform)(object)val4, "StatValues", "", 0f, 0f, 1f, 1f, 18, (TextAlignmentOptions)257);
			stats.textWrappingMode = (TextWrappingModes)1;
			ScrollRect val5 = (statsScroll = ((Component)val2).gameObject.AddComponent<ScrollRect>());
			val5.viewport = val3;
			val5.content = val4;
			val5.horizontal = false;
			val5.movementType = (MovementType)2;
			val5.scrollSensitivity = 25f;
			((Graphic)((Component)val3).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			string[] array = new string[3] { "Fire", "Lightning", "Poison" };
			foreach (string text in array)
			{
				string captured = text;
				int count = elementButtons.Count;
				elementButtons.Add(Button((Transform)(object)details, text, text, 0.05f + (float)count * 0.305f, 0.172f, 0.335f + (float)count * 0.305f, 0.23f, (UnityAction)delegate
				{
					element = captured;
					message = "";
					Refresh();
				}));
			}
			materialChoice = Button((Transform)(object)details, "Alternative resource", "Change crafting resource", 0.05f, 0.116f, 0.95f, 0.165f, (UnityAction)delegate
			{
				materialOption++;
				message = "";
				Refresh();
			});
			upgrade = Button((Transform)(object)details, "Upgrade equipment", "Upgrade", 0.12f, 0.04f, 0.88f, 0.11f, new UnityAction(Commit));
			status = Text((Transform)(object)details, "Status", "", 0.04f, 0.002f, 0.96f, 0.038f, 14, (TextAlignmentOptions)514);
			status.enableAutoSizing = true;
			status.fontSizeMin = 8f;
			status.fontSizeMax = 14f;
			BuildItemList();
			ApplyViewLayout();
			((Component)backdrop).gameObject.SetActive(false);
		}

		private List<ItemData> Items()
		{
			IEnumerable<ItemData> source = ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(Station.Eligible);
			if (!traditional)
			{
				return source.ToList();
			}
			return source.OrderBy<ItemData, string>((ItemData i) => Localization.instance.Localize(i.m_shared.m_name), StringComparer.CurrentCultureIgnoreCase).ThenBy((ItemData i) => i.m_quality).ToList();
		}

		private void BuildItemList()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			itemList = Rect("TraditionalEquipmentList", (Transform)(object)panel, new Vector2(0.025f, 0.08f), new Vector2(0.445f, 0.86f));
			((Graphic)((Component)itemList).gameObject.AddComponent<Image>()).color = new Color(0.14f, 0.12f, 0.09f, 0.8f);
			Text((Transform)(object)itemList, "List heading", "EQUIPMENT", 0.03f, 0.94f, 0.93f, 0.995f, 16, (TextAlignmentOptions)514);
			RectTransform val = Rect("ItemScroll", (Transform)(object)itemList, Vector2.zero, new Vector2(1f, 0.935f));
			listViewport = Rect("Viewport", (Transform)(object)val, Vector2.zero, new Vector2(0.93f, 1f));
			((Component)listViewport).gameObject.AddComponent<RectMask2D>();
			((Graphic)((Component)listViewport).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.02f);
			listContent = Rect("Content", (Transform)(object)listViewport, new Vector2(0f, 1f), Vector2.one);
			listContent.pivot = new Vector2(0.5f, 1f);
			itemScroll = ((Component)val).gameObject.AddComponent<ScrollRect>();
			itemScroll.viewport = listViewport;
			itemScroll.content = listContent;
			itemScroll.horizontal = false;
			itemScroll.movementType = (MovementType)2;
			itemScroll.scrollSensitivity = 30f;
			RectTransform val2 = Rect("Scrollbar", (Transform)(object)val, new Vector2(0.945f, 0.015f), new Vector2(0.99f, 0.985f));
			((Graphic)((Component)val2).gameObject.AddComponent<Image>()).color = new Color(0.22f, 0.18f, 0.12f);
			RectTransform val3 = Rect("Handle", (Transform)(object)val2, Vector2.zero, Vector2.one);
			Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.75f, 0.59f, 0.35f);
			Scrollbar val5 = ((Component)val2).gameObject.AddComponent<Scrollbar>();
			val5.handleRect = val3;
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			val5.direction = (Direction)2;
			itemScroll.verticalScrollbar = val5;
			itemScroll.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			listCount = Text((Transform)(object)panel, "List count", "", 0.025f, 0.025f, 0.445f, 0.07f, 13, (TextAlignmentOptions)514);
		}

		private void ApplyViewLayout()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			details.anchorMin = (Vector2)(traditional ? new Vector2(0.46f, 0f) : Vector2.zero);
			details.anchorMax = new Vector2(1f, 0.875f);
			RectTransform obj = details;
			Vector2 offsetMin = (details.offsetMax = Vector2.zero);
			obj.offsetMin = offsetMin;
			((Component)itemList).gameObject.SetActive(traditional);
			((Component)listCount).gameObject.SetActive(traditional);
			((Component)previous).gameObject.SetActive(!traditional);
			((Component)nextItem).gameObject.SetActive(!traditional);
			RectTransform val = (RectTransform)selection.transform;
			val.anchorMin = new Vector2(traditional ? 0.03f : 0.19f, 0.855f);
			val.anchorMax = new Vector2(traditional ? 0.97f : 0.81f, 0.925f);
			offsetMin = (val.offsetMax = Vector2.zero);
			val.offsetMin = offsetMin;
			((Component)viewToggle).GetComponentInChildren<TMP_Text>().text = (traditional ? "Use Selector View" : "Use Traditional List");
			stats.fontSize = 14f;
			stats.enableAutoSizing = true;
			stats.fontSizeMin = 8f;
			stats.fontSizeMax = 14f;
			statsScroll.StopMovement();
			((Behaviour)statsScroll).enabled = false;
			RectTransform content = statsScroll.content;
			content.anchorMin = Vector2.zero;
			content.anchorMax = Vector2.one;
			offsetMin = (content.offsetMax = Vector2.zero);
			content.offsetMin = offsetMin;
		}

		private void RefreshItemList(List<ItemData> items)
		{
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result t