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 WorkbenchSearchFilters v1.1.0
WorkbenchSearchFilters.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; 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: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WorkbenchSearchFilters")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+a34a8b094cf2ae13d83be2405df58ccfe10f51eb")] [assembly: AssemblyProduct("WorkbenchSearchFilters")] [assembly: AssemblyTitle("WorkbenchSearchFilters")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WorkbenchSearchFilters { internal enum Category { All, Weapons, Armor, Tools, Consumables, Materials, Misc, FoodStamina, FoodHealth, FoodEitr, FoodBalanced, Meads } internal static class Categories { internal static readonly int Count = Enum.GetValues(typeof(Category)).Length; internal static readonly Category[] Crafting = new Category[7] { Category.All, Category.Weapons, Category.Armor, Category.Tools, Category.Consumables, Category.Materials, Category.Misc }; internal static readonly Category[] Food = new Category[7] { Category.All, Category.FoodHealth, Category.FoodStamina, Category.FoodEitr, Category.FoodBalanced, Category.Meads, Category.Misc }; internal static readonly Category[] Buttons = Crafting.Concat(Food).Distinct().ToArray(); internal static readonly string ReportPath = Path.Combine(Paths.ConfigPath, "WorkbenchSearchFilters.adrirf7.Categories.txt"); private static readonly Dictionary<ItemDrop, Category> s_cache = new Dictionary<ItemDrop, Category>(); private static readonly Dictionary<ItemDrop, Category> s_foodCache = new Dictionary<ItemDrop, Category>(); private static Dictionary<string, Category> s_overrides; private static HashSet<string> s_foodIngredients; private static Dictionary<string, ItemDrop> s_cookedResults; private static HashSet<string> s_fermenterInputs; internal static Category[] ForStation(bool foodStation) { if (!foodStation) { return Crafting; } return Food; } internal static bool IsFoodStation(CraftingStation station) { if ((Object)(object)station == (Object)null) { return false; } string text = (station.m_name + " " + ((Object)((Component)station).gameObject).name).ToLowerInvariant(); if (!text.Contains("cauldron")) { return text.Contains("preptable"); } return true; } internal static string Token(Category category) { return "$wsf_cat_" + category.ToString().ToLowerInvariant(); } internal static string[] IconPrefabs(Category category) { return category switch { Category.Weapons => new string[3] { "SwordIron", "SwordBronze", "AxeBronze" }, Category.Armor => new string[3] { "ShieldBanded:1", "ArmorBronzeChest", "HelmetBronze" }, Category.Tools => new string[3] { "Hammer", "PickaxeIron", "Hoe" }, Category.Consumables => new string[2] { "MeadHealthMinor", "CookedMeat" }, Category.Materials => new string[3] { "Bronze", "Iron", "Wood" }, Category.Misc => new string[2] { "Coins", "Wishbone" }, Category.Meads => new string[2] { "MeadBaseHealthMinor", "MeadHealthMinor" }, _ => new string[0], }; } internal static Color? FoodColor(Category category) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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) return category switch { Category.FoodStamina => new Color(1f, 0.85f, 0.25f, 1f), Category.FoodHealth => new Color(1f, 0.35f, 0.35f, 1f), Category.FoodEitr => new Color(0.75f, 0.45f, 1f, 1f), Category.FoodBalanced => Color.white, _ => null, }; } internal static void ResetCache() { s_cache.Clear(); s_foodCache.Clear(); s_overrides = null; s_foodIngredients = null; s_cookedResults = null; s_fermenterInputs = null; } internal static Category Classify(ItemDrop item, bool foodStation) { Dictionary<ItemDrop, Category> dictionary = (foodStation ? s_foodCache : s_cache); if (!dictionary.TryGetValue(item, out var value)) { value = (dictionary[item] = (foodStation ? ClassifyFood(item) : ClassifyUncached(item))); } return value; } private static Category ClassifyFood(ItemDrop item) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Invalid comparison between Unknown and I4 if (GetOverrides().TryGetValue(((Object)item).name, out var value) && Food.Contains(value)) { return value; } SharedData shared = item.m_itemData.m_shared; SharedData val = FoodStats(item); if (val.m_food > 0f || val.m_foodStamina > 0f || val.m_foodEitr > 0f) { if (val.m_food < val.m_foodEitr / 2f && val.m_foodStamina < val.m_foodEitr / 2f) { return Category.FoodEitr; } if (val.m_foodStamina < val.m_food / 2f) { return Category.FoodHealth; } if (val.m_food < val.m_foodStamina / 2f) { return Category.FoodStamina; } return Category.FoodBalanced; } if ((s_fermenterInputs != null && s_fermenterInputs.Contains(((Object)item).name)) || shared.m_isDrink || (int)shared.m_itemType == 2) { return Category.Meads; } return Category.Misc; } private static SharedData FoodStats(ItemDrop item) { GetFoodIngredients(); if (s_cookedResults != null && s_cookedResults.TryGetValue(((Object)item).name, out var value) && (Object)(object)value != (Object)null) { return value.m_itemData.m_shared; } return item.m_itemData.m_shared; } internal static float FoodSortValue(ItemDrop item, Category category) { switch (category) { case Category.FoodHealth: return FoodStats(item).m_food; case Category.FoodStamina: return FoodStats(item).m_foodStamina; case Category.FoodEitr: return FoodStats(item).m_foodEitr; case Category.FoodBalanced: { SharedData val = FoodStats(item); return val.m_food + val.m_foodStamina; } default: return 0f; } } internal static bool IsFoodType(Category category) { if (category != Category.FoodHealth && category != Category.FoodStamina && category != Category.FoodEitr) { return category == Category.FoodBalanced; } return true; } private static Category ClassifyUncached(ItemDrop item) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected I4, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Invalid comparison between Unknown and I4 //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Invalid comparison between Unknown and I4 //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Invalid comparison between Unknown and I4 if (GetOverrides().TryGetValue(((Object)item).name, out var value) && Crafting.Contains(value)) { return value; } SharedData shared = item.m_itemData.m_shared; ItemType itemType = shared.m_itemType; if ((int)itemType == 9 || (int)itemType == 23) { return Category.Consumables; } if (shared.m_attack != null && shared.m_attack.m_consumeItem) { return Category.Consumables; } if ((int)itemType == 2 || shared.m_isDrink || shared.m_food > 0f || shared.m_foodStamina > 0f || shared.m_foodEitr > 0f) { return Category.Consumables; } if (GetFoodIngredients().Contains(((Object)item).name)) { return Category.Consumables; } switch (itemType - 1) { case 2: case 3: case 13: case 19: case 21: if ((int)shared.m_skillType == 12 || (int)shared.m_skillType == 104) { return Category.Tools; } if ((int)itemType != 4 && ((DamageTypes)(ref shared.m_damages)).GetTotalDamage() <= 0f) { return Category.Misc; } return Category.Weapons; case 4: case 5: case 6: case 10: case 11: case 16: case 17: case 23: return Category.Armor; case 14: case 18: return Category.Tools; case 0: return Category.Materials; default: return Category.Misc; } } private static Dictionary<string, Category> GetOverrides() { if (s_overrides != null) { return s_overrides; } s_overrides = new Dictionary<string, Category>(StringComparer.OrdinalIgnoreCase); string[] array = WorkbenchSearchFiltersPlugin.CategoryOverrides.Value.Split(','); foreach (string text in array) { string[] array2 = text.Split(':'); if (array2.Length == 2) { string text2 = array2[0].Trim(); if (text2.Length > 0 && Enum.TryParse<Category>(array2[1].Trim(), ignoreCase: true, out var result) && result != Category.All) { s_overrides[text2] = result; } else { WorkbenchSearchFiltersPlugin.Log.LogWarning((object)("Invalid category override: '" + text.Trim() + "'")); } } } return s_overrides; } private static HashSet<string> GetFoodIngredients() { if (s_foodIngredients != null) { return s_foodIngredients; } HashSet<string> hashSet = new HashSet<string>(); if ((Object)(object)ZNetScene.instance == (Object)null) { return hashSet; } Dictionary<string, ItemDrop> dictionary = new Dictionary<string, ItemDrop>(); HashSet<string> hashSet2 = new HashSet<string>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } CookingStation component = prefab.GetComponent<CookingStation>(); if ((Object)(object)component != (Object)null) { foreach (ItemConversion item in component.m_conversion) { if ((Object)(object)item?.m_from != (Object)null) { hashSet.Add(((Object)item.m_from).name); if ((Object)(object)item.m_to != (Object)null) { dictionary[((Object)item.m_from).name] = item.m_to; } } } } Fermenter component2 = prefab.GetComponent<Fermenter>(); if (!((Object)(object)component2 != (Object)null)) { continue; } foreach (ItemConversion item2 in component2.m_conversion) { if ((Object)(object)item2?.m_from != (Object)null) { hashSet.Add(((Object)item2.m_from).name); hashSet2.Add(((Object)item2.m_from).name); } } } s_foodIngredients = hashSet; s_cookedResults = dictionary; s_fermenterInputs = hashSet2; return hashSet; } internal static void WriteReport() { //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ObjectDB.instance == (Object)null) { return; } try { var list = (from item in (from recipe in ObjectDB.instance.m_recipes where (Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && recipe.m_enabled select recipe.m_item).Distinct() select new { Category = Classify(item, foodStation: false), Prefab = ((Object)item).name, Name = Localization.instance.Localize(item.m_itemData.m_shared.m_name), Type = item.m_itemData.m_shared.m_itemType } into row orderby row.Category, row.Name select row).ToList(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Category of every craftable item, as shown by WorkbenchSearchFilters."); stringBuilder.AppendLine("# Regenerated every time you enter a world. To move an item, add 'Prefab:Category' to"); stringBuilder.AppendLine("# CategoryOverrides in WorkbenchSearchFilters.adrirf7.cfg (categories: " + string.Join(", ", Crafting.Where((Category c) => c != Category.All)) + ";"); stringBuilder.AppendLine("# at the cauldron and the food preparation table: " + string.Join(", ", Food.Where((Category c) => c != Category.All)) + ")."); Category? category = null; foreach (var item in list) { if (category != item.Category) { category = item.Category; stringBuilder.AppendLine(); stringBuilder.AppendLine("[" + item.Category.ToString() + "]"); } stringBuilder.AppendLine(item.Prefab.PadRight(32) + " " + item.Name.PadRight(32) + " (" + ((object)item.Type/*cast due to .constrained prefix*/).ToString() + ")"); } File.WriteAllText(ReportPath, stringBuilder.ToString(), Encoding.UTF8); } catch (Exception ex) { WorkbenchSearchFiltersPlugin.Log.LogWarning((object)("Could not write " + ReportPath + ": " + ex.Message)); } } } internal static class FilterBar { private sealed class CategoryButton { public Category Category; public Image Background; public Graphic Content; public Color ContentColor; } private struct Entry { public RecipeDataPair Pair; public Category Category; public string Name; public float FoodValue; } private const float SearchHeight = 26f; private const float ButtonsHeight = 28f; private const float Gap = 3f; private const float BarHeight = 60f; private static readonly Color s_buttonColor = new Color(0f, 0f, 0f, 0.55f); private static readonly Color s_selectedColor = new Color(0.85f, 0.6f, 0.2f, 0.9f); private const float EmptyIconAlpha = 0.3f; private static GameObject s_root; private static InventoryGui s_gui; private static RectTransform s_list; private static RectTransform s_scrollbar; private static TMP_InputField s_search; private static TMP_Text s_allLabel; private static readonly List<CategoryButton> s_buttons = new List<CategoryButton>(); internal static Category CurrentCategory = Category.All; private static Category s_activeCategory = Category.All; internal static string SearchText = ""; private static bool s_foodStation; private static bool? s_buttonsFoodStation; private static readonly List<Entry> s_entries = new List<Entry>(); internal static bool IsSearchFocused { get { if ((Object)(object)s_search != (Object)null) { return s_search.isFocused; } return false; } } internal static void EnsureCreated(InventoryGui gui) { if ((Object)(object)s_root != (Object)null) { return; } try { Categories.ResetCache(); Create(gui); RefreshTexts(); Categories.WriteReport(); } catch (Exception ex) { WorkbenchSearchFiltersPlugin.Log.LogError((object)("Could not create the crafting filter bar: " + ex)); if ((Object)(object)s_root != (Object)null) { Object.Destroy((Object)(object)s_root); } s_root = null; } } internal static void Teardown() { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_search != (Object)null && s_search.isFocused) { s_search.DeactivateInputField(false); } foreach (Entry s_entry in s_entries) { Entry current = s_entry; if ((Object)(object)((RecipeDataPair)(ref current.Pair)).InterfaceElement != (Object)null && !((RecipeDataPair)(ref current.Pair)).InterfaceElement.activeSelf) { Object.Destroy((Object)(object)((RecipeDataPair)(ref current.Pair)).InterfaceElement); } } s_entries.Clear(); if ((Object)(object)s_root != (Object)null && (Object)(object)s_gui != (Object)null) { Object.Destroy((Object)(object)s_root); if ((Object)(object)s_list != (Object)null) { RectTransform obj = s_list; obj.offsetMax += new Vector2(0f, 60f); } if ((Object)(object)s_scrollbar != (Object)null) { RectTransform obj2 = s_scrollbar; obj2.offsetMax += new Vector2(0f, 60f); } InventoryGui obj3 = s_gui; obj3.m_recipeListBaseSize += 60f; if (InventoryGui.IsVisible() && (Object)(object)Player.m_localPlayer != (Object)null) { s_gui.UpdateCraftingPanel(false); } } s_root = null; s_gui = null; s_list = null; s_scrollbar = null; s_search = null; s_allLabel = null; s_buttons.Clear(); s_buttonsFoodStation = null; } internal static void BeforeGameRebuild(InventoryGui gui) { foreach (Entry s_entry in s_entries) { Entry current = s_entry; if ((Object)(object)((RecipeDataPair)(ref current.Pair)).InterfaceElement != (Object)null && !((RecipeDataPair)(ref current.Pair)).InterfaceElement.activeSelf) { Object.Destroy((Object)(object)((RecipeDataPair)(ref current.Pair)).InterfaceElement); } } s_entries.Clear(); } internal static void AfterGameRebuild(InventoryGui gui) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) s_entries.Clear(); s_foodStation = Categories.IsFoodStation(((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetCurrentCraftingStation() : null); foreach (RecipeDataPair availableRecipe in gui.m_availableRecipes) { RecipeDataPair current = availableRecipe; Category category = Categories.Classify(((RecipeDataPair)(ref current)).Recipe.m_item, s_foodStation); s_entries.Add(new Entry { Pair = current, Category = category, Name = Localization.instance.Localize(((RecipeDataPair)(ref current)).Recipe.m_item.m_itemData.m_shared.m_name), FoodValue = Categories.FoodSortValue(((RecipeDataPair)(ref current)).Recipe.m_item, category) }); } ApplyFilter(gui); } private static void SyncWithGame(InventoryGui gui) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) List<RecipeDataPair> availableRecipes = gui.m_availableRecipes; HashSet<GameObject> hashSet = new HashSet<GameObject>(); foreach (RecipeDataPair item in availableRecipes) { RecipeDataPair current = item; if ((Object)(object)((RecipeDataPair)(ref current)).InterfaceElement != (Object)null) { hashSet.Add(((RecipeDataPair)(ref current)).InterfaceElement); } } int num = 0; bool flag = hashSet.Count == availableRecipes.Count; foreach (Entry s_entry in s_entries) { Entry current2 = s_entry; GameObject interfaceElement = ((RecipeDataPair)(ref current2.Pair)).InterfaceElement; if (!flag) { break; } if (!((Object)(object)interfaceElement == (Object)null) && interfaceElement.activeSelf) { num++; flag = hashSet.Contains(interfaceElement); } } if (flag && num == availableRecipes.Count) { return; } foreach (Entry s_entry2 in s_entries) { Entry current3 = s_entry2; GameObject interfaceElement2 = ((RecipeDataPair)(ref current3.Pair)).InterfaceElement; if ((Object)(object)interfaceElement2 != (Object)null && !hashSet.Contains(interfaceElement2)) { Object.Destroy((Object)(object)interfaceElement2); } } AfterGameRebuild(gui); } private static void ApplyFilter(InventoryGui gui) { //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) List<RecipeDataPair> availableRecipes = gui.m_availableRecipes; availableRecipes.Clear(); string text = SearchText.Trim(); int[] array = new int[Categories.Count]; int[] array2 = new int[Categories.Count]; bool[] array3 = new bool[s_entries.Count]; for (int i = 0; i < s_entries.Count; i++) { Category category = s_entries[i].Category; array[0]++; array[(int)category]++; array3[i] = text.Length == 0 || Contains(s_entries[i].Name, text); if (array3[i]) { array2[0]++; array2[(int)category]++; } } s_activeCategory = ((array[(int)CurrentCategory] > 0) ? CurrentCategory : Category.All); int[] array4 = new int[s_entries.Count]; for (int j = 0; j < array4.Length; j++) { array4[j] = j; } if (Categories.IsFoodType(s_activeCategory)) { Array.Sort(array4, delegate(int a, int b) { int num4 = s_entries[b].FoodValue.CompareTo(s_entries[a].FoodValue); return (num4 == 0) ? a.CompareTo(b) : num4; }); } int[] array5 = array4; foreach (int num2 in array5) { Entry entry = s_entries[num2]; bool flag = array3[num2] && (s_activeCategory == Category.All || entry.Category == s_activeCategory); GameObject interfaceElement = ((RecipeDataPair)(ref entry.Pair)).InterfaceElement; if (!((Object)(object)interfaceElement == (Object)null)) { if (interfaceElement.activeSelf != flag) { interfaceElement.SetActive(flag); } if (flag) { ((RectTransform)interfaceElement.transform).anchoredPosition = new Vector2(0f, (float)availableRecipes.Count * (0f - gui.m_recipeListSpace)); availableRecipes.Add(entry.Pair); } } } float num3 = Mathf.Max(gui.m_recipeListBaseSize, (float)availableRecipes.Count * gui.m_recipeListSpace); gui.m_recipeListRoot.SetSizeWithCurrentAnchors((Axis)1, num3); UpdateButtons(array, array2); } private static bool Contains(string text, string term) { return CultureInfo.InvariantCulture.CompareInfo.IndexOf(text, term, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0; } internal static void OnInventoryHidden() { if (WorkbenchSearchFiltersPlugin.ClearSearchOnClose.Value) { SearchText = ""; if ((Object)(object)s_search != (Object)null) { s_search.SetTextWithoutNotify(""); } } if (!WorkbenchSearchFiltersPlugin.RememberCategory.Value) { CurrentCategory = Category.All; } if ((Object)(object)s_search != (Object)null && s_search.isFocused) { s_search.DeactivateInputField(false); } } private static void RefreshRecipes() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && InventoryGui.IsVisible()) { SyncWithGame(instance); ApplyFilter(instance); if (instance.m_availableRecipes.Count == 0) { instance.SetRecipe(-1, false); } else { instance.SetRecipe(((Object)(object)((RecipeDataPair)(ref instance.m_selectedRecipe)).Recipe != (Object)null) ? instance.GetSelectedRecipeIndex(false) : 0, true); } } } internal static void RefreshTexts() { if (!((Object)(object)s_root == (Object)null)) { Graphic placeholder = s_search.placeholder; TMP_Text val = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null); if (val != null) { val.text = Localization.instance.Localize("$wsf_search"); } if ((Object)(object)s_allLabel != (Object)null) { s_allLabel.text = Localization.instance.Localize("$wsf_cat_all"); } } } private static void UpdateButtons(int[] available, int[] matches) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) Category[] array = Categories.ForStation(s_foodStation); if (s_buttonsFoodStation != s_foodStation) { s_buttonsFoodStation = s_foodStation; Category[] array2 = array; foreach (Category category in array2) { CategoryButton? categoryButton = s_buttons.Find((CategoryButton b) => b.Category == category); if (categoryButton != null) { ((Component)categoryButton.Background).transform.SetAsLastSibling(); } } } foreach (CategoryButton s_button in s_buttons) { bool flag = s_button.Category == Category.All || (Array.IndexOf(array, s_button.Category) >= 0 && available[(int)s_button.Category] > 0); GameObject gameObject = ((Component)s_button.Background).gameObject; if (gameObject.activeSelf != flag) { gameObject.SetActive(flag); } ((Graphic)s_button.Background).color = ((s_button.Category == s_activeCategory) ? s_selectedColor : s_buttonColor); Color contentColor = s_button.ContentColor; if (matches[(int)s_button.Category] == 0) { contentColor.a *= 0.3f; } s_button.Content.color = contentColor; } } private static void Create(InventoryGui gui) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) s_buttons.Clear(); s_buttonsFoodStation = null; s_allLabel = null; ScrollRect componentInParent = ((Component)gui.m_recipeListRoot).GetComponentInParent<ScrollRect>(); RectTransform val = (((Object)(object)componentInParent != (Object)null) ? ((RectTransform)((Component)componentInParent).transform) : ((RectTransform)((Transform)gui.m_recipeListRoot).parent)); RectTransform val2 = (RectTransform)((Transform)val).parent; s_root = new GameObject("WSF_FilterArea", new Type[1] { typeof(RectTransform) }); RectTransform val3 = (RectTransform)s_root.transform; ((Transform)val3).SetParent((Transform)(object)val2, false); val3.anchorMin = val.anchorMin; val3.anchorMax = val.anchorMax; val3.pivot = val.pivot; val3.offsetMin = val.offsetMin; val3.offsetMax = val.offsetMax; ((Transform)val3).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1); RectTransform val4 = NewRect("WSF_FilterBar", (Transform)(object)val3); SetTop(val4, 0f, 57f); val.offsetMax -= new Vector2(0f, 60f); s_gui = gui; s_list = val; s_scrollbar = null; RectTransform val5 = ((!((Object)(object)gui.m_recipeListScroll != (Object)null)) ? ((RectTransform)null) : ((RectTransform)((Component)gui.m_recipeListScroll).transform)); if ((Object)(object)val5 != (Object)null && (Object)(object)((Transform)val5).parent == (Object)(object)val2) { val5.offsetMax -= new Vector2(0f, 60f); s_scrollbar = val5; } gui.m_recipeListBaseSize -= 60f; TMP_Text component = ((Component)gui.m_recipeElementPrefab.transform.Find("name")).GetComponent<TMP_Text>(); CreateSearchField(val4, component); CreateCategoryButtons(gui, val4, component); } private static void CreateSearchField(RectTransform bar, TMP_Text referenceText) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown TMP_InputField val = (TMP_InputField)(object)(((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_buildUi != (Object)null) ? Hud.instance.m_buildUi.m_searchField : null); GameObject val2 = null; if ((Object)(object)val != (Object)null) { try { val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)bar, false); ((Object)val2).name = "WSF_Search"; MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val3 in componentsInChildren) { if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().Name == "Localize") { Object.DestroyImmediate((Object)(object)val3); } } s_search = val2.GetComponent<TMP_InputField>(); RemoveExtras(val2, s_search); } catch (Exception ex) { WorkbenchSearchFiltersPlugin.Log.LogWarning((object)("Could not copy the build menu search field, using a simple one: " + ex.Message)); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } val2 = null; } } if ((Object)(object)val2 == (Object)null) { val2 = CreateSimpleInputField(bar, referenceText); s_search = val2.GetComponent<TMP_InputField>(); } val2.SetActive(true); LayoutElement component = val2.GetComponent<LayoutElement>(); if ((Object)(object)component != (Object)null) { component.ignoreLayout = true; } SetTop((RectTransform)val2.transform, 0f, 26f); s_search.onValueChanged = new OnChangeEvent(); s_search.onEndEdit = new SubmitEvent(); s_search.onSubmit = new SubmitEvent(); s_search.restoreOriginalTextOnEscape = false; s_search.characterLimit = 40; s_search.SetTextWithoutNotify(SearchText); ((UnityEvent<string>)(object)s_search.onValueChanged).AddListener((UnityAction<string>)delegate(string text) { SearchText = text ?? ""; RefreshRecipes(); }); } private static void RemoveExtras(GameObject go, TMP_InputField input) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown HashSet<Transform> hashSet = new HashSet<Transform>(); Component[] array = (Component[])(object)new Component[3] { (Component)input.textViewport, (Component)input.textComponent, (Component)input.placeholder }; foreach (Component val in array) { Transform val2 = (((Object)(object)val != (Object)null) ? val.transform : null); while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)go.transform) { hashSet.Add(val2); val2 = val2.parent; } } List<GameObject> list = new List<GameObject>(); foreach (Transform item in go.transform) { Transform val3 = item; if (!hashSet.Contains(val3)) { list.Add(((Component)val3).gameObject); } } foreach (GameObject item2 in list) { Object.DestroyImmediate((Object)(object)item2); } } private static GameObject CreateSimpleInputField(RectTransform bar, TMP_Text referenceText) { //IL_0021: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) RectTransform val = NewRect("WSF_Search", (Transform)(object)bar); GameObject gameObject = ((Component)val).gameObject; gameObject.SetActive(false); Image val2 = gameObject.AddComponent<Image>(); ((Graphic)val2).color = s_buttonColor; RectTransform val3 = NewRect("Text Area", (Transform)(object)val); Stretch(val3, new Vector2(8f, 2f), new Vector2(-8f, -2f)); ((Component)val3).gameObject.AddComponent<RectMask2D>(); TextMeshProUGUI val4 = NewText("Placeholder", val3, referenceText, 16f); ((TMP_Text)val4).fontStyle = (FontStyles)2; ((Graphic)val4).color = new Color(1f, 1f, 1f, 0.45f); TextMeshProUGUI textComponent = NewText("Text", val3, referenceText, 16f); TMP_InputField obj = gameObject.AddComponent<TMP_InputField>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val2; obj.textViewport = val3; obj.textComponent = (TMP_Text)(object)textComponent; obj.placeholder = (Graphic)(object)val4; obj.fontAsset = referenceText.font; obj.pointSize = 16f; return gameObject; } private static void CreateCategoryButtons(InventoryGui gui, RectTransform bar, TMP_Text referenceText) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) RectTransform val = NewRect("WSF_Categories", (Transform)(object)bar); SetTop(val, 29f, 28f); HorizontalLayoutGroup obj = ((Component)val).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 3f; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = true; UITooltip val2 = (((Object)(object)gui.m_craftButton != (Object)null) ? ((Component)gui.m_craftButton).GetComponent<UITooltip>() : null); Sprite val3 = FindFoodIcon(gui); Category[] buttons = Categories.Buttons; for (int i = 0; i < buttons.Length; i++) { Category category = buttons[i]; RectTransform val4 = NewRect("WSF_Cat_" + category, (Transform)(object)val); Image val5 = ((Component)val4).gameObject.AddComponent<Image>(); ((Graphic)val5).color = s_buttonColor; Button obj2 = ((Component)val4).gameObject.AddComponent<Button>(); ((Selectable)obj2).targetGraphic = (Graphic)(object)val5; ColorBlock colors = ((Selectable)obj2).colors; ((ColorBlock)(ref colors)).highlightedColor = new Color(1.4f, 1.4f, 1.4f, 1f); ((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.8f, 0.8f, 1f); ((ColorBlock)(ref colors)).selectedColor = Color.white; ((Selectable)obj2).colors = colors; Category captured = category; ((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate { OnCategoryClicked(captured); }); ((Component)val4).gameObject.AddComponent<LayoutElement>().flexibleWidth = ((category == Category.All) ? 1.8f : 1f); Color? val6 = Categories.FoodColor(category); Color contentColor = (Color)(((??)val6) ?? Color.white); Sprite val7 = ((category == Category.All) ? null : (val6.HasValue ? val3 : FindIcon(category))); Graphic content; if ((Object)(object)val7 != (Object)null) { RectTransform obj3 = NewRect("icon", (Transform)(object)val4); Stretch(obj3, new Vector2(2f, 2f), new Vector2(-2f, -2f)); Image obj4 = ((Component)obj3).gameObject.AddComponent<Image>(); obj4.sprite = val7; obj4.preserveAspect = true; ((Graphic)obj4).raycastTarget = false; content = (Graphic)(object)obj4; } else { TextMeshProUGUI val8 = NewText("label", val4, referenceText, 14f); ((TMP_Text)val8).alignment = (TextAlignmentOptions)514; ((TMP_Text)val8).enableAutoSizing = true; ((TMP_Text)val8).fontSizeMin = 8f; ((TMP_Text)val8).fontSizeMax = 14f; ((TMP_Text)val8).text = Localization.instance.Localize(Categories.Token(category)); content = (Graphic)(object)val8; if (category == Category.All) { s_allLabel = (TMP_Text)(object)val8; } } if ((Object)(object)val2 != (Object)null && category != Category.All) { UITooltip obj5 = ((Component)val4).gameObject.AddComponent<UITooltip>(); obj5.m_tooltipPrefab = val2.m_tooltipPrefab; obj5.m_text = Categories.Token(category); } s_buttons.Add(new CategoryButton { Category = category, Background = val5, Content = content, ContentColor = contentColor }); } } private static Sprite FindFoodIcon(InventoryGui gui) { if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_foodIcon != (Object)null && (Object)(object)Hud.instance.m_foodIcon.sprite != (Object)null) { return Hud.instance.m_foodIcon.sprite; } InventoryElement val = (((Object)(object)gui.m_playerGrid != (Object)null && (Object)(object)gui.m_playerGrid.m_elementPrefab != (Object)null) ? gui.m_playerGrid.m_elementPrefab.GetComponent<InventoryElement>() : null); if (!((Object)(object)val != (Object)null) || !((Object)(object)val.m_food != (Object)null)) { return null; } return val.m_food.sprite; } private static void OnCategoryClicked(Category category) { CurrentCategory = category; RefreshRecipes(); } private static Sprite FindIcon(Category category) { if ((Object)(object)ObjectDB.instance == (Object)null) { return null; } string[] array = Categories.IconPrefabs(category); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(':'); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0]); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); Sprite[] array3 = (((Object)(object)val != (Object)null) ? val.m_itemData.m_shared.m_icons : null); if (array3 != null && array3.Length != 0) { int result; int num = ((array2.Length > 1 && int.TryParse(array2[1], out result) && result >= 0 && result < array3.Length) ? result : 0); return array3[num]; } } return null; } private static RectTransform NewRect(string name, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent(parent, false); return val; } private static void SetTop(RectTransform rect, float top, float height) { //IL_000b: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(1f, 1f); rect.pivot = new Vector2(0.5f, 1f); rect.sizeDelta = new Vector2(0f, height); rect.anchoredPosition = new Vector2(0f, 0f - top); } private static void Stretch(RectTransform rect, Vector2 offsetMin, Vector2 offsetMax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = offsetMin; rect.offsetMax = offsetMax; } private static TextMeshProUGUI NewText(string name, RectTransform parent, TMP_Text reference, float size) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = NewRect(name, (Transform)(object)parent); Stretch(obj, Vector2.zero, Vector2.zero); TextMeshProUGUI obj2 = ((Component)obj).gameObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj2).font = reference.font; ((TMP_Text)obj2).fontSize = size; ((Graphic)obj2).color = Color.white; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj2).textWrappingMode = (TextWrappingModes)0; ((Graphic)obj2).raycastTarget = false; return obj2; } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] internal static class InventoryGui_UpdateRecipeList_Patch { [HarmonyPriority(800)] private static void Prefix(InventoryGui __instance) { FilterBar.BeforeGameRebuild(__instance); } [HarmonyPriority(0)] [HarmonyAfter(new string[] { "org.lafchi.plugins.valheim_recycle" })] private static void Postfix(InventoryGui __instance) { FilterBar.EnsureCreated(__instance); FilterBar.AfterGameRebuild(__instance); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide_Patch { private static void Postfix() { FilterBar.OnInventoryHidden(); } } [HarmonyPatch(typeof(Chat), "HasFocus")] internal static class Chat_HasFocus_Patch { private static void Postfix(ref bool __result) { if (!__result && FilterBar.IsSearchFocused) { __result = true; } } } [BepInPlugin("adrirf7.WorkbenchSearchFilters", "WorkbenchSearchFilters", "1.1.0")] public class WorkbenchSearchFiltersPlugin : BaseUnityPlugin { public const string ModGuid = "adrirf7.WorkbenchSearchFilters"; public const string ModName = "WorkbenchSearchFilters"; public const string ModVersion = "1.1.0"; internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<bool> ClearSearchOnClose; internal static ConfigEntry<bool> RememberCategory; internal static ConfigEntry<string> CategoryOverrides; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_00b8: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "WorkbenchSearchFilters.adrirf7.cfg"), true, ((BaseUnityPlugin)this).Info.Metadata); ClearSearchOnClose = val.Bind<bool>("General", "ClearSearchOnClose", true, "true = the search text is cleared every time the inventory is closed."); RememberCategory = val.Bind<bool>("General", "RememberCategory", true, "true = the selected category is kept when the inventory is closed and opened again; false = it goes back to 'All' every time."); CategoryOverrides = val.Bind<string>("Categories", "CategoryOverrides", "Tankard:Misc,TankardOdin:Misc,Tankard_dvergr:Misc,TankardAnniversary:Misc", "Force the category of specific items, as Prefab:Category separated by commas. Categories: Weapons, Armor, Tools, Consumables, Materials, Misc; at the cauldron and the food preparation table: FoodStamina, FoodHealth, FoodEitr, FoodBalanced, Meads, Misc. The prefab name and current category of every craftable item are listed in WorkbenchSearchFilters.adrirf7.Categories.txt (generated when entering a world)."); CategoryOverrides.SettingChanged += delegate { Categories.ResetCache(); }; _harmony = new Harmony("adrirf7.WorkbenchSearchFilters"); _harmony.PatchAll(); Translations.Register(Localization.instance, Localization.instance.GetSelectedLanguage()); Log.LogInfo((object)"WorkbenchSearchFilters 1.1.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } FilterBar.Teardown(); } } internal static class Translations { private const string DefaultLanguage = "English"; private static readonly string[] s_keys = new string[13] { "wsf_search", "wsf_cat_all", "wsf_cat_weapons", "wsf_cat_armor", "wsf_cat_tools", "wsf_cat_consumables", "wsf_cat_materials", "wsf_cat_misc", "wsf_cat_foodstamina", "wsf_cat_foodhealth", "wsf_cat_foodeitr", "wsf_cat_foodbalanced", "wsf_cat_meads" }; private static readonly Dictionary<string, string[]> s_languages = new Dictionary<string, string[]> { ["English"] = new string[13] { "Search...", "All", "Weapons", "Armor", "Tools", "Consumables", "Materials", "Misc", "Stamina food", "Health food", "Eitr food", "Balanced food", "Meads" }, ["Spanish"] = new string[13] { "Buscar...", "Todo", "Armas", "Armaduras", "Herramientas", "Consumibles", "Materiales", "Otros", "Comida de vigor", "Comida de vida", "Comida de eitr", "Comida equilibrada", "Hidromieles" }, ["German"] = new string[13] { "Suchen...", "Alle", "Waffen", "Rüstung", "Werkzeuge", "Verbrauchsgüter", "Materialien", "Sonstiges", "Ausdauer-Essen", "Lebens-Essen", "Eitr-Essen", "Ausgewogenes Essen", "Met" }, ["French"] = new string[13] { "Rechercher...", "Tout", "Armes", "Armures", "Outils", "Consommables", "Matériaux", "Divers", "Nourriture d'endurance", "Nourriture de santé", "Nourriture d'eitr", "Nourriture équilibrée", "Hydromels" }, ["Italian"] = new string[13] { "Cerca...", "Tutto", "Armi", "Armature", "Strumenti", "Consumabili", "Materiali", "Varie", "Cibo per la resistenza", "Cibo per la salute", "Cibo per l'eitr", "Cibo bilanciato", "Idromele" }, ["Portuguese_Brazilian"] = new string[13] { "Pesquisar...", "Tudo", "Armas", "Armaduras", "Ferramentas", "Consumíveis", "Materiais", "Outros", "Comida de vigor", "Comida de vida", "Comida de eitr", "Comida equilibrada", "Hidroméis" }, ["Portuguese_European"] = new string[13] { "Pesquisar...", "Tudo", "Armas", "Armaduras", "Ferramentas", "Consumíveis", "Materiais", "Outros", "Comida de vigor", "Comida de vida", "Comida de eitr", "Comida equilibrada", "Hidroméis" }, ["Russian"] = new string[13] { "Поиск...", "Все", "Оружие", "Броня", "Инструменты", "Расходники", "Материалы", "Прочее", "Еда на выносливость", "Еда на здоровье", "Еда на эйтр", "Сбалансированная еда", "Медовуха" }, ["Ukrainian"] = new string[13] { "Пошук...", "Усе", "Зброя", "Броня", "Інструменти", "Витратні", "Матеріали", "Інше", "Їжа на витривалість", "Їжа на здоров'я", "Їжа на ейтр", "Збалансована їжа", "Медовуха" }, ["Polish"] = new string[13] { "Szukaj...", "Wszystko", "Broń", "Pancerz", "Narzędzia", "Konsumpcyjne", "Materiały", "Inne", "Jedzenie na wytrzymałość", "Jedzenie na zdrowie", "Jedzenie na eitr", "Zbilansowane jedzenie", "Miody pitne" }, ["Czech"] = new string[13] { "Hledat...", "Vše", "Zbraně", "Zbroj", "Nástroje", "Spotřební", "Materiály", "Ostatní", "Jídlo na výdrž", "Jídlo na zdraví", "Jídlo na eitr", "Vyvážené jídlo", "Medoviny" }, ["Dutch"] = new string[13] { "Zoeken...", "Alles", "Wapens", "Pantser", "Gereedschap", "Verbruiksartikelen", "Materialen", "Overig", "Uithoudingsvoedsel", "Gezondheidsvoedsel", "Eitr-voedsel", "Gebalanceerd voedsel", "Mede" }, ["Swedish"] = new string[13] { "Sök...", "Alla", "Vapen", "Rustning", "Verktyg", "Förbrukningsvaror", "Material", "Övrigt", "Uthållighetsmat", "Hälsomat", "Eitr-mat", "Balanserad mat", "Mjöd" }, ["Norwegian"] = new string[13] { "Søk...", "Alle", "Våpen", "Rustning", "Verktøy", "Forbruksvarer", "Materialer", "Diverse", "Utholdenhetsmat", "Helsemat", "Eitr-mat", "Balansert mat", "Mjød" }, ["Danish"] = new string[13] { "Søg...", "Alle", "Våben", "Rustning", "Værktøj", "Forbrugsvarer", "Materialer", "Diverse", "Udholdenhedsmad", "Helbredsmad", "Eitr-mad", "Balanceret mad", "Mjød" }, ["Finnish"] = new string[13] { "Hae...", "Kaikki", "Aseet", "Panssarit", "Työkalut", "Kulutustavarat", "Materiaalit", "Muut", "Kestävyysruoka", "Terveysruoka", "Eitr-ruoka", "Tasapainoinen ruoka", "Simat" }, ["Turkish"] = new string[13] { "Ara...", "Tümü", "Silahlar", "Zırhlar", "Aletler", "Sarf Malzemeleri", "Malzemeler", "Diğer", "Dayanıklılık yemeği", "Sağlık yemeği", "Eitr yemeği", "Dengeli yemek", "Bal şarapları" }, ["Hungarian"] = new string[13] { "Keresés...", "Mind", "Fegyverek", "Páncélok", "Eszközök", "Fogyóeszközök", "Nyersanyagok", "Egyéb", "Állóképesség-étel", "Életerő-étel", "Eitr-étel", "Kiegyensúlyozott étel", "Mézborok" }, ["Chinese"] = new string[13] { "搜索...", "全部", "武器", "护甲", "工具", "消耗品", "材料", "其他", "耐力食物", "生命食物", "艾特食物", "均衡食物", "蜂蜜酒" }, ["Chinese_Trad"] = new string[13] { "搜尋...", "全部", "武器", "護甲", "工具", "消耗品", "材料", "其他", "耐力食物", "生命食物", "艾特食物", "均衡食物", "蜂蜜酒" }, ["Japanese"] = new string[13] { "検索...", "すべて", "武器", "防具", "道具", "消耗品", "素材", "その他", "スタミナ料理", "体力料理", "エイトル料理", "バランス料理", "ミード" }, ["Korean"] = new string[13] { "검색...", "전체", "무기", "방어구", "도구", "소모품", "재료", "기타", "기력 음식", "체력 음식", "에이트르 음식", "균형 음식", "미드" } }; internal static void Register(Localization localization, string language) { if (!s_languages.TryGetValue(language, out var value)) { value = s_languages["English"]; } for (int i = 0; i < s_keys.Length; i++) { localization.AddWord(s_keys[i], value[i]); } } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] internal static class Localization_SetupLanguage_Patch { private static void Postfix(Localization __instance, string language) { Translations.Register(__instance, language); FilterBar.RefreshTexts(); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }