Decompiled source of BetterHealthbars v0.0.3

BetterHealthbars.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Landfall.TABC;
using Landfall.TABS;
using Landfall.TABS.GameMode;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("BetterHealthbars")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterHealthbars")]
[assembly: AssemblyTitle("BetterHealthbars")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace BetterHealthbars;

[BepInPlugin("me.fern.betterHealthbars", "BetterHealthbars", "0.0.3")]
public sealed class Main : BaseUnityPlugin
{
	public enum HealthType
	{
		Health,
		Fraction,
		Percentage,
		None
	}

	public const string modGUID = "me.fern.betterHealthbars";

	public const string modName = "BetterHealthbars";

	public const string modVersion = "0.0.3";

	public readonly Harmony harmony = new Harmony("me.fern.betterHealthbars");

	public static ConfigEntry<HealthType> CurrentType;

	public static ConfigEntry<bool> AllowUnitCreator;

	public static string modPrefix => "[BetterHealthbars]";

	private void Awake()
	{
		DoConfig();
		harmony.PatchAll();
		((MonoBehaviour)this).StartCoroutine(GenerateSettings());
	}

	private void DoConfig()
	{
		CurrentType = ((BaseUnityPlugin)this).Config.Bind<HealthType>("General", "HealthDisplay", HealthType.Health, (ConfigDescription)null);
		AllowUnitCreator = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisplayUC", true, "Allows healthbars to be displayed inside the unit creator");
	}

	private IEnumerator GenerateSettings()
	{
		GlobalSettingsHandler service = null;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Waiting for settings service...");
		yield return (object)new WaitUntil((Func<bool>)(() => Object.op_Implicit((Object)(object)(service = ServiceLocator.GetService<GlobalSettingsHandler>()))));
		List<SettingsInstance> settings = service.GameplaySettings.ToList();
		SettingsInstance val = new SettingsInstance();
		val.settingsType = (SettingsType)0;
		val.options = new string[4] { "Health", "Fraction", "Percentage", "None" };
		val.currentValue = (int)CurrentType.Value;
		val.m_settingsKey = "Healthbar Display Type";
		SettingsInstance enableMod = val;
		enableMod.OnValueChanged += delegate(int value)
		{
			CurrentType.Value = (HealthType)value;
		};
		settings.Add(enableMod);
		val = new SettingsInstance();
		val.settingsType = (SettingsType)0;
		val.options = new string[2] { "On", "Off" };
		val.currentValue = ((!AllowUnitCreator.Value) ? 1 : 0);
		val.m_settingsKey = "Allow UC Healthbars";
		val.toolTip = "Enables healthbars in the unit creator.";
		SettingsInstance allowUc = val;
		allowUc.OnValueChanged += delegate(int num)
		{
			AllowUnitCreator.Value = num == 0;
		};
		settings.Add(allowUc);
		AccessTools.Field(typeof(GlobalSettingsHandler), "m_gameplaySettings").SetValue(service, settings.ToArray());
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Successfully injected custom settings!");
	}
}
[HarmonyPatch(typeof(UnitHealthbars), "HandleUnitSpawned")]
internal class HealthbarUCPatch
{
	private static readonly FieldRef<UnitHealthbars, SettingsInstance> healthBarOption = AccessTools.FieldRefAccess<UnitHealthbars, SettingsInstance>("m_healthBarOption");

	private static readonly FieldRef<UnitHealthbars, GameObject> healthBar = AccessTools.FieldRefAccess<UnitHealthbars, GameObject>("healthBar");

	private static readonly Action<UnitHealthbars> getHealthBarSettings = AccessTools.MethodDelegate<Action<UnitHealthbars>>(AccessTools.Method(typeof(UnitHealthbars), "GetHealthBarSettings", (Type[])null, (Type[])null), (object)null, true);

	private static bool Prefix(UnitHealthbars __instance, Unit unit)
	{
		BaseGameMode currentGameMode = ServiceLocator.GetService<GameModeService>().CurrentGameMode;
		if (currentGameMode is MainMenuGameMode || (currentGameMode is UnitCreatorGameMode && !Main.AllowUnitCreator.Value))
		{
			return false;
		}
		if (healthBarOption.Invoke(__instance) == null)
		{
			getHealthBarSettings(__instance);
		}
		SettingsInstance obj = healthBarOption.Invoke(__instance);
		if (obj != null && obj.currentValue == 1)
		{
			Object.Instantiate<GameObject>(healthBar.Invoke(__instance)).GetComponent<TABCUnitUI>().Init(unit);
		}
		return false;
	}
}
[HarmonyPatch(typeof(TABCUnitUI), "Init")]
internal class HealthbarTextPatch
{
	private static readonly FieldRef<TABCUnitUI, DataHandler> dataHandler = AccessTools.FieldRefAccess<TABCUnitUI, DataHandler>("m_dataHandler");

	private static void Postfix(TABCUnitUI __instance)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInChildren<HealthText>(true)))
		{
			GameObject val = new GameObject("BetterHealthbarsText", new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(((Component)__instance).transform, false);
			((Transform)val2).SetAsLastSibling();
			((Transform)val2).localScale = Vector3.one * 0.1f;
			TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val3).enableWordWrapping = false;
			((TMP_Text)val3).overflowMode = (TextOverflowModes)0;
			((Graphic)val3).raycastTarget = false;
			val.AddComponent<HealthText>().Init(val3, dataHandler.Invoke(__instance));
		}
	}
}
internal sealed class HealthText : MonoBehaviour
{
	private TextMeshProUGUI tmp;

	private DataHandler data;

	private Main.HealthType type = (Main.HealthType)(-1);

	private float health;

	private float maxHealth;

	public void Init(TextMeshProUGUI tmp, DataHandler data)
	{
		this.tmp = tmp;
		this.data = data;
	}

	private void LateUpdate()
	{
		if ((Object)(object)data == (Object)null)
		{
			return;
		}
		Main.HealthType value = Main.CurrentType.Value;
		float a = Mathf.Max(0f, Mathf.Ceil(data.health));
		float a2 = Mathf.Ceil(data.maxHealth);
		if (value != type || !Same(a, health) || !Same(a2, maxHealth))
		{
			type = value;
			health = a;
			maxHealth = a2;
			string text;
			switch (type)
			{
			case Main.HealthType.Health:
				text = health.ToString();
				break;
			case Main.HealthType.Fraction:
				text = $"{health} / {maxHealth}";
				break;
			case Main.HealthType.Percentage:
				text = $"{(float)Math.Ceiling((double)health * 100.0 / (double)maxHealth)} %";
				break;
			default:
				((Behaviour)tmp).enabled = false;
				return;
			}
			((Behaviour)tmp).enabled = true;
			((TMP_Text)tmp).text = text;
			((TMP_Text)tmp).fontSize = Mathf.Max(100, 400 - text.Length * 15);
		}
	}

	private static bool Same(float a, float b)
	{
		return a == b || (float.IsNaN(a) && float.IsNaN(b));
	}
}