using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.bkolacinski")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © bkolacinski 2025")]
[assembly: AssemblyDescription("Displays numerical values on stamina, bonus stamina, and affliction bars with extensive customization options.")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+d517eb109368d4c7210d8451bc9a9e4d01fca1f9")]
[assembly: AssemblyProduct("Numberry")]
[assembly: AssemblyTitle("Numberry")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Numberry
{
[BepInPlugin("com.github.bkolacinski.numberry", "Numberry", "0.1.2")]
public class Plugin : BaseUnityPlugin
{
[HarmonyPatch]
internal static class StaminaBar_Patches
{
[HarmonyPatch(typeof(StaminaBar), "Update")]
[HarmonyPostfix]
private static void UpdatePostfix(StaminaBar __instance)
{
try
{
if (!InitializedBars.ContainsKey(__instance) || !InitializedBars[__instance])
{
InitializeBars(__instance);
InitializedBars[__instance] = true;
}
UpdateAllTexts(__instance);
}
catch (Exception arg)
{
Log.LogError((object)$"Error in StaminaBar.Update patch: {arg}");
if ((Object)(object)__instance != (Object)null && !InitializedBars.ContainsKey(__instance))
{
InitializedBars[__instance] = true;
}
}
}
}
private static Plugin _instance = null;
private static TMP_FontAsset _gameFont = null;
private static ConfigEntry<int> _fontSize = null;
private static ConfigEntry<float> _outlineWidth = null;
private static ConfigEntry<string> _textColorHex = null;
private static ConfigEntry<string> _outlineColorHex = null;
private static ConfigEntry<float> _textOffsetY = null;
private static ConfigEntry<float> _fontWidthScale = null;
private static ConfigEntry<float> _valueDivisor = null;
private static ConfigEntry<bool> _displayStaminaValue = null;
private static ConfigEntry<bool> _displayBonusStaminaValue = null;
private static ConfigEntry<bool> _displayBonusAsInteger = null;
private static ConfigEntry<float> _bonusTextOffsetY = null;
private static Color _textColorValue;
private static Color _outlineColorValue;
private static readonly Dictionary<StaminaBar, bool> InitializedBars = new Dictionary<StaminaBar, bool>();
private static readonly Dictionary<string, TextMeshProUGUI> BarTexts = new Dictionary<string, TextMeshProUGUI>();
private static readonly Dictionary<string, float> LastKnownValues = new Dictionary<string, float>();
private static readonly Dictionary<StaminaBar, float> MaxBonusWidths = new Dictionary<StaminaBar, float>();
public const string Id = "com.github.bkolacinski.numberry";
internal static ManualLogSource Log { get; private set; } = null;
public static string Name => "Numberry";
public static string Version => "0.1.2";
private void Awake()
{
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Expected O, but got Unknown
_instance = this;
Log = ((BaseUnityPlugin)this).Logger;
_fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "FontSize", 24, "Font size.");
_outlineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "OutlineWidth", 0.125f, "Outline width (0-1). Lower value gives a thinner outline.");
_textColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "TextColor", "#FFFFFF", "Text color.");
_outlineColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "OutlineColor", "#000000", "Outline color.");
_textOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "TextOffsetY", 3.5f, "Text vertical offset (up/down).");
_fontWidthScale = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "FontWidthScale", 1.1f, "Font width scale (horizontal stretch, e.g. 1.1 for 110% width).");
_valueDivisor = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ValueDivisor", 15f, "Divisor for converting UI width to stamina/bonus/affliction units (wiki uses 6, this mode uses 15).");
_displayStaminaValue = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "DisplayStamina", true, "Display raw stamina value.");
_displayBonusStaminaValue = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "DisplayBonusStaminaValue", true, "Display bonus stamina value.");
_displayBonusAsInteger = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "DisplayBonusAsInteger", true, "Display bonus stamina as integer (true) or with one decimal (false).");
_bonusTextOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "BonusTextOffsetY", _textOffsetY.Value, "Bonus text vertical offset.");
ColorUtility.TryParseHtmlString(_textColorHex.Value, ref _textColorValue);
ColorUtility.TryParseHtmlString(_outlineColorHex.Value, ref _outlineColorValue);
Harmony val = new Harmony("com.peakmodding.peakmod");
val.PatchAll(typeof(StaminaBar_Patches));
}
private static void InitializeBars(StaminaBar sb)
{
Log.LogInfo((object)$"Initializing stamina info text objects for StaminaBar {((Object)sb).GetInstanceID()}.");
TextMeshProUGUI[] componentsInChildren = ((Component)sb).GetComponentsInChildren<TextMeshProUGUI>();
foreach (TextMeshProUGUI val in componentsInChildren)
{
if (((Object)val).name.EndsWith("ValueText"))
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
if ((Object)(object)_gameFont == (Object)null)
{
_gameFont = ((TMP_Text)GameObject.Find("GAME/GUIManager").GetComponent<GUIManager>().heroDayText).font;
}
if (_displayStaminaValue.Value)
{
FieldInfo field = ((object)sb).GetType().GetField("staminaBar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object? value = field.GetValue(sb);
Component val2 = (Component)((value is Component) ? value : null);
if (val2 != null)
{
CreateTextObject(((Component)val2.transform.parent).gameObject, $"Stamina_{((Object)sb).GetInstanceID()}", _textOffsetY.Value);
goto IL_0103;
}
}
Log.LogWarning((object)"Could not find 'staminaBar' to attach stamina text.");
}
goto IL_0103;
IL_0103:
if (_displayBonusStaminaValue.Value)
{
FieldInfo field2 = ((object)sb).GetType().GetField("extraBarStamina", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field2 != null)
{
object? value2 = field2.GetValue(sb);
Component val3 = (Component)((value2 is Component) ? value2 : null);
if (val3 != null)
{
CreateTextObject(val3.gameObject, $"BonusStamina_{((Object)sb).GetInstanceID()}", _bonusTextOffsetY.Value);
goto IL_017c;
}
}
Log.LogWarning((object)"Could not find 'extraBarStamina' to attach bonus stamina text.");
}
goto IL_017c;
IL_017c:
BarAffliction[] componentsInChildren2 = ((Component)sb).GetComponentsInChildren<BarAffliction>(true);
BarAffliction[] array = componentsInChildren2;
foreach (BarAffliction val4 in array)
{
CreateTextObject(((Component)val4).gameObject, $"Affliction_{((Object)val4).GetInstanceID()}", _textOffsetY.Value);
}
Log.LogInfo((object)$"Finished initializing stamina info text objects for StaminaBar {((Object)sb).GetInstanceID()}.");
}
private static void CreateTextObject(GameObject parent, string key, float yOffset)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(key + "_ValueText", new Type[1] { typeof(RectTransform) });
val.transform.SetParent(parent.transform, false);
TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)val2).font = _gameFont;
((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
((Graphic)val2).color = _textColorValue;
((TMP_Text)val2).fontSize = _fontSize.Value;
Material val3 = Object.Instantiate<Material>(((TMP_Text)val2).fontSharedMaterial);
val3.SetFloat(ShaderUtilities.ID_OutlineWidth, _outlineWidth.Value);
val3.SetColor(ShaderUtilities.ID_OutlineColor, _outlineColorValue);
val3.EnableKeyword("OUTLINE_ON");
((TMP_Text)val2).fontMaterial = val3;
((Graphic)val2).raycastTarget = false;
RectTransform component = val.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
component.anchoredPosition = new Vector2(0f, yOffset);
val.transform.localScale = new Vector3(_fontWidthScale.Value, 1f, 1f);
BarTexts[key] = val2;
LastKnownValues[key] = -1f;
((Component)val2).gameObject.SetActive(false);
}
private static void UpdateAllTexts(StaminaBar sb)
{
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
string key = $"Stamina_{((Object)sb).GetInstanceID()}";
if (_displayStaminaValue.Value && BarTexts.ContainsKey(key))
{
FieldInfo field = ((object)sb).GetType().GetField("desiredStaminaSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
float rawValue = (float)field.GetValue(sb);
UpdateText(key, rawValue, showDecimal: false);
}
}
string key2 = $"BonusStamina_{((Object)sb).GetInstanceID()}";
if (_displayBonusStaminaValue.Value && BarTexts.ContainsKey(key2))
{
FieldInfo field2 = ((object)sb).GetType().GetField("desiredExtraStaminaSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo field3 = ((object)sb).GetType().GetField("extraBarStamina", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo field4 = ((object)sb).GetType().GetField("desiredStaminaSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field2 != null && field3 != null && field4 != null)
{
float num = (float)field2.GetValue(sb);
float num2 = (float)field4.GetValue(sb);
object? value = field3.GetValue(sb);
Component val = (Component)((value is Component) ? value : null);
RectTransform val2 = ((val != null) ? val.GetComponent<RectTransform>() : null);
if ((Object)(object)val2 != (Object)null && BarTexts.TryGetValue(key2, out TextMeshProUGUI value2))
{
RectTransform component = ((Component)value2).GetComponent<RectTransform>();
LastKnownValues.TryGetValue(key2, out var value3);
bool flag = num < value3;
if (num2 < 0.01f && flag)
{
Rect rect;
if (!MaxBonusWidths.ContainsKey(sb))
{
Dictionary<StaminaBar, float> maxBonusWidths = MaxBonusWidths;
rect = val2.rect;
maxBonusWidths[sb] = ((Rect)(ref rect)).width;
}
float num3 = MaxBonusWidths[sb];
rect = val2.rect;
if (((Rect)(ref rect)).width > num3)
{
rect = val2.rect;
num3 = ((Rect)(ref rect)).width;
MaxBonusWidths[sb] = num3;
}
rect = val2.rect;
float width = ((Rect)(ref rect)).width;
float num4 = (num3 - width) / 2f;
component.anchoredPosition = new Vector2(num4, _bonusTextOffsetY.Value);
}
else
{
MaxBonusWidths.Remove(sb);
component.anchoredPosition = new Vector2(0f, _bonusTextOffsetY.Value);
}
UpdateText(key2, num, !_displayBonusAsInteger.Value);
}
else
{
UpdateText(key2, num, !_displayBonusAsInteger.Value);
}
}
}
BarAffliction[] componentsInChildren = ((Component)sb).GetComponentsInChildren<BarAffliction>(true);
BarAffliction[] array = componentsInChildren;
foreach (BarAffliction val3 in array)
{
string key3 = $"Affliction_{((Object)val3).GetInstanceID()}";
if (BarTexts.ContainsKey(key3))
{
UpdateText(key3, val3.size, showDecimal: false);
}
}
}
private static void UpdateText(string key, float rawValue, bool showDecimal)
{
if (!BarTexts.TryGetValue(key, out TextMeshProUGUI value) || !LastKnownValues.TryGetValue(key, out var value2))
{
return;
}
if ((Object)(object)value == (Object)null)
{
BarTexts.Remove(key);
LastKnownValues.Remove(key);
}
else if (!Mathf.Approximately(rawValue, value2))
{
LastKnownValues[key] = rawValue;
float num = rawValue / _valueDivisor.Value;
if (showDecimal ? (num > 0.5f) : (num >= 1f))
{
((TMP_Text)value).text = (showDecimal ? num.ToString("F1") : Mathf.FloorToInt(num).ToString());
((Component)value).gameObject.SetActive(true);
}
else
{
((Component)value).gameObject.SetActive(false);
}
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}