Decompiled source of PeakStatsEx v1.6.2

plugins/com.github.LengSword.PeakStatsEx.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Peak;
using PeakStatsEx.Compatibility;
using PeakStatsEx.MonoBehaviours;
using Photon.Pun;
using Steamworks;
using TMPro;
using TerrainRandomiser;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.Editor;

[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.LengSword.PeakStatsEx")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.6.2.0")]
[assembly: AssemblyInformationalVersion("1.6.2+8faac81322fa0895d63c65a3cdb91b2adc023f1c")]
[assembly: AssemblyProduct("com.github.LengSword.PeakStatsEx")]
[assembly: AssemblyTitle("PeakStatsEx")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://codeberg.org/yls-peak-mods/PeakStatsEx")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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")]
	[Embedded]
	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")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace PeakStatsEx
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.github.LengSword.PeakStatsEx", "PeakStatsEx", "1.6.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.github.LengSword.PeakStatsEx";

		internal static ManualLogSource Logger { get; private set; }

		public static string Name => "PeakStatsEx";

		public static string Version => "1.6.2";

		private void Awake()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)("Plugin " + Name + " is loaded!"));
			PluginConfig.Initialize(((BaseUnityPlugin)this).Config, Logger);
			Harmony val = new Harmony("com.github.LengSword.PeakStatsEx");
			val.PatchAll();
		}
	}
	[HarmonyWrapSafe]
	internal sealed class Patches
	{
		[HarmonyPatch(typeof(GUIManager), "Start")]
		[HarmonyPostfix]
		private static void GUIManagerStartHook(GUIManager __instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			TrueFinalAscentCompatibility tfaCompatibility = new TrueFinalAscentCompatibility();
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "Airport")
			{
				CreateTimerAndHeightStats();
				CreateMapStats();
			}
			ProximityStaminaManager.InitializeBarGroup(__instance);
			void CreateMapStats()
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: 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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0182: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = (RectTransform)((Component)((Component)__instance).GetComponentInChildren<AscentUI>()).transform;
				RectTransform val2 = Object.Instantiate<RectTransform>(val, ((Transform)val).parent);
				((Object)val2).name = "Map & Level UI";
				Object.Destroy((Object)(object)((Component)val2).GetComponent<AscentUI>());
				MapStats mapStats = ((Component)val2).gameObject.AddComponent<MapStats>();
				mapStats.InitializeCompatibility(tfaCompatibility);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(1f, 1f);
				val2.anchorMin = val3;
				Vector2 pivot = (val2.anchorMax = val3);
				val2.pivot = pivot;
				val2.anchoredPosition = new Vector2(-4f, 5f);
				RectTransform val5 = Object.Instantiate<RectTransform>(val, ((Transform)val).parent);
				((Object)val5).name = "Biome Route UI";
				Object.Destroy((Object)(object)((Component)val5).GetComponent<AscentUI>());
				((Vector2)(ref val3))..ctor(1f, 1f);
				val5.anchorMin = val3;
				pivot = (val5.anchorMax = val3);
				val5.pivot = pivot;
				float y = val.anchoredPosition.y;
				Rect rect = val.rect;
				val5.anchoredPosition = new Vector2(0f, y - ((Rect)(ref rect)).height + 8f);
				TMP_Text component = ((Component)val5).GetComponent<TMP_Text>();
				RectTransform val7 = Object.Instantiate<RectTransform>(val, ((Transform)val).parent);
				((Object)val7).name = "Biome Variant UI";
				Object.Destroy((Object)(object)((Component)val7).GetComponent<AscentUI>());
				((Vector2)(ref val3))..ctor(1f, 1f);
				val7.anchorMin = val3;
				pivot = (val7.anchorMax = val3);
				val7.pivot = pivot;
				float y2 = val5.anchoredPosition.y;
				rect = val.rect;
				val7.anchoredPosition = new Vector2(0f, y2 - ((Rect)(ref rect)).height + 22f);
				TMP_Text component2 = ((Component)val7).GetComponent<TMP_Text>();
				RectTransform component3 = ((Component)__instance.hudCanvas).GetComponent<RectTransform>();
				mapStats.InitializeRouteText(component, component2, component3);
			}
			void CreateTimerAndHeightStats()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				Transform transform = ((Component)((Component)__instance).GetComponentInChildren<AscentUI>()).transform;
				RectTransform val = (RectTransform)Object.Instantiate<Transform>(transform, transform.parent);
				((Object)val).name = "Timer & Height UI";
				Object.Destroy((Object)(object)((Component)val).GetComponent<AscentUI>());
				((Component)val).gameObject.AddComponent<TimerHeightStats>().InitializeCompatibility(tfaCompatibility);
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(0.5f, 1f);
				val.anchorMin = val2;
				Vector2 pivot = (val.anchorMax = val2);
				val.pivot = pivot;
				val.anchoredPosition = Vector2.zero;
			}
		}

		[HarmonyPatch(typeof(PlayerHandler), "RegisterCharacter")]
		[HarmonyPostfix]
		private static void PlayerHandlerRegisterCharacterHook(Character character)
		{
			if ((Object)(object)character != (Object)null && (Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.IsMine && (Object)(object)((Component)character).GetComponent<ProximityStaminaManager>() == (Object)null)
			{
				((Component)character).gameObject.AddComponent<ProximityStaminaManager>();
			}
		}

		[HarmonyPatch(typeof(LoadingScreenHandler), "LoadSceneProcess")]
		[HarmonyPostfix]
		private static void LoadSceneProcessHook(string sceneName)
		{
			if (sceneName.Contains("Level_"))
			{
				MapStats.currentLevelName = sceneName;
				MapStats.currentLevelIndex = -1;
				Plugin.Logger.LogDebug((object)("After: LoadingScreenHandler.LoadSceneProcess called. sceneName: " + sceneName));
			}
		}
	}
	internal static class StringExtensions
	{
		public static string TrimToByteLength(this string input, int byteLength)
		{
			if (string.IsNullOrEmpty(input))
			{
				return input;
			}
			int byteCount = Encoding.UTF8.GetByteCount(input);
			if (byteCount <= byteLength)
			{
				return input;
			}
			if (byteCount == input.Length)
			{
				return input.Substring(0, byteLength);
			}
			byte[] array = Encoding.UTF8.GetBytes(input);
			Array.Resize(ref array, byteLength);
			string text = Encoding.UTF8.GetString(array, 0, byteLength);
			return text.TrimEnd('\ufffd');
		}
	}
	public static class PluginConfig
	{
		internal static ConfigEntry<bool> DisplayTimer { get; private set; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static void Initialize(ConfigFile config, ManualLogSource logger)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Expected O, but got Unknown
			DisplayTeammateStaminaBars = config.Bind<bool>("General", "Display Teammate Stamina Bars", true, "Displays your teammates' stamina bars at the bottom left of your screen");
			TeammateStaminaBarProximity = config.Bind<float>("General", "Teammate Stamina Bar Proximity", 30f, new ConfigDescription("How close you need to be to your teammate to see their stamina bar", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10000f), Array.Empty<object>()));
			TeammateStaminaBarLimit = config.Bind<int>("General", "Teammate Stamina Bar Limit", 4, new ConfigDescription("Max teammate stamina bars", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 16), Array.Empty<object>()));
			TeammateStaminaBarScale = config.Bind<float>("General", "Teammate Stamina Bar Scale (Default: 0.72)", 0.72f, new ConfigDescription("Teammate stamina bars scale", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
			ShowInventorySlots = config.Bind<bool>("General", "Show Inventory Slots", true, "Show teammate inventory slots");
			ShowStaminaInfo = config.Bind<bool>("General", "Show Stamina Info", true, "Show all stamina bars info number (current stamina, extra stamina, affliction bars) when stamina bar is visible");
			DisplayTimer = config.Bind<bool>("Stats", "Display Timer", true, "Displays how long you've been climbing for, at the top of your screen");
			DisplayHeight = config.Bind<bool>("Stats", "Display Height", true, "Displays how far you've climbed, in meters, at the top of your screen");
			DisplayLevel = config.Bind<bool>("Stats", "Display Level", true, "Displays current map level name, at the top right of your screen");
			DisplayBiomes = config.Bind<bool>("Stats", "Display Biomes", true, "Displays current map biomes name, at the top right of your screen");
			DisplayDayNightCountdown = config.Bind<bool>("Stats", "Display Day Night Countdown", true, "Displays current day and night countdown, at the top of your screen");
			DisplayFog = config.Bind<bool>("Stats", "Display Fog Stats", true, "Displays current fog stats, at the top of your screen");
			DisplayLava = config.Bind<bool>("Stats", "Display Lava Stats", true, "Displays current kiln lava, gloom, and void ghost rising stats, at the top of your screen");
			DisplayMapSeed = config.Bind<bool>("Stats", "Display Map Seed", true, "Displays the current map seed from a supported map generation mod, at the top right of your screen");
			StaminaInfoFontSize = config.Bind<float>("StaminaInfo", "Bar Font Size", 20f, "Customize the Font Size for stamina bar text.");
			StaminaInfoOutlineWidth = config.Bind<float>("StaminaInfo", "Bar Outline Width", 0.08f, "Customize the Outline Width for stamina bar text.");
			StaminaInfoRoundStaminaBars = config.Bind<bool>("StaminaInfo", "Round Stamina Bars", true, "If true, rounds to the nearest whole number for the stamina and extra stamina bars.");
			StaminaInfoRoundAfflictionBars = config.Bind<bool>("StaminaInfo", "Round Affliction Bars", false, "If true, rounds to the nearest whole number for affliction bars.");
			StaminaInfoShowAfflictionCountdown = config.Bind<bool>("StaminaInfo", "Show Affliction Countdown", true, "If true, show self affliction bars with countdown.");
			StaminaInfoShowHungerCountdown = config.Bind<bool>("StaminaInfo", "Show Hunger Countdown", true, "If true, show local hunger countdown values in stamina info.");
			StaminaInfoShowTeammateExtraStaminaOutsideBar = config.Bind<bool>("StaminaInfo", "Show Teammate Extra Stamina Outside Bar", false, "If true, show teammate extra stamina values outside the right side of the full extra stamina bar with a + prefix. If false, show them inside the extra stamina bar.");
			DisplaySelfStaminaBar = config.Bind<bool>("Debug", "Display Self Stamina Bar", false, "Displays your stamina bar at the bottom left of your screen");
			SelfStaminaBarCount = config.Bind<int>("Debug", "Self Stamina Bar Count", 1, new ConfigDescription("Number of duplicate self stamina bars to display when Display Self Stamina Bar is enabled", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 16), Array.Empty<object>()));
			logger.LogInfo((object)"Plugin Config Loaded.");
		}
	}
	internal readonly struct AfflictionDisplayState
	{
		private readonly float[] statuses;

		internal float StatusSum { get; }

		internal bool UsesSnapshot { get; }

		internal AfflictionDisplayState(float[] statuses, float statusSum, bool usesSnapshot)
		{
			this.statuses = statuses;
			StatusSum = statusSum;
			UsesSnapshot = usesSnapshot;
		}

		internal float GetStatus(STATUSTYPE type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)type;
			if (num < 0 || num >= statuses.Length)
			{
				return 0f;
			}
			return statuses[num];
		}
	}
	[HarmonyPatch]
	internal static class RemoteAfflictionDisplay
	{
		private sealed class Snapshot
		{
			internal float[]? Statuses;

			internal float StatusSum;

			internal bool Required;
		}

		private static readonly ConditionalWeakTable<CharacterAfflictions, Snapshot> snapshots = new ConditionalWeakTable<CharacterAfflictions, Snapshot>();

		[HarmonyPatch(typeof(CharacterAfflictions), "DeserializeStatusArray")]
		[HarmonyPostfix]
		private static void CaptureSnapshot(CharacterAfflictions __instance, float[] __result)
		{
			if (((MonoBehaviourPun)__instance).photonView.IsMine)
			{
				return;
			}
			Snapshot value = snapshots.GetValue(__instance, (CharacterAfflictions _) => new Snapshot());
			value.Required |= __instance.character.data.isSkeleton;
			if (__result.Length == __instance.currentStatuses.Length)
			{
				float num = 0f;
				foreach (float num3 in __result)
				{
					num += num3;
				}
				value.Statuses = __result;
				value.StatusSum = num;
			}
		}

		internal static bool TryRead(Character character, out AfflictionDisplayState state)
		{
			state = default(AfflictionDisplayState);
			if (!Object.op_Implicit((Object)(object)character) || (Object)(object)character.refs.afflictions == (Object)null)
			{
				return false;
			}
			CharacterAfflictions afflictions = character.refs.afflictions;
			if (!character.IsLocal && !((MonoBehaviourPun)character).photonView.IsMine)
			{
				snapshots.TryGetValue(afflictions, out Snapshot value);
				if (character.data.isSkeleton)
				{
					if (value == null)
					{
						value = snapshots.GetValue(afflictions, (CharacterAfflictions _) => new Snapshot());
					}
					value.Required = true;
				}
				if (value != null && value.Required)
				{
					if (value.Statuses == null)
					{
						return false;
					}
					state = new AfflictionDisplayState(value.Statuses, value.StatusSum, usesSnapshot: true);
					return true;
				}
			}
			state = new AfflictionDisplayState(afflictions.currentStatuses, afflictions.statusSum, usesSnapshot: false);
			return true;
		}
	}
	[HarmonyWrapSafe]
	internal sealed class StaminaInfoPatch
	{
		private sealed class TextDisplayCache
		{
			internal (float Size, float? DisplayValue, bool Round, bool Trim, CultureInfo Culture)? NumberInput;

			internal string Number = string.Empty;

			internal (string Number, string Prefix, string Suffix)? ContentInput;

			internal string Content = string.Empty;

			internal (string Number, string Suffix)? MeasurementInput;

			internal string MeasurementText = string.Empty;

			internal (string Text, TMP_FontAsset Font, Material Material, float Size, FontStyles Style, FontWeight Weight, float CharacterSpacing, float WordSpacing, float LineSpacing, float ParagraphSpacing, bool RichText, bool ParseControlCharacters, bool RightToLeft, bool ExtraPadding, bool AutoSize, TMP_Style TextStyle)? WidthInput;

			internal float PreferredWidth;
		}

		private sealed class CountdownEntry
		{
			internal bool Eligible;

			internal int Visibility;

			internal float NextRefreshTime;

			internal string Suffix = string.Empty;

			internal string HighlightedSuffix = string.Empty;
		}

		private sealed class CountdownCache
		{
			internal Character? Character;

			internal CharacterAfflictions? Afflictions;

			internal (int Options, bool Conscious, bool Invincible, bool CanGetHungry, bool Airport, float HungerRate, CultureInfo Culture)? Input;

			internal int LastVisibleFrame = -1;

			internal readonly Dictionary<STATUSTYPE, CountdownEntry> Entries = new Dictionary<STATUSTYPE, CountdownEntry>();

			internal readonly RectTransform? MaxStamina;

			internal readonly BarAffliction? HungerBar;

			internal CountdownCache(StaminaBar bar)
			{
				ref RectTransform? maxStamina = ref MaxStamina;
				Transform obj = ((Component)bar).transform.Find("LayoutGroup/MaxStamina");
				maxStamina = (RectTransform?)(object)((obj is RectTransform) ? obj : null);
				HungerBar = GetHungerBar(bar);
			}
		}

		internal static GUIManager guiManager = null;

		internal static Dictionary<string, TextMeshProUGUI> barTexts = new Dictionary<string, TextMeshProUGUI>();

		internal static Dictionary<string, float> lastKnownData = new Dictionary<string, float>();

		internal static Dictionary<string, float> lastKnownAffData = new Dictionary<string, float>();

		private const float LargeBarThreshold = 30f;

		private const float SmallBarThreshold = 15f;

		private const float BarUnitSize = 6f;

		private const float AfflictionRefreshInterval = 0.5f;

		private const float HungerIncrementThreshold = 0.025f;

		private const float CharacterExtraStaminaTextOffsetX = 6f;

		private const float CharacterExtraStaminaTextWidth = 80f;

		private const string HiddenHungerCountdownKey = "HiddenHungerCountdown";

		private const string YellowTextStart = "<color=#FFFF00>";

		private const string ColorTextEnd = "</color>";

		private static readonly Dictionary<int, float> hungerIncrementalStatuses = new Dictionary<int, float>();

		private static readonly Dictionary<int, float> lastTrackedHungerAddTimes = new Dictionary<int, float>();

		private static readonly Dictionary<int, float> lastObservedRealHungerIncrementalStatuses = new Dictionary<int, float>();

		private static readonly Dictionary<int, float> lastRealHungerProgressTimes = new Dictionary<int, float>();

		private static readonly Dictionary<int, bool> wasHungerBlockedByVanilla = new Dictionary<int, bool>();

		private static readonly FieldInfo? currentIncrementalStatusesField = AccessTools.Field(typeof(CharacterAfflictions), "currentIncrementalStatuses");

		private static ConditionalWeakTable<TextMeshProUGUI, TextDisplayCache> textCaches = new ConditionalWeakTable<TextMeshProUGUI, TextDisplayCache>();

		private static ConditionalWeakTable<StaminaBar, CountdownCache> countdownCaches = new ConditionalWeakTable<StaminaBar, CountdownCache>();

		internal static Dictionary<int, float> LastUpdateTime { get; set; } = new Dictionary<int, float>();

		[HarmonyPatch(typeof(StaminaBar), "Update")]
		[HarmonyPostfix]
		private static void StaminaInfoStaminaBarUpdate(StaminaBar __instance)
		{
			try
			{
				if ((Object)(object)guiManager == (Object)null)
				{
					barTexts = new Dictionary<string, TextMeshProUGUI>();
					lastKnownData = new Dictionary<string, float>();
					lastKnownAffData = new Dictionary<string, float>();
					textCaches = new ConditionalWeakTable<TextMeshProUGUI, TextDisplayCache>();
					countdownCaches = new ConditionalWeakTable<StaminaBar, CountdownCache>();
					InitStaminaInfo(__instance);
				}
				if (!PluginConfig.ShowStaminaInfo.Value)
				{
					if (countdownCaches.TryGetValue(__instance, out CountdownCache value))
					{
						value.LastVisibleFrame = -1;
					}
					HideBarTexts(__instance);
				}
				else
				{
					ConstrainStaminaTextToFill(((Object)__instance.staminaBar).name, __instance.staminaBar);
					if ((Object)(object)Character.observedCharacter != (Object)null)
					{
						UpdateBarTexts(__instance);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)(ex.Message + ex.StackTrace));
			}
		}

		[HarmonyPatch(typeof(CharacterStaminaBar), "Update")]
		[HarmonyPostfix]
		public static void Update(CharacterStaminaBar __instance)
		{
			try
			{
				if (!((Component)__instance).gameObject.activeInHierarchy || !__instance.HasDisplayAfflictions)
				{
					return;
				}
				int instanceID = ((Object)__instance).GetInstanceID();
				if (!LastUpdateTime.ContainsKey(instanceID))
				{
					LastUpdateTime.Add(instanceID, -1f);
				}
				if (!barTexts.ContainsKey(GetCharacterStaminaKey(instanceID)))
				{
					InitCharacterStaminaInfo(__instance);
				}
				if (!PluginConfig.ShowStaminaInfo.Value)
				{
					HideCharacterBarTexts(__instance);
					return;
				}
				ConstrainStaminaTextToFill(GetCharacterStaminaKey(instanceID), __instance.staminaBarRectTransform);
				if ((Object)(object)Character.observedCharacter != (Object)null && (__instance.NeedsImmediateTextRefresh || Time.time - LastUpdateTime[instanceID] > 1f))
				{
					UpdateCharacterBarTexts(__instance);
					__instance.NeedsImmediateTextRefresh = false;
					LastUpdateTime[instanceID] = Time.time;
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)(ex.Message + ex.StackTrace));
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
		[HarmonyPostfix]
		private static void CharacterAfflictionsAddStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)statusType != 1 || amount <= 0f)
			{
				return;
			}
			if (__result)
			{
				if (TryReadCurrentIncrementalHunger(__instance, out var currentIncrementalStatus))
				{
					SetFallbackHungerIncrementalStatus(__instance, currentIncrementalStatus);
				}
				else
				{
					AddFallbackHungerIncrementalStatus(__instance, amount);
				}
			}
			else if (ShouldTrackHungerAdd(__instance))
			{
				AddFallbackHungerIncrementalStatus(__instance, amount);
			}
		}

		private static bool ShouldTrackHungerAdd(CharacterAfflictions afflictions)
		{
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)observedCharacter?.refs?.afflictions != (Object)(object)afflictions)
			{
				return false;
			}
			if (observedCharacter.data.fullyConscious && afflictions.canGetHungry)
			{
				return afflictions.hungerPerSecond * Ascents.hungerRateMultiplier > 0f;
			}
			return false;
		}

		private static void AddFallbackHungerIncrementalStatus(CharacterAfflictions afflictions, float amount)
		{
			int instanceID = ((Object)afflictions).GetInstanceID();
			hungerIncrementalStatuses.TryGetValue(instanceID, out var value);
			value += amount;
			SetFallbackHungerIncrementalStatus(afflictions, (value >= 0.025f) ? 0f : value);
		}

		private static void SetFallbackHungerIncrementalStatus(CharacterAfflictions afflictions, float currentIncrementalStatus)
		{
			int instanceID = ((Object)afflictions).GetInstanceID();
			hungerIncrementalStatuses[instanceID] = currentIncrementalStatus;
			lastTrackedHungerAddTimes[instanceID] = Time.time;
		}

		private static void ClearFallbackHungerIncrementalStatus(CharacterAfflictions afflictions)
		{
			hungerIncrementalStatuses[((Object)afflictions).GetInstanceID()] = 0f;
		}

		private static float GetFallbackHungerIncrementalStatus(CharacterAfflictions afflictions)
		{
			int instanceID = ((Object)afflictions).GetInstanceID();
			hungerIncrementalStatuses.TryGetValue(instanceID, out var value);
			return value;
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "SubtractStatus")]
		[HarmonyPrefix]
		private static void CharacterAfflictionsSubtractStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			__state = (((int)statusType == 1) ? __instance.GetCurrentStatus((STATUSTYPE)1) : (-1f));
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "SubtractStatus")]
		[HarmonyPostfix]
		private static void CharacterAfflictionsSubtractStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType, float __state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)statusType == 1 && !(__state <= 0f))
			{
				float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)1);
				if (currentStatus < __state)
				{
					hungerIncrementalStatuses[((Object)__instance).GetInstanceID()] = 0f;
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "SetStatus")]
		[HarmonyPostfix]
		private static void CharacterAfflictionsSetStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)statusType == 1)
			{
				hungerIncrementalStatuses[((Object)__instance).GetInstanceID()] = 0f;
			}
		}

		private static void UpdateBarTexts(StaminaBar staminaBar)
		{
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Invalid comparison between Unknown and I4
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			CountdownCache countdownCache = PrepareCountdowns(staminaBar);
			BarAffliction hungerBar = countdownCache.HungerBar;
			Character character = countdownCache.Character;
			CharacterAfflictions afflictions = countdownCache.Afflictions;
			bool eligible = PluginConfig.StaminaInfoShowHungerCountdown.Value && (Object)(object)character != (Object)null && (Object)(object)character == (Object)(object)Character.localCharacter && (Object)(object)afflictions != (Object)null && character.data.fullyConscious && !afflictions.m_inAirport && afflictions.hungerPerSecond * Ascents.hungerRateMultiplier > 0f;
			CountdownEntry countdownEntry = ReadCountdown(countdownCache, (STATUSTYPE)1, eligible, GetCountdownVisibility(hungerBar, afflictions, (STATUSTYPE)1));
			bool flag = countdownEntry.Suffix.Length > 0 && ((Object)(object)hungerBar == (Object)null || !IsVisibleAfflictionBar(hungerBar) || ShouldMoveHungerCountdownToStamina(hungerBar, countdownEntry.Suffix));
			string text = (flag ? countdownEntry.HighlightedSuffix : string.Empty);
			bool flag2 = staminaBar.desiredStaminaSize >= 15f;
			UpdateMaxStaminaHungerCountdown(countdownCache, flag2 ? string.Empty : text);
			UpdateBarText(((Object)staminaBar.staminaBar).name, staminaBar.desiredStaminaSize, PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData, "", flag2 ? text : string.Empty);
			UpdateBarText("ExtraStamina", staminaBar.desiredExtraStaminaSize, PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData);
			BarAffliction[] afflictions2 = staminaBar.afflictions;
			foreach (BarAffliction val in afflictions2)
			{
				string name = ((Object)val).name;
				string suffix = string.Empty;
				if ((int)val.afflictionType == 1)
				{
					if (!flag)
					{
						suffix = countdownEntry.Suffix;
					}
				}
				else if (CanShowCountdown(val.afflictionType))
				{
					bool eligible2 = IsCountdownEnabled(val.afflictionType) && IsVisibleAfflictionBar(val);
					suffix = ReadCountdown(countdownCache, val.afflictionType, eligible2, GetCountdownVisibility(val, afflictions, val.afflictionType)).Suffix;
				}
				UpdateBarText(name, val.size, PluginConfig.StaminaInfoRoundAfflictionBars.Value, trimWholeDecimal: true, lastKnownAffData, "", suffix);
			}
		}

		private static CountdownCache PrepareCountdowns(StaminaBar staminaBar)
		{
			CountdownCache value = countdownCaches.GetValue(staminaBar, (StaminaBar bar) => new CountdownCache(bar));
			Character observedCharacter = Character.observedCharacter;
			CharacterAfflictions val = observedCharacter?.refs?.afflictions;
			int item = (int)((PluginConfig.StaminaInfoShowHungerCountdown.Value ? 1u : 0u) | (uint)(PluginConfig.StaminaInfoShowAfflictionCountdown.Value ? 2 : 0) | (uint)(PluginConfig.StaminaInfoRoundStaminaBars.Value ? 4 : 0)) | (PluginConfig.StaminaInfoRoundAfflictionBars.Value ? 8 : 0);
			(int, bool, bool, bool, bool, float, CultureInfo) tuple = (item, observedCharacter != null && observedCharacter.data.fullyConscious, observedCharacter?.data.isInvincible ?? false, val != null && val.canGetHungry, val?.m_inAirport ?? false, ((Object)(object)val != (Object)null) ? (val.hungerPerSecond * Ascents.hungerRateMultiplier) : 0f, CultureInfo.CurrentCulture);
			if (!((Object)(object)value.Character != (Object)(object)observedCharacter) && !((Object)(object)value.Afflictions != (Object)(object)val))
			{
				(int, bool, bool, bool, bool, float, CultureInfo)? input = value.Input;
				(int, bool, bool, bool, bool, float, CultureInfo) tuple2 = tuple;
				bool hasValue = input.HasValue;
				if (hasValue)
				{
					if (hasValue)
					{
						(int, bool, bool, bool, bool, float, CultureInfo) valueOrDefault = input.GetValueOrDefault();
						(int, bool, bool, bool, bool, float, CultureInfo) tuple3 = tuple2;
						if (valueOrDefault.Item1 != tuple3.Item1 || valueOrDefault.Item2 != tuple3.Item2 || valueOrDefault.Item3 != tuple3.Item3 || valueOrDefault.Item4 != tuple3.Item4 || valueOrDefault.Item5 != tuple3.Item5 || valueOrDefault.Item6 != tuple3.Item6 || valueOrDefault.Item7 != tuple3.Item7)
						{
							goto IL_01cd;
						}
					}
					if (value.LastVisibleFrame >= Time.frameCount - 1)
					{
						goto IL_01f3;
					}
				}
			}
			goto IL_01cd;
			IL_01f3:
			value.LastVisibleFrame = Time.frameCount;
			return value;
			IL_01cd:
			value.Entries.Clear();
			value.Character = observedCharacter;
			value.Afflictions = val;
			value.Input = tuple;
			goto IL_01f3;
		}

		private static int GetCountdownVisibility(BarAffliction? bar, CharacterAfflictions? afflictions, STATUSTYPE type)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return (((Object)(object)bar != (Object)null && IsVisibleAfflictionBar(bar)) ? 1 : 0) | (((Object)(object)afflictions != (Object)null && afflictions.GetCurrentStatus(type) > 0f) ? 2 : 0);
		}

		private static CountdownEntry ReadCountdown(CountdownCache countdown, STATUSTYPE type, bool eligible, int visibility)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (!countdown.Entries.TryGetValue(type, out CountdownEntry value))
			{
				value = new CountdownEntry();
				countdown.Entries.Add(type, value);
			}
			bool flag = value.Eligible != eligible || value.Visibility != visibility;
			value.Eligible = eligible;
			value.Visibility = visibility;
			if (!eligible)
			{
				value.Suffix = (value.HighlightedSuffix = string.Empty);
				return value;
			}
			if (!flag && Time.unscaledTime < value.NextRefreshTime)
			{
				return value;
			}
			value.NextRefreshTime = Time.unscaledTime + 0.5f;
			float num = (((int)type == 1) ? GetHungerIncreaseTimeRemaining(countdown.Character, countdown.Afflictions) : GetReductionTimeRemaining(type));
			string text = ((num > 0f) ? ("(" + FormatTime(num) + ")") : string.Empty);
			if (value.Suffix != text)
			{
				value.Suffix = text;
				value.HighlightedSuffix = ((text.Length > 0) ? ("<color=#FFFF00>" + text + "</color>") : string.Empty);
			}
			return value;
		}

		private static void UpdateMaxStaminaHungerCountdown(CountdownCache countdown, string suffix)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (!barTexts.TryGetValue("HiddenHungerCountdown", out TextMeshProUGUI value))
			{
				return;
			}
			if (suffix.Length == 0 || (Object)(object)countdown.MaxStamina == (Object)null || GetPreferredWidth(value, suffix) > countdown.MaxStamina.sizeDelta.x)
			{
				SetTextVisible(value, visible: false);
				return;
			}
			if (((TMP_Text)value).text != suffix)
			{
				((TMP_Text)value).text = suffix;
			}
			SetTextVisible(value, visible: true);
		}

		private static BarAffliction? GetHungerBar(StaminaBar staminaBar)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			BarAffliction[] afflictions = staminaBar.afflictions;
			foreach (BarAffliction val in afflictions)
			{
				if ((int)val.afflictionType == 1)
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsVisibleAfflictionBar(BarAffliction affliction)
		{
			if (((Component)affliction).gameObject.activeSelf)
			{
				return affliction.size >= 15f;
			}
			return false;
		}

		private static bool ShouldMoveHungerCountdownToStamina(BarAffliction affliction, string suffix)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)affliction.afflictionType != 1 || !IsVisibleAfflictionBar(affliction))
			{
				return false;
			}
			if (!barTexts.TryGetValue(((Object)affliction).name, out TextMeshProUGUI value))
			{
				return false;
			}
			TextDisplayCache value2 = textCaches.GetValue(value, (TextMeshProUGUI _) => new TextDisplayCache());
			string numberText = GetNumberText(value2, affliction.size, PluginConfig.StaminaInfoRoundAfflictionBars.Value, trimWholeDecimal: true, null);
			(string, string) tuple = (numberText, suffix);
			(string, string)? measurementInput = value2.MeasurementInput;
			(string, string) tuple2 = tuple;
			bool hasValue = measurementInput.HasValue;
			if (!hasValue)
			{
				goto IL_00d7;
			}
			if (hasValue)
			{
				(string, string) valueOrDefault = measurementInput.GetValueOrDefault();
				if (valueOrDefault.Item1 != tuple2.Item1 || valueOrDefault.Item2 != tuple2.Item2)
				{
					goto IL_00d7;
				}
			}
			goto IL_00f0;
			IL_00d7:
			value2.MeasurementText = numberText + suffix;
			value2.MeasurementInput = tuple;
			goto IL_00f0;
			IL_00f0:
			float preferredWidth = GetPreferredWidth(value, value2.MeasurementText);
			return preferredWidth > affliction.size;
		}

		public static void UpdateCharacterBarTexts(CharacterStaminaBar characterStaminaBar)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)characterStaminaBar.ObservedCharacter == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)characterStaminaBar).GetInstanceID();
			float size = Mathf.Max(0f, characterStaminaBar.ObservedCharacter.data.currentStamina * characterStaminaBar.fullBarRectTransform.sizeDelta.x);
			UpdateBarText(GetCharacterStaminaKey(instanceID), size, PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData);
			float size2 = Mathf.Max(0f, characterStaminaBar.ObservedCharacter.data.extraStamina * characterStaminaBar.fullBarRectTransform.sizeDelta.x);
			bool value = PluginConfig.StaminaInfoShowTeammateExtraStaminaOutsideBar.Value;
			ApplyCharacterExtraStaminaTextLayout(characterStaminaBar, value);
			UpdateBarText(GetCharacterExtraStaminaKey(instanceID), size2, PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData, value ? "+" : string.Empty);
			foreach (CharacterBarAffliction characterBarAffliction in characterStaminaBar.characterBarAfflictions)
			{
				characterBarAffliction.FetchDesiredSize();
				UpdateBarText(GetCharacterAfflictionKey(instanceID, characterBarAffliction), characterBarAffliction.size, PluginConfig.StaminaInfoRoundAfflictionBars.Value, trimWholeDecimal: true, lastKnownAffData, "", "", characterStaminaBar.DisplayAfflictions.UsesSnapshot ? new float?(characterBarAffliction.StatusValue) : ((float?)null));
			}
		}

		private static void UpdateBarText(string key, float size, bool roundLargeValue, bool trimWholeDecimal, Dictionary<string, float> cache, string prefix = "", string suffix = "", float? displayValue = null)
		{
			if (!barTexts.TryGetValue(key, out TextMeshProUGUI value))
			{
				return;
			}
			if (size < 15f)
			{
				SetTextVisible(value, visible: false);
				cache[key] = size;
				return;
			}
			TextDisplayCache value2 = textCaches.GetValue(value, (TextMeshProUGUI _) => new TextDisplayCache());
			string numberText = GetNumberText(value2, size, roundLargeValue, trimWholeDecimal, displayValue);
			string contentText = GetContentText(value2, numberText, prefix, suffix);
			if (((TMP_Text)value).text != contentText)
			{
				((TMP_Text)value).text = contentText;
			}
			SetTextVisible(value, visible: true);
			cache[key] = size;
		}

		private static string GetNumberText(TextDisplayCache cache, float size, bool roundLargeValue, bool trimWholeDecimal, float? displayValue)
		{
			(float, float?, bool, bool, CultureInfo) tuple = (size, displayValue, roundLargeValue, trimWholeDecimal, CultureInfo.CurrentCulture);
			(float, float?, bool, bool, CultureInfo)? numberInput = cache.NumberInput;
			(float, float?, bool, bool, CultureInfo) tuple2 = tuple;
			bool hasValue = numberInput.HasValue;
			if (!hasValue)
			{
				goto IL_00bd;
			}
			if (hasValue)
			{
				(float, float?, bool, bool, CultureInfo) valueOrDefault = numberInput.GetValueOrDefault();
				(float, float?, bool, bool, CultureInfo) tuple3 = tuple2;
				if (valueOrDefault.Item1 != tuple3.Item1 || valueOrDefault.Item2 != tuple3.Item2 || valueOrDefault.Item3 != tuple3.Item3 || valueOrDefault.Item4 != tuple3.Item4 || valueOrDefault.Item5 != tuple3.Item5)
				{
					goto IL_00bd;
				}
			}
			goto IL_00ef;
			IL_00bd:
			cache.Number = (displayValue.HasValue ? FormatAfflictionValue(displayValue.Value, roundLargeValue) : FormatBarValue(size, roundLargeValue, trimWholeDecimal));
			cache.NumberInput = tuple;
			goto IL_00ef;
			IL_00ef:
			return cache.Number;
		}

		private static string GetContentText(TextDisplayCache cache, string number, string prefix, string suffix)
		{
			(string, string, string) tuple = (number, prefix, suffix);
			(string, string, string)? contentInput = cache.ContentInput;
			(string, string, string) tuple2 = tuple;
			bool hasValue = contentInput.HasValue;
			if (!hasValue)
			{
				goto IL_006f;
			}
			if (hasValue)
			{
				(string, string, string) valueOrDefault = contentInput.GetValueOrDefault();
				if (valueOrDefault.Item1 != tuple2.Item1 || valueOrDefault.Item2 != tuple2.Item2 || valueOrDefault.Item3 != tuple2.Item3)
				{
					goto IL_006f;
				}
			}
			goto IL_0089;
			IL_006f:
			cache.Content = prefix + number + suffix;
			cache.ContentInput = tuple;
			goto IL_0089;
			IL_0089:
			return cache.Content;
		}

		private static float GetPreferredWidth(TextMeshProUGUI text, string content)
		{
			//IL_0041: 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_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			TextDisplayCache value = textCaches.GetValue(text, (TextMeshProUGUI _) => new TextDisplayCache());
			(string, TMP_FontAsset, Material, float, FontStyles, FontWeight, float, float, float, float, bool, bool, bool, bool, bool, TMP_Style) tuple = (content, ((TMP_Text)text).font, ((TMP_Text)text).fontSharedMaterial, ((TMP_Text)text).fontSize, ((TMP_Text)text).fontStyle, ((TMP_Text)text).fontWeight, ((TMP_Text)text).characterSpacing, ((TMP_Text)text).wordSpacing, ((TMP_Text)text).lineSpacing, ((TMP_Text)text).paragraphSpacing, ((TMP_Text)text).richText, ((TMP_Text)text).parseCtrlCharacters, ((TMP_Text)text).isRightToLeftText, ((TMP_Text)text).extraPadding, ((TMP_Text)text).enableAutoSizing, ((TMP_Text)text).textStyle);
			(string, TMP_FontAsset, Material, float, FontStyles, FontWeight, float, float, float, float, bool, bool, bool, bool, bool, TMP_Style)? widthInput = value.WidthInput;
			(string, TMP_FontAsset, Material, float, FontStyles, FontWeight, float, float, float, float, bool, bool, bool, bool, bool, TMP_Style) tuple2 = tuple;
			bool hasValue = widthInput.HasValue;
			if (!hasValue)
			{
				goto IL_0272;
			}
			if (hasValue)
			{
				(string, TMP_FontAsset, Material, float, FontStyles, FontWeight, float, float, float, float, bool, bool, bool, bool, bool, TMP_Style) valueOrDefault = widthInput.GetValueOrDefault();
				(string, TMP_FontAsset, Material, float, FontStyles, FontWeight, float, float, float, float, bool, bool, bool, bool, bool, TMP_Style) tuple3 = tuple2;
				if (valueOrDefault.Item1 != tuple3.Item1 || (Object)(object)valueOrDefault.Item2 != (Object)(object)tuple3.Item2 || (Object)(object)valueOrDefault.Item3 != (Object)(object)tuple3.Item3 || valueOrDefault.Item4 != tuple3.Item4 || valueOrDefault.Item5 != tuple3.Item5 || valueOrDefault.Item6 != tuple3.Item6 || valueOrDefault.Item7 != tuple3.Item7 || valueOrDefault.Rest.Item1 != tuple3.Rest.Item1 || valueOrDefault.Rest.Item2 != tuple3.Rest.Item2 || valueOrDefault.Rest.Item3 != tuple3.Rest.Item3 || valueOrDefault.Rest.Item4 != tuple3.Rest.Item4 || valueOrDefault.Rest.Item5 != tuple3.Rest.Item5 || valueOrDefault.Rest.Item6 != tuple3.Rest.Item6 || valueOrDefault.Rest.Item7 != tuple3.Rest.Item7 || valueOrDefault.Rest.Rest.Item1 != tuple3.Rest.Rest.Item1 || valueOrDefault.Rest.Rest.Item2 != tuple3.Rest.Rest.Item2)
				{
					goto IL_0272;
				}
			}
			goto IL_0290;
			IL_0272:
			value.PreferredWidth = ((TMP_Text)text).GetPreferredValues(content).x;
			value.WidthInput = tuple;
			goto IL_0290;
			IL_0290:
			return value.PreferredWidth;
		}

		private static void SetTextVisible(TextMeshProUGUI text, bool visible)
		{
			if (((Component)text).gameObject.activeSelf != visible)
			{
				((Component)text).gameObject.SetActive(visible);
			}
		}

		private static string FormatAfflictionValue(float value, bool round)
		{
			if (!round)
			{
				return value.ToString("F1").Replace(".0", "");
			}
			return Mathf.Round(value).ToString();
		}

		private static string FormatBarValue(float size, bool roundLargeValue, bool trimWholeDecimal)
		{
			if (size >= 30f)
			{
				float num = size / 6f;
				if (roundLargeValue)
				{
					return Mathf.Round(num).ToString();
				}
				string text = num.ToString("F1");
				if (!trimWholeDecimal)
				{
					return text;
				}
				return text.Replace(".0", "");
			}
			return Mathf.Round(size / 6f).ToString();
		}

		private static void HideBarTexts(StaminaBar staminaBar)
		{
			HideText(((Object)staminaBar.staminaBar).name);
			HideText("ExtraStamina");
			HideText("HiddenHungerCountdown");
			BarAffliction[] afflictions = staminaBar.afflictions;
			foreach (BarAffliction val in afflictions)
			{
				HideText(((Object)val).name);
			}
		}

		private static void HideCharacterBarTexts(CharacterStaminaBar characterStaminaBar)
		{
			int instanceID = ((Object)characterStaminaBar).GetInstanceID();
			HideText(GetCharacterStaminaKey(instanceID));
			HideText(GetCharacterExtraStaminaKey(instanceID));
			foreach (CharacterBarAffliction characterBarAffliction in characterStaminaBar.characterBarAfflictions)
			{
				HideText(GetCharacterAfflictionKey(instanceID, characterBarAffliction));
			}
		}

		private static void HideText(string key)
		{
			if (barTexts.TryGetValue(key, out TextMeshProUGUI value))
			{
				SetTextVisible(value, visible: false);
			}
		}

		private static bool CanShowCountdown(STATUSTYPE afflictionType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected I4, but got Unknown
			switch (afflictionType - 1)
			{
			case 0:
			case 2:
			case 5:
			case 7:
			case 8:
			case 9:
				return true;
			default:
				return false;
			}
		}

		private static bool IsCountdownEnabled(STATUSTYPE afflictionType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)afflictionType != 1)
			{
				return PluginConfig.StaminaInfoShowAfflictionCountdown.Value;
			}
			return PluginConfig.StaminaInfoShowHungerCountdown.Value;
		}

		private static string GetCharacterStaminaKey(int id)
		{
			return id + "_Stamina";
		}

		private static string GetCharacterExtraStaminaKey(int id)
		{
			return id + "_ExtraStamina";
		}

		private static string GetCharacterAfflictionKey(int id, CharacterBarAffliction affliction)
		{
			return id + "_" + ((Object)((Component)affliction).gameObject).name;
		}

		private static void InitStaminaInfo(StaminaBar staminaBar)
		{
			GameObject val = GameObject.Find("GAME/GUIManager");
			guiManager = val.GetComponent<GUIManager>();
			AddTextObject(((Component)staminaBar.staminaBar).gameObject, ((Object)staminaBar.staminaBar).name);
			AddMaxStaminaHungerCountdownTextObject(staminaBar);
			AddTextObject(((Component)staminaBar.extraBarStamina).gameObject, "ExtraStamina");
			BarAffliction[] afflictions = staminaBar.afflictions;
			foreach (BarAffliction val2 in afflictions)
			{
				AddTextObject(((Component)val2).gameObject, ((Object)((Component)val2).gameObject).name);
			}
			countdownCaches.GetValue(staminaBar, (StaminaBar bar) => new CountdownCache(bar));
		}

		public static void InitCharacterStaminaInfo(CharacterStaminaBar characterStaminaBar)
		{
			int instanceID = ((Object)characterStaminaBar).GetInstanceID();
			AddTextObject(((Component)characterStaminaBar.staminaBarRectTransform).gameObject, GetCharacterStaminaKey(instanceID));
			string characterExtraStaminaKey = GetCharacterExtraStaminaKey(instanceID);
			AddTextObject(((Component)characterStaminaBar.extraBar).gameObject, characterExtraStaminaKey);
			ApplyCharacterExtraStaminaTextLayout(characterStaminaBar, PluginConfig.StaminaInfoShowTeammateExtraStaminaOutsideBar.Value);
			foreach (CharacterBarAffliction characterBarAffliction in characterStaminaBar.characterBarAfflictions)
			{
				AddTextObject(((Component)characterBarAffliction).gameObject, GetCharacterAfflictionKey(instanceID, characterBarAffliction));
			}
		}

		private static void ApplyCharacterExtraStaminaTextLayout(CharacterStaminaBar characterStaminaBar, bool showOutsideBar)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			string characterExtraStaminaKey = GetCharacterExtraStaminaKey(((Object)characterStaminaBar).GetInstanceID());
			if (!barTexts.TryGetValue(characterExtraStaminaKey, out TextMeshProUGUI value))
			{
				return;
			}
			if (showOutsideBar)
			{
				if ((Object)(object)((TMP_Text)value).transform.parent != (Object)(object)characterStaminaBar.extraBar)
				{
					((TMP_Text)value).transform.SetParent((Transform)(object)characterStaminaBar.extraBar, false);
				}
				((Graphic)value).color = Color.green;
				PositionCharacterExtraStaminaTextOutsideBar(value, characterStaminaBar);
			}
			else
			{
				Transform val = (Transform)(((object)((Transform)characterStaminaBar.extraBarStamina).Find("Stamina")) ?? ((object)characterStaminaBar.extraBarStamina));
				if ((Object)(object)((TMP_Text)value).transform.parent != (Object)(object)val)
				{
					((TMP_Text)value).transform.SetParent(val, false);
				}
				PositionCharacterExtraStaminaTextInsideBar(value);
			}
		}

		private static void PositionCharacterExtraStaminaTextInsideBar(TextMeshProUGUI text)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((TMP_Text)text).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = Vector2.zero;
			((Transform)rectTransform).localRotation = Quaternion.identity;
			((Transform)rectTransform).localScale = Vector3.one;
			rectTransform.offsetMin = Vector2.zero;
			rectTransform.offsetMax = Vector2.zero;
			((Graphic)text).color = Color.black;
			((TMP_Text)text).alignment = (TextAlignmentOptions)514;
		}

		private static void PositionCharacterExtraStaminaTextOutsideBar(TextMeshProUGUI text, CharacterStaminaBar characterStaminaBar)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0058: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((TMP_Text)text).rectTransform;
			RectTransform extraBarOutline = characterStaminaBar.extraBarOutline;
			float num = extraBarOutline.anchoredPosition.x + extraBarOutline.sizeDelta.x * (1f - extraBarOutline.pivot.x);
			rectTransform.anchorMin = new Vector2(0f, 0.5f);
			rectTransform.anchorMax = new Vector2(0f, 0.5f);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.anchoredPosition = new Vector2(num + 6f, extraBarOutline.anchoredPosition.y);
			rectTransform.sizeDelta = new Vector2(80f, Mathf.Max(extraBarOutline.sizeDelta.y, 1f));
			((Transform)rectTransform).localRotation = Quaternion.identity;
			((Transform)rectTransform).localScale = Vector3.one;
			((TMP_Text)text).alignment = (TextAlignmentOptions)513;
		}

		private static void AddMaxStaminaHungerCountdownTextObject(StaminaBar staminaBar)
		{
			Transform val = ((Component)staminaBar).transform.Find("LayoutGroup/MaxStamina");
			if (!((Object)(object)val == (Object)null))
			{
				AddTextObject(((Component)val).gameObject, "HiddenHungerCountdown");
			}
		}

		internal static void AddTextObject(GameObject gameObj, string barName)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)guiManager == (Object)null)
			{
				guiManager = GUIManager.instance;
			}
			if ((Object)(object)guiManager == (Object)null)
			{
				return;
			}
			TMP_FontAsset font = ((TMP_Text)guiManager.heroDayText).font;
			GameObject val = new GameObject("StaminaInfo");
			val.transform.SetParent(gameObj.transform);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			RectTransform component = val.GetComponent<RectTransform>();
			gameObj.SetActive(true);
			((TMP_Text)val2).font = font;
			((TMP_Text)val2).fontSize = PluginConfig.StaminaInfoFontSize.Value;
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			((Transform)component).localRotation = Quaternion.identity;
			CharacterBarAffliction characterBarAffliction = default(CharacterBarAffliction);
			((Transform)component).localScale = (Vector3)((gameObj.TryGetComponent<CharacterBarAffliction>(ref characterBarAffliction) && characterBarAffliction.isPetrify) ? new Vector3(1.4285715f, 2f, 1f) : Vector3.one);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val2).verticalAlignment = (VerticalAlignmentOptions)8192;
			((TMP_Text)val2).richText = true;
			((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val2).text = "";
			((Component)val2).gameObject.SetActive(false);
			barTexts[barName] = val2;
			lastKnownData[barName] = 0f;
			lastKnownAffData[barName] = 0f;
			try
			{
				((TMP_Text)val2).outlineWidth = PluginConfig.StaminaInfoOutlineWidth.Value;
			}
			catch
			{
			}
		}

		private static void ConstrainStaminaTextToFill(string key, RectTransform fillRectTransform)
		{
			if (barTexts.TryGetValue(key, out TextMeshProUGUI value))
			{
				SetStaminaTextBounds(value, fillRectTransform);
			}
		}

		private static void SetStaminaTextBounds(TextMeshProUGUI text, RectTransform fillRectTransform)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0064: 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_0084: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = fillRectTransform.rect;
			float num = Mathf.Max(0f, ((Rect)(ref rect)).width);
			Transform parent = ((Transform)fillRectTransform).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if (val != null)
			{
				float num2 = num;
				rect = val.rect;
				num = Mathf.Min(num2, Mathf.Max(0f, ((Rect)(ref rect)).width));
			}
			RectTransform rectTransform = ((TMP_Text)text).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.anchoredPosition = Vector2.zero;
			rectTransform.sizeDelta = new Vector2(num, 0f);
		}

		private static float GetReductionTimeRemaining(STATUSTYPE statusType)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			CharacterAfflictions val = Character.observedCharacter?.refs?.afflictions;
			if ((Object)(object)val == (Object)null)
			{
				return 0f;
			}
			if ((int)statusType == 1)
			{
				Character observedCharacter = Character.observedCharacter;
				if (!((Object)(object)observedCharacter == (Object)null))
				{
					return GetHungerIncreaseTimeRemaining(observedCharacter, val);
				}
				return 0f;
			}
			if ((int)statusType == 9)
			{
				float num = 0f;
				int num2 = 0;
				foreach (ThornOnMe physicalThorn in val.physicalThorns)
				{
					if (physicalThorn.stuckIn)
					{
						num2++;
						num += Time.time - physicalThorn.popOutTime;
					}
				}
				if (num2 == 0)
				{
					return 0f;
				}
				return Mathf.Abs(num) / (float)num2;
			}
			float currentStatus = val.GetCurrentStatus(statusType);
			if (currentStatus <= 0f)
			{
				return 0f;
			}
			float reductionRate = GetReductionRate(val, statusType);
			if (reductionRate <= 0f)
			{
				return 0f;
			}
			float cooldown = GetCooldown(val, statusType);
			float num3 = val.LastAddedStatus(statusType);
			float time = Time.time;
			if (cooldown > 0f && time - num3 < cooldown)
			{
				float num4 = cooldown - (time - num3);
				float num5 = currentStatus / reductionRate;
				return num4 + num5;
			}
			return currentStatus / reductionRate;
		}

		private static float GetHungerIncreaseTimeRemaining(Character character, CharacterAfflictions afflictions)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)character != (Object)(object)Character.localCharacter || !character.data.fullyConscious || afflictions.m_inAirport)
			{
				return 0f;
			}
			float num = afflictions.hungerPerSecond * Ascents.hungerRateMultiplier;
			if (num <= 0f)
			{
				return 0f;
			}
			bool flag = character.data.isInvincible || !afflictions.canGetHungry;
			if (flag)
			{
				ResetRealHungerProgressWhenBlockedStateStarts(afflictions);
			}
			else
			{
				wasHungerBlockedByVanilla[((Object)afflictions).GetInstanceID()] = false;
			}
			bool flag2 = HasRecentlyObservedRealHungerProgress(afflictions);
			if (flag && !flag2)
			{
				ClearFallbackHungerIncrementalStatus(afflictions);
			}
			float hungerIncrementalStatus = GetHungerIncrementalStatus(afflictions);
			float num2 = 0.025f - hungerIncrementalStatus;
			if (num2 <= 0f)
			{
				num2 = 0.025f;
			}
			return num2 / num;
		}

		private static void ResetRealHungerProgressWhenBlockedStateStarts(CharacterAfflictions afflictions)
		{
			int instanceID = ((Object)afflictions).GetInstanceID();
			if (!(wasHungerBlockedByVanilla.TryGetValue(instanceID, out var value) && value))
			{
				wasHungerBlockedByVanilla[instanceID] = true;
				lastRealHungerProgressTimes.Remove(instanceID);
				if (TryReadCurrentIncrementalHunger(afflictions, out var currentIncrementalStatus))
				{
					lastObservedRealHungerIncrementalStatuses[instanceID] = currentIncrementalStatus;
				}
			}
		}

		private static bool HasRecentlyObservedRealHungerProgress(CharacterAfflictions afflictions)
		{
			int instanceID = ((Object)afflictions).GetInstanceID();
			if (TryReadCurrentIncrementalHunger(afflictions, out var currentIncrementalStatus))
			{
				if (lastObservedRealHungerIncrementalStatuses.TryGetValue(instanceID, out var value) && currentIncrementalStatus > value)
				{
					lastRealHungerProgressTimes[instanceID] = Time.time;
				}
				lastObservedRealHungerIncrementalStatuses[instanceID] = currentIncrementalStatus;
			}
			if (lastRealHungerProgressTimes.TryGetValue(instanceID, out var value2))
			{
				return Time.time - value2 <= 1f;
			}
			return false;
		}

		private static float GetHungerIncrementalStatus(CharacterAfflictions afflictions)
		{
			float fallbackHungerIncrementalStatus = GetFallbackHungerIncrementalStatus(afflictions);
			if (TryReadCurrentIncrementalHunger(afflictions, out var currentIncrementalStatus))
			{
				return Mathf.Max(currentIncrementalStatus, fallbackHungerIncrementalStatus);
			}
			return fallbackHungerIncrementalStatus;
		}

		private static bool TryReadCurrentIncrementalHunger(CharacterAfflictions afflictions, out float currentIncrementalStatus)
		{
			currentIncrementalStatus = 0f;
			if (!(currentIncrementalStatusesField?.GetValue(afflictions) is float[] array))
			{
				return false;
			}
			int num = 1;
			if (num < 0 || num >= array.Length)
			{
				return false;
			}
			currentIncrementalStatus = array[num];
			return true;
		}

		private static float GetReductionRate(CharacterAfflictions afflictions, STATUSTYPE statusType)
		{
			//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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected I4, but got Unknown
			if ((int)statusType != 3)
			{
				return (statusType - 6) switch
				{
					2 => afflictions.hotReductionPerSecond, 
					4 => afflictions.sporesReductionPerSecond, 
					0 => afflictions.drowsyReductionPerSecond, 
					_ => 0f, 
				};
			}
			return afflictions.poisonReductionPerSecond;
		}

		private static float GetCooldown(CharacterAfflictions afflictions, STATUSTYPE statusType)
		{
			//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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected I4, but got Unknown
			if ((int)statusType != 3)
			{
				return (statusType - 6) switch
				{
					2 => afflictions.hotReductionCooldown, 
					4 => afflictions.sporesReductionCooldown, 
					0 => afflictions.drowsyReductionCooldown, 
					_ => 0f, 
				};
			}
			return afflictions.poisonReductionCooldown;
		}

		private static string FormatTime(float seconds)
		{
			if (seconds < 60f)
			{
				return Mathf.CeilToInt(seconds).ToString();
			}
			if (seconds < 3600f)
			{
				int num = Mathf.FloorToInt(seconds / 60f);
				int num2 = Mathf.CeilToInt(seconds % 60f);
				return $"{num}:{num2:D2}";
			}
			int num3 = Mathf.FloorToInt(seconds / 3600f);
			int num4 = Mathf.FloorToInt(seconds % 3600f / 60f);
			return $"{num3}:{num4:D2}";
		}
	}
}
namespace PeakStatsEx.MonoBehaviours
{
	internal sealed class CharacterBarAffliction : MonoBehaviour
	{
		internal STATUSTYPE afflictionType;

		internal bool isPetrify;

		private RectTransform rectTransform;

		private CharacterStaminaBar characterStaminaBar;

		internal float size;

		internal float StatusValue { get; private set; }

		internal void FetchReferences()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			rectTransform = (RectTransform)((Component)this).transform;
			((Component)((Component)this).transform.Find("Icon")).gameObject.SetActive(false);
			characterStaminaBar = ((Component)this).GetComponentInParent<CharacterStaminaBar>();
			characterStaminaBar.AddCharacterBarAffliction(this);
		}

		internal void FetchDesiredSize()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			CharacterStaminaBar characterStaminaBar = this.characterStaminaBar;
			Character observedCharacter = characterStaminaBar.ObservedCharacter;
			if (!Object.op_Implicit((Object)(object)observedCharacter))
			{
				return;
			}
			float num = (isPetrify ? ((float)observedCharacter.data.petrifyAmount / 100f) : (characterStaminaBar.DisplayAfflictions.UsesSnapshot ? characterStaminaBar.DisplayAfflictions.GetStatus(afflictionType) : observedCharacter.refs.afflictions.GetCurrentStatus(afflictionType)));
			StatusValue = num * 100f;
			size = this.characterStaminaBar.fullBarRectTransform.sizeDelta.x * num;
			if (num > 0.01f)
			{
				if (size < characterStaminaBar.minAfflictionWidth)
				{
					size = characterStaminaBar.minAfflictionWidth;
				}
				((Component)this).gameObject.SetActive(true);
			}
			else
			{
				((Component)this).gameObject.SetActive(false);
			}
		}

		internal void UpdateVisual(bool snapToTarget = false)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = rectTransform;
			Vector2 sizeDelta = rectTransform.sizeDelta;
			sizeDelta.x = (snapToTarget ? size : Mathf.Lerp(rectTransform.sizeDelta.x, size, Mathf.Min(Time.deltaTime * 10f, 0.1f)));
			val.sizeDelta = sizeDelta;
		}
	}
	internal sealed class CharacterStaminaBar : MonoBehaviour
	{
		private const float SampleScaleLow = 0.6f;

		private const float DefaultTeammateScale = 0.72f;

		private const float SampleScaleHigh = 1f;

		private const float DefaultTeammateVisualYOffset = 10f;

		private const float ExtraBarExpandedSize = 28f;

		private const float TeammateExtraStaminaFillOffsetX = 5f;

		private const float InventorySlotsBaseX = 284f;

		private const float HeaderRowWidth = 600f;

		private const float HeaderVisualGap = -2f;

		private const float SelectedSlotEnvelopeScale = 1.38f;

		private const float LargestInventorySlotSize = 38f;

		private const float HeaderRowHeight = 52.44f;

		internal const float ExtraStaminaBarWidthScale = 0.7f;

		internal const float PetrifyBarHeightScale = 0.5f;

		private static readonly Color defaultBarColor = new Color(0.1035f, 0.2656f, 0.3019f, 1f);

		private static readonly Color outOfStaminaColor = new Color(0.566f, 0.0089f, 0.0089f, 1f);

		private float minStaminaBarWidth = 20f;

		internal float minAfflictionWidth = 60f;

		internal RectTransform fullBarRectTransform;

		internal RectTransform staminaBarRectTransform;

		internal RectTransform maxStaminaBarRectTransform;

		internal RectTransform staminaBarOutlineRectTransform;

		internal RectTransform staminaBarOutlineOverflowBar;

		internal Image barImage;

		internal Image glowImage;

		internal RectTransform extraBar;

		internal RectTransform extraBarStamina;

		internal RectTransform extraBarOutline;

		internal GameObject shieldIcon;

		internal GameObject campfireIcon;

		private float staminaBarOffset;

		internal readonly List<CharacterBarAffliction> characterBarAfflictions = new List<CharacterBarAffliction>();

		private CharacterBarAffliction? petrifyAffliction;

		private Coroutine? animateDisableCoroutine;

		private Character? _observedCharacter;

		private bool hadObservedCharacter;

		private bool resetSnapshotVisuals;

		private bool outOfStamina;

		private bool sequencingExtraBar;

		private bool isEnabled;

		private float sinTime;

		private readonly float TAU = MathF.PI * 2f;

		private float desiredExtraStaminaSize;

		private float extraOutlineMaxWidth;

		private float extraBarDefaultVisualGap;

		private RectTransform headerRowRectTransform;

		private readonly Vector3[] outlineWorldCorners = (Vector3[])(object)new Vector3[4];

		private readonly List<InventorySlotUI> inventorySlotUIs = new List<InventorySlotUI>();

		private readonly List<InventorySlotUI> backpackSlotUIs = new List<InventorySlotUI>();

		private InventorySlotUI? heldItemSlot;

		private bool inventorySlotsCreated;

		private bool inventorySlotsVisible;

		private float appliedTeammateVisualYOffset;

		internal AfflictionDisplayState DisplayAfflictions { get; private set; }

		internal bool HasDisplayAfflictions { get; private set; }

		internal bool NeedsImmediateTextRefresh { get; set; }

		internal Character? ObservedCharacter
		{
			get
			{
				return _observedCharacter;
			}
			set
			{
				if ((Object)(object)value != (Object)null)
				{
					hadObservedCharacter = true;
				}
				_observedCharacter = value;
				if ((Object)(object)value != (Object)null)
				{
					ApplyTeammateVisualOffset();
				}
			}
		}

		internal void AnimateEnable()
		{
			if (!isEnabled && animateDisableCoroutine == null)
			{
				isEnabled = true;
				((Component)this).gameObject.SetActive(true);
				animateDisableCoroutine = ((MonoBehaviour)this).StartCoroutine(EnableIEnumerator());
			}
		}

		internal void AnimateDisable()
		{
			if (isEnabled && animateDisableCoroutine == null)
			{
				isEnabled = false;
				animateDisableCoroutine = ((MonoBehaviour)this).StartCoroutine(DisableIEnumerator());
			}
		}

		private void OnDisable()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (DisplayAfflictions.UsesSnapshot)
			{
				resetSnapshotVisuals = true;
				NeedsImmediateTextRefresh = true;
			}
			ShortcutExtensions.DOKill((Component)(object)((Component)this).transform, false);
			((MonoBehaviour)this).StopAllCoroutines();
			animateDisableCoroutine = null;
			isEnabled = false;
			((Component)this).transform.localScale = Vector3.zero;
			if (((Component)this).gameObject.activeSelf)
			{
				((Component)this).gameObject.SetActive(false);
			}
		}

		internal void InitializeHeader(RectTransform playerNameRectTransform)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			((Transform)playerNameRectTransform).SetParent((Transform)(object)headerRowRectTransform, false);
			playerNameRectTransform.anchorMin = Vector2.zero;
			playerNameRectTransform.anchorMax = Vector2.zero;
			playerNameRectTransform.pivot = Vector2.zero;
			playerNameRectTransform.anchoredPosition = Vector2.zero;
			UpdateHeaderRowPosition();
		}

		private void Awake()
		{
			Plugin.Logger.LogDebug((object)"[UpdateStaminaBar] CharacterStaminaBar Awake");
			StaminaBar val = default(StaminaBar);
			if (((Component)this).TryGetComponent<StaminaBar>(ref val))
			{
				staminaBarOffset = val.staminaBarOffset;
				minStaminaBarWidth = val.minStaminaBarWidth;
				minAfflictionWidth = val.minAfflictionWidth;
				DisableMoraleBoostUi(val);
			}
			CacheStaminaBarReferences();
			CreateHeaderRow();
			if ((Object)(object)val != (Object)null)
			{
				CreateExtraStaminaBar(val);
				if ((Object)(object)val.extraBar != (Object)null)
				{
					((Component)val.extraBar).gameObject.SetActive(false);
				}
			}
		}

		private void Update()
		{
			HasDisplayAfflictions = false;
			if (!Object.op_Implicit((Object)(object)ObservedCharacter) || !((Component)ObservedCharacter).gameObject.activeSelf)
			{
				if (hadObservedCharacter)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				return;
			}
			if (!RemoteAfflictionDisplay.TryRead(ObservedCharacter, out var state))
			{
				resetSnapshotVisuals = true;
				NeedsImmediateTextRefresh = true;
				((Component)this).gameObject.SetActive(false);
				return;
			}
			bool flag = state.UsesSnapshot && (resetSnapshotVisuals || !DisplayAfflictions.UsesSnapshot);
			DisplayAfflictions = state;
			HasDisplayAfflictions = true;
			NeedsImmediateTextRefresh |= flag;
			resetSnapshotVisuals = false;
			ApplyConfiguredScale();
			ApplyTeammateVisualOffset();
			ApplyExtraBarScaleCompensation();
			UpdateStaminaBar(flag);
			UpdateExtraStaminaBar();
			if (PluginConfig.ShowInventorySlots.Value)
			{
				EnsureInventorySlotsCreated();
				inventorySlotsVisible = true;
				UpdateInventorySlots();
			}
			else if (inventorySlotsVisible)
			{
				ClearInventorySlots();
				inventorySlotsVisible = false;
			}
			UpdateHeaderRowPosition();
		}

		private void CreateHeaderRow()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("HeaderRow", new Type[1] { typeof(RectTransform) });
			headerRowRectTransform = val.GetComponent<RectTransform>();
			((Transform)headerRowRectTransform).SetParent(((Component)this).transform, false);
			headerRowRectTransform.anchorMin = new Vector2(0f, 0.5f);
			headerRowRectTransform.anchorMax = new Vector2(0f, 0.5f);
			headerRowRectTransform.pivot = Vector2.zero;
			headerRowRectTransform.sizeDelta = new Vector2(600f, 52.44f);
			headerRowRectTransform.anchoredPosition = Vector2.zero;
		}

		private void UpdateHeaderRowPosition()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00a0: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)headerRowRectTransform == (Object)null) && !((Object)(object)staminaBarOutlineRectTransform == (Object)null) && animateDisableCoroutine == null)
			{
				staminaBarOutlineRectTransform.GetWorldCorners(outlineWorldCorners);
				float num = float.NegativeInfinity;
				for (int i = 0; i < outlineWorldCorners.Length; i++)
				{
					num = Mathf.Max(num, ((Component)this).transform.InverseTransformPoint(outlineWorldCorners[i]).y);
				}
				float num2 = num + -2f / GetConfiguredScale();
				Vector3 localPosition = ((Transform)headerRowRectTransform).localPosition;
				if (!Mathf.Approximately(localPosition.y, num2))
				{
					((Transform)headerRowRectTransform).localPosition = new Vector3(localPosition.x, num2, localPosition.z);
				}
			}
		}

		private void CacheStaminaBarReferences()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			fullBarRectTransform = (RectTransform)((Component)this).transform.Find("FullBar");
			maxStaminaBarRectTransform = (RectTransform)((Component)this).transform.Find("LayoutGroup/MaxStamina");
			staminaBarOutlineRectTransform = (RectTransform)((Component)this).transform.Find("OutlineMask/Outline");
			staminaBarOutlineOverflowBar = (RectTransform)((Component)this).transform.Find("OutlineOverflowLine");
			barImage = ((Component)((Transform)maxStaminaBarRectTransform).Find("Back")).GetComponent<Image>();
			staminaBarRectTransform = (RectTransform)((Component)barImage).transform.Find("Stamina");
			glowImage = ((Component)((Transform)staminaBarRectTransform).Find("Glow")).GetComponent<Image>();
			campfireIcon = ((Component)((Transform)staminaBarOutlineRectTransform).Find("CampfireIcon")).gameObject;
			shieldIcon = ((Component)((Transform)staminaBarOutlineRectTransform).Find("ShieldIcon")).gameObject;
		}

		private static void DisableMoraleBoostUi(StaminaBar original)
		{
			if ((Object)(object)original.moraleBoostAnimator != (Object)null)
			{
				((Behaviour)original.moraleBoostAnimator).enabled = false;
			}
			if ((Object)(object)original.moraleBoostText != (Object)null)
			{
				((Behaviour)original.moraleBoostText).enabled = false;
				((Component)original.moraleBoostText).gameObject.SetActive(false);
			}
		}

		private void CreateExtraStaminaBar(StaminaBar original)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0090: 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_009c: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fullBarRectTransform == (Object)null)
			{
				Plugin.Logger.LogDebug((object)"[CreateExtraStaminaBar] fullBar not found");
				return;
			}
			GameObject val = new GameObject("FriendExtraBar");
			val.transform.SetParent(((Component)this).transform, false);
			extraBar = val.AddComponent<RectTransform>();
			RectTransform obj = extraBar;
			RectTransform obj2 = extraBar;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0.5f);
			obj2.anchorMax = val2;
			obj.anchorMin = val2;
			extraBar.pivot = new Vector2(0f, 0.5f);
			Vector2 anchoredPosition = fullBarRectTransform.anchoredPosition;
			extraBar.anchoredPosition = new Vector2(anchoredPosition.x, anchoredPosition.y - 31f);
			extraBarDefaultVisualGap = (fullBarRectTransform.anchoredPosition.y - extraBar.anchoredPosition.y) * 0.72f;
			extraBar.sizeDelta = Vector2.one * 28f;
			if ((Object)(object)original.extraBarOutline != (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)original.extraBarOutline).gameObject, val.transform, false);
				((Object)val3).name = "FriendExtraBarOutline";
				extraBarOutline = val3.GetComponent<RectTransform>();
				Vector2 anchoredPosition2 = extraBarOutline.anchoredPosition;
				extraBarOutline.anchoredPosition = new Vector2(anchoredPosition2.x - 46f, anchoredPosition2.y - 1f);
				extraOutlineMaxWidth = fullBarRectTransform.sizeDelta.x * 0.7f + 12f;
				extraBarOutline.sizeDelta = new Vector2(extraOutlineMaxWidth, extraBarOutline.sizeDelta.y);
				RemoveAllScriptsExcept<Image, RectTransform>(val3);
				RemoveCopiedStaminaInfo(val3);
			}
			if ((Object)(object)original.extraBarStamina != (Object)null)
			{
				GameObject val4 = Object.Instantiate<GameObject>(((Component)original.extraBarStamina).gameObject, val.transform, false);
				((Object)val4).name = "FriendExtraBarStamina";
				extraBarStamina = val4.GetComponent<RectTransform>();
				((Transform)extraBarStamina).SetParent((Transform)(object)extraBarOutline, false);
				RectTransform obj3 = extraBarStamina;
				RectTransform obj4 = extraBarStamina;
				((Vector2)(ref val2))..ctor(0f, 0.5f);
				obj4.anchorMax = val2;
				obj3.anchorMin = val2;
				extraBarStamina.pivot = new Vector2(0f, 0.5f);
				extraBarStamina.anchoredPosition = Vector2.zero;
				((Transform)extraBarStamina).localRotation = Quaternion.identity;
				((Transform)extraBarStamina).localScale = Vector3.one;
				extraBarStamina.offsetMin = new Vector2(0f, extraBarStamina.offsetMin.y);
				Transform obj5 = val4.transform.Find("Stamina");
				RectTransform val5 = (RectTransform)(object)((obj5 is RectTransform) ? obj5 : null);
				if (val5 != null)
				{
					val5.anchoredPosition = new Vector2(val5.anchoredPosition.x + 5f, val5.anchoredPosition.y);
					val5.sizeDelta = new Vector2(val5.sizeDelta.x, val5.sizeDelta.y * 0.5f);
				}
				RemoveAllScriptsExcept<Image, RectTransform>(val4);
				RemoveCopiedStaminaInfo(val4);
			}
			CreateOrMovePetrifyAffliction();
			val.SetActive(false);
		}

		private void CreateOrMovePetrifyAffliction()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)petrifyAffliction == (Object)null && (Object)(object)GUIManager.instance.bar.petrifyAffliction != (Object)null)
			{
				BarAffliction val = GUIManager.instance.bar.petrifyAffliction;
				GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)extraBarOutline, false);
				((Object)val2).name = "FriendPetrifyAffliction";
				RemoveAllScriptsExcept<Image, RectTransform>(val2);
				petrifyAffliction = val2.AddComponent<CharacterBarAffliction>();
				petrifyAffliction.afflictionType = val.afflictionType;
				petrifyAffliction.isPetrify = true;
				petrifyAffliction.FetchReferences();
			}
			if ((Object)(object)petrifyAffliction != (Object)null)
			{
				RectTransform val3 = (RectTransform)((Component)petrifyAffliction).transform;
				((Transform)val3).SetParent((Transform)(object)extraBarOutline, false);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(1f, 0.5f);
				val3.anchorMax = val4;
				val3.anchorMin = val4;
				val3.pivot = new Vector2(1f, 0.5f);
				val3.anchoredPosition = new Vector2(-8f, 0f);
				((Transform)val3).localRotation = Quaternion.identity;
				((Transform)val3).localScale = new Vector3(0.7f, 0.5f, 1f);
				((Transform)val3).SetAsLastSibling();
			}
		}

		private void UpdateExtraStaminaBar()
		{
			//IL_009c: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			if ((Object)(object)extraBar == (Object)null || (Object)(object)extraBarStamina == (Object)null || (Object)(object)extraBarOutline == (Object)null || (Object)(object)ObservedCharacter == (Object)null)
			{
				return;
			}
			float extraStamina = ObservedCharacter.data.extraStamina;
			bool flag = (Object)(object)petrifyAffliction != (Object)null && (float)ObservedCharacter.data.petrifyAmount > 1f;
			bool flag2 = extraStamina > 0f || flag;
			if (!((Component)extraBar).gameObject.activeSelf && flag2)
			{
				extraBar.sizeDelta = Vector2.zero;
				ShortcutExtensions.DOKill((Component)(object)extraBar, false);
				TweenSettingsExtensions.SetEase<TweenerCore<Vector2, Vector2, VectorOptions>>(DOTweenModuleUI.DOSizeDelta(extraBar, Vector2.one * 28f, 0.25f, false), (Ease)9);
				((Component)extraBar).gameObject.SetActive(true);
			}
			if (((Component)extraBar).gameObject.activeSelf)
			{
				desiredExtraStaminaSize = Mathf.Max(0f, extraStamina * fullBarRectTransform.sizeDelta.x * 0.7f);
				extraBarStamina.sizeDelta = new Vector2(Mathf.Lerp(extraBarStamina.sizeDelta.x, Mathf.Max(4f, desiredExtraStaminaSize), Time.deltaTime * 10f), extraBarStamina.sizeDelta.y);
				((Component)extraBarStamina).gameObject.SetActive(extraBarStamina.sizeDelta.x > 6.1f);
				extraBarOutline.sizeDelta = new Vector2(extraOutlineMaxWidth, extraBarOutline.sizeDelta.y);
				if (!flag2 && !sequencingExtraBar)
				{
					sequencingExtraBar = true;
					TweenSettingsExtensions.OnComplete<Sequence>(TweenSettingsExtensions.Append(DOTween.Sequence(), (Tween)(object)DOTweenModuleUI.DOSizeDelta(extraBar, new Vector2(extraBar.sizeDelta.x, 0f), 0.2f, false)), new TweenCallback(DisableExtraBar));
				}
			}
		}

		private void DisableExtraBar()
		{
			((Component)extraBar).gameObject.SetActive(false);
			sequencingExtraBar = false;
		}

		private static void RemoveAllScriptsExcept<T1, T2>(GameObject gameObject)
		{
			MonoBehaviour[] components = gameObject.GetComponents<MonoBehaviour>();
			MonoBehaviour[] array = components;
			foreach (MonoBehaviour val in array)
			{
				if (((object)val).GetType() != typeof(T1) && ((object)val).GetType() != typeof(T2))
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static void RemoveCopiedStaminaInfo(GameObject gameObject)
		{
			Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>(true);
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if ((Object)(object)val != (Object)(object)gameObject.transform && ((Object)val).name == "StaminaInfo")
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
			}
		}

		internal void AddCharacterBarAffliction(CharacterBarAffliction characterBarAffliction)
		{
			characterBarAfflictions.Add(characterBarAffliction);
			if (characterBarAffliction.isPetrify)
			{
				petrifyAffliction = characterBarAffliction;
			}
		}

		private void CreateInventorySlots()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			float num = 26.22f;
			for (int i = 0; i < 3; i++)
			{
				InventorySlotUI item = CreateInventorySlot($"InvSlot_{i}", new Vector2(32f, 32f), new Vector2(284f + (float)(i * 38), num));
				inventorySlotUIs.Add(item);
			}
			heldItemSlot = CreateInventorySlot("HoldingItemSlot", new Vector2(38f, 38f), new Vector2(398f, num));
			for (int j = 0; j < 4; j++)
			{
				InventorySlotUI item2 = CreateInventorySlot($"BackpackSlot_{j}", new Vector2(32f, 32f), new Vector2(454f + (float)(j * 38), num));
				backpackSlotUIs.Add(item2);
			}
		}

		private void EnsureInventorySlotsCreated()
		{
			if (!inventorySlotsCreated)
			{
				CreateInventorySlots();
				inventorySlotsCreated = true;
			}
		}

		private void UpdateInventorySlots()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Character? observedCharacter = ObservedCharacter;
			if (((observedCharacter == null) ? null : observedCharacter.player?.itemSlots) == null)
			{
				ClearInventorySlots();
				return;
			}
			ItemSlot[] itemSlots = ObservedCharacter.player.itemSlots;
			Optionable<byte> currentSelectedSlot = ObservedCharacter.refs.items.currentSelectedSlot;
			for (int i = 0; i < inventorySlotUIs.Count && i < itemSlots.Length; i++)
			{
				bool selected = currentSelectedSlot.IsSome && currentSelectedSlot.Value == i;
				inventorySlotUIs[i].SetItem(itemSlots[i], selected);
			}
			Item currentItem = ObservedCharacter.data.currentItem;
			if ((Object)(object)heldItemSlot != (Object)null)
			{
				bool selected2 = (Object)(object)currentItem != (Object)null && currentItem.UIData != null;
				heldItemSlot.SetItem(currentItem, currentItem?.data, selected2);
			}
			BackpackSlot backpackSlot = ObservedCharacter.player.backpackSlot;
			BackpackData val = default(BackpackData);
			if (!((ItemSlot)backpackSlot).IsEmpty() && ((ItemSlot)backpackSlot).data != null && ((ItemSlot)backpackSlot).data.TryGetDataEntry<BackpackData>((DataEntryKey)7, ref val))
			{
				ItemSlot[] array = val?.itemSlots;
				if (array != null)
				{
					for (int j = 0; j < backpackSlotUIs.Count && j < array.Length; j++)
					{
						backpackSlotUIs[j].SetItem(array[j], selected: false);
					}
					return;
				}
			}
			foreach (InventorySlotUI backpackSlotUI in backpackSlotUIs)
			{
				backpackSlotUI.Clear();
			}
		}

		private void ClearInventorySlots()
		{
			foreach (InventorySlotUI inventorySlotUI in inventorySlotUIs)
			{
				inventorySlotUI.Clear();
			}
			heldItemSlot?.Clear();
			foreach (InventorySlotUI backpackSlotUI in backpackSlotUIs)
			{
				backpackSlotUI.Clear();
			}
		}

		private void ApplyTeammateVisualOffset()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			float teammateVisualYOffset = GetTeammateVisualYOffset();
			float num = teammateVisualYOffset - appliedTeammateVisualYOffset;
			if (Mathf.Abs(num) < 0.001f)
			{
				return;
			}
			appliedTeammateVisualYOffset = teammateVisualYOffset;
			for (int i = 0; i < ((Component)this).transform.childCount; i++)
			{
				Transform child = ((Component)this).transform.GetChild(i);
				RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
				if (val != null && !((Object)(object)val == (Object)(object)headerRowRectTransform))
				{
					val.anchoredPosition += new Vector2(0f, num);
				}
			}
			UpdateHeaderRowPosition();
		}

		private static float GetTeammateVisualYOffset()
		{
			return 10f + InterpolateScaleSetting(10f, -1f, -21f);
		}

		private void ApplyConfiguredScale()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			if (isEnabled && animateDisableCoroutine == null)
			{
				float configuredScale = GetConfiguredScale();
				if (!(Mathf.Abs(((Component)this).transform.localScale.x - configuredScale) < 0.001f))
				{
					ShortcutExtensions.DOKill((Component)(object)((Component)this).transform, false);
					((Component)this).transform.localScale = Vector3.one * configuredScale;
				}
			}
		}

		private void ApplyExtraBarScaleCompensation()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL