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 FoodCategories v0.1.35
FoodCategories.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("FoodCategories")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.35.0")] [assembly: AssemblyInformationalVersion("0.1.35")] [assembly: AssemblyProduct("FoodCategories")] [assembly: AssemblyTitle("FoodCategories")] [assembly: AssemblyVersion("0.1.35.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 FoodCategories { [BepInPlugin("branchofyore.foodcategories", "Food Categories", "0.1.35")] public sealed class Plugin : BaseUnityPlugin { private enum FoodFilter { All, Health, Stamina, Eitr, Balanced, Feast } private sealed class FilterBar { public FoodFilter Current; public RectTransform Root; public bool PreparationStation; public readonly Dictionary<FoodFilter, Button> Buttons = new Dictionary<FoodFilter, Button>(); public Sprite? TabSprite; public Image? CraftTabTemplate; public Image? UpgradeTabTemplate; } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] private static class RecipeListPatch { private static void Postfix(InventoryGui __instance) { try { Apply(__instance, resetScroll: true); } catch (Exception ex) { Debug.LogWarning((object)("Food Categories: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Update")] private static class CraftWindowRefreshPatch { private static void Postfix(InventoryGui __instance) { if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1" && KeepManualCraftMenuOpen) { if (Input.GetKeyDown((KeyCode)27)) { KeepManualCraftMenuOpen = false; } else { if (Object.op_Implicit((Object)(object)__instance.m_inventoryRoot) && !((Component)__instance.m_inventoryRoot).gameObject.activeSelf) { ((Component)__instance.m_inventoryRoot).gameObject.SetActive(true); } if (Object.op_Implicit((Object)(object)__instance.m_inventoryGroup) && !__instance.m_inventoryGroup.IsActive) { __instance.m_inventoryGroup.SetActive(true); } if (Object.op_Implicit((Object)(object)__instance.m_crafting) && !((Component)__instance.m_crafting).gameObject.activeSelf) { ((Component)__instance.m_crafting).gameObject.SetActive(true); } if (Object.op_Implicit((Object)(object)__instance.m_recipeListRoot) && !((Component)__instance.m_recipeListRoot).gameObject.activeSelf) { ((Component)__instance.m_recipeListRoot).gameObject.SetActive(true); } if (Object.op_Implicit((Object)(object)__instance.m_inventoryRoot)) { foreach (CanvasGroup item in ((Component)__instance.m_inventoryRoot).GetComponentsInParent<CanvasGroup>(true).Concat(((Component)__instance.m_inventoryRoot).GetComponentsInChildren<CanvasGroup>(true)).Distinct()) { item.alpha = 1f; item.interactable = true; item.blocksRaycasts = true; } } if (!__instance.InCraftTab()) { AccessTools.Method(typeof(InventoryGui), "OnTabCraftPressed", (Type[])null, (Type[])null)?.Invoke(__instance, null); } } } if (!Object.op_Implicit((Object)(object)__instance)) { return; } Transform inventoryRoot = __instance.m_inventoryRoot; if (!Object.op_Implicit((Object)(object)inventoryRoot) || !((Component)inventoryRoot).gameObject.activeInHierarchy || !Object.op_Implicit((Object)(object)__instance.m_inventoryGroup) || !__instance.m_inventoryGroup.IsActive || !__instance.InCraftTab()) { HideBar(__instance); return; } float unscaledTime = Time.unscaledTime; if (NextCategoryRefresh.TryGetValue(__instance, out var value) && unscaledTime < value) { return; } NextCategoryRefresh[__instance] = unscaledTime + 0.2f; try { Apply(__instance); } catch (Exception ex) { Debug.LogWarning((object)("Food Categories refresh: " + ex.Message)); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] private static class HideCraftMenuPatch { private static void Postfix(InventoryGui __instance) { HideBar(__instance); } } [HarmonyPatch(typeof(UIGroupHandler), "SetActive")] private static class InventoryGroupVisibilityPatch { private static void Postfix(UIGroupHandler __instance, bool active) { if (active) { return; } InventoryGui[] array = Bars.Keys.ToArray(); foreach (InventoryGui val in array) { if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.m_inventoryGroup == (Object)(object)__instance) { HideBar(val); } } } } private sealed class Entry { public Recipe Recipe; public ItemData Item; public GameObject Element; } public const string Id = "branchofyore.foodcategories"; private static readonly Harmony Harmony = new Harmony("branchofyore.foodcategories"); private static readonly Dictionary<InventoryGui, FilterBar> Bars = new Dictionary<InventoryGui, FilterBar>(); private static readonly Dictionary<InventoryGui, float> NextCategoryRefresh = new Dictionary<InventoryGui, float>(); private static readonly HashSet<string> AuditedRows = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<RectTransform, Vector2> OriginalRowPositions = new Dictionary<RectTransform, Vector2>(); private static readonly Dictionary<RectTransform, Vector2> OriginalRowSizes = new Dictionary<RectTransform, Vector2>(); private static ManualLogSource? TestLog; private static bool KeepManualCraftMenuOpen; private void Awake() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown TestLog = ((BaseUnityPlugin)this).Logger; if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1") { Application.runInBackground = true; } Harmony.PatchAll(); if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1") { MethodInfo methodInfo = AccessTools.Method(typeof(Player), "GetMaxCarryWeight", (Type[])null, (Type[])null); if (methodInfo != null) { Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "TestCarryWeightPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Food Categories: crafting food filters enabled."); if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1") { ((MonoBehaviour)this).StartCoroutine(PrepareManualTest()); } } private void OnDestroy() { Harmony.UnpatchSelf(); } private static void TestCarryWeightPostfix(ref float __result) { if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1") { __result = 100000f; } } private IEnumerator PrepareManualTest() { yield return (object)new WaitForSecondsRealtime(10f); Game.SetProfile("FoodCategories_Manual_" + DateTime.UtcNow.Ticks, (FileSource)2); ZNet.SetServer(true, false, false, "Food Categories test", "", World.GetCreateWorld("FoodCategories_Test", (FileSource)2)); AccessTools.Method(typeof(FejdStartup), "LoadMainScene", (Type[])null, (Type[])null)?.Invoke(FejdStartup.instance, null); float deadline = Time.realtimeSinceStartup + 180f; while (!Object.op_Implicit((Object)(object)Player.m_localPlayer) && Time.realtimeSinceStartup < deadline) { yield return (object)new WaitForSecondsRealtime(1f); } if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { yield break; } yield return (object)new WaitForSecondsRealtime(4f); Valkyrie[] array = Object.FindObjectsByType<Valkyrie>((FindObjectsSortMode)0); foreach (Valkyrie val in array) { ZNetScene.instance.Destroy(((Component)val).gameObject); } Player player = Player.m_localPlayer; player.SetIntro(false); ((Character)player).AttachStop(); if (Object.op_Implicit((Object)(object)TextViewer.instance)) { TextViewer.instance.HideIntro(); } Vector3 val2 = default(Vector3); ZoneSystem.instance.GetLocationIcon("StartTemple", ref val2); val2.y = ZoneSystem.instance.GetGroundHeight(val2) + 0.2f; ((Component)player).transform.position = val2; ((Component)player).GetComponent<Rigidbody>().position = val2; ((Component)player).GetComponent<Rigidbody>().linearVelocity = Vector3.zero; AccessTools.Field(typeof(Player), "m_noPlacementCost")?.SetValue(player, true); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Native food labels: " + Localization.instance.Localize("$item_food_health") + " | " + Localization.instance.Localize("$item_food_stamina") + " | " + Localization.instance.Localize("$item_food_eitr"))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("TEST station interaction APIs: " + string.Join(" | ", from method in typeof(CraftingStation).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where method.Name.IndexOf("interact", StringComparison.OrdinalIgnoreCase) >= 0 || method.Name.IndexOf("craft", StringComparison.OrdinalIgnoreCase) >= 0 select method.Name + "(" + string.Join(",", from parameter in method.GetParameters() select parameter.ParameterType.Name) + ")"))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Native UI sprite candidates: " + string.Join(", ", (from sprite in Resources.FindObjectsOfTypeAll<Sprite>() where ((Object)sprite).name.IndexOf("food", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sprite).name.IndexOf("health", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sprite).name.IndexOf("stamina", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sprite).name.IndexOf("eitr", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sprite).name.IndexOf("fork", StringComparison.OrdinalIgnoreCase) >= 0 select ((Object)sprite).name).Distinct().Take(80)))); List<Recipe> testRecipes = ObjectDB.instance.m_recipes.Where((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && (IsFood(recipe.m_item.m_itemData) || IsFeast(recipe.m_item.m_itemData) || IsMead(recipe.m_item.m_itemData))).ToList(); foreach (Recipe item in testRecipes) { AccessTools.Method(typeof(Player), "AddKnownRecipe", new Type[1] { typeof(Recipe) }, (Type[])null)?.Invoke(player, new object[1] { item }); player.AddKnownItem(item.m_item.m_itemData); Requirement[] resources = item.m_resources; foreach (Requirement val3 in resources) { if (Object.op_Implicit((Object)(object)val3?.m_resItem)) { player.AddKnownItem(val3.m_resItem.m_itemData); } } } (string, int)[] array2 = new(string, int)[23] { ("Hammer", 1), ("Wood", 100), ("Stone", 100), ("Tin", 40), ("RawMeat", 20), ("DeerMeat", 20), ("WolfMeat", 20), ("LoxMeat", 20), ("Raspberry", 20), ("Blueberries", 20), ("Cloudberry", 20), ("Mushroom", 20), ("Honey", 20), ("Barley", 20), ("BarleyFlour", 20), ("FishRaw", 20), ("Thistle", 20), ("Dandelion", 20), ("GreydwarfEye", 20), ("Bloodbag", 20), ("FreezeGland", 20), ("Ooze", 20), ("Entrails", 20) }; for (int i = 0; i < array2.Length; i++) { (string, int) tuple = array2[i]; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(tuple.Item1); ItemDrop val4 = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); if (Object.op_Implicit((Object)(object)val4)) { ItemData val5 = val4.m_itemData.Clone(); val5.m_dropPrefab = itemPrefab; val5.m_stack = tuple.Item2; ((Humanoid)player).GetInventory().AddItem(val5); } } foreach (Requirement item2 in from @group in (from requirement in testRecipes.Where((Recipe recipe) => IsMead(recipe.m_item.m_itemData)).SelectMany((Recipe recipe) => recipe.m_resources) where Object.op_Implicit((Object)(object)requirement?.m_resItem) select requirement).GroupBy<Requirement, string>((Requirement requirement) => ((Object)requirement.m_resItem).name, StringComparer.OrdinalIgnoreCase) select @group.First()) { GameObject gameObject = ((Component)item2.m_resItem).gameObject; ItemDrop component = gameObject.GetComponent<ItemDrop>(); if (Object.op_Implicit((Object)(object)component)) { ItemData val6 = component.m_itemData.Clone(); val6.m_dropPrefab = gameObject; val6.m_stack = Math.Max(20, item2.m_amount); ((Humanoid)player).GetInventory().AddItem(val6); } } Vector3 kitchen = val2 + ((Component)player).transform.forward * 6f; kitchen.y = ZoneSystem.instance.GetGroundHeight(kitchen); SpawnTestPiece("fire_pit", kitchen); SpawnTestPiece("piece_cauldron", kitchen + Vector3.up * 1.15f, 180f); SpawnTestPiece("piece_cauldron_ext1_spice", kitchen + new Vector3(-2.3f, 0f, 1.4f), 35f); SpawnTestPiece("piece_cauldron_ext3_butchertable", kitchen + new Vector3(2.3f, 0f, 1.4f), -35f); SpawnTestPiece("piece_cauldron_ext4_pans", kitchen + new Vector3(-2.3f, 0f, -1.4f), 145f); SpawnTestPiece("piece_cauldron_ext5_mortarandpestle", kitchen + new Vector3(2.3f, 0f, -1.4f), -145f); SpawnTestPiece("piece_cauldron_ext6_rollingpins", kitchen + new Vector3(0f, 0f, 2.8f)); SpawnTestPiece("piece_cauldron_ext7_smoker", kitchen + new Vector3(0f, 0f, -2.8f), 180f); Vector3 meadKitchen = kitchen + ((Component)player).transform.right * 6f; meadKitchen.y = ZoneSystem.instance.GetGroundHeight(meadKitchen); GameObject val7 = SpawnTestPiece("fire_pit", meadKitchen); GameObject val8 = SpawnTestPiece("piece_meadcauldron", meadKitchen + Vector3.up * 1.15f, 180f); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories manual Mead setup: Mead Cauldron=" + (Object.op_Implicit((Object)(object)val8) ? ((Object)val8).name : "prefab not found") + ", fire pit beneath=" + (Object.op_Implicit((Object)(object)val7) ? ((Object)val7).name : "prefab not found"))); Vector3 preparationTable = kitchen + ((Component)player).transform.right * 12f; preparationTable.y = ZoneSystem.instance.GetGroundHeight(preparationTable) + 0.05f; SpawnTestPiece("piece_preptable", preparationTable, 90f); SpawnTestPiece("wood_wall", preparationTable + new Vector3(-2f, 1.3f, 0f), 90f); SpawnTestPiece("wood_wall", preparationTable + new Vector3(2f, 1.3f, 0f), -90f); SpawnTestPiece("wood_wall", preparationTable + new Vector3(0f, 1.3f, 2f), 180f); SpawnTestPiece("wood_roof_45", preparationTable + new Vector3(-1f, 1.75f, 0f), 90f); SpawnTestPiece("wood_roof_45", preparationTable + new Vector3(1f, 1.75f, 0f), -90f); SpawnTestPiece("wood_floor_2x2", preparationTable + new Vector3(0f, 1.9f, 0f)); AccessTools.Field(typeof(Player), "m_noPlacementCost")?.SetValue(player, false); AccessTools.Field(typeof(Player), "m_maxCarryWeight")?.SetValue(player, 100000f); Vector3 val9 = preparationTable + new Vector3(0f, 0f, 0.45f); val9.y = ZoneSystem.instance.GetGroundHeight(val9) + 0.2f; ((Component)player).transform.position = val9; Transform transform = ((Component)player).transform; Vector3 val10 = preparationTable - val9; transform.rotation = Quaternion.LookRotation(((Vector3)(ref val10)).normalized, Vector3.up); ((Component)player).GetComponent<Rigidbody>().position = val9; ((Component)player).GetComponent<Rigidbody>().linearVelocity = Vector3.zero; yield return (object)new WaitForSecondsRealtime(1f); object obj = AccessTools.Method(typeof(Player), "IsUnderRoof", (Type[])null, (Type[])null)?.Invoke(player, null); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories test shelter check: player under roof=" + (obj ?? "unavailable")?.ToString() + ", table distance=" + Vector3.Distance(((Component)player).transform.position, preparationTable))); IEnumerable<string> values = from @group in (from recipe in ObjectDB.instance.m_recipes select recipe?.m_item?.m_itemData into item where item != null select (item)).Where(IsFood).GroupBy(Classify) orderby @group.Key select @group.Key.ToString() + "=" + @group.Count(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories recipe audit: " + string.Join(", ", values))); foreach (GameObject item3 in ObjectDB.instance.m_items) { ItemData val11 = ((!Object.op_Implicit((Object)(object)item3)) ? null : item3.GetComponent<ItemDrop>()?.m_itemData); if (val11 != null && IsFood(val11)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories catalog: " + val11.m_shared.m_name + "=" + Classify(val11).ToString() + " (HP=" + val11.m_shared.m_food + ", stamina=" + val11.m_shared.m_foodStamina + ", eitr=" + val11.m_shared.m_foodEitr + ")")); } } ItemData val12 = ObjectDB.instance.m_items.Select((GameObject prefab) => (!Object.op_Implicit((Object)(object)prefab)) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item?.m_shared.m_name.Equals("$item_bakedpoteitr_uncooked", StringComparison.OrdinalIgnoreCase) ?? false)); string text = ((val12 == null) ? "not-found" : Classify(val12).ToString()); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories check: Unbaked Poteitr=" + text + " (HP=" + val12?.m_shared.m_food + ", stamina=" + val12?.m_shared.m_foodStamina + ", eitr=" + val12?.m_shared.m_foodEitr + "), Feast recipes=" + ObjectDB.instance.m_recipes.Count((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && IsFeast(recipe.m_item.m_itemData)))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories station audit: Cauldron=" + ObjectDB.instance.m_recipes.Count((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && IsFood(recipe.m_item.m_itemData) && BelongsToStation(recipe, preparationStation: false)) + ", Preparation=" + ObjectDB.instance.m_recipes.Count((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && IsFood(recipe.m_item.m_itemData) && BelongsToStation(recipe, preparationStation: true)))); foreach (Recipe item4 in ObjectDB.instance.m_recipes.Where((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && recipe.m_item.m_itemData.m_shared.m_name.IndexOf("pancake", StringComparison.OrdinalIgnoreCase) >= 0)) { ItemData itemData = item4.m_item.m_itemData; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories pancake check: " + itemData.m_shared.m_name + "=" + Classify(itemData).ToString() + " (HP=" + itemData.m_shared.m_food + ", stamina=" + itemData.m_shared.m_foodStamina + ", eitr=" + itemData.m_shared.m_foodEitr + ")")); } foreach (Recipe item5 in ObjectDB.instance.m_recipes.Where((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && (recipe.m_item.m_itemData.m_shared.m_name.IndexOf("crust", StringComparison.OrdinalIgnoreCase) >= 0 || recipe.m_item.m_itemData.m_shared.m_name.IndexOf("sweetbread", StringComparison.OrdinalIgnoreCase) >= 0))) { ItemData itemData2 = item5.m_item.m_itemData; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories row audit: " + itemData2.m_shared.m_name + "=" + Classify(itemData2).ToString() + " (HP=" + itemData2.m_shared.m_food + ", stamina=" + itemData2.m_shared.m_foodStamina + ", eitr=" + itemData2.m_shared.m_foodEitr + ")")); } foreach (Recipe item6 in ObjectDB.instance.m_recipes.Where((Recipe recipe) => Object.op_Implicit((Object)(object)recipe?.m_item) && IsFood(recipe.m_item.m_itemData) && BelongsToStation(recipe, preparationStation: true))) { ItemData itemData3 = item6.m_item.m_itemData; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories preparation audit: " + itemData3.m_shared.m_name + "=" + Classify(itemData3).ToString() + " (HP=" + itemData3.m_shared.m_food + ", stamina=" + itemData3.m_shared.m_foodStamina + ", eitr=" + itemData3.m_shared.m_foodEitr + ")")); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Food Categories manual test ready: fully upgraded cauldron and Food Preparation Table placed."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories manual test Mead recipes unlocked: " + string.Join(", ", from recipe in testRecipes where IsMead(recipe.m_item.m_itemData) select ((Object)recipe.m_item).name))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Food Categories manual test Mead station requirements: " + string.Join(" | ", from recipe in testRecipes where IsMead(recipe.m_item.m_itemData) select ((Object)recipe.m_item).name + " station=" + RecipeStationName(recipe) + " level=" + AccessTools.Field(typeof(Recipe), "m_minStationLevel")?.GetValue(recipe)))); CraftingStation[] source = Object.FindObjectsByType<CraftingStation>((FindObjectsSortMode)0); CraftingStation val13 = (from candidate in source where Object.op_Implicit((Object)(object)candidate) && ((Object)((Component)candidate).gameObject).name.IndexOf("meadcauldron", StringComparison.OrdinalIgnoreCase) >= 0 orderby Vector3.Distance(((Component)candidate).transform.position, meadKitchen) select candidate).FirstOrDefault(); CraftingStation val14 = (from candidate in source where Object.op_Implicit((Object)(object)candidate) && ((Object)((Component)candidate).gameObject).name.IndexOf("cauldron", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)((Component)candidate).gameObject).name.IndexOf("meadcauldron", StringComparison.OrdinalIgnoreCase) < 0 orderby Vector3.Distance(((Component)candidate).transform.position, kitchen) select candidate).FirstOrDefault(); (from candidate in source where Object.op_Implicit((Object)(object)candidate) && ((Object)((Component)candidate).gameObject).name.IndexOf("preptable", StringComparison.OrdinalIgnoreCase) >= 0 orderby Vector3.Distance(((Component)candidate).transform.position, preparationTable) select candidate).FirstOrDefault(); CraftingStation val15 = (Object.op_Implicit((Object)(object)val13) ? val13 : val14); if (Object.op_Implicit((Object)(object)val15)) { Vector3 val16 = ((Component)val15).transform.position - ((Component)val15).transform.forward * 1.4f; val16.y = ZoneSystem.instance.GetGroundHeight(val16) + 0.2f; ((Component)player).transform.position = val16; ((Component)player).GetComponent<Rigidbody>().position = val16; ((Component)player).GetComponent<Rigidbody>().linearVelocity = Vector3.zero; val10 = ((Component)val15).transform.position + Vector3.up * 0.35f - (val16 + Vector3.up * 1.5f); Vector3 normalized = ((Vector3)(ref val10)).normalized; ((Component)player).transform.rotation = Quaternion.LookRotation(new Vector3(normalized.x, 0f, normalized.z), Vector3.up); player.SetCraftingStation(val15); MethodInfo methodInfo = AccessTools.Method(typeof(CraftingStation), "Interact", new Type[3] { typeof(Humanoid), typeof(bool), typeof(bool) }, (Type[])null); bool num = methodInfo != null && (bool)(methodInfo.Invoke(val15, new object[3] { player, false, false }) ?? ((object)false)); InventoryGui instance = InventoryGui.instance; KeepManualCraftMenuOpen = true; if (!num) { AccessTools.Method(typeof(InventoryGui), "Show", new Type[2] { typeof(Container), typeof(int) }, (Type[])null)?.Invoke(instance, new object[2] { null, 0 }); if (Object.op_Implicit((Object)(object)instance.m_inventoryRoot) && !((Component)instance.m_inventoryRoot).gameObject.activeSelf) { ((Component)instance.m_inventoryRoot).gameObject.SetActive(true); } if (Object.op_Implicit((Object)(object)instance.m_inventoryGroup) && !instance.m_inventoryGroup.IsActive) { instance.m_inventoryGroup.SetActive(true); } AccessTools.Method(typeof(InventoryGui), "OnTabCraftPressed", (Type[])null, (Type[])null)?.Invoke(instance, null); AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", new Type[1] { typeof(bool) }, (Type[])null)?.Invoke(instance, new object[1] { true }); } List<string> list = (from entry in Entries(instance) where IsMead(entry.Item) select (!Object.op_Implicit((Object)(object)entry.Item.m_dropPrefab)) ? entry.Item.m_shared.m_name : ((Object)entry.Item.m_dropPrefab).name).ToList(); ManualLogSource? testLog = TestLog; if (testLog != null) { testLog.LogInfo((object)("TEST visible Mead rows=" + list.Count + ": " + string.Join(", ", list))); } ManualLogSource? testLog2 = TestLog; if (testLog2 != null) { testLog2.LogInfo((object)("TEST ready: " + (Object.op_Implicit((Object)(object)val13) ? "Mead Cauldron" : "Cauldron fallback") + " menu requested (visible=" + (Object.op_Implicit((Object)(object)instance.m_inventoryRoot) && ((Component)instance.m_inventoryRoot).gameObject.activeInHierarchy) + ", recipes=" + Entries(instance).Count() + "); player is " + Vector3.Distance(((Component)player).transform.position, ((Component)val15).transform.position) + "m from station; fire pit beneath Mead Cauldron and Food Preparation Table under a roof nearby.")); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"TEST could not find a Cauldron or Mead Cauldron."); } yield return null; } private static GameObject? SpawnTestPiece(string prefabName, Vector3 position, float yaw = 0f) { //IL_0017: 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) GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); if (!Object.op_Implicit((Object)(object)prefab)) { return null; } GameObject obj = Object.Instantiate<GameObject>(prefab, position, Quaternion.Euler(0f, yaw, 0f)); WearNTear component = obj.GetComponent<WearNTear>(); FieldInfo fieldInfo = AccessTools.Field(typeof(WearNTear), "m_noSupportWear"); if ((object)fieldInfo != null) { fieldInfo.SetValue(component, true); return obj; } return obj; } private static void Apply(InventoryGui gui, bool resetScroll = false) { //IL_0156: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)gui)) { return; } List<Entry> list = Entries(gui).ToList(); if (!gui.InCraftTab()) { HideFoodEntries(list); HideBar(gui); return; } RectTransform recipeListRoot = gui.m_recipeListRoot; if (!Object.op_Implicit((Object)(object)recipeListRoot)) { return; } if (!IsFoodStation(gui, list, out var preparationStation)) { HideFoodEntries(list); HideBar(gui); return; } List<Entry> list2 = list.Where((Entry entry) => IsFood(entry.Item) && BelongsToStation(entry.Recipe, preparationStation)).ToList(); if (list2.Count == 0) { HideBar(gui); return; } FilterBar bar = GetOrCreateBar(gui, recipeListRoot, preparationStation, list); if (list.Count == 0) { return; } List<Entry> list3 = (from entry in list2 where bar.Current == FoodFilter.All || (!IsUnfilteredOnly(entry.Item) && Matches(entry.Item, bar.Current)) orderby Score(entry.Item, bar.Current) descending select entry).Concat(list.Where((Entry entry) => bar.Current == FoodFilter.All && !IsFood(entry.Item))).ToList(); foreach (Entry item in list) { item.Element.SetActive(list3.Contains(item)); } for (int num = 0; num < list3.Count; num++) { RectTransform component = list3[num].Element.GetComponent<RectTransform>(); if (!OriginalRowPositions.ContainsKey(component)) { OriginalRowPositions[component] = component.anchoredPosition; } if (!OriginalRowSizes.ContainsKey(component)) { OriginalRowSizes[component] = component.sizeDelta; } Vector2 val = OriginalRowPositions[component]; Vector2 sizeDelta = OriginalRowSizes[component]; component.anchoredPosition = new Vector2(val.x, (float)(-num) * gui.m_recipeListSpace); component.sizeDelta = sizeDelta; } recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max((float)list3.Count * gui.m_recipeListSpace, 30f)); if (resetScroll) { gui.m_recipeListScroll.value = 1f; } SetButtonColors(bar); PositionBar(gui, bar, recipeListRoot); } private static void HideFoodEntries(IEnumerable<Entry> entries) { foreach (Entry entry in entries) { if (IsFood(entry.Item)) { entry.Element.SetActive(false); } } } private unsafe static FilterBar GetOrCreateBar(InventoryGui gui, RectTransform list, bool preparationStation, IReadOnlyCollection<Entry> entries) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) if (Bars.TryGetValue(gui, out FilterBar value) && Object.op_Implicit((Object)(object)value.Root) && value.PreparationStation == preparationStation) { ((Component)value.Root).gameObject.SetActive(true); return value; } if (Object.op_Implicit((Object)(object)value?.Root)) { Object.Destroy((Object)(object)((Component)value.Root).gameObject); } FilterBar filterBar = new FilterBar { PreparationStation = preparationStation }; GameObject val = new GameObject("Food Category Filters", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); filterBar.Root = val.GetComponent<RectTransform>(); filterBar.CraftTabTemplate = FindNativeTabImage(gui, "m_tabCraft"); filterBar.UpgradeTabTemplate = FindNativeTabImage(gui, "m_tabUpgrade"); if (!Object.op_Implicit((Object)(object)filterBar.CraftTabTemplate) || !Object.op_Implicit((Object)(object)filterBar.UpgradeTabTemplate)) { FindNativeTabTemplates(gui, out filterBar.CraftTabTemplate, out filterBar.UpgradeTabTemplate); } Image? craftTabTemplate = filterBar.CraftTabTemplate; object obj = ((craftTabTemplate != null) ? craftTabTemplate.sprite : null); if (obj == null) { Image? upgradeTabTemplate = filterBar.UpgradeTabTemplate; obj = ((upgradeTabTemplate != null) ? upgradeTabTemplate.sprite : null) ?? FindNativeTabSprite(gui); } filterBar.TabSprite = (Sprite?)obj; filterBar.Root.anchorMin = new Vector2(0f, 1f); filterBar.Root.anchorMax = new Vector2(0f, 1f); filterBar.Root.pivot = new Vector2(0f, 1f); List<FoodFilter> list2 = new List<FoodFilter> { FoodFilter.Health, FoodFilter.Stamina, FoodFilter.Eitr, FoodFilter.Balanced }; if (preparationStation) { list2.Add(FoodFilter.Feast); } filterBar.Root.sizeDelta = new Vector2(58f, 4f + (float)list2.Count * 24f + (float)(list2.Count - 1) * 1f); Canvas componentInParent = ((Component)gui).GetComponentInParent<Canvas>(); RectTransform val2 = (RectTransform)(Object.op_Implicit((Object)(object)componentInParent) ? /*isinst with value type is only supported in some contexts*/: null); val.transform.SetParent((Transform)(Object.op_Implicit((Object)(object)val2) ? ((object)val2) : ((object)((Transform)list).parent)), false); Image component = val.GetComponent<Image>(); Image? obj2 = filterBar.UpgradeTabTemplate ?? filterBar.CraftTabTemplate; CopyTabStyle(obj2, component); Image val3 = component; if (val3.sprite == null) { Sprite val4 = (val3.sprite = filterBar.TabSprite); } int num; if (Object.op_Implicit((Object)(object)component.sprite)) { Vector4 border = component.sprite.border; if (((Vector4)(ref border)).sqrMagnitude > 0f) { num = 1; goto IL_0297; } } num = 0; goto IL_0297; IL_0297: component.type = (Type)num; if (!Object.op_Implicit((Object)(object)obj2)) { ((Graphic)component).color = new Color(0.5f, 0.36f, 0.22f, 1f); } ((Graphic)component).raycastTarget = false; VerticalLayoutGroup obj3 = val.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj3).padding = new RectOffset(3, 3, 3, 3); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 1f; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; Outline obj4 = val.AddComponent<Outline>(); ((Shadow)obj4).effectColor = new Color(0.76f, 0.4f, 0.1f, 0.9f); ((Shadow)obj4).effectDistance = new Vector2(1f, -1f); foreach (FoodFilter item in list2) { filterBar.Buttons[item] = CreateButton(filterBar, item); } Bars[gui] = filterBar; PositionBar(gui, filterBar, list); gui.m_recipeListScroll.value = 1f; Vector2 val5 = RectTransformUtility.WorldToScreenPoint(Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.worldCamera : null, ((Transform)filterBar.Root).position); ManualLogSource? testLog = TestLog; if (testLog != null) { string[] obj5 = new string[11] { "Food Categories: created ", filterBar.Buttons.Count.ToString(), " filters for ", preparationStation ? "Food Preparation Station" : "Cauldron", "; available rows=", Entries(gui).Count().ToString(), "; parent=", null, null, null, null }; Transform parent = val.transform.parent; obj5[7] = ((parent != null) ? ((Object)parent).name : null); obj5[8] = "; screen position="; Vector2 val6 = val5; obj5[9] = ((object)(*(Vector2*)(&val6))/*cast due to .constrained prefix*/).ToString(); obj5[10] = "."; testLog.LogInfo((object)string.Concat(obj5)); } return filterBar; } private static void PositionBar(InventoryGui gui, FilterBar bar, RectTransform list) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_018d: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)gui).GetComponentInParent<Canvas>(); Canvas val = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.rootCanvas : null); RectTransform val2 = (RectTransform)(Object.op_Implicit((Object)(object)val) ? /*isinst with value type is only supported in some contexts*/: null); if (Object.op_Implicit((Object)(object)val2)) { Camera val3 = (Object.op_Implicit((Object)(object)val) ? val.worldCamera : null); Transform parent = ((Transform)list).parent; RectTransform val4 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!Object.op_Implicit((Object)(object)val4)) { val4 = list; } Vector3[] array = (Vector3[])(object)new Vector3[4]; val4.GetWorldCorners(array); Vector2 val5 = RectTransformUtility.WorldToScreenPoint(val3, array[1]); object obj = (Object.op_Implicit((Object)(object)gui.m_crafting) ? ((object)gui.m_crafting) : ((object)list)); Vector3[] array2 = (Vector3[])(object)new Vector3[4]; ((RectTransform)obj).GetWorldCorners(array2); Vector2 val6 = RectTransformUtility.WorldToScreenPoint(val3, array2[1]); Rect rect = bar.Root.rect; float num = ((Rect)(ref rect)).width * val.scaleFactor; Vector2 val7 = default(Vector2); ((Vector2)(ref val7))..ctor(val6.x - num - 2f, val5.y - 58f); RectTransform val8 = FindRepairRect(gui); if (Object.op_Implicit((Object)(object)val8)) { Vector3[] array3 = (Vector3[])(object)new Vector3[4]; val8.GetWorldCorners(array3); Vector2 val9 = RectTransformUtility.WorldToScreenPoint(val3, array3[0]); val7.y = val9.y - 8f; } float y = val7.y; rect = bar.Root.rect; val7.y = Mathf.Clamp(y, ((Rect)(ref rect)).height + 4f, (float)Screen.height - 6f); Vector3 position = default(Vector3); if (RectTransformUtility.ScreenPointToWorldPointInRectangle(val2, val7, val3, ref position)) { ((Transform)bar.Root).position = position; } } } private static Image? FindNativeTabImage(InventoryGui gui, string fieldName) { object obj = AccessTools.Field(typeof(InventoryGui), fieldName)?.GetValue(gui); if (obj == null) { return null; } Image val = (Image)((obj is Image) ? obj : null); if (val != null) { return val; } Button val2 = (Button)((obj is Button) ? obj : null); if (val2 != null) { Graphic targetGraphic = ((Selectable)val2).targetGraphic; return (Image?)(((object)((targetGraphic is Image) ? targetGraphic : null)) ?? ((object)((Component)val2).GetComponent<Image>())); } Component val3 = (Component)((obj is Component) ? obj : null); if (val3 != null) { Button componentInChildren = val3.GetComponentInChildren<Button>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { Graphic targetGraphic2 = ((Selectable)componentInChildren).targetGraphic; Image val4 = (Image)(object)((targetGraphic2 is Image) ? targetGraphic2 : null); if (val4 != null) { return val4; } } return val3.GetComponentInChildren<Image>(true); } GameObject val5 = (GameObject)((obj is GameObject) ? obj : null); if (val5 != null) { Button componentInChildren2 = val5.GetComponentInChildren<Button>(true); if (Object.op_Implicit((Object)(object)componentInChildren2)) { Graphic targetGraphic3 = ((Selectable)componentInChildren2).targetGraphic; Image val6 = (Image)(object)((targetGraphic3 is Image) ? targetGraphic3 : null); if (val6 != null) { return val6; } } return val5.GetComponentInChildren<Image>(true); } FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { object value = fields[i].GetValue(obj); Image val7 = (Image)((value is Image) ? value : null); if (val7 != null) { return val7; } Button val8 = (Button)((value is Button) ? value : null); if (val8 != null) { Graphic targetGraphic4 = ((Selectable)val8).targetGraphic; Image val9 = (Image)(object)((targetGraphic4 is Image) ? targetGraphic4 : null); if (val9 != null) { return val9; } } Component val10 = (Component)((value is Component) ? value : null); if (val10 != null) { Button componentInChildren3 = val10.GetComponentInChildren<Button>(true); if (Object.op_Implicit((Object)(object)componentInChildren3)) { Graphic targetGraphic5 = ((Selectable)componentInChildren3).targetGraphic; Image val11 = (Image)(object)((targetGraphic5 is Image) ? targetGraphic5 : null); if (val11 != null) { return val11; } } Image componentInChildren4 = val10.GetComponentInChildren<Image>(true); if (Object.op_Implicit((Object)(object)componentInChildren4)) { return componentInChildren4; } } GameObject val12 = (GameObject)((value is GameObject) ? value : null); if (val12 == null) { continue; } Button componentInChildren5 = val12.GetComponentInChildren<Button>(true); if (Object.op_Implicit((Object)(object)componentInChildren5)) { Graphic targetGraphic6 = ((Selectable)componentInChildren5).targetGraphic; Image val13 = (Image)(object)((targetGraphic6 is Image) ? targetGraphic6 : null); if (val13 != null) { return val13; } } Image componentInChildren6 = val12.GetComponentInChildren<Image>(true); if (Object.op_Implicit((Object)(object)componentInChildren6)) { return componentInChildren6; } } return null; } private static RectTransform? FindRepairRect(InventoryGui gui) { object obj = AccessTools.Field(typeof(InventoryGui), "m_repairButton")?.GetValue(gui); RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null); if (val != null) { return val; } Component val2 = (Component)((obj is Component) ? obj : null); if (val2 != null) { Transform transform = val2.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val3 != null) { return val3; } } GameObject val4 = (GameObject)((obj is GameObject) ? obj : null); if (val4 != null) { Transform transform2 = val4.transform; RectTransform val5 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); if (val5 != null) { return val5; } } return ((IEnumerable<RectTransform>)((Component)gui).GetComponentsInChildren<RectTransform>(true)).FirstOrDefault((Func<RectTransform, bool>)((RectTransform candidate) => ((Component)candidate).gameObject.activeInHierarchy && ((Object)candidate).name.IndexOf("repair", StringComparison.OrdinalIgnoreCase) >= 0)); } private static void FindNativeTabTemplates(InventoryGui gui, out Image? craft, out Image? upgrade) { craft = null; upgrade = null; Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true); foreach (Button obj in componentsInChildren) { TMP_Text componentInChildren = ((Component)obj).GetComponentInChildren<TMP_Text>(true); Image component = ((Component)obj).GetComponent<Image>(); if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sprite)) { if (componentInChildren.text.IndexOf("Craft", StringComparison.OrdinalIgnoreCase) >= 0 && craft == null) { craft = component; } if (componentInChildren.text.IndexOf("Upgrade", StringComparison.OrdinalIgnoreCase) >= 0 && upgrade == null) { upgrade = component; } if (Object.op_Implicit((Object)(object)craft) && Object.op_Implicit((Object)(object)upgrade)) { break; } } } } private static Sprite? FindNativeTabSprite(InventoryGui gui) { return (from sprite in Resources.FindObjectsOfTypeAll<Sprite>() where Object.op_Implicit((Object)(object)sprite) && (((Object)sprite).name.IndexOf("tab", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sprite).name.IndexOf("woodpanel", StringComparison.OrdinalIgnoreCase) >= 0) orderby (((Object)sprite).name.IndexOf("tab", StringComparison.OrdinalIgnoreCase) < 0) ? 1 : 0 select sprite).FirstOrDefault(); } private static void CopyTabStyle(Image? template, Image target) { //IL_0017: 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) if (Object.op_Implicit((Object)(object)template)) { target.sprite = template.sprite; target.type = template.type; ((Graphic)target).color = ((Graphic)template).color; ((Graphic)target).material = ((Graphic)template).material; target.preserveAspect = template.preserveAspect; target.fillCenter = template.fillCenter; } } private static Button CreateButton(FilterBar bar, FoodFilter filter) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0161: 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_0169: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Food " + filter, new Type[5] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button), typeof(LayoutElement) }); val.transform.SetParent((Transform)(object)bar.Root, false); LayoutElement component = val.GetComponent<LayoutElement>(); component.minWidth = 50f; component.preferredWidth = 50f; component.minHeight = 24f; component.preferredHeight = 24f; component.flexibleHeight = 0f; Image component2 = val.GetComponent<Image>(); CopyTabStyle(bar.UpgradeTabTemplate ?? bar.CraftTabTemplate, component2); Image val2 = component2; if (val2.sprite == null) { Sprite val3 = (val2.sprite = bar.TabSprite); } if (!Object.op_Implicit((Object)(object)bar.UpgradeTabTemplate) && !Object.op_Implicit((Object)(object)bar.CraftTabTemplate)) { ((Graphic)component2).color = new Color(0.5f, 0.36f, 0.22f, 1f); } Button component3 = val.GetComponent<Button>(); ColorBlock colors = ((Selectable)component3).colors; ((ColorBlock)(ref colors)).normalColor = Color.white; ((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 0.9f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.72f, 0.72f, 0.72f, 1f); ((Selectable)component3).colors = colors; CreateNativeFoodIcon(val.transform, filter); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { bar.Current = ((bar.Current != filter) ? filter : FoodFilter.All); Apply(Bars.First<KeyValuePair<InventoryGui, FilterBar>>((KeyValuePair<InventoryGui, FilterBar> pair) => pair.Value == bar).Key, resetScroll: true); }); return component3; } private static void CreateNativeFoodIcon(Transform parent, FoodFilter filter) { //IL_0087: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) Sprite[] source = Resources.FindObjectsOfTypeAll<Sprite>(); Sprite sprite = ((IEnumerable<Sprite>)source).FirstOrDefault((Func<Sprite, bool>)((Sprite candidate) => ((Object)candidate).name.Equals("food_icon", StringComparison.OrdinalIgnoreCase))) ?? ((IEnumerable<Sprite>)source).FirstOrDefault((Func<Sprite, bool>)((Sprite candidate) => ((Object)candidate).name.Equals("food_icon", StringComparison.OrdinalIgnoreCase))); GameObject val = new GameObject("Valheim Food Icon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(17f, 17f); Image component2 = val.GetComponent<Image>(); component2.sprite = sprite; ((Graphic)component2).color = FilterColor(filter); component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; } private static void SetButtonColors(FilterBar bar) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<FoodFilter, Button> button in bar.Buttons) { Image component = ((Component)button.Value).GetComponent<Image>(); bool flag = button.Key == bar.Current; CopyTabStyle(flag ? bar.CraftTabTemplate : bar.UpgradeTabTemplate, component); if (!Object.op_Implicit((Object)(object)component.sprite)) { component.sprite = bar.TabSprite; } if (flag && !Object.op_Implicit((Object)(object)bar.CraftTabTemplate)) { ((Graphic)component).color = new Color(1f, 0.58f, 0.12f, 1f); } if (!flag && !Object.op_Implicit((Object)(object)bar.UpgradeTabTemplate) && !Object.op_Implicit((Object)(object)bar.CraftTabTemplate)) { ((Graphic)component).color = new Color(0.5f, 0.36f, 0.22f, 1f); } Outline obj = ((Component)button.Value).GetComponent<Outline>() ?? ((Component)button.Value).gameObject.AddComponent<Outline>(); ((Behaviour)obj).enabled = flag; ((Shadow)obj).effectColor = new Color(1f, 0.42f, 0.06f, 1f); ((Shadow)obj).effectDistance = new Vector2(3f, -3f); Transform obj2 = ((Component)button.Value).transform.Find("Valheim Food Icon"); Image val = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); if (Object.op_Implicit((Object)(object)val)) { ((Graphic)val).rectTransform.sizeDelta = (flag ? new Vector2(21f, 21f) : new Vector2(17f, 17f)); } } } private static IEnumerable<Entry> Entries(InventoryGui gui) { if (!(AccessTools.Field(typeof(InventoryGui), "m_availableRecipes")?.GetValue(gui) is IEnumerable enumerable)) { yield break; } foreach (object item in enumerable) { if (item == null) { continue; } Type type = item.GetType(); object? obj = AccessTools.Property(type, "Recipe")?.GetValue(item); Recipe val = (Recipe)((obj is Recipe) ? obj : null); object? obj2 = AccessTools.Property(type, "ItemData")?.GetValue(item); ItemData val2 = (ItemData)(((obj2 is ItemData) ? obj2 : null) ?? val?.m_item?.m_itemData); object? obj3 = AccessTools.Property(type, "InterfaceElement")?.GetValue(item); GameObject val3 = (GameObject)((obj3 is GameObject) ? obj3 : null); if (!((Object)(object)val != (Object)null) || val2 == null || !((Object)(object)val3 != (Object)null)) { continue; } ItemData val4 = val.m_item?.m_itemData; if (Environment.GetEnvironmentVariable("FOOD_CATEGORIES_MANUAL_TEST") == "1" && val4 != null && IsFood(val2)) { string name = val2.m_shared.m_name; if (!string.IsNullOrEmpty(name) && AuditedRows.Add(name)) { Debug.Log((object)("Food Categories actual row: " + name + "=" + Classify(val2).ToString() + " HP=" + val2.m_shared.m_food + " stamina=" + val2.m_shared.m_foodStamina + " eitr=" + val2.m_shared.m_foodEitr + "; recipe data=" + val4.m_shared.m_food + "/" + val4.m_shared.m_foodStamina + "/" + val4.m_shared.m_foodEitr)); } } yield return new Entry { Recipe = val, Item = val2, Element = val3 }; } } private static bool BelongsToStation(Recipe recipe, bool preparationStation) { string text = RecipeStationName(recipe); if (preparationStation) { if (!text.Contains("preparation")) { return text.Contains("preptable"); } return true; } return text.Contains("cauldron"); } private static string RecipeStationName(Recipe recipe) { return AccessTools.Field(typeof(Recipe), "m_craftingStation")?.GetValue(recipe)?.ToString()?.ToLowerInvariant() ?? string.Empty; } private static bool IsFood(ItemData item) { (item.m_shared.m_name + " " + (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : string.Empty)).ToLowerInvariant(); if (IsMead(item)) { return false; } if (!IsFeast(item) && !(item.m_shared.m_food > 0f) && !(item.m_shared.m_foodStamina > 0f)) { return item.m_shared.m_foodEitr > 0f; } return true; } private static bool IsMead(ItemData item) { if (!item.m_shared.m_name.StartsWith("$item_mead", StringComparison.OrdinalIgnoreCase)) { if (Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)item.m_dropPrefab).name.StartsWith("Mead", StringComparison.OrdinalIgnoreCase); } return false; } return true; } private static bool IsUnfilteredOnly(ItemData item) { if (!item.m_shared.m_name.Equals("$item_fish_raw", StringComparison.OrdinalIgnoreCase) && item.m_shared.m_name.IndexOf("bait", StringComparison.OrdinalIgnoreCase) < 0) { if (Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)item.m_dropPrefab).name.IndexOf("bait", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } return true; } private static bool IsFeast(ItemData item) { if (item.m_shared.m_name.Equals("$item_feaster", StringComparison.OrdinalIgnoreCase) || (Object.op_Implicit((Object)(object)item.m_dropPrefab) && ((Object)item.m_dropPrefab).name.Equals("Feaster", StringComparison.OrdinalIgnoreCase))) { return false; } if (item.m_shared.m_name.IndexOf("feast", StringComparison.OrdinalIgnoreCase) < 0) { if (Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)item.m_dropPrefab).name.IndexOf("feast", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } return true; } private static FoodFilter Classify(ItemData item) { if (IsFeast(item)) { return FoodFilter.Feast; } string text = (item.m_shared.m_name + " " + (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : string.Empty)).ToLowerInvariant(); if (text.Contains("misthare")) { return FoodFilter.Health; } if (text.Contains("sweetbread") || text.Contains("vikingcupcake")) { return FoodFilter.Balanced; } if (text.Contains("bakedpoteitr_uncooked")) { return FoodFilter.Health; } if (text.Contains("ovenpancake_uncooked") || text.Contains("ovenpancakebatter")) { return FoodFilter.Health; } if (text.Contains("roastedcrustpie_uncooked")) { return FoodFilter.Stamina; } if (text.Contains("kalechips_uncooked")) { return FoodFilter.Health; } float food = item.m_shared.m_food; float foodStamina = item.m_shared.m_foodStamina; float foodEitr = item.m_shared.m_foodEitr; if (food <= 0f && foodStamina <= 0f && foodEitr > 0f) { return FoodFilter.Eitr; } if (food > 0f && foodStamina > 0f) { float num = Mathf.Max(food, foodStamina); if (Mathf.Abs(food - foodStamina) <= num * 0.2f) { return FoodFilter.Balanced; } } if (foodEitr > 0f) { return FoodFilter.Eitr; } if (!(food > foodStamina)) { return FoodFilter.Stamina; } return FoodFilter.Health; } private static bool Matches(ItemData item, FoodFilter filter) { if (filter == FoodFilter.All) { return true; } return Classify(item) == filter; } private static float Score(ItemData item, FoodFilter filter) { return filter switch { FoodFilter.Health => item.m_shared.m_food, FoodFilter.Stamina => item.m_shared.m_foodStamina, FoodFilter.Eitr => item.m_shared.m_foodEitr, FoodFilter.Balanced => item.m_shared.m_food + item.m_shared.m_foodStamina, FoodFilter.Feast => 1f, _ => 0f, }; } private static Color FilterColor(FoodFilter filter) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0049: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) return (Color)(filter switch { FoodFilter.Health => new Color(0.82f, 0.16f, 0.12f), FoodFilter.Stamina => new Color(0.95f, 0.72f, 0.12f), FoodFilter.Eitr => new Color(0.18f, 0.53f, 0.95f), FoodFilter.Feast => new Color(0.55f, 0.28f, 0.82f), _ => new Color(0.58f, 0.58f, 0.58f), }); } private static bool IsFoodStation(InventoryGui gui, IReadOnlyCollection<Entry> entries, out bool preparationStation) { preparationStation = false; List<string> list = new List<string>(); if (Object.op_Implicit((Object)(object)gui.m_craftingStationName)) { list.Add(gui.m_craftingStationName.text); } CraftingStation val = (Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Player.m_localPlayer.GetCurrentCraftingStation() : null); if (Object.op_Implicit((Object)(object)val)) { list.Add(((Object)((Component)val).gameObject).name); list.Add(val.m_name); } string text = string.Join(" ", list).ToLowerInvariant(); if (text.Contains("preparation") || text.Contains("preptable")) { preparationStation = true; return true; } if (text.Contains("cauldron") || text.Contains("cooking")) { return true; } if (Object.op_Implicit((Object)(object)val) || list.Any((string candidate) => !string.IsNullOrWhiteSpace(candidate))) { return false; } bool flag = entries.Any((Entry entry) => IsFood(entry.Item) && BelongsToStation(entry.Recipe, preparationStation: true)); bool flag2 = entries.Any((Entry entry) => IsFood(entry.Item) && BelongsToStation(entry.Recipe, preparationStation: false)); if (flag || flag2) { preparationStation = flag && !flag2; return true; } return false; } private static void HideBar(InventoryGui gui) { if (Bars.TryGetValue(gui, out FilterBar value) && Object.op_Implicit((Object)(object)value.Root)) { ((Component)value.Root).gameObject.SetActive(false); } } } }