Decompiled source of PerfectStatusHUD v0.2.1

plugins/PerfectStatusHUD/PerfectStatusHUD.dll

Decompiled a day ago
using 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;
			}
		}
	}
}