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 Valhalla Wardrobe v1.6.0
ValhallaWardrobe.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Primerochnaya; public static class Biomes { public static readonly Biome[] Order; private static readonly Dictionary<string, Biome> Map; private static readonly HashSet<string> Fixed; public static int Tier(Biome b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 switch (b - 1) { default: if ((int)b != 16) { if ((int)b != 32) { if ((int)b != 64) { if ((int)b != 256) { if ((int)b == 512) { return 6; } return 0; } return 3; } return 8; } return 7; } return 5; case 0: return 1; case 7: return 2; case 1: return 3; case 3: return 4; } } public static string Name(Biome b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 switch (b - 1) { default: if ((int)b != 16) { if ((int)b != 32) { if ((int)b != 64) { if ((int)b != 256) { if ((int)b == 512) { return Loc.T("Туманные земли", "Mistlands"); } return Loc.T("неизвестно", "unknown"); } return Loc.T("Океан", "Ocean"); } return Loc.T("Крайний север", "Deep North"); } return Loc.T("Пепельные земли", "Ashlands"); } return Loc.T("Равнины", "Plains"); case 0: return Loc.T("Луга", "Meadows"); case 7: return Loc.T("Чёрный лес", "Black Forest"); case 1: return Loc.T("Болото", "Swamp"); case 3: return Loc.T("Горы", "Mountains"); } } public static string Color(Biome b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 switch (b - 1) { default: if ((int)b != 16) { if ((int)b != 32) { if ((int)b != 64) { if ((int)b != 256) { if ((int)b == 512) { return "#b79ad8"; } return "#a89f8c"; } return "#6fb3d6"; } return "#9fd3e8"; } return "#e0805a"; } return "#e3cc6e"; case 0: return "#a7d47a"; case 7: return "#6fae7f"; case 1: return "#a2a36a"; case 3: return "#d3dde6"; } } public static string Tag(Biome b) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return "<color=" + Color(b) + ">" + Name(b) + "</color>"; } public static Biome Of(string prefab) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Biome value; return (Biome)((prefab != null && Map.TryGetValue(prefab, out value)) ? ((int)value) : 0); } private static void Seed(Biome b, params string[] names) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) foreach (string text in names) { Map[text] = b; Fixed.Add(text); } } private static void Offer(string prefab, Biome flags) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(prefab) && !Fixed.Contains(prefab)) { Biome val = Lowest(flags); if ((int)val != 0 && (!Map.TryGetValue(prefab, out var value) || Tier(val) < Tier(value))) { Map[prefab] = val; } } } private static Biome Lowest(Biome flags) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Biome[] order = Order; foreach (Biome val in order) { if ((flags & val) != 0) { return val; } } return (Biome)0; } public static void Build(ObjectDB db) { //IL_00d5: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) Map.Clear(); Fixed.Clear(); SeedVanilla(); try { FromVegetation(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Биомы: растительность не прочитана: " + ex.Message)); } try { FromSpawns(); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Биомы: спавны не прочитаны: " + ex2.Message)); } List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); try { CollectConversions(list); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("Биомы: станции переработки не прочитаны: " + ex3.Message)); } for (int i = 0; i < 2; i++) { bool flag = i == 0; for (int j = 0; j < 12; j++) { bool flag2 = false; foreach (KeyValuePair<string, string> item in list) { Biome val = Of(item.Key); if ((int)val != 0 && !Map.ContainsKey(item.Value)) { Map[item.Value] = val; flag2 = true; } } foreach (Recipe recipe in db.m_recipes) { if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || recipe.m_resources == null) { continue; } string name = ((Object)((Component)recipe.m_item).gameObject).name; if (!Map.ContainsKey(name)) { bool allKnown; Biome val2 = MaxOf(recipe, 1, out allKnown); if ((int)val2 != 0 && (allKnown || !flag)) { Map[name] = val2; flag2 = true; } } } if (!flag2) { break; } if (!flag) { flag = true; } } } Plugin.Log.LogInfo((object)("Биомы определены для " + Map.Count + " предметов")); } public static Biome MaxOf(Recipe r, int quality) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) bool allKnown; return MaxOf(r, quality, out allKnown); } public static Biome MaxOf(Recipe r, int quality, out bool allKnown) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) allKnown = true; Biome val = (Biome)0; if ((Object)(object)r == (Object)null || r.m_resources == null) { return val; } Requirement[] resources = r.m_resources; foreach (Requirement val2 in resources) { if (val2 == null || (Object)(object)val2.m_resItem == (Object)null) { continue; } bool flag = false; for (int j = 1; j <= quality; j++) { if (flag) { break; } int num; try { num = val2.GetAmount(j); } catch { num = ((j > 1) ? val2.m_amountPerLevel : val2.m_amount); } if (num > 0) { flag = true; } } if (flag) { Biome val3 = Of(((Object)((Component)val2.m_resItem).gameObject).name); if ((int)val3 == 0) { allKnown = false; } if (Tier(val3) > Tier(val)) { val = val3; } } } return val; } private static void FromVegetation() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance == (Object)null || instance.m_vegetation == null) { return; } foreach (ZoneVegetation item in instance.m_vegetation) { if (item == null || !item.m_enable || (Object)(object)item.m_prefab == (Object)null) { continue; } foreach (string item2 in DropsOf(item.m_prefab, 0)) { Offer(item2, item.m_biome); } } } private static void FromSpawns() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) SpawnSystemList[] array = Resources.FindObjectsOfTypeAll<SpawnSystemList>(); foreach (SpawnSystemList val in array) { if ((Object)(object)val == (Object)null || val.m_spawners == null) { continue; } foreach (SpawnData spawner in val.m_spawners) { if (spawner == null || !spawner.m_enabled || (Object)(object)spawner.m_prefab == (Object)null) { continue; } foreach (string item in DropsOf(spawner.m_prefab, 0)) { Offer(item, spawner.m_biome); } } } } private static void CollectConversions(List<KeyValuePair<string, string>> outList) { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Smelter component = prefab.GetComponent<Smelter>(); if ((Object)(object)component != (Object)null && component.m_conversion != null) { foreach (ItemConversion item in component.m_conversion) { if (item != null && (Object)(object)item.m_from != (Object)null && (Object)(object)item.m_to != (Object)null) { outList.Add(new KeyValuePair<string, string>(((Object)((Component)item.m_from).gameObject).name, ((Object)((Component)item.m_to).gameObject).name)); } } } CookingStation component2 = prefab.GetComponent<CookingStation>(); if ((Object)(object)component2 != (Object)null && component2.m_conversion != null) { foreach (ItemConversion item2 in component2.m_conversion) { if (item2 != null && (Object)(object)item2.m_from != (Object)null && (Object)(object)item2.m_to != (Object)null) { outList.Add(new KeyValuePair<string, string>(((Object)((Component)item2.m_from).gameObject).name, ((Object)((Component)item2.m_to).gameObject).name)); } } } Fermenter component3 = prefab.GetComponent<Fermenter>(); if (!((Object)(object)component3 != (Object)null) || component3.m_conversion == null) { continue; } foreach (ItemConversion item3 in component3.m_conversion) { if (item3 != null && (Object)(object)item3.m_from != (Object)null && (Object)(object)item3.m_to != (Object)null) { outList.Add(new KeyValuePair<string, string>(((Object)((Component)item3.m_from).gameObject).name, ((Object)((Component)item3.m_to).gameObject).name)); } } } } private static IEnumerable<string> DropsOf(GameObject go, int depth) { List<string> list = new List<string>(); if ((Object)(object)go == (Object)null || depth > 3) { return list; } CharacterDrop component = go.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null && component.m_drops != null) { foreach (Drop drop in component.m_drops) { if (drop != null && (Object)(object)drop.m_prefab != (Object)null) { list.Add(((Object)drop.m_prefab).name); } } } Pickable component2 = go.GetComponent<Pickable>(); if ((Object)(object)component2 != (Object)null) { if ((Object)(object)component2.m_itemPrefab != (Object)null) { list.Add(((Object)component2.m_itemPrefab).name); } AddTable(list, component2.m_extraDrops); } MineRock component3 = go.GetComponent<MineRock>(); if ((Object)(object)component3 != (Object)null) { AddTable(list, component3.m_dropItems); } MineRock5 component4 = go.GetComponent<MineRock5>(); if ((Object)(object)component4 != (Object)null) { AddTable(list, component4.m_dropItems); } DropOnDestroyed component5 = go.GetComponent<DropOnDestroyed>(); if ((Object)(object)component5 != (Object)null) { AddTable(list, component5.m_dropWhenDestroyed); } TreeBase component6 = go.GetComponent<TreeBase>(); if ((Object)(object)component6 != (Object)null) { AddTable(list, component6.m_dropWhenDestroyed); list.AddRange(DropsOf(component6.m_logPrefab, depth + 1)); } TreeLog component7 = go.GetComponent<TreeLog>(); if ((Object)(object)component7 != (Object)null) { AddTable(list, component7.m_dropWhenDestroyed); list.AddRange(DropsOf(component7.m_subLogPrefab, depth + 1)); } Destructible component8 = go.GetComponent<Destructible>(); if ((Object)(object)component8 != (Object)null && (Object)(object)component8.m_spawnWhenDestroyed != (Object)null) { list.AddRange(DropsOf(component8.m_spawnWhenDestroyed, depth + 1)); } return list; } private static void AddTable(List<string> list, DropTable t) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (t == null || t.m_drops == null) { return; } foreach (DropData drop in t.m_drops) { if ((Object)(object)drop.m_item != (Object)null) { list.Add(((Object)drop.m_item).name); } } } private static void SeedVanilla() { Seed((Biome)1, "Wood", "Stone", "Resin", "Flint", "LeatherScraps", "DeerHide", "Feathers", "RawMeat", "DeerMeat", "NeckTail", "Raspberry", "Mushroom", "Dandelion", "HardAntler", "TrophyDeer", "TrophyBoar", "TrophyNeck", "Honey", "QueenBee", "TrophyEikthyr", "BeechSeeds", "Acorn", "BirchSeeds"); Seed((Biome)8, "FineWood", "RoundLog", "CopperOre", "Copper", "TinOre", "Tin", "Bronze", "TrollHide", "GreydwarfEye", "AncientSeed", "SurtlingCore", "Thistle", "Carrot", "CarrotSeeds", "BoneFragments", "Blueberries", "Coal", "CryptKey", "PineCone", "TrophyGreydwarf", "TrophyGreydwarfBrute", "TrophyGreydwarfShaman", "TrophyTroll", "TrophySkeleton", "TrophySkeletonPoison", "TrophyTheElder", "BjornHide", "BjornPaw", "TrophyBjorn", "TrophyGhost", "TrophyRazorback"); Seed((Biome)2, "IronScrap", "IronOre", "Iron", "Guck", "Ooze", "Bloodbag", "Entrails", "WitheredBone", "ElderBark", "Root", "Turnip", "TurnipSeeds", "Wishbone", "TrophyDraugr", "TrophyDraugrElite", "TrophyDraugrFem", "TrophyBlob", "TrophyLeech", "TrophyWraith", "TrophyAbomination", "TrophyBonemass", "TrophySurtling", "Thunderstone"); Seed((Biome)256, "SerpentScale", "SerpentMeat", "TrophySerpent", "Chitin"); Seed((Biome)4, "SilverOre", "Silver", "WolfPelt", "WolfFang", "WolfClaw", "WolfMeat", "FreezeGland", "Obsidian", "Crystal", "DragonEgg", "DragonTear", "JuteRed", "Onion", "OnionSeeds", "FenrisHair", "FenrisClaw", "TrophyWolf", "TrophyHatchling", "TrophyFenring", "TrophyCultist", "TrophySGolem", "TrophyDragonQueen", "TrophyUlv", "TrophyFrostTroll", "TrophyCultist_Hildir", "TrophyBjornUndead"); Seed((Biome)16, "BlackMetalScrap", "BlackMetal", "Flax", "Barley", "LinenThread", "Needle", "LoxPelt", "LoxMeat", "Tar", "Cloudberry", "GoblinTotem", "YagluthDrop", "TrophyGoblin", "TrophyGoblinBrute", "TrophyGoblinShaman", "TrophyLox", "TrophyDeathsquito", "TrophyGrowth", "TrophyGoblinKing", "BarleyFlour", "TrophyGoblinBruteBrosShaman"); Seed((Biome)512, "Sap", "Eitr", "BlackCore", "Softtissue", "YggdrasilWood", "Carapace", "ScaleHide", "Mandible", "RoyalJelly", "BlackMarble", "Wisp", "DvergrNeedle", "DvergrKeyFragment", "JuteBlue", "Bilebag", "MushroomJotunPuffs", "MushroomMagecap", "QueenDrop", "TrophySeeker", "TrophySeekerBrute", "TrophyGjall", "TrophyTick", "TrophyDvergr", "TrophyHare", "TrophySeekerQueen", "GiantBloodSack", "CopperScrap", "HareMeat", "ChickenEgg"); Seed((Biome)32, "FlametalOre", "FlametalOreNew", "FlametalNew", "Flametal", "CharredBone", "MoltenCore", "Blackwood", "AskHide", "AskBladder", "BonemawSerpentScale", "BonemawSerpentTooth", "CelestialFeather", "CharcoalResin", "GemstoneBlue", "GemstoneGreen", "GemstoneRed", "MorgenHeart", "MorgenSinew", "ProustitePowder", "SulfurStone", "Grausten", "FaderDrop", "Fiddleheadfern", "Vineberry", "VineberrySeeds", "TrophyFader", "TrophyAsksvin", "TrophyBonemawSerpent", "TrophyCharredArcher", "TrophyCharredMage", "TrophyCharredMelee", "TrophyFallenValkyrie", "TrophyKvastur", "TrophyMorgen", "TrophyVolture", "AsksvinMeat", "VoltureMeat", "BellFragment"); } static Biomes() { Biome[] array = new Biome[9]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Order = (Biome[])(object)array; Map = new Dictionary<string, Biome>(StringComparer.OrdinalIgnoreCase); Fixed = new HashSet<string>(StringComparer.OrdinalIgnoreCase); } } public enum Role { Mage, Tank, Damage, Archer } public class Entry { public string Key; public string Name; public string Mod; public bool IsSet; public bool IsWeapon; public string Category; public List<ItemDrop> Pieces = new List<ItemDrop>(); public StatusEffect SetEffect; public HashSet<Role> Roles = new HashSet<Role>(); public Sprite Icon; public string SearchText; public int MaxQuality = 1; public Biome Biome; } public static class Catalog { public static readonly List<Entry> Armor = new List<Entry>(); public static readonly List<Entry> Weapons = new List<Entry>(); public static readonly List<Entry> ArmorPieces = new List<Entry>(); private static bool _builtRu; public static readonly List<string> Mods = new List<string>(); public static readonly Dictionary<string, List<Recipe>> RecipesByItem = new Dictionary<string, List<Recipe>>(); public static readonly HashSet<string> VanillaNames = new HashSet<string>(); private static int _builtForCount = -1; private static ObjectDB _builtForDb; private static readonly ItemType[] ArmorSlots; private static readonly Regex SlotWords; public static int SlotOrder(ItemDrop d) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 ItemType itemType = d.m_itemData.m_shared.m_itemType; switch (itemType - 6) { default: if ((int)itemType == 17) { return 3; } return 4; case 0: return 0; case 1: return 1; case 5: return 2; } } public static string L(string s) { if (string.IsNullOrEmpty(s)) { return string.Empty; } try { return (Localization.instance == null) ? s : Localization.instance.Localize(s); } catch { return s; } } public static bool EnsureBuilt() { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items == null || instance.m_items.Count == 0) { return false; } if ((Object)(object)instance == (Object)(object)_builtForDb && instance.m_items.Count == _builtForCount && _builtRu == Loc.Ru && Armor.Count + Weapons.Count > 0) { return true; } try { Build(instance); } catch (Exception ex) { Plugin.Log.LogError((object)("Не удалось собрать каталог: " + ex)); } _builtForDb = instance; _builtRu = Loc.Ru; _builtForCount = instance.m_items.Count; return true; } private static bool IsJunk(GameObject go, SharedData sh, string locName) { if (sh.m_icons == null || sh.m_icons.Length == 0 || (Object)(object)sh.m_icons[0] == (Object)null) { return true; } if (string.IsNullOrEmpty(locName) || locName.StartsWith("$") || locName.StartsWith("[")) { return true; } string text = ((Object)go).name.ToLowerInvariant(); if (text.Contains("cheat") || text.Contains("dummy") || text.Contains("debug") || text.Contains("_dev") || text.Contains("test")) { return true; } if (text.StartsWith("player") && text.Contains("unarmed")) { return true; } return false; } private static void Build(ObjectDB db) { //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Invalid comparison between Unknown and I4 //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Invalid comparison between Unknown and I4 //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Invalid comparison between Unknown and I4 //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Invalid comparison between Unknown and I4 //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Invalid comparison between Unknown and I4 //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Invalid comparison between Unknown and I4 //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Invalid comparison between Unknown and I4 //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Invalid comparison between Unknown and I4 //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Invalid comparison between Unknown and I4 //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Invalid comparison between Unknown and I4 //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Invalid comparison between Unknown and I4 //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Invalid comparison between Unknown and I4 //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Invalid comparison between Unknown and I4 //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Invalid comparison between Unknown and I4 Armor.Clear(); Weapons.Clear(); ArmorPieces.Clear(); Mods.Clear(); RecipesByItem.Clear(); ModResolver.Prepare(); foreach (Recipe recipe in db.m_recipes) { if (!((Object)(object)recipe == (Object)null) && !((Object)(object)recipe.m_item == (Object)null)) { string name = ((Object)((Component)recipe.m_item).gameObject).name; if (!RecipesByItem.TryGetValue(name, out var value)) { value = new List<Recipe>(); RecipesByItem[name] = value; } value.Add(recipe); } } List<ItemDrop> list = new List<ItemDrop>(); HashSet<string> hashSet = new HashSet<string>(); foreach (GameObject item in db.m_items) { if ((Object)(object)item == (Object)null || !hashSet.Add(((Object)item).name)) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { continue; } SharedData shared = component.m_itemData.m_shared; ItemType itemType = shared.m_itemType; bool flag = Array.IndexOf(ArmorSlots, itemType) >= 0; bool flag2 = (int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4 || (int)itemType == 5; if (!flag && !flag2) { continue; } string text = L(shared.m_name); if (IsJunk(item, shared, text)) { continue; } if (flag) { list.Add(component); continue; } SkillType skillType = shared.m_skillType; if ((int)skillType != 12 && (int)skillType != 104 && (int)skillType != 13) { Entry entry = new Entry(); entry.Key = "w:" + ((Object)item).name; entry.Name = text; entry.Mod = ModResolver.Resolve(((Object)item).name); entry.IsWeapon = true; entry.Category = WeaponCategory(shared); entry.Icon = shared.m_icons[0]; entry.MaxQuality = Mathf.Max(1, shared.m_maxQuality); Entry entry2 = entry; entry2.Pieces.Add(component); if ((int)skillType == 9 || (int)skillType == 10) { entry2.Roles.Add(Role.Mage); } else if ((int)itemType == 5) { entry2.Roles.Add(Role.Tank); } else if ((int)skillType == 8 || (int)skillType == 14 || (int)itemType == 4) { entry2.Roles.Add(Role.Archer); } else { entry2.Roles.Add(Role.Damage); } if (shared.m_attack != null && shared.m_attack.m_attackEitr > 0f && !entry2.Roles.Contains(Role.Mage)) { entry2.Roles.Add(Role.Mage); } entry2.SearchText = (entry2.Name + " " + entry2.Mod + " " + entry2.Category + " " + ((Object)item).name).ToLowerInvariant(); Weapons.Add(entry2); } } BuildArmorSets(list); try { Biomes.Build(db); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Биомы не определены: " + ex)); } foreach (Entry item2 in Armor.Concat(Weapons).Concat(ArmorPieces)) { item2.Biome = EntryBiome(item2, 1); } ArmorPieces.Sort((Entry a, Entry b) => string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase)); foreach (Entry item3 in Armor.Concat(Weapons)) { if (!Mods.Contains(item3.Mod)) { Mods.Add(item3.Mod); } } Mods.Sort(delegate(string a, string b) { if (a == "Valheim") { return -1; } return (b == "Valheim") ? 1 : string.Compare(a, b, StringComparison.OrdinalIgnoreCase); }); Armor.Sort(CompareEntries); Weapons.Sort(delegate(Entry a, Entry b) { int num = string.Compare(a.Category, b.Category, StringComparison.Ordinal); return (num == 0) ? CompareEntries(a, b) : num; }); Plugin.Log.LogInfo((object)$"Каталог собран: {Armor.Count} сетов/вещей брони, {Weapons.Count} оружия, модов: {Mods.Count}"); } private static int CompareEntries(Entry a, Entry b) { if (a.IsSet != b.IsSet) { return (!a.IsSet) ? 1 : (-1); } return string.Compare(a.Name, b.Name, StringComparison.CurrentCultureIgnoreCase); } private static string Stem(string prefabName) { string text = SlotWords.Replace(prefabName, string.Empty); return text.ToLowerInvariant().Trim(); } private static void BuildArmorSets(List<ItemDrop> pieces) { Dictionary<string, List<ItemDrop>> dictionary = new Dictionary<string, List<ItemDrop>>(); List<string> list = new List<string>(); foreach (ItemDrop piece in pieces) { SharedData shared = piece.m_itemData.m_shared; string text; if (!string.IsNullOrEmpty(shared.m_setName)) { text = "set:" + shared.m_setName; } else { string text2 = Stem(((Object)((Component)piece).gameObject).name); text = ((!string.IsNullOrEmpty(text2)) ? ("stem:" + ModResolver.Resolve(((Object)((Component)piece).gameObject).name) + ":" + text2) : ("one:" + ((Object)((Component)piece).gameObject).name)); } if (!dictionary.TryGetValue(text, out var value)) { value = (dictionary[text] = new List<ItemDrop>()); list.Add(text); } value.Add(piece); } List<float> list3 = new List<float>(); foreach (ItemDrop piece2 in pieces) { list3.Add(piece2.m_itemData.m_shared.m_armor); } list3.Sort(); float heavyArmor = ((list3.Count <= 0) ? 999f : list3[(int)((float)list3.Count * 0.7f)]); foreach (string item in list) { List<ItemDrop> list4 = dictionary[item]; if (item.StartsWith("stem:")) { HashSet<ItemType> hashSet = new HashSet<ItemType>(list4.Select((ItemDrop x) => x.m_itemData.m_shared.m_itemType)); if (hashSet.Count < 2 || hashSet.Count < list4.Count - 1) { foreach (ItemDrop item2 in list4) { List<ItemDrop> list5 = new List<ItemDrop>(); list5.Add(item2); AddArmorEntry(list5, "one:" + ((Object)((Component)item2).gameObject).name, heavyArmor); } continue; } } AddArmorEntry(list4, item, heavyArmor); } } private static void AddArmorEntry(List<ItemDrop> g, string key, float heavyArmor) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) g.Sort((ItemDrop a, ItemDrop b) => SlotOrder(a).CompareTo(SlotOrder(b))); ItemDrop val = g[0]; ItemDrop val2 = ((IEnumerable<ItemDrop>)g).FirstOrDefault((Func<ItemDrop, bool>)((ItemDrop x) => (int)x.m_itemData.m_shared.m_itemType == 7)) ?? val; SharedData shared = val2.m_itemData.m_shared; StatusEffect val3 = g.Select((ItemDrop x) => x.m_itemData.m_shared.m_setStatusEffect).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect x) => (Object)(object)x != (Object)null)); Entry entry = new Entry(); entry.Key = key; entry.Mod = ModResolver.Resolve(((Object)((Component)val).gameObject).name); entry.IsSet = g.Count > 1; entry.Category = ((g.Count <= 1) ? SlotName(val.m_itemData.m_shared.m_itemType) : Loc.T("Сет", "Set")); entry.Icon = shared.m_icons[0]; entry.SetEffect = val3; entry.MaxQuality = Mathf.Max(1, g.Max((ItemDrop x) => x.m_itemData.m_shared.m_maxQuality)); Entry entry2 = entry; entry2.Pieces.AddRange(g); string text = ((!((Object)(object)val3 != (Object)null)) ? string.Empty : L(val3.m_name)); if (g.Count > 1) { string text2 = (entry2.Name = L(shared.m_name)); if (!string.IsNullOrEmpty(text) && !text.StartsWith("$")) { entry2.Name = text2 + " · " + text; } } else { entry2.Name = L(val.m_itemData.m_shared.m_name); } float num = 0f; float num2 = 0f; float num3 = 0f; foreach (ItemDrop item in g) { SharedData shared2 = item.m_itemData.m_shared; num += shared2.m_eitrRegenModifier; num2 += shared2.m_movementModifier; num3 += shared2.m_armor; } string text3 = string.Empty; if ((Object)(object)val3 != (Object)null) { try { text3 = (L(val3.m_name) + " " + L(val3.GetTooltipString())).ToLowerInvariant(); } catch { } } string text4 = string.Join(" ", g.Select((ItemDrop p) => L(p.m_itemData.m_shared.m_description) + " " + ((Object)((Component)p).gameObject).name).ToArray()).ToLowerInvariant(); string text5 = text3 + " " + text4; if (num > 0.001f || text5.Contains("eitr") || text5.Contains("эйтр") || text5.Contains("magic") || text5.Contains("маги")) { entry2.Roles.Add(Role.Mage); } if (num2 <= -0.099f || (num3 / (float)g.Count >= heavyArmor && heavyArmor > 0f)) { entry2.Roles.Add(Role.Tank); } if (text5.Contains("bow") || text5.Contains("лук") || text5.Contains("стрел") || text5.Contains("arrow") || text5.Contains("sneak") || text5.Contains("скрыт") || text5.Contains("ranger") || text5.Contains("hunter") || text5.Contains("охотн")) { entry2.Roles.Add(Role.Archer); } if (!entry2.Roles.Contains(Role.Mage) && !entry2.Roles.Contains(Role.Tank)) { entry2.Roles.Add(Role.Damage); } entry2.SearchText = (entry2.Name + " " + entry2.Mod + " " + string.Join(" ", g.Select((ItemDrop p) => L(p.m_itemData.m_shared.m_name) + " " + ((Object)((Component)p).gameObject).name).ToArray())).ToLowerInvariant(); Armor.Add(entry2); foreach (ItemDrop item2 in g) { SharedData shared3 = item2.m_itemData.m_shared; entry = new Entry(); entry.Key = "piece:" + ((Object)((Component)item2).gameObject).name; entry.Name = L(shared3.m_name); entry.Mod = entry2.Mod; entry.IsSet = false; entry.Category = SlotName(shared3.m_itemType); entry.Icon = shared3.m_icons[0]; entry.SetEffect = entry2.SetEffect; entry.MaxQuality = Mathf.Max(1, shared3.m_maxQuality); Entry entry3 = entry; entry3.Pieces.Add(item2); foreach (Role role in entry2.Roles) { entry3.Roles.Add(role); } entry3.SearchText = (entry3.Name + " " + entry3.Mod + " " + entry2.Name + " " + ((Object)((Component)item2).gameObject).name).ToLowerInvariant(); ArmorPieces.Add(entry3); } } public static string SlotName(ItemType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 switch (t - 6) { default: if ((int)t == 17) { return Loc.T("Плащ", "Cape"); } return Loc.T("Вещь", "Item"); case 0: return Loc.T("Шлем", "Helmet"); case 1: return Loc.T("Грудь", "Chest"); case 5: return Loc.T("Ноги", "Legs"); } } private static string WeaponCategory(SharedData sh) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected I4, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Invalid comparison between Unknown and I4 if ((int)sh.m_itemType == 5) { return Loc.T("Щиты", "Shields"); } SkillType skillType = sh.m_skillType; switch (skillType - 1) { case 0: return Loc.T("Мечи", "Swords"); case 6: return Loc.T("Топоры", "Axes"); case 2: return Loc.T("Дубины и молоты", "Clubs & maces"); case 1: return Loc.T("Ножи", "Knives"); case 3: return Loc.T("Древковое", "Polearms"); case 4: return Loc.T("Копья", "Spears"); case 7: return Loc.T("Луки", "Bows"); case 13: return Loc.T("Арбалеты", "Crossbows"); case 8: return Loc.T("Посохи: стихии", "Staffs: elemental"); case 9: return Loc.T("Посохи: кровь", "Staffs: blood"); case 10: return Loc.T("Кастеты", "Fists"); case 5: return Loc.T("Щиты", "Shields"); default: if ((int)sh.m_itemType == 4) { return Loc.T("Луки", "Bows"); } return Loc.T("Прочее", "Other"); } } public static Biome EntryBiome(Entry e, int quality) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Biome val = (Biome)0; foreach (ItemDrop piece in e.Pieces) { Recipe recipe = GetRecipe(piece); int quality2 = Mathf.Min(quality, Mathf.Max(1, piece.m_itemData.m_shared.m_maxQuality)); Biome val2 = ((!((Object)(object)recipe != (Object)null)) ? Biomes.Of(((Object)((Component)piece).gameObject).name) : Biomes.MaxOf(recipe, quality2)); if (Biomes.Tier(val2) > Biomes.Tier(val)) { val = val2; } } return val; } public static Recipe GetRecipe(ItemDrop d) { if (!RecipesByItem.TryGetValue(((Object)((Component)d).gameObject).name, out var value)) { return null; } Recipe val = ((IEnumerable<Recipe>)value).FirstOrDefault((Func<Recipe, bool>)((Recipe x) => x.m_enabled && x.m_resources != null && x.m_resources.Length > 0)); return val ?? value.FirstOrDefault(); } static Catalog() { ItemType[] array = new ItemType[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ArmorSlots = (ItemType[])(object)array; SlotWords = new Regex("(helmet|helm|hood|hat|cap|crown|circlet|mask|head|armou?r|chest|cuirass|torso|body|tunic|robe|shirt|coat|jacket|vest|legs?|pants|trousers|leggings|greaves|boots|cape|cloak|mantle|shoulders?|pauldrons?|scarf|_|-|\\d+$)", RegexOptions.IgnoreCase); } } public static class ModResolver { public const string Vanilla = "Valheim"; private static readonly Dictionary<string, string> PrefabToBundle = new Dictionary<string, string>(); private static readonly Dictionary<string, string> PrefabToJotunnMod = new Dictionary<string, string>(); private static readonly string[][] KnownBundles = new string[17][] { new string[2] { "southsil", "Southsil Armor" }, new string[2] { "warfare", "Warfare" }, new string[2] { "wizardry", "Wizardry" }, new string[2] { "hugo", "Hugo's Armory" }, new string[2] { "ascend", "Ascendant Armory" }, new string[2] { "magicsupremacy", "Magic Supremacy" }, new string[2] { "supremacy", "Magic Supremacy" }, new string[2] { "valheimarmory", "Valheim Armory" }, new string[2] { "epicloot", "Epic Loot" }, new string[2] { "magicrevamp", "Magic Revamp" }, new string[2] { "magicplugin", "Magic Plugin" }, new string[2] { "bowplugin", "Bow Plugin" }, new string[2] { "wildweapons", "Wild Weapons" }, new string[2] { "odin", "OdinPlus" }, new string[2] { "corsair", "Corsairs" }, new string[2] { "backpack", "Backpacks" }, new string[2] { "fortress", "Valheim Fortress" } }; private static string Unknown => Loc.T("Мод (неизвестный)", "Unknown mod"); public static void Prepare() { PrefabToBundle.Clear(); PrefabToJotunnMod.Clear(); try { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle == (Object)null || allLoadedAssetBundle.isStreamedSceneAssetBundle) { continue; } string[] allAssetNames; try { allAssetNames = allLoadedAssetBundle.GetAllAssetNames(); } catch { continue; } string[] array = allAssetNames; foreach (string text in array) { if (text.EndsWith(".prefab")) { int num = text.LastIndexOf('/'); string key = text.Substring(num + 1, text.Length - num - 1 - ".prefab".Length); if (!PrefabToBundle.ContainsKey(key)) { PrefabToBundle[key] = ((Object)allLoadedAssetBundle).name; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Ассет-бандлы не прочитались: " + ex.Message)); } try { Type type = AccessTools.TypeByName("Jotunn.Managers.ItemManager"); if (!(type != null)) { return; } object value = Traverse.Create(type).Property("Instance", (object[])null).GetValue(); if (!(Traverse.Create(value).Field("Items").GetValue() is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { object obj2 = Traverse.Create(item).Property("Value", (object[])null).GetValue() ?? item; object value2 = Traverse.Create(obj2).Property("ItemPrefab", (object[])null).GetValue(); GameObject val = (GameObject)((value2 is GameObject) ? value2 : null); object value3 = Traverse.Create(obj2).Property("SourceMod", (object[])null).GetValue(); string value4 = ((value3 == null) ? null : (Traverse.Create(value3).Property("Name", (object[])null).GetValue() as string)); if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(value4)) { PrefabToJotunnMod[((Object)val).name] = value4; } } } catch (Exception ex2) { Plugin.Log.LogDebug((object)("Jotunn не опрошен: " + ex2.Message)); } } public static string Resolve(string prefab) { if (Catalog.VanillaNames.Contains(prefab)) { return "Valheim"; } if (PrefabToJotunnMod.TryGetValue(prefab, out var value)) { return value; } if (PrefabToBundle.TryGetValue(prefab.ToLowerInvariant(), out var value2)) { return Pretty(value2); } return Unknown; } private static string Pretty(string bundle) { string text = bundle.ToLowerInvariant(); string[][] knownBundles = KnownBundles; foreach (string[] array in knownBundles) { if (text.Contains(array[0])) { return array[1]; } } int num = text.LastIndexOf('/'); if (num >= 0) { bundle = bundle.Substring(num + 1); } if (bundle.Length > 0) { bundle = char.ToUpperInvariant(bundle[0]) + bundle.Substring(1); } return bundle; } } public static class Loc { public static bool Ru = true; public static void Detect() { string text = ((Plugin.Language == null) ? "Auto" : Plugin.Language.Value); if (text == "Russian") { Ru = true; return; } if (text == "English") { Ru = false; return; } string text2 = "English"; try { if (Localization.instance != null) { text2 = Localization.instance.GetSelectedLanguage(); } } catch { } Ru = text2 == "Russian" || text2 == "Ukrainian" || text2 == "Belarusian"; } public static string T(string ru, string en) { return (!Ru) ? en : ru; } } public static class Outfits { public class Outfit { public string Name; public string[] Slots = new string[4]; public string Right = string.Empty; public string Left = string.Empty; } public static readonly List<Outfit> List = new List<Outfit>(); private static bool _loaded; private static string FilePath => Path.Combine(Paths.ConfigPath, "umorise.valhallawardrobe.outfits.txt"); public static void EnsureLoaded() { if (_loaded) { return; } _loaded = true; List.Clear(); try { if (!File.Exists(FilePath)) { return; } string[] array = File.ReadAllLines(FilePath); foreach (string text in array) { string[] array2 = text.Split('\t'); if (array2.Length >= 7 && !string.IsNullOrEmpty(array2[0])) { Outfit outfit = new Outfit(); outfit.Name = array2[0]; outfit.Right = array2[5]; outfit.Left = array2[6]; Outfit outfit2 = outfit; for (int j = 0; j < 4; j++) { outfit2.Slots[j] = array2[1 + j]; } List.Add(outfit2); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Outfits not loaded: " + ex.Message)); } } private static void Save() { try { List<string> list = new List<string>(); foreach (Outfit item in List) { list.Add(string.Join("\t", item.Name.Replace("\t", " "), item.Slots[0], item.Slots[1], item.Slots[2], item.Slots[3], item.Right, item.Left)); } File.WriteAllLines(FilePath, list.ToArray()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Outfits not saved: " + ex.Message)); } } private static string Code(ItemDrop d, bool empty) { return ((Object)(object)d != (Object)null) ? ((Object)((Component)d).gameObject).name : ((!empty) ? string.Empty : "-"); } public static void SaveCurrent(string name) { EnsureLoaded(); Outfit o = new Outfit { Name = ((!string.IsNullOrEmpty(name)) ? name.Trim() : ("Outfit " + (List.Count + 1))) }; for (int i = 0; i < 4; i++) { o.Slots[i] = Code(Preview.Slots[i], Preview.Naked[i]); } o.Right = Code(Preview.RightItem, Preview.RightEmpty); o.Left = Code(Preview.LeftItem, Preview.LeftEmpty); int num = List.FindIndex((Outfit x) => x.Name == o.Name); if (num >= 0) { List[num] = o; } else { List.Add(o); } Save(); } public static void Delete(int idx) { if (idx >= 0 && idx < List.Count) { List.RemoveAt(idx); Save(); } } private static ItemDrop Find(string code) { if (string.IsNullOrEmpty(code) || code == "-" || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(code); return (!((Object)(object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>(); } public static void Apply(Outfit o) { Preview.ClearAll(); for (int i = 0; i < 4; i++) { if (o.Slots[i] == "-") { Preview.EmptySlot(i); continue; } ItemDrop val = Find(o.Slots[i]); if ((Object)(object)val != (Object)null) { Preview.SetArmorPiece(val); } } Preview.RightItem = Find(o.Right); Preview.RightEmpty = o.Right == "-"; Preview.LeftItem = Find(o.Left); Preview.LeftEmpty = o.Left == "-"; Preview.MarkDirty(); } } [BepInPlugin("umorise.valhallawardrobe", "Valhalla Wardrobe", "1.6.0")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDBAwake { [HarmonyPriority(800)] private static void Prefix(ObjectDB __instance) { if (Catalog.VanillaNames.Count > 0 || __instance.m_items == null) { return; } foreach (GameObject item in __instance.m_items) { if ((Object)(object)item != (Object)null) { Catalog.VanillaNames.Add(((Object)item).name); } } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] private static class BlockControllerInput { private static bool Prefix(ref bool __result) { if ((Object)(object)Instance == (Object)null || !Instance.Ui.Open) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Player), "TakeInput")] private static class BlockPlayerInput { private static bool Prefix(ref bool __result) { if ((Object)(object)Instance == (Object)null || !Instance.Ui.Open) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] private static class FreeCursor { private static void Postfix() { if (!((Object)(object)Instance == (Object)null) && Instance.Ui.Open) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } } [HarmonyPatch(typeof(Menu), "Update")] private static class NoEscMenu { private static bool Prefix() { return (Object)(object)Instance == (Object)null || (!Instance.Ui.Open && Instance.Ui.ClosedFrame != Time.frameCount); } } [HarmonyPatch(typeof(InventoryGui), "Update")] private static class NoInventoryWhileOpen { private static bool Prefix() { return (Object)(object)Instance == (Object)null || !Instance.Ui.Open; } } [HarmonyPatch(typeof(Minimap), "Update")] private static class NoMapWhileOpen { private static bool Prefix() { return (Object)(object)Instance == (Object)null || !Instance.Ui.Open; } } public const string Guid = "umorise.valhallawardrobe"; public const string Version = "1.6.0"; public static ManualLogSource Log; public static Plugin Instance; public static ConfigEntry<KeyCode> Hotkey; public static ConfigEntry<float> ChestRadius; public static ConfigEntry<float> UiScale; public static ConfigEntry<string> Language; private Harmony _harmony; public Window Ui = new Window(); private ObjectDB _recoloredFor; private void Awake() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Hotkey", (KeyCode)290, "Open/close Valhalla Wardrobe / Открыть или закрыть окно"); ChestRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Crafting", "Chest radius", 30f, "Chests within this radius count toward have/need (0 = inventory only) / Радиус сундуков для счётчика «есть / нужно»"); UiScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "UI scale", 1f, "Window size multiplier / Масштаб окна"); Language = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Language", "Auto", new ConfigDescription("Interface language / Язык интерфейса: Auto follows the game language", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Auto", "English", "Russian" }), Array.Empty<object>())); _harmony = new Harmony("umorise.valhallawardrobe"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)("Valhalla Wardrobe загружен. Клавиша: " + Hotkey.Value)); } private void OnDestroy() { Preview.Destroy(); if (_harmony != null) { _harmony.UnpatchSelf(); } } private static bool OtherUiBusy() { if (Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || Minimap.InTextInput() || StoreGui.IsVisible()) { return true; } if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } return false; } private void Update() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ObjectDB.instance != (Object)(object)_recoloredFor) { _recoloredFor = ObjectDB.instance; try { Recolor.ApplyAll(); } catch (Exception ex) { Log.LogWarning((object)("Recolor: " + ex.Message)); } } if ((Object)(object)Player.m_localPlayer != (Object)null) { Recolor.Tick(); } if ((Object)(object)Player.m_localPlayer == (Object)null) { if (Ui.Open) { Ui.Close(); } return; } bool flag = false; try { flag = ZInput.GetKeyDown(Hotkey.Value, false); } catch { flag = Input.GetKeyDown(Hotkey.Value); } if (Ui.Open) { if (flag || ZInput.GetKeyDown((KeyCode)27, false)) { Ui.Close(); } else if (((Character)Player.m_localPlayer).IsDead()) { Ui.Close(); } } else if (flag && !OtherUiBusy()) { if (InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } Ui.Show(); } } private void LateUpdate() { if (Ui.Open) { Preview.Update(); } } private void OnGUI() { if (Ui.Open) { Ui.Draw(); } } } public static class Preview { public const int Keep = -1; public static readonly ItemDrop[] Slots = (ItemDrop[])(object)new ItemDrop[4]; public static readonly bool[] Naked = new bool[4]; public static ItemDrop RightItem; public static ItemDrop LeftItem; public static bool RightEmpty; public static bool LeftEmpty; public static float Yaw = 0f; public static float Zoom = 3.4f; public static RenderTexture Texture; private static GameObject _clone; private static GameObject _camGo; private static GameObject _lightGo; private static GameObject _fillGo; private static VisEquipment _vis; private static Camera _cam; private static int _layer = -1; private static Vector3 _origin; private static bool _dirty; private static int _lastLayerFix; private static int sHelmet; private static int sChest; private static int sLegs; private static int sShoulder; private static int sShoulderVar; private static int sShoulderQ; private static int sUtility; private static int sRight; private static int sRightQ; private static int sLeft; private static int sLeftVar; private static int sLeftQ; private static int sModel; private static int sHair; private static int sBeard; private static Vector3 sSkin; private static Vector3 sHairColor; private static readonly FieldInfo VisRef = AccessTools.Field(typeof(Humanoid), "m_visEquipment"); public static bool WeaponActive => (Object)(object)RightItem != (Object)null || (Object)(object)LeftItem != (Object)null || RightEmpty || LeftEmpty; public static VisEquipment Vis => _vis; public static bool Active => (Object)(object)_clone != (Object)null; public static int SlotOf(ItemDrop p) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 ItemType itemType = p.m_itemData.m_shared.m_itemType; switch (itemType - 6) { default: if ((int)itemType == 17) { return 3; } return -1; case 0: return 0; case 1: return 1; case 5: return 2; } } private static FieldInfo F(string n) { return AccessTools.Field(typeof(VisEquipment), n); } private static int GetI(VisEquipment v, string n) { FieldInfo fieldInfo = F(n); return (fieldInfo != null) ? ((int)fieldInfo.GetValue(v)) : 0; } public static void SetArmor(Entry e) { for (int i = 0; i < 4; i++) { Slots[i] = null; Naked[i] = false; } if (e != null) { foreach (ItemDrop piece in e.Pieces) { int num = SlotOf(piece); if (num >= 0 && (Object)(object)Slots[num] == (Object)null) { Slots[num] = piece; } } } _dirty = true; } public static void SetArmorPiece(ItemDrop p) { int num = SlotOf(p); if (num >= 0) { Slots[num] = p; Naked[num] = false; _dirty = true; } } public static void ResetSlot(int s) { Slots[s] = null; Naked[s] = false; _dirty = true; } public static void EmptySlot(int s) { Slots[s] = null; Naked[s] = true; _dirty = true; } public static void SetWeapon(Entry e) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Invalid comparison between Unknown and I4 if (e == null) { RightItem = (LeftItem = null); RightEmpty = (LeftEmpty = false); _dirty = true; return; } ItemDrop val = e.Pieces[0]; ItemType itemType = val.m_itemData.m_shared.m_itemType; if ((int)itemType == 4) { goto IL_00a2; } if ((int)itemType != 5) { if ((int)itemType != 14) { if ((int)itemType == 22) { goto IL_00a2; } RightItem = val; RightEmpty = false; if ((Object)(object)LeftItem != (Object)null && (int)LeftItem.m_itemData.m_shared.m_itemType != 5) { LeftItem = null; LeftEmpty = true; } } else { RightItem = val; RightEmpty = false; LeftItem = null; LeftEmpty = true; } } else { LeftItem = val; LeftEmpty = false; if ((Object)(object)RightItem != (Object)null && IsTwoHanded(RightItem)) { RightItem = null; RightEmpty = true; } } goto IL_0123; IL_0123: _dirty = true; return; IL_00a2: LeftItem = val; LeftEmpty = false; RightItem = null; RightEmpty = true; goto IL_0123; } private static bool IsTwoHanded(ItemDrop d) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 ItemType itemType = d.m_itemData.m_shared.m_itemType; return (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4; } public static void MarkDirty() { _dirty = true; } public static void ClearHand(bool right) { if (right) { RightItem = null; RightEmpty = false; } else { LeftItem = null; LeftEmpty = false; } _dirty = true; } public static void ClearAll() { for (int i = 0; i < 4; i++) { Slots[i] = null; Naked[i] = false; } RightItem = (LeftItem = null); RightEmpty = (LeftEmpty = false); _dirty = true; } public static void Undress() { for (int i = 0; i < 4; i++) { Slots[i] = null; Naked[i] = true; } _dirty = true; } private static int Hash(ItemDrop d) { return StringExtensionMethods.GetStableHashCode(((Object)((Component)d).gameObject).name); } private static int SlotHash(int i, int own) { if ((Object)(object)Slots[i] != (Object)null) { return Hash(Slots[i]); } return (!Naked[i]) ? own : 0; } public static bool Create() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) Destroy(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return false; } try { SnapshotPlayer(localPlayer); GameObject prefab = ZNetScene.instance.GetPrefab("Player"); if ((Object)(object)prefab == (Object)null) { Plugin.Log.LogError((object)"Не найден префаб Player"); return false; } _origin = ((Component)localPlayer).transform.position + new Vector3(0f, 3000f, 0f); ZNetView.m_forceDisableInit = true; try { _clone = Object.Instantiate<GameObject>(prefab, _origin, Quaternion.identity); } finally { ZNetView.m_forceDisableInit = false; } ((Object)_clone).name = "ValhallaWardrobe_Mannequin"; Rigidbody component = _clone.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Collider[] componentsInChildren = _clone.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { val.enabled = false; } Animator[] componentsInChildren2 = _clone.GetComponentsInChildren<Animator>(true); foreach (Animator val2 in componentsInChildren2) { val2.updateMode = (AnimatorUpdateMode)2; } RemoveFromStaticList(typeof(Player), "s_players", _clone.GetComponent<Player>()); RemoveFromStaticList(typeof(Character), "s_characters", _clone.GetComponent<Character>()); RemoveFromInstances(_clone.GetComponent<Character>()); _vis = _clone.GetComponent<VisEquipment>(); _layer = FindFreeLayer(); SetLayer(_clone, _layer); RenderTexture val3 = new RenderTexture(640, 1000, 24, (RenderTextureFormat)0); val3.antiAliasing = 4; RenderTexture val4 = val3; val4.Create(); Texture = val4; _camGo = new GameObject("ValhallaWardrobe_Camera"); _cam = _camGo.AddComponent<Camera>(); _cam.clearFlags = (CameraClearFlags)2; _cam.backgroundColor = new Color(0.1f, 0.085f, 0.07f, 1f); _cam.cullingMask = 1 << _layer; _cam.fieldOfView = 30f; _cam.nearClipPlane = 0.05f; _cam.farClipPlane = 50f; _cam.targetTexture = val4; _cam.allowHDR = false; _cam.depth = -50f; _lightGo = new GameObject("ValhallaWardrobe_Key"); Light val5 = _lightGo.AddComponent<Light>(); val5.type = (LightType)1; val5.intensity = 1.25f; val5.color = new Color(1f, 0.93f, 0.82f); val5.cullingMask = 1 << _layer; val5.shadows = (LightShadows)0; _fillGo = new GameObject("ValhallaWardrobe_Fill"); Light val6 = _fillGo.AddComponent<Light>(); val6.type = (LightType)1; val6.intensity = 0.55f; val6.color = new Color(0.7f, 0.78f, 1f); val6.cullingMask = 1 << _layer; val6.shadows = (LightShadows)0; ApplyAppearance(); _dirty = true; Update(); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Не удалось создать манекен: " + ex)); Destroy(); return false; } } public static void Destroy() { if ((Object)(object)_clone != (Object)null) { Object.Destroy((Object)(object)_clone); } if ((Object)(object)_camGo != (Object)null) { Object.Destroy((Object)(object)_camGo); } if ((Object)(object)_lightGo != (Object)null) { Object.Destroy((Object)(object)_lightGo); } if ((Object)(object)_fillGo != (Object)null) { Object.Destroy((Object)(object)_fillGo); } if ((Object)(object)Texture != (Object)null) { Texture.Release(); Object.Destroy((Object)(object)Texture); } _clone = (_camGo = (_lightGo = (_fillGo = null))); _vis = null; _cam = null; Texture = null; } public static void Update() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_clone == (Object)null) && !((Object)(object)_vis == (Object)null)) { _clone.transform.position = _origin; _clone.transform.rotation = Quaternion.Euler(0f, 180f + Yaw, 0f); if (_dirty) { _dirty = false; ApplyEquipment(); } if (Time.frameCount - _lastLayerFix > 5) { _lastLayerFix = Time.frameCount; SetLayer(_clone, _layer); } float num = 1f; Vector3 val = _origin + Vector3.up * num; Vector3 val2 = _origin + new Vector3(0f, num + 0.15f, 0f - Zoom); _camGo.transform.position = val2; _camGo.transform.rotation = Quaternion.LookRotation(val - val2, Vector3.up); _lightGo.transform.rotation = Quaternion.Euler(35f, 25f, 0f); _fillGo.transform.rotation = Quaternion.Euler(15f, 160f, 0f); } } private static void SnapshotPlayer(Player p) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) object? value = VisRef.GetValue(p); VisEquipment val = (VisEquipment)((value is VisEquipment) ? value : null); if (!((Object)(object)val == (Object)null)) { sHelmet = GetI(val, "m_helmetItem"); sChest = GetI(val, "m_chestItem"); sLegs = GetI(val, "m_legItem"); sShoulder = GetI(val, "m_shoulderItem"); sShoulderVar = GetI(val, "m_shoulderItemVariant"); sShoulderQ = GetI(val, "m_shoulderItemQuality"); sUtility = GetI(val, "m_utilityItem"); sRight = GetI(val, "m_rightItem"); sRightQ = GetI(val, "m_rightItemQuality"); sLeft = GetI(val, "m_leftItem"); sLeftVar = GetI(val, "m_leftItemVariant"); sLeftQ = GetI(val, "m_leftItemQuality"); sModel = GetI(val, "m_modelIndex"); sHair = GetI(val, "m_hairItem"); sBeard = GetI(val, "m_beardItem"); FieldInfo fieldInfo = F("m_skinColor"); if (fieldInfo != null) { sSkin = (Vector3)fieldInfo.GetValue(val); } FieldInfo fieldInfo2 = F("m_hairColor"); if (fieldInfo2 != null) { sHairColor = (Vector3)fieldInfo2.GetValue(val); } } } private static void ApplyAppearance() { //IL_0014: 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) try { _vis.SetModel(sModel); _vis.SetSkinColor(sSkin); _vis.SetHairColor(sHairColor); _vis.SetHairItem(sHair); _vis.SetBeardItem(sBeard); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Внешность не скопирована: " + ex.Message)); } } private static void ApplyEquipment() { try { _vis.SetHelmetItem(SlotHash(0, sHelmet)); _vis.SetChestItem(SlotHash(1, sChest)); _vis.SetLegItem(SlotHash(2, sLegs)); if ((Object)(object)Slots[3] != (Object)null) { _vis.SetShoulderItem(Hash(Slots[3]), 0, 1); } else { _vis.SetShoulderItem((!Naked[3]) ? sShoulder : 0, sShoulderVar, Mathf.Max(1, sShoulderQ)); } _vis.SetUtilityItem(sUtility); if ((Object)(object)RightItem != (Object)null) { _vis.SetRightItem(Hash(RightItem), 1); } else { _vis.SetRightItem((!RightEmpty) ? sRight : 0, Mathf.Max(1, sRightQ)); } if ((Object)(object)LeftItem != (Object)null) { _vis.SetLeftItem(Hash(LeftItem), 0, 1); } else { _vis.SetLeftItem((!LeftEmpty) ? sLeft : 0, sLeftVar, Mathf.Max(1, sLeftQ)); } _vis.SetRightBackItem(0, 1); _vis.SetLeftBackItem(0, 0, 1); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Не удалось надеть вещи на манекен: " + ex.Message)); } } private static int FindFreeLayer() { for (int num = 31; num >= 8; num--) { if (string.IsNullOrEmpty(LayerMask.LayerToName(num))) { return num; } } return 31; } private static void SetLayer(GameObject go, int layer) { Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { ((Component)val).gameObject.layer = layer; } } private static void RemoveFromStaticList(Type t, string field, object item) { if (item == null) { return; } try { FieldInfo fieldInfo = AccessTools.Field(t, field); IList list = ((!(fieldInfo != null)) ? null : (fieldInfo.GetValue(null) as IList)); if (list != null) { while (list.Contains(item)) { list.Remove(item); } } } catch { } } private static void RemoveFromInstances(Character c) { if ((Object)(object)c == (Object)null) { return; } try { PropertyInfo propertyInfo = AccessTools.Property(typeof(Character), "Instances"); IList list = ((!(propertyInfo != null)) ? null : (propertyInfo.GetValue(null, null) as IList)); if (list != null) { while (list.Contains(c)) { list.Remove(c); } } } catch { } } } public static class Recolor { public class Preset { public string Ru; public string En; public Color Swatch; public float Hue = -1f; public float SatMul = 1f; public float ValMul = 1f; public float ValAdd; public float MinSat = 0.55f; public float Lift; public string Name => Loc.T(Ru, En); } [HarmonyPatch(typeof(VisEquipment), "SetHelmetEquipped")] private static class PHelmet { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_helmetItemInstance", hash); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")] private static class PChest { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_chestItemInstances", hash); ApplyBody(__instance, hash, "_ChestTex"); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")] private static class PLegs { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_legItemInstances", hash); ApplyBody(__instance, hash, "_LegsTex"); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped")] private static class PShoulder { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_shoulderItemInstances", hash); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetUtilityEquipped")] private static class PUtility { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_utilityItemInstances", hash); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")] private static class PRight { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_rightItemInstance", hash); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetLeftHandEquipped")] private static class PLeft { private static void Postfix(VisEquipment __instance, bool __result, int hash) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_leftItemInstance", hash); }); } } } [HarmonyPatch(typeof(VisEquipment), "SetBackEquipped")] private static class PBack { private static void Postfix(VisEquipment __instance, bool __result, int leftItem, int rightItem) { if (__result) { Safe(delegate { ApplyInstances(__instance, "m_leftBackItemInstance", leftItem); ApplyInstances(__instance, "m_rightBackItemInstance", rightItem); }); } } } public static readonly Preset[] Presets = new Preset[12] { new Preset { Ru = "Оригинал", En = "Original", Swatch = new Color(0.25f, 0.22f, 0.19f) }, new Preset { Ru = "Красный", En = "Red", Swatch = new Color(0.78f, 0.13f, 0.13f), Hue = 0f, MinSat = 0.65f }, new Preset { Ru = "Оранжевый", En = "Orange", Swatch = new Color(0.9f, 0.45f, 0.1f), Hue = 0.075f, MinSat = 0.78f, Lift = 0.3f }, new Preset { Ru = "Жёлтый", En = "Yellow", Swatch = new Color(0.9f, 0.78f, 0.15f), Hue = 0.14f, MinSat = 0.78f, Lift = 0.42f }, new Preset { Ru = "Зелёный", En = "Green", Swatch = new Color(0.2f, 0.62f, 0.22f), Hue = 0.33f }, new Preset { Ru = "Бирюзовый", En = "Teal", Swatch = new Color(0.1f, 0.62f, 0.62f), Hue = 0.49f, MinSat = 0.55f, Lift = 0.08f }, new Preset { Ru = "Синий", En = "Blue", Swatch = new Color(0.15f, 0.3f, 0.82f), Hue = 0.62f }, new Preset { Ru = "Фиолетовый", En = "Purple", Swatch = new Color(0.5f, 0.2f, 0.78f), Hue = 0.76f }, new Preset { Ru = "Розовый", En = "Pink", Swatch = new Color(0.9f, 0.35f, 0.62f), Hue = 0.91f, MinSat = 0.5f, Lift = 0.22f }, new Preset { Ru = "Чёрный", En = "Black", Swatch = new Color(0.08f, 0.08f, 0.09f), SatMul = 0.12f, ValMul = 0.32f }, new Preset { Ru = "Белый", En = "White", Swatch = new Color(0.92f, 0.92f, 0.9f), SatMul = 0.08f, ValMul = 0.45f, ValAdd = 0.55f }, new Preset { Ru = "Серый", En = "Grey", Swatch = new Color(0.5f, 0.5f, 0.52f), SatMul = 0.06f } }; public const string ZdoKey = "vw_recolors"; private static readonly Dictionary<string, int> Rules = new Dictionary<string, int>(); private static bool _loaded; private static string _rulesString = string.Empty; private static readonly Dictionary<string, float> HueCache = new Dictionary<string, float>(); private static readonly Dictionary<string, Texture2D> TexCache = new Dictionary<string, Texture2D>(); private static readonly Dictionary<string, Material> MatCache = new Dictionary<string, Material>(); private static readonly Dictionary<string, Sprite[]> OrigIcons = new Dictionary<string, Sprite[]>(); private static readonly Dictionary<string, Dictionary<string, int>> ParsedCache = new Dictionary<string, Dictionary<string, int>>(); private static readonly Dictionary<VisEquipment, string> SeenRemote = new Dictionary<VisEquipment, string>(); private static readonly FieldInfo VisRef = AccessTools.Field(typeof(Humanoid), "m_visEquipment"); private static readonly FieldInfo NviewRef = AccessTools.Field(typeof(VisEquipment), "m_nview"); private static readonly FieldInfo BodyRef = AccessTools.Field(typeof(VisEquipment), "m_bodyModel"); private static float _tick; private static readonly string[] HashFields = new string[9] { "m_currentLeftItemHash", "m_currentRightItemHash", "m_currentChestItemHash", "m_currentLegItemHash", "m_currentHelmetItemHash", "m_currentShoulderItemHash", "m_currentUtilityItemHash", "m_currentLeftBackItemHash", "m_currentRightBackItemHash" }; private static FieldInfo[] _hashFields; private static readonly string[] ColorProps = new string[3] { "_Color", "_TintColor", "_BaseColor" }; private static string FilePath => Path.Combine(Paths.ConfigPath, "umorise.valhallawardrobe.recolors.txt"); public static int Get(string prefab) { EnsureLoaded(); int value; return Rules.TryGetValue(prefab, out value) ? value : 0; } private static void EnsureLoaded() { if (_loaded) { return; } _loaded = true; try { if (File.Exists(FilePath)) { string[] array = File.ReadAllLines(FilePath); foreach (string text in array) { string[] array2 = text.Split('\t'); if (array2.Length >= 2 && int.TryParse(array2[1], out var result) && result > 0 && result < Presets.Length) { Rules[array2[0]] = result; } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Recolors not loaded: " + ex.Message)); } _rulesString = Serialize(Rules); } private static void Save() { try { File.WriteAllLines(FilePath, Rules.Select((KeyValuePair<string, int> kv) => kv.Key + "\t" + kv.Value).ToArray()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Recolors not saved: " + ex.Message)); } } private static string Serialize(Dictionary<string, int> r) { return string.Join(";", (from kv in r orderby kv.Key select kv.Key + ":" + kv.Value).ToArray()); } private static Dictionary<string, int> Parse(string s) { if (ParsedCache.TryGetValue(s, out var value)) { return value; } value = new Dictionary<string, int>(); string[] array = s.Split(';'); foreach (string text in array) { int num = text.LastIndexOf(':'); if (num > 0 && int.TryParse(text.Substring(num + 1), out var result) && result > 0 && result < Presets.Length) { value[text.Substring(0, num)] = result; } } if (ParsedCache.Count > 200) { ParsedCache.Clear(); } ParsedCache[s] = value; return value; } public static void Set(IEnumerable<ItemDrop> items, int preset) { EnsureLoaded(); foreach (ItemDrop item in items) { if (!((Object)(object)item == (Object)null)) { string name = ((Object)((Component)item).gameObject).name; if (preset <= 0) { Rules.Remove(name); } else { Rules[name] = preset; } ApplyIcon(item, preset); } } _rulesString = Serialize(Rules); Save(); Publish(); ForceRefresh(LocalVis()); ForceRefresh(Preview.Vis); } public static void ApplyAll() { EnsureLoaded(); ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (KeyValuePair<string, int> rule in Rules) { GameObject itemPrefab = instance.GetItemPrefab(rule.Key); ItemDrop val = ((!((Object)(object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>()); if ((Object)(object)val != (Object)null) { ApplyIcon(val, rule.Value); } } Publish(); ForceRefresh(LocalVis()); } private static VisEquipment LocalVis() { Player localPlayer = Player.m_localPlayer; return (VisEquipment)((!((Object)(object)localPlayer != (Object)null)) ? null : /*isinst with value type is only supported in some contexts*/); } private static ZDO ZdoOf(VisEquipment v) { object? value = NviewRef.GetValue(v); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); return (!((Object)(object)val != (Object)null) || !val.IsValid()) ? null : val.GetZDO(); } private static void Publish() { VisEquipment val = LocalVis(); if (!((Object)(object)val == (Object)null)) { ZDO val2 = ZdoOf(val); if (val2 != null && val2.GetString("vw_recolors", string.Empty) != _rulesString) { val2.Set("vw_recolors", _rulesString); } } } private static Dictionary<string, int> RulesFor(VisEquipment v) { if ((Object)(object)v == (Object)null) { return null; } if ((Object)(object)v == (Object)(object)LocalVis() || (Object)(object)v == (Object)(object)Preview.Vis) { EnsureLoaded(); return Rules; } ZDO val = ZdoOf(v); if (val == null) { return null; } string text = val.GetString("vw_recolors", string.Empty); return (!string.IsNullOrEmpty(text)) ? Parse(text) : null; } public static void Tick() { if (Time.unscaledTime - _tick < 1f) { return; } _tick = Time.unscaledTime; try { EnsureLoaded(); Publish(); VisEquipment val = LocalVis(); IList list = InstancesList(); if (list == null) { return; } HashSet<VisEquipment> alive = new HashSet<VisEquipment>(); foreach (object item in list) { VisEquipment val2 = (VisEquipment)((item is VisEquipment) ? item : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)val || (Object)(object)val2 == (Object)(object)Preview.Vis || !val2.m_isPlayer) { continue; } ZDO val3 = ZdoOf(val2); if (val3 == null) { continue; } alive.Add(val2); string text = val3.GetString("vw_recolors", string.Empty); if (!SeenRemote.TryGetValue(val2, out var value)) { SeenRemote[val2] = text; if (text.Length > 0) { ForceRefresh(val2); } } else if (value != text) { SeenRemote[val2] = text; ForceRefresh(val2); } } foreach (VisEquipment item2 in SeenRemote.Keys.Where((VisEquipment k) => (Object)(object)k == (Object)null || !alive.Contains(k)).ToList()) { SeenRemote.Remove(item2); } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Recolor tick: " + ex.Message)); } } private static IList InstancesList() { PropertyInfo propertyInfo = AccessTools.Property(typeof(VisEquipment), "Instances"); return (!(propertyInfo != null)) ? null : (propertyInfo.GetValue(null, null) as IList); } public static void ForceRefresh(VisEquipment v) { if ((Object)(object)v == (Object)null) { return; } if (_hashFields == null) { _hashFields = (from n in HashFields select AccessTools.Field(typeof(VisEquipment), n) into f where f != null select f).ToArray(); } FieldInfo[] hashFields = _hashFields; foreach (FieldInfo fieldInfo in hashFields) { fieldInfo.SetValue(v, -1); } } private static ItemDrop ItemOf(int hash) { if (hash == 0 || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash); return (!((Object)(object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>(); } private static int PresetFor(VisEquipment v, ItemDrop d) { if ((Object)(object)d == (Object)null) { return 0; } Dictionary<string, int> dictionary = RulesFor(v); int value; return (dictionary != null && dictionary.TryGetValue(((Object)((Component)d).gameObject).name, out value)) ? value : 0; } private static void ApplyInstance(VisEquipment v, GameObject inst, int hash) { if ((Object)(object)inst == (Object)null) { return; } ItemDrop d = ItemOf(hash); int num = PresetFor(v, d); if (num <= 0) { return; } float hue = HueOf(d); Preset p = Presets[num]; Renderer[] componentsInChildren = inst.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Name == "ParticleSystemRenderer") { continue; } Material[] sharedMaterials = val.sharedMaterials; bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = RecolorMaterialCached(sharedMaterials[j], hue, p, num); if ((Object)(object)val2 != (Object)(object)sharedMaterials[j]) { sharedMaterials[j] = val2; flag = true; } } if (flag) { val.sharedMaterials = sharedMaterials; } } } private static void ApplyInstances(VisEquipment v, string field, int hash) { FieldInfo fieldInfo = AccessTools.Field(typeof(VisEquipment), field); object obj = ((!(fieldInfo != null)) ? null : fieldInfo.GetValue(v)); if (obj is List<GameObject> list) { { foreach (GameObject item in list) { ApplyInstance(v, item, hash); } return; } } ApplyInstance(v, (GameObject)((obj is GameObject) ? obj : null), hash); } private static void ApplyBody(VisEquipment v, int hash, string prop) { ItemDrop val = ItemOf(hash); int num = PresetFor(v, val); if (num <= 0) { return; } Material armorMaterial = val.m_itemData.m_shared.m_armorMaterial; if ((Object)(object)armorMaterial == (Object)null || !armorMaterial.HasProperty(prop)) { return; } Texture texture = armorMaterial.GetTexture(prop); object? value = BodyRef.GetValue(v); SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)((value is SkinnedMeshRenderer) ? value : null); if ((Object)(object)texture == (Object)null || (Object)(object)val2 == (Object)null) { return; } try { ((Renderer)val2).material.SetTexture(prop, RecolorTexture(texture, HueOf(val), Presets[num], num)); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Recolor body: " + ex.Message)); } } private static Material RecolorMaterialCached(Material m, float hue, Preset p, int preset) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if ((Object)(object)m == (Object)null) { return null; } string key = ((Object)m).GetInstanceID() + ":" + preset + ":" + hue.ToString("0.000"); if (MatCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Material val = new Material(m); bool flag = RecolorTints(val, hue, p); if (m.HasProperty("_MainTex") && (Object)(object)m.GetTexture("_MainTex") != (Object)null) { val.SetTexture("_MainTex", RecolorTexture(m.GetTexture("_MainTex"), hue, p, preset)); flag = true; } if (!flag) { Object.Destroy((Object)(object)val); val = m; } MatCache[key] = val; return val; } private static float HueOf(ItemDrop d) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) string name = ((Object)((Component)d).gameObject).name; if (HueCache.TryGetValue(name, out var value)) { return value; } List<Texture> list = new List<Texture>(); List<Color> list2 = new List<Color>(); Renderer[] componentsInChildren = ((Component)d).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Name == "ParticleSystemRenderer") { continue; } Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 == (Object)null) { continue; } if (val2.HasProperty("_MainTex") && (Object)(object)val2.GetTexture("_MainTex") != (Object)null && !list.Contains(val2.GetTexture("_MainTex"))) { list.Add(val2.GetTexture("_MainTex")); } string[] colorProps = ColorProps; foreach (string text in colorProps) { if (val2.HasProperty(text)) { list2.Add(val2.GetColor(text)); } } } } Material armorMaterial = d.m_itemData.m_shared.m_armorMaterial; if ((Object)(object)armorMaterial != (Object)null) { string[] array = new string[2] { "_ChestTex", "_LegsTex" }; foreach (string text2 in array) { if (armorMaterial.HasProperty(text2) && (Object)(object)armorMaterial.GetTexture(text2) != (Object)null && !list.Contains(armorMaterial.GetTexture(text2))) { list.Add(armorMaterial.GetTexture(text2)); } } } try { value = DominantHue(list, list2); } catch { value = -1f; } HueCache[name] = value; return value; } private static void ApplyIcon(ItemDrop d, int preset) { SharedData shared = d.m_itemData.m_shared; string name = ((Object)((Component)d).gameObject).name; if (!OrigIcons.TryGetValue(name, out var value)) { value = ((shared.m_icons == null) ? null : ((Sprite[])shared.m_icons.Clone())); OrigIcons[name] = value; } if (value == null) { return; } if (preset <= 0) { shared.m_icons = (Sprite[])value.Clone(); return; } try { float hue = HueOf(d); Sprite[] array = (Sprite[])value.Clone(); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { array[i] = RecolorSprite(array[i], hue, Presets[preset], preset); } } shared.m_icons = array; } catch (Exception ex) { Plugin.Log.LogDebug((object)("Recolor icon: " + ex.Message)); } } private static void Safe(Action a) { try { a(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Recolor apply: " + ex.Message)); } } private static Color32[] ReadPixels(Texture src, int x, int y, int w, int h, out int outW, out int outH) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) RenderTexture temporary = RenderTexture.GetTemporary(src.width, src.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; Graphics.Blit(src, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(w, h, (TextureFormat)4, false, false); val.ReadPixels(new Rect((float)x, (float)y, (float)w, (float)h), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Color32[] pixels = val.GetPixels32(); Object.Destroy((Object)(object)val); outW = w; outH = h; return pixels; } private static float DominantHue(List<Texture> textures, List<Color> tints) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) float[] array = new float[36]; float num = 0f; float num3 = default(float); float num4 = default(float); float num5 = default(float); foreach (Texture texture in textures) { Color32[] array2; try { array2 = ReadPixels(texture, 0, 0, texture.width, texture.height, out var _, out var _); } catch { continue; } int num2 = Mathf.Max(1, array2.Length / 60000); for (int i = 0; i < array2.Length; i += num2) { Color32 val = array2[i]; if (val.a >= 128) { Color.RGBToHSV(Color32.op_Implicit(val), ref num3, ref num4, ref num5); if (!(num4 < 0.22f) && !(num5 < 0.12f)) { array[Mathf.Min(35, (int)(num3 * 36f))] += num4 * num5; num += num4 * num5; } } } } float num6 = default(float); float num7 = default(float); float num8 = default(float); foreach (Color tint in tints) { Color.RGBToHSV(tint, ref num6, ref num7, ref num8); if (!(num7 < 0.2f) && !(num8 < 0.1f)) { array[Mathf.Min(35, (int)(num6 * 36f))] += Mathf.Max(num * 0.35f, 1f) * num7; } } int num9 = -1; float num10 = 0f; for (int j = 0; j < 36; j++) { float num11 = array[j] + 0.6f * (array[(j + 1) % 36] + array[(j + 36 - 1) % 36]); if (num11 > num10) { num10 = num11; num9 = j; } } return (num9 >= 0) ? (((float)num9 + 0.5f) / 36f) : (-1f); } private static float HueDist(float a, float b) { float num = Mathf.Abs(a - b); return Mathf.Min(num, 1f - num); } private static void Transform(float h, float s, float v, float hue, Preset p, out float nh, out float ns, out float nv) { nh = h; ns = s; nv = v; if (p.Hue >= 0f) { float num = ((!(hue >= 0f)) ? 0f : (h - hue)); if (num > 0.5f) { num -= 1f; } if (num < -0.5f) { num += 1f; } nh = Mathf.Repeat(p.Hue + num * 0.4f, 1f); ns = Mathf.Clamp01(p.MinSat + s * (1f - p.MinSat)); nv = Mathf.Clamp01(v + (1f - v) * p.Lift); } else { ns = s * p.SatMul; nv = Mathf.Clamp01(v * p.ValMul + p.ValAdd); } } private static bool RecolorTints(Material m, float hue, Preset p) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) bool result = false; string[] colorProps = ColorProps; float num = default(float); float num2 = default(float); float v = default(float); foreach (string text in colorProps) { if (m.HasProperty(text)) { Color color = m.GetColor(text); Color.RGBToHSV(color, ref num, ref num2, ref v); if (!(num2 < 0.2f) && (!(hue >= 0f) || !(HueDist(num, hue) > 0.12f))) { Transform(num, num2, v, hue, p, out var nh, out var ns, out var nv); Color val = Color.HSVToRGB(nh, ns, nv); val.a = color.a; m.SetColor(text, val); result = true; } } } return result; } private static void RecolorPixels(Color32[] px, float hue, Preset p) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float v = default(float); for (int i = 0; i < px.Length; i++) { Color32 val = px[i]; Color.RGBToHSV(Color32.op_Implicit(val), ref num, ref num2, ref v); if (num2 < 0.08f) { continue; } float num3; if (hue < 0f) { num3 = 1f; } else { float num4 = HueDist(num, hue); if (num4 >= 0.12f) { continue; } num3 = ((!(num4 <= 0.07f)) ? (1f - (num4 - 0.07f) / 0.049999997f) : 1f); } num3 *= Mathf.Clamp01((num2 - 0.08f) / 0.1f); if (!(num3 <= 0f)) { Transform(num, num2, v, hue, p, out var nh, out var ns, out var nv); Color32 val2 = Color32.op_Implicit(Color.HSVToRGB(nh, ns, nv)); ref Color32 reference = ref px[i]; reference = new Color32((byte)Mathf.Lerp((float)(int)val.r, (float)(int)val2.r, num3), (byte)Mathf.Lerp((float)(int)val.g, (float)(int)val2.g, num3), (byte)Mathf.Lerp((float)(int)val.b, (float)(int)val2.b, num3), val.a); } } } private static Texture RecolorTexture(Texture src, float hue, Preset p, int preset) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00ab: 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) string key = ((Object)src).GetInstanceID() + ":" + preset + ":" + hue.ToString("0.000"); if (TexCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return (Texture)(object)value; } int outW; int outH; Color32[] array = ReadPixels(src, 0, 0, src.width, src.height, out outW, out outH); RecolorPixels(array, hue, p); Texture2D val = new Texture2D(outW, outH, (TextureFormat)4, true, false); ((Object)val).name = ((Object)src).name + "_recolor"; ((Texture)val).wrapMode = src.wrapMode; ((Texture)val).filterMode = src.filterMode; ((Texture)val).anisoLevel = src.anisoLevel; Texture2D val2 = val; val2.SetPixels32(array); val2.Apply(true, true); TexCache[key] = val2; return (Texture)(object)val2; } private static Sprite RecolorSprite(Sprite s, float hue, Preset p, int preset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) Rect textureRect = s.textureRect; int outW; int outH; Color32[] array = ReadPixels((Texture)(object)s.texture, (int)((Rect)(ref textureRect)).x, (int)((Rect)(ref textureRect)).y, (int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, out outW, out outH); RecolorPixels(array, hue, p); Texture2D val = new Texture2D(outW, outH, (TextureFormat)4, false, false); ((Object)val).name = ((Object)s).name + "_recolor"; Texture2D val2 = val; val2.SetPixels32(array); val2.Apply(false, true); return Sprite.Create(val2, new Rect(0f, 0f, (float)outW, (float)outH), new Vector2(0.5f, 0.5f), s.pixelsPerUnit); } } public class Window { private class Need { public ItemDrop Item; public int Amount; } public bool Open; public int ClosedFrame = -1; private int _tab; private int _role = -1; private int _modIdx = -1; private int _catIdx = -1; private int _biomeIdx = -1; private bool _biomeAndEarlier; private bool _showOutfit; private string _outfitName = string.Empty; private int _outfitIdx = -1; private int _slot = -1; private string _search = string.Empty; private Vector2 _listScroll; private Vector2 _detailScroll; private Entry _selArmor; private Entry _selWeapon; private int _quality = 1; private readonly HashSet<string> _expanded = new HashSet<string>(); private List<Entry> _filtered = new List<Entry>(); private string _filt