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 ChipGauge v1.2.0
plugins/ChipGauge.dll
Decompiled 8 hours agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("Reynum")] [assembly: AssemblyTitle("ChipGauge")] [assembly: AssemblyVersion("1.2.0.0")] namespace ChipGauge; [BepInPlugin("Reynum.ChipGauge", "Chip Gauge", "1.2.0")] public class ChipGaugePlugin : BaseUnityPlugin { public const string ModGuid = "Reynum.ChipGauge"; public const string ModName = "Chip Gauge"; public const string ModVersion = "1.2.0"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> Range; internal static ConfigEntry<bool> ShowToolWarning; internal static ConfigEntry<bool> ShowRockChunk; internal static ConfigEntry<bool> ShowPercent; internal static ConfigEntry<bool> OnlyMatchingTool; internal static ConfigEntry<bool> HideInBase; private Harmony _harmony; private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Show remaining health of trees, logs, rocks and other destructibles in the crosshair hover text."); Range = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "Range", 6f, new ConfigDescription("How far from your character (metres) to show health.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>())); ShowPercent = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Show Percentage", true, "Add the percentage after the numbers."); ShowToolWarning = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Warn If Tool Too Weak", true, "Add a red line when your current tool can't damage the target."); OnlyMatchingTool = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Only With Matching Tool", true, "Only show health when your equipped tool can damage the target: axe for trees, logs and stumps; pickaxe for rocks and ore deposits."); HideInBase = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Hide Inside Base", true, "Don't show anything inside your base area (the zone around workbenches, fires and beds where enemies can't spawn)."); ShowRockChunk = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Show Rock Chunk Health", true, "For big rocks and deposits, also show the health of the chunk you're aiming at."); _harmony = new Harmony("Reynum.ChipGauge"); _harmony.PatchAll(typeof(HudPatch)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Chip Gauge 1.2.0 loaded."); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } } [HarmonyPatch] internal static class HudPatch { private static readonly FieldInfo F_TreeBase_nview = AccessTools.Field(typeof(TreeBase), "m_nview"); private static readonly FieldInfo F_TreeLog_nview = AccessTools.Field(typeof(TreeLog), "m_nview"); private static readonly FieldInfo F_Destr_nview = AccessTools.Field(typeof(Destructible), "m_nview"); private static readonly FieldInfo F_MineRock_nview = AccessTools.Field(typeof(MineRock), "m_nview"); private static readonly FieldInfo F_MineRock_areas = AccessTools.Field(typeof(MineRock), "m_hitAreas"); private static readonly MethodInfo M_MineRock_areaIndex = AccessTools.Method(typeof(MineRock), "GetAreaIndex", (Type[])null, (Type[])null); private static readonly FieldInfo F_MineRock5_areas = AccessTools.Field(typeof(MineRock5), "m_hitAreas"); private static readonly MethodInfo M_MineRock5_areaIndex = AccessTools.Method(typeof(MineRock5), "GetAreaIndex", (Type[])null, (Type[])null); private static FieldInfo F_HitArea_health; private static int s_healthHash = int.MinValue; private static bool s_failedOnce; [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] [HarmonyPostfix] [HarmonyPriority(0)] private static void UpdateCrosshair_Postfix(Hud __instance, Player player) { if (!ChipGaugePlugin.Enabled.Value || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_hoverName == (Object)null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).IsDead()) { return; } try { if (!Describe(player, out var name, out var health, out var root)) { return; } string text = ((TMP_Text)__instance.m_hoverName).text ?? ""; if (text.Length == 0) { ((TMP_Text)__instance.m_hoverName).text = name + "\n" + health; return; } GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if (!((Object)(object)hoverObject == (Object)null) && !((Object)(object)root == (Object)null) && hoverObject.transform.IsChildOf(root.transform)) { ((TMP_Text)__instance.m_hoverName).text = text + "\n" + health; } } catch (Exception ex) { if (!s_failedOnce) { s_failedOnce = true; Debug.LogWarning((object)("[ChipGauge] " + ex)); } } } private static bool Describe(Player p, out string name, out string health, out GameObject root) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) name = (health = null); root = null; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } float num = Vector3.Distance(((Component)main).transform.position, ((Component)p).transform.position) + ChipGaugePlugin.Range.Value + 1f; RaycastHit[] array = Physics.RaycastAll(((Component)main).transform.position, ((Component)main).transform.forward, num, -1, (QueryTriggerInteraction)1); if (array.Length == 0) { return false; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); RaycastHit[] array2 = array; for (int num2 = 0; num2 < array2.Length; num2++) { RaycastHit val = array2[num2]; Collider collider = ((RaycastHit)(ref val)).collider; if (!((Object)(object)collider == (Object)null) && !((Object)(object)((Component)collider).GetComponentInParent<Player>() == (Object)(object)p) && !(Vector3.Distance(((Component)p).transform.position, ((RaycastHit)(ref val)).point) > ChipGaugePlugin.Range.Value)) { if (Target(p, collider, out name, out health, out root)) { return true; } if ((Object)(object)((Component)collider).GetComponentInParent<WearNTear>() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent<Heightmap>() != (Object)null) { return false; } } } return false; } private static bool Target(Player p, Collider col, out string name, out string health, out GameObject root) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) name = (health = null); root = null; if ((Object)(object)((Component)col).GetComponentInParent<Character>() != (Object)null) { return false; } if (ChipGaugePlugin.HideInBase.Value && (Object)(object)EffectArea.IsPointInsideArea(((Component)col).transform.position, (Type)4, 0f) != (Object)null) { return false; } ItemData currentWeapon = ((Humanoid)p).GetCurrentWeapon(); TreeBase componentInParent = ((Component)col).GetComponentInParent<TreeBase>(); if ((Object)(object)componentInParent != (Object)null) { if (!ToolFits(currentWeapon, componentInParent.m_damageModifiers)) { return false; } root = ((Component)componentInParent).gameObject; name = NameOf(((Component)componentInParent).gameObject); object? value = F_TreeBase_nview.GetValue(componentInParent); health = Line(ZdoHealth((ZNetView)((value is ZNetView) ? value : null), componentInParent.m_health), componentInParent.m_health, p, componentInParent.m_minToolTier, null); return true; } TreeLog componentInParent2 = ((Component)col).GetComponentInParent<TreeLog>(); if ((Object)(object)componentInParent2 != (Object)null) { if (!ToolFits(currentWeapon, componentInParent2.m_damages)) { return false; } root = ((Component)componentInParent2).gameObject; name = NameOf(((Component)componentInParent2).gameObject); object? value2 = F_TreeLog_nview.GetValue(componentInParent2); health = Line(ZdoHealth((ZNetView)((value2 is ZNetView) ? value2 : null), componentInParent2.m_health), componentInParent2.m_health, p, componentInParent2.m_minToolTier, null); return true; } MineRock5 componentInParent3 = ((Component)col).GetComponentInParent<MineRock5>(); if ((Object)(object)componentInParent3 != (Object)null && !ToolFits(currentWeapon, componentInParent3.m_damageModifiers)) { return false; } if ((Object)(object)componentInParent3 != (Object)null) { root = ((Component)componentInParent3).gameObject; return Rock5(p, componentInParent3, col, out name, out health); } MineRock componentInParent4 = ((Component)col).GetComponentInParent<MineRock>(); if ((Object)(object)componentInParent4 != (Object)null && !ToolFits(currentWeapon, componentInParent4.m_damageModifiers)) { return false; } if ((Object)(object)componentInParent4 != (Object)null) { root = ((Component)componentInParent4).gameObject; return Rock(p, componentInParent4, col, out name, out health); } Destructible componentInParent5 = ((Component)col).GetComponentInParent<Destructible>(); if ((Object)(object)componentInParent5 != (Object)null && (Object)(object)((Component)componentInParent5).GetComponentInParent<Piece>() == (Object)null) { if (!ToolFits(currentWeapon, componentInParent5.m_damages)) { return false; } root = ((Component)componentInParent5).gameObject; name = NameOf(((Component)componentInParent5).gameObject); object? value3 = F_Destr_nview.GetValue(componentInParent5); health = Line(ZdoHealth((ZNetView)((value3 is ZNetView) ? value3 : null), componentInParent5.m_health), componentInParent5.m_health, p, componentInParent5.m_minToolTier, null); return true; } return false; } private static bool Rock5(Player p, MineRock5 rock, Collider col, out string name, out string health) { name = Localize(rock.m_name); health = null; if (!(F_MineRock5_areas.GetValue(rock) is IList { Count: not 0 } list)) { return false; } if (F_HitArea_health == null) { F_HitArea_health = AccessTools.Field(list[0].GetType(), "m_health"); } float num = 0f; float num2 = 0f; string chunk = null; foreach (object item in list) { num += rock.m_health; num2 += Mathf.Max(0f, (float)F_HitArea_health.GetValue(item)); } if (ChipGaugePlugin.ShowRockChunk.Value && list.Count > 1) { try { int num3 = (int)M_MineRock5_areaIndex.Invoke(rock, new object[1] { col }); if (num3 >= 0 && num3 < list.Count) { chunk = "Chunk: " + Mathf.CeilToInt(Mathf.Max(0f, (float)F_HitArea_health.GetValue(list[num3]))) + " / " + Mathf.CeilToInt(rock.m_health); } } catch { } } health = Line(num2, num, p, rock.m_minToolTier, chunk); return true; } private static bool Rock(Player p, MineRock rock, Collider col, out string name, out string health) { name = Localize(rock.m_name); health = null; object? value = F_MineRock_nview.GetValue(rock); ZNetView val = (ZNetView)((value is ZNetView) ? value : null); Collider[] array = F_MineRock_areas.GetValue(rock) as Collider[]; if ((Object)(object)val == (Object)null || !val.IsValid() || array == null || array.Length == 0) { return false; } ZDO zDO = val.GetZDO(); float health2 = rock.GetHealth(); float num = 0f; float num2 = 0f; string chunk = null; for (int i = 0; i < array.Length; i++) { num += health2; num2 += Mathf.Max(0f, zDO.GetFloat("Health" + i, health2)); } if (ChipGaugePlugin.ShowRockChunk.Value && array.Length > 1) { try { int num3 = (int)M_MineRock_areaIndex.Invoke(rock, new object[1] { col }); if (num3 >= 0) { chunk = "Chunk: " + Mathf.CeilToInt(Mathf.Max(0f, zDO.GetFloat("Health" + num3, health2))) + " / " + Mathf.CeilToInt(health2); } } catch { } } health = Line(num2, num, p, rock.m_minToolTier, chunk); return true; } private static bool ToolFits(ItemData tool, DamageModifiers mods) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!ChipGaugePlugin.OnlyMatchingTool.Value) { return true; } if (tool == null) { return false; } DamageTypes damages = tool.m_shared.m_damages; if (damages.m_chop > 0f && Hurts(((DamageModifiers)(ref mods)).GetModifier((DamageType)8))) { return true; } if (damages.m_pickaxe > 0f && Hurts(((DamageModifiers)(ref mods)).GetModifier((DamageType)16))) { return true; } return false; } private static bool Hurts(DamageModifier m) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)m != 3) { return (int)m != 4; } return false; } private static float ZdoHealth(ZNetView nv, float def) { if ((Object)(object)nv == (Object)null || !nv.IsValid()) { return def; } if (s_healthHash == int.MinValue) { try { s_healthHash = (int)AccessTools.Field(typeof(ZDOVars), "s_health").GetValue(null); } catch { s_healthHash = StringExtensionMethods.GetStableHashCode("health"); } } return nv.GetZDO().GetFloat(s_healthHash, def); } private static string Line(float cur, float max, Player p, int minTier, string chunk) { if (max <= 0f) { max = 1f; } cur = Mathf.Max(0f, cur); string text = Mathf.CeilToInt(cur) + " / " + Mathf.CeilToInt(max); if (ChipGaugePlugin.ShowPercent.Value) { text = text + " (" + Mathf.RoundToInt(Mathf.Clamp01(cur / max) * 100f) + "%)"; } if (!string.IsNullOrEmpty(chunk)) { text = text + "\n" + chunk; } if (ChipGaugePlugin.ShowToolWarning.Value && minTier > 0) { int num = ((Humanoid)p).GetCurrentWeapon()?.m_shared.m_toolTier ?? 0; if (num < minTier) { text = text + "\n<color=red>Tool too weak (tier " + num + ", needs " + minTier + ")</color>"; } } return text; } private static string NameOf(GameObject go) { HoverText componentInParent = go.GetComponentInParent<HoverText>(); if ((Object)(object)componentInParent != (Object)null && !string.IsNullOrEmpty(componentInParent.m_text)) { return Localize(componentInParent.m_text); } string text = ((Object)go).name; int num = text.IndexOf("(Clone)", StringComparison.Ordinal); if (num >= 0) { text = text.Substring(0, num); } text = Regex.Replace(text, "[_\\s]*\\d+$", ""); text = text.Replace('_', ' '); text = Regex.Replace(text, "([a-z])([A-Z])", "$1 $2"); text = text.Trim(); if (text.Length <= 0) { return ((Object)go).name; } return char.ToUpperInvariant(text[0]) + text.Substring(1); } private static string Localize(string s) { if (string.IsNullOrEmpty(s)) { return s; } if (Localization.instance == null) { return s; } return Localization.instance.Localize(s); } }