Decompiled source of StaminaStatsTactikot v1.1.0

plugins/StaminaStatsTactikot.dll

Decompiled 15 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("pixx; TactiKot")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Numerical stamina and affliction values for current PEAK builds.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("StaminaStatsTactikot")]
[assembly: AssemblyTitle("StaminaStatsTactikot")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 StaminaStatsTactikot
{
	internal sealed class AfflictionTextTracker : MonoBehaviour
	{
		private BarAffliction affliction;

		private RectTransform textRect;

		private float verticalOffset;

		internal void Initialize(BarAffliction trackedAffliction, float offset)
		{
			affliction = trackedAffliction;
			textRect = ((Component)this).GetComponent<RectTransform>();
			verticalOffset = offset;
		}

		internal void UpdateWidth(float width)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)textRect != (Object)null)
			{
				textRect.sizeDelta = new Vector2(width, textRect.sizeDelta.y);
			}
		}

		internal void UpdateAffliction(BarAffliction updatedAffliction)
		{
			if ((Object)(object)updatedAffliction != (Object)null && (Object)(object)affliction != (Object)(object)updatedAffliction)
			{
				affliction = updatedAffliction;
			}
		}

		private void LateUpdate()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			if (!((Object)(object)affliction == (Object)null) && !((Object)(object)textRect == (Object)null))
			{
				RectTransform component = ((Component)affliction).GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					Vector3 position = ((Transform)component).position;
					((Transform)textRect).position = new Vector3(position.x, position.y + verticalOffset, ((Transform)textRect).position.z);
				}
			}
		}
	}
	internal static class HudController
	{
		private static readonly Color LowStaminaColor = new Color(1f, 0.3f, 0.3f);

		private static readonly Color MediumStaminaColor = new Color(1f, 0.92f, 0.016f);

		private static readonly Color HighStaminaColor = new Color(0.5f, 1f, 0.5f);

		private static readonly Color ExtraStaminaColor = new Color(1f, 0.92f, 0.016f);

		private static readonly Dictionary<STATUSTYPE, Color> StatusColors = new Dictionary<STATUSTYPE, Color>
		{
			[(STATUSTYPE)0] = new Color(1f, 0.3f, 0.3f),
			[(STATUSTYPE)1] = new Color(0.9f, 0.6f, 0.1f),
			[(STATUSTYPE)2] = new Color(0.2f, 0.6f, 0.9f),
			[(STATUSTYPE)3] = new Color(0.6f, 0.1f, 0.6f),
			[(STATUSTYPE)4] = new Color(0.9f, 0.4f, 0.4f),
			[(STATUSTYPE)5] = new Color(0.5f, 0.1f, 0.5f),
			[(STATUSTYPE)6] = new Color(1f, 0.4f, 0.8f),
			[(STATUSTYPE)7] = new Color(0.6f, 0.4f, 0.2f),
			[(STATUSTYPE)8] = new Color(1f, 0.3f, 0.1f)
		};

		private static readonly Dictionary<STATUSTYPE, TextMeshProUGUI> AfflictionTexts = new Dictionary<STATUSTYPE, TextMeshProUGUI>();

		private static readonly Dictionary<STATUSTYPE, int> RoundedAfflictionValues = new Dictionary<STATUSTYPE, int>();

		private static readonly Dictionary<STATUSTYPE, float> ExactAfflictionValues = new Dictionary<STATUSTYPE, float>();

		private static StaminaBar attachedBar;

		private static GameObject staminaTextContainer;

		private static TextMeshProUGUI staminaText;

		private static TextMeshProUGUI extraStaminaText;

		private static Canvas afflictionCanvas;

		private static TMP_FontAsset gameFont;

		private static Material textMaterial;

		private static int roundedFrame = -1;

		private static int roundedStaminaValue;

		private static int roundedExtraStaminaValue;

		internal static void AttachTo(StaminaBar bar)
		{
			if (!((Object)(object)bar == (Object)null))
			{
				if ((Object)(object)attachedBar != (Object)(object)bar)
				{
					DestroyStaminaText();
					CleanupAfflictionTexts();
					attachedBar = bar;
					InvalidateRoundedValues();
				}
				EnsureStaminaText(bar);
				RefreshAfflictions(bar);
			}
		}

		internal static void UpdateStamina(StaminaBar bar)
		{
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)bar == (Object)null || (Object)(object)observedCharacter == (Object)null || (Object)(object)observedCharacter.data == (Object)null)
			{
				SetStaminaTextVisible(visible: false);
				return;
			}
			if ((Object)(object)attachedBar != (Object)(object)bar || (Object)(object)staminaText == (Object)null)
			{
				AttachTo(bar);
			}
			if ((Object)(object)staminaText == (Object)null)
			{
				return;
			}
			float current = observedCharacter.data.currentStamina * 100f;
			float num = observedCharacter.data.extraStamina * 100f;
			float maximum = observedCharacter.GetMaxStamina() * 100f;
			EnsureRoundedValues(bar, observedCharacter);
			ApplyLiveTextSettings(staminaText, Plugin.StaminaFontSize.Value);
			((TMP_Text)staminaText).text = FormatValue(roundedStaminaValue);
			if ((Object)(object)extraStaminaText != (Object)null)
			{
				ApplyLiveTextSettings(extraStaminaText, Plugin.StaminaFontSize.Value);
				bool flag = num > 0.005f;
				((Component)extraStaminaText).gameObject.SetActive(flag);
				if (flag)
				{
					((TMP_Text)extraStaminaText).text = "  +" + FormatValue(roundedExtraStaminaValue);
				}
			}
			UpdateExistingAfflictionTexts();
			UpdateStaminaTextColor(current, maximum, bar);
			bool num2 = (Object)(object)bar.staminaBar != (Object)null && ((Component)bar.staminaBar).gameObject.activeSelf;
			bool flag2 = !observedCharacter.data.fullyPassedOut && !observedCharacter.data.dead;
			SetStaminaTextVisible(num2 && flag2);
		}

		internal static void RefreshAfflictions(StaminaBar bar)
		{
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)bar == (Object)null || (Object)(object)observedCharacter == (Object)null || bar.afflictions == null)
			{
				return;
			}
			BarAffliction[] afflictions = bar.afflictions;
			foreach (BarAffliction val in afflictions)
			{
				if ((Object)(object)val != (Object)null)
				{
					UpdateAffliction(val, bar);
				}
			}
		}

		internal static void UpdateAffliction(BarAffliction affliction, StaminaBar bar)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)affliction == (Object)null || (Object)(object)bar == (Object)null || (Object)(object)observedCharacter == (Object)null || observedCharacter.refs == null || (Object)(object)observedCharacter.refs.afflictions == (Object)null)
			{
				return;
			}
			STATUSTYPE afflictionType = affliction.afflictionType;
			if (!((Component)affliction).gameObject.activeSelf && !AfflictionTexts.ContainsKey(afflictionType))
			{
				return;
			}
			EnsureRoundedValues(bar, observedCharacter);
			float value;
			float num = (ExactAfflictionValues.TryGetValue(afflictionType, out value) ? value : (observedCharacter.refs.afflictions.GetCurrentStatus(afflictionType) * 100f));
			int value3;
			int value2 = (RoundedAfflictionValues.TryGetValue(afflictionType, out value3) ? value3 : ((int)Math.Round(num, MidpointRounding.AwayFromZero)));
			if (!AfflictionTexts.TryGetValue(afflictionType, out var value4) || (Object)(object)value4 == (Object)null)
			{
				value4 = CreateAfflictionText(affliction);
				AfflictionTexts[afflictionType] = value4;
			}
			else
			{
				ApplyLiveTextSettings(value4, Plugin.AfflictionFontSize.Value);
				AfflictionTextTracker component = ((Component)value4).GetComponent<AfflictionTextTracker>();
				if ((Object)(object)component != (Object)null)
				{
					component.UpdateAffliction(affliction);
					component.UpdateWidth(Mathf.Max(40f, affliction.width * 0.8f));
				}
			}
			((TMP_Text)value4).text = FormatValue(value2);
			((Graphic)value4).color = ResolveStatusColor(afflictionType, affliction);
			((Component)value4).gameObject.SetActive(num > 0.005f);
		}

		internal static void ResetForNewRun()
		{
			CleanupAfflictionTexts();
			DestroyStaminaText();
			attachedBar = null;
			InvalidateRoundedValues();
		}

		internal static void Cleanup()
		{
			CleanupAfflictionTexts();
			DestroyStaminaText();
			if ((Object)(object)afflictionCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)afflictionCanvas).gameObject);
				afflictionCanvas = null;
			}
			attachedBar = null;
			gameFont = null;
			textMaterial = null;
			InvalidateRoundedValues();
		}

		private static void EnsureStaminaText(StaminaBar bar)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)staminaTextContainer != (Object)null))
			{
				FindGameTextStyle();
				staminaTextContainer = new GameObject("StaminaStatsTactikotContainer");
				staminaTextContainer.transform.SetParent(((Component)bar).transform, false);
				staminaText = CreateText("StaminaText", staminaTextContainer.transform);
				RectTransform rectTransform = ((TMP_Text)staminaText).rectTransform;
				rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
				rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
				rectTransform.pivot = new Vector2(1f, 0f);
				rectTransform.sizeDelta = new Vector2(60f, 30f);
				rectTransform.anchoredPosition = new Vector2(20f, 25f);
				SetupTextStyle(staminaText, Plugin.StaminaFontSize.Value, (TextAlignmentOptions)516);
				extraStaminaText = CreateText("ExtraStaminaText", staminaTextContainer.transform);
				RectTransform rectTransform2 = ((TMP_Text)extraStaminaText).rectTransform;
				rectTransform2.anchorMin = new Vector2(0.5f, 0.5f);
				rectTransform2.anchorMax = new Vector2(0.5f, 0.5f);
				rectTransform2.pivot = new Vector2(0f, 0f);
				rectTransform2.sizeDelta = new Vector2(60f, 30f);
				rectTransform2.anchoredPosition = new Vector2(24f, 25f);
				SetupTextStyle(extraStaminaText, Plugin.StaminaFontSize.Value, (TextAlignmentOptions)513);
				((Graphic)extraStaminaText).color = ExtraStaminaColor;
				if (Plugin.VerboseLogging.Value)
				{
					Plugin.Log.LogInfo((object)"Created stamina text elements.");
				}
			}
		}

		private static TextMeshProUGUI CreateAfflictionText(BarAffliction affliction)
		{
			//IL_0045: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			FindGameTextStyle();
			EnsureAfflictionCanvas();
			TextMeshProUGUI obj = CreateText(((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref affliction.afflictionType)/*cast due to .constrained prefix*/).ToString() + "Text", ((Component)afflictionCanvas).transform);
			RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(Mathf.Max(40f, affliction.width * 0.8f), 24f);
			((Component)obj).gameObject.AddComponent<AfflictionTextTracker>().Initialize(affliction, -15f);
			SetupTextStyle(obj, Plugin.AfflictionFontSize.Value, (TextAlignmentOptions)514);
			return obj;
		}

		private static TextMeshProUGUI CreateText(string name, Transform parent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void EnsureAfflictionCanvas()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)afflictionCanvas != (Object)null))
			{
				GameObject val = new GameObject("StaminaStatsTactikotAfflictionCanvas");
				Object.DontDestroyOnLoad((Object)val);
				val.layer = LayerMask.NameToLayer("UI");
				afflictionCanvas = val.AddComponent<Canvas>();
				afflictionCanvas.renderMode = (RenderMode)0;
				afflictionCanvas.sortingOrder = 100;
				CanvasScaler obj = val.AddComponent<CanvasScaler>();
				obj.uiScaleMode = (ScaleMode)1;
				obj.referenceResolution = new Vector2(1920f, 1080f);
				obj.screenMatchMode = (ScreenMatchMode)0;
				val.AddComponent<GraphicRaycaster>();
			}
		}

		private static void FindGameTextStyle()
		{
			if ((Object)(object)gameFont != (Object)null)
			{
				return;
			}
			TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
			foreach (TextMeshProUGUI val in array)
			{
				bool flag;
				switch (((Object)val).name)
				{
				case "InteractNameText":
				case "InteractPromptText":
				case "ItemPromptMain":
					flag = true;
					break;
				default:
					flag = false;
					break;
				}
				if (flag)
				{
					gameFont = ((TMP_Text)val).font;
					textMaterial = ((Graphic)val).material;
					return;
				}
			}
			TMP_FontAsset[] array2 = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			if (array2.Length != 0)
			{
				gameFont = array2[0];
			}
		}

		private static void SetupTextStyle(TextMeshProUGUI text, int fontSize, TextAlignmentOptions alignment)
		{
			//IL_0009: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)text).fontSize = fontSize;
			((TMP_Text)text).alignment = alignment;
			((TMP_Text)text).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)text).overflowMode = (TextOverflowModes)0;
			((Graphic)text).color = Color.white;
			((TMP_Text)text).enableAutoSizing = false;
			((TMP_Text)text).fontStyle = (FontStyles)1;
			((TMP_Text)text).outlineColor = Color32.op_Implicit(Color.black);
			((TMP_Text)text).faceColor = Color32.op_Implicit(Color.white);
			if ((Object)(object)gameFont != (Object)null)
			{
				((TMP_Text)text).font = gameFont;
			}
			if ((Object)(object)textMaterial != (Object)null)
			{
				((Graphic)text).material = textMaterial;
			}
			Shadow obj = ((Component)text).gameObject.AddComponent<Shadow>();
			obj.effectColor = new Color(0f, 0f, 0f, 0.95f);
			obj.effectDistance = new Vector2(2f, -2f);
			ApplyLiveTextSettings(text, fontSize);
		}

		private static void ApplyLiveTextSettings(TextMeshProUGUI text, int fontSize)
		{
			((TMP_Text)text).fontSize = fontSize;
			((TMP_Text)text).outlineWidth = Plugin.TextOutlineThickness.Value;
		}

		private static void UpdateStaminaTextColor(float current, float maximum, StaminaBar bar)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)staminaText == (Object)null))
			{
				float num = ((maximum > 0.001f) ? (current / maximum) : 0f);
				Image val = (((Object)(object)bar.staminaBar != (Object)null) ? ((Component)bar.staminaBar).GetComponent<Image>() : null);
				Color val2;
				if ((Object)(object)val != (Object)null)
				{
					float num2 = default(float);
					float num3 = default(float);
					float num4 = default(float);
					Color.RGBToHSV(((Graphic)val).color, ref num2, ref num3, ref num4);
					val2 = Color.HSVToRGB(num2, Mathf.Clamp01(num3 * 1.2f), Mathf.Clamp01(num4 * 1.3f));
				}
				else
				{
					val2 = ((num < 0.25f) ? LowStaminaColor : ((num < 0.5f) ? MediumStaminaColor : HighStaminaColor));
				}
				float num5 = default(float);
				float num6 = default(float);
				float num7 = default(float);
				Color.RGBToHSV(val2, ref num5, ref num6, ref num7);
				((Graphic)staminaText).color = Color.HSVToRGB(num5, num6, Mathf.Max(0.8f, num7));
				if ((Object)(object)extraStaminaText != (Object)null)
				{
					((Graphic)extraStaminaText).color = ExtraStaminaColor;
				}
			}
		}

		private static Color ResolveStatusColor(STATUSTYPE statusType, BarAffliction affliction)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			if (StatusColors.TryGetValue(statusType, out var value))
			{
				return value;
			}
			Image componentInChildren = ((Component)affliction).GetComponentInChildren<Image>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return Color.white;
			}
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(((Graphic)componentInChildren).color, ref num, ref num2, ref num3);
			return Color.HSVToRGB(num, Mathf.Clamp01(num2 * 1.2f), Mathf.Clamp01(num3 * 1.3f));
		}

		private static void EnsureRoundedValues(StaminaBar bar, Character observed)
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			if (roundedFrame == Time.frameCount && (Object)(object)attachedBar == (Object)(object)bar)
			{
				return;
			}
			roundedFrame = Time.frameCount;
			RoundedAfflictionValues.Clear();
			ExactAfflictionValues.Clear();
			List<STATUSTYPE> list = new List<STATUSTYPE>();
			HashSet<STATUSTYPE> hashSet = new HashSet<STATUSTYPE>();
			if (bar.afflictions != null)
			{
				BarAffliction[] afflictions = bar.afflictions;
				foreach (BarAffliction val in afflictions)
				{
					if ((Object)(object)val != (Object)null && hashSet.Add(val.afflictionType))
					{
						list.Add(val.afflictionType);
					}
				}
			}
			List<double> list2 = new List<double>(list.Count + 1) { (double)observed.data.currentStamina * 100.0 };
			foreach (STATUSTYPE item in list)
			{
				float num = ((observed.refs != null && (Object)(object)observed.refs.afflictions != (Object)null) ? (observed.refs.afflictions.GetCurrentStatus(item) * 100f) : 0f);
				ExactAfflictionValues[item] = num;
				list2.Add(num);
			}
			int[] array = MinimaxRounding.Round(list2);
			roundedStaminaValue = array[0];
			for (int j = 0; j < list.Count; j++)
			{
				RoundedAfflictionValues[list[j]] = array[j + 1];
			}
			roundedExtraStaminaValue = (int)Math.Round((double)observed.data.extraStamina * 100.0, MidpointRounding.AwayFromZero);
		}

		private static void UpdateExistingAfflictionTexts()
		{
			//IL_0030: 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)
			foreach (KeyValuePair<STATUSTYPE, TextMeshProUGUI> afflictionText in AfflictionTexts)
			{
				TextMeshProUGUI value = afflictionText.Value;
				if (!((Object)(object)value == (Object)null) && RoundedAfflictionValues.TryGetValue(afflictionText.Key, out var value2))
				{
					ApplyLiveTextSettings(value, Plugin.AfflictionFontSize.Value);
					((TMP_Text)value).text = FormatValue(value2);
					float value3;
					bool flag = ExactAfflictionValues.TryGetValue(afflictionText.Key, out value3) && value3 > 0.005f;
					if (((Component)value).gameObject.activeSelf != flag)
					{
						((Component)value).gameObject.SetActive(flag);
					}
				}
			}
		}

		private static string FormatValue(int value)
		{
			if (!Plugin.ShowPercentageSign.Value)
			{
				return value.ToString();
			}
			return $"{value}%";
		}

		private static void InvalidateRoundedValues()
		{
			roundedFrame = -1;
			roundedStaminaValue = 0;
			roundedExtraStaminaValue = 0;
			RoundedAfflictionValues.Clear();
			ExactAfflictionValues.Clear();
		}

		private static void SetStaminaTextVisible(bool visible)
		{
			if ((Object)(object)staminaTextContainer != (Object)null && staminaTextContainer.activeSelf != visible)
			{
				staminaTextContainer.SetActive(visible);
			}
		}

		private static void DestroyStaminaText()
		{
			if ((Object)(object)staminaTextContainer != (Object)null)
			{
				Object.Destroy((Object)(object)staminaTextContainer);
			}
			staminaTextContainer = null;
			staminaText = null;
			extraStaminaText = null;
		}

		private static void CleanupAfflictionTexts()
		{
			foreach (TextMeshProUGUI value in AfflictionTexts.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
			}
			AfflictionTexts.Clear();
		}
	}
	internal static class MinimaxRounding
	{
		private readonly struct Remainder
		{
			internal int Index { get; }

			internal double Fraction { get; }

			internal Remainder(int index, double fraction)
			{
				Index = index;
				Fraction = fraction;
			}
		}

		internal static int[] Round(IReadOnlyList<double> values)
		{
			if (values == null)
			{
				throw new ArgumentNullException("values");
			}
			int count = values.Count;
			int[] array = new int[count];
			if (count == 0)
			{
				return array;
			}
			double num = 0.0;
			long num2 = 0L;
			List<Remainder> list = new List<Remainder>(count);
			for (int i = 0; i < count; i++)
			{
				double num3 = values[i];
				if (double.IsNaN(num3) || double.IsInfinity(num3))
				{
					throw new ArgumentOutOfRangeException("values", "Values must be finite.");
				}
				double num4 = Math.Floor(num3);
				if (num4 < -2147483648.0 || num4 > 2147483647.0)
				{
					throw new ArgumentOutOfRangeException("values", "Values are outside the supported range.");
				}
				array[i] = (int)num4;
				num2 += array[i];
				num += num3;
				list.Add(new Remainder(i, num3 - num4));
			}
			long num5 = checked((long)Math.Round(num, MidpointRounding.AwayFromZero)) - num2;
			if (num5 < 0 || num5 > count)
			{
				throw new InvalidOperationException("The rounded total cannot be reached.");
			}
			list.Sort(delegate(Remainder left, Remainder right)
			{
				int num7 = right.Fraction.CompareTo(left.Fraction);
				return (num7 == 0) ? left.Index.CompareTo(right.Index) : num7;
			});
			for (int num6 = 0; num6 < num5; num6++)
			{
				array[list[num6].Index]++;
			}
			return array;
		}
	}
	[BepInPlugin("com.tactikot.StaminaStatsTactikot", "StaminaStatsTactikot", "1.1.0")]
	[BepInProcess("PEAK.exe")]
	[BepInIncompatibility("com.StaminaStats")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(StaminaBar), "Start")]
		private static class StaminaBarStartPatch
		{
			private static void Postfix(StaminaBar __instance)
			{
				try
				{
					HudController.AttachTo(__instance);
				}
				catch (Exception exception)
				{
					ReportOnce("StaminaBar.Start patch failed", exception);
				}
			}
		}

		[HarmonyPatch(typeof(StaminaBar), "Update")]
		private static class StaminaBarUpdatePatch
		{
			private static void Postfix(StaminaBar __instance)
			{
				try
				{
					HudController.UpdateStamina(__instance);
				}
				catch (Exception exception)
				{
					ReportOnce("StaminaBar.Update patch failed", exception);
				}
			}
		}

		[HarmonyPatch(typeof(StaminaBar), "ChangeBar")]
		private static class StaminaBarChangePatch
		{
			private static void Postfix(StaminaBar __instance)
			{
				try
				{
					HudController.RefreshAfflictions(__instance);
				}
				catch (Exception exception)
				{
					ReportOnce("StaminaBar.ChangeBar patch failed", exception);
				}
			}
		}

		[HarmonyPatch(typeof(BarAffliction), "UpdateAffliction")]
		private static class BarAfflictionUpdatePatch
		{
			private static void Postfix(BarAffliction __instance, StaminaBar bar)
			{
				try
				{
					HudController.UpdateAffliction(__instance, bar);
				}
				catch (Exception exception)
				{
					ReportOnce("BarAffliction.UpdateAffliction patch failed", exception);
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static LogCallback <0>__OnUnityLogMessage;
		}

		public const string PluginGuid = "com.tactikot.StaminaStatsTactikot";

		public const string PluginName = "StaminaStatsTactikot";

		public const string PluginVersion = "1.1.0";

		private static readonly HashSet<string> ReportedErrors = new HashSet<string>();

		private Harmony harmony;

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> ShowPercentageSign { get; private set; }

		internal static ConfigEntry<int> StaminaFontSize { get; private set; }

		internal static ConfigEntry<int> AfflictionFontSize { get; private set; }

		internal static ConfigEntry<float> TextOutlineThickness { get; private set; }

		internal static ConfigEntry<bool> VerboseLogging { get; private set; }

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			harmony = new Harmony("com.tactikot.StaminaStatsTactikot");
			harmony.PatchAll();
			object obj = <>O.<0>__OnUnityLogMessage;
			if (obj == null)
			{
				LogCallback val = OnUnityLogMessage;
				<>O.<0>__OnUnityLogMessage = val;
				obj = (object)val;
			}
			Application.logMessageReceived += (LogCallback)obj;
			Log.LogInfo((object)"StaminaStatsTactikot v1.1.0 loaded.");
		}

		private void OnDestroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__OnUnityLogMessage;
			if (obj == null)
			{
				LogCallback val = OnUnityLogMessage;
				<>O.<0>__OnUnityLogMessage = val;
				obj = (object)val;
			}
			Application.logMessageReceived -= (LogCallback)obj;
			Harmony obj2 = harmony;
			if (obj2 != null)
			{
				obj2.UnpatchSelf();
			}
			HudController.Cleanup();
		}

		private void BindConfig()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			ShowPercentageSign = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowPercentageSign", false, "Whether to show a percentage sign (%) after numeric values.");
			StaminaFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "StaminaFontSize", 18, new ConfigDescription("Font size for stamina text display.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 32), Array.Empty<object>()));
			AfflictionFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "AfflictionFontSize", 16, new ConfigDescription("Font size for affliction text display.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 32), Array.Empty<object>()));
			TextOutlineThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "TextOutlineThickness", 0.1f, new ConfigDescription("Thickness of the text outline.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.3f), Array.Empty<object>()));
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Enable detailed diagnostic logging.");
		}

		private static void OnUnityLogMessage(string message, string stackTrace, LogType type)
		{
			if (message.Contains("RUN STARTED"))
			{
				HudController.ResetForNewRun();
			}
		}

		internal static void ReportOnce(string operation, Exception exception)
		{
			string item = operation + ":" + exception.GetType().FullName + ":" + exception.Message;
			if (ReportedErrors.Add(item))
			{
				Log.LogError((object)(operation + ": " + exception.Message));
				if (VerboseLogging.Value)
				{
					Log.LogError((object)exception);
				}
			}
		}
	}
}