using 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();
}
}
}
}