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 PerfectStatusHUD v0.2.1
plugins/PerfectStatusHUD/PerfectStatusHUD.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Bootstrap; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace PerfectStatusHUD; [BepInPlugin("com.perfectmods.statushud", "Perfect Status HUD", "0.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private sealed class CompendiumEntry { internal TextInfo Text; internal List<Sprite> Icons; } private sealed class HudRow { internal RectTransform Row; internal RectTransform Icon; internal RectTransform Timer; internal Image Image; internal Transform Cooldown; } private static readonly Dictionary<TextsDialog, CompendiumEntry> compendiumEntries = new Dictionary<TextsDialog, CompendiumEntry>(); private readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private readonly HashSet<string> logged = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private float nextScan; private readonly HashSet<string> matchedIcons = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private float nextAudit = 15f; private Harmony harmony; private readonly HashSet<Sprite> ownedSprites = new HashSet<Sprite>(); private readonly Dictionary<string, Sprite> originalPrefabIcons = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private readonly HashSet<StatusEffect> liveEffects = new HashSet<StatusEffect>(); private readonly List<StatusEffect> retiredEffects = new List<StatusEffect>(); private readonly Dictionary<StatusEffect, Sprite> originalIcons = new Dictionary<StatusEffect, Sprite>(); private static readonly FieldInfo hudRowsField = AccessTools.Field(typeof(Hud), "m_statusEffects"); private readonly List<HudRow> hudRows = new List<HudRow>(); private Hud cachedHud; private ObjectDB cachedDatabase; private Vector2 cachedTemplateSize; private float cachedTimerHeight; private string lastAudit; private static readonly Dictionary<string, string> names = CreateNames(); private static Plugin active; private static readonly HashSet<string> meadSprites = new HashSet<string>(new string[20] { "PSH_deathstinger_resist", "PSH_lightfoot_mead", "PSH_health_major", "PSH_health_medium", "PSH_health_minor", "PSH_love_potion", "PSH_powerful_healing_mead", "PSH_stamina_major", "PSH_stamina_medium", "PSH_stamina_minor", "PSH_troll_strength_mead", "PSH_eitr_minor", "PSH_vananidir_drink", "PSH_ratatosk_elixir", "PSH_frost_resist_mead", "PSH_antidote_mead", "PSH_barley_wine", "PSH_tasty_mead", "PSH_powerful_eitr", "PSH_berserker_mead" }, StringComparer.OrdinalIgnoreCase); private void PatchCompendium() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown try { harmony.Patch((MethodBase)AccessTools.Method(typeof(TextsDialog), "AddActiveEffects", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CompendiumEffectsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(TextsDialog), "ShowText", new Type[1] { typeof(TextInfo) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CompendiumShowPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(TextsDialog), "OnClose", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "CompendiumClosePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Compendium effect icons patch active"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Compendium patch: " + ex)); } } private static void CompendiumEffectsPostfix(TextsDialog __instance) { if ((Object)(object)active == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } try { active.ScanEffects(); if (!(FieldValue(__instance, "m_texts") is List<TextInfo> { Count: not 0 } list)) { return; } List<StatusEffect> list2 = new List<StatusEffect>(); ((Character)Player.m_localPlayer).GetSEMan().GetHUDStatusEffects(list2); List<Sprite> icons = new List<Sprite>(); StringBuilder stringBuilder = new StringBuilder("<indent=64>"); foreach (StatusEffect item in list2) { if (!((Object)(object)item == (Object)null) && !item.m_hidden) { AppendCompendiumEffect(stringBuilder, icons, item); stringBuilder.Append("\n\n"); } } StatusEffect val = default(StatusEffect); float num = default(float); Player.m_localPlayer.GetGuardianPowerHUD(ref val, ref num); if ((Object)(object)val != (Object)null) { active.ReplaceAll(new StatusEffect[1] { val }); stringBuilder.Append("<color=yellow>").Append(Localization.instance.Localize("$inventory_selectedgp")).Append("</color>\n"); AppendCompendiumEffect(stringBuilder, icons, val); } stringBuilder.Append("</indent>"); list[0].m_text = stringBuilder.ToString(); if ((Object)(object)((Component)__instance).GetComponent<CompendiumDialogLifetime>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<CompendiumDialogLifetime>(); } compendiumEntries[__instance] = new CompendiumEntry { Text = list[0], Icons = icons }; } catch (Exception ex) { if (active.logged.Add("compendium-effects-error")) { ((BaseUnityPlugin)active).Logger.LogWarning((object)("Compendium effects: " + ex)); } } } private static void AppendCompendiumEffect(StringBuilder body, List<Sprite> icons, StatusEffect effect) { body.Append("<link=\"PSH_").Append(icons.Count).Append("\"><color=orange>") .Append(Localization.instance.Localize(effect.m_name)) .Append("</color></link>\n") .Append(Localization.instance.Localize(effect.GetTooltipString())); icons.Add(effect.m_icon); } private static void CompendiumShowPostfix(TextsDialog __instance, TextInfo __0) { if ((Object)(object)active == (Object)null || (Object)(object)__instance.m_textArea == (Object)null) { return; } try { CompendiumIconLayout compendiumIconLayout = ((Component)__instance.m_textArea).GetComponent<CompendiumIconLayout>(); if (!compendiumEntries.TryGetValue(__instance, out var value) || !object.ReferenceEquals(value.Text, __0)) { if ((Object)(object)compendiumIconLayout != (Object)null) { compendiumIconLayout.SetIcons(null); } return; } if ((Object)(object)compendiumIconLayout == (Object)null) { compendiumIconLayout = ((Component)__instance.m_textArea).gameObject.AddComponent<CompendiumIconLayout>(); } compendiumIconLayout.SetIcons(value.Icons); } catch (Exception ex) { if (active.logged.Add("compendium-layout-error")) { ((BaseUnityPlugin)active).Logger.LogWarning((object)("Compendium layout: " + ex)); } } } private static void CompendiumClosePostfix(TextsDialog __instance) { ClearCompendium(__instance); } private static void CleanupCompendium() { foreach (TextsDialog item in new List<TextsDialog>(compendiumEntries.Keys)) { if ((Object)(object)item == (Object)null) { continue; } if ((Object)(object)item.m_textArea != (Object)null) { CompendiumIconLayout component = ((Component)item.m_textArea).GetComponent<CompendiumIconLayout>(); if ((Object)(object)component != (Object)null) { component.SetIcons(null); Object.Destroy((Object)(object)component); } } CompendiumDialogLifetime component2 = ((Component)item).GetComponent<CompendiumDialogLifetime>(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } } compendiumEntries.Clear(); } internal static void ClearCompendium(TextsDialog dialog) { if (object.ReferenceEquals(dialog, null)) { return; } compendiumEntries.Remove(dialog); if (!((Object)(object)dialog == (Object)null) && !((Object)(object)dialog.m_textArea == (Object)null)) { CompendiumIconLayout component = ((Component)dialog.m_textArea).GetComponent<CompendiumIconLayout>(); if ((Object)(object)component != (Object)null) { component.SetIcons(null); } } } private static Dictionary<string, string> CreateNames() { Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); Add(dictionary, "resting", "SE_Resting", "Resting", "$se_resting"); Add(dictionary, "fire", "SE_NearFire", "NearFire", "SE_Fire", "$se_fire", "$se_nearfire", "$se_fireplace"); Add(dictionary, "wisp_light", "SE_WispLight", "WispLight", "SE_Wisp", "Wisp", "$se_wisplight", "$se_wisp"); Add(dictionary, "no_skill_drain", "SE_NoSkillDrain", "NoSkillDrain", "$se_noskilldrain", "SE_Death", "Death", "$se_death", "SE_DeathProtection", "DeathProtection", "$se_deathprotection", "$se_noskillloss", "$se_no_skill_drain"); Add(dictionary, "rested", "SE_Rested", "Rested", "$se_rested"); Add(dictionary, "feather", "SE_FeatherFall", "FeatherFall", "SE_Feather", "$se_featherfall"); Add(dictionary, "wet", "SE_Wet", "Wet", "$se_wet"); Add(dictionary, "corpse_run", "SE_CorpseRun", "CorpseRun", "$se_corpserun"); Add(dictionary, "shelter", "SE_Shelter", "Shelter", "$se_shelter", "$se_sheltered"); Add(dictionary, "sneaky", "SE_Sneaky", "Sneaky", "SE_Sneak", "$se_sneaky"); Add(dictionary, "archer", "SE_SkilledArcher", "SkilledArcher", "$se_skilledarcher"); Add(dictionary, "berserker", "SE_Berserker", "Berserker", "SE_Berserk", "$se_berserker"); Add(dictionary, "encumbered", "SE_Encumbered", "Encumbered", "$se_encumbered"); Add(dictionary, "smoke", "SE_Smoke", "Smoke", "$se_smoke"); Add(dictionary, "freezing", "SE_Freezing", "Freezing", "$se_freezing"); Add(dictionary, "cold", "SE_Cold", "Cold", "$se_cold"); Add(dictionary, "burning", "SE_Burning", "Burning", "$se_burning", "SE_Burn", "$se_burn"); Add(dictionary, "immobilized", "SE_Immobilized", "Immobilized", "$se_immobilized", "SE_Rooted", "Rooted", "$se_rooted"); Add(dictionary, "harpooned", "SE_Harpooned", "Harpooned", "$se_harpooned"); Add(dictionary, "magic_barrier", "SE_Shield", "SE_StaffShield", "SE_Staff_shield", "StaffShield", "Staff_shield", "$se_shield", "$se_staffshield", "$se_staff_shield", "SE_MagicBarrier", "MagicBarrier", "$se_magicbarrier"); Add(dictionary, "fishing_hat", "SE_FishingHat", "FishingHat", "$se_fishinghat", "SE_Fishing", "Fishing", "$se_fishing"); Add(dictionary, "fenris_blessing", "SE_Fenris", "SE_FenrisBlessing", "SE_FenrisSet", "SetEffect_Fenris", "SetEffect_FenrisArmor", "$se_fenris", "$se_fenrisblessing"); Add(dictionary, "tarred", "SE_Tarred", "Tarred", "$se_tarred"); Add(dictionary, "slimed", "SE_Slimed", "Slimed", "$se_slimed"); Add(dictionary, "wind_run", "SE_WindRun", "WindRun", "$se_windrun"); Add(dictionary, "ask_endurance", "SE_Ask", "SE_AskEndurance", "SetEffect_AskArmor", "SetEffect_Ask", "$se_ask", "$se_askendurance"); Add(dictionary, "rotting_rage", "SE_RottingRage", "RottingRage", "$se_rottingrage"); Add(dictionary, "frost", "SE_Frost", "Frost", "$se_frost"); Add(dictionary, "lightning", "SE_Lightning", "Lightning", "$se_lightning"); Add(dictionary, "staggered", "SE_Stagger", "SE_Staggered", "Staggered", "$se_stagger", "$se_staggered"); Add(dictionary, "poison", "SE_Poison", "Poison", "$se_poison"); Add(dictionary, "harvester", "SetEffect_HarvesterArmor", "SE_Harvester", "Harvester", "$se_harvester"); Add(dictionary, "sick", "SE_Vomit", "SE_Sick", "SE_FeelingSick", "FeelingSick", "$se_sick", "$se_feelingsick", "$se_vomit"); Add(dictionary, "health_minor", "Potion_health_minor", "SE_Potion_health_minor", "$se_potion_health_minor"); Add(dictionary, "health_medium", "Potion_health_medium", "SE_Potion_health_medium", "$se_potion_health_medium"); Add(dictionary, "health_major", "Potion_health_major", "SE_Potion_health_major", "$se_potion_health_major"); Add(dictionary, "stamina_minor", "Potion_stamina_minor", "SE_Potion_stamina_minor", "$se_potion_stamina_minor"); Add(dictionary, "stamina_medium", "Potion_stamina_medium", "SE_Potion_stamina_medium", "$se_potion_stamina_medium"); Add(dictionary, "stamina_major", "Potion_stamina_major", "SE_Potion_stamina_major", "$se_potion_stamina_major"); Add(dictionary, "queen", "GP_Queen", "SE_Queen", "Queen", "$se_queen"); Add(dictionary, "bonemass", "GP_Bonemass", "SE_Bonemass", "Bonemass", "$se_bonemass"); Add(dictionary, "moder", "GP_Moder", "SE_Moder", "Moder", "$se_moder"); Add(dictionary, "yagluth", "GP_Yagluth", "SE_Yagluth", "Yagluth", "$se_yagluth"); Add(dictionary, "eikthyr", "GP_Eikthyr", "SE_Eikthyr", "Eikthyr", "$se_eikthyr"); Add(dictionary, "elder", "GP_TheElder", "SE_TheElder", "TheElder", "The Elder", "$se_theelder", "$se_elder"); Add(dictionary, "frost_resist_mead", "Potion_frostresist", "SE_Potion_frostresist", "$se_potion_frostresist"); Add(dictionary, "antidote_mead", "Potion_poisonresist", "SE_Potion_poisonresist", "$se_potion_poisonresist"); Add(dictionary, "barley_wine", "Potion_barleywine", "SE_Potion_barleywine", "$se_potion_barleywine"); Add(dictionary, "dvergr_power", "SE_DvergrPower", "DvergrPower", "$se_dvergrpower"); Add(dictionary, "megingjord", "SE_Megingjord", "Megingjord", "$se_megingjord"); Add(dictionary, "lox_set", "SE_LoxSet", "SetEffect_Lox", "SetEffect_LoxArmor", "LoxSet", "$se_loxset", "$se_loxarmor"); Add(dictionary, "duzhka", "SE_Duzhka", "Duzhka", "$se_duzhka"); Add(dictionary, "vanguard", "SE_Vanguard", "Vanguard", "$se_vanguard"); Add(dictionary, "love_potion", "SE_LovePotion", "LovePotion", "Potion_love", "SE_Potion_love", "$se_lovepotion", "$se_potion_love"); Add(dictionary, "eitr_minor", "SE_EitrMinor", "EitrMinor", "Potion_eitr_minor", "SE_Potion_eitr_minor", "$se_potion_eitr_minor"); Add(dictionary, "berserker_mead", "SE_BerserkerMead", "BerserkerMead", "Potion_berserker", "SE_Potion_berserker", "$se_berserkermead"); Add(dictionary, "lightfoot_mead", "SE_LightfootMead", "LightfootMead", "Potion_lightfoot", "SE_Potion_lightfoot", "$se_lightfootmead"); Add(dictionary, "troll_strength_mead", "SE_TrollStrengthMead", "TrollStrengthMead", "Potion_trollstrength", "SE_Potion_trollstrength", "$se_trollstrengthmead"); Add(dictionary, "vananidir_drink", "SE_Vananidir", "SE_VananidirDrink", "Vananidir", "VananidirDrink", "Potion_vananidir", "SE_Potion_vananidir", "$se_vananidir"); Add(dictionary, "beast_whisper", "SE_BeastWhisper", "BeastWhisper", "Potion_beastwhisper", "SE_Potion_beastwhisper", "$se_beastwhisper"); Add(dictionary, "deathstinger_resist", "SE_DeathstingerResist", "DeathstingerResist", "Potion_deathstingerresist", "SE_Potion_deathstingerresist", "$se_deathstingerresist"); Add(dictionary, "ratatosk_elixir", "SE_Ratatosk", "SE_RatatoskElixir", "Ratatosk", "RatatoskElixir", "Potion_ratatosk", "SE_Potion_ratatosk", "$se_ratatosk"); Add(dictionary, "powerful_eitr", "SE_PowerfulEitr", "PowerfulEitr", "Potion_eitr_major", "SE_Potion_eitr_major", "$se_powerfuleitr"); Add(dictionary, "tasty_mead", "SE_TastyMead", "TastyMead", "Potion_tasty", "SE_Potion_tasty", "$se_tastymead"); Add(dictionary, "powerful_healing_mead", "SE_PowerfulHealingMead", "PowerfulHealingMead", "Potion_health_mega", "SE_Potion_health_mega", "Potion_health_powerful", "SE_Potion_health_powerful", "$se_powerfulhealingmead"); Add(dictionary, "fire", "CampFire", "$se_fire_name"); Add(dictionary, "wisp_light", "Demister", "$item_demister"); Add(dictionary, "no_skill_drain", "SoftDeath", "$se_softdeath_name"); Add(dictionary, "feather", "SlowFall", "$se_slowfall_name"); Add(dictionary, "smoke", "Smoked", "$se_smoked_name"); Add(dictionary, "tarred", "Tared", "$se_tared_name"); Add(dictionary, "sick", "Puke", "$se_puke_name"); Add(dictionary, "megingjord", "BeltStrength", "$item_beltstrength"); Add(dictionary, "duzhka", "Wishbone", "$se_wishbone_name"); Add(dictionary, "fenris_blessing", "SetEffect_FenringArmor", "$se_fenringseteffect_name"); Add(dictionary, "ask_endurance", "SetEffect_AshlandsMediumArmor", "$se_ashlandsmediumarmorseteffect_name"); Add(dictionary, "rotting_rage", "SetEffect_BerserkerUndeadArmor", "$se_berserker_undead_effect_name"); Add(dictionary, "vanguard", "SetEffect_DeepNorthMediumArmor", "$se_deepnorthmediumarmorseteffect_name"); Add(dictionary, "fishing_hat", "SetEffect_FishingHat", "$item_helmet_fishinghat"); Add(dictionary, "archer", "SetEffect_RootArmor", "$se_rootseteffect_name"); Add(dictionary, "sneaky", "SetEffect_TrollArmor", "$se_trollseteffect_name"); Add(dictionary, "berserker", "SetEffect_BerserkerArmor", "$se_berserkereffect_name"); Add(dictionary, "lox_set", "SetEffect_LoxArmor", "$se_loxseteffect_name"); Add(dictionary, "dvergr_power", "SE_Dvergr_buff", "$dvergr_buff"); Add(dictionary, "stamina_major", "Potion_stamina_lingering", "$item_mead_stamina_lingering"); Add(dictionary, "powerful_eitr", "Potion_eitr_lingering", "$item_mead_eitr_lingering"); Add(dictionary, "powerful_healing_mead", "Potion_health_lingering", "$item_mead_hp_lingering"); Add(dictionary, "berserker_mead", "Potion_bzerker", "$item_mead_bzerker"); Add(dictionary, "lightfoot_mead", "Potion_LightFoot", "$item_mead_lightfoot"); Add(dictionary, "troll_strength_mead", "Potion_strength", "$item_mead_strength"); Add(dictionary, "vananidir_drink", "Potion_swimmer", "$item_mead_swimmer"); Add(dictionary, "beast_whisper", "Potion_tamer", "$item_mead_tamer"); Add(dictionary, "deathstinger_resist", "Potion_BugRepellent", "$item_mead_bugrepellent"); Add(dictionary, "ratatosk_elixir", "Potion_hasty", "$item_mead_hasty"); Add(dictionary, "love_potion", "Potion_TrollPheromones", "$item_mead_trollpheromones"); Add(dictionary, "immobilized", "ImmobilizedAshlands", "ImmobilizedLong"); Add(dictionary, "fader", "GP_Fader", "SE_Fader", "$se_fader_name"); Add(dictionary, "northern_vengeance", "Staff_FrostOrbs", "$se_frostorbs"); return dictionary; } private static void Add(Dictionary<string, string> m, string icon, params string[] aliases) { foreach (string key in aliases) { m[key] = icon; } } private void Awake() { //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0216: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { int num = text.IndexOf(".Assets.", StringComparison.OrdinalIgnoreCase); if (num < 0 || !text.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { continue; } string text2 = text.Substring(num + ".Assets.".Length); text2 = text2.Substring(0, text2.Length - 4); try { using Stream stream = executingAssembly.GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), false)) { Object.Destroy((Object)(object)val); ((BaseUnityPlugin)this).Logger.LogWarning((object)("Invalid PNG: " + text2)); continue; } ((Object)val).name = "PSH_" + text2; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Rect val2 = VisibleBounds(val); Sprite val3 = Sprite.Create(val, val2, new Vector2(0.5f, 0.5f), 100f); val.Apply(false, true); ((Object)val3).name = ((Object)val).name; sprites[text2] = val3; ownedSprites.Add(val3); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("PNG load error " + text2 + ": " + ex.Message)); } } try { harmony = new Harmony("com.perfectmods.statushud.hudfix"); Type type = FindType("Hud"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "UpdateStatusEffects", (Type[])null, (Type[])null)); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin).GetMethod("HudPrefix", BindingFlags.Static | BindingFlags.NonPublic)), new HarmonyMethod(typeof(Plugin).GetMethod("HudPostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HUD status refresh patch active"); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Hud.UpdateStatusEffects not found; using periodic replacement"); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("HUD patch: " + ex2.Message)); } PatchCompendium(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Perfect Status HUD 0.2.1: loaded " + sprites.Count + " icons; direct StatusEffect.m_icon replacement only.")); } private static Rect VisibleBounds(Texture2D texture) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Color32[] pixels = texture.GetPixels32(); int num = ((Texture)texture).width; int num2 = ((Texture)texture).height; int num3 = -1; int num4 = -1; for (int i = 0; i < ((Texture)texture).height; i++) { for (int j = 0; j < ((Texture)texture).width; j++) { if (pixels[i * ((Texture)texture).width + j].a >= 32) { num = Math.Min(num, j); num3 = Math.Max(num3, j); num2 = Math.Min(num2, i); num4 = Math.Max(num4, i); } } } if (num3 < num) { return new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); } return new Rect((float)num, (float)num2, (float)(num3 - num + 1), (float)(num4 - num2 + 1)); } private void OnEnable() { active = this; } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)active == (Object)(object)this) { active = null; } CleanupCompendium(); foreach (KeyValuePair<StatusEffect, Sprite> originalIcon in originalIcons) { if ((Object)(object)originalIcon.Key != (Object)null && (Object)(object)originalIcon.Key.m_icon != (Object)null && ownedSprites.Contains(originalIcon.Key.m_icon)) { originalIcon.Key.m_icon = originalIcon.Value; } } originalIcons.Clear(); liveEffects.Clear(); retiredEffects.Clear(); foreach (Sprite value in sprites.Values) { if (!((Object)(object)value == (Object)null)) { Texture2D texture = value.texture; Object.Destroy((Object)(object)value); if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } } } sprites.Clear(); ownedSprites.Clear(); originalPrefabIcons.Clear(); hudRows.Clear(); } private static void HudPrefix(List<StatusEffect> __0) { if ((Object)(object)active != (Object)null) { active.ReplaceAll(__0); } } private static void HudPostfix(Hud __instance) { if ((Object)(object)active != (Object)null) { active.ResizeHudIcons(__instance); } } private void ResizeHudIcons(Hud hud) { //IL_0067: 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_0070: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)hud == (Object)null || (Object)(object)hud.m_statusEffectTemplate == (Object)null || hudRowsField == null || !(hudRowsField.GetValue(hud) is List<RectTransform> list)) { return; } Transform obj = ((Transform)hud.m_statusEffectTemplate).Find("Icon"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if ((Object)(object)val == (Object)null) { return; } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; if (size.x <= 0f || size.y <= 0f) { return; } Transform obj2 = ((Transform)hud.m_statusEffectTemplate).Find("TimeText"); RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); float num; if (!((Object)(object)val2 == (Object)null)) { Rect rect2 = val2.rect; num = Mathf.Max(18f, ((Rect)(ref rect2)).height); } else { num = 18f; } float num2 = num; bool flag = (Object)(object)cachedHud != (Object)(object)hud || hudRows.Count != list.Count || cachedTemplateSize != size || cachedTimerHeight != num2; if (!flag) { for (int i = 0; i < list.Count; i++) { if ((Object)(object)hudRows[i].Row != (Object)(object)list[i]) { flag = true; break; } } } if (flag) { hudRows.Clear(); cachedHud = hud; cachedTemplateSize = size; cachedTimerHeight = num2; float num3 = Mathf.Min(size.x, size.y); for (int j = 0; j < list.Count; j++) { RectTransform val3 = list[j]; HudRow hudRow = new HudRow(); hudRow.Row = val3; hudRows.Add(hudRow); if ((Object)(object)val3 == (Object)null) { continue; } val3.anchoredPosition = new Vector2(-4f - (float)(j % 7) * (size.x + 6f), (float)(-(j / 7)) * (size.y + num2 + 6f)); ref RectTransform icon = ref hudRow.Icon; Transform obj3 = ((Transform)val3).Find("Icon"); icon = (RectTransform)(object)((obj3 is RectTransform) ? obj3 : null); ref RectTransform timer = ref hudRow.Timer; Transform obj4 = ((Transform)val3).Find("TimeText"); timer = (RectTransform)(object)((obj4 is RectTransform) ? obj4 : null); hudRow.Cooldown = ((Transform)val3).Find("Cooldown"); if ((Object)(object)hudRow.Icon == (Object)null) { continue; } hudRow.Icon.SetSizeWithCurrentAnchors((Axis)0, num3); hudRow.Icon.SetSizeWithCurrentAnchors((Axis)1, num3); hudRow.Image = ((Component)hudRow.Icon).GetComponent<Image>(); if ((Object)(object)hudRow.Image != (Object)null) { hudRow.Image.preserveAspect = true; } TMP_Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val4 in componentsInChildren) { if ((Object)(object)hudRow.Timer == (Object)null || ((Object)(object)val4.transform != (Object)(object)hudRow.Timer && !val4.transform.IsChildOf((Transform)(object)hudRow.Timer))) { ((Behaviour)val4).enabled = false; } } if ((Object)(object)hudRow.Timer != (Object)null) { Vector2 val5 = (hudRow.Icon.anchorMin + hudRow.Icon.anchorMax) * 0.5f; RectTransform timer2 = hudRow.Timer; Vector2 anchorMin = (hudRow.Timer.anchorMax = val5); timer2.anchorMin = anchorMin; hudRow.Timer.pivot = new Vector2(0.5f, 0.5f); hudRow.Timer.sizeDelta = new Vector2(size.x + 6f, num2); hudRow.Timer.anchoredPosition = hudRow.Icon.anchoredPosition + new Vector2((0.5f - hudRow.Icon.pivot.x) * size.x, (0f - hudRow.Icon.pivot.y) * size.y - num2 * 0.5f - 2f); } } } foreach (HudRow hudRow2 in hudRows) { if ((Object)(object)hudRow2.Image != (Object)null && (Object)(object)hudRow2.Image.sprite != (Object)null && (Object)(object)hudRow2.Cooldown != (Object)null && ((Component)hudRow2.Cooldown).gameObject.activeSelf && IsMeadIcon(((Object)hudRow2.Image.sprite).name)) { ((Component)hudRow2.Cooldown).gameObject.SetActive(false); } } } catch (Exception ex) { if (logged.Add("hud-layout-error")) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("HUD compact layout: " + ex.Message)); } } } private static bool IsMeadIcon(string spriteName) { if (spriteName != null) { return meadSprites.Contains(spriteName); } return false; } private void Update() { if (Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 2f; ScanEffects(); if (!(Time.unscaledTime >= nextAudit)) { return; } nextAudit = Time.unscaledTime + 60f; List<string> list = new List<string>(); foreach (string key in sprites.Keys) { if (!matchedIcons.Contains(key)) { list.Add(key); } } list.Sort(StringComparer.Ordinal); string text = "Icon audit: " + matchedIcons.Count + "/" + sprites.Count + " matched; not yet observed: " + string.Join(", ", list.ToArray()); if (text != lastAudit) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); lastAudit = text; } } private void ScanEffects() { try { liveEffects.Clear(); if ((Object)(object)cachedDatabase != (Object)(object)ObjectDB.instance) { originalPrefabIcons.Clear(); cachedDatabase = ObjectDB.instance; } if ((Object)(object)ObjectDB.instance != (Object)null) { foreach (StatusEffect statusEffect in ObjectDB.instance.m_StatusEffects) { if ((Object)(object)statusEffect != (Object)null) { liveEffects.Add(statusEffect); } } ReplaceAll(ObjectDB.instance.m_StatusEffects); } if ((Object)(object)Player.m_localPlayer != (Object)null) { List<StatusEffect> statusEffects = ((Character)Player.m_localPlayer).GetSEMan().GetStatusEffects(); foreach (StatusEffect item in statusEffects) { if ((Object)(object)item != (Object)null) { liveEffects.Add(item); } } ReplaceAll(statusEffects); StatusEffect val = default(StatusEffect); float num = default(float); Player.m_localPlayer.GetGuardianPowerHUD(ref val, ref num); if ((Object)(object)val != (Object)null) { liveEffects.Add(val); } } retiredEffects.Clear(); foreach (KeyValuePair<StatusEffect, Sprite> originalIcon in originalIcons) { if (!((Object)(object)originalIcon.Key != (Object)null) || !liveEffects.Contains(originalIcon.Key)) { if ((Object)(object)originalIcon.Key != (Object)null && (Object)(object)originalIcon.Key.m_icon != (Object)null && ownedSprites.Contains(originalIcon.Key.m_icon)) { originalIcon.Key.m_icon = originalIcon.Value; } retiredEffects.Add(originalIcon.Key); } } foreach (StatusEffect retiredEffect in retiredEffects) { originalIcons.Remove(retiredEffect); } retiredEffects.Clear(); } catch (Exception ex) { if (logged.Add("status-scan-error|" + ex.Message)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Status scan: " + ex.Message)); } } } private void ReplaceAll(IEnumerable effects) { if (effects == null) { return; } foreach (object effect in effects) { StatusEffect val = (StatusEffect)((effect is StatusEffect) ? effect : null); if ((Object)(object)val == (Object)null) { continue; } Sprite icon = val.m_icon; if ((Object)(object)icon != (Object)null && ownedSprites.Contains(icon)) { if (!originalIcons.ContainsKey(val) && originalPrefabIcons.TryGetValue(((Object)val).name.Replace("(Clone)", "").Trim(), out var value)) { originalIcons.Add(val, value); } continue; } string name = ((Object)val).name; string name2 = val.m_name; string text = Resolve(name, name2, ((object)val).GetType().Name); if (text == null) { text = ResolveNovaPearl(Chainloader.PluginInfos.ContainsKey("nova.chitinarmor"), name); } if (text == null) { text = ResolveLocalized(name2); } Sprite value2; if (text == null) { if (logged.Add("unmapped|" + name)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Unmapped status: " + name + " | " + name2 + " | " + ((object)val).GetType().Name)); } } else if (sprites.TryGetValue(text, out value2)) { if (!originalIcons.ContainsKey(val)) { originalIcons.Add(val, icon); } string key = name.Replace("(Clone)", "").Trim(); if (!originalPrefabIcons.ContainsKey(key)) { originalPrefabIcons.Add(key, icon); } val.m_icon = value2; if (logged.Add(((object)val).GetType().Name + "|" + text)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Replaced icon: " + ((object)val).GetType().Name + " -> " + text)); } matchedIcons.Add(text); } } } private static string ResolveLocalized(string raw) { if (string.IsNullOrEmpty(raw)) { return null; } string text = raw; try { if (Localization.instance != null) { text = Localization.instance.Localize(raw); } } catch { } switch (text.Trim().ToLowerInvariant()) { case "огонь": case "fire": return "fire"; case "свет светлячка": case "свет виспа": case "wisp light": case "wisplight": return "wisp_light"; case "укрытие": case "shelter": case "sheltered": return "shelter"; case "сырость": case "wet": return "wet"; case "дым": case "smoke": return "smoke"; case "бодрость": case "rested": return "rested"; case "словно перышко": case "feather fall": return "feather"; case "нагруженность": case "encumbered": return "encumbered"; case "бег мертвеца": case "corpse run": return "corpse_run"; case "без потери навыков": case "нет потери навыков": case "no skill drain": case "no skill loss": case "no skill loss on death": return "no_skill_drain"; case "скрытный": case "sneaky": return "sneaky"; case "искусный лучник": case "skilled archer": return "archer"; case "берсерк": case "berserker": return "berserker"; case "замерзание": case "freezing": return "freezing"; case "холод": case "холодно": case "cold": return "cold"; case "горение": case "горит": case "burning": return "burning"; case "обездвиженность": case "immobilized": case "rooted": return "immobilized"; case "harpooned": return "harpooned"; case "магический барьер": case "magic barrier": case "staff shield": return "magic_barrier"; case "рыбацкая шляпа": case "fishing hat": return "fishing_hat"; case "благословение фенриса": case "fenris' blessing": return "fenris_blessing"; case "в дёгте": case "в дегте": case "tarred": return "tarred"; case "в слизи": case "slimed": return "slimed"; case "ветрокрылый": case "wind run": return "wind_run"; case "выносливость аска": case "ask's endurance": return "ask_endurance"; case "гнилокостный гнев": case "гнилостный гнев": case "rotting rage": return "rotting_rage"; case "лёд": case "лед": case "frost": return "frost"; case "молния": case "lightning": return "lightning"; case "оглушение": case "staggered": return "staggered"; case "отравление": case "poisoned": case "poison": return "poison"; case "сборщик урожая": case "harvester": return "harvester"; case "тошнота": case "feeling sick": return "sick"; case "королева": case "queen": return "queen"; case "масса костей": case "костемасс": case "bonemass": return "bonemass"; case "матерь": case "moder": return "moder"; case "яглут": case "yagluth": return "yagluth"; case "эйктюр": case "eikthyr": return "eikthyr"; case "the elder": case "elder": return "elder"; case "морозоустойчивая медовуха": case "frost resistance mead": return "frost_resist_mead"; case "медовуха антидот": case "антидот": case "poison resistance mead": return "antidote_mead"; case "ячменное вино": case "barley wine": return "barley_wine"; case "мощь двергов": case "dvergr power": return "dvergr_power"; case "мегингъёрд": case "megingjord": return "megingjord"; case "благословение быкоящера": case "сет быкоящера": case "boon of the lox": case "lox set": return "lox_set"; case "дужка": case "duzhka": return "duzhka"; case "авангард": case "vanguard": return "vanguard"; case "любовное зелье": case "love potion": return "love_potion"; case "малый эйтр": case "minor eitr": case "lesser eitr": return "eitr_minor"; case "медовуха берсеркера": case "медовуха берсеркира": case "берсеркира": case "berserker mead": return "berserker_mead"; case "медовуха легкоступа": case "легкоступ": case "lightfoot mead": return "lightfoot_mead"; case "медовуха силы тролля": case "сила тролля": case "troll strength mead": return "troll_strength_mead"; case "напиток вананидир": case "вананидир": case "vananidir drink": return "vananidir_drink"; case "отвар звериного шёпота": case "отвар звериного шепота": case "звериный шёпот": case "звериный шепот": case "beast whisper": return "beast_whisper"; case "средство от смертожалов": case "сопротивление смертожалам": case "deathstinger resistance": return "deathstinger_resist"; case "элексир рататоска": case "эликсир рататоска": case "рататоск": case "ratatosk elixir": return "ratatosk_elixir"; case "мощный эйтр": case "мощная медовуха эйтра": case "мощная медовуха эйтр": case "powerful eitr": case "powerful eitr mead": return "powerful_eitr"; case "вкусная медовуха": case "tasty mead": return "tasty_mead"; case "мощная медовуха лечения": case "мощная лечебная медовуха": case "powerful healing mead": return "powerful_healing_mead"; case "большая медовуха выносливости": case "major stamina mead": case "lingering stamina mead": case "медовуха долгой выносливости": return "stamina_major"; default: return null; } } private static Type FindType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType(name, throwOnError: false); if (type != null) { return type; } } return null; } private static string ResolveNovaPearl(bool installed, string prefab) { if (!installed || string.IsNullOrEmpty(prefab)) { return null; } if (!string.Equals(prefab.Replace("(Clone)", "").Trim(), "SE_ChitinPearl", StringComparison.OrdinalIgnoreCase)) { return null; } return "nova_chitin_pearl"; } private static string Resolve(params string[] candidates) { foreach (string text in candidates) { if (!string.IsNullOrEmpty(text)) { if (names.TryGetValue(text, out var value)) { return value; } string key = text.Replace("(Clone)", "").Trim(); if (names.TryGetValue(key, out value)) { return value; } } } return null; } private static string ReadString(object obj, string member) { FieldInfo fieldInfo = FindField(obj.GetType(), member); if (fieldInfo != null && fieldInfo.FieldType == typeof(string)) { return fieldInfo.GetValue(obj) as string; } PropertyInfo property = obj.GetType().GetProperty(member, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.PropertyType == typeof(string)) { return property.GetValue(obj, null) as string; } return null; } private static FieldInfo FindField(Type type, string name) { Type type2 = type; while (type2 != null) { FieldInfo field = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type2 = type2.BaseType; } return null; } private static object FieldValue(object obj, string name) { FieldInfo fieldInfo = FindField(obj.GetType(), name); if (!(fieldInfo == null)) { return fieldInfo.GetValue(obj); } return null; } private static object StaticMember(string className, string member) { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType(className, throwOnError: false); if (type != null) { break; } } if (type == null) { return null; } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = type.GetField(member, bindingAttr); if (field != null) { return field.GetValue(null); } PropertyInfo property = type.GetProperty(member, bindingAttr); if (!(property == null)) { return property.GetValue(null, null); } return null; } private static object Call(object obj, string method) { MethodInfo method2 = obj.GetType().GetMethod(method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (!(method2 == null)) { return method2.Invoke(obj, null); } return null; } } public sealed class CompendiumDialogLifetime : MonoBehaviour { private TextsDialog dialog; private void Awake() { dialog = ((Component)this).GetComponent<TextsDialog>(); } private void OnDisable() { Plugin.ClearCompendium(dialog); } private void OnDestroy() { Plugin.ClearCompendium(dialog); } } public sealed class CompendiumIconLayout : MonoBehaviour { private TMP_Text text; private readonly List<Image> images = new List<Image>(); private int visibleCount; private bool subscribed; private void OnEnable() { text = ((Component)this).GetComponent<TMP_Text>(); Subscribe(); } private void Subscribe() { if (!((Object)(object)text == (Object)null) && !subscribed && ((Behaviour)this).isActiveAndEnabled) { text.OnPreRenderText += UpdatePositions; subscribed = true; } } private void OnDisable() { if ((Object)(object)text != (Object)null && subscribed) { text.OnPreRenderText -= UpdatePositions; } subscribed = false; } public void SetIcons(List<Sprite> sprites) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00cd: 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_00d3: 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_00ec: 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 ((Object)(object)text == (Object)null) { text = ((Component)this).GetComponent<TMP_Text>(); } visibleCount = sprites?.Count ?? 0; if (visibleCount > 0) { Subscribe(); } while (images.Count < visibleCount) { GameObject val = new GameObject("PSH_CompendiumIcon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.layer = ((Component)this).gameObject.layer; val.transform.SetParent(((Component)this).transform, false); Image component = val.GetComponent<Image>(); component.preserveAspect = true; ((Graphic)component).raycastTarget = false; RectTransform rectTransform = ((Graphic)component).rectTransform; Vector2 anchorMin = (rectTransform.anchorMax = new Vector2(0.5f, 0.5f)); rectTransform.anchorMin = anchorMin; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.sizeDelta = new Vector2(48f, 48f); images.Add(component); } for (int i = 0; i < images.Count; i++) { images[i].sprite = ((i < visibleCount) ? sprites[i] : null); ((Behaviour)images[i]).enabled = false; ((Component)images[i]).gameObject.SetActive(i < visibleCount); } if (visibleCount > 0 && (Object)(object)text != (Object)null) { text.ForceMeshUpdate(false, false); } } private void UpdatePositions(TMP_TextInfo info) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null || visibleCount == 0) { return; } for (int i = 0; i < visibleCount; i++) { ((Behaviour)images[i]).enabled = false; } Vector3 val3 = default(Vector3); for (int j = 0; j < info.linkCount; j++) { TMP_LinkInfo val = info.linkInfo[j]; string linkID = ((TMP_LinkInfo)(ref val)).GetLinkID(); if (!linkID.StartsWith("PSH_", StringComparison.Ordinal) || !int.TryParse(linkID.Substring(4), out var result) || result < 0 || result >= visibleCount) { continue; } int linkTextfirstCharacterIndex = val.linkTextfirstCharacterIndex; if (linkTextfirstCharacterIndex >= 0 && linkTextfirstCharacterIndex < info.characterCount) { TMP_CharacterInfo val2 = info.characterInfo[linkTextfirstCharacterIndex]; RectTransform rectTransform = ((Graphic)images[result]).rectTransform; Rect rect = text.rectTransform.rect; ((Vector3)(ref val3))..ctor(((Rect)(ref rect)).xMin + text.margin.x + 26f, val2.ascender + 2f, 0f); if (((Transform)rectTransform).localPosition != val3) { ((Transform)rectTransform).localPosition = val3; } ((Behaviour)images[result]).enabled = (Object)(object)images[result].sprite != (Object)null; } } } }