Decompiled source of PeakOverheadStats v1.0.2
plugins\PeakOverheadStats.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; 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 Peak; using PeakOverheadStats.Compatibility; using PeakOverheadStats.MonoBehaviours; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("DOTween")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PeakOverheadStats")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PeakOverheadStats")] [assembly: AssemblyTitle("PeakOverheadStats")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } 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 PeakOverheadStats { internal static class GameRef { private static readonly FieldInfo _runManager_timeSinceRunStarted = typeof(RunManager).GetField("timeSinceRunStarted", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _staminaBar_desiredStaminaSize = typeof(StaminaBar).GetField("desiredStaminaSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _staminaBar_desiredExtraStaminaSize = typeof(StaminaBar).GetField("desiredExtraStaminaSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _orbFogHandler_sphere = typeof(OrbFogHandler).GetField("sphere", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _characterStats_character = typeof(CharacterStats).GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _lavaRising_startHeight = typeof(LavaRising).GetField("startHeight", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo _characterData_isInvincible = typeof(CharacterData).GetField("isInvincible", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo _thornOnMe_popOutTime; private static FieldInfo _characterAfflictions_m_inAirport; private static FieldInfo _fogSphere_fogPoint; public static float GetTimeSinceRunStarted(RunManager rm) { if (!(_runManager_timeSinceRunStarted != null)) { return Time.time; } return (float)_runManager_timeSinceRunStarted.GetValue(rm); } public static float GetDesiredStaminaSize(StaminaBar bar) { if (!(_staminaBar_desiredStaminaSize != null)) { return 0f; } return (float)_staminaBar_desiredStaminaSize.GetValue(bar); } public static float GetDesiredExtraStaminaSize(StaminaBar bar) { if (!(_staminaBar_desiredExtraStaminaSize != null)) { return 0f; } return (float)_staminaBar_desiredExtraStaminaSize.GetValue(bar); } public static object GetFogSphere(OrbFogHandler handler) { return _orbFogHandler_sphere?.GetValue(handler); } public static Character GetCharacter(CharacterStats stats) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (!(_characterStats_character != null)) { return null; } return (Character)_characterStats_character.GetValue(stats); } public static float GetStartHeight(LavaRising lava) { if (!(_lavaRising_startHeight != null)) { return 0f; } return (float)_lavaRising_startHeight.GetValue(lava); } public static bool GetIsInvincible(CharacterData data) { if (_characterData_isInvincible != null) { return (bool)_characterData_isInvincible.GetValue(data); } return false; } public static float GetPopOutTime(object thorn) { if (_thornOnMe_popOutTime == null && thorn != null) { _thornOnMe_popOutTime = thorn.GetType().GetField("popOutTime", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (!(_thornOnMe_popOutTime != null)) { return 0f; } return (float)_thornOnMe_popOutTime.GetValue(thorn); } public static bool GetInAirport(object afflictions) { if (_characterAfflictions_m_inAirport == null && afflictions != null) { _characterAfflictions_m_inAirport = afflictions.GetType().GetField("m_inAirport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_characterAfflictions_m_inAirport != null) { return (bool)_characterAfflictions_m_inAirport.GetValue(afflictions); } return false; } public static Vector3 GetFogPoint(object sphere) { //IL_0045: 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) if (_fogSphere_fogPoint == null && sphere != null) { _fogSphere_fogPoint = sphere.GetType().GetField("fogPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (!(_fogSphere_fogPoint != null)) { return Vector3.zero; } return (Vector3)_fogSphere_fogPoint.GetValue(sphere); } } [BepInPlugin("com.yls.peakoverheadstats", "PeakOverheadStats", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger { get; private set; } private void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)$"Plugin {((BaseUnityPlugin)this).Info.Metadata.Name} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded!"); PluginConfig.Initialize(((BaseUnityPlugin)this).Config, Logger); new Harmony("com.yls.peakoverheadstats").PatchAll(); } } [HarmonyWrapSafe] internal sealed class Patches { [HarmonyPatch(typeof(GUIManager), "Start")] [HarmonyPostfix] private static void GUIManagerStartHook(GUIManager __instance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Airport") { CreateTimerAndHeightStats(); CreateMapStats(); } void CreateMapStats() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0058: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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) //IL_00cc: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_014b: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)((Component)__instance).GetComponentInChildren<AscentUI>()).transform; RectTransform obj = Object.Instantiate<RectTransform>(val, ((Transform)val).parent); ((Object)obj).name = "Map & Level UI"; Object.Destroy((Object)(object)((Component)obj).GetComponent<AscentUI>()); MapStats mapStats = ((Component)obj).gameObject.AddComponent<MapStats>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 1f); obj.anchorMin = val2; Vector2 pivot = (obj.anchorMax = val2); obj.pivot = pivot; obj.anchoredPosition = new Vector2(-4f, 5f); RectTransform val4 = Object.Instantiate<RectTransform>(val, ((Transform)val).parent); ((Object)val4).name = "Biome Route UI"; Object.Destroy((Object)(object)((Component)val4).GetComponent<AscentUI>()); ((Vector2)(ref val2))..ctor(1f, 1f); val4.anchorMin = val2; pivot = (val4.anchorMax = val2); val4.pivot = pivot; float y = val.anchoredPosition.y; Rect rect = val.rect; val4.anchoredPosition = new Vector2(0f, y - ((Rect)(ref rect)).height + 8f); TMP_Text component = ((Component)val4).GetComponent<TMP_Text>(); RectTransform obj2 = Object.Instantiate<RectTransform>(val, ((Transform)val).parent); ((Object)obj2).name = "Biome Variant UI"; Object.Destroy((Object)(object)((Component)obj2).GetComponent<AscentUI>()); ((Vector2)(ref val2))..ctor(1f, 1f); obj2.anchorMin = val2; pivot = (obj2.anchorMax = val2); obj2.pivot = pivot; float y2 = val4.anchoredPosition.y; rect = val.rect; obj2.anchoredPosition = new Vector2(0f, y2 - ((Rect)(ref rect)).height + 22f); TMP_Text component2 = ((Component)obj2).GetComponent<TMP_Text>(); RectTransform component3 = ((Component)__instance.hudCanvas).GetComponent<RectTransform>(); mapStats.InitializeRouteText(component, component2, component3); } void CreateTimerAndHeightStats() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0042: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_005e: 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_006a: 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>(); 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(UIPlayerNames), "UpdateName")] [HarmonyPostfix] private static void UIPlayerNamesUpdateNameHook(UIPlayerNames __instance, int index, bool visible) { if (__instance.playerNameText == null || index < 0 || index >= __instance.playerNameText.Length) { return; } PlayerName val = __instance.playerNameText[index]; if (!((Object)(object)val == (Object)null)) { OverheadNameplate overheadNameplate = ((Component)val).GetComponent<OverheadNameplate>(); if ((Object)(object)overheadNameplate == (Object)null) { overheadNameplate = ((Component)val).gameObject.AddComponent<OverheadNameplate>(); } overheadNameplate.Refresh(val, visible); } } [HarmonyPatch(typeof(UIPlayerNames), "DisableName")] [HarmonyPrefix] private static void UIPlayerNamesDisableNameHook(UIPlayerNames __instance, int index) { if (__instance.playerNameText != null && index >= 0 && index < __instance.playerNameText.Length) { PlayerName val = __instance.playerNameText[index]; OverheadNameplate overheadNameplate = default(OverheadNameplate); if ((Object)(object)val != (Object)null && ((Component)val).TryGetComponent<OverheadNameplate>(ref overheadNameplate)) { overheadNameplate.Hide(); } } } [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); return Encoding.UTF8.GetString(array, 0, byteLength).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."); } } [HarmonyWrapSafe] internal sealed class StaminaInfoPatch { 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>(); internal static Dictionary<string, float> lastAfflictionUpdateTime = 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 bool wasHiddenHungerCountdownShown; 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>(); lastAfflictionUpdateTime = new Dictionary<string, float>(); InitStaminaInfo(__instance); } if (!PluginConfig.ShowStaminaInfo.Value) { HideBarTexts(__instance); return; } 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 { 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 && Time.time - LastUpdateTime[instanceID] > 1f) { UpdateCharacterBarTexts(__instance); 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) && __instance.GetCurrentStatus((STATUSTYPE)1) < __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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) bool forceUpdate; string staminaHungerCountdownSuffix = GetStaminaHungerCountdownSuffix(staminaBar, out forceUpdate); bool flag = GameRef.GetDesiredStaminaSize(staminaBar) >= 15f; UpdateMaxStaminaHungerCountdown(staminaBar, flag ? string.Empty : staminaHungerCountdownSuffix, forceUpdate); UpdateBarText(((Object)staminaBar.staminaBar).name, GameRef.GetDesiredStaminaSize(staminaBar), PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData, "", flag ? staminaHungerCountdownSuffix : string.Empty, forceUpdate); if (forceUpdate) { lastAfflictionUpdateTime["HiddenHungerCountdown"] = Time.time; } UpdateBarText("ExtraStamina", GameRef.GetDesiredExtraStaminaSize(staminaBar), PluginConfig.StaminaInfoRoundStaminaBars.Value, trimWholeDecimal: false, lastKnownData); BarAffliction[] afflictions = staminaBar.afflictions; foreach (BarAffliction val in afflictions) { string name = ((Object)val).name; bool num = CanShowCountdown(val.afflictionType); bool flag2 = num && val.size > 0f && (!lastAfflictionUpdateTime.ContainsKey(name) || Time.time - lastAfflictionUpdateTime[name] > 0.5f); string suffix = string.Empty; if (num && IsCountdownEnabled(val.afflictionType)) { float reductionTimeRemaining = GetReductionTimeRemaining(val.afflictionType); if (reductionTimeRemaining > 0f && !ShouldMoveHungerCountdownToStamina(val, reductionTimeRemaining)) { suffix = "(" + FormatTime(reductionTimeRemaining) + ")"; } } UpdateBarText(name, val.size, PluginConfig.StaminaInfoRoundAfflictionBars.Value, trimWholeDecimal: true, lastKnownAffData, "", suffix, flag2); if (flag2) { lastAfflictionUpdateTime[name] = Time.time; } } } private static void UpdateMaxStaminaHungerCountdown(StaminaBar staminaBar, string suffix, bool forceUpdate) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!barTexts.TryGetValue("HiddenHungerCountdown", out TextMeshProUGUI value)) { return; } if (string.IsNullOrEmpty(suffix)) { ((Component)value).gameObject.SetActive(false); return; } Transform obj = ((Component)staminaBar).transform.Find("LayoutGroup/MaxStamina"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (val == null) { ((Component)value).gameObject.SetActive(false); } else if (((TMP_Text)value).GetPreferredValues(suffix).x > val.sizeDelta.x) { ((Component)value).gameObject.SetActive(false); } else if (forceUpdate || !((Component)value).gameObject.activeSelf) { ((TMP_Text)value).text = suffix; ((Component)value).gameObject.SetActive(true); } } private static string GetStaminaHungerCountdownSuffix(StaminaBar staminaBar, out bool forceUpdate) { forceUpdate = false; Character observedCharacter = Character.observedCharacter; CharacterAfflictions val = observedCharacter?.refs?.afflictions; float num = 0f; bool num2 = PluginConfig.StaminaInfoShowHungerCountdown.Value && (Object)(object)observedCharacter != (Object)null && (Object)(object)val != (Object)null; bool flag = false; if (num2) { num = GetHungerIncreaseTimeRemaining(observedCharacter, val); BarAffliction hungerBar = GetHungerBar(staminaBar); flag = num > 0f && ((Object)(object)hungerBar == (Object)null || !IsVisibleAfflictionBar(hungerBar) || ShouldMoveHungerCountdownToStamina(hungerBar, num)); } string text = string.Empty; if (flag) { text = "<color=#FFFF00>(" + FormatTime(num) + ")</color>"; } bool flag2 = !string.IsNullOrEmpty(text); forceUpdate = wasHiddenHungerCountdownShown != flag2 || (flag2 && (!lastAfflictionUpdateTime.ContainsKey("HiddenHungerCountdown") || Time.time - lastAfflictionUpdateTime["HiddenHungerCountdown"] > 0.5f)); wasHiddenHungerCountdownShown = flag2; return text; } 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, float timeRemaining) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((int)affliction.afflictionType != 1 || !IsVisibleAfflictionBar(affliction)) { return false; } if (!barTexts.TryGetValue(((Object)affliction).name, out TextMeshProUGUI value)) { return false; } string text = FormatBarValue(affliction.size, PluginConfig.StaminaInfoRoundAfflictionBars.Value, trimWholeDecimal: true); string text2 = "(" + FormatTime(timeRemaining) + ")"; return ((TMP_Text)value).GetPreferredValues(text + text2).x > affliction.size; } public static void UpdateCharacterBarTexts(CharacterStaminaBar characterStaminaBar) { //IL_0031: 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) 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); } } private static void UpdateBarText(string key, float size, bool roundLargeValue, bool trimWholeDecimal, Dictionary<string, float> cache, string prefix = "", string suffix = "", bool forceUpdate = false) { if (!barTexts.TryGetValue(key, out TextMeshProUGUI value)) { return; } bool flag = forceUpdate || !cache.ContainsKey(key) || !Mathf.Approximately(cache[key], size) || !((Component)value).gameObject.activeSelf; if (size < 15f) { ((Component)value).gameObject.SetActive(false); cache[key] = size; return; } string text = prefix + FormatBarValue(size, roundLargeValue, trimWholeDecimal); string text2 = (string.IsNullOrEmpty(suffix) ? text : (text + suffix)); if (flag || ((TMP_Text)value).text != text2) { ((TMP_Text)value).text = text2; ((Component)value).gameObject.SetActive(true); cache[key] = size; } } 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; for (int i = 0; i < afflictions.Length; i++) { HideText(((Object)afflictions[i]).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)) { ((Component)value).gameObject.SetActive(false); } } private static bool CanShowCountdown(STATUSTYPE afflictionType) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)afflictionType != 7 && (int)afflictionType != 0) { return (int)afflictionType != 5; } 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) { guiManager = GameObject.Find("GAME/GUIManager").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 val in afflictions) { AddTextObject(((Component)val).gameObject, ((Object)((Component)val).gameObject).name); } } 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_0007: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) 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_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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_007f: 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_009a: 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_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) 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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; lastAfflictionUpdateTime[barName] = -1f; 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_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 - GameRef.GetPopOutTime(physicalThorn); } } 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 || GameRef.GetInAirport(afflictions)) { return 0f; } float num = afflictions.hungerPerSecond * Ascents.hungerRateMultiplier; if (num <= 0f) { return 0f; } int num2; if (!GameRef.GetIsInvincible(character.data)) { num2 = ((!afflictions.canGetHungry) ? 1 : 0); if (num2 == 0) { wasHungerBlockedByVanilla[((Object)afflictions).GetInstanceID()] = false; goto IL_0081; } } else { num2 = 1; } ResetRealHungerProgressWhenBlockedStateStarts(afflictions); goto IL_0081; IL_0081: bool flag = HasRecentlyObservedRealHungerProgress(afflictions); if (num2 != 0 && !flag) { ClearFallbackHungerIncrementalStatus(afflictions); } float hungerIncrementalStatus = GetHungerIncrementalStatus(afflictions); float num3 = 0.025f - hungerIncrementalStatus; if (num3 <= 0f) { num3 = 0.025f; } return num3 / 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 PeakOverheadStats.Compatibility { internal sealed class PllRouteProjection { public string?[] SegmentTitles { get; } = Array.Empty<string>(); } internal static class PLLCompatibility { public static bool Enabled => false; public static bool MapActive => false; public static bool TryGetMapSeed(out int seed) { seed = 0; return false; } public static bool TryCreateRouteProjection(MapSegment[] segments, ProgressPoint[] progressPoints, out PllRouteProjection projection) { projection = new PllRouteProjection(); return false; } } internal static class TerrainCustomiserCompatibility { public static bool Enabled => false; public static bool TryGetMapSeed(out int seed) { seed = 0; return false; } } internal static class TerrainRandomiserCompatibility { public static bool Enabled => false; public static bool TryGetMapSeed(out int seed) { seed = 0; return false; } } internal enum TfaRouteStatus { NotApplicable, Pending, Ready, Unsupported } internal sealed class TfaRouteStage { internal object Source { get; } internal int SegmentIndex { get; } internal int ChainIndex { get; } internal BiomeType BiomeType { get; } internal string TitleKey { get; } internal Transform Terrain { get; } internal TfaRouteStage(object source, int segmentIndex, int chainIndex, BiomeType biomeType, string titleKey, Transform terrain) { //IL_001c: 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) Source = source; SegmentIndex = segmentIndex; ChainIndex = chainIndex; BiomeType = biomeType; TitleKey = titleKey; Terrain = terrain; } } internal sealed class TfaRouteProjection { internal IReadOnlyList<TfaRouteStage> Stages { get; } internal TfaRouteProjection(List<TfaRouteStage> stages) { Stages = stages; } } internal sealed class TrueFinalAscentCompatibility { private sealed class StageContract { private const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal string? FailureReason { get; private set; } internal Type? StageType { get; } internal PropertyInfo? Active { get; } internal PropertyInfo? Seed { get; } internal PropertyInfo? Done { get; } internal PropertyInfo? Ready { get; } internal PropertyInfo? Building { get; } internal PropertyInfo? Aborted { get; } internal PropertyInfo? CurrentStage { get; } internal MethodInfo? AllStages { get; } internal FieldInfo? SegmentIndex { get; } internal FieldInfo? ChainIndex { get; } internal FieldInfo? BiomeType { get; } internal FieldInfo? Title { get; } internal FieldInfo? Terrain { get; } internal StageContract(Assembly assembly) { Type type = FindType(assembly, "FinalAscent"); Active = GetProperty(type, "Active", typeof(bool)); Seed = GetProperty(type, "Seed", typeof(int)); Type type2 = FindType(assembly, "FinalAscentBuilder"); Done = GetProperty(type2, "Done", typeof(bool)); Ready = GetProperty(type2, "Ready", typeof(bool)); Building = GetProperty(type2, "Building", typeof(bool)); Aborted = GetProperty(type2, "Aborted", typeof(bool)); StageType = FindType(assembly, "FinalAscentStage"); Type type3 = FindType(assembly, "FinalAscentSegments"); CurrentStage = GetProperty(type3, "CurrentStage", StageType); AllStages = type3?.GetMethod("AllStages", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if ((AllStages == null || StageType == null || !typeof(IEnumerable<>).MakeGenericType(StageType).IsAssignableFrom(AllStages.ReturnType)) && FailureReason == null) { string text = (FailureReason = "FinalAscentSegments.AllStages has an unsupported signature."); } SegmentIndex = GetField("SegmentIndex", typeof(int)); ChainIndex = GetField("ChainIndex", typeof(int)); BiomeType = GetField("Type", typeof(BiomeType)); Title = GetField("Title", typeof(string)); Terrain = GetField("Terrain", typeof(GameObject)); } private Type? FindType(Assembly assembly, string name) { Type? type = assembly.GetType("TrueFinalAscent." + name); if (type == null && FailureReason == null) { string text = (FailureReason = "TrueFinalAscent." + name + " is missing."); } return type; } private PropertyInfo? GetProperty(Type? type, string name, Type? expectedType) { PropertyInfo propertyInfo = type?.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (!(propertyInfo == null) && !(propertyInfo.PropertyType != expectedType)) { MethodInfo? getMethod = propertyInfo.GetGetMethod(nonPublic: true); if ((object)getMethod != null && getMethod.IsStatic && propertyInfo.GetIndexParameters().Length == 0) { return propertyInfo; } } if (FailureReason == null) { string text = (FailureReason = type?.Name + "." + name + " has an unsupported signature."); } return null; } private FieldInfo? GetField(string name, Type expectedType) { FieldInfo fieldInfo = StageType?.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo == null || fieldInfo.FieldType != expectedType) { if (FailureReason == null) { string text = (FailureReason = "FinalAscentStage." + name + " has an unsupported type."); } return null; } return fieldInfo; } } private const string PluginGuid = "com.CptPICHU.peak.truefinalascent"; private static readonly Dictionary<Assembly, StageContract> Contracts = new Dictionary<Assembly, StageContract>(); private static readonly HashSet<Assembly> WarnedAssemblies = new HashSet<Assembly>(); private Assembly? cachedAssembly; private Assembly? cachedSeedAssembly; private MapHandler? cachedMapHandler; private MapSegment[]? cachedSegments; private TfaRouteProjection? cachedProjection; private StageContract? currentContract; private MapHandler? contextMapHandler; private Scene contextScene; private string? failureReason; private bool seedReady; internal TfaRouteStatus ReadSeedStatus(Scene scene, MapHandler? mapHandler, bool atTerminal, out bool assemblyChanged) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) TfaRouteProjection projection; int currentIndex; TfaRouteStatus result = ReadRoute(scene, mapHandler, atTerminal, out projection, out currentIndex); assemblyChanged = (object)cachedSeedAssembly != cachedAssembly; cachedSeedAssembly = cachedAssembly; return result; } internal bool TryGetMapSeed(out int seed) { seed = 0; if (!seedReady || currentContract?.Seed == null) { return false; } seed = (int)currentContract.Seed.GetValue(null); return true; } internal TfaRouteStatus ReadRoute(Scene scene, MapHandler? mapHandler, bool atTerminal, out TfaRouteProjection? projection, out int currentIndex) { //IL_0094: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_0237: 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) projection = null; currentIndex = -1; seedReady = false; if (!Chainloader.PluginInfos.TryGetValue("com.CptPICHU.peak.truefinalascent", out var value)) { ClearProjection(); cachedAssembly = null; currentContract = null; failureReason = null; return TfaRouteStatus.NotApplicable; } if ((Object)(object)value.Instance == (Object)null) { ClearProjection(); return TfaRouteStatus.Pending; } Assembly assembly = ((object)value.Instance).GetType().Assembly; if ((object)cachedAssembly != assembly || contextScene != scene || contextMapHandler != mapHandler) { ClearProjection(); cachedAssembly = assembly; contextScene = scene; contextMapHandler = mapHandler; failureReason = null; } if (!Contracts.TryGetValue(assembly, out StageContract value2)) { value2 = new StageContract(assembly); Contracts.Add(assembly, value2); } currentContract = value2; if (value2.Active != null && !(bool)value2.Active.GetValue(null)) { ClearProjection(); return TfaRouteStatus.NotApplicable; } if (value2.FailureReason != null || failureReason != null) { return Unsupported(value, assembly, value2.FailureReason ?? failureReason); } if (!(bool)value2.Done.GetValue(null) || !(bool)value2.Ready.GetValue(null) || (bool)value2.Building.GetValue(null) || (bool)value2.Aborted.GetValue(null) || (Object)(object)mapHandler == (Object)null || !MapHandler.ExistsAndInitialized || ((Component)mapHandler).gameObject.scene != scene || mapHandler.segments == null) { ClearProjection(); return TfaRouteStatus.Pending; } MapSegment[] segments = mapHandler.segments; if ((Object)(object)cachedMapHandler != (Object)(object)mapHandler || cachedSegments != segments) { ClearProjection(); cachedMapHandler = mapHandler; cachedSegments = segments; } object value3 = value2.CurrentStage.GetValue(null); currentIndex = FindCurrentStage(value2, value3); int num; if (currentIndex >= 0) { if (Object.op_Implicit((Object)(object)cachedProjection.Stages[currentIndex].Terrain)) { object? value4 = value2.Terrain.GetValue(value3); GameObject val = (GameObject)((value4 is GameObject) ? value4 : null); if (val != null && !((Object)(object)val == (Object)null) && !(val.scene != scene)) { num = (((Object)(object)cachedProjection.Stages[currentIndex].Terrain != (Object)(object)val.transform) ? 1 : 0); goto IL_026e; } } num = 1; } else { num = 0; } goto IL_026e; IL_026e: bool flag = (byte)num != 0; if (cachedProjection == null || flag || (currentIndex < 0 && !atTerminal)) { string reason; TfaRouteStatus tfaRouteStatus = Capture(scene, segments, value2, out reason); switch (tfaRouteStatus) { case TfaRouteStatus.Unsupported: return Unsupported(value, assembly, reason); case TfaRouteStatus.Pending: ClearProjection(); return tfaRouteStatus; } currentIndex = FindCurrentStage(value2, value3); } if (currentIndex < 0 && !atTerminal) { return Unsupported(value, assembly, "CurrentStage does not match the completed stage chain."); } projection = cachedProjection; seedReady = true; return TfaRouteStatus.Ready; } private int FindCurrentStage(StageContract contract, object? currentStage) { if (cachedProjection == null || currentStage == null || !contract.StageType.IsInstanceOfType(currentStage)) { return -1; } int num = (int)contract.SegmentIndex.GetValue(currentStage); int num2 = (int)contract.ChainIndex.GetValue(currentStage); for (int i = 0; i < cachedProjection.Stages.Count; i++) { TfaRouteStage tfaRouteStage = cachedProjection.Stages[i]; if (tfaRouteStage.Source == currentStage && tfaRouteStage.SegmentIndex == num && tfaRouteStage.ChainIndex == num2) { return i; } } return -1; } private TfaRouteStatus Capture(Scene scene, MapSegment[] segments, StageContract contract, out string reason) { //IL_00a8: 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) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_015c: 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_01b8: 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) //IL_019a: Invalid comparison between Unknown and I4 reason = ""; if (!(contract.AllStages.Invoke(null, null) is IEnumerable enumerable)) { reason = "AllStages returned no stage sequence."; return TfaRouteStatus.Unsupported; } List<TfaRouteStage> list = new List<TfaRouteStage>(); HashSet<(int, int)> hashSet = new HashSet<(int, int)>(); VoidBiome instance = VoidBiome.instance; foreach (object item in enumerable) { if (item == null || !contract.StageType.IsInstanceOfType(item)) { reason = "AllStages contains an invalid stage object."; return TfaRouteStatus.Unsupported; } int num = (int)contract.SegmentIndex.GetValue(item); int num2 = (int)contract.ChainIndex.GetValue(item); BiomeType val = (BiomeType)contract.BiomeType.GetValue(item); if (num < 0 || num >= segments.Length || num2 < 0 || !hashSet.Add((num, num2))) { reason = $"AllStages has an invalid or repeated identity ({num}, {num2})."; return TfaRouteStatus.Unsupported; } if ((int)val != 17 && (!((Object)(object)instance != (Object)null) || segments[num] != instance.segment)) { object? value = contract.Terrain.GetValue(item); GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (val2 == null || (Object)(object)val2 == (Object)null) { reason = $"Stage ({num}, {num2}) has no terrain."; return TfaRouteStatus.Unsupported; } if (val2.scene != scene) { return TfaRouteStatus.Pending; } string text = (contract.Title.GetValue(item) as string) ?? ""; if (num == 3 && num2 == 0 && (int)val == 3 && text == "THE KILN") { text = "CALDERA"; } list.Add(new TfaRouteStage(item, num, num2, val, text, val2.transform)); } } if (list.Count == 0) { reason = "The completed stage chain contains no visible route stages."; return TfaRouteStatus.Unsupported; } cachedProjection = new TfaRouteProjection(list); return TfaRouteStatus.Ready; } private TfaRouteStatus Unsupported(PluginInfo plugin, Assembly assembly, string reason) { ClearProjection(); failureReason = reason; seedReady = false; if (WarnedAssemblies.Add(assembly)) { Plugin.Logger.LogWarning((object)($"True Final Ascent {plugin.Metadata.Version} compatibility failed: {reason} " + "Using the original biome collection instead. Map seed display is disabled.")); } return TfaRouteStatus.Unsupported; } internal void ResetRoute() { ClearProjection(); seedReady = false; } private void ClearProjection() { cachedMapHandler = null; cachedSegments = null; cachedProjection = null; } } } namespace PeakOverheadStats.MonoBehaviours { internal sealed class CharacterBarAffliction : MonoBehaviour { internal STATUSTYPE afflictionType; internal bool isPetrify; private RectTransform rectTransform; private CharacterStaminaBar characterStaminaBar; private Image? barImage; internal float size; internal void FetchReferences() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) rectTransform = (RectTransform)((Component)this).transform; barImage = ((Component)this).GetComponent<Image>(); Transform val = ((Component)this).transform.Find("Icon"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } characterStaminaBar = ((Component)this).GetComponentInParent<CharacterStaminaBar>(); characterStaminaBar.AddCharacterBarAffliction(this); if ((int)afflictionType == 7 && (Object)(object)barImage != (Object)null) { ((Graphic)barImage).color = new Color(1f, 0.55f, 0f, 1f); } } internal void FetchDesiredSize() { //IL_002b: 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) CharacterStaminaBar characterStaminaBar = this.characterStaminaBar; Character observedCharacter = characterStaminaBar.ObservedCharacter; if (!Object.op_Implicit((Object)(object)observedCharacter)) { return; } float num = (isPetrify ? ((float)observedCharacter.data.petrifyAmount / 100f) : observedCharacter.refs.afflictions.GetCurrentStatus(afflictionType)); 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() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0049: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = rectTransform; Vector2 sizeDelta = rectTransform.sizeDelta; sizeDelta.x = Mathf.Lerp(rectTransform.sizeDelta.x, size, Mathf.Min(Time.deltaTime * 10f, 0.1f)); obj.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.12f, 0.12f, 0.15f, 0.7f); 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 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 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_0027: Unknown result type (might be due to invalid IL or missing references) 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) ((Transform)playerNameRectTransform).SetParent((Transform)(object)headerRowRectTransform, false); playerNameRectTransform.anchorMin = new Vector2(0.5f, 0f); playerNameRectTransform.anchorMax = new Vector2(0.5f, 0f); playerNameRectTransform.pivot = new Vector2(0.5f, 0f); 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() { if (!Object.op_Implicit((Object)(object)ObservedCharacter) || !((Component)ObservedCharacter).gameObject.activeSelf) { if (hadObservedCharacter) { Object.Destroy((Object)(object)((Component)this).gameObject); } return; } ApplyConfiguredScale(); ApplyTeammateVisualOffset(); ApplyExtraBarScaleCompensation(); UpdateStaminaBar(); 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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(0.5f, 0.5f); headerRowRectTransform.anchorMax = new Vector2(0.5f, 0.5f); headerRowRectTransform.pivot = new Vector2(0.5f, 0f); headerRowRectTransform.sizeDelta = new Vector2(600f, 52.44f); headerRowRectTransform.anchoredPosition = Vector2.zero; } private void UpdateHeaderRowPosition() { //IL_0035: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) { headerRowRectTransform.pivot = new Vector2(0f, 0f); staminaBarOutlineRectTransform.GetWorldCorners(outlineWorldCorners); float num = float.NegativeInfinity; float num2 = float.PositiveInfinity; for (int i = 0; i < outlineWorldCorners.Length; i++) { Vector3 val = ((Component)this).transform.InverseTransformPoint(outlineWorldCorners[i]); num = Mathf.Max(num, val.y); num2 = Mathf.Min(num2, val.x); } float num3 = num + -2f / GetConfiguredScale(); Vector3 localPosition = ((Transform)headerRowRectTransform).localPosition; ((Transform)headerRowRectTransform).localPosition = new Vector3(num2, num3, 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_008d: 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) //IL_00b7: 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>(); ((Graphic)barImage).color = defaultBarColor; 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_01e5: Unknown result type (might be due to invalid IL or missing references) 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); extraBar.sizeDelta = Vector2.one * 28f; ((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; extraBar.sizeDelta = new Vector2(extraBar.sizeDelta.x, 0f); DisableExtraBar(); } } } private void DisableExtraBar() { ((Component)extraBar).gameObject.SetActive(false); sequencingExtraBar = false; } private static void RemoveAllScriptsExcept<T1, T2>(GameObject gameObject) { MonoBehaviour[] components = gameObject.GetComponents<MonoBehaviour>(); foreach (MonoBehaviour val in components) { 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); foreach (Transform val in componentsInChildren) { 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)