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));
}
}