Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CraftIndex v0.3.1
CraftIndex.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using 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("CraftIndex")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.1.0")] [assembly: AssemblyInformationalVersion("0.3.1+3a9829310d8cc8c9761d7177112baaee7c67cc84")] [assembly: AssemblyProduct("CraftIndex")] [assembly: AssemblyTitle("CraftIndex")] [assembly: AssemblyVersion("0.3.1.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", "CraftIndex", "0.3.1")] public sealed class Plugin : BaseUnityPlugin { internal const string PluginGuid = "com.inventoryux.valheim"; internal const string PluginName = "CraftIndex"; internal const string PluginVersion = "0.3.1"; 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)"CraftIndex 0.3.1 loaded. Undiscovered content is never rendered."); } private void OnDestroy() { Cleanup("Hammer UI", HammerGroupDecorations.Shutdown); Cleanup("Hammer sizing", HammerGridSizer.Restore); Cleanup("Hammer caches", HammerOrganizer.Reset); Cleanup("recipe UI", RecipeOrganizer.Shutdown); Cleanup("food cache", FoodStatsResolver.Reset); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void Cleanup(string name, Action action) { try { action(); } catch (Exception arg) { LogInstance.LogWarning((object)$"CraftIndex could not fully release {name} during shutdown: {arg}"); } } } } 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, (PieceCategory)1)); 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, "CraftIndex"); 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 sealed class FailureCircuitBreaker { private readonly string _operation; private readonly float _retryDelaySeconds; private readonly float _logIntervalSeconds; private float _retryAfter; private float _nextLogAt; private int _suppressedFailures; internal bool IsOpen => Time.realtimeSinceStartup < _retryAfter; internal FailureCircuitBreaker(string operation, float retryDelaySeconds = 10f, float logIntervalSeconds = 60f) { _operation = operation; _retryDelaySeconds = retryDelaySeconds; _logIntervalSeconds = logIntervalSeconds; } internal void Reset() { _retryAfter = 0f; } internal void Trip(Exception exception) { float realtimeSinceStartup = Time.realtimeSinceStartup; _retryAfter = realtimeSinceStartup + _retryDelaySeconds; if (realtimeSinceStartup < _nextLogAt) { _suppressedFailures++; return; } string text = ((_suppressedFailures > 0) ? $" ({_suppressedFailures} repeated failures suppressed)" : string.Empty); _suppressedFailures = 0; _nextLogAt = realtimeSinceStartup + _logIntervalSeconds; Plugin.LogInstance.LogWarning((object)$"{_operation} paused for {_retryDelaySeconds:0} seconds after an error{text}: {exception}"); } } internal static class FoodStatsResolver { private readonly struct FoodResolutionCacheEntry { internal ItemDrop Output { get; } internal ResolvedFoodStats Stats { get; } internal FoodResolutionCacheEntry(ItemDrop output, ResolvedFoodStats stats) { Output = output; Stats = stats; } } 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 readonly Dictionary<int, FoodResolutionCacheEntry> ResolutionByOutput = new Dictionary<int, FoodResolutionCacheEntry>(); private static int _sceneInstanceId = int.MinValue; private static int _scenePrefabCount = -1; internal static void Reset() { CookedByInput.Clear(); FeastFoodByInput.Clear(); ResolutionByOutput.Clear(); _sceneInstanceId = int.MinValue; _scenePrefabCount = -1; } internal static ResolvedFoodStats Resolve(ItemDrop output) { if (output == null || (Object)(object)output == (Object)null) { return default(ResolvedFoodStats); } bool flag = EnsureIndex(); int instanceID = ((Object)output).GetInstanceID(); if (ResolutionByOutput.TryGetValue(instanceID, out var value) && value.Output == output) { return value.Stats; } 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) { ResolvedFoodStats resolvedFoodStats = FromItem(val2, resolved: true, isFeast: true); if (flag) { ResolutionByOutput[instanceID] = new FoodResolutionCacheEntry(output, resolvedFoodStats); } return resolvedFoodStats; } string name = ((Object)((Component)output).gameObject).name; if (FeastFoodByInput.TryGetValue(name, out ItemDrop value2) && (Object)(object)value2 != (Object)null) { ResolvedFoodStats resolvedFoodStats2 = FromItem(value2, resolved: true, isFeast: true); if (flag) { ResolutionByOutput[instanceID] = new FoodResolutionCacheEntry(output, resolvedFoodStats2); } return resolvedFoodStats2; } ItemDrop val3 = output; bool resolved = false; string b = null; string b2 = null; string b3 = null; string b4 = null; for (int i = 0; i < 4; i++) { string name2 = ((Object)((Component)val3).gameObject).name; if (string.Equals(name2, b, StringComparison.Ordinal) || string.Equals(name2, b2, StringComparison.Ordinal) || string.Equals(name2, b3, StringComparison.Ordinal) || string.Equals(name2, b4, StringComparison.Ordinal) || !CookedByInput.TryGetValue(name2, out ItemDrop value3) || (Object)(object)value3 == (Object)null) { break; } switch (i) { case 0: b = name2; break; case 1: b2 = name2; break; case 2: b3 = name2; break; default: b4 = name2; break; } val3 = value3; resolved = true; } ResolvedFoodStats resolvedFoodStats3 = FromItem(val3, resolved, isFeast: false); if (flag) { ResolutionByOutput[instanceID] = new FoodResolutionCacheEntry(output, resolvedFoodStats3); } return resolvedFoodStats3; } private static bool EnsureIndex() { //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Invalid comparison between Unknown and I4 ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || instance.m_prefabs == null) { return false; } int instanceID = ((Object)instance).GetInstanceID(); int count = instance.m_prefabs.Count; if (_sceneInstanceId == instanceID && _scenePrefabCount == count) { return true; } Reset(); _sceneInstanceId = instanceID; _scenePrefabCount = count; 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); } } } } return true; } 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 string[] RowLabels { get; } internal int[] Representatives { get; } internal List<SubgroupDivider> SubgroupBreaks { get; } internal int VisibleRows { get; } internal CraftingLayoutResult(int[] slots, float[] xOffsets, int repairIndex, string[] rowLabels, int[] representatives, List<SubgroupDivider> subgroupBreaks, int visibleRows) { Slots = slots; XOffsets = xOffsets; RepairIndex = repairIndex; RowLabels = rowLabels; 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 GameObject Root { get; } private bool Active { get; } 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(GameObject root, bool active, Image image, Color color, bool raycastTarget, RectTransform rect, Vector2 sizeDelta, UIInputHandler? input, bool inputEnabled) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) Root = root; Active = active; 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_0034: 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) if ((Object)(object)Root != (Object)null) { Root.SetActive(Active); } 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 sealed class CategoryCardView { internal GameObject Root { get; } internal RectTransform Rect { get; } internal Image Background { get; } internal RectTransform IconRect { get; } internal Image Icon { get; } internal RectTransform LabelRect { get; } internal TextMeshProUGUI Label { get; } internal CategoryCardView(GameObject root, RectTransform rect, Image background, RectTransform iconRect, Image icon, RectTransform labelRect, TextMeshProUGUI label) { Root = root; Rect = rect; Background = background; IconRect = iconRect; Icon = icon; LabelRect = labelRect; Label = label; } } 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 const float HammerSearchHeight = 30f; 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 readonly Dictionary<int, Piece> FavoritePiecesByInput = new Dictionary<int, Piece>(); private static readonly List<CategoryCardView> CategoryCardPool = new List<CategoryCardView>(); private static readonly List<Image> DecorationLinePool = new List<Image>(); private static readonly List<GameObject> IconDecorationPool = new List<GameObject>(); private static readonly HashSet<int> IconDecorationIds = new HashSet<int>(); private static int _decorationPoolHudId = int.MinValue; private static int _usedCategoryCards; private static int _usedDecorationLines; private static Image? _categoryHeaderBackgroundForPass; 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 readonly int[] PieceGenerations = new int[9]; private static int _appliedPiecesGeneration = -1; private static int _appliedPieceCount = -1; private static bool _appliedShowSeparators; private static bool _appliedShowPieceNames; 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 int _cleanedGeneratedBackgroundHudId = int.MinValue; private static GameObject? _persistentHammerSearch; private static TMP_InputField? _hammerSearchInput; private static Image? _hammerSearchBackground; private static int _hammerSearchHudId = int.MinValue; private static string _hammerSearchText = string.Empty; private static string _hammerSearchQuery = string.Empty; private static bool _hammerSearchHasFocus; private static PieceCategory _hammerSearchCategory = (PieceCategory)8; private static GameObject? _hammerNoResults; private static bool _refreshingHammerList; 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 bool IsSearchFocused => _hammerSearchHasFocus; internal static bool ShouldUseModView(PieceTable table) { if ((Object)(object)table != (Object)null && (Object)(object)((Component)table).gameObject != (Object)null) { return ModConfig.GetToolModView(((Object)((Component)table).gameObject).name); } return false; } internal static void NotifyPiecesChanged(PieceCategory category) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown int num = (int)category; if (num >= 0 && num < PieceGenerations.Length) { PieceGenerations[num]++; } } private static int GetPiecesGeneration(PieceCategory category) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown int num = (int)category; if (num < 0 || num >= PieceGenerations.Length) { return 0; } return PieceGenerations[num]; } internal static void Apply(Hud hud, IReadOnlyList<Piece> pieces, PieceCategory category) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Invalid comparison between Unknown and I4 //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: 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_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)hud).GetInstanceID(); RemoveStaleRepairForDifferentHud(instanceID); Player localPlayer = Player.m_localPlayer; PieceTable val = (PieceTable)(((Object)(object)localPlayer == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val != (Object)null) { UseModView = ShouldUseModView(val); } EnsurePersistentViewControls(hud, instanceID); PrepareHammerSearchCategory(category); EnsurePersistentHammerSearch(hud, instanceID); UpdateHammerSearchVisibility(category); if (_cleanedGeneratedBackgroundHudId != instanceID) { RemoveGeneratedWarmBackgrounds(hud); _cleanedGeneratedBackgroundHudId = instanceID; } if (!IsEnabled(category)) { Clear(hud, (int)category == 1); return; } bool value = ModConfig.ShowSeparators.Value; bool value2 = ModConfig.ShowHammerPieceNames.Value; if (_stateValid && _appliedHudId == instanceID && _appliedCategory == category && _appliedPiecesGeneration == GetPiecesGeneration(category) && _appliedPieceCount == pieces.Count && _appliedShowSeparators == value && _appliedShowPieceNames == value2) { return; } IList list = (IList)PieceIconsField.GetValue(hud); int num = Math.Min(pieces.Count, list.Count); Clear(hud); SetHammerNoResultsVisible(hud, visible: false); _categoryHeaderBackgroundForPass = FindVanillaCategoryHeaderBackground(hud); try { if (CountVisiblePieces(pieces, num, category) == 0 && !string.IsNullOrWhiteSpace(_hammerSearchText)) { int[] array = new int[num]; for (int i = 0; i < array.Length; i++) { array[i] = -1; } int num2 = FindRepairIndex(pieces, num); if (num2 >= 0) { EnsurePersistentRepair(hud, pieces, list, num2); } ConfigureNativePieceCells(list, pieces, num, array, num2); _visualSlots = array; _visualWidth = 15; _visualHeight = 6; SetHammerNoResultsVisible(hud, visible: true); RememberState(instanceID, category, pieces.Count, value, value2); return; } 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, pieces, num, craftingLayoutResult.Slots, craftingLayoutResult.RepairIndex); AddReferenceCraftingRows(hud, pieces, list, num, craftingLayoutResult); _visualWidth = 15; _visualHeight = craftingLayoutResult.VisibleRows; RememberState(instanceID, category, pieces.Count, value, value2); return; } if ((int)category != 1 && CanUseShelfLayout(pieces, num, category)) { 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, pieces, num, shelfLayoutResult.Slots, shelfLayoutResult.RepairIndex); ApplyShelfPositions(hud, list, shelfLayoutResult, num); AddShelfRows(hud, pieces, list, num, shelfLayoutResult); RememberState(instanceID, category, pieces.Count, value, value2); return; } string a = null; for (int j = 0; j < num; j++) { string text = HammerOrganizer.GetLabel(pieces[j], category) ?? "Other"; GroupPalette palette = GetPalette(category, text); bool flag = !string.Equals(a, text, StringComparison.Ordinal); GameObject iconGameObject = GetIconGameObject(list[j]); AddTileTint(iconGameObject, palette, flag); if (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(pieces[j]))) { AddFavoriteMarker(hud, iconGameObject); } if (flag && !IsStandaloneAction(category, text)) { AddLabel(hud, iconGameObject, CompactLabel(text), palette); } a = text; } RememberState(instanceID, category, pieces.Count, value, value2); } catch { RemoveDecorations(hud, list); ResetState(); throw; } } private static void RememberState(int hudInstanceId, PieceCategory category, int pieceCount, bool showSeparators, bool showPieceNames) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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 = hudInstanceId; _appliedCategory = category; _appliedPiecesGeneration = GetPiecesGeneration(category); _appliedPieceCount = pieceCount; _appliedShowSeparators = showSeparators; _appliedShowPieceNames = showPieceNames; _stateValid = true; } private static void ResetState() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) _stateValid = false; _appliedHudId = int.MinValue; _appliedPiecesGeneration = -1; _appliedPieceCount = -1; _appliedCategory = (PieceCategory)8; _visualSlots = Array.Empty<int>(); _visualWidth = 15; _visualHeight = 6; _repairLogicalIndex = -1; _categoryHeaderBackgroundForPass = null; } 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>(); } List<CraftingEntry> list = new List<CraftingEntry>(); int repairIndex = -1; for (int j = 0; j < count; j++) { Piece val = pieces[j]; if (CraftingLayoutMetadata.IsRepair(val)) { repairIndex = j; } else if (HammerOrganizer.MatchesPreparedSearch(val, (PieceCategory)1, _hammerSearchQuery)) { CraftingPieceLayout metadata = CraftingLayoutMetadata.Resolve(val); CraftingEntry item = new CraftingEntry(j, metadata, Localize(val.m_name)); if (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(val))) { list.Add(item); } else { array[(int)metadata.Section].Add(item); } } } list.Sort(CompareCraftingEntries); for (int k = 0; k < array.Length; k++) { array[k].Sort(CompareCraftingEntries); } int num = 6 + ((list.Count > 0) ? 1 : 0); int[] array2 = new int[count]; for (int l = 0; l < array2.Length; l++) { array2[l] = -1; } float[] array3 = new float[count]; bool[] array4 = new bool[15 * num]; string[] array5 = new string[num]; int[] array6 = new int[num]; for (int m = 0; m < array6.Length; m++) { array6[m] = -1; } List<SubgroupDivider> list2 = new List<SubgroupDivider>(); List<int> list3 = new List<int>(); int num2 = 0; if (list.Count > 0) { array5[num2] = "FAVORITES"; array6[num2] = list[0].PieceIndex; int num3 = 3; for (int n = 0; n < list.Count; n++) { CraftingEntry craftingEntry = list[n]; if (num3 >= 15) { list3.Add(craftingEntry.PieceIndex); continue; } int num4 = num2 * 15 + num3++; array2[craftingEntry.PieceIndex] = num4; array4[num4] = true; } num2++; } for (int num5 = 0; num5 < array.Length; num5++) { if (num2 >= num) { break; } List<CraftingEntry> list4 = array[num5]; if (list4.Count == 0) { continue; } array5[num2] = CraftingLayoutMetadata.Label((CraftingSection)num5); array6[num2] = FindCategoryRepresentative(list4, (CraftingSection)num5); int num6 = 3; int subgroup = list4[0].Metadata.Subgroup; int num7 = 0; for (int num8 = 0; num8 < list4.Count; num8++) { CraftingEntry craftingEntry2 = list4[num8]; if (num8 > 0 && craftingEntry2.Metadata.Subgroup != subgroup) { num7++; list2.Add(new SubgroupDivider(num2, num6, num7)); } if (num6 >= 15) { list3.Add(craftingEntry2.PieceIndex); } else { int num9 = num2 * 15 + num6; array2[craftingEntry2.PieceIndex] = num9; array3[craftingEntry2.PieceIndex] = (float)num7 * 26.4f; array4[num9] = true; num6++; } subgroup = craftingEntry2.Metadata.Subgroup; } num2++; } for (int num10 = 0; num10 < list3.Count; num10++) { int num11 = FirstFreePieceSlot(array4, num); if (num11 < 0) { break; } array2[list3[num10]] = num11; array4[num11] = true; } return new CraftingLayoutResult(array2, array3, repairIndex, array5, array6, list2, num2); } private static int CompareCraftingEntries(CraftingEntry left, CraftingEntry right) { int num = left.Metadata.SortOrder.CompareTo(right.Metadata.SortOrder); if (num != 0) { return num; } num = string.Compare(left.Name, right.Name, StringComparison.CurrentCultureIgnoreCase); if (num == 0) { return left.PieceIndex.CompareTo(right.PieceIndex); } return num; } private static bool CanUseShelfLayout(IReadOnlyList<Piece> pieces, int count, PieceCategory category) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 0; i < count; i++) { if (!CraftingLayoutMetadata.IsRepair(pieces[i]) && HammerOrganizer.MatchesPreparedSearch(pieces[i], category, _hammerSearchQuery)) { num++; } } if (num > 0) { return num <= 105; } return false; } private static ShelfLayoutResult BuildShelfLayout(Hud hud, IReadOnlyList<Piece> pieces, int count, PieceCategory category) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Invalid comparison between Unknown and I4 //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_030f: 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; } } for (int j = 0; j < 2; j++) { bool flag = j == 0; for (int k = 0; k < count; k++) { Piece piece = pieces[k]; if (!CraftingLayoutMetadata.IsRepair(piece) && HammerOrganizer.MatchesPreparedSearch(piece, category, _hammerSearchQuery) && ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(piece)) == flag) { list.Add(k); } } } string[] array = new string[list.Count]; int[] array2 = new int[list.Count]; int num = 0; int num2 = 0; string a = null; for (int l = 0; l < list.Count; l++) { Piece piece2 = pieces[list[l]]; PieceGroup pieceGroup = HammerOrganizer.Classify(piece2, category); string text = (array[l] = (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(piece2)) ? "Favorites" : (HammerOrganizer.GetLabel(piece2, category) ?? pieceGroup.Label))); array2[l] = pieceGroup.Suborder; if (l == 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) : (((int)category == 0 && HasCultivatorGroups(array)) ? BuildCultivatorRowSizes(array, array2) : 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 m = 0; m < array3.Length; m++) { array3[m] = -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 n = 0; n < num3; n++) { int num7 = list2?[n] ?? ShelfRowPlanner.ChooseGroupRowSize(array, num6, 15, num3 - n); array5[n] = array[num6]; array6[n] = list[num6]; int num8 = 0; for (int num9 = 1; num9 < num7; num9++) { if (IsShelfBreak(array, array2, num6 + num9, category)) { num8++; } } float num10 = pieceIconSpacing * 0.93f; if (num7 > 1) { float num11 = (num5 - num4 - (float)num8 * 26.4f) / (float)(num7 - 1); num10 = Mathf.Min(num10, num11); } int num12 = 0; for (int num13 = 0; num13 < num7; num13++) { int index = num6 + num13; int num14 = list[index]; if (num13 > 0 && IsShelfBreak(array, array2, index, category)) { num12++; } float num15 = num4 + (float)num13 * num10 + (float)num12 * 26.4f; if (num13 > 0 && IsShelfBreak(array, array2, index, category)) { list3.Add(new ShelfDivider(n, num15 - 19.8f)); } array3[num14] = n * 15 + num13; array4[num14] = num15; } 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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 == 0 && (string.Equals(Normalize(labels[index]), "vanilla", StringComparison.Ordinal) || string.Equals(Normalize(labels[index]), "planteverything", StringComparison.Ordinal))) { return subgroups[index - 1] != subgroups[index]; } 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 bool HasCultivatorGroups(string[] labels) { for (int i = 0; i < labels.Length; i++) { string text = Normalize(labels[i]); if (text == "vanilla" || text == "planteverything") { return true; } } return false; } private static List<int> BuildCultivatorRowSizes(string[] labels, int[] subgroups) { List<int> list = new List<int>(); int num = 0; while (num < labels.Length) { string text = labels[num]; int i; for (i = num + 1; i < labels.Length && string.Equals(text, labels[i], StringComparison.Ordinal); i++) { } string text2 = Normalize(text); if (text2 != "vanilla" && text2 != "planteverything") { AddBalancedRowSizes(list, i - num); num = i; continue; } while (num < i) { int num2 = subgroups[num]; int j; for (j = num + 1; j < i && subgroups[j] == num2; j++) { } AddBalancedRowSizes(list, j - num); num = j; } } return list; } private static void AddBalancedRowSizes(List<int> sizes, int count) { int num = Mathf.CeilToInt((float)count / 15f); int num2 = count; for (int i = 0; i < num; i++) { int num3 = Mathf.CeilToInt((float)num2 / (float)(num - i)); sizes.Add(num3); num2 -= num3; } } 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 int CountVisiblePieces(IReadOnlyList<Piece> pieces, int count, PieceCategory category) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 0; i < count; i++) { if (!CraftingLayoutMetadata.IsRepair(pieces[i]) && HammerOrganizer.MatchesPreparedSearch(pieces[i], category, _hammerSearchQuery)) { num++; } } return num; } private static int FindRepairIndex(IReadOnlyList<Piece> pieces, int count) { for (int i = 0; i < count; i++) { if (CraftingLayoutMetadata.IsRepair(pieces[i])) { return i; } } return -1; } private static bool CanUseReferenceCraftingLayout(IReadOnlyList<Piece> pieces, int count) { int num = 0; bool flag = false; for (int i = 0; i < count; i++) { Piece piece = pieces[i]; if (!CraftingLayoutMetadata.IsRepair(piece) && HammerOrganizer.MatchesPreparedSearch(piece, (PieceCategory)1, _hammerSearchQuery)) { num++; if (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(piece))) { flag = true; } } } int num2 = 6 + (flag ? 1 : 0); if (num > 0) { return num <= 12 * num2; } return false; } private static int FirstFreePieceSlot(bool[] used, int rows) { for (int i = 0; i < rows; 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) { GameObject iconGameObject = GetIconGameObject(icons[i]); if (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(pieces[i]))) { AddFavoriteMarker(hud, iconGameObject); } if (ModConfig.ShowHammerPieceNames.Value) { AddReferenceTile(hud, iconGameObject, pieces[i]); } } } for (int j = 0; j < layout.VisibleRows; j++) { if (j < layout.VisibleRows - 1 && ModConfig.ShowSeparators.Value) { AddRowSeparator(hud, templateRect, j, CraftingRowPitch(hud, layout.VisibleRows)); } int num = layout.Representatives[j]; if (!string.IsNullOrEmpty(layout.RowLabels[j]) && num >= 0) { AddCategoryCard(hud, templateRect, j, CraftingRowPitch(hud, layout.VisibleRows), layout.RowLabels[j], pieces[num]); } } if (ModConfig.ShowSeparators.Value) { for (int k = 0; k < layout.SubgroupBreaks.Count; k++) { AddSubgroupSeparator(hud, templateRect, layout.SubgroupBreaks[k], CraftingRowPitch(hud, layout.VisibleRows)); } } } 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) { GameObject iconGameObject = GetIconGameObject(icons[i]); if (ModConfig.IsFavorite(HammerOrganizer.GetPieceKey(pieces[i]))) { AddFavoriteMarker(hud, iconGameObject); } if (ModConfig.ShowHammerPieceNames.Value) { AddReferenceTile(hud, iconGameObject, 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00b8: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) Transform val = iconRoot.transform.Find("InventoryUX_CraftingPieceName"); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = ((Component)val).gameObject; val2.SetActive(true); } else { val2 = new GameObject("InventoryUX_CraftingPieceName", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(iconRoot.transform, false); } TrackIconDecoration(val2); val2.transform.SetAsLastSibling(); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 0f); val3.anchorMax = new Vector2(1f, 0f); val3.pivot = new Vector2(0.5f, 0f); val3.anchoredPosition = new Vector2(0f, 3f); val3.sizeDelta = new Vector2(-8f, 27f); TextMeshProUGUI component = val2.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 AddFavoriteMarker(Hud hud, GameObject iconRoot) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00b8: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) Transform val = iconRoot.transform.Find("InventoryUX_FavoriteMarker"); GameObject val2; if ((Object)(object)val != (Object)null) { val2 = ((Component)val).gameObject; val2.SetActive(true); } else { val2 = new GameObject("InventoryUX_FavoriteMarker", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(iconRoot.transform, false); } TrackIconDecoration(val2); val2.transform.SetAsLastSibling(); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(1f, 1f); val3.anchorMax = new Vector2(1f, 1f); val3.pivot = new Vector2(1f, 1f); val3.anchoredPosition = new Vector2(-2f, -1f); val3.sizeDelta = new Vector2(22f, 22f); TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = "★"; ((TMP_Text)component).font = (((Object)(object)hud.m_pieceDescription != (Object)null) ? hud.m_pieceDescription.font : null); ((TMP_Text)component).fontSize = 17f; ((TMP_Text)component).fontStyle = (FontStyles)1; ((Graphic)component).color = new Color(0.93f, 0.63f, 0.25f, 1f); ((TMP_Text)component).alignment = (TextAlignmentOptions)260; ((TMP_Text)component).outlineWidth = 0.22f; ((TMP_Text)component).outlineColor = Color32.op_Implicit(Color.black); ((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_003c: 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_0054: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) float pieceIconSpacing = hud.m_pieceIconSpacing; CategoryCardView categoryCardView = AcquireCategoryCard(hud); GameObject root = categoryCardView.Root; ((Object)root).name = "InventoryUX_CraftingCategory_" + row; root.transform.SetAsLastSibling(); RectTransform rect = categoryCardView.Rect; rect.anchorMin = templateRect.anchorMin; rect.anchorMax = templateRect.anchorMax; rect.pivot = templateRect.pivot; rect.anchoredPosition = new Vector2(0f, (float)(-row) * rowPitch); rect.sizeDelta = new Vector2(CategoryRailWidth(pieceIconSpacing), rowPitch * (float)rowSpan - 7f); Image background = categoryCardView.Background; Image categoryHeaderBackgroundForPass = _categoryHeaderBackgroundForPass; if ((Object)(object)categoryHeaderBackgroundForPass != (Object)null) { background.sprite = categoryHeaderBackgroundForPass.sprite; background.overrideSprite = categoryHeaderBackgroundForPass.overrideSprite; ((Graphic)background).material = ((Graphic)categoryHeaderBackgroundForPass).material; background.type = categoryHeaderBackgroundForPass.type; background.preserveAspect = categoryHeaderBackgroundForPass.preserveAspect; background.fillCenter = categoryHeaderBackgroundForPass.fillCenter; background.pixelsPerUnitMultiplier = categoryHeaderBackgroundForPass.pixelsPerUnitMultiplier; ((Graphic)background).color = ((Graphic)categoryHeaderBackgroundForPass).canvasRenderer.GetColor(); } else { background.sprite = null; background.overrideSprite = null; ((Graphic)background).material = null; background.type = (Type)0; ((Graphic)background).color = new Color(0.2f, 0.2f, 0.2f, 0.7f); } ((Graphic)background).raycastTarget = false; RectTransform iconRect = categoryCardView.IconRect; iconRect.anchorMin = new Vector2(0f, 0.5f); iconRect.anchorMax = new Vector2(0f, 0.5f); iconRect.pivot = new Vector2(0f, 0.5f); iconRect.anchoredPosition = new Vector2(8f, 0f); iconRect.sizeDelta = new Vector2(56f, 56f); Image icon = categoryCardView.Icon; icon.sprite = representative.m_icon; icon.preserveAspect = true; ((Graphic)icon).color = Color.white; ((Graphic)icon).raycastTarget = false; RectTransform labelRect = categoryCardView.LabelRect; labelRect.anchorMin = Vector2.zero; labelRect.anchorMax = Vector2.one; labelRect.offsetMin = new Vector2(66f, 6f); labelRect.offsetMax = new Vector2(-7f, -6f); TextMeshProUGUI label = categoryCardView.Label; ((TMP_Text)label).text = text.ToUpperInvariant(); ((TMP_Text)label).font = (((Object)(object)hud.m_pieceDescription != (Object)null) ? hud.m_pieceDescription.font : null); ((TMP_Text)label).fontSize = 12.8f; ((TMP_Text)label).fontSizeMin = 9.5f; ((TMP_Text)label).fontSizeMax = 12.8f; ((TMP_Text)label).enableAutoSizing = true; ((TMP_Text)label).fontStyle = (FontStyles)1; ((Graphic)label).color = new Color(0.84f, 0.69f, 0.43f, 1f); ((TMP_Text)label).alignment = (TextAlignmentOptions)4097; ((TMP_Text)label).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)label).overflowMode = (TextOverflowModes)1; ((TMP_Text)label).outlineWidth = 0.12f; ((TMP_Text)label).outlineColor = new Color32((byte)18, (byte)12, (byte)8, (byte)245); ((Graphic)label).raycastTarget = false; } private static CategoryCardView AcquireCategoryCard(Hud hud) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown EnsureDecorationPoolOwner(hud); CategoryCardView categoryCardView = ((_usedCategoryCards < CategoryCardPool.Count) ? CategoryCardPool[_usedCategoryCards] : null); if (categoryCardView == null || (Object)(object)categoryCardView.Root == (Object)null) { GameObject val = new GameObject("InventoryUX_CraftingCategoryPool", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent((Transform)(object)hud.m_pieceListRoot, false); RectTransform val2 = (RectTransform)val.transform; Image component = val.GetComponent<Image>(); AddRectBorder(val2, new Color(0.68f, 0.5f, 0.25f, 0.68f)); GameObject val3 = new GameObject("InventoryUX_CraftingCategoryIcon", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent((Transform)(object)val2, false); RectTransform iconRect = (RectTransform)val3.transform; Image component2 = val3.GetComponent<Image>(); GameObject val4 = new GameObject("InventoryUX_CraftingCategoryLabel", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val4.transform.SetParent((Transform)(object)val2, false); RectTransform labelRect = (RectTransform)val4.transform; TextMeshProUGUI component3 = val4.GetComponent<TextMeshProUGUI>(); categoryCardView = new CategoryCardView(val, val2, component, iconRect, component2, labelRect, component3); if (_usedCategoryCards < CategoryCardPool.Count) { CategoryCardPool[_usedCategoryCards] = categoryCardView; } else { CategoryCardPool.Add(categoryCardView); } } categoryCardView.Root.SetActive(true); _usedCategoryCards++; return categoryCardView; } private static Image? FindVanillaCategoryHeaderBackground(Hud hud) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Image result = null; float num = float.MaxValue; GameObject[] pieceCategoryTabs = hud.m_pieceCategoryTabs; foreach (GameObject val in pieceCategoryTabs) { if ((Object)(object)val == (Object)null || !val.activeInHierarchy) { continue; } Image val2 = val.GetComponent<Image>() ?? val.GetComponentInChildren<Image>(true); if ((Object)(object)val2 == (Object)null) { continue; } Color color = ((Graphic)val2).canvasRenderer.GetColor(); if (!(color.a <= 0.05f)) { float num2 = color.r * 0.2126f + color.g * 0.7152f + color.b * 0.0722f; if (num2 < num) { result = val2; num = num2; } } } return result; } 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_002f: 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_0036: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) float pieceIconSpacing = hud.m_pieceIconSpacing; Image obj = AcquireDecorationLine(hud, "InventoryUX_CraftingRowSeparator_" + row); ((Component)obj).transform.SetAsLastSibling(); RectTransform val = (RectTransform)((Component)obj).transform; val.anchorMin = templateRect.anchorMin; val.anchorMax = templateRect.anchorMax; val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(startX, (0f - ((float)row + 1f)) * rowPitch + 3.5f); val.sizeDelta = new Vector2(15f * pieceIconSpacing - 9f - startX, 1f); ((Graphic)obj).color = new Color(0.57f, 0.4f, 0.19f, 0.34f); ((Graphic)obj).raycastTarget = false; } private static void AddSubgroupSeparator(Hud hud, RectTransform templateRect, SubgroupDivider divider, float rowPitch) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to