Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SpeedrunManager v1.0.2
SpeedrunManager.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using SpeedrunManager.Patches; using SpeedrunManager.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SpeedrunManager")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SpeedrunManager")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("031bb4ac-9b74-4f04-b34e-cb63952a95ae")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace SpeedrunManager { public enum BossNameEnum { [BossNameAttr("TrophyEikthyr", "$enemy_eikthyr")] Eikthyr, [BossNameAttr("TrophyTheElder", "$enemy_gdking")] gd_king, [BossNameAttr("TrophyBonemass", "$enemy_bonemass")] Bonemass, [BossNameAttr("TrophyDragonQueen", "$enemy_dragon")] Dragon, [BossNameAttr("TrophyGoblinKing", "$enemy_goblinking")] GoblinKing, [BossNameAttr("TrophySeekerQueen", "$enemy_seekerqueen")] SeekerQueen, [BossNameAttr("TrophyFader", "$enemy_fader")] Fader } internal class BossNameAttr : Attribute { public string translationKey { get; private set; } public string trophySpriteKey { get; private set; } internal BossNameAttr(string trophySpriteKey, string translationKey) { this.trophySpriteKey = trophySpriteKey; this.translationKey = translationKey; } } public static class BossNameFields { public static string GetTranslationKey(this BossNameEnum p) { BossNameAttr attr = GetAttr(p); return attr.translationKey; } public static string GetTrophySpriteKey(this BossNameEnum p) { BossNameAttr attr = GetAttr(p); return attr.trophySpriteKey; } private static BossNameAttr GetAttr(BossNameEnum p) { return (BossNameAttr)Attribute.GetCustomAttribute(ForValue(p), typeof(BossNameAttr)); } private static MemberInfo ForValue(BossNameEnum p) { return typeof(BossNameEnum).GetField(Enum.GetName(typeof(BossNameEnum), p)); } } public class SplitsCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; internal void <RegisterConsoleCommand>b__0_0(ConsoleEventArgs args) { BossNameEnum result; if (args.Args.Length < 3) { args.Context.AddString("Usage: speedrun_set_split <boss_name> <timer_value>"); } else if (Enum.TryParse<BossNameEnum>(args.Args[1], out result)) { RegisterBossDefeatPatch.setupBossSplitTime(args.Args[1], args.Args[2], overwrite: true); Split split = new Split(result, args.Args[2]); SpeedrunTimer.AddSplitTimer(split); } } internal void <RegisterConsoleCommand>b__0_1(ConsoleEventArgs args) { if (args.Args.Length < 1) { args.Context.AddString("Usage: speedrun_reset"); } else { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return; } Dictionary<string, string> dictionary = (Dictionary<string, string>)ModUtils.GetPrivateValue(Player.m_localPlayer, "m_knownTexts"); List<string> list = new List<string>(); string worldName = ZNet.instance.GetWorldName(); foreach (string key in dictionary.Keys) { if (key.StartsWith("Turbero.SpeedrunManager_" + worldName)) { list.Add(key); } } foreach (string item in list) { dictionary.Remove(item); } } } } public static void RegisterConsoleCommand() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { BossNameEnum result; if (args.Args.Length < 3) { args.Context.AddString("Usage: speedrun_set_split <boss_name> <timer_value>"); } else if (Enum.TryParse<BossNameEnum>(args.Args[1], out result)) { RegisterBossDefeatPatch.setupBossSplitTime(args.Args[1], args.Args[2], overwrite: true); Split split = new Split(result, args.Args[2]); SpeedrunTimer.AddSplitTimer(split); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("speedrun_set_split", "[boss_prefab_id] [timer_value]", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate(ConsoleEventArgs args) { if (args.Args.Length < 1) { args.Context.AddString("Usage: speedrun_reset"); } else if (!((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)ZNet.instance == (Object)null)) { Dictionary<string, string> dictionary = (Dictionary<string, string>)ModUtils.GetPrivateValue(Player.m_localPlayer, "m_knownTexts"); List<string> list = new List<string>(); string worldName = ZNet.instance.GetWorldName(); foreach (string key in dictionary.Keys) { if (key.StartsWith("Turbero.SpeedrunManager_" + worldName)) { list.Add(key); } } foreach (string item in list) { dictionary.Remove(item); } } }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("speedrun_reset", "", (ConsoleEvent)obj2, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public enum SpeedrunType { Permadeath, InfiniteLives } public class DefaultUIPositions { public static readonly Vector2 positionTimer = new Vector2(885f, 20f); public static readonly int fontSizeTimer = 64; public static readonly Vector2 positionSplits = new Vector2(630f, 8f); public static readonly int fontSizeSplits = 20; public static readonly int splitsColumnSize = 4; public static readonly int splitsColumnsSpace = 0; public static readonly int splitsRowsSpace = 40; } internal class ConfigurationFile { public static ConfigEntry<bool> debug; public static ConfigEntry<KeyCode> hotKey; public static ConfigEntry<SpeedrunType> speedrunType; private static ConfigFile configFile; private static readonly string ConfigFileName = "Turbero.SpeedrunManager.cfg"; private static readonly string ConfigFileFullPath; public static ConfigEntry<Color> colorTimerAfterDyingInPermadeath; public static ConfigEntry<bool> countHuginnInitTravelAsPartOfTimer; public static ConfigEntry<bool> overrideBossSplitTimerIfKilledAgain; public static ConfigEntry<int> effectsPerRow; public static ConfigEntry<bool> showTimer; public static ConfigEntry<Vector2> positionTimer; public static ConfigEntry<Color> colorTimer; public static ConfigEntry<float> colorWidthTimer; public static ConfigEntry<int> fontSizeTimer; public static ConfigEntry<bool> showSplits; public static ConfigEntry<Vector2> positionSplits; public static ConfigEntry<Color> colorSplits; public static ConfigEntry<float> colorWidthSplits; public static ConfigEntry<int> fontSizeSplits; public static ConfigEntry<int> splitsColumnSize; public static ConfigEntry<int> splitsColumnsSpace; public static ConfigEntry<int> splitsRowsSpace; internal static void LoadConfig(BaseUnityPlugin plugin) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01a4: 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_01be: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Expected O, but got Unknown //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Expected O, but got Unknown //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Expected O, but got Unknown //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Expected O, but got Unknown configFile = plugin.Config; debug = configFile.Bind<bool>("1 - General", "DebugMode", false, "Enabling/Disabling the debugging in the console (default = false)"); hotKey = configFile.Bind<KeyCode>("1 - General", "Hotkey Panel", (KeyCode)121, "Key to show/hide the speedrun panel configuration"); speedrunType = configFile.Bind<SpeedrunType>("2 - Configuration", "Speedrun Type", SpeedrunType.Permadeath, new ConfigDescription("Speedrun type", (AcceptableValueBase)null, Array.Empty<object>())); countHuginnInitTravelAsPartOfTimer = configFile.Bind<bool>("2 - Configuration", "Count from Huginn Intro", false, new ConfigDescription("If active, the time will start since Huginn is taking you to the spawn, that's ~1min47seg (default = false)", (AcceptableValueBase)null, Array.Empty<object>())); overrideBossSplitTimerIfKilledAgain = configFile.Bind<bool>("2 - Configuration", "Override Boss Split Timer if killed again", false, new ConfigDescription("Replaces the time the boss was killed in his split when it is killed again if this is enabled (default = false)", (AcceptableValueBase)null, Array.Empty<object>())); effectsPerRow = configFile.Bind<int>("2 - Configuration", "Effects Per Row", 7, new ConfigDescription("Effects Per Row", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); showTimer = configFile.Bind<bool>("3 - UI", "Show Timer", true, new ConfigDescription("Show/hide timer (still running while hidden)", (AcceptableValueBase)null, Array.Empty<object>())); showSplits = configFile.Bind<bool>("3 - UI", "Show Splits", true, new ConfigDescription("Show/hide splits information", (AcceptableValueBase)null, Array.Empty<object>())); positionTimer = configFile.Bind<Vector2>("3.1 - UI Timer", "Position", new Vector2(885f, 20f), new ConfigDescription("UI Timer position", (AcceptableValueBase)null, Array.Empty<object>())); colorTimer = configFile.Bind<Color>("3.1 - UI Timer", "Color", new Color(0f, 1f, 0f), new ConfigDescription("UI Timer color", (AcceptableValueBase)null, Array.Empty<object>())); colorWidthTimer = configFile.Bind<float>("3.1 - UI Timer", "Color Intensity", 0.15f, new ConfigDescription("UI Timer color intensity (recommended between 0 and 0.5f)", (AcceptableValueBase)null, Array.Empty<object>())); fontSizeTimer = configFile.Bind<int>("3.1 - UI Timer", "Size", 64, new ConfigDescription("UI Timer size", (AcceptableValueBase)null, Array.Empty<object>())); colorTimerAfterDyingInPermadeath = configFile.Bind<Color>("3.1 - UI Timer", "Timer Color After Dying In Permadeath", new Color(1f, 0f, 0f), "Timer color after dying for first time in permadeath mode"); positionSplits = configFile.Bind<Vector2>("3.2 - UI Splits", "Splits Position", new Vector2(630f, 8f), new ConfigDescription("UI Splits position", (AcceptableValueBase)null, Array.Empty<object>())); colorSplits = configFile.Bind<Color>("3.2 - UI Splits", "Splits Color", Color.white, new ConfigDescription("UI Splits color", (AcceptableValueBase)null, Array.Empty<object>())); colorWidthSplits = configFile.Bind<float>("3.2 - UI Splits", "Splits Color Intensity", 0.05f, new ConfigDescription("UI Splits color intensity (recommended between 0 and 0.5f)", (AcceptableValueBase)null, Array.Empty<object>())); fontSizeSplits = configFile.Bind<int>("3.2 - UI Splits", "Splits Font Size", 20, new ConfigDescription("UI Splits size", (AcceptableValueBase)null, Array.Empty<object>())); splitsColumnSize = configFile.Bind<int>("3.2 - UI Splits", "Splits Column Size", 4, new ConfigDescription("UI Splits size", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 8), Array.Empty<object>())); splitsColumnsSpace = configFile.Bind<int>("3.2 - UI Splits", "Splits Columns Space", 0, new ConfigDescription("UI Splits Columns Space", (AcceptableValueBase)null, Array.Empty<object>())); splitsRowsSpace = configFile.Bind<int>("3.2 - UI Splits", "Splits Rows Space", 40, new ConfigDescription("UI Splits Rows Space", (AcceptableValueBase)null, Array.Empty<object>())); SetupWatcher(); } private static void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private static void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { Logger.Log("Attempting to reload configuration..."); configFile.Reload(); SettingsChanged(null, null); } catch (Exception arg) { Logger.LogError($"There was an issue loading {ConfigFileName}, {arg}"); } } private static void SettingsChanged(object sender, EventArgs e) { if ((Object)(object)SpeedrunTimer._text != (Object)null) { Hud.instance.m_effectsPerRow = effectsPerRow.Value; SpeedrunTimer.UpdateVisibility(); SpeedrunTimer.UpdateTimer(); SpeedrunTimer.UpdateTimerUI(); SpeedrunTimer.DrawSplits(); } } static ConfigurationFile() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; } } public class ControllerUtils { public static void RemoveHint(Transform buttonGo, InventoryGui inventoryGui = null) { UIGamePad val = null; if (((Component)buttonGo).TryGetComponent<UIGamePad>(ref val)) { if (ZInput.instance == null) { ZInput.Initialize(); } ((TMP_Text)val.m_hint.GetComponentInChildren<TextMeshProUGUI>(true)).text = ""; } } public static void BindGamePad(Transform buttonGo, KeyCode gamepadKeyCode, InventoryGui inventoryGui = null) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) UIGamePad val = null; if (((Component)buttonGo).TryGetComponent<UIGamePad>(ref val)) { string text = KeyCodeToString(gamepadKeyCode); if (ZInput.instance == null) { ZInput.Initialize(); } TextMeshProUGUI componentInChildren = val.m_hint.GetComponentInChildren<TextMeshProUGUI>(true); ZInput instance = ZInput.instance; ((TMP_Text)componentInChildren).text = ((instance != null) ? instance.GetBoundKeyString(text, true) : null); val.m_zinputKey = text; val.m_keyCode = gamepadKeyCode; UIGroupHandler value = default(UIGroupHandler); if ((Object)(object)inventoryGui != (Object)null && ((Component)inventoryGui.m_crafting).TryGetComponent<UIGroupHandler>(ref value)) { SetPrivateValue(val, "m_group", value); } } } private static void SetPrivateValue(object obj, string name, object value, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic) { obj.GetType().GetField(name, bindingAttr)?.SetValue(obj, value); } public static string KeyCodeToString(KeyCode keyCode) { //IL_0001: 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: Expected I4, but got Unknown int num = keyCode - 330; if (1 == 0) { } string result = num switch { 1 => "JoyButtonB", 2 => "JoyButtonX", 3 => "JoyButtonY", 4 => "JoyLBumper", 5 => "JoyRBumper", 6 => "JoyBack", 7 => "JoyStart", 8 => "JoyLStick", 9 => "JoyRStick", 10 => "JoyDPadLeft", 11 => "JoyDPadRight", 12 => "JoyDPadUp", 13 => "JoyDPadDown", 14 => "JoyLTrigger", 15 => "JoyRTrigger", 16 => "JoyButtonA", 17 => "JoyButtonB", 18 => "JoyButtonX", 19 => "JoyButtonY", _ => "JoyButtonA", }; if (1 == 0) { } return result; } } public static class Logger { public static ManualLogSource logger = Logger.CreateLogSource("Speedrun Manager"); internal static void Log(object s) { if (ConfigurationFile.debug.Value) { logger.LogInfo((object)s?.ToString()); } } internal static void LogInfo(object s) { logger.LogInfo((object)s?.ToString()); } internal static void LogWarning(object s) { string text = "Speedrun Manager 1.0.2: " + ((s != null) ? s.ToString() : "null"); Debug.LogWarning((object)text); } internal static void LogError(object s) { string text = "Speedrun Manager 1.0.2: " + ((s != null) ? s.ToString() : "null"); Debug.LogError((object)text); } } public class ModStatsUtils { public static Dictionary<string, string> GetKnownTexts() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return new Dictionary<string, string>(); } return (Dictionary<string, string>)ModUtils.GetPrivateValue(Player.m_localPlayer, "m_knownTexts"); } public static Dictionary<PlayerStatType, float> GetStats() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if ((Object)(object)Game.instance == (Object)null) { return new Dictionary<PlayerStatType, float>(); } return ((PlayerProfile)(typeof(Game).GetField("m_playerProfile", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(Game.instance)))?.m_playerStats.m_stats; } public static string GetSpeedrunKnownTextKey(string name) { ZNet instance = ZNet.instance; string text = ((instance != null) ? instance.GetWorldName() : null); return "Turbero.SpeedrunManager_" + text + "_" + name; } public static string GetSpeedrunKnownTextValue(string name) { return ZDOHelper.GetValueOrDefaultPiktiv<string, string>((IDictionary<string, string>)GetKnownTexts(), GetSpeedrunKnownTextKey(name), (string)null); } public static void SetSpeedrunKnownTextKeyValue(string name, string value) { Dictionary<string, string> knownTexts = GetKnownTexts(); string speedrunKnownTextKey = GetSpeedrunKnownTextKey(name); knownTexts.Remove(speedrunKnownTextKey); knownTexts.Add(speedrunKnownTextKey, value); } } public static class ModUtils { private static readonly Dictionary<string, Sprite> cachedSprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, TMP_FontAsset> cachedFonts = new Dictionary<string, TMP_FontAsset>(); public static object GetPrivateValue(object obj, string name, BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic) { return obj.GetType().GetField(name, bindingAttr)?.GetValue(obj); } public static BossNameEnum parseBossName(string value) { Logger.Log("Parsing value: " + value); return (BossNameEnum)Enum.Parse(typeof(BossNameEnum), value, ignoreCase: true); } public static TMP_FontAsset getFontAsset(string name) { if (!cachedFonts.ContainsKey(name)) { Logger.Log("Finding " + name + " font..."); TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset val in array) { if (((Object)val).name == name) { Logger.Log(name + " font found."); cachedFonts.Add(name, val); return val; } } Logger.Log(name + " font NOT found."); return null; } return GeneralExtensions.GetValueSafe<string, TMP_FontAsset>(cachedFonts, name); } public static Sprite getSprite(string name) { if (!cachedSprites.ContainsKey(name)) { Logger.Log("Finding " + name + " sprite..."); Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if (((Object)val).name == name) { Logger.Log(name + " sprite found."); cachedSprites.Add(name, val); return val; } } Logger.Log(name + " sprite NOT found."); return null; } return GeneralExtensions.GetValueSafe<string, Sprite>(cachedSprites, name); } } [BepInPlugin("Turbero.SpeedrunManager", "Speedrun Manager", "1.0.2")] public class SpeedrunManager : BaseUnityPlugin { [CompilerGenerated] private sealed class <WaitForNetworking>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SpeedrunManager <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworking>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (ZRoutedRpc.instance == null || (Object)(object)ZNet.instance == (Object)null) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } SplitsCommands.RegisterConsoleCommand(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string GUID = "Turbero.SpeedrunManager"; public const string NAME = "Speedrun Manager"; public const string VERSION = "1.0.2"; private readonly Harmony harmony = new Harmony("Turbero.SpeedrunManager"); private void Awake() { ConfigurationFile.LoadConfig((BaseUnityPlugin)(object)this); harmony.PatchAll(); } private void onDestroy() { harmony.UnpatchSelf(); } private void Start() { ((MonoBehaviour)this).StartCoroutine(WaitForNetworking()); } [IteratorStateMachine(typeof(<WaitForNetworking>d__7))] private IEnumerator WaitForNetworking() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworking>d__7(0) { <>4__this = this }; } private void Update() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || InventoryGui.IsVisible() || !Object.op_Implicit((Object)(object)Hud.instance) || !SpeedrunConfigPanel.IsCreated()) { return; } if (Input.GetKeyDown((KeyCode)27) && SpeedrunConfigPanel.IsVisible()) { SpeedrunConfigPanel.Hide(hideMenu: false); } if ((Input.GetKeyDown((KeyCode)271) || Input.GetKeyDown((KeyCode)13) || ((Character)Player.m_localPlayer).IsDead()) && SpeedrunConfigPanel.IsVisible()) { SpeedrunConfigPanel.Hide(); } if (!Input.GetKeyDown(ConfigurationFile.hotKey.Value)) { return; } if (SpeedrunConfigPanel.IsVisible()) { SpeedrunConfigPanel.Hide(); } else if (CanShowSpeedrunConfigPanel()) { if (!SpeedrunConfigPanel.IsCreated()) { SpeedrunConfigPanel.Create(); } SpeedrunConfigPanel.Show(); } } private static bool CanShowSpeedrunConfigPanel() { return (Object)(object)Player.m_localPlayer != (Object)null && (((Character)Player.m_localPlayer).CanMove() || ((Character)Player.m_localPlayer).IsSitting()) && !Game.IsPaused() && !InventoryGui.IsVisible() && !Console.IsVisible() && !((Component)((Component)Hud.instance).transform.parent.Find("Chat_box/root/ChatInput")).gameObject.activeSelf && !((Component)((Component)Game.instance).transform.Find("LoadingGUI/PixelFix/IngameGui/TextInput/panel")).gameObject.activeSelf && !((Component)((Component)Minimap.instance).transform.Find("large")).gameObject.activeSelf && !StoreGui.instance.m_rootPanel.activeSelf; } } [HarmonyPatch(typeof(Player), "GetKnownTexts")] public class FixCompendium { public static void Postfix(ref List<KeyValuePair<string, string>> __result) { __result = __result.Where((KeyValuePair<string, string> p) => !p.Key.StartsWith("Turbero.SpeedrunManager")).ToList(); } } } namespace SpeedrunManager.UI { public class ResetConfirmDialog { public GameObject resetConfirmDialog; public ResetConfirmDialog() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) Logger.Log("Creating resetConfirmDialog..."); resetConfirmDialog = Object.Instantiate<GameObject>(GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/Menu/MenuRoot/ExitConfirm"), ((Component)Menu.instance).transform); ((Object)resetConfirmDialog).name = "ResetConfirmDialog"; UIGroupHandler componentInChildren = resetConfirmDialog.GetComponentInChildren<UIGroupHandler>(); ((TMP_Text)((Component)((Component)componentInChildren).transform.Find("Exit")).GetComponentInChildren<TextMeshProUGUI>()).text = "Confirm?"; Button[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<Button>(); Button val = componentsInChildren[0]; val.onClick = new ButtonClickedEvent(); ((UnityEvent)val.onClick).AddListener((UnityAction)delegate { Logger.Log("Yes button clicked"); showResetDialog(show: false, impactMenu: false); SpeedrunTimer.ResetTimer(); }); Button val2 = componentsInChildren[1]; val2.onClick = new ButtonClickedEvent(); ((UnityEvent)val2.onClick).AddListener((UnityAction)delegate { Logger.Log("No button clicked"); showResetDialog(show: false, impactMenu: false); }); GameObject val3 = Object.Instantiate<GameObject>(((Component)((Component)InventoryGui.instance.m_skillsDialog).transform.Find("darken")).gameObject, resetConfirmDialog.transform); ((Object)val3).name = "dark_en"; val3.transform.SetAsFirstSibling(); val3.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, -140f); } public void showResetDialog(bool show, bool impactMenu = true) { resetConfirmDialog.SetActive(show); if (impactMenu) { if (show) { Menu.instance.Show(); ((Component)((Component)Menu.instance).transform.Find("MenuRoot/Menu/MenuEntries")).gameObject.SetActive(false); ((Component)((Component)Menu.instance).transform.Find("MenuRoot/Menu/ornament")).gameObject.SetActive(false); } else { ((Component)((Component)Menu.instance).transform.Find("MenuRoot/Menu/MenuEntries")).gameObject.SetActive(true); ((Component)((Component)Menu.instance).transform.Find("MenuRoot/Menu/ornament")).gameObject.SetActive(true); Menu.instance.Hide(); } } } } public class CustomSlider { private int initValue; private readonly GameObject sliderObject; private readonly Slider slider; private readonly TextMeshProUGUI sliderValue; public TextMeshProUGUI sliderLabelDescription; private Button resetButton; public CustomSlider(string name, int minValue, int maxValue, Vector2 sizeDelta, Vector2 position, int posXIcon, string spriteName, int posXDescription, string description, int posXValue, int initValue, string valueDesc, bool hasResetButton = false) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0034: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Expected O, but got Unknown //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Expected O, but got Unknown //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Expected O, but got Unknown //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Expected O, but got Unknown //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Expected O, but got Unknown sliderObject = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform component = sliderObject.GetComponent<RectTransform>(); component.sizeDelta = sizeDelta; component.anchoredPosition = position; slider = sliderObject.AddComponent<Slider>(); ((Object)slider).name = name; slider.minValue = minValue; slider.maxValue = maxValue; slider.value = initValue; this.initValue = initValue; typeof(Slider).GetField("m_WholeNumbers", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(slider, true); GameObject val = new GameObject("Background", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(sliderObject.transform, false); RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(1f, 1f); component2.sizeDelta = new Vector2(0f, 0f); ((Graphic)val.GetComponent<Image>()).color = Color.gray; GameObject val2 = new GameObject("Fill Area", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(sliderObject.transform, false); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 0.25f); component3.anchorMax = new Vector2(1f, 0.75f); component3.sizeDelta = new Vector2(0f, 0f); GameObject val3 = new GameObject("Fill", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform component4 = val3.GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0f, 0f); component4.anchorMax = new Vector2(1f, 1f); component4.sizeDelta = new Vector2(0f, 0f); ((Graphic)val3.GetComponent<Image>()).color = Color.green; slider.fillRect = component4; GameObject val4 = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); val4.transform.SetParent(sliderObject.transform, false); RectTransform component5 = val4.GetComponent<RectTransform>(); component5.sizeDelta = new Vector2(10f, 10f); ((Graphic)val4.GetComponent<Image>()).color = Color.white; ((Selectable)slider).targetGraphic = (Graphic)(object)val4.GetComponent<Image>(); slider.handleRect = component5; if (spriteName != null) { GameObject val5 = new GameObject("Icon"); Image val6 = val5.AddComponent<Image>(); val6.sprite = ModUtils.getSprite(spriteName); RectTransform component6 = val5.GetComponent<RectTransform>(); ((Transform)component6).SetParent(sliderObject.transform, false); component6.sizeDelta = new Vector2(25f, 25f); component6.anchoredPosition = new Vector2((float)posXIcon, 0f); } if (description != null) { GameObject val7 = new GameObject("SliderLabel", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val7.transform.SetParent(sliderObject.transform, false); RectTransform component7 = val7.GetComponent<RectTransform>(); component7.anchoredPosition = new Vector2((float)posXDescription, 0f); sliderLabelDescription = val7.GetComponent<TextMeshProUGUI>(); ((TMP_Text)sliderLabelDescription).text = description; ((TMP_Text)sliderLabelDescription).fontSize = 18f; ((TMP_Text)sliderLabelDescription).alignment = (TextAlignmentOptions)516; ((TMP_Text)sliderLabelDescription).font = ModUtils.getFontAsset("Valheim-AveriaSansLibre"); } if (initValue >= 0) { GameObject val8 = new GameObject("SliderValue", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val8.transform.SetParent(sliderObject.transform, false); RectTransform component8 = val8.GetComponent<RectTransform>(); component8.anchoredPosition = new Vector2((float)posXValue, 0f); sliderValue = val8.GetComponent<TextMeshProUGUI>(); ((TMP_Text)sliderValue).fontSize = 18f; ((TMP_Text)sliderValue).font = ModUtils.getFontAsset("Valheim-AveriaSansLibre"); ((TMP_Text)sliderValue).alignment = (TextAlignmentOptions)513; ((TMP_Text)sliderValue).text = valueDesc; } if (hasResetButton) { resetButton = Object.Instantiate<Button>(InventoryGui.instance.m_takeAllButton, sliderObject.transform); ((Object)resetButton).name = "ResetButton"; ControllerUtils.RemoveHint(((Component)resetButton).transform); ((Component)resetButton).GetComponent<RectTransform>().anchoredPosition = new Vector2(140f, 0f); ((Component)resetButton).GetComponent<RectTransform>().sizeDelta = new Vector2(30f, 30f); ((TMP_Text)((Component)resetButton).GetComponentInChildren<TextMeshProUGUI>()).text = "R"; resetButton.onClick = new ButtonClickedEvent(); ((UnityEvent)resetButton.onClick).AddListener((UnityAction)delegate { updateValue(this.initValue); updateTextValue(this.initValue.ToString()); }); UITooltip val9 = ((Component)resetButton).gameObject.AddComponent<UITooltip>(); val9.m_tooltipPrefab = Object.Instantiate<GameObject>(((Component)((Component)InventoryGui.instance).transform.Find("root/Info/Skills")).GetComponent<UITooltip>().m_tooltipPrefab); val9.m_text = "Reset"; } } public GameObject getGameObject() { return sliderObject; } public void OnValueChanged(UnityAction<float> call) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown slider.onValueChanged = new SliderEvent(); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener(call); } public void updateTextValue(string value) { ((TMP_Text)sliderValue).text = value; } public void updateValue(float value) { slider.value = value; } public float getValue() { return slider.value; } } public class SpeedrunConfigPanel { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__14_0; public static UnityAction <>9__14_1; public static UnityAction<float> <>9__15_0; public static UnityAction<float> <>9__15_1; public static UnityAction<float> <>9__15_2; public static UnityAction<float> <>9__15_3; public static UnityAction<float> <>9__15_4; public static UnityAction<float> <>9__16_0; public static UnityAction<float> <>9__16_1; public static UnityAction<float> <>9__16_2; public static UnityAction<float> <>9__16_3; public static UnityAction<float> <>9__16_4; public static UnityAction<float> <>9__16_5; public static UnityAction<float> <>9__16_6; internal void <Create>b__14_0() { resetConfirmDialog.showResetDialog(show: false); Hide(); } internal void <Create>b__14_1() { resetConfirmDialog.showResetDialog(show: true, impactMenu: false); } internal void <addTimerSliders>b__15_0(float value) { customSliderShowTimer.updateTextValue(value.Equals(1f).ToString()); ConfigurationFile.showTimer.Value = value.Equals(1f); } internal void <addTimerSliders>b__15_1(float value) { Logger.Log("slider changed to " + value); customSliderRunType.updateTextValue(value.Equals(1f) ? "Permadeath" : "InfiniteLives"); ConfigurationFile.speedrunType.Value = ((!value.Equals(1f)) ? SpeedrunType.InfiniteLives : SpeedrunType.Permadeath); } internal void <addTimerSliders>b__15_2(float value) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderTimerPositionX.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionTimer.Value = new Vector2(value, ConfigurationFile.positionTimer.Value.y); } internal void <addTimerSliders>b__15_3(float value) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderTimerPositionY.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionTimer.Value = new Vector2(ConfigurationFile.positionTimer.Value.x, value); } internal void <addTimerSliders>b__15_4(float value) { Logger.Log("slider changed to " + value); customSliderFontTimer.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.fontSizeTimer.Value = (int)value; } internal void <addSplitsSliders>b__16_0(float value) { customSliderShowSplits.updateTextValue(value.Equals(1f).ToString()); ConfigurationFile.showSplits.Value = value.Equals(1f); } internal void <addSplitsSliders>b__16_1(float value) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderSplitsPositionX.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionSplits.Value = new Vector2(value, ConfigurationFile.positionSplits.Value.y); } internal void <addSplitsSliders>b__16_2(float value) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderSplitsPositionY.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionSplits.Value = new Vector2(ConfigurationFile.positionSplits.Value.x, value); } internal void <addSplitsSliders>b__16_3(float value) { Logger.Log("slider changed to " + value); customSliderSplitsColumnSize.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsColumnSize.Value = (int)value; } internal void <addSplitsSliders>b__16_4(float value) { Logger.Log("slider changed to " + value); customSliderSplitsColumnsSpace.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsColumnsSpace.Value = (int)(value + 104f); } internal void <addSplitsSliders>b__16_5(float value) { Logger.Log("slider changed to " + value); customSliderSplitsRowsSpace.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsRowsSpace.Value = (int)value; } internal void <addSplitsSliders>b__16_6(float value) { Logger.Log("slider changed to " + value); customSliderFontSplits.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.fontSizeSplits.Value = (int)value; } } public static GameObject panel; private static CustomSlider customSliderShowTimer; private static CustomSlider customSliderTimerPositionX; private static CustomSlider customSliderTimerPositionY; private static CustomSlider customSliderFontTimer; private static CustomSlider customSliderSplitsPositionX; private static CustomSlider customSliderSplitsPositionY; private static CustomSlider customSliderSplitsColumnSize; private static CustomSlider customSliderSplitsColumnsSpace; private static CustomSlider customSliderSplitsRowsSpace; private static CustomSlider customSliderFontSplits; private static CustomSlider customSliderRunType; private static CustomSlider customSliderShowSplits; private static ResetConfirmDialog resetConfirmDialog; public static void Create() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_007f: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Expected O, but got Unknown //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Expected O, but got Unknown //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Expected O, but got Unknown Transform transform = ((Component)((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame")).transform; panel = new GameObject("SpeedrunConfigPanel", new Type[1] { typeof(RectTransform) }); panel.SetActive(false); panel.transform.SetParent(((Component)Menu.instance).transform, false); RectTransform component = panel.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(820f, 550f); component.anchoredPosition = new Vector2(0f, 0f); Image component2 = ((Component)transform.Find("bkg")).GetComponent<Image>(); Image val = Object.Instantiate<Image>(component2, panel.transform); ((Object)val).name = "bkg"; GameObject gameObject = ((Component)transform.Find("topic")).gameObject; GameObject val2 = Object.Instantiate<GameObject>(gameObject, panel.transform); ((Object)val2).name = "Title"; val2.GetComponent<RectTransform>().sizeDelta = new Vector2(400f, 50f); TextMeshProUGUI component3 = val2.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component3).text = "SPEEDRUN CONFIGURATION (v1.0.2)"; RectTransform component4 = val2.GetComponent<RectTransform>(); component4.anchoredPosition = new Vector2(0f, -30f); Transform val3 = ((Component)InventoryGui.instance.m_skillsDialog).transform.Find("SkillsFrame/Closebutton"); GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, panel.transform); ((Object)val4).name = "CloseButton"; val4.transform.SetParent(panel.transform, false); ControllerUtils.BindGamePad(val4.transform, (KeyCode)331); RectTransform component5 = val4.GetComponent<RectTransform>(); component5.anchoredPosition = new Vector2(200f, 40f); TMP_Text componentInChildren = val4.GetComponentInChildren<TMP_Text>(); componentInChildren.text = Localization.instance.Localize("$menu_close"); Button component6 = val4.GetComponent<Button>(); component6.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = component6.onClick; object obj = <>c.<>9__14_0; if (obj == null) { UnityAction val5 = delegate { resetConfirmDialog.showResetDialog(show: false); Hide(); }; <>c.<>9__14_0 = val5; obj = (object)val5; } ((UnityEvent)onClick).AddListener((UnityAction)obj); GameObject val6 = Object.Instantiate<GameObject>(val4.gameObject, panel.transform); ((Object)val6).name = "ResetButton"; val6.transform.SetParent(panel.transform, false); ControllerUtils.BindGamePad(val6.transform, (KeyCode)332); RectTransform component7 = val6.GetComponent<RectTransform>(); component7.anchoredPosition = new Vector2(-200f, 40f); TMP_Text componentInChildren2 = val6.GetComponentInChildren<TMP_Text>(); componentInChildren2.text = "Reset"; Button component8 = val6.GetComponent<Button>(); component8.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick2 = component8.onClick; object obj2 = <>c.<>9__14_1; if (obj2 == null) { UnityAction val7 = delegate { resetConfirmDialog.showResetDialog(show: true, impactMenu: false); }; <>c.<>9__14_1 = val7; obj2 = (object)val7; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); addTimerSliders(); addSplitsSliders(); resetConfirmDialog = new ResetConfirmDialog(); } private static void addTimerSliders() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) customSliderShowTimer = new CustomSlider("ShowTimerSlider", 0, 1, new Vector2(25f, 10f), new Vector2(-272f, 200f), -1, null, -124, "Show Timer", 123, ConfigurationFile.showTimer.Value ? 1 : 0, ConfigurationFile.showTimer.Value.ToString()); customSliderShowTimer.getGameObject().transform.SetParent(panel.transform, false); customSliderShowTimer.OnValueChanged(delegate(float value) { customSliderShowTimer.updateTextValue(value.Equals(1f).ToString()); ConfigurationFile.showTimer.Value = value.Equals(1f); }); customSliderRunType = new CustomSlider("RunTypeSlider", 0, 1, new Vector2(25f, 10f), new Vector2(-272f, 170f), -1, null, -124, "Run Type", 123, (ConfigurationFile.speedrunType.Value == SpeedrunType.Permadeath) ? 1 : 0, ConfigurationFile.speedrunType.Value.ToString()); customSliderRunType.getGameObject().transform.SetParent(panel.transform, false); customSliderRunType.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderRunType.updateTextValue(value.Equals(1f) ? "Permadeath" : "InfiniteLives"); ConfigurationFile.speedrunType.Value = ((!value.Equals(1f)) ? SpeedrunType.InfiniteLives : SpeedrunType.Permadeath); }); customSliderTimerPositionX = new CustomSlider("TimerPositionXSlider", 0, 2000, new Vector2(150f, 10f), new Vector2(-210f, 140f), 0, null, -186, "Timer X-ayis", 185, (int)DefaultUIPositions.positionTimer.x, Utils.ToGlobalInvariantString(ConfigurationFile.positionTimer.Value.x), hasResetButton: true); customSliderTimerPositionX.getGameObject().transform.SetParent(panel.transform, false); customSliderTimerPositionX.OnValueChanged(delegate(float value) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderTimerPositionX.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionTimer.Value = new Vector2(value, ConfigurationFile.positionTimer.Value.y); }); customSliderTimerPositionY = new CustomSlider("TimerPositionYSlider", 0, 1100, new Vector2(150f, 10f), new Vector2(-210f, 110f), 0, null, -186, "Timer Y-ayis", 185, (int)DefaultUIPositions.positionTimer.y, Utils.ToGlobalInvariantString(ConfigurationFile.positionTimer.Value.y), hasResetButton: true); customSliderTimerPositionY.getGameObject().transform.SetParent(panel.transform, false); customSliderTimerPositionY.OnValueChanged(delegate(float value) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderTimerPositionY.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionTimer.Value = new Vector2(ConfigurationFile.positionTimer.Value.x, value); }); customSliderFontTimer = new CustomSlider("FontTimerSlider", 1, 256, new Vector2(150f, 10f), new Vector2(-210f, 80f), 0, null, -186, "Timer Size", 185, DefaultUIPositions.fontSizeTimer, ConfigurationFile.fontSizeTimer.Value.ToString(), hasResetButton: true); customSliderFontTimer.getGameObject().transform.SetParent(panel.transform, false); customSliderFontTimer.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderFontTimer.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.fontSizeTimer.Value = (int)value; }); } private static void addSplitsSliders() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00f2: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) customSliderShowSplits = new CustomSlider("ShowSplitsSlider", 0, 1, new Vector2(25f, 10f), new Vector2(178f, 200f), -1, null, -124, "Show Splits", 123, ConfigurationFile.showSplits.Value ? 1 : 0, ConfigurationFile.showSplits.Value.ToString()); customSliderShowSplits.getGameObject().transform.SetParent(panel.transform, false); customSliderShowSplits.OnValueChanged(delegate(float value) { customSliderShowSplits.updateTextValue(value.Equals(1f).ToString()); ConfigurationFile.showSplits.Value = value.Equals(1f); }); customSliderSplitsPositionX = new CustomSlider("SplitsPositionXSlider", 0, 1800, new Vector2(150f, 10f), new Vector2(240f, 170f), 0, null, -186, "Splits X-ayis", 185, (int)DefaultUIPositions.positionSplits.x, Utils.ToGlobalInvariantString(ConfigurationFile.positionSplits.Value.x), hasResetButton: true); customSliderSplitsPositionX.getGameObject().transform.SetParent(panel.transform, false); customSliderSplitsPositionX.OnValueChanged(delegate(float value) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderSplitsPositionX.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionSplits.Value = new Vector2(value, ConfigurationFile.positionSplits.Value.y); }); customSliderSplitsPositionY = new CustomSlider("SplitsPositionYSlider", 0, 960, new Vector2(150f, 10f), new Vector2(240f, 140f), 0, null, -186, "Splits Y-ayis", 185, (int)DefaultUIPositions.positionSplits.y, Utils.ToGlobalInvariantString(ConfigurationFile.positionSplits.Value.y), hasResetButton: true); customSliderSplitsPositionY.getGameObject().transform.SetParent(panel.transform, false); customSliderSplitsPositionY.OnValueChanged(delegate(float value) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Logger.Log("slider changed to " + value); customSliderSplitsPositionY.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.positionSplits.Value = new Vector2(ConfigurationFile.positionSplits.Value.x, value); }); customSliderSplitsColumnSize = new CustomSlider("SplitsColumnSize", 4, 8, new Vector2(150f, 10f), new Vector2(240f, 110f), 0, null, -186, "Splits Column Size", 185, DefaultUIPositions.splitsColumnSize, ConfigurationFile.splitsColumnSize.Value.ToString(), hasResetButton: true); customSliderSplitsColumnSize.getGameObject().transform.SetParent(panel.transform, false); customSliderSplitsColumnSize.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderSplitsColumnSize.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsColumnSize.Value = (int)value; }); customSliderSplitsColumnsSpace = new CustomSlider("SplitsColumnsSpace", 0, 2000, new Vector2(150f, 10f), new Vector2(240f, 80f), 0, null, -186, "Splits Columns Space", 185, DefaultUIPositions.splitsColumnsSpace, ConfigurationFile.splitsColumnsSpace.Value.ToString(), hasResetButton: true); customSliderSplitsColumnsSpace.getGameObject().transform.SetParent(panel.transform, false); customSliderSplitsColumnsSpace.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderSplitsColumnsSpace.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsColumnsSpace.Value = (int)(value + 104f); }); customSliderSplitsRowsSpace = new CustomSlider("SplitsRowsSpace", 40, 256, new Vector2(150f, 10f), new Vector2(240f, 50f), 0, null, -186, "Splits Rows Space", 185, DefaultUIPositions.splitsRowsSpace, ConfigurationFile.splitsRowsSpace.Value.ToString(), hasResetButton: true); customSliderSplitsRowsSpace.getGameObject().transform.SetParent(panel.transform, false); customSliderSplitsRowsSpace.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderSplitsRowsSpace.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.splitsRowsSpace.Value = (int)value; }); customSliderFontSplits = new CustomSlider("FontSplitsSlider", 1, 256, new Vector2(150f, 10f), new Vector2(240f, 20f), 0, null, -186, "Splits Size", 185, DefaultUIPositions.fontSizeSplits, ConfigurationFile.fontSizeSplits.Value.ToString(), hasResetButton: true); customSliderFontSplits.OnValueChanged(delegate(float value) { Logger.Log("slider changed to " + value); customSliderFontSplits.updateTextValue(Utils.ToGlobalInvariantString(value)); ConfigurationFile.fontSizeSplits.Value = (int)value; }); } public static bool IsCreated() { return (Object)(object)panel != (Object)null; } public static bool IsVisible() { return (Object)(object)panel != (Object)null && panel.activeSelf; } public static void Show() { panel.SetActive(true); ((Component)((Component)Hud.instance).transform.Find("hudroot")).gameObject.SetActive(false); Menu.instance.Show(); resetConfirmDialog.resetConfirmDialog.SetActive(false); } public static void Hide(bool hideMenu = true) { panel.SetActive(false); ((Component)((Component)Hud.instance).transform.Find("hudroot")).gameObject.SetActive(true); resetConfirmDialog.showResetDialog(show: false); if (hideMenu) { Menu.instance.Hide(); } } } public static class SpeedrunTimer { private static bool painted = false; private static RectTransform rect; public static TextMeshProUGUI _text; private static GameObject goSplitsTimers; private static readonly List<Split> splits = new List<Split>(); private static bool splitsLoaded = false; private static double _lastRealtime; private static double _displayedTime; private static float _lastStatTime; public static void Create(Hud hud) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_text != (Object)null)) { GameObject val = new GameObject("SpeedrunTimerText", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(((Component)hud).transform, false); rect = val.GetComponent<RectTransform>(); rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(0f, 1f); rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = ConfigurationFile.positionTimer.Value; rect.sizeDelta = new Vector2(500f, 80f); _text = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)_text).fontSize = ConfigurationFile.fontSizeTimer.Value; ((TMP_Text)_text).alignment = (TextAlignmentOptions)513; ((TMP_Text)_text).font = ModUtils.getFontAsset("Valheim-Norse"); UpdateTimerUI(); splits.Clear(); } } public static void UpdateTimerUI() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) rect.anchoredPosition = new Vector2(ConfigurationFile.positionTimer.Value.x, ConfigurationFile.positionTimer.Value.y * -1f); ((TMP_Text)_text).fontSize = ConfigurationFile.fontSizeTimer.Value; ((Graphic)_text).color = ConfigurationFile.colorTimer.Value; Color value = ConfigurationFile.colorTimer.Value; if (HasPlayerDeadAlreadyInPermadeath()) { ((TMP_Text)_text).text = ModStatsUtils.GetSpeedrunKnownTextValue("TimerStopped"); value = ConfigurationFile.colorTimerAfterDyingInPermadeath.Value; } ((Graphic)_text).color = value; ((TMP_Text)_text).outlineColor = new Color32((byte)(value.r * 255f), (byte)(value.g * 255f), (byte)(value.b * 255f), byte.MaxValue); ((TMP_Text)_text).outlineWidth = ConfigurationFile.colorWidthTimer.Value; } private static void LoadSplits() { Logger.Log("Loading splits..."); string speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("Eikthyr"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for Eikthyr..."); splits.Add(new Split(BossNameEnum.Eikthyr, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("gd_king"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for The Elder..."); splits.Add(new Split(BossNameEnum.gd_king, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("Bonemass"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for Bonemass..."); splits.Add(new Split(BossNameEnum.Bonemass, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("Dragon"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for Moder..."); splits.Add(new Split(BossNameEnum.Dragon, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("GoblinKing"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for Yagluth..."); splits.Add(new Split(BossNameEnum.GoblinKing, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("SeekerQueen"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for The Queen..."); splits.Add(new Split(BossNameEnum.SeekerQueen, speedrunKnownTextValue)); } speedrunKnownTextValue = ModStatsUtils.GetSpeedrunKnownTextValue("Fader"); if (speedrunKnownTextValue != null) { Logger.Log("Found split for Fader..."); splits.Add(new Split(BossNameEnum.Fader, speedrunKnownTextValue)); } DrawSplits(); } public static void DrawSplits() { //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_00a7: 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_0180: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) Logger.Log("Drawing splits..."); goSplitsTimers = (GameObject)(((object)GameObject.Find("SpeedrunTimerSplits")) ?? ((object)new GameObject("SpeedrunTimerSplits", new Type[1] { typeof(RectTransform) }))); goSplitsTimers.transform.SetParent(((Component)Hud.instance).transform, false); goSplitsTimers.SetActive(ConfigurationFile.showSplits.Value); goSplitsTimers.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 950f); int num = (int)ConfigurationFile.positionSplits.Value.x - 900; int num2 = (int)ConfigurationFile.positionSplits.Value.y * -1 - 480; int num3 = num; int num4 = num2; int num5 = 0; foreach (Split split in splits) { string text = Localization.instance.Localize(split.BossName.GetTranslationKey()); Logger.Log("Drawing " + text + " split"); string text2 = "Split_" + text + "_Icon"; GameObject val = (GameObject)(((object)GameObject.Find(text2)) ?? ((object)new GameObject(text2, new Type[2] { typeof(RectTransform), typeof(Image) }))); val.transform.SetParent(goSplitsTimers.transform); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2((float)num3, (float)num4); component.sizeDelta = new Vector2(32f, 32f); Image component2 = val.GetComponent<Image>(); component2.sprite = ModUtils.getSprite(split.BossName.GetTrophySpriteKey()); string text3 = "Split_" + text + "_Time"; GameObject val2 = (GameObject)(((object)GameObject.Find(text3)) ?? ((object)new GameObject(text3, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }))); val2.transform.SetParent(goSplitsTimers.transform); RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 1f); component3.anchoredPosition = new Vector2((float)(num3 + 40), (float)num4); component3.sizeDelta = new Vector2(256f, 32f); TextMeshProUGUI component4 = val2.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component4).transform.SetParent(goSplitsTimers.transform); ((TMP_Text)component4).fontSize = ConfigurationFile.fontSizeSplits.Value; ((TMP_Text)component4).alignment = (TextAlignmentOptions)513; ((TMP_Text)component4).font = ModUtils.getFontAsset("Valheim-Norse"); ((Graphic)component4).color = ConfigurationFile.colorSplits.Value; ((TMP_Text)component4).outlineColor = new Color32((byte)(((Graphic)component4).color.r * 255f), (byte)(((Graphic)component4).color.g * 255f), (byte)(((Graphic)component4).color.b * 255f), byte.MaxValue); ((TMP_Text)component4).outlineWidth = ConfigurationFile.colorWidthSplits.Value; ((TMP_Text)component4).text = split.TimerValue; num5++; if (num5 == ConfigurationFile.splitsColumnSize.Value) { num3 = num + ConfigurationFile.splitsColumnsSpace.Value; num4 = num2; num5 = 0; } else { num4 -= ConfigurationFile.splitsRowsSpace.Value; } } } public static void UpdateVisibility() { if ((Object)(object)goSplitsTimers != (Object)null) { goSplitsTimers.SetActive(ConfigurationFile.showSplits.Value); } if ((Object)(object)rect != (Object)null) { ((Component)rect).gameObject.SetActive(ConfigurationFile.showTimer.Value); } } public static void Update() { if ((Object)(object)_text == (Object)null || (Object)(object)Game.instance == (Object)null) { return; } if (Time.timeScale == 0f) { _lastRealtime = Time.realtimeSinceStartupAsDouble; } else { if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } if (!splitsLoaded) { LoadSplits(); splitsLoaded = true; } UpdateVisibility(); if (painted && IsTimerStoppedInPermadeath()) { return; } if (!"true".Equals(ModStatsUtils.GetSpeedrunKnownTextValue("TimerStarted"))) { if (ConfigurationFile.countHuginnInitTravelAsPartOfTimer.Value) { Logger.Log("Starting speedrun..."); ModStatsUtils.SetSpeedrunKnownTextKeyValue("TimerStarted", "true"); } else { if (!((Character)Player.m_localPlayer).CanMove()) { return; } Logger.Log("Starting speedrun..."); ModStatsUtils.SetSpeedrunKnownTextKeyValue("TimerStarted", "true"); Dictionary<PlayerStatType, float> stats = ModStatsUtils.GetStats(); if (stats != null) { Utils.IncrementOrSet<PlayerStatType>(stats, (PlayerStatType)21, GeneralExtensions.GetValueSafe<PlayerStatType, float>(stats, (PlayerStatType)21) * -1f); Utils.IncrementOrSet<PlayerStatType>(stats, (PlayerStatType)22, GeneralExtensions.GetValueSafe<PlayerStatType, float>(stats, (PlayerStatType)22) * -1f); } _lastRealtime = Time.realtimeSinceStartupAsDouble; _displayedTime = 0.0; _lastStatTime = 0f; } } UpdateTimer(); UpdateTimerUI(); painted = true; } } public static void UpdateTimer() { float totalPlaytimeSeconds = GetTotalPlaytimeSeconds(); double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; double num = realtimeSinceStartupAsDouble - _lastRealtime; _lastRealtime = realtimeSinceStartupAsDouble; _displayedTime += Mathf.Min((float)num, 0.25f); if (totalPlaytimeSeconds > _lastStatTime) { _displayedTime = totalPlaytimeSeconds; _lastStatTime = totalPlaytimeSeconds; } ((TMP_Text)_text).text = ((!HasPlayerDeadAlreadyInPermadeath()) ? FormatTime((float)_displayedTime) : ModStatsUtils.GetSpeedrunKnownTextValue("TimerStopped")); } private static float GetTotalPlaytimeSeconds() { Dictionary<PlayerStatType, float> stats = ModStatsUtils.GetStats(); if (stats == null) { return 0f; } float valueSafe = GeneralExtensions.GetValueSafe<PlayerStatType, float>(stats, (PlayerStatType)21); float valueSafe2 = GeneralExtensions.GetValueSafe<PlayerStatType, float>(stats, (PlayerStatType)22); return valueSafe + valueSafe2; } private static string FormatTime(float seconds) { int num = Mathf.FloorToInt(seconds * 100f); int num2 = num / 100; int num3 = num2 % 60; int num4 = num2 / 60 % 60; int num5 = num2 / 3600; return $"{num5:D2}:{num4:D2}:{num3:D2}"; } public static bool IsCreated() { return (Object)(object)_text != (Object)null; } public static void AddSplitTimer(Split split) { int num = splits.FindIndex((Split s) => s.BossName.Equals(split.BossName)); if (num == -1) { splits.Add(split); DrawSplits(); } else if (ConfigurationFile.overrideBossSplitTimerIfKilledAgain.Value) { splits[num].TimerValue = split.TimerValue; DrawSplits(); } else { Logger.Log("Nothing to update."); } } public static void StopTimer() { if (!IsTimerStoppedInPermadeath()) { string text = FormatTime((float)_displayedTime); Logger.Log("Permadeath 1st kill timer to save: " + text); ModStatsUtils.SetSpeedrunKnownTextKeyValue("TimerStopped", text); UpdateTimer(); } else { Logger.Log("value already saved"); } UpdateTimerUI(); } private static bool IsTimerStoppedInPermadeath() { return ConfigurationFile.speedrunType.Value == SpeedrunType.Permadeath && ModStatsUtils.GetSpeedrunKnownTextValue("TimerStopped") != null; } private static bool HasPlayerDeadAlreadyInPermadeath() { return ConfigurationFile.speedrunType.Value == SpeedrunType.Permadeath && ZDOHelper.GetValueOrDefaultPiktiv<PlayerStatType, float>((IDictionary<PlayerStatType, float>)ModStatsUtils.GetStats(), (PlayerStatType)0, 0f) > 0f; } public static void ResetTimer() { Dictionary<PlayerStatType, float> stats = ModStatsUtils.GetStats(); stats[(PlayerStatType)21] = 0f; stats[(PlayerStatType)22] = 0f; stats[(PlayerStatType)0] = 0f; ModStatsUtils.SetSpeedrunKnownTextKeyValue("TimerStopped", null); GameObject val = GameObject.Find("SpeedrunTimerSplits"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } splits.Clear(); splitsLoaded = false; ZNet instance = ZNet.instance; string worldName = ((instance != null) ? instance.GetWorldName() : null); Dictionary<string, string> knownTexts = ModStatsUtils.GetKnownTexts(); List<string> list = knownTexts.Keys.ToList().FindAll((string k) => k.StartsWith("Turbero.SpeedrunManager_" + worldName + "_")); foreach (string item in list) { knownTexts.Remove(item); } ((TMP_Text)_text).text = "00:00:00"; UpdateTimerUI(); } } public class Split { public BossNameEnum BossName { get; } public string TimerValue { get; set; } public Split(BossNameEnum bossName, string timerValue) { BossName = bossName; TimerValue = timerValue; } } } namespace SpeedrunManager.Patches { [HarmonyPatch(typeof(Hud), "Update")] public static class Hud_Update_Patch { private static void Postfix(Hud __instance) { if (!SpeedrunConfigPanel.IsCreated()) { SpeedrunConfigPanel.Create(); } if (!SpeedrunTimer.IsCreated()) { SpeedrunTimer.Create(__instance); } SpeedrunTimer.Update(); } } [HarmonyPatch(typeof(Hud), "Awake")] public static class Hud_Awake_Patch { private static void Postfix(Hud __instance) { __instance.m_effectsPerRow = ConfigurationFile.effectsPerRow.Value; } } [HarmonyPatch(typeof(Character), "OnDeath")] public class RegisterBossDefeatPatch { [UsedImplicitly] public static void Postfix(Character __instance) { Logger.Log("Character OnDeath"); if (!((Object)(object)__instance == (Object)null) && __instance.IsBoss()) { string text = ((Object)__instance).name.Replace("(Clone)", ""); string text2 = ((TMP_Text)SpeedrunTimer._text).text; setupBossSplitTime(text, text2, overwrite: false); Logger.Log("Gonna parse " + text + "..."); BossNameEnum bossName = ModUtils.parseBossName(text); Split split = new Split(bossName, text2); SpeedrunTimer.AddSplitTimer(split); } } public static void setupBossSplitTime(string bossName, string timerValue, bool overwrite) { ZNet instance = ZNet.instance; string text = ((instance != null) ? instance.GetWorldName() : null); string key = "Turbero.SpeedrunManager_" + text + "_" + bossName; Dictionary<string, string> dictionary = (Dictionary<string, string>)ModUtils.GetPrivateValue(Player.m_localPlayer, "m_knownTexts"); if (!dictionary.ContainsKey(key)) { dictionary.Add(key, timerValue); } else if (overwrite) { dictionary.Remove(key); dictionary.Add(key, timerValue); } } } [HarmonyPatch(typeof(Player), "OnDeath")] public class PlayerDeathDefeatPatch { [UsedImplicitly] public static void Postfix(Player __instance) { Logger.Log("Player OnDeath"); if (!((Object)(object)__instance == (Object)null) && ConfigurationFile.speedrunType.Value == SpeedrunType.Permadeath) { SpeedrunTimer.StopTimer(); } } } }