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 ItemCompare v1.0.9
ItemCompare.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jewelcrafting; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ItemCompare")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("ItemCompare")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.9")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.9.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ItemCompare { [BepInPlugin("Azumatt.ItemCompare", "ItemCompare", "1.0.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ItemComparePlugin : BaseUnityPlugin { public enum Toggle { Off, On } private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; } private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "ItemCompare"; internal const string ModVersion = "1.0.9"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.ItemCompare"; private static string ConfigFileName = "Azumatt.ItemCompare.cfg"; private static string ConfigFileFullPath; private readonly Harmony _harmony = new Harmony("Azumatt.ItemCompare"); public static readonly ManualLogSource ItemCompareLogger; public static bool ZenUILoaded; public const string ZenUIGridElements = "RootCache_ZenUI"; internal static ConfigEntry<KeyboardShortcut> HoverKeybind; internal static ConfigEntry<Toggle> KeyHoldNeeded; internal static ConfigEntry<Toggle> ShowConversionsInTooltip; public void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) KeyHoldNeeded = config("1 - General", "Key Hold Needed", Toggle.Off, "Should they key be held down to compare items? [Default: On]"); HoverKeybind = config<KeyboardShortcut>("1 - General", "Hover Keybind", new KeyboardShortcut((KeyCode)122, Array.Empty<KeyCode>()), "Key to hold down while hovering over an item to compare it to the item already equipped. [Default: Z]"); ShowConversionsInTooltip = config("1 - General", "Show Conversions in Tooltip", Toggle.Off, "Should the conversions of items be shown in the crafting menu description (tooltip)? [Default: Off]"); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); } public void Start() { if (Chainloader.PluginInfos.ContainsKey("ZenDragon.ZenUI")) { ZenUILoaded = true; } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { ItemCompareLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { ItemCompareLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); ItemCompareLogger.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description) { return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); } private ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } static ItemComparePlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ItemCompareLogger = Logger.CreateLogSource("ItemCompare"); ZenUILoaded = false; HoverKeybind = null; KeyHoldNeeded = null; ShowConversionsInTooltip = null; } } public static class KeyboardExtensions { public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } } public class Util { public static string ColorToHexString(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGB(color); } internal static ItemData? FindEquippedItemMatching(ItemData hoveredItem) { ItemData hoveredItem2 = hoveredItem; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return null; } if (!hoveredItem2.IsWeapon()) { return ((IEnumerable<ItemData>)((Humanoid)localPlayer).GetInventory().GetEquippedItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i.m_shared.m_itemType == hoveredItem2.m_shared.m_itemType)); } return ((IEnumerable<ItemData>)((Humanoid)localPlayer).GetInventory().GetEquippedItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i.IsWeapon())); } public static void AddDurabilityComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { float maxDurability = hoveredItem.GetMaxDurability(); float maxDurability2 = equippedItem.GetMaxDurability(); float num = maxDurability - maxDurability2; if (num != 0f) { comparisonText.AppendLine(string.Format("$item_durability: ({0}{1:+0;-0}</color>)", (num >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } } public static void AddDamageComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText, Player player) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_001c: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) DamageTypes damage = hoveredItem.GetDamage(); DamageTypes damage2 = equippedItem.GetDamage(); float num = damage.m_damage - damage2.m_damage; float num2 = damage.m_blunt - damage2.m_blunt; float num3 = damage.m_slash - damage2.m_slash; float num4 = damage.m_pierce - damage2.m_pierce; float num5 = damage.m_chop - damage2.m_chop; float num6 = damage.m_pickaxe - damage2.m_pickaxe; float num7 = damage.m_fire - damage2.m_fire; float num8 = damage.m_frost - damage2.m_frost; float num9 = damage.m_lightning - damage2.m_lightning; float num10 = damage.m_poison - damage2.m_poison; float num11 = damage.m_spirit - damage2.m_spirit; float num12 = ((DamageTypes)(ref damage)).GetTotalDamage() - ((DamageTypes)(ref damage2)).GetTotalDamage(); if (num != 0f) { comparisonText.AppendLine(string.Format("$inventory_damage: ({0}{1:+0;-0}</color>)", (num >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } if (num2 != 0f) { comparisonText.AppendLine(string.Format("$inventory_blunt: ({0}{1:+0;-0}</color>)", (num2 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num2)); } if (num3 != 0f) { comparisonText.AppendLine(string.Format("$inventory_slash: ({0}{1:+0;-0}</color>)", (num3 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num3)); } if (num4 != 0f) { comparisonText.AppendLine(string.Format("$inventory_pierce: ({0}{1:+0;-0}</color>)", (num4 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num4)); } if (num5 != 0f) { comparisonText.AppendLine(string.Format("$inventory_chop: ({0}{1:+0;-0}</color>)", (num5 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num5)); } if (num6 != 0f) { comparisonText.AppendLine(string.Format("$inventory_pickaxe: ({0}{1:+0;-0}</color>)", (num6 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num6)); } if (num7 != 0f) { comparisonText.AppendLine(string.Format("$inventory_fire: ({0}{1:+0;-0}</color>)", (num7 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num7)); } if (num8 != 0f) { comparisonText.AppendLine(string.Format("$inventory_frost: ({0}{1:+0;-0}</color>)", (num8 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num8)); } if (num9 != 0f) { comparisonText.AppendLine(string.Format("$inventory_lightning: ({0}{1:+0;-0}</color>)", (num9 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num9)); } if (num10 != 0f) { comparisonText.AppendLine(string.Format("$inventory_poison: ({0}{1:+0;-0}</color>)", (num10 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num10)); } if (num11 != 0f) { comparisonText.AppendLine(string.Format("$inventory_spirit: ({0}{1:+0;-0}</color>)", (num11 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num11)); } if (num12 != 0f) { comparisonText.AppendLine(string.Format("$item_total $inventory_damage: ({0}{1:+0;-0}</color>)", (num12 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num12)); } } public static void AddArmorComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { float armor = hoveredItem.GetArmor(); float armor2 = equippedItem.GetArmor(); float num = armor - armor2; if (num != 0f) { comparisonText.AppendLine(string.Format("$item_armor: ({0}{1:+0;-0}</color>)", (num >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } } public static void AddBowMechanicsComparison(ItemData h, ItemData e, StringBuilder sb) { StringBuilder sb2 = sb; float drawStaminaDrain = h.GetDrawStaminaDrain(); float drawStaminaDrain2 = e.GetDrawStaminaDrain(); float drawEitrDrain = h.GetDrawEitrDrain(); float drawEitrDrain2 = e.GetDrawEitrDrain(); float weaponLoadingTime = h.GetWeaponLoadingTime(); float weaponLoadingTime2 = e.GetWeaponLoadingTime(); if (drawStaminaDrain > 0f || drawStaminaDrain2 > 0f) { L("Stam hold/s", drawStaminaDrain, drawStaminaDrain2, lowerIsBetter: true); } if (drawEitrDrain > 0f || drawEitrDrain2 > 0f) { L("Eitr hold/s", drawEitrDrain, drawEitrDrain2, lowerIsBetter: true); } if (!Mathf.Approximately(weaponLoadingTime, weaponLoadingTime2)) { L("Reload", weaponLoadingTime, weaponLoadingTime2, lowerIsBetter: true); } void L(string n, float hv, float ev, bool lowerIsBetter = false) { if (!Mathf.Approximately(hv, ev)) { float num = hv - ev; bool flag = (lowerIsBetter ? (num <= 0f) : (num >= 0f)); sb2.AppendLine(string.Format("{0}: <color={1}>{2:+0.##;-0.##}</color> ({3:0.##} vs {4:0.##})", n, flag ? "green" : "red", lowerIsBetter ? (0f - Mathf.Abs(num)) : num, hv, ev)); } } } public static void AddDamageModsComparison(ItemData h, ItemData e, StringBuilder sb) { string text = ModsStr(h.m_shared.m_damageModifiers); string text2 = ModsStr(e.m_shared.m_damageModifiers); if (text != text2) { sb.AppendLine("Resists: <color=orange>" + text + "</color> vs <color=yellow>" + text2 + "</color>"); } static string ModsStr(List<DamageModPair> mods) { if (mods == null || mods.Count == 0) { return "—"; } return string.Join(", ", mods.Select((DamageModPair m) => $"{m.m_type}:{m.m_modifier}")); } } public static void AddSetBonusHeadline(ItemData item, StringBuilder sb) { SharedData shared = item.m_shared; if (Object.op_Implicit((Object)(object)shared.m_setStatusEffect) && shared.m_setSize > 0 && !string.IsNullOrEmpty(shared.m_setName)) { sb.AppendLine($"Set: <color=orange>{shared.m_setName}</color> ({shared.m_setSize}) → <color=yellow>{shared.m_setStatusEffect.m_name}</color>"); } } public static void AddEquipmentModifiers(ItemData h, ItemData e, StringBuilder sb) { StringBuilder sb2 = sb; SharedData shared = h.m_shared; SharedData shared2 = e.m_shared; M("Move speed", shared.m_movementModifier, shared2.m_movementModifier); M("Run stamina", shared.m_runStaminaModifier, shared2.m_runStaminaModifier); M("Jump stamina", shared.m_jumpStaminaModifier, shared2.m_jumpStaminaModifier); M("Swim stamina", shared.m_swimStaminaModifier, shared2.m_swimStaminaModifier); M("Sneak stamina", shared.m_sneakStaminaModifier, shared2.m_sneakStaminaModifier); M("Dodge stamina", shared.m_dodgeStaminaModifier, shared2.m_dodgeStaminaModifier); M("Attack stamina", shared.m_attackStaminaModifier, shared2.m_attackStaminaModifier); M("Block stamina", shared.m_blockStaminaModifier, shared2.m_blockStaminaModifier); M("Home items stamina", shared.m_homeItemsStaminaModifier, shared2.m_homeItemsStaminaModifier); M("Heat resistance", shared.m_heatResistanceModifier, shared2.m_heatResistanceModifier); M("Eitr regen", shared.m_eitrRegenModifier, shared2.m_eitrRegenModifier); void M(string name, float hv, float ev) { if (!Mathf.Approximately(hv, ev)) { float num = (hv - ev) * 100f; bool flag = num >= 0f; sb2.AppendLine(string.Format("{0}: <color={1}>{2:+0.##;-0.##}%</color> ({3:+0.##;-0.##}% vs {4:+0.##;-0.##}%)", name, flag ? "green" : "red", num, hv * 100f, ev * 100f)); } } } public static void AddStatusEffectsSummary(ItemData h, ItemData e, StringBuilder sb) { SharedData shared = h.m_shared; SharedData shared2 = e.m_shared; if (Object.op_Implicit((Object)(object)shared.m_equipStatusEffect) || Object.op_Implicit((Object)(object)shared2.m_equipStatusEffect)) { string text = (Object.op_Implicit((Object)(object)shared.m_equipStatusEffect) ? shared.m_equipStatusEffect.m_name : "—"); string text2 = (Object.op_Implicit((Object)(object)shared2.m_equipStatusEffect) ? shared2.m_equipStatusEffect.m_name : "—"); if (text != text2) { sb.AppendLine("Equip SE: <color=orange>" + text + "</color> vs <color=yellow>" + text2 + "</color>"); } } if (Object.op_Implicit((Object)(object)shared.m_attackStatusEffect) || Object.op_Implicit((Object)(object)shared2.m_attackStatusEffect)) { string text3 = (Object.op_Implicit((Object)(object)shared.m_attackStatusEffect) ? shared.m_attackStatusEffect.m_name : "—"); string text4 = (Object.op_Implicit((Object)(object)shared2.m_attackStatusEffect) ? shared2.m_attackStatusEffect.m_name : "—"); float attackStatusEffectChance = shared.m_attackStatusEffectChance; float attackStatusEffectChance2 = shared2.m_attackStatusEffectChance; if (text3 != text4 || !Mathf.Approximately(attackStatusEffectChance, attackStatusEffectChance2)) { sb.AppendLine($"On-hit SE: <color=orange>{text3}</color> {attackStatusEffectChance * 100f:0.#}% vs <color=yellow>{text4}</color> {attackStatusEffectChance2 * 100f:0.#}%"); } } } public static void AddAdrenalineComparison(ItemData h, ItemData e, StringBuilder sb) { StringBuilder sb2 = sb; SharedData shared = h.m_shared; SharedData shared2 = e.m_shared; Line("$item_parryadrenaline", shared.m_perfectBlockAdrenaline, shared2.m_perfectBlockAdrenaline); Line("Adrenaline on block", shared.m_blockAdrenaline, shared2.m_blockAdrenaline); Line("Adrenaline max", shared.m_maxAdrenaline, shared2.m_maxAdrenaline); StatusEffect fullAdrenalineSE = shared.m_fullAdrenalineSE; StatusEffect fullAdrenalineSE2 = shared2.m_fullAdrenalineSE; if ((Object)(object)fullAdrenalineSE != (Object)(object)fullAdrenalineSE2) { string text = (Object.op_Implicit((Object)(object)fullAdrenalineSE) ? fullAdrenalineSE.m_name : "—"); string text2 = (Object.op_Implicit((Object)(object)fullAdrenalineSE2) ? fullAdrenalineSE2.m_name : "—"); sb2.AppendLine("$item_fulladrenaline: <color=orange>" + text + "</color> vs <color=yellow>" + text2 + "</color>"); if (Object.op_Implicit((Object)(object)fullAdrenalineSE) && !Object.op_Implicit((Object)(object)fullAdrenalineSE2)) { sb2.AppendLine("+ $piece_smelter_add: <color=orange>" + fullAdrenalineSE.m_name + "</color> " + fullAdrenalineSE.GetTooltipString()); } else if (!Object.op_Implicit((Object)(object)fullAdrenalineSE) && Object.op_Implicit((Object)(object)fullAdrenalineSE2)) { sb2.AppendLine("- $hud_remove: <color=orange>" + fullAdrenalineSE2.m_name + "</color> " + fullAdrenalineSE2.GetTooltipString()); } else if (Object.op_Implicit((Object)(object)fullAdrenalineSE) && Object.op_Implicit((Object)(object)fullAdrenalineSE2) && fullAdrenalineSE.m_name != fullAdrenalineSE2.m_name) { sb2.AppendLine("- $hud_remove: <color=orange>" + fullAdrenalineSE2.m_name + "</color> " + fullAdrenalineSE2.GetTooltipString()); sb2.AppendLine("+ $piece_smelter_add: <color=orange>" + fullAdrenalineSE.m_name + "</color> " + fullAdrenalineSE.GetTooltipString()); } } void Line(string locKey, float hv, float ev) { if (!Mathf.Approximately(hv, ev)) { float num = hv - ev; sb2.AppendLine(string.Format("{0}: <color={1}>{2:+0.##;-0.##}</color> ({3:0.##} vs {4:0.##})", locKey, (num >= 0f) ? "green" : "red", num, hv, ev)); } } } public static void AddWeightComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { float weight = hoveredItem.GetWeight(-1); float weight2 = equippedItem.GetWeight(-1); float num = weight - weight2; if (num != 0f) { comparisonText.AppendLine(string.Format("$item_weight: ({0}{1:+0;-0}</color>)", (num >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } } public static void AddValueComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { int value = hoveredItem.GetValue(); int value2 = equippedItem.GetValue(); int num = value - value2; if (num != 0) { comparisonText.AppendLine(string.Format("$item_value: ({0}{1:+0;-0}</color>)", (num >= 0) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } } public static void AddUseComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder sb) { StringBuilder sb2 = sb; Attack attack = hoveredItem.m_shared.m_attack; Attack attack2 = equippedItem.m_shared.m_attack; Line("$item_staminause", attack.m_attackStamina, attack2.m_attackStamina, percent: false, lowerIsBetter: true); Line("$item_eitruse", attack.m_attackEitr, attack2.m_attackEitr, percent: false, lowerIsBetter: true); Line("$item_healthuse", attack.m_attackHealth, attack2.m_attackHealth, percent: false, lowerIsBetter: true); Line("$item_healthuse", attack.m_attackHealthPercentage, attack2.m_attackHealthPercentage, percent: true, lowerIsBetter: true); if (!Mathf.Approximately(attack.m_attackHealthReturnHit, attack2.m_attackHealthReturnHit)) { float num = attack.m_attackHealthReturnHit - attack2.m_attackHealthReturnHit; string text = ((num >= 0f) ? "green" : "red"); sb2.AppendLine($"$item_healthhitreturn: <color={text}>{num:+0.##;-0.##}</color> ({attack.m_attackHealthReturnHit:0.##} vs {attack2.m_attackHealthReturnHit:0.##})"); } void Line(string key, float hv, float ev, bool percent = false, bool lowerIsBetter = false, int decimals = 1) { if (!Mathf.Approximately(hv, ev)) { float num2 = hv - ev; string text2 = ((lowerIsBetter ? (num2 <= 0f) : (num2 >= 0f)) ? "green" : "red"); if (percent) { sb2.AppendLine($"{key}: <color={text2}>{num2:+0.#;-0.#}%</color> ({hv:0.#}% vs {ev:0.#}%)"); } else { sb2.AppendLine($"{key}: <color={text2}>{num2:+0.##;-0.##}</color> ({hv:0.##} vs {ev:0.##})"); } } } } public static void AddOtherStatComparison(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) float blockPower = hoveredItem.GetBlockPower(hoveredItem.m_quality, ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)6)); float blockPower2 = equippedItem.GetBlockPower(hoveredItem.m_quality, ((Character)Player.m_localPlayer).GetSkillFactor((SkillType)6)); float num = blockPower - blockPower2; float deflectionForce = hoveredItem.GetDeflectionForce(hoveredItem.m_quality); float deflectionForce2 = equippedItem.GetDeflectionForce(equippedItem.m_quality); float num2 = deflectionForce - deflectionForce2; float drawStaminaDrain = hoveredItem.GetDrawStaminaDrain(); float drawStaminaDrain2 = equippedItem.GetDrawStaminaDrain(); float num3 = drawStaminaDrain - drawStaminaDrain2; float attackForce = hoveredItem.m_shared.m_attackForce; float attackForce2 = equippedItem.m_shared.m_attackForce; float num4 = attackForce - attackForce2; float backstabBonus = hoveredItem.m_shared.m_backstabBonus; float backstabBonus2 = equippedItem.m_shared.m_backstabBonus; float num5 = backstabBonus - backstabBonus2; float eitrRegenModifier = hoveredItem.m_shared.m_eitrRegenModifier; float eitrRegenModifier2 = equippedItem.m_shared.m_eitrRegenModifier; float num6 = eitrRegenModifier - eitrRegenModifier2; float movementModifier = hoveredItem.m_shared.m_movementModifier; float movementModifier2 = equippedItem.m_shared.m_movementModifier; float num7 = movementModifier - movementModifier2; float timedBlockBonus = hoveredItem.m_shared.m_timedBlockBonus; float timedBlockBonus2 = equippedItem.m_shared.m_timedBlockBonus; float num8 = timedBlockBonus - timedBlockBonus2; if (num != 0f) { comparisonText.AppendLine(string.Format("$item_blockarmor: ({0}{1:+0;-0}</color>)", (num >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num)); } if (num2 != 0f) { comparisonText.AppendLine(string.Format("$item_blockforce: ({0}{1:+0;-0}</color>)", (num2 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num2)); } if (num8 != 0f) { comparisonText.AppendLine(string.Format("$item_parrybonus: ({0}{1:+0;-0}x</color>)", (num8 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num8)); } if (num3 != 0f) { comparisonText.AppendLine(string.Format("$item_staminahold: ({0}{1:+0;-0}</color>)", (num3 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num3)); } if (num4 != 0f) { comparisonText.AppendLine(string.Format("$item_knockback: ({0}{1:+0;-0}</color>)", (num4 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num4)); } if (num5 != 0f) { comparisonText.AppendLine(string.Format("$item_backstab: ({0}{1:+0;-0}x</color>)", (num5 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num5)); } if (num6 != 0f) { comparisonText.AppendLine(string.Format("$item_eitrregen_modifier: ({0}{1:+0;-0}</color>)", (num6 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num6)); } if (num7 != 0f) { comparisonText.AppendLine(string.Format("$item_movement_modifier: ({0}{1:+0;-0}</color>)", (num7 >= 0f) ? "<color=#00FF00>" : "<color=#FF0000>", num7)); } string statusEffectTooltip = hoveredItem.GetStatusEffectTooltip(hoveredItem.m_quality, ((Character)Player.m_localPlayer).GetSkillLevel(hoveredItem.m_shared.m_skillType)); string statusEffectTooltip2 = equippedItem.GetStatusEffectTooltip(equippedItem.m_quality, ((Character)Player.m_localPlayer).GetSkillLevel(equippedItem.m_shared.m_skillType)); if (statusEffectTooltip != statusEffectTooltip2) { comparisonText.AppendLine("\n\n$inventory_activeeffects:"); if (!string.IsNullOrEmpty(statusEffectTooltip2) && string.IsNullOrEmpty(statusEffectTooltip)) { comparisonText.AppendLine("<color=#FF0000>- $hud_remove: " + statusEffectTooltip2 + "</color>"); } else if (string.IsNullOrEmpty(statusEffectTooltip2) && !string.IsNullOrEmpty(statusEffectTooltip)) { comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: " + statusEffectTooltip + "</color>"); } else { comparisonText.AppendLine("<color=#FF0000>- $hud_remove: " + statusEffectTooltip2 + "</color>"); comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: " + statusEffectTooltip + "</color>"); } } string setStatusEffectTooltip = hoveredItem.GetSetStatusEffectTooltip(hoveredItem.m_quality, ((Character)Player.m_localPlayer).GetSkillLevel(hoveredItem.m_shared.m_skillType)); string setStatusEffectTooltip2 = equippedItem.GetSetStatusEffectTooltip(equippedItem.m_quality, ((Character)Player.m_localPlayer).GetSkillLevel(equippedItem.m_shared.m_skillType)); if (setStatusEffectTooltip != setStatusEffectTooltip2) { comparisonText.AppendLine("\n\n$item_seteffect:"); if (!string.IsNullOrEmpty(setStatusEffectTooltip2) && string.IsNullOrEmpty(setStatusEffectTooltip)) { comparisonText.AppendLine("<color=#FF0000>- $hud_remove: <color=orange>" + equippedItem.m_shared.m_setStatusEffect.m_name + "</color> " + setStatusEffectTooltip2 + "</color>"); return; } if (string.IsNullOrEmpty(setStatusEffectTooltip2) && !string.IsNullOrEmpty(setStatusEffectTooltip)) { comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: <color=orange>" + hoveredItem.m_shared.m_setStatusEffect.m_name + "</color> " + setStatusEffectTooltip + "</color>"); return; } comparisonText.AppendLine("<color=#FF0000>- $hud_remove: <color=orange>" + equippedItem.m_shared.m_setStatusEffect.m_name + "</color> " + setStatusEffectTooltip2 + "</color>"); comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: <color=orange>" + hoveredItem.m_shared.m_setStatusEffect.m_name + "</color> " + setStatusEffectTooltip + "</color>"); } } public static void AddSeInformation(ItemData hoveredItem, ItemData equippedItem, StringBuilder comparisonText) { string damageModifiersTooltipString = SE_Stats.GetDamageModifiersTooltipString(hoveredItem.m_shared.m_damageModifiers); string damageModifiersTooltipString2 = SE_Stats.GetDamageModifiersTooltipString(equippedItem.m_shared.m_damageModifiers); if (damageModifiersTooltipString != damageModifiersTooltipString2) { if (!string.IsNullOrEmpty(damageModifiersTooltipString2) && string.IsNullOrEmpty(damageModifiersTooltipString)) { comparisonText.AppendLine("<color=#FF0000>- $hud_remove: " + damageModifiersTooltipString2 + "</color>"); return; } if (string.IsNullOrEmpty(damageModifiersTooltipString2) && !string.IsNullOrEmpty(damageModifiersTooltipString)) { comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: " + damageModifiersTooltipString + "</color>"); return; } comparisonText.AppendLine("<color=#FF0000>- $hud_remove: " + damageModifiersTooltipString2 + "</color>"); comparisonText.AppendLine("<color=#00FF00>+ $piece_smelter_add: " + damageModifiersTooltipString + "</color>"); } } } } namespace ItemCompare.Patches { public class DescriptionExpander { [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] [HarmonyAfter(new string[] { "org.bepinex.plugins.jewelcrafting" })] [HarmonyPriority(700)] public static class InventoryGuiUpdateRecipePatch { public static void Postfix(InventoryGui __instance) { TMP_Text recipeDesc = __instance.m_recipeDecription; if ((Object)(object)recipeDesc == (Object)null) { return; } Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var value); if (value != null && __instance.InCraftTab() && (Object)(object)value.Instance != (Object)null) { if (__instance.m_itemCraftType.text.Length > 0) { recipeDesc.text = recipeDesc.text + Environment.NewLine + Environment.NewLine + "<color=yellow>" + __instance.m_itemCraftType.text + "</color>"; } __instance.m_itemCraftType.text = ""; } if (!((Object)(object)((Component)recipeDesc).GetComponent<ContentSizeFitter>() != (Object)null)) { ((Component)recipeDesc).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; RecipeDescTweaks(ref recipeDesc); GameObject scrollRectGo = GenScrollView(ref __instance); RectTransform vrt = GenViewPort(ref scrollRectGo, ref recipeDesc); ScrollRect scrollRect = GenScrollRect(ref scrollRectGo, ref recipeDesc, ref vrt); GenScrollBar(ref __instance, ref scrollRectGo, ref scrollRect); } } } internal static void RecipeDescTweaks(ref TMP_Text? recipeDesc) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) if ((Object)(object)recipeDesc != (Object)null) { recipeDesc.enableAutoSizing = false; recipeDesc.fontSize = 18f; recipeDesc.rectTransform.anchorMin = new Vector2(0f, 1f); recipeDesc.rectTransform.anchorMax = new Vector2(1f, 1f); recipeDesc.rectTransform.pivot = new Vector2(0f, 1f); recipeDesc.textWrappingMode = (TextWrappingModes)1; recipeDesc.rectTransform.anchoredPosition = new Vector2(4f, 4f); ((Graphic)recipeDesc).raycastTarget = false; } } internal static GameObject GenScrollView(ref InventoryGui __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("RecipeExpansionScrollView", new Type[3] { typeof(RectTransform), typeof(ScrollRect), typeof(Image) }); val.transform.SetParent(__instance.m_recipeDecription.transform.parent, false); val.transform.SetSiblingIndex(0); Transform transform = val.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val2 != (Object)null) { val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(11f, -74f); val2.SetSizeWithCurrentAnchors((Axis)0, 330f); val2.SetSizeWithCurrentAnchors((Axis)1, 300f); } ((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.2f); return val; } internal static RectTransform GenViewPort(ref GameObject scrollRectGo, ref TMP_Text? recipeDesc) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("RecipeExpansionViewport", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }); val.transform.SetParent(scrollRectGo.transform, false); Transform transform = val.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); val2.anchorMin = new Vector2(0f, 0f); val2.anchorMax = new Vector2(1f, 1f); val2.sizeDelta = new Vector2(0f, 0f); TMP_Text? obj = recipeDesc; if (obj != null) { obj.transform.SetParent((Transform)(object)val2, false); } return val2; } internal static ScrollRect GenScrollRect(ref GameObject scrollRectGo, ref TMP_Text? recipeDesc, ref RectTransform vrt) { ScrollRect component = scrollRectGo.GetComponent<ScrollRect>(); component.viewport = vrt; TMP_Text? obj = recipeDesc; component.content = ((obj != null) ? obj.rectTransform : null); component.horizontal = false; component.vertical = true; component.verticalScrollbarVisibility = (ScrollbarVisibility)1; component.scrollSensitivity = 40f; component.inertia = true; component.movementType = (MovementType)2; ((UnityEventBase)component.onValueChanged).RemoveAllListeners(); return component; } internal static void GenScrollBar(ref InventoryGui __instance, ref GameObject scrollRectGo, ref ScrollRect scrollRect) { Scrollbar newScrollbar = Object.Instantiate<Scrollbar>(__instance.m_recipeListScroll, scrollRectGo.transform); newScrollbar.size = 0.4f; ((UnityEvent<Vector2>)(object)scrollRect.onValueChanged).AddListener((UnityAction<Vector2>)delegate { newScrollbar.size = 0.4f; }); scrollRect.verticalScrollbar = newScrollbar; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class GatherConversions { public static readonly Dictionary<string?, ItemDrop?> CookingStationConversions = new Dictionary<string, ItemDrop>(); public static readonly Dictionary<string?, ItemDrop?> FermenterConversions = new Dictionary<string, ItemDrop>(); [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { CookingStation val = default(CookingStation); Fermenter val2 = default(Fermenter); foreach (GameObject prefab in __instance.m_prefabs) { if (prefab.TryGetComponent<CookingStation>(ref val)) { foreach (ItemConversion item in val.m_conversion) { if (!CookingStationConversions.ContainsKey(item.m_from.m_itemData?.m_shared?.m_name)) { CookingStationConversions.Add(item.m_from.m_itemData?.m_shared?.m_name, item.m_to); } } } if (!prefab.TryGetComponent<Fermenter>(ref val2)) { continue; } foreach (ItemConversion item2 in val2.m_conversion) { if (!FermenterConversions.ContainsKey(item2.m_from.m_itemData?.m_shared?.m_name)) { FermenterConversions.Add(item2.m_from.m_itemData?.m_shared?.m_name, item2.m_to); } } } } } [HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")] internal static class InventoryGridCreateItemTooltipPatch { public static GameObject ClonedTooltip; [HarmonyPriority(0)] [HarmonyAfter(new string[] { "org.bepinex.plugins.jewelcrafting", "randyknapp.mods.epicloot" })] public static void Postfix(ItemData item, UITooltip tooltip, InventoryGrid __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) if (!ItemComparePlugin.HoverKeybind.Value.IsKeyHeld() && ItemComparePlugin.KeyHoldNeeded.Value != 0) { return; } ItemData val = Util.FindEquippedItemMatching(item); if (val != null && val != item) { if ((Object)(object)ClonedTooltip != (Object)null) { Object.Destroy((Object)(object)ClonedTooltip); ClonedTooltip = null; } GameObject tooltipPrefab = tooltip.m_tooltipPrefab; if (!((Object)(object)tooltipPrefab == (Object)null)) { ClonedTooltip = Object.Instantiate<GameObject>(tooltipPrefab, ((Component)((Component)((Component)tooltip).transform).GetComponentInParent<Canvas>()).transform); RectTransform component = ((Component)tooltip).GetComponent<RectTransform>(); RectTransform component2 = ClonedTooltip.GetComponent<RectTransform>(); component2.sizeDelta = component.sizeDelta; component2.anchorMin = component.anchorMin; component2.anchorMax = component.anchorMax; component2.pivot = component.pivot; ((Transform)component2).position = ((Transform)component).position; ((Transform)component2).localScale = ((Transform)component).localScale; ((Transform)component2).localRotation = ((Transform)component).localRotation; ((Transform)component2).localEulerAngles = ((Transform)component).localEulerAngles; ((Transform)component2).localPosition = ((Transform)component).localPosition; component2.offsetMin = component.offsetMin; component2.offsetMax = component.offsetMax; UpdateClonedTooltipText(ClonedTooltip, item); } } } private static void UpdateClonedTooltipText(GameObject clonedTooltip, ItemData hoveredItem) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) ItemData val = Util.FindEquippedItemMatching(hoveredItem); string text = Util.ColorToHexString((Color)((!API.IsLoaded()) ? Color.yellow : (((??)API.GetSocketableItemColor(hoveredItem)) ?? Color.yellow))); string text2 = ((val != null) ? Util.ColorToHexString((Color)((!API.IsLoaded()) ? Color.yellow : (((??)API.GetSocketableItemColor(val)) ?? Color.yellow))) : "FFFFFF"); string text3 = Localization.instance.Localize("$hud_equipping"); string text4 = Environment.NewLine + text3 + " <color=#" + text + ">" + Localization.instance.Localize(hoveredItem.m_shared.m_name) + "</color> changes the following stats:" + Environment.NewLine + Environment.NewLine + GenerateComparisonText(hoveredItem); string text5 = "<color=#" + text2 + ">" + Localization.instance.Localize(val?.m_shared.m_name) + " (Equipped)</color>"; if (API.IsLoaded()) { Transform jewelcraftingTooltipRoot = API.GetJewelcraftingTooltipRoot(clonedTooltip); if (jewelcraftingTooltipRoot != null) { API.FillItemContainerTooltip(val, jewelcraftingTooltipRoot, showInteract: false); } } Transform val2 = Utils.FindChild(clonedTooltip.transform, "Text", (IterativeSearchType)0); if ((Object)(object)val2 != (Object)null) { TMP_Text component = ((Component)val2).GetComponent<TMP_Text>(); if ((Object)(object)component != (Object)null) { component.text = text4; } } Transform val3 = Utils.FindChild(clonedTooltip.transform, "Topic", (IterativeSearchType)0); if ((Object)(object)val3 != (Object)null) { TMP_Text component2 = ((Component)val3).GetComponent<TMP_Text>(); if ((Object)(object)component2 != (Object)null) { component2.text = text5; } } } internal static string GenerateComparisonText(ItemData hoveredItem) { StringBuilder stringBuilder = new StringBuilder(); Player localPlayer = Player.m_localPlayer; ItemData val = Util.FindEquippedItemMatching(hoveredItem); if (val != null) { Util.AddDurabilityComparison(hoveredItem, val, stringBuilder); Util.AddWeightComparison(hoveredItem, val, stringBuilder); Util.AddUseComparison(hoveredItem, val, stringBuilder); Util.AddDamageComparison(hoveredItem, val, stringBuilder, localPlayer); Util.AddArmorComparison(hoveredItem, val, stringBuilder); Util.AddBowMechanicsComparison(hoveredItem, val, stringBuilder); Util.AddAdrenalineComparison(hoveredItem, val, stringBuilder); Util.AddDamageModsComparison(hoveredItem, val, stringBuilder); Util.AddEquipmentModifiers(hoveredItem, val, stringBuilder); Util.AddSetBonusHeadline(hoveredItem, stringBuilder); Util.AddStatusEffectsSummary(hoveredItem, val, stringBuilder); Util.AddValueComparison(hoveredItem, val, stringBuilder); Util.AddOtherStatComparison(hoveredItem, val, stringBuilder); Util.AddSeInformation(hoveredItem, val, stringBuilder); } return Localization.instance.Localize(stringBuilder.ToString()); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int) })] [HarmonyBefore(new string[] { "Azumatt.BindOnEquip" })] internal static class ItemDropItemDataGetTooltipPatch { [UsedImplicitly] [HarmonyPriority(0)] private static void Postfix(ItemData item, bool crafting, ref string __result) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!crafting) { return; } string text = ""; if (item.m_dropPrefab == null) { return; } ItemData val = Util.FindEquippedItemMatching(item); if (val != null) { string text2 = Util.ColorToHexString((Color)((!API.IsLoaded()) ? Color.yellow : (((??)API.GetSocketableItemColor(item)) ?? Color.yellow))); string text3 = Util.ColorToHexString((Color)((!API.IsLoaded()) ? Color.yellow : (((??)API.GetSocketableItemColor(val)) ?? Color.yellow))); string text4 = Environment.NewLine + Environment.NewLine + "<color=#" + text2 + ">" + Localization.instance.Localize(item.m_shared.m_name) + "</color> vs. <color=#" + text3 + ">" + Localization.instance.Localize(val?.m_shared.m_name) + " (Equipped)</color>:" + Environment.NewLine + Environment.NewLine; text = text + text4 + InventoryGridCreateItemTooltipPatch.GenerateComparisonText(item); } if (ItemComparePlugin.ShowConversionsInTooltip.Value == ItemComparePlugin.Toggle.On) { if (GatherConversions.CookingStationConversions.TryGetValue(item.m_shared.m_name, out ItemDrop value)) { text = text + Environment.NewLine + Environment.NewLine + "Turns into:" + Environment.NewLine; text = text + Localization.instance.Localize(value?.m_itemData?.m_shared.m_name) + Environment.NewLine; string text5 = text; object obj; if (value == null) { obj = null; } else { ItemData itemData = value.m_itemData; obj = ((itemData != null) ? itemData.GetTooltip(-1) : null); } text = text5 + (string?)obj; } if (GatherConversions.FermenterConversions.TryGetValue(item.m_shared.m_name, out ItemDrop value2)) { text = text + Environment.NewLine + Environment.NewLine + "Turns into:" + Environment.NewLine; text = text + Localization.instance.Localize(value2?.m_itemData?.m_shared.m_name) + Environment.NewLine; string text6 = text; object obj2; if (value2 == null) { obj2 = null; } else { ItemData itemData2 = value2.m_itemData; obj2 = ((itemData2 != null) ? itemData2.GetTooltip(-1) : null); } text = text6 + (string?)obj2; } } __result += text; } } [HarmonyPatch(typeof(UITooltip), "OnHoverStart")] internal static class UITooltipOnHoverStartPatch { public static void Postfix() { if ((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip != (Object)null) { InventoryGridCreateItemTooltipPatch.ClonedTooltip.SetActive(true); } } } [HarmonyPatch(typeof(UITooltip), "OnPointerExit")] public static class UITooltipOnPointerExitPatch { public static void Prefix() { if (!((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip == (Object)null)) { Object.Destroy((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip); InventoryGridCreateItemTooltipPatch.ClonedTooltip = null; } } } [HarmonyPatch(typeof(UITooltip), "HideTooltip")] internal static class UITooltipHideTooltipPatch { private static void Prefix(UITooltip __instance) { if (!((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip == (Object)null)) { Object.Destroy((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip); InventoryGridCreateItemTooltipPatch.ClonedTooltip = null; } } } [HarmonyPatch(typeof(UITooltip), "LateUpdate")] internal static class UITooltipLateUpdatePatch { private static void Postfix(UITooltip __instance) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)InventoryGridCreateItemTooltipPatch.ClonedTooltip == (Object)null || (Object)(object)UITooltip.m_current != (Object)(object)__instance || !Object.op_Implicit((Object)(object)UITooltip.m_tooltip)) { return; } RectTransform val = (RectTransform)((UITooltip.m_tooltip.transform.childCount > 0) ? /*isinst with value type is only supported in some contexts*/: /*isinst with value type is only supported in some contexts*/); if (!Object.op_Implicit((Object)(object)val)) { return; } RectTransform val2 = ResolveComparePanel(InventoryGridCreateItemTooltipPatch.ClonedTooltip); if (!Object.op_Implicit((Object)(object)val2)) { return; } LayoutRebuilder.ForceRebuildLayoutImmediate(val); LayoutRebuilder.ForceRebuildLayoutImmediate(val2); Vector3 val3 = (ShouldPlaceLeft(((Component)__instance).GetComponent<RectTransform>()) ? Vector3.left : Vector3.right); if (!UITooltip.m_tooltip.activeSelf) { __instance.m_showTimer += Time.deltaTime; if ((double)__instance.m_showTimer > 0.5 || (ZInput.IsGamepadActive() && !ZInput.IsMouseActive())) { InventoryGridCreateItemTooltipPatch.ClonedTooltip.SetActive(true); } } else { InventoryGridCreateItemTooltipPatch.ClonedTooltip.SetActive(true); } Rect rect = val2.rect; Vector3 val4 = val3 * (((Rect)(ref rect)).width + 16f); ((Transform)val2).position = ((Transform)val).position + val4 * GuiScaler.m_largeGuiScale; Utils.ClampUIToScreen(val2); } private static RectTransform? ResolveComparePanel(GameObject root) { if (API.IsLoaded()) { Transform jewelcraftingTooltipRoot = API.GetJewelcraftingTooltipRoot(root); if (Object.op_Implicit((Object)(object)jewelcraftingTooltipRoot)) { Transform transform = ((Component)jewelcraftingTooltipRoot).transform; return (RectTransform?)(object)((transform is RectTransform) ? transform : null); } } if (root.transform.childCount > 0) { Transform child = root.transform.GetChild(0); return (RectTransform?)(object)((child is RectTransform) ? child : null); } Transform transform2 = root.transform; return (RectTransform?)(object)((transform2 is RectTransform) ? transform2 : null); } private static bool ShouldPlaceLeft(RectTransform originalRT) { try { if (!ItemComparePlugin.ZenUILoaded) { return false; } Transform val = (Object.op_Implicit((Object)(object)originalRT) ? ((Component)originalRT).transform.parent : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } return ((Object)val).name.IndexOf("RootCache_ZenUI", StringComparison.OrdinalIgnoreCase) >= 0; } catch { return false; } } } } namespace Jewelcrafting { [PublicAPI] internal static class API { [PublicAPI] public class GemInfo { public readonly string gemPrefab; public readonly Dictionary<string, uint>? gemSeed; public readonly Sprite gemSprite; public readonly Dictionary<string, float> gemEffects; public readonly Dictionary<string, float[]> gemEffectsPowerRange; public GemInfo(string gemPrefab, Sprite gemSprite, Dictionary<string, float> gemEffects, Dictionary<string, float[]> gemEffectsPowerRange, Dictionary<string, uint>? gemSeed = null) { this.gemPrefab = gemPrefab; this.gemSeed = gemSeed; this.gemSprite = gemSprite; this.gemEffects = gemEffects; this.gemEffectsPowerRange = gemEffectsPowerRange; base..ctor(); } } public delegate bool GemBreakHandler(ItemData? container, ItemData gem, int count = 1); public delegate bool ItemBreakHandler(ItemData? container); public delegate bool ItemMirroredHandler(ItemData? item); public static event Action? OnEffectRecalc; public static bool IsLoaded() { return false; } internal static void InvokeEffectRecalc() { API.OnEffectRecalc?.Invoke(); } public static GameObject CreateNecklaceFromTemplate(string colorName, Color color) { return null; } public static GameObject CreateNecklaceFromTemplate(string colorName, Material material) { return null; } public static GameObject CreateRingFromTemplate(string colorName, Color color) { return null; } public static GameObject CreateRingFromTemplate(string colorName, Material material) { return null; } public static void MarkJewelry(GameObject jewelry) { } public static void AddGems(string type, string colorName, Color color) { } public static List<GameObject> AddGems(string type, string colorName, Material material, Color color) { return null; } public static GameObject AddDestructibleFromTemplate(string type, string colorName, Color color) { return null; } public static GameObject AddDestructibleFromTemplate(string type, string colorName, Material material) { return null; } public static GameObject AddUncutFromTemplate(string type, string colorName, Color color) { return null; } public static GameObject AddUncutFromTemplate(string type, string colorName, Material material) { return null; } public static GameObject AddAndRegisterUncutFromTemplate(string type, string colorName, Color color) { return null; } public static GameObject AddAndRegisterUncutFromTemplate(string type, string colorName, Material material) { return null; } public static GameObject AddShardFromTemplate(string type, string colorName, Color color) { return null; } public static GameObject AddShardFromTemplate(string type, string colorName, Material material) { return null; } public static GameObject[] AddTieredGemFromTemplate(string type, string colorName, Color color) { return null; } public static GameObject[] AddTieredGemFromTemplate(string type, string colorName, Material material, Color color) { return null; } public static void AddGem(GameObject prefab, string colorName) { } public static void AddShard(GameObject prefab, string colorName) { } public static void AddDestructible(GameObject prefab, string colorName) { } public static void AddUncutGem(GameObject prefab, string colorName, ConfigEntry<float>? dropChance = null) { } public static void AddGemEffect<T>(string name, string? englishDescription = null, string? englishDescriptionDetailed = null) where T : struct { } public static void AddGemConfig(string yaml) { } public static T GetEffectPower<T>(this Player player, string name) where T : struct { return default(T); } public static List<GemInfo?> GetGems(ItemData item) { return new List<GemInfo>(); } public static bool SetGems(ItemData item, List<GemInfo?> gems) { return false; } public static Sprite GetSocketBorder() { return null; } public static GameObject GetGemcuttersTable() { return null; } public static void AddParticleEffect(string prefabName, GameObject effect, VisualEffectCondition displayCondition) { } public static void SetSocketsLock(ItemData item, bool enabled) { } public static void OnGemBreak(GemBreakHandler callback) { } public static void OnItemBreak(ItemBreakHandler callback) { } public static void OnItemMirrored(ItemMirroredHandler callback) { } public static bool IsJewelryEquipped(Player player, string prefabName) { return false; } public static bool BlacklistItem(GameObject item) { return false; } public static Transform? GetJewelcraftingTooltipRoot(GameObject tooltip) { return null; } public static bool FillItemContainerTooltip(ItemData? item, Transform root, bool showInteract) { return false; } public static Color? GetSocketableItemColor(ItemData item) { return null; } } [AttributeUsage(AttributeTargets.Field)] internal abstract class PowerAttribute : Attribute { public abstract float Add(float a, float b); } internal class AdditivePowerAttribute : PowerAttribute { public override float Add(float a, float b) { return a + b; } } internal class MultiplicativePercentagePowerAttribute : PowerAttribute { public override float Add(float a, float b) { return ((1f + a / 100f) * (1f + b / 100f) - 1f) * 100f; } } internal class InverseMultiplicativePercentagePowerAttribute : PowerAttribute { public override float Add(float a, float b) { return (1f - (1f - a / 100f) * (1f - b / 100f)) * 100f; } } internal class MinPowerAttribute : PowerAttribute { public override float Add(float a, float b) { return Mathf.Min(a, b); } } internal class MaxPowerAttribute : PowerAttribute { public override float Add(float a, float b) { return Mathf.Max(a, b); } } [AttributeUsage(AttributeTargets.Field)] internal class OptionalPowerAttribute : Attribute { public readonly float DefaultValue; public OptionalPowerAttribute(float defaultValue) { DefaultValue = defaultValue; } } [Flags] internal enum VisualEffectCondition : uint { IsSkill = 0xFFFu, Swords = 1u, Knives = 2u, Clubs = 3u, Polearms = 4u, Spears = 5u, Blocking = 6u, Axes = 7u, Bows = 8u, Unarmed = 0xBu, Pickaxes = 0xCu, WoodCutting = 0xDu, Crossbows = 0xEu, IsItem = 0xFF000u, Helmet = 0x6000u, Chest = 0x7000u, Legs = 0xB000u, Hands = 0xC000u, Shoulder = 0x11000u, Tool = 0x13000u, GenericExtraAttributes = 0xFF000000u, Blackmetal = 0x40000000u, TwoHanded = 0x80000000u, SpecificExtraAttributes = 0xF00000u, Hammer = 0x113000u, Hoe = 0x213000u, Buckler = 0x100006u, Towershield = 0x200006u, FineWoodBow = 0x100008u, BowHuntsman = 0x200008u, BowDraugrFang = 0x300008u, PickaxeIron = 0x10000Cu, Club = 0x100003u } }