Decompiled source of CraftGuard v0.1.2

CraftGuard.dll

Decompiled 12 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InventoryUX.Core;
using InventoryUX.Runtime;
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("CraftGuard")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+519a49c399d64d3275a092e9dfe269a0696aaf8b")]
[assembly: AssemblyProduct("CraftGuard")]
[assembly: AssemblyTitle("CraftGuard")]
[assembly: AssemblyVersion("0.1.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 InventoryUX
{
	[BepInPlugin("com.inventoryux.valheim", "CraftGuard", "0.1.2")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "com.inventoryux.valheim";

		internal const string PluginName = "CraftGuard";

		internal const string PluginVersion = "0.1.2";

		private Harmony? _harmony;

		internal static ManualLogSource LogInstance { get; private set; }

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Instance = this;
			LogInstance = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.inventoryux.valheim");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"CraftGuard 0.1.2 loaded. Undiscovered content is never rendered.");
		}

		private void Update()
		{
			if (ModConfig.Enabled.Value && ModConfig.WriteDataInventoryOnStartup.Value)
			{
				DataInventoryWriter.TryWriteOnce();
			}
		}

		private void OnDestroy()
		{
			HammerGroupDecorations.Shutdown();
			HammerGridSizer.Restore();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace InventoryUX.Runtime
{
	internal enum CraftingSection
	{
		Workbench,
		Forge,
		Cooking,
		Advanced,
		Processing,
		Utility
	}
	internal readonly struct CraftingPieceLayout
	{
		internal CraftingSection Section { get; }

		internal int SortOrder { get; }

		internal int Subgroup { get; }

		internal bool IsPrimaryStation { get; }

		internal CraftingPieceLayout(CraftingSection section, int sortOrder, int subgroup, bool isPrimaryStation = false)
		{
			Section = section;
			SortOrder = sortOrder;
			Subgroup = subgroup;
			IsPrimaryStation = isPrimaryStation;
		}
	}
	internal static class CraftingLayoutMetadata
	{
		private readonly struct PieceRule
		{
			internal CraftingPieceLayout Layout { get; }

			private string[] Markers { get; }

			internal PieceRule(CraftingPieceLayout layout, string[] markers)
			{
				Layout = layout;
				Markers = markers;
			}

			internal bool Matches(string id)
			{
				for (int i = 0; i < Markers.Length; i++)
				{
					if (id.Contains(Markers[i]))
					{
						return true;
					}
				}
				return false;
			}
		}

		private static readonly PieceRule[] Rules = new PieceRule[46]
		{
			Rule(CraftingSection.Workbench, 110, 0, "choppingblock"),
			Rule(CraftingSection.Workbench, 120, 0, "tanningrack"),
			Rule(CraftingSection.Workbench, 130, 0, "adze"),
			Rule(CraftingSection.Workbench, 140, 0, "toolshelf"),
			Rule(CraftingSection.Workbench, 100, 0, true, "workbench"),
			Rule(CraftingSection.Forge, 210, 0, "forgebellows", "bellows"),
			Rule(CraftingSection.Forge, 220, 0, "anvils"),
			Rule(CraftingSection.Forge, 230, 0, "grindingwheel"),
			Rule(CraftingSection.Forge, 240, 0, "smithsanvil"),
			Rule(CraftingSection.Forge, 250, 0, "forgecooler"),
			Rule(CraftingSection.Forge, 260, 0, "forgetoolrack", "toolrack"),
			Rule(CraftingSection.Forge, 100, 0, true, "forge"),
			Rule(CraftingSection.Cooking, 110, 0, "spicerack"),
			Rule(CraftingSection.Cooking, 120, 0, "butcherstable", "butchertable"),
			Rule(CraftingSection.Cooking, 130, 0, "potsandpans"),
			Rule(CraftingSection.Cooking, 140, 0, "mortarandpestle", "mortar"),
			Rule(CraftingSection.Cooking, 150, 0, "rollingpin", "cuttingboard"),
			Rule(CraftingSection.Cooking, 400, 3, true, "meadketill", "meadkettle", "ketill", "kettle"),
			Rule(CraftingSection.Cooking, 410, 3, "fermenter", "fermentationbarrel"),
			Rule(CraftingSection.Cooking, 100, 0, true, "cauldron"),
			Rule(CraftingSection.Cooking, 210, 1, "ironcookingstation", "cookingstationiron"),
			Rule(CraftingSection.Cooking, 200, 1, true, "cookingstation"),
			Rule(CraftingSection.Cooking, 300, 2, true, "foodpreparation", "foodprep", "preptable"),
			Rule(CraftingSection.Cooking, 310, 2, "stoneoven", "oven"),
			Rule(CraftingSection.Advanced, 110, 0, "artisanpress"),
			Rule(CraftingSection.Advanced, 100, 0, true, "artisantable", "artisan"),
			Rule(CraftingSection.Advanced, 210, 1, "blackforgecooler"),
			Rule(CraftingSection.Advanced, 200, 1, true, "blackforge"),
			Rule(CraftingSection.Advanced, 300, 2, "gemcutter"),
			Rule(CraftingSection.Advanced, 310, 2, "metalcutter"),
			Rule(CraftingSection.Advanced, 320, 2, "vice", "vise"),
			Rule(CraftingSection.Advanced, 410, 3, "unfadingcandles"),
			Rule(CraftingSection.Advanced, 420, 3, "featherywreath", "wreath"),
			Rule(CraftingSection.Advanced, 430, 3, "runetable"),
			Rule(CraftingSection.Advanced, 400, 3, true, "galdrtable", "galdr"),
			Rule(CraftingSection.Processing, 100, 0, "charcoalkiln", "kiln"),
			Rule(CraftingSection.Processing, 110, 0, "smelter"),
			Rule(CraftingSection.Processing, 120, 0, "blastfurnace"),
			Rule(CraftingSection.Processing, 130, 0, "windmill"),
			Rule(CraftingSection.Processing, 140, 0, "spinningwheel"),
			Rule(CraftingSection.Processing, 150, 0, "sapextractor", "sapcollector"),
			Rule(CraftingSection.Processing, 160, 0, "obliterator", "incinerator"),
			Rule(CraftingSection.Processing, 170, 0, "eitrrefinery", "refineryeitr"),
			Rule(CraftingSection.Utility, 100, 0, "stonecutter"),
			Rule(CraftingSection.Utility, 110, 0, "beehive"),
			Rule(CraftingSection.Utility, 120, 0, "wispfountain")
		};

		internal static CraftingPieceLayout Resolve(Piece piece)
		{
			string text = Normalize(HammerOrganizer.GetLabel(piece));
			string text2 = ((Localization.instance != null) ? Localization.instance.Localize(piece.m_name) : piece.m_name);
			string text3 = Normalize(text + " " + ((Object)((Component)piece).gameObject).name + " " + piece.m_name + " " + text2);
			if (ContainsAny(text3, "eitrrefinery", "refineryeitr"))
			{
				return ResolveWithin(text3, CraftingSection.Processing, 170, 0);
			}
			if (text.Contains("workbench"))
			{
				return ResolveWithin(text3, CraftingSection.Workbench, 900, 1);
			}
			if (text.Contains("artisan"))
			{
				return ResolveWithin(text3, CraftingSection.Advanced, 900, 0);
			}
			if (text.Contains("blackforge"))
			{
				return ResolveWithin(text3, CraftingSection.Advanced, 900, 1);
			}
			if (text.Contains("galdr"))
			{
				return ResolveWithin(text3, CraftingSection.Advanced, 900, 3);
			}
			if (text.Contains("forge"))
			{
				return ResolveWithin(text3, CraftingSection.Forge, 900, 1);
			}
			if (ContainsAny(text, "cauldron", "foodpreparation", "foodprep", "preptable", "cooking"))
			{
				return ResolveWithin(text3, CraftingSection.Cooking, 900, 3);
			}
			if (ContainsAny(text, "mead", "ketill", "kettle", "brewing"))
			{
				return ResolveWithin(text3, CraftingSection.Cooking, 900, 3);
			}
			for (int i = 0; i < Rules.Length; i++)
			{
				if (Rules[i].Matches(text3))
				{
					return Rules[i].Layout;
				}
			}
			return new CraftingPieceLayout(CraftingSection.Utility, 900, 9);
		}

		internal static string Label(CraftingSection section)
		{
			return section switch
			{
				CraftingSection.Workbench => "WORKBENCH", 
				CraftingSection.Forge => "FORGE", 
				CraftingSection.Cooking => "COOKING", 
				CraftingSection.Advanced => "ADVANCED", 
				CraftingSection.Processing => "PROCESSING", 
				_ => "UTILITY", 
			};
		}

		internal static bool IsRepair(Piece piece)
		{
			if (piece.m_repairPiece)
			{
				return true;
			}
			string text = Normalize(((Object)((Component)piece).gameObject).name);
			string text2 = Normalize(piece.m_name);
			switch (text)
			{
			default:
				if (!(text2 == "repair"))
				{
					return text2 == "piecerepair";
				}
				break;
			case "repair":
			case "piecerepair":
			case "hammerrepair":
			case "repairpiece":
				break;
			}
			return true;
		}

		private static CraftingPieceLayout ResolveWithin(string id, CraftingSection section, int fallbackOrder, int fallbackSubgroup)
		{
			for (int i = 0; i < Rules.Length; i++)
			{
				PieceRule pieceRule = Rules[i];
				if (pieceRule.Layout.Section == section && pieceRule.Matches(id))
				{
					return pieceRule.Layout;
				}
			}
			return new CraftingPieceLayout(section, fallbackOrder, fallbackSubgroup);
		}

		private static PieceRule Rule(CraftingSection section, int order, int subgroup, params string[] markers)
		{
			return new PieceRule(new CraftingPieceLayout(section, order, subgroup), markers);
		}

		private static PieceRule Rule(CraftingSection section, int order, int subgroup, bool primary, params string[] markers)
		{
			return new PieceRule(new CraftingPieceLayout(section, order, subgroup, primary), markers);
		}

		private static bool ContainsAny(string value, params string[] markers)
		{
			for (int i = 0; i < markers.Length; i++)
			{
				if (value.Contains(markers[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static string Normalize(string? value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			char[] array = new char[value.Length];
			int length = 0;
			foreach (char c in value)
			{
				if (char.IsLetterOrDigit(c))
				{
					array[length++] = char.ToLower(c, CultureInfo.InvariantCulture);
				}
			}
			return new string(array, 0, length);
		}
	}
	internal static class DataInventoryWriter
	{
		private static bool _written;

		internal static void TryWriteOnce()
		{
			if (_written || (Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "CraftGuard");
				Directory.CreateDirectory(text);
				string text2 = Path.Combine(text, "loaded-data-inventory.csv");
				File.WriteAllText(text2, BuildCsv(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
				_written = true;
				Plugin.LogInstance.LogInfo((object)("Wrote the loaded piece/recipe inventory to " + text2));
			}
			catch (Exception arg)
			{
				_written = true;
				Plugin.LogInstance.LogError((object)$"Could not write the data inventory: {arg}");
			}
		}

		private static string BuildCsv()
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteRow(stringBuilder, "ContentType", "PrefabID", "DisplayName", "KnownUnlockMechanism", "HammerCategory", "PieceType", "CraftingStation", "StationExtensionParent", "StationLevelContribution", "ItemType", "WeaponFamily", "ArmorType", "Recipe", "Ingredients", "RequiredStation", "RequiredStationLevel", "FoodHP", "FoodStamina", "FoodEitr", "FoodDuration", "FoodRegen", "ProposedGroup", "ProposedBiome", "ProposedSortOrder");
			WritePieces(stringBuilder);
			WriteRecipes(stringBuilder);
			return stringBuilder.ToString();
		}

		private static void WritePieces(StringBuilder output)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			List<GameObject> prefabs = ZNetScene.instance.m_prefabs;
			for (int i = 0; i < prefabs.Count; i++)
			{
				GameObject val = prefabs[i];
				if (!((Object)(object)val == (Object)null))
				{
					Piece component = val.GetComponent<Piece>();
					if (!((Object)(object)component == (Object)null) && hashSet.Add(((Object)val).name))
					{
						CraftingStation component2 = val.GetComponent<CraftingStation>();
						StationExtension component3 = val.GetComponent<StationExtension>();
						PieceGroup pieceGroup = HammerOrganizer.Classify(component, component.m_category);
						string text = (((Object)(object)component2 != (Object)null) ? "Crafting station" : (((Object)(object)component3 != (Object)null) ? "Station extension" : "Build piece"));
						WriteRow(output, "Piece", ((Object)val).name, Localize(component.m_name), "Piece.m_name in Player.m_knownRecipes", ((object)Unsafe.As<PieceCategory, PieceCategory>(ref component.m_category)/*cast due to .constrained prefix*/).ToString(), text, ((Object)(object)component.m_craftingStation != (Object)null) ? Localize(component.m_craftingStation.m_name) : (((Object)(object)component2 != (Object)null) ? Localize(component2.m_name) : string.Empty), ((Object)(object)component3 != (Object)null && (Object)(object)component3.m_craftingStation != (Object)null) ? Localize(component3.m_craftingStation.m_name) : string.Empty, ((Object)(object)component3 != (Object)null) ? "Native unique attached extension (+1)" : string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, FormatPieceIngredients(component), string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, pieceGroup.Label, string.Empty, $"{pieceGroup.Order}:{pieceGroup.Suborder}");
					}
				}
			}
		}

		private static void WriteRecipes(StringBuilder output)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			List<Recipe> recipes = ObjectDB.instance.m_recipes;
			for (int i = 0; i < recipes.Count; i++)
			{
				Recipe val = recipes[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.m_item == (Object)null))
				{
					SharedData shared = val.m_item.m_itemData.m_shared;
					RecipeFacts recipeFacts = ToFacts(val, i);
					RecipeGroup recipeGroup = (recipeFacts.IsFeast ? new RecipeGroup("Feasts", 4) : (recipeFacts.IsFood ? FoodClassifier.ToGroup(FoodClassifier.Classify(recipeFacts.Health, recipeFacts.Stamina, recipeFacts.Eitr)) : RecipeClassifier.GetTypeGroup(recipeFacts)));
					ProgressionBiome biome = BiomeClassifier.Classify(recipeFacts.Id, recipeFacts.IngredientIds);
					WriteRow(output, "Recipe", recipeFacts.Id, recipeFacts.DisplayName, "Player.GetAvailableRecipes / Player.IsRecipeKnown", string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, ((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString(), ((object)Unsafe.As<SkillType, SkillType>(ref shared.m_skillType)/*cast due to .constrained prefix*/).ToString(), ArmorType(shared.m_itemType), ((Object)val).name, FormatRecipeIngredients(val), ((Object)(object)val.m_craftingStation != (Object)null) ? Localize(val.m_craftingStation.m_name) : string.Empty, val.m_minStationLevel.ToString(CultureInfo.InvariantCulture), shared.m_food.ToString(CultureInfo.InvariantCulture), shared.m_foodStamina.ToString(CultureInfo.InvariantCulture), shared.m_foodEitr.ToString(CultureInfo.InvariantCulture), shared.m_foodBurnTime.ToString(CultureInfo.InvariantCulture), shared.m_foodRegen.ToString(CultureInfo.InvariantCulture), recipeGroup.Label, biome.ToString(), $"{BiomeClassifier.ToGroup(biome).Order}:{recipeGroup.Order}");
				}
			}
		}

		private static RecipeFacts ToFacts(Recipe recipe, int originalIndex)
		{
			SharedData shared = recipe.m_item.m_itemData.m_shared;
			List<string> list = new List<string>();
			if (recipe.m_resources != null)
			{
				for (int i = 0; i < recipe.m_resources.Length; i++)
				{
					ItemDrop val = recipe.m_resources[i]?.m_resItem;
					if (!((Object)(object)val == (Object)null))
					{
						list.Add(((Object)((Component)val).gameObject).name);
						list.Add(val.m_itemData.m_shared.m_name);
					}
				}
			}
			ResolvedFoodStats resolvedFoodStats = FoodStatsResolver.Resolve(recipe.m_item);
			float health = (resolvedFoodStats.Resolved ? resolvedFoodStats.Health : shared.m_food);
			float stamina = (resolvedFoodStats.Resolved ? resolvedFoodStats.Stamina : shared.m_foodStamina);
			float eitr = (resolvedFoodStats.Resolved ? resolvedFoodStats.Eitr : shared.m_foodEitr);
			return new RecipeFacts(((Object)((Component)recipe.m_item).gameObject).name, Localize(shared.m_name), ((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString(), ((object)Unsafe.As<SkillType, SkillType>(ref shared.m_skillType)/*cast due to .constrained prefix*/).ToString(), list, health, stamina, eitr, originalIndex, resolvedFoodStats.IsFeast);
		}

		private static string FormatPieceIngredients(Piece piece)
		{
			if (piece.m_resources == null)
			{
				return string.Empty;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < piece.m_resources.Length; i++)
			{
				Requirement val = piece.m_resources[i];
				if ((Object)(object)val?.m_resItem != (Object)null)
				{
					list.Add($"{Localize(val.m_resItem.m_itemData.m_shared.m_name)} x{val.m_amount}");
				}
			}
			return string.Join("; ", list);
		}

		private static string FormatRecipeIngredients(Recipe recipe)
		{
			if (recipe.m_resources == null)
			{
				return string.Empty;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < recipe.m_resources.Length; i++)
			{
				Requirement val = recipe.m_resources[i];
				if ((Object)(object)val?.m_resItem != (Object)null)
				{
					list.Add($"{Localize(val.m_resItem.m_itemData.m_shared.m_name)} x{val.m_amount}");
				}
			}
			return string.Join("; ", list);
		}

		private static string ArmorType(ItemType itemType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected I4, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			switch (itemType - 6)
			{
			default:
				if ((int)itemType != 17)
				{
					break;
				}
				return "Shoulder";
			case 0:
				return "Helmet";
			case 1:
				return "Chest";
			case 5:
				return "Legs";
			case 6:
				return "Hands";
			case 2:
			case 3:
			case 4:
				break;
			}
			return string.Empty;
		}

		private static string Localize(string value)
		{
			if (Localization.instance == null)
			{
				return value;
			}
			return Localization.instance.Localize(value);
		}

		private static void WriteRow(StringBuilder output, params string[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				if (i > 0)
				{
					output.Append(',');
				}
				output.Append(Escape(values[i]));
			}
			output.AppendLine();
		}

		private static string Escape(string? value)
		{
			value = value ?? string.Empty;
			if (value.IndexOfAny(new char[4] { ',', '"', '\r', '\n' }) < 0)
			{
				return value;
			}
			return "\"" + value.Replace("\"", "\"\"") + "\"";
		}
	}
	internal static class FoodStatsResolver
	{
		private static readonly Dictionary<string, ItemDrop> CookedByInput = new Dictionary<string, ItemDrop>(StringComparer.Ordinal);

		private static readonly Dictionary<string, ItemDrop> FeastFoodByInput = new Dictionary<string, ItemDrop>(StringComparer.Ordinal);

		private static int _sceneInstanceId = int.MinValue;

		private static int _scenePrefabCount = -1;

		internal static ResolvedFoodStats Resolve(ItemDrop output)
		{
			EnsureIndex();
			if (output == null || (Object)(object)output == (Object)null)
			{
				return default(ResolvedFoodStats);
			}
			Feast val = ((Component)output).GetComponent<Feast>() ?? ((Component)output).GetComponentInChildren<Feast>(true);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? GetFeastFood(val) : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return FromItem(val2, resolved: true, isFeast: true);
			}
			string name = ((Object)((Component)output).gameObject).name;
			if (FeastFoodByInput.TryGetValue(name, out ItemDrop value) && (Object)(object)value != (Object)null)
			{
				return FromItem(value, resolved: true, isFeast: true);
			}
			ItemDrop val3 = output;
			bool resolved = false;
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < 4; i++)
			{
				string name2 = ((Object)((Component)val3).gameObject).name;
				if (!hashSet.Add(name2) || !CookedByInput.TryGetValue(name2, out ItemDrop value2) || (Object)(object)value2 == (Object)null)
				{
					break;
				}
				val3 = value2;
				resolved = true;
			}
			return FromItem(val3, resolved, isFeast: false);
		}

		private static void EnsureIndex()
		{
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Invalid comparison between Unknown and I4
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null || instance.m_prefabs == null)
			{
				return;
			}
			int instanceID = ((Object)instance).GetInstanceID();
			int count = instance.m_prefabs.Count;
			if (_sceneInstanceId == instanceID && _scenePrefabCount == count)
			{
				return;
			}
			_sceneInstanceId = instanceID;
			_scenePrefabCount = count;
			CookedByInput.Clear();
			FeastFoodByInput.Clear();
			for (int i = 0; i < instance.m_prefabs.Count; i++)
			{
				GameObject val = instance.m_prefabs[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				CookingStation[] componentsInChildren = val.GetComponentsInChildren<CookingStation>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					List<ItemConversion> conversion = componentsInChildren[j].m_conversion;
					if (conversion == null)
					{
						continue;
					}
					for (int k = 0; k < conversion.Count; k++)
					{
						ItemConversion val2 = conversion[k];
						if (!((Object)(object)val2?.m_from == (Object)null) && !((Object)(object)val2.m_to == (Object)null))
						{
							string name = ((Object)((Component)val2.m_from).gameObject).name;
							if (!CookedByInput.ContainsKey(name))
							{
								CookedByInput.Add(name, val2.m_to);
							}
						}
					}
				}
				Feast[] componentsInChildren2 = val.GetComponentsInChildren<Feast>(true);
				foreach (Feast val3 in componentsInChildren2)
				{
					Piece val4 = ((Component)val3).GetComponent<Piece>() ?? ((Component)val3).GetComponentInParent<Piece>();
					ItemDrop feastFood = GetFeastFood(val3);
					if ((Object)(object)feastFood == (Object)null)
					{
						continue;
					}
					ItemDrop val5 = ((Component)val3).GetComponent<ItemDrop>() ?? ((Component)val3).GetComponentInParent<ItemDrop>();
					if ((Object)(object)val5 != (Object)null)
					{
						AddFeastMapping(((Object)((Component)val5).gameObject).name, feastFood);
					}
					ItemDrop component = val.GetComponent<ItemDrop>();
					if ((Object)(object)component != (Object)null)
					{
						AddFeastMapping(((Object)((Component)component).gameObject).name, feastFood);
					}
					if ((Object)(object)val4 == (Object)null || (int)val4.m_category != 5 || val4.m_resources == null)
					{
						continue;
					}
					for (int m = 0; m < val4.m_resources.Length; m++)
					{
						ItemDrop val6 = val4.m_resources[m]?.m_resItem;
						if (!((Object)(object)val6 == (Object)null))
						{
							AddFeastMapping(((Object)((Component)val6).gameObject).name, feastFood);
						}
					}
				}
			}
		}

		private static ItemDrop? GetFeastFood(Feast feast)
		{
			if ((Object)(object)feast.m_foodItem != (Object)null)
			{
				return feast.m_foodItem;
			}
			return ((Component)feast).GetComponent<ItemDrop>() ?? ((Component)feast).GetComponentInParent<ItemDrop>();
		}

		private static void AddFeastMapping(string inputId, ItemDrop feastFood)
		{
			if (!string.IsNullOrEmpty(inputId) && !FeastFoodByInput.ContainsKey(inputId))
			{
				FeastFoodByInput.Add(inputId, feastFood);
			}
		}

		private static ResolvedFoodStats FromItem(ItemDrop item, bool resolved, bool isFeast)
		{
			SharedData shared = item.m_itemData.m_shared;
			return new ResolvedFoodStats(shared.m_food, shared.m_foodStamina, shared.m_foodEitr, resolved, isFeast);
		}
	}
	internal readonly struct ResolvedFoodStats
	{
		internal float Health { get; }

		internal float Stamina { get; }

		internal float Eitr { get; }

		internal bool Resolved { get; }

		internal bool IsFeast { get; }

		internal ResolvedFoodStats(float health, float stamina, float eitr, bool resolved, bool isFeast)
		{
			Health = health;
			Stamina = stamina;
			Eitr = eitr;
			Resolved = resolved;
			IsFeast = isFeast;
		}
	}
	internal static class HammerGridDimensions
	{
		internal const int NativeWidth = 15;

		internal const int NativeHeight = 6;

		internal const int ExpandedWidth = 15;

		internal const int ExpandedHeight = 6;

		internal const float ReferenceCraftingRowScale = 1.1666666f;

		internal static int Width
		{
			get
			{
				if (!ModConfig.Enabled.Value)
				{
					return 15;
				}
				return 15;
			}
		}

		internal static int Height
		{
			get
			{
				if (!ModConfig.Enabled.Value)
				{
					return 6;
				}
				return 6;
			}
		}

		internal static int MaxX => Width - 1;

		internal static int MaxY => Height - 1;

		internal static float CraftingRowPitch(Hud hud)
		{
			return hud.m_pieceIconSpacing * 1.1666666f;
		}
	}
	internal static class HammerGridSizer
	{
		private sealed class RectState
		{
			private readonly RectTransform _rect;

			private readonly Vector2 _sizeDelta;

			private readonly Vector2 _anchoredPosition;

			internal RectState(RectTransform rect)
			{
				//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_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				_rect = rect;
				_sizeDelta = rect.sizeDelta;
				_anchoredPosition = rect.anchoredPosition;
			}

			internal void Restore()
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_rect == (Object)null))
				{
					_rect.sizeDelta = _sizeDelta;
					_rect.anchoredPosition = _anchoredPosition;
				}
			}
		}

		private sealed class ReparentedRectState
		{
			private readonly RectTransform _rect;

			private readonly Transform _parent;

			private readonly int _siblingIndex;

			private readonly Vector2 _anchorMin;

			private readonly Vector2 _anchorMax;

			private readonly Vector2 _pivot;

			private readonly Vector2 _sizeDelta;

			private readonly Vector2 _anchoredPosition;

			internal ReparentedRectState(RectTransform rect)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: 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_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				_rect = rect;
				_parent = ((Transform)rect).parent;
				_siblingIndex = ((Transform)rect).GetSiblingIndex();
				_anchorMin = rect.anchorMin;
				_anchorMax = rect.anchorMax;
				_pivot = rect.pivot;
				_sizeDelta = rect.sizeDelta;
				_anchoredPosition = rect.anchoredPosition;
			}

			internal void Restore()
			{
				//IL_0059: 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_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_rect == (Object)null) && !((Object)(object)_parent == (Object)null))
				{
					((Transform)_rect).SetParent(_parent, false);
					((Transform)_rect).SetSiblingIndex(Mathf.Min(_siblingIndex, _parent.childCount - 1));
					_rect.anchorMin = _anchorMin;
					_rect.anchorMax = _anchorMax;
					_rect.pivot = _pivot;
					_rect.sizeDelta = _sizeDelta;
					_rect.anchoredPosition = _anchoredPosition;
				}
			}
		}

		private static int _hudInstanceId = int.MinValue;

		private static RectState? _windowState;

		private static RectState? _maskState;

		private static RectState? _categoryState;

		private static ReparentedRectState? _previousCategoryControlState;

		internal static float RepairRailWidth { get; private set; }

		internal static void Apply(Hud hud)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)hud).GetInstanceID();
			if (_hudInstanceId != instanceID)
			{
				Restore();
				float pieceIconSpacing = hud.m_pieceIconSpacing;
				float num = 0f * pieceIconSpacing;
				float num2 = Mathf.Max(0f, 1f * pieceIconSpacing);
				RepairRailWidth = pieceIconSpacing + 28f;
				RectTransform val = (((Object)(object)hud.m_pieceSelectionWindow != (Object)null) ? hud.m_pieceSelectionWindow.GetComponent<RectTransform>() : null);
				if ((Object)(object)val != (Object)null)
				{
					_windowState = new RectState(val);
					ExpandCentered(val, num + RepairRailWidth, num2);
				}
				RectTransform pieceListMask = hud.m_pieceListMask;
				if ((Object)(object)pieceListMask != (Object)null)
				{
					_maskState = new RectState(pieceListMask);
					float widthDelta = (Mathf.Approximately(pieceListMask.anchorMin.x, pieceListMask.anchorMax.x) ? num : 0f);
					float heightDelta = (Mathf.Approximately(pieceListMask.anchorMin.y, pieceListMask.anchorMax.y) ? num2 : 0f);
					ExpandKeepingTopLeft(pieceListMask, widthDelta, heightDelta);
					pieceListMask.anchoredPosition += new Vector2(RepairRailWidth, 0f);
				}
				RectTransform val2 = (((Object)(object)hud.m_pieceCategoryRoot != (Object)null) ? hud.m_pieceCategoryRoot.GetComponent<RectTransform>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					_categoryState = new RectState(val2);
					val2.sizeDelta -= new Vector2(RepairRailWidth, 0f);
					val2.anchoredPosition += new Vector2(RepairRailWidth * (1f - val2.pivot.x), 0f);
					MovePreviousCategoryControl(val2, val, RepairRailWidth);
				}
				_hudInstanceId = instanceID;
			}
		}

		internal static void Restore()
		{
			_windowState?.Restore();
			_maskState?.Restore();
			_categoryState?.Restore();
			_previousCategoryControlState?.Restore();
			_windowState = null;
			_maskState = null;
			_categoryState = null;
			_previousCategoryControlState = null;
			_hudInstanceId = int.MinValue;
			RepairRailWidth = 0f;
		}

		private static void MovePreviousCategoryControl(RectTransform categoryRoot, RectTransform? window, float repairRailWidth)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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)
			if (!((Object)(object)window == (Object)null))
			{
				RectTransform val = FindInteractiveControl(categoryRoot, "Q") ?? FindInteractiveControl(window, "Q");
				if (!((Object)(object)val == (Object)null))
				{
					_previousCategoryControlState = new ReparentedRectState(val);
					((Transform)val).SetParent((Transform)(object)window, false);
					((Transform)val).SetAsLastSibling();
					val.anchorMin = new Vector2(0f, 1f);
					val.anchorMax = new Vector2(0f, 1f);
					val.pivot = new Vector2(0f, 1f);
					val.anchoredPosition = new Vector2(repairRailWidth + 42f, -18f);
				}
			}
		}

		private static RectTransform? FindInteractiveControl(RectTransform root, string displayedText)
		{
			TextMeshProUGUI[] componentsInChildren = ((Component)root).GetComponentsInChildren<TextMeshProUGUI>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (string.Equals(((TMP_Text)componentsInChildren[i]).text?.Trim(), displayedText, StringComparison.OrdinalIgnoreCase))
				{
					return InteractiveAncestor(root, ((TMP_Text)componentsInChildren[i]).transform);
				}
			}
			Text[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<Text>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if (string.Equals(componentsInChildren2[j].text?.Trim(), displayedText, StringComparison.OrdinalIgnoreCase))
				{
					return InteractiveAncestor(root, ((Component)componentsInChildren2[j]).transform);
				}
			}
			return null;
		}

		private static RectTransform? InteractiveAncestor(RectTransform root, Transform child)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)(object)root && (Object)(object)val.parent != (Object)null)
			{
				if ((Object)(object)((Component)val).GetComponent<UIInputHandler>() != (Object)null || (Object)(object)((Component)val).GetComponent<Button>() != (Object)null)
				{
					return (RectTransform?)(object)((val is RectTransform) ? val : null);
				}
				val = val.parent;
			}
			return TopLevelChild(root, child);
		}

		private static RectTransform? TopLevelChild(RectTransform root, Transform child)
		{
			Transform val = child;
			while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root)
			{
				val = val.parent;
			}
			if (!((Object)(object)val.parent == (Object)(object)root))
			{
				return null;
			}
			return (RectTransform?)(object)((val is RectTransform) ? val : null);
		}

		private static void ExpandCentered(RectTransform rect, float widthDelta, float heightDelta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			rect.sizeDelta += new Vector2(widthDelta, heightDelta);
		}

		private static void ExpandKeepingTopLeft(RectTransform rect, float widthDelta, float heightDelta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			rect.sizeDelta += new Vector2(widthDelta, heightDelta);
			rect.anchoredPosition += new Vector2(widthDelta * rect.pivot.x, (0f - heightDelta) * (1f - rect.pivot.y));
		}
	}
	internal static class HammerGroupDecorations
	{
		private readonly struct CraftingEntry
		{
			internal int PieceIndex { get; }

			internal CraftingPieceLayout Metadata { get; }

			internal string Name { get; }

			internal CraftingEntry(int pieceIndex, CraftingPieceLayout metadata, string name)
			{
				PieceIndex = pieceIndex;
				Metadata = metadata;
				Name = name;
			}
		}

		private sealed class CraftingLayoutResult
		{
			internal int[] Slots { get; }

			internal float[] XOffsets { get; }

			internal int RepairIndex { get; }

			internal CraftingSection?[] RowSections { get; }

			internal int[] Representatives { get; }

			internal List<SubgroupDivider> SubgroupBreaks { get; }

			internal int VisibleRows { get; }

			internal CraftingLayoutResult(int[] slots, float[] xOffsets, int repairIndex, CraftingSection?[] rowSections, int[] representatives, List<SubgroupDivider> subgroupBreaks, int visibleRows)
			{
				Slots = slots;
				XOffsets = xOffsets;
				RepairIndex = repairIndex;
				RowSections = rowSections;
				Representatives = representatives;
				SubgroupBreaks = subgroupBreaks;
				VisibleRows = visibleRows;
			}
		}

		private readonly struct SubgroupDivider
		{
			internal int Row { get; }

			internal int Column { get; }

			internal int GapCount { get; }

			internal SubgroupDivider(int row, int column, int gapCount)
			{
				Row = row;
				Column = column;
				GapCount = gapCount;
			}
		}

		private sealed class ShelfLayoutResult
		{
			internal int[] Slots { get; }

			internal float[] XPositions { get; }

			internal List<ShelfCard> Cards { get; }

			internal List<ShelfDivider> Dividers { get; }

			internal int VisibleRows { get; }

			internal float RowPitch { get; }

			internal int RepairIndex { get; }

			internal ShelfLayoutResult(int[] slots, float[] xPositions, List<ShelfCard> cards, List<ShelfDivider> dividers, int visibleRows, float rowPitch, int repairIndex)
			{
				Slots = slots;
				XPositions = xPositions;
				Cards = cards;
				Dividers = dividers;
				VisibleRows = visibleRows;
				RowPitch = rowPitch;
				RepairIndex = repairIndex;
			}
		}

		private readonly struct ShelfCard
		{
			internal int StartRow { get; }

			internal int RowSpan { get; }

			internal string Label { get; }

			internal int Representative { get; }

			internal ShelfCard(int startRow, int rowSpan, string label, int representative)
			{
				StartRow = startRow;
				RowSpan = rowSpan;
				Label = label;
				Representative = representative;
			}
		}

		private readonly struct ShelfDivider
		{
			internal int Row { get; }

			internal float X { get; }

			internal ShelfDivider(int row, float x)
			{
				Row = row;
				X = x;
			}
		}

		private readonly struct NativeBackgroundState
		{
			private Image Image { get; }

			private Color Color { get; }

			private bool RaycastTarget { get; }

			private RectTransform Rect { get; }

			private Vector2 SizeDelta { get; }

			private UIInputHandler? Input { get; }

			private bool InputEnabled { get; }

			internal NativeBackgroundState(Image image, Color color, bool raycastTarget, RectTransform rect, Vector2 sizeDelta, UIInputHandler? input, bool inputEnabled)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				Image = image;
				Color = color;
				RaycastTarget = raycastTarget;
				Rect = rect;
				SizeDelta = sizeDelta;
				Input = input;
				InputEnabled = inputEnabled;
			}

			internal void SetHovered(bool hovered)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: 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)
				if (!((Object)(object)Image == (Object)null))
				{
					Color color = Color;
					color.a = (hovered ? Mathf.Max(Color.a, 0.62f) : 0f);
					((Graphic)Image).color = color;
				}
			}

			internal void Restore()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Image != (Object)null)
				{
					((Graphic)Image).color = Color;
					((Graphic)Image).raycastTarget = RaycastTarget;
				}
				if ((Object)(object)Rect != (Object)null)
				{
					Rect.sizeDelta = SizeDelta;
				}
				if ((Object)(object)Input != (Object)null)
				{
					((Behaviour)Input).enabled = InputEnabled;
				}
			}
		}

		private readonly struct GroupPalette
		{
			internal Color Text { get; }

			internal Color Background { get; }

			internal GroupPalette(Color text, Color background)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				Text = text;
				Background = background;
			}
		}

		private const string Prefix = "InventoryUX_";

		private const int GridWidth = 15;

		private const int GridHeight = 6;

		private const int CategoryColumns = 3;

		private const int ShelfColumns = 15;

		private const int ShelfRows = 7;

		private const float CraftingColumnPitchScale = 0.95f;

		private const float ShelfColumnPitchScale = 0.93f;

		private const float CategoryRailScale = 0.9f;

		private const float CategoryToItemsGap = 14f;

		private const float SubgroupSpacing = 26.4f;

		private const float SubgroupLineInset = 19.8f;

		private const float TileInset = 3f;

		private const float LabelHeight = 14f;

		private const float ViewControlsHeight = 76f;

		private const float ViewButtonGap = 6f;

		private static readonly FieldInfo PieceIconsField = AccessTools.Field(typeof(Hud), "m_pieceIcons");

		private static readonly FieldInfo PlayerBuildPiecesField = AccessTools.Field(typeof(Player), "m_buildPieces");

		private static readonly MethodInfo UpdateAvailablePiecesMethod = AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null);

		private static readonly MethodInfo HudUpdatePieceListMethod = AccessTools.Method(typeof(Hud), "UpdatePieceList", new Type[4]
		{
			typeof(Player),
			typeof(Vector2Int),
			typeof(PieceCategory),
			typeof(bool)
		}, (Type[])null);

		private static readonly Dictionary<int, NativeBackgroundState> NativeBackgrounds = new Dictionary<int, NativeBackgroundState>();

		private static readonly Dictionary<int, UIInputHandler> HoverInputs = new Dictionary<int, UIInputHandler>();

		private static Type? _iconType;

		private static FieldInfo? _iconGoField;

		private static int[] _visualSlots = Array.Empty<int>();

		private static int _visualWidth = 15;

		private static int _visualHeight = 6;

		private static bool _stateValid;

		private static int _appliedHudId = int.MinValue;

		private static int _appliedSignature;

		private static PieceCategory _appliedCategory = (PieceCategory)8;

		private static int _repairLogicalIndex = -1;

		private static Piece? _repairPiece;

		private static GameObject? _persistentRepair;

		private static GameObject? _hiddenRepairRoot;

		private static int _repairHudId = int.MinValue;

		private static GameObject? _persistentViewControls;

		private static Image? _defaultViewBackground;

		private static Image? _modViewBackground;

		private static int _viewControlsHudId = int.MinValue;

		private static readonly GroupPalette[] FallbackPalettes = new GroupPalette[8]
		{
			Palette(0.88f, 0.69f, 0.39f, 0.5f, 0.34f, 0.14f),
			Palette(0.84f, 0.52f, 0.4f, 0.46f, 0.25f, 0.2f),
			Palette(0.62f, 0.76f, 0.53f, 0.28f, 0.42f, 0.24f),
			Palette(0.59f, 0.72f, 0.82f, 0.25f, 0.37f, 0.48f),
			Palette(0.71f, 0.63f, 0.81f, 0.35f, 0.29f, 0.44f),
			Palette(0.49f, 0.76f, 0.73f, 0.2f, 0.4f, 0.38f),
			Palette(0.82f, 0.68f, 0.48f, 0.45f, 0.34f, 0.21f),
			Palette(0.77f, 0.6f, 0.68f, 0.42f, 0.27f, 0.35f)
		};

		internal static bool UseModView { get; private set; } = true;

		internal static void Apply(Hud hud, IReadOnlyList<Piece> pieces, PieceCategory category)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Invalid comparison between Unknown and I4
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			RemoveStaleRepairForDifferentHud(hud);
			EnsurePersistentViewControls(hud);
			UpdateRepairSelectionState();
			if (!IsEnabled(category))
			{
				Clear(hud, (int)category == 1);
				return;
			}
			IList list = (IList)PieceIconsField.GetValue(hud);
			int num = Math.Min(pieces.Count, list.Count);
			int num2 = ComputeSignature(pieces, list, num);
			if (_stateValid && _appliedHudId == ((Object)hud).GetInstanceID() && _appliedCategory == category && _appliedSignature == num2)
			{
				return;
			}
			Clear(hud);
			try
			{
				if ((int)category == 1 && CanUseReferenceCraftingLayout(pieces, num))
				{
					CraftingLayoutResult craftingLayoutResult = BuildCraftingLayout(pieces, num);
					_visualSlots = craftingLayoutResult.Slots;
					_repairLogicalIndex = craftingLayoutResult.RepairIndex;
					EnsurePersistentRepair(hud, pieces, list, craftingLayoutResult.RepairIndex);
					ApplyGridPermutation(hud, list, craftingLayoutResult, num);
					ConfigureNativePieceCells(list, num, craftingLayoutResult.Slots, craftingLayoutResult.RepairIndex);
					AddReferenceCraftingRows(hud, pieces, list, num, craftingLayoutResult);
					_visualWidth = 15;
					_visualHeight = 6;
					RememberState(hud, category, num2);
					return;
				}
				if ((int)category != 1 && CanUseShelfLayout(pieces, num))
				{
					ShelfLayoutResult shelfLayoutResult = BuildShelfLayout(hud, pieces, num, category);
					_visualSlots = shelfLayoutResult.Slots;
					_visualWidth = 15;
					_visualHeight = shelfLayoutResult.VisibleRows;
					_repairLogicalIndex = shelfLayoutResult.RepairIndex;
					if (shelfLayoutResult.RepairIndex >= 0)
					{
						EnsurePersistentRepair(hud, pieces, list, shelfLayoutResult.RepairIndex);
					}
					ConfigureNativePieceCells(list, num, shelfLayoutResult.Slots, shelfLayoutResult.RepairIndex);
					ApplyShelfPositions(hud, list, shelfLayoutResult, num);
					AddShelfRows(hud, pieces, list, num, shelfLayoutResult);
					RememberState(hud, category, num2);
					return;
				}
				string a = null;
				for (int i = 0; i < num; i++)
				{
					string text = HammerOrganizer.GetLabel(pieces[i]) ?? "Other";
					GroupPalette palette = GetPalette(category, text);
					bool flag = !string.Equals(a, text, StringComparison.Ordinal);
					GameObject iconGameObject = GetIconGameObject(list[i]);
					AddTileTint(iconGameObject, palette, flag);
					if (flag && !IsStandaloneAction(category, text))
					{
						AddLabel(hud, iconGameObject, CompactLabel(text), palette);
					}
					a = text;
				}
				RememberState(hud, category, num2);
			}
			catch
			{
				RemoveDecorations(hud, list);
				ResetState();
				throw;
			}
		}

		private static int ComputeSignature(IReadOnlyList<Piece> pieces, IList icons, int count)
		{
			int num = 17;
			num = num * 31 + count;
			num = num * 31 + icons.Count;
			num = num * 31 + (ModConfig.ShowSeparators.Value ? 1 : 0);
			num = num * 31 + (ModConfig.ShowHammerPieceNames.Value ? 1 : 0);
			if (icons.Count > 0)
			{
				num = num * 31 + ((Object)GetIconGameObject(icons[0])).GetInstanceID();
			}
			for (int i = 0; i < count; i++)
			{
				Piece val = pieces[i];
				num = num * 31 + ((Object)val).GetInstanceID();
				string text = HammerOrganizer.GetLabel(val) ?? string.Empty;
				num = num * 31 + text.GetHashCode();
			}
			return num;
		}

		private static void RememberState(Hud hud, PieceCategory category, int signature)
		{
			//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)
			_appliedHudId = ((Object)hud).GetInstanceID();
			_appliedCategory = category;
			_appliedSignature = signature;
			_stateValid = true;
		}

		private static void ResetState()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			_stateValid = false;
			_appliedHudId = int.MinValue;
			_appliedSignature = 0;
			_appliedCategory = (PieceCategory)8;
			_visualSlots = Array.Empty<int>();
			_visualWidth = 15;
			_visualHeight = 6;
			_repairLogicalIndex = -1;
		}

		internal static bool TryNavigate(PieceTable table, int horizontal, int vertical)
		{
			//IL_000b: 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_001a: 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)
			if (_visualSlots.Length < 2 || table.GetSelectedCategory() != _appliedCategory)
			{
				return false;
			}
			Vector2Int selectedIndex = table.GetSelectedIndex();
			int num = ((Vector2Int)(ref selectedIndex)).y * 15 + ((Vector2Int)(ref selectedIndex)).x;
			if (num < 0 || num >= _visualSlots.Length)
			{
				return false;
			}
			int num2 = _visualSlots[num];
			if (num2 < 0)
			{
				int num3 = ((horizontal < 0 || vertical < 0) ? FindLastVisualPiece() : FindFirstVisualPiece());
				if (num3 >= 0)
				{
					SelectLogicalIndex(table, num3);
				}
				return true;
			}
			int num4 = num2 % _visualWidth;
			int num5 = num2 / _visualWidth;
			int num6 = -1;
			if (horizontal != 0)
			{
				int num7 = int.MaxValue;
				for (int i = 0; i < _visualSlots.Length; i++)
				{
					int num8 = _visualSlots[i];
					if (num8 < 0 || num8 / _visualWidth != num5)
					{
						continue;
					}
					int num9 = num8 % _visualWidth - num4;
					if ((horizontal >= 0 || num9 < 0) && (horizontal <= 0 || num9 > 0))
					{
						int num10 = Math.Abs(num9);
						if (num10 < num7)
						{
							num7 = num10;
							num6 = i;
						}
					}
				}
				if (num6 < 0 && horizontal < 0 && _repairLogicalIndex >= 0)
				{
					num6 = _repairLogicalIndex;
				}
				else if (num6 < 0)
				{
					int num11 = ((horizontal < 0) ? int.MinValue : int.MaxValue);
					for (int j = 0; j < _visualSlots.Length; j++)
					{
						int num12 = _visualSlots[j];
						if (num12 >= 0 && num12 / _visualWidth == num5)
						{
							int num13 = num12 % _visualWidth;
							if ((horizontal < 0 && num13 > num11) || (horizontal > 0 && num13 < num11))
							{
								num11 = num13;
								num6 = j;
							}
						}
					}
				}
			}
			else if (vertical != 0)
			{
				for (int k = 1; k < _visualHeight; k++)
				{
					if (num6 >= 0)
					{
						break;
					}
					int num14 = (num5 + vertical * k + _visualHeight * 2) % _visualHeight;
					int num15 = int.MaxValue;
					for (int l = 0; l < _visualSlots.Length; l++)
					{
						int num16 = _visualSlots[l];
						if (num16 >= 0 && num16 / _visualWidth == num14)
						{
							int num17 = Math.Abs(num16 % _visualWidth - num4);
							if (num17 < num15)
							{
								num15 = num17;
								num6 = l;
							}
						}
					}
				}
			}
			if (num6 >= 0 && num6 != num)
			{
				SelectLogicalIndex(table, num6);
			}
			return true;
		}

		private static void SelectLogicalIndex(PieceTable table, int logicalIndex)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			table.SetSelected(new Vector2Int(logicalIndex % 15, logicalIndex / 15));
		}

		private static int FindFirstVisualPiece()
		{
			int result = -1;
			int num = int.MaxValue;
			for (int i = 0; i < _visualSlots.Length; i++)
			{
				int num2 = _visualSlots[i];
				if (num2 >= 0 && num2 < num)
				{
					num = num2;
					result = i;
				}
			}
			return result;
		}

		private static int FindLastVisualPiece()
		{
			int result = -1;
			int num = int.MinValue;
			for (int i = 0; i < _visualSlots.Length; i++)
			{
				int num2 = _visualSlots[i];
				if (num2 > num)
				{
					num = num2;
					result = i;
				}
			}
			return result;
		}

		private static CraftingLayoutResult BuildCraftingLayout(IReadOnlyList<Piece> pieces, int count)
		{
			List<CraftingEntry>[] array = new List<CraftingEntry>[6];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new List<CraftingEntry>();
			}
			int repairIndex = -1;
			for (int j = 0; j < count; j++)
			{
				Piece val = pieces[j];
				if (CraftingLayoutMetadata.IsRepair(val))
				{
					repairIndex = j;
					continue;
				}
				CraftingPieceLayout metadata = CraftingLayoutMetadata.Resolve(val);
				array[(int)metadata.Section].Add(new CraftingEntry(j, metadata, Localize(val.m_name)));
			}
			for (int k = 0; k < array.Length; k++)
			{
				array[k].Sort(delegate(CraftingEntry left, CraftingEntry right)
				{
					int num11 = left.Metadata.SortOrder.CompareTo(right.Metadata.SortOrder);
					if (num11 != 0)
					{
						return num11;
					}
					num11 = string.Compare(left.Name, right.Name, StringComparison.CurrentCultureIgnoreCase);
					return (num11 == 0) ? left.PieceIndex.CompareTo(right.PieceIndex) : num11;
				});
			}
			int[] array2 = new int[count];
			for (int num = 0; num < array2.Length; num++)
			{
				array2[num] = -1;
			}
			float[] array3 = new float[count];
			bool[] array4 = new bool[90];
			CraftingSection?[] array5 = new CraftingSection?[6];
			int[] array6 = new int[6];
			for (int num2 = 0; num2 < array6.Length; num2++)
			{
				array6[num2] = -1;
			}
			List<SubgroupDivider> list = new List<SubgroupDivider>();
			List<int> list2 = new List<int>();
			int num3 = 0;
			for (int num4 = 0; num4 < array.Length; num4++)
			{
				if (num3 >= 6)
				{
					break;
				}
				List<CraftingEntry> list3 = array[num4];
				if (list3.Count == 0)
				{
					continue;
				}
				array5[num3] = (CraftingSection)num4;
				array6[num3] = FindCategoryRepresentative(list3, (CraftingSection)num4);
				int num5 = 3;
				int subgroup = list3[0].Metadata.Subgroup;
				int num6 = 0;
				for (int num7 = 0; num7 < list3.Count; num7++)
				{
					CraftingEntry craftingEntry = list3[num7];
					if (num7 > 0 && craftingEntry.Metadata.Subgroup != subgroup)
					{
						num6++;
						list.Add(new SubgroupDivider(num3, num5, num6));
					}
					if (num5 >= 15)
					{
						list2.Add(craftingEntry.PieceIndex);
					}
					else
					{
						int num8 = num3 * 15 + num5;
						array2[craftingEntry.PieceIndex] = num8;
						array3[craftingEntry.PieceIndex] = (float)num6 * 26.4f;
						array4[num8] = true;
						num5++;
					}
					subgroup = craftingEntry.Metadata.Subgroup;
				}
				num3++;
			}
			for (int num9 = 0; num9 < list2.Count; num9++)
			{
				int num10 = FirstFreePieceSlot(array4);
				if (num10 < 0)
				{
					break;
				}
				array2[list2[num9]] = num10;
				array4[num10] = true;
			}
			return new CraftingLayoutResult(array2, array3, repairIndex, array5, array6, list, num3);
		}

		private static bool CanUseShelfLayout(IReadOnlyList<Piece> pieces, int count)
		{
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				if (!CraftingLayoutMetadata.IsRepair(pieces[i]))
				{
					num++;
				}
			}
			if (num > 0)
			{
				return num <= 105;
			}
			return false;
		}

		private static ShelfLayoutResult BuildShelfLayout(Hud hud, IReadOnlyList<Piece> pieces, int count, PieceCategory category)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Invalid comparison between Unknown and I4
			//IL_02e1: 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_0257: 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)
			List<int> list = new List<int>(count);
			int repairIndex = -1;
			for (int i = 0; i < count; i++)
			{
				if (CraftingLayoutMetadata.IsRepair(pieces[i]))
				{
					repairIndex = i;
				}
				else
				{
					list.Add(i);
				}
			}
			string[] array = new string[list.Count];
			int[] array2 = new int[list.Count];
			int num = 0;
			int num2 = 0;
			string a = null;
			for (int j = 0; j < list.Count; j++)
			{
				Piece piece = pieces[list[j]];
				PieceGroup pieceGroup = HammerOrganizer.Classify(piece, category);
				string text = (array[j] = HammerOrganizer.GetLabel(piece) ?? pieceGroup.Label);
				array2[j] = pieceGroup.Suborder;
				if (j == 0 || string.Equals(a, text, StringComparison.Ordinal))
				{
					num2++;
				}
				else
				{
					num += Mathf.CeilToInt((float)num2 / 15f);
					num2 = 1;
				}
				a = text;
			}
			if (num2 > 0)
			{
				num += Mathf.CeilToInt((float)num2 / 15f);
			}
			int num3 = Mathf.Clamp(Mathf.Max(Mathf.CeilToInt((float)list.Count / 15f), num), 1, 7);
			List<int> list2 = (((int)category == 2) ? BuildMaterialRowSizes(array) : null);
			if (list2 != null)
			{
				num3 = list2.Count;
			}
			float pieceIconSpacing = hud.m_pieceIconSpacing;
			float rowPitch = ShelfRowPitch(hud, num3);
			float num4 = CategoryRailWidth(pieceIconSpacing) + 14f;
			float num5 = 14f * pieceIconSpacing;
			int[] array3 = new int[count];
			for (int k = 0; k < array3.Length; k++)
			{
				array3[k] = -1;
			}
			float[] array4 = new float[count];
			string[] array5 = new string[num3];
			int[] array6 = new int[num3];
			List<ShelfDivider> list3 = new List<ShelfDivider>();
			int num6 = 0;
			for (int l = 0; l < num3; l++)
			{
				int num7 = list2?[l] ?? ShelfRowPlanner.ChooseGroupRowSize(array, num6, 15, num3 - l);
				array5[l] = array[num6];
				array6[l] = list[num6];
				int num8 = 0;
				for (int m = 1; m < num7; m++)
				{
					if (IsShelfBreak(array, array2, num6 + m, category))
					{
						num8++;
					}
				}
				float num9 = pieceIconSpacing * 0.93f;
				if (num7 > 1)
				{
					float num10 = (num5 - num4 - (float)num8 * 26.4f) / (float)(num7 - 1);
					num9 = Mathf.Min(num9, num10);
				}
				int num11 = 0;
				for (int n = 0; n < num7; n++)
				{
					int index = num6 + n;
					int num12 = list[index];
					if (n > 0 && IsShelfBreak(array, array2, index, category))
					{
						num11++;
					}
					float num13 = num4 + (float)n * num9 + (float)num11 * 26.4f;
					if (n > 0 && IsShelfBreak(array, array2, index, category))
					{
						list3.Add(new ShelfDivider(l, num13 - 19.8f));
					}
					array3[num12] = l * 15 + n;
					array4[num12] = num13;
				}
				num6 += num7;
			}
			List<ShelfCard> cards = BuildShelfCards(pieces, list, array, array5, array6, category);
			return new ShelfLayoutResult(array3, array4, cards, list3, num3, rowPitch, repairIndex);
		}

		private static bool IsShelfBreak(string[] labels, int[] subgroups, int index, PieceCategory category)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			if (index <= 0 || index >= labels.Length)
			{
				return false;
			}
			if (!string.Equals(labels[index - 1], labels[index], StringComparison.Ordinal))
			{
				return true;
			}
			if ((int)category == 2 && string.Equals(Normalize(labels[index]), "corewood", StringComparison.Ordinal))
			{
				return false;
			}
			if ((int)category == 2)
			{
				return subgroups[index - 1] != subgroups[index];
			}
			return false;
		}

		private static List<int> BuildMaterialRowSizes(string[] labels)
		{
			List<int> list = new List<int>();
			int num = 0;
			while (num < labels.Length)
			{
				int i;
				for (i = num + 1; i < labels.Length && string.Equals(labels[num], labels[i], StringComparison.Ordinal); i++)
				{
				}
				int num2 = i - num;
				int num3 = Mathf.CeilToInt((float)num2 / 15f);
				for (int j = 0; j < num3; j++)
				{
					int num4 = Mathf.CeilToInt((float)num2 / (float)(num3 - j));
					list.Add(num4);
					num2 -= num4;
				}
				num = i;
			}
			return list;
		}

		private static List<ShelfCard> BuildShelfCards(IReadOnlyList<Piece> pieces, List<int> sourceIndices, string[] labels, string[] rowLabels, int[] representatives, PieceCategory category)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Invalid comparison between Unknown and I4
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			List<ShelfCard> list = new List<ShelfCard>();
			for (int i = 0; i < rowLabels.Length; i++)
			{
				string text = rowLabels[i];
				if (list.Count > 0 && string.Equals(list[list.Count - 1].Label, text, StringComparison.Ordinal))
				{
					ShelfCard shelfCard = list[list.Count - 1];
					list[list.Count - 1] = new ShelfCard(shelfCard.StartRow, shelfCard.RowSpan + 1, shelfCard.Label, shelfCard.Representative);
					continue;
				}
				int num = representatives[i];
				if ((int)category == 2)
				{
					num = FindBuildingBeamRepresentative(pieces, sourceIndices, labels, text, num);
				}
				else if ((int)category == 0 && string.Equals(Normalize(text), "utility", StringComparison.Ordinal))
				{
					num = FindCartographyRepresentative(pieces, sourceIndices, labels, text, num);
				}
				list.Add(new ShelfCard(i, 1, text, num));
			}
			return list;
		}

		private static int FindBuildingBeamRepresentative(IReadOnlyList<Piece> pieces, List<int> sourceIndices, string[] labels, string label, int fallback)
		{
			string text = Normalize(label);
			for (int i = 0; i < sourceIndices.Count; i++)
			{
				if (string.Equals(labels[i], label, StringComparison.Ordinal))
				{
					Piece val = pieces[sourceIndices[i]];
					string text2 = Normalize(((Object)((Component)val).gameObject).name + " " + val.m_name);
					if (text2.Contains("beam") && (!(text == "darkwood") || text2.Contains("darkwood")) && (!(text == "ashwood") || text2.Contains("grausten") || text2.Contains("ashwood") || text2.Contains("blackwood")) && (!(text == "corewood") || text2.Contains("corewood") || text2.Contains("log")) && (!(text == "wood") || (!text2.Contains("darkwood") && !text2.Contains("grausten") && !text2.Contains("ashwood") && !text2.Contains("corewood") && !text2.Contains("log"))))
					{
						return sourceIndices[i];
					}
				}
			}
			return fallback;
		}

		private static int FindCartographyRepresentative(IReadOnlyList<Piece> pieces, List<int> sourceIndices, string[] labels, string label, int fallback)
		{
			for (int i = 0; i < sourceIndices.Count; i++)
			{
				if (string.Equals(labels[i], label, StringComparison.Ordinal))
				{
					Piece val = pieces[sourceIndices[i]];
					string text = Normalize(((Object)((Component)val).gameObject).name + " " + val.m_name);
					if (text.Contains("cartography") || text.Contains("maptable"))
					{
						return sourceIndices[i];
					}
				}
			}
			return fallback;
		}

		private static float CategoryRailWidth(float spacing)
		{
			return (3f * spacing - 28f) * 0.9f;
		}

		private static float CraftingContentShift(float spacing)
		{
			return CategoryRailWidth(spacing) + 14f - 3f * spacing * 0.95f;
		}

		private static float ShelfRowPitch(Hud hud, int visibleRows)
		{
			if (visibleRows <= 6)
			{
				return hud.m_pieceIconSpacing * 1.1666666f;
			}
			return hud.m_pieceIconSpacing * 7f / (float)visibleRows;
		}

		private static int FindCategoryRepresentative(List<CraftingEntry> entries, CraftingSection section)
		{
			int num = 100;
			for (int i = 0; i < entries.Count; i++)
			{
				if (entries[i].Metadata.SortOrder == num)
				{
					return entries[i].PieceIndex;
				}
			}
			return entries[0].PieceIndex;
		}

		private static bool CanUseReferenceCraftingLayout(IReadOnlyList<Piece> pieces, int count)
		{
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				if (!CraftingLayoutMetadata.IsRepair(pieces[i]))
				{
					num++;
				}
			}
			if (num > 0)
			{
				return num <= 72;
			}
			return false;
		}

		private static int FirstFreePieceSlot(bool[] used)
		{
			for (int i = 0; i < 6; i++)
			{
				for (int j = 3; j < 15; j++)
				{
					int num = i * 15 + j;
					if (!used[num])
					{
						return num;
					}
				}
			}
			return -1;
		}

		private static void AddReferenceCraftingRows(Hud hud, IReadOnlyList<Piece> pieces, IList icons, int count, CraftingLayoutResult layout)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			RectTransform templateRect = (RectTransform)GetIconGameObject(icons[0]).transform;
			for (int i = 0; i < count; i++)
			{
				if (i != layout.RepairIndex && layout.Slots[i] >= 0 && ModConfig.ShowHammerPieceNames.Value)
				{
					AddReferenceTile(hud, GetIconGameObject(icons[i]), pieces[i]);
				}
			}
			for (int j = 0; j < layout.VisibleRows; j++)
			{
				if (j < layout.VisibleRows - 1 && ModConfig.ShowSeparators.Value)
				{
					AddRowSeparator(hud, templateRect, j);
				}
				CraftingSection? craftingSection = layout.RowSections[j];
				int num = layout.Representatives[j];
				if (craftingSection.HasValue && num >= 0)
				{
					AddCategoryCard(hud, templateRect, j, craftingSection.Value, pieces[num]);
				}
			}
			if (ModConfig.ShowSeparators.Value)
			{
				for (int k = 0; k < layout.SubgroupBreaks.Count; k++)
				{
					AddSubgroupSeparator(hud, templateRect, layout.SubgroupBreaks[k]);
				}
			}
		}

		private static void AddShelfRows(Hud hud, IReadOnlyList<Piece> pieces, IList icons, int count, ShelfLayoutResult layout)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			RectTransform templateRect = (RectTransform)GetIconGameObject(icons[0]).transform;
			for (int i = 0; i < count; i++)
			{
				if (layout.Slots[i] >= 0 && ModConfig.ShowHammerPieceNames.Value)
				{
					AddReferenceTile(hud, GetIconGameObject(icons[i]), pieces[i]);
				}
			}
			for (int j = 0; j < layout.VisibleRows; j++)
			{
				if (j >= layout.VisibleRows - 1 || !ModConfig.ShowSeparators.Value)
				{
					continue;
				}
				bool flag = false;
				for (int k = 0; k < layout.Cards.Count; k++)
				{
					if (layout.Cards[k].StartRow == j + 1)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					AddRowSeparator(hud, templateRect, j, layout.RowPitch, 0f);
				}
			}
			for (int l = 0; l < layout.Cards.Count; l++)
			{
				ShelfCard shelfCard = layout.Cards[l];
				AddCategoryCard(hud, templateRect, shelfCard.StartRow, layout.RowPitch, shelfCard.Label, pieces[shelfCard.Representative], shelfCard.RowSpan);
			}
			if (ModConfig.ShowSeparators.Value)
			{
				for (int m = 0; m < layout.Dividers.Count; m++)
				{
					AddShelfDivider(hud, templateRect, layout.Dividers[m], layout.RowPitch);
				}
			}
		}

		private static void AddReferenceTile(Hud hud, GameObject iconRoot, Piece piece)
		{
			//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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("InventoryUX_CraftingPieceName", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val.transform.SetParent(iconRoot.transform, false);
			val.transform.SetAsLastSibling();
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(1f, 0f);
			val2.pivot = new Vector2(0.5f, 0f);
			val2.anchoredPosition = new Vector2(0f, 3f);
			val2.sizeDelta = new Vector2(-8f, 27f);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = Localize(piece.m_name);
			((TMP_Text)component).font = (((Object)(object)hud.m_pieceDescription != (Object)null) ? hud.m_pieceDescription.font : null);
			((TMP_Text)component).fontSize = 10.6f;
			((TMP_Text)component).fontSizeMin = 8.6f;
			((TMP_Text)component).fontSizeMax = 10.6f;
			((TMP_Text)component).enableAutoSizing = true;
			((TMP_Text)component).fontStyle = (FontStyles)1;
			((Graphic)component).color = new Color(0.96f, 0.88f, 0.72f, 1f);
			((TMP_Text)component).alignment = (TextAlignmentOptions)1026;
			((TMP_Text)component).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)component).overflowMode = (TextOverflowModes)1;
			((TMP_Text)component).maxVisibleLines = 2;
			((TMP_Text)component).outlineWidth = 0.22f;
			((TMP_Text)component).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);
			((Graphic)component).raycastTarget = false;
		}

		private static void AddCategoryCard(Hud hud, RectTransform templateRect, int row, CraftingSection section, Piece representative)
		{
			AddCategoryCard(hud, templateRect, row, HammerGridDimensions.CraftingRowPitch(hud), CraftingLayoutMetadata.Label(section), representative);
		}

		private static void AddCategoryCard(Hud hud, RectTransform templateRect, int row, float rowPitch, string text, Piece representative, int rowSpan = 1)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0068: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			float pieceIconSpacing = hud.m_pieceIconSpacing;
			GameObject val = new GameObject("InventoryUX_CraftingCategory_" + row, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)hud.m_pieceListRoot, false);
			val.transform.SetAsLastSibling();
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = templateRect.anchorMin;
			val2.anchorMax = templateRect.anchorMax;
			val2.pivot = templateRect.pivot;
			val2.anchoredPosition = new Vector2(0f, (float)(-row) * rowPitch);
			val2.sizeDelta = new Vector2(CategoryRailWidth(pieceIconSpacing), rowPitch * (float)rowSpan - 7f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.075f, 0.048f, 0.027f, 0.91f);
			((Graphic)component).raycastTarget = false;
			AddOutline((Transform)(object)val2, "InventoryUX_CraftingCategoryBorder", 0f, new Color(0.66f, 0.49f, 0.25f, 0.54f));
			GameObject val3 = new GameObject("InventoryUX_CraftingCategoryIcon", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val3.transform.SetParent((Transform)(object)val2, false);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = new Vector2(0f, 0.5f);
			val4.anchorMax = new Vector2(0f, 0.5f);
			val4.pivot = new Vector2(0f, 0.5f);
			val4.anchoredPosition = new Vector2(8f, 0f);
			val4.sizeDelta = new Vector2(56f, 56f);
			Image component2 = val3.GetComponent<Image>();
			component2.sprite = representative.m_icon;
			component2.preserveAspect = true;
			((Graphic)component2).color = Color.white;
			((Graphic)component2).raycastTarget = false;
			GameObject val5 = new GameObject("InventoryUX_CraftingCategoryLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val5.transform.SetParent((Transform)(object)val2, false);
			RectTransform val6 = (RectTransform)val5.transform;
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = new Vector2(66f, 6f);
			val6.offsetMax = new Vector2(-7f, -6f);
			TextMeshProUGUI component3 = val5.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component3).text = text.ToUpperInvariant();
			((TMP_Text)component3).font = (((Object)(object)hud.m_pieceDescription != (Object)null) ? hud.m_pieceDescription.font : null);
			((TMP_Text)component3).fontSize = 12.8f;
			((TMP_Text)component3).fontSizeMin = 9.5f;
			((TMP_Text)component3).fontSizeMax = 12.8f;
			((TMP_Text)component3).enableAutoSizing = true;
			((TMP_Text)component3).fontStyle = (FontStyles)1;
			((Graphic)component3).color = new Color(0.84f, 0.69f, 0.43f, 1f);
			((TMP_Text)component3).alignment = (TextAlignmentOptions)4097;
			((TMP_Text)component3).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)component3).overflowMode = (TextOverflowModes)1;
			((TMP_Text)component3).outlineWidth = 0.12f;
			((TMP_Text)component3).outlineColor = new Color32((byte)18, (byte)12, (byte)8, (byte)245);
			((Graphic)component3).raycastTarget = false;
		}

		private static void AddRowSeparator(Hud hud, RectTransform templateRect, int row)
		{
			AddRowSeparator(hud, templateRect, row, HammerGridDimensions.CraftingRowPitch(hud));
		}

		private static void AddRowSeparator(Hud hud, RectTransform templateRect, int row, float rowPitch)
		{
			AddRowSeparator(hud, templateRect, row, rowPitch, 0f);
		}

		private static void AddRowSeparator(Hud hud, RectTransform templateRect, int row, float rowPitch, float startX)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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)
			float pieceIconSpacing = hud.m_pieceIconSpacing;
			GameObject val = new GameObject("InventoryUX_CraftingRowSeparator_" + row, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)hud.m_pieceListRoot, false);
			val.transform.SetAsLastSibling();
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = templateRect.anchorMin;
			val2.anchorMax = templateRect.anchorMax;
			val2.pivot = new Vector2(0f, 0.5f);
			val2.anchoredPosition = new Vector2(startX, (0f - ((float)row + 1f)) * rowPitch + 3.5f);
			val2.sizeDelta = new Vector2(15f * pieceIconSpacing - 9f - startX, 1f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.57f, 0.4f, 0.19f, 0.34f);
			((Graphic)component).raycastTarget = false;
		}

		private static void AddSubgroupSeparator(Hud hud, RectTransform templateRect, SubgroupDivider divider)
		{
			//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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			float pieceIconSpacing = hud.m_pieceIconSpacing;
			float num = pieceIconSpacing * 0.95f;
			float num2 = HammerGridDimensions.CraftingRowPitch(hud);
			float num3 = (float)divider.Column * num + CraftingContentShift(pieceIconSpacing) + (float)divider.GapCount * 26.4f;
			GameObject val = new GameObject("InventoryUX_CraftingSubgroupSeparator_" + divider.Row + "_" + divider.Column, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)hud.m_pieceListRoot, false);
			val.transform.SetAsLastSibling();
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = templateRect.anchorMin;
			val2.anchorMax = templateRect.anchorMax;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = new Vector2(num3 - 19.8f, (float)(-divider.Row) * num2 - num2 * 0.5f);
			val2.sizeDelta = new Vector2(1f, num2 - 20f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.62f, 0.47f, 0.25f, 0.42f);
			((Graphic)component).raycastTarget = false;
		}

		private static void AddShelfDivider(Hud hud, RectTransform templateRect, ShelfDivider divider, float rowPitch)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0075: 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_007c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("InventoryUX_CraftingShelfDivider_" + divider.Row + "_" + divider.X, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)hud.m_pieceListRoot, false);
			val.transform.SetAsLastSibling();
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = templateRect.anchorMin;
			val2.anchorMax = templateRect.anchorMax;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = new Vector2(divider.X, (float)(-divider.Row) * rowPitch - rowPitch * 0.5f);
			val2.sizeDelta = new Vector2(1f, rowPitch - 20f);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.62f, 0.47f, 0.25f, 0.42f);
			((Graphic)component).raycastTarget = false;
		}

		private static void ConfigureNativePieceCells(IList icons, int occupiedCount, int[] slots, int repairIndex)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			for (int i = 0; i < icons.Count; i++)
			{
				GameObject iconGameObject = GetIconGameObject(icons[i]);
				Image component = iconGameObject.GetComponent<Image>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				UIInputHandler component2 = iconGameObject.GetComponent<UIInputHandler>();
				int instanceID = ((Object)component).GetInstanceID();
				if (!NativeBackgrounds.ContainsKey(instanceID))
				{
					NativeBackgrounds[instanceID] = new NativeBackgroundState(component, ((Graphic)component).color, ((Graphic)component).raycastTarget, (RectTransform)iconGameObject.transform, ((RectTransform)iconGameObject.transform).sizeDelta, component2, (Object)(object)component2 != (Object)null && ((Behaviour)component2).enabled);
				}
				bool flag = i < occupiedCount && i < slots.Length && slots[i] >= 0 && i != repairIndex;
				Color color = ((Graphic)component).color;
				color.a = 0f;
				((Graphic)component).color = color;
				((Graphic)component).raycastTarget = flag;
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = flag;
					if (flag && !HoverInputs.ContainsKey(((Object)component2).GetInstanceID()))
					{
						component2.m_onPointerEnter = (Action<UIInputHandler>)Delegate.Combine(component2.m_onPointerEnter, new Action<UIInputHandler>(OnPieceHoverEnter));
						component2.m_onPointerExit = (Action<UIInputHandler>)Delegate.Combine(component2.m_onPointerExit, new Action<UIInputHandler>(OnPieceHoverExit));
						HoverInputs[((Object)component2).GetInstanceID()] = component2;
					}
				}
			}
		}

		private static void OnPieceHoverEnter(UIInputHandler input)
		{
			Image val = (((Object)(object)input != (Object)null) ? ((Component)input).GetComponent<Image>() : null);
			if (!((Object)(object)val == (Object)null) && NativeBackgrounds.TryGetValue(((Object)val).GetInstanceID(), out var value))
			{
				value.SetHovered(hovered: true);
			}
		}

		private static void OnPieceHoverExit(UIInputHandler input)
		{
			Image val = (((Object)(object)input != (Object)null) ? ((Component)input).GetComponent<Image>() : null);
			if (!((Object)(object)val == (Object)null) && NativeBackgrounds.TryGetValue(((Object)val).GetInstanceID(), out var value))
			{
				value.SetHovered(hovered: false);
			}
		}

		private static void RestoreNativeCraftingCells()
		{
			foreach (KeyValuePair<int, UIInputHandler> hoverInput in HoverInputs)
			{
				UIInputHandler value = hoverInput.Value;
				if (!((Object)(object)value == (Object)null))
				{
					value.m_onPointerEnter = (Action<UIInputHandler>)Delegate.Remove(value.m_onPointerEnter, new Action<UIInputHandler>(OnPieceHoverEnter));
					value.m_onPointerExit = (Action<UIInputHandler>)Delegate.Remove(value.m_onPointerExit, new Action<UIInputHandler>(OnPieceHoverExit));
				}
			}
			HoverInputs.Clear();
			foreach (KeyValuePair<int, NativeBackgroundState> nativeBackground in NativeBackgrounds)
			{
				nativeBackground.Value.Restore();
			}
			NativeBackgrounds.Clear();
		}

		private static void EnsurePersistentRepair(Hud hud, IReadOnlyList<Piece> pieces, IList icons, int repairIndex)
		{
			if (repairIndex < 0 || repairIndex >= pieces.Count || repairIndex >= icons.Count)
			{
				DestroyPersistentRepair();
				return;
			}
			Piece val = pieces[repairIndex];
			if ((Object)(object)_persistentRepair == (Object)null || _repairHudId != ((Object)hud).GetInstanceID() || (Object)(object)_repairPiece == (Object)null || ((Object)_repairPiece).GetInstanceID() != ((Object)val).GetInstanceID())
			{
				DestroyPersistentRepair();
				_persistentRepair = Object.Instantiate<GameObject>(GetIconGameObject(icons[repairIndex]), hud.m_pieceSelectionWindow.transform);
				((Object)_persistentRepair).name = "InventoryUX_PersistentRepair";
				_repairHudId = ((Object)hud).GetInstanceID();
				_repairPiece = val;
				ConfigurePersistentRepair(hud, _persistentRepair, val);
			}
			_hiddenRepairRoot = GetIconGameObject(icons[repairIndex]);
			_hiddenRepairRoot.SetActive(false);
			_persistentRepair.SetActive(true);
			UpdateRepairSelectionState();
		}

		private static void EnsurePersistentViewControls(Hud hud)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			if ((Object)(object)_persistentViewControls == (Object)null || _viewControlsHudId != ((Object)hud).GetInstanceID())
			{
				DestroyPersistentViewControls();
				GameObject val = new GameObject("InventoryUX_PersistentViewControls", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(hud.m_pieceSelectionWindow.transform, false);
				val.transform.SetAsLastSibling();
				RectTransform val2 = (RectTransform)val.transform;
				val2.anchorMin = new Vector2(0f, 1f);
				val2.anchorMax = new Vector2(0f, 1f);
				val2.pivot = new Vector2(0f, 1f);
				val2.anchoredPosition = new Vector2(18f, 0f - (hud.m_pieceIconSpacing + 49f));
				val2.sizeDelta = new Vector2(hud.m_pieceIconSpacing + 8f, 76f);
				_defaultViewBackground = CreateViewButton(hud, val2, "DEFAULT VIEW", 0, useModView: false);
				_modViewBackground = CreateViewButton(hud, val2, "MOD VIEW", 1, useModView: true);
				_persistentViewControls = val;
				_viewControlsHudId = ((Object)hud).GetInstanceID();
			}
			_persistentViewControls.SetActive(true);
			_persistentViewControls.transform.SetAsLastSibling();
			UpdateViewButtonState();
		}

		private static Image CreateViewButton(Hud hud, RectTransform parent, string caption, int index, bool useModView)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_016e: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: 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_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			float num = 35f;
			GameObject val = new GameObject("InventoryUX_" + (useModView ? "ModView" : "DefaultView"), new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(Button)
			});
			val.transform.SetParent((Transform)(object)parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.anchoredPosition = new Vector2(0f, (float)(-index) * (num + 6f));
			val2.sizeDelta = new Vector2(0f, num);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.09f, 0.055f, 0.03f, 0.94f);
			((Graphic)component).raycastTarget = true;
			AddOutline((Transform)(object)val2, "InventoryUX_ViewButtonBorder", 1f, new Color(0.68f, 0.5f, 0.25f, 0.68f));
			Button component2 = val.GetComponent<Button>();
			((Selectable)component2).targetGraphic = (Graphic)(object)component;
			((Selectable)component2).transition = (Transition)0;
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				SetHammerView(hud, useModView);
			});
			GameObject val3 = new GameObject("InventoryUX_ViewButtonLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val3.transform.SetParent((Transform)(object)val2, false);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(4f, 2f);
			val4.offsetMax = new Vector2(-4f, -2f);
			TextMeshProUGUI component3 = val3.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component3).text = caption;
			((TMP_Text)component3).font = (((Object)(object)hud.m_pieceDescription != (Object)null) ? hud.m_pieceDescription.font : null);
			((TMP_Text)component3).fontSize = 9.5f;
			((TMP_Text)component3).fontSizeMin = 7f;
			((TMP_Text)component3).fontSizeMax = 9.5f;
			((TMP_Text)component3).enableAutoSizing = true;
			((TMP_Text)component3).fontStyle = (FontStyles)1;
			((Graphic)component3).color = new Color(0.94f, 0.83f, 0.64f, 1f);
			((TMP_Text)component3).alignment = (TextAlignmentOptions)514;
			((TMP_Text)component3).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)component3).overflowMode = (TextOverflowModes)1;
			((TMP_Text)component3).outlineWidth = 0.16f;
			((TMP_Text)component3).outlineColor = Color32.op_Implicit(Color.black);
			((Graphic)component3).raycastTarget = false;
			return component;
		}

		private static void SetHammerView(Hud hud, bool useModView)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (UseModView == useModView)
			{
				return;
			}
			UseModView = useModView;
			Clear(hud, removePersistentRepair: true);
			UpdateViewButtonState();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			try
			{
				UpdateAvailablePiecesMethod.Invoke(localPlayer, null);
				object? value = PlayerBuildPiecesField.GetValue(localPlayer);
				PieceTable val = (PieceTable)((value is PieceTable) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					HudUpdatePieceListMethod.Invoke(hud, new object[4]
					{
						localPlayer,
						val.GetSelectedIndex(),
						val.GetSelectedCategory(),
						true
					});
				}
			}
			catch (Exception arg)
			{
				Plugin.LogInstance.LogWarning((object)$"Hammer view switch failed: {arg}");
			}
		}

		private static void UpdateViewButtonState()
		{
			//IL_0052: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.25f, 0.56f, 0.78f, 0.96f);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.09f, 0.055f, 0.03f, 0.94f);
			if ((Object)(object)_defaultViewBackground != (Object)null)
			{
				((Graphic)_defaultViewBackground).color = (UseModView ? val2 : val);
			}
			if ((Object)(object)_modViewBackground != (Object)null)
			{
				((Graphic)_modViewBackground).color = (UseModView ? val : val2);
			}
		}

		private static void ConfigurePersistentRepair(Hud hud, GameObject button, Piece repairPiece)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing reference