using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Alienpxgaming")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright © 2026 Alienpxgaming. All rights reserved.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("Alien's Speedrun Paths")]
[assembly: AssemblyTitle("AliensSpeedrunPaths")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[BepInPlugin("alien.runrecorder", "Run Path Recorder Compare Speed Kills", "9.3.0")]
public class Plugin : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <AutoStartAfterSceneLoad>d__67 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Plugin <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AutoStartAfterSceneLoad>d__67(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (!<>4__this.isRecording && (Object)(object)<>4__this.GetPlayerTransform() != (Object)null)
{
<>4__this.StartRecording();
<>4__this.SetStatus("AUTO RECORDING STARTED");
}
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();
}
}
private PluginConfigurator pluginConfig;
private EnumField<BindKey> recordKeyField;
private EnumField<BindKey> loadKeyField;
private EnumField<BindKey> autoStartKeyField;
private EnumField<BindKey> toggleGhostKeyField;
private EnumField<BindKey> clearKeyField;
private EnumField<BindKey> toggleTimeKeyField;
private EnumField<BindKey> menuKeyField;
private BoolField autoStartField;
private BoolField showActionTimesField;
private FloatField highHorizontalSpeedThresholdField;
private FloatField horizontalSpeedDropThresholdField;
private FloatField verticalSpeedThresholdField;
private FloatField routeDifferenceThresholdField;
private bool isRecording = false;
private bool ghostVisible = true;
private bool menuOpen = false;
private float recordTimer = 0f;
private float recordInterval = 0.08f;
private float checkpointScanTimer = 0f;
private float checkpointScanInterval = 0.3f;
private float checkpointDetectDistance = 5f;
private float enemyScanTimer = 0f;
private float enemyScanInterval = 0.25f;
private float speedEventTimer = 0f;
private float speedEventInterval = 0.45f;
private float lastSampledHorizontalSpeed = 0f;
private bool hasLastSpeedSample = false;
private float fallbackRecordStartTime;
private float hoverScreenRadius = 95f;
private float hoverMaxWorldDistance = 200f;
private float clusterDistance = 3f;
private float routeDifferenceSampleStep = 0.5f;
private float routeDifferenceCooldown = 2f;
private List<RunPoint> currentPoints = new List<RunPoint>();
private List<ActionPoint> currentActions = new List<ActionPoint>();
private List<CheckpointPoint> currentCheckpoints = new List<CheckpointPoint>();
private List<KillPoint> currentKills = new List<KillPoint>();
private List<SpeedMarkerPoint> currentSpeedMarkers = new List<SpeedMarkerPoint>();
private List<RunPoint> loadedAPoints = new List<RunPoint>();
private List<RunPoint> loadedBPoints = new List<RunPoint>();
private bool loadedA = false;
private bool loadedB = false;
private HashSet<string> touchedCheckpointIds = new HashSet<string>();
private Dictionary<int, EnemyTrack> trackedEnemies = new Dictionary<int, EnemyTrack>();
private readonly List<GameObject> ghostObjects = new List<GameObject>();
private readonly List<HoverMarker> hoverMarkers = new List<HoverMarker>();
private string saveFolder;
private string latestRunPath;
private string defaultRunColorHex = "#00FFFF";
private string activeColorFilter = "";
private ColorOption[] palette = new ColorOption[8]
{
new ColorOption("Cyan", "#00FFFF"),
new ColorOption("Pink", "#FF40FF"),
new ColorOption("Yellow", "#FFFF00"),
new ColorOption("Green", "#40FF40"),
new ColorOption("Red", "#FF4040"),
new ColorOption("Blue", "#4080FF"),
new ColorOption("Orange", "#FF9900"),
new ColorOption("White", "#FFFFFF")
};
private string screenStatus = "";
private float screenStatusTimer = 0f;
private GUIStyle keybindStyle;
private GUIStyle statusStyle;
private GUIStyle menuStyle;
private GUIStyle buttonStyle;
private GUIStyle smallStyle;
private GUIStyle selectedStyle;
private Vector2 menuScroll = Vector2.zero;
private List<RunFileEntry> runFiles = new List<RunFileEntry>();
private Dictionary<string, string> renameInputs = new Dictionary<string, string>();
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Run Path Recorder Compare Speed Kills loaded.");
CreatePluginConfiguratorMenu();
saveFolder = Path.Combine(Paths.PluginPath, "AlienRuns");
if (!Directory.Exists(saveFolder))
{
Directory.CreateDirectory(saveFolder);
}
latestRunPath = Path.Combine(saveFolder, "latest_run.txt");
SceneManager.activeSceneChanged += OnSceneChanged;
RefreshRunFiles();
SetStatus("RUN RECORDER LOADED");
}
private void CreatePluginConfiguratorMenu()
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Expected O, but got Unknown
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Expected O, but got Unknown
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Expected O, but got Unknown
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
pluginConfig = PluginConfigurator.Create("Run Path Recorder", "alien.runrecorder");
recordKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Start/Stop Recording Key", "key_start_stop_recording", BindKey.Semicolon);
loadKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Load Latest Run to A Key", "key_load_latest_run_to_a", BindKey.Quote);
autoStartKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Toggle Auto Start Key", "key_toggle_auto_start", BindKey.LeftBracket);
toggleGhostKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Show/Hide Loaded Runs Key", "key_show_hide_loaded_runs", BindKey.Comma);
clearKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Clear Loaded Runs Key", "key_clear_loaded_runs", BindKey.Period);
toggleTimeKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Toggle Dot Time Key", "key_toggle_dot_time", BindKey.Backslash);
menuKeyField = new EnumField<BindKey>(pluginConfig.rootPanel, "Open/Close Run Menu Key", "key_open_close_menu", BindKey.RightBracket);
autoStartField = new BoolField(pluginConfig.rootPanel, "Auto-start recording on level entry", "auto_start_recording", false);
showActionTimesField = new BoolField(pluginConfig.rootPanel, "Show dot run time text", "show_dot_time_text", true);
highHorizontalSpeedThresholdField = new FloatField(pluginConfig.rootPanel, "High horizontal speed threshold", "high_horizontal_speed_threshold", 35f);
horizontalSpeedDropThresholdField = new FloatField(pluginConfig.rootPanel, "Speed drop threshold", "horizontal_speed_drop_threshold", 18f);
verticalSpeedThresholdField = new FloatField(pluginConfig.rootPanel, "Vertical speed threshold", "vertical_speed_threshold", 12f);
routeDifferenceThresholdField = new FloatField(pluginConfig.rootPanel, "Route difference marker distance", "route_difference_threshold", 8f);
highHorizontalSpeedThresholdField.minimumValue = 0f;
highHorizontalSpeedThresholdField.maximumValue = 200f;
horizontalSpeedDropThresholdField.minimumValue = 0f;
horizontalSpeedDropThresholdField.maximumValue = 200f;
verticalSpeedThresholdField.minimumValue = 0f;
verticalSpeedThresholdField.maximumValue = 200f;
routeDifferenceThresholdField.minimumValue = 0f;
routeDifferenceThresholdField.maximumValue = 100f;
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnSceneChanged;
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (isRecording)
{
StopRecordingAndSave("LEVEL FINISHED / CHANGED - AUTO SAVED", levelFinished: true);
}
if (autoStartField.value)
{
((MonoBehaviour)this).StartCoroutine(AutoStartAfterSceneLoad());
}
}
[IteratorStateMachine(typeof(<AutoStartAfterSceneLoad>d__67))]
private IEnumerator AutoStartAfterSceneLoad()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AutoStartAfterSceneLoad>d__67(0)
{
<>4__this = this
};
}
private void Update()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(GetKey(recordKeyField, (KeyCode)59)))
{
ToggleRecording();
}
if (Input.GetKeyDown(GetKey(loadKeyField, (KeyCode)39)))
{
LoadLatestRunIntoSlot("A");
}
if (Input.GetKeyDown(GetKey(autoStartKeyField, (KeyCode)91)))
{
autoStartField.value = !autoStartField.value;
SetStatus(autoStartField.value ? "AUTO START RECORDING: ON" : "AUTO START RECORDING: OFF");
}
if (Input.GetKeyDown(GetKey(toggleGhostKeyField, (KeyCode)44)))
{
ToggleGhostVisibility();
}
if (Input.GetKeyDown(GetKey(clearKeyField, (KeyCode)46)))
{
ClearGhost();
loadedA = false;
loadedB = false;
SetStatus("GHOST CLEARED");
}
if (Input.GetKeyDown(GetKey(toggleTimeKeyField, (KeyCode)92)))
{
showActionTimesField.value = !showActionTimesField.value;
SetStatus(showActionTimesField.value ? "DOT TIME TEXT: ON" : "DOT TIME TEXT: OFF");
}
if (Input.GetKeyDown(GetKey(menuKeyField, (KeyCode)93)))
{
menuOpen = !menuOpen;
RefreshRunFiles();
SetStatus(menuOpen ? "RUN MENU OPENED" : "RUN MENU CLOSED");
}
if (isRecording)
{
RecordMovementTick();
RecordActions();
ScanCheckpoints();
TrackEnemyKills();
RecordSpeedEvents();
}
if (screenStatusTimer > 0f)
{
screenStatusTimer -= Time.deltaTime;
}
UpdateDotLookHover();
FaceHoverTextsToCamera();
}
private void OnGUI()
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
EnsureStyles();
string text = (isRecording ? "RECORDING: ON" : "RECORDING: OFF");
string text2 = (autoStartField.value ? "AUTO START: ON" : "AUTO START: OFF");
string text3 = (ghostVisible ? "LOADED RUNS: SHOWN" : "LOADED RUNS: HIDDEN");
string text4 = (showActionTimesField.value ? "DOT TIME: ON" : "DOT TIME: OFF");
string text5 = text + "\n" + text2 + "\n" + text3 + "\n" + text4 + "\n" + KeyText(GetKey(recordKeyField, (KeyCode)59)) + " Start/Stop Recording\n" + KeyText(GetKey(loadKeyField, (KeyCode)39)) + " Load Latest Run to A\n" + KeyText(GetKey(autoStartKeyField, (KeyCode)91)) + " Toggle Auto Start\n" + KeyText(GetKey(toggleGhostKeyField, (KeyCode)44)) + " Show/Hide Loaded Runs\n" + KeyText(GetKey(clearKeyField, (KeyCode)46)) + " Clear Loaded Runs\n" + KeyText(GetKey(toggleTimeKeyField, (KeyCode)92)) + " Toggle Dot Time\n" + KeyText(GetKey(menuKeyField, (KeyCode)93)) + " Open/Close Run Menu";
GUI.Label(new Rect(15f, (float)(Screen.height - 275), 620f, 275f), text5, keybindStyle);
if (screenStatusTimer > 0f && !string.IsNullOrEmpty(screenStatus))
{
GUI.Label(new Rect(15f, (float)(Screen.height - 320), 1300f, 40f), screenStatus, statusStyle);
}
if (menuOpen)
{
DrawRunMenu();
}
}
private KeyCode GetKey(EnumField<BindKey> field, KeyCode fallback)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (field == null)
{
return fallback;
}
return BindKeyToKeyCode(field.value, fallback);
}
private KeyCode BindKeyToKeyCode(BindKey bindKey, KeyCode fallback)
{
//IL_013d: 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_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01a3: 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_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_0229: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Unknown result type (might be due to invalid IL or missing references)
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
//IL_0271: 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_0281: Unknown result type (might be due to invalid IL or missing references)
//IL_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_0291: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0301: Unknown result type (might be due to invalid IL or missing references)
//IL_0309: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_0321: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_0331: Unknown result type (might be due to invalid IL or missing references)
//IL_033c: Unknown result type (might be due to invalid IL or missing references)
//IL_0341: Unknown result type (might be due to invalid IL or missing references)
//IL_0349: Unknown result type (might be due to invalid IL or missing references)
//IL_0351: Unknown result type (might be due to invalid IL or missing references)
//IL_0359: Unknown result type (might be due to invalid IL or missing references)
//IL_0361: Unknown result type (might be due to invalid IL or missing references)
//IL_0369: 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_0379: Unknown result type (might be due to invalid IL or missing references)
//IL_0381: Unknown result type (might be due to invalid IL or missing references)
//IL_0389: Unknown result type (might be due to invalid IL or missing references)
//IL_0391: Unknown result type (might be due to invalid IL or missing references)
//IL_0399: Unknown result type (might be due to invalid IL or missing references)
//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
return (KeyCode)(bindKey switch
{
BindKey.None => 0,
BindKey.Semicolon => 59,
BindKey.Quote => 39,
BindKey.LeftBracket => 91,
BindKey.RightBracket => 93,
BindKey.Backslash => 92,
BindKey.Comma => 44,
BindKey.Period => 46,
BindKey.Slash => 47,
BindKey.Minus => 45,
BindKey.Equals => 61,
BindKey.F1 => 282,
BindKey.F2 => 283,
BindKey.F3 => 284,
BindKey.F4 => 285,
BindKey.F5 => 286,
BindKey.F6 => 287,
BindKey.F7 => 288,
BindKey.F8 => 289,
BindKey.F9 => 290,
BindKey.F10 => 291,
BindKey.F11 => 292,
BindKey.F12 => 293,
BindKey.Alpha0 => 48,
BindKey.Alpha1 => 49,
BindKey.Alpha2 => 50,
BindKey.Alpha3 => 51,
BindKey.Alpha4 => 52,
BindKey.Alpha5 => 53,
BindKey.Alpha6 => 54,
BindKey.Alpha7 => 55,
BindKey.Alpha8 => 56,
BindKey.Alpha9 => 57,
BindKey.A => 97,
BindKey.B => 98,
BindKey.C => 99,
BindKey.D => 100,
BindKey.E => 101,
BindKey.F => 102,
BindKey.G => 103,
BindKey.H => 104,
BindKey.I => 105,
BindKey.J => 106,
BindKey.K => 107,
BindKey.L => 108,
BindKey.M => 109,
BindKey.N => 110,
BindKey.O => 111,
BindKey.P => 112,
BindKey.Q => 113,
BindKey.R => 114,
BindKey.S => 115,
BindKey.T => 116,
BindKey.U => 117,
BindKey.V => 118,
BindKey.W => 119,
BindKey.X => 120,
BindKey.Y => 121,
BindKey.Z => 122,
BindKey.Insert => 277,
BindKey.Delete => 127,
BindKey.Home => 278,
BindKey.End => 279,
BindKey.PageUp => 280,
BindKey.PageDown => 281,
BindKey.Keypad0 => 256,
BindKey.Keypad1 => 257,
BindKey.Keypad2 => 258,
BindKey.Keypad3 => 259,
BindKey.Keypad4 => 260,
BindKey.Keypad5 => 261,
BindKey.Keypad6 => 262,
BindKey.Keypad7 => 263,
BindKey.Keypad8 => 264,
BindKey.Keypad9 => 265,
_ => fallback,
});
}
private string KeyText(KeyCode key)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Invalid comparison between Unknown and I4
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Invalid comparison between Unknown and I4
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Invalid comparison between Unknown and I4
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Invalid comparison between Unknown and I4
if ((int)key == 59)
{
return ";";
}
if ((int)key == 39)
{
return "'";
}
if ((int)key == 91)
{
return "[";
}
if ((int)key == 93)
{
return "]";
}
if ((int)key == 92)
{
return "\\";
}
if ((int)key == 44)
{
return ",";
}
if ((int)key == 46)
{
return ".";
}
if ((int)key == 32)
{
return "Space";
}
return ((object)(KeyCode)(ref key)).ToString();
}
private void EnsureStyles()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_00cd: 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_00fc: Expected O, but got Unknown
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Expected O, but got Unknown
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Expected O, but got Unknown
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
if (keybindStyle == null)
{
keybindStyle = new GUIStyle(GUI.skin.label);
keybindStyle.fontSize = 18;
keybindStyle.normal.textColor = Color.white;
}
if (statusStyle == null)
{
statusStyle = new GUIStyle(GUI.skin.label);
statusStyle.fontSize = 24;
statusStyle.normal.textColor = Color.yellow;
}
if (menuStyle == null)
{
menuStyle = new GUIStyle(GUI.skin.box);
menuStyle.fontSize = 18;
menuStyle.normal.textColor = Color.white;
}
if (buttonStyle == null)
{
buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.fontSize = 15;
}
if (smallStyle == null)
{
smallStyle = new GUIStyle(GUI.skin.label);
smallStyle.fontSize = 14;
smallStyle.normal.textColor = Color.white;
}
if (selectedStyle == null)
{
selectedStyle = new GUIStyle(GUI.skin.label);
selectedStyle.fontSize = 18;
selectedStyle.normal.textColor = Color.white;
selectedStyle.alignment = (TextAnchor)4;
}
}
private void DrawRunMenu()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_0225: 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_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_0289: 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_02c0: Unknown result type (might be due to invalid IL or missing references)
//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
//IL_033a: Unknown result type (might be due to invalid IL or missing references)
//IL_0361: Unknown result type (might be due to invalid IL or missing references)
//IL_0390: Unknown result type (might be due to invalid IL or missing references)
//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
//IL_0402: Unknown result type (might be due to invalid IL or missing references)
//IL_0441: Unknown result type (might be due to invalid IL or missing references)
//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0546: Unknown result type (might be due to invalid IL or missing references)
//IL_0593: Unknown result type (might be due to invalid IL or missing references)
//IL_0689: Unknown result type (might be due to invalid IL or missing references)
//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
//IL_0636: Unknown result type (might be due to invalid IL or missing references)
//IL_0713: Unknown result type (might be due to invalid IL or missing references)
float num = 1030f;
float num2 = 640f;
float num3 = (float)Screen.width - num - 25f;
float num4 = 30f;
GUI.Box(new Rect(num3, num4, num, num2), "Saved Runs - Speed / Kills / Compare", menuStyle);
if (GUI.Button(new Rect(num3 + 20f, num4 + 35f, 110f, 32f), "Refresh", buttonStyle))
{
RefreshRunFiles();
}
GUI.Label(new Rect(num3 + 145f, num4 + 40f, 130f, 24f), "Filter:", smallStyle);
float num5 = num3 + 200f;
if (GUI.Button(new Rect(num5, num4 + 35f, 55f, 32f), "All", buttonStyle))
{
activeColorFilter = "";
RefreshRunFiles();
}
num5 += 65f;
for (int i = 0; i < palette.Length; i++)
{
ColorOption colorOption = palette[i];
if (DrawColorButton(new Rect(num5, num4 + 35f, 45f, 32f), colorOption.hex))
{
if (activeColorFilter == colorOption.hex)
{
activeColorFilter = "";
}
else
{
activeColorFilter = colorOption.hex;
}
RefreshRunFiles();
}
if (activeColorFilter == colorOption.hex)
{
GUI.Label(new Rect(num5 + 12f, num4 + 65f, 25f, 18f), "▲", selectedStyle);
}
num5 += 52f;
}
string text = (string.IsNullOrEmpty(activeColorFilter) ? "Showing: All" : ("Showing: " + GetColorName(activeColorFilter)));
GUI.Label(new Rect(num5 + 10f, num4 + 40f, 260f, 24f), text, smallStyle);
GUI.Label(new Rect(num3 + 20f, num4 + 82f, 950f, 24f), "Keybinds/settings are in Settings > PLUGIN CONFIG > Run Path Recorder.", smallStyle);
menuScroll = GUI.BeginScrollView(new Rect(num3 + 20f, num4 + 115f, num - 40f, num2 - 135f), menuScroll, new Rect(0f, 0f, num - 70f, Mathf.Max(500f, (float)runFiles.Count * 150f)));
float num6 = 0f;
if (runFiles.Count == 0)
{
GUI.Label(new Rect(0f, 0f, 600f, 30f), "No runs found for this filter.", smallStyle);
}
Rect rect = default(Rect);
for (int j = 0; j < runFiles.Count; j++)
{
RunFileEntry runFileEntry = runFiles[j];
GUI.Box(new Rect(0f, num6, num - 80f, 140f), "");
GUI.Label(new Rect(10f, num6 + 8f, 410f, 22f), runFileEntry.displayName, smallStyle);
GUI.Label(new Rect(10f, num6 + 32f, 410f, 22f), "Saved: " + runFileEntry.savedTime, smallStyle);
GUI.Label(new Rect(10f, num6 + 56f, 410f, 22f), "Status: " + runFileEntry.finishStatus, smallStyle);
GUI.Label(new Rect(10f, num6 + 80f, 410f, 22f), "Color: " + GetColorName(runFileEntry.colorHex), smallStyle);
GUI.Label(new Rect(10f, num6 + 104f, 410f, 22f), runFileEntry.fileName, smallStyle);
if (!renameInputs.ContainsKey(runFileEntry.path))
{
renameInputs[runFileEntry.path] = runFileEntry.displayName;
}
renameInputs[runFileEntry.path] = GUI.TextField(new Rect(430f, num6 + 10f, 180f, 30f), renameInputs[runFileEntry.path]);
if (GUI.Button(new Rect(620f, num6 + 10f, 90f, 30f), "Rename", buttonStyle))
{
RenameRun(runFileEntry.path, renameInputs[runFileEntry.path]);
RefreshRunFiles();
}
GUI.Label(new Rect(430f, num6 + 50f, 70f, 24f), "Color:", smallStyle);
float num7 = 500f;
for (int k = 0; k < palette.Length; k++)
{
ColorOption colorOption2 = palette[k];
((Rect)(ref rect))..ctor(num7, num6 + 47f, 48f, 34f);
if (DrawColorButton(rect, colorOption2.hex))
{
ChangeRunColor(runFileEntry.path, colorOption2.hex);
runFileEntry.colorHex = colorOption2.hex;
runFiles[j].colorHex = colorOption2.hex;
SetStatus("RUN COLOR SET TO " + GetColorName(colorOption2.hex));
}
if (runFileEntry.colorHex == colorOption2.hex)
{
GUI.Label(new Rect(num7 + 15f, num6 + 80f, 25f, 18f), "▲", selectedStyle);
}
num7 += 55f;
}
if (GUI.Button(new Rect(430f, num6 + 100f, 95f, 30f), "Load A", buttonStyle))
{
LoadRunFile(runFileEntry.path, "A");
}
if (GUI.Button(new Rect(535f, num6 + 100f, 95f, 30f), "Load B", buttonStyle))
{
LoadRunFile(runFileEntry.path, "B");
}
if (GUI.Button(new Rect(640f, num6 + 100f, 130f, 30f), "Set Latest", buttonStyle))
{
CopyToLatest(runFileEntry.path);
SetStatus("SET AS LATEST RUN");
}
num6 += 150f;
}
GUI.EndScrollView();
}
private bool DrawColorButton(Rect rect, string hex)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
Color backgroundColor = GUI.backgroundColor;
Color white = default(Color);
if (!ColorUtility.TryParseHtmlString(hex, ref white))
{
white = Color.white;
}
GUI.backgroundColor = white;
bool result = GUI.Button(rect, "");
GUI.backgroundColor = backgroundColor;
return result;
}
private string GetColorName(string hex)
{
for (int i = 0; i < palette.Length; i++)
{
if (palette[i].hex == hex)
{
return palette[i].name;
}
}
return hex;
}
private Material MakeMaterial(string hex)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
Shader val = Shader.Find("Sprites/Default");
Material val2 = new Material(val);
Color cyan = default(Color);
if (!ColorUtility.TryParseHtmlString(hex, ref cyan))
{
cyan = Color.cyan;
}
val2.color = cyan;
return val2;
}
private Material MakeMaterialColor(Color color)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
Shader val = Shader.Find("Sprites/Default");
Material val2 = new Material(val);
val2.color = color;
return val2;
}
private Color HexToColor(string hex)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
Color result = default(Color);
if (!ColorUtility.TryParseHtmlString(hex, ref result))
{
return Color.cyan;
}
return result;
}
private void UpdateDotLookHover()
{
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
if (!ghostVisible)
{
HideAllHoverTexts();
return;
}
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
return;
}
HideAllHoverTexts();
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor((float)Screen.width / 2f, (float)Screen.height / 2f);
HoverMarker hoverMarker = null;
float num = 999999f;
Vector2 val3 = default(Vector2);
foreach (HoverMarker hoverMarker2 in hoverMarkers)
{
if (hoverMarker2 == null || (Object)(object)hoverMarker2.dotObject == (Object)null || (Object)(object)hoverMarker2.textObject == (Object)null || !hoverMarker2.dotObject.activeInHierarchy)
{
continue;
}
Vector3 position = hoverMarker2.dotObject.transform.position;
float num2 = Vector3.Distance(((Component)main).transform.position, position);
if (num2 > hoverMaxWorldDistance)
{
continue;
}
Vector3 val2 = main.WorldToScreenPoint(position);
if (!(val2.z <= 0f))
{
((Vector2)(ref val3))..ctor(val2.x, val2.y);
float num3 = Vector2.Distance(val, val3);
if (num3 <= hoverScreenRadius && num3 < num)
{
hoverMarker = hoverMarker2;
num = num3;
}
}
}
if (hoverMarker != null)
{
hoverMarker.textMesh.text = BuildHoverText(hoverMarker);
hoverMarker.textObject.SetActive(true);
}
}
private void HideAllHoverTexts()
{
foreach (HoverMarker hoverMarker in hoverMarkers)
{
if (hoverMarker != null && (Object)(object)hoverMarker.textObject != (Object)null)
{
hoverMarker.textObject.SetActive(false);
}
}
}
private string BuildHoverText(HoverMarker marker)
{
if (showActionTimesField.value)
{
return marker.label + "\nRun Time: " + marker.timeText;
}
return marker.label;
}
private void FaceHoverTextsToCamera()
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
return;
}
foreach (HoverMarker hoverMarker in hoverMarkers)
{
if (hoverMarker != null && !((Object)(object)hoverMarker.textObject == (Object)null) && hoverMarker.textObject.activeSelf)
{
hoverMarker.textObject.transform.rotation = Quaternion.LookRotation(hoverMarker.textObject.transform.position - ((Component)main).transform.position);
}
}
}
private void SetStatus(string message)
{
screenStatus = message;
screenStatusTimer = 5f;
((BaseUnityPlugin)this).Logger.LogInfo((object)message);
}
private void ToggleRecording()
{
if (!isRecording)
{
StartRecording();
}
else
{
StopRecordingAndSave("RECORDING SAVED", levelFinished: false);
}
}
private void StartRecording()
{
Transform playerTransform = GetPlayerTransform();
if ((Object)(object)playerTransform == (Object)null)
{
SetStatus("CANNOT START: NO PLAYER/CAMERA");
return;
}
currentPoints = new List<RunPoint>();
currentActions = new List<ActionPoint>();
currentCheckpoints = new List<CheckpointPoint>();
currentKills = new List<KillPoint>();
currentSpeedMarkers = new List<SpeedMarkerPoint>();
touchedCheckpointIds = new HashSet<string>();
trackedEnemies = new Dictionary<int, EnemyTrack>();
fallbackRecordStartTime = Time.time;
recordTimer = 0f;
checkpointScanTimer = 0f;
enemyScanTimer = 0f;
speedEventTimer = 0f;
lastSampledHorizontalSpeed = 0f;
hasLastSpeedSample = false;
isRecording = true;
RecordMovementPointNow();
TrackEnemyKills();
SetStatus("RECORDING STARTED");
}
private void StopRecordingAndSave(string statusMessage, bool levelFinished)
{
isRecording = false;
RecordMovementPointNow();
string text = SaveRunTXT(levelFinished);
SetStatus(statusMessage + " | " + currentPoints.Count + " POINTS / " + currentActions.Count + " ACTIONS / " + currentKills.Count + " KILLS / " + currentSpeedMarkers.Count + " SPEED DOTS");
if (!string.IsNullOrEmpty(text))
{
CopyToLatest(text);
}
RefreshRunFiles();
}
private Transform GetPlayerTransform()
{
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
return ((Component)main).transform;
}
GameObject val = GameObject.Find("Player");
if ((Object)(object)val != (Object)null)
{
return val.transform;
}
return null;
}
private float GetRunTimerSeconds()
{
if (TryFindUltrakillTimer(out var timer))
{
return timer;
}
return Time.time - fallbackRecordStartTime;
}
private bool TryFindUltrakillTimer(out float timer)
{
timer = 0f;
GameObject[] array = Object.FindObjectsOfType<GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
{
continue;
}
string text = ((Object)val).name.ToLower();
if (!text.Contains("timer") && !text.Contains("time") && !text.Contains("rank") && !text.Contains("stats") && !text.Contains("hud"))
{
continue;
}
Component[] components = val.GetComponents<Component>();
Component[] array3 = components;
foreach (Component val2 in array3)
{
if (!((Object)(object)val2 == (Object)null) && TryReadTimerFromComponent(val2, out timer))
{
return true;
}
}
}
return false;
}
private bool TryReadTimerFromComponent(Component component, out float timer)
{
timer = 0f;
Type type = ((object)component).GetType();
string text = type.Name.ToLower();
if (!text.Contains("timer") && !text.Contains("time") && !text.Contains("rank") && !text.Contains("stats") && !text.Contains("hud"))
{
return false;
}
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
FieldInfo[] fields = type.GetFields(bindingAttr);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
string text2 = fieldInfo.Name.ToLower();
switch (text2)
{
default:
if (!text2.Contains("leveltime") && !text2.Contains("currenttime") && !text2.Contains("seconds") && !text2.Contains("timer"))
{
continue;
}
break;
case "time":
case "timer":
case "currenttime":
case "leveltime":
case "seconds":
break;
}
object value;
try
{
value = fieldInfo.GetValue(component);
}
catch
{
continue;
}
if (TryConvertToFloat(value, out timer) && timer >= 0f && timer < 99999f)
{
return true;
}
}
PropertyInfo[] properties = type.GetProperties(bindingAttr);
PropertyInfo[] array2 = properties;
foreach (PropertyInfo propertyInfo in array2)
{
if (!propertyInfo.CanRead)
{
continue;
}
string text3 = propertyInfo.Name.ToLower();
switch (text3)
{
default:
if (!text3.Contains("leveltime") && !text3.Contains("currenttime") && !text3.Contains("seconds") && !text3.Contains("timer"))
{
continue;
}
break;
case "time":
case "timer":
case "currenttime":
case "leveltime":
case "seconds":
break;
}
object value2;
try
{
value2 = propertyInfo.GetValue(component, null);
}
catch
{
continue;
}
if (!TryConvertToFloat(value2, out timer) || !(timer >= 0f) || !(timer < 99999f))
{
continue;
}
return true;
}
return false;
}
private bool TryConvertToFloat(object value, out float result)
{
if (value is float num)
{
result = num;
return true;
}
if (value is int num2)
{
result = num2;
return true;
}
if (value is double num3)
{
result = (float)num3;
return true;
}
result = 0f;
return false;
}
private void RecordMovementTick()
{
recordTimer += Time.deltaTime;
if (!(recordTimer < recordInterval))
{
recordTimer = 0f;
RecordMovementPointNow();
}
}
private void RecordMovementPointNow()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Transform playerTransform = GetPlayerTransform();
if (!((Object)(object)playerTransform == (Object)null))
{
Vector3 position = playerTransform.position;
RunPoint runPoint = new RunPoint();
runPoint.time = GetRunTimerSeconds();
runPoint.x = position.x;
runPoint.y = position.y;
runPoint.z = position.z;
currentPoints.Add(runPoint);
}
}
private void RecordSpeedEvents()
{
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
speedEventTimer += Time.deltaTime;
if (speedEventTimer < speedEventInterval)
{
return;
}
speedEventTimer = 0f;
if (currentPoints == null || currentPoints.Count < 2)
{
return;
}
RunPoint runPoint = currentPoints[currentPoints.Count - 1];
int index = Mathf.Max(0, currentPoints.Count - 8);
RunPoint runPoint2 = currentPoints[index];
float num = Mathf.Max(0.01f, runPoint.time - runPoint2.time);
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
Vector3 val2 = default(Vector3);
((Vector3)(ref val2))..ctor(runPoint.x, runPoint.y, runPoint.z);
Vector3 val3 = val2 - val;
Vector2 val4 = default(Vector2);
((Vector2)(ref val4))..ctor(val3.x, val3.z);
float num2 = ((Vector2)(ref val4)).magnitude / num;
float num3 = val3.y / num;
string text = "";
if (num2 >= highHorizontalSpeedThresholdField.value)
{
text = "HIGH SPEED";
}
if (hasLastSpeedSample)
{
float num4 = lastSampledHorizontalSpeed - num2;
if (num4 >= horizontalSpeedDropThresholdField.value)
{
if (text.Length > 0)
{
text += " + ";
}
text += "SPEED DROP";
}
}
if (Mathf.Abs(num3) >= verticalSpeedThresholdField.value)
{
if (text.Length > 0)
{
text += " + ";
}
text += ((num3 > 0f) ? "VERT UP" : "VERT DOWN");
}
lastSampledHorizontalSpeed = num2;
hasLastSpeedSample = true;
if (text.Length != 0)
{
SpeedMarkerPoint speedMarkerPoint = new SpeedMarkerPoint();
speedMarkerPoint.time = runPoint.time;
speedMarkerPoint.x = runPoint.x;
speedMarkerPoint.y = runPoint.y;
speedMarkerPoint.z = runPoint.z;
speedMarkerPoint.horizontalSpeed = num2;
speedMarkerPoint.verticalSpeed = num3;
speedMarkerPoint.label = text;
currentSpeedMarkers.Add(speedMarkerPoint);
}
}
private void RecordActions()
{
Camera main = Camera.main;
if (!((Object)(object)main == (Object)null))
{
string currentWeaponName = GetCurrentWeaponName();
if (Input.GetMouseButtonDown(0))
{
RecordActionMarker(main, currentWeaponName + " PRIMARY");
}
if (Input.GetMouseButtonDown(1))
{
RecordActionMarker(main, currentWeaponName + " ALT");
}
if (Input.GetMouseButtonDown(2))
{
RecordActionMarker(main, currentWeaponName + " MIDDLE");
}
if (Input.GetKeyDown((KeyCode)114))
{
RecordActionMarker(main, currentWeaponName + " R");
}
if (Input.GetKeyDown((KeyCode)102))
{
RecordActionMarker(main, "PUNCH / MELEE");
}
}
}
private void RecordActionMarker(Camera cam, string label)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_0068: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = ((Component)cam).transform.position;
Vector3 forward = ((Component)cam).transform.forward;
ActionPoint actionPoint = new ActionPoint();
actionPoint.time = GetRunTimerSeconds();
actionPoint.x = position.x;
actionPoint.y = position.y;
actionPoint.z = position.z;
actionPoint.dx = forward.x;
actionPoint.dy = forward.y;
actionPoint.dz = forward.z;
actionPoint.label = label;
currentActions.Add(actionPoint);
}
private void ScanCheckpoints()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0213: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
checkpointScanTimer += Time.deltaTime;
if (checkpointScanTimer < checkpointScanInterval)
{
return;
}
checkpointScanTimer = 0f;
Transform playerTransform = GetPlayerTransform();
if ((Object)(object)playerTransform == (Object)null)
{
return;
}
Vector3 position = playerTransform.position;
GameObject[] array = Object.FindObjectsOfType<GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if ((Object)(object)val == (Object)null || !val.activeInHierarchy)
{
continue;
}
string text = ((Object)val).name.ToLower();
string text2 = "";
try
{
text2 = val.tag.ToLower();
}
catch
{
}
if (!text.Contains("checkpoint") && !text.Contains("check point") && !text2.Contains("checkpoint"))
{
continue;
}
float num = Vector3.Distance(position, val.transform.position);
if (!(num > checkpointDetectDistance))
{
string item = ((Object)val).name + "_" + Mathf.RoundToInt(val.transform.position.x) + "_" + Mathf.RoundToInt(val.transform.position.y) + "_" + Mathf.RoundToInt(val.transform.position.z);
if (!touchedCheckpointIds.Contains(item))
{
touchedCheckpointIds.Add(item);
CheckpointPoint checkpointPoint = new CheckpointPoint();
checkpointPoint.time = GetRunTimerSeconds();
checkpointPoint.x = val.transform.position.x;
checkpointPoint.y = val.transform.position.y;
checkpointPoint.z = val.transform.position.z;
checkpointPoint.label = "CHECKPOINT";
currentCheckpoints.Add(checkpointPoint);
SetStatus("CHECKPOINT RECORDED");
}
}
}
}
private void TrackEnemyKills()
{
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
enemyScanTimer += Time.deltaTime;
if (enemyScanTimer < enemyScanInterval)
{
return;
}
enemyScanTimer = 0f;
HashSet<int> hashSet = new HashSet<int>();
GameObject[] array = (GameObject[])(object)new GameObject[0];
try
{
array = GameObject.FindGameObjectsWithTag("Enemy");
}
catch
{
return;
}
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (!((Object)(object)val == (Object)null) && val.activeInHierarchy)
{
int instanceID = ((Object)val).GetInstanceID();
hashSet.Add(instanceID);
if (!trackedEnemies.ContainsKey(instanceID))
{
EnemyTrack enemyTrack = new EnemyTrack();
enemyTrack.id = instanceID;
enemyTrack.name = ((Object)val).name.Replace("(Clone)", "").Trim();
enemyTrack.lastPosition = val.transform.position;
enemyTrack.lastSeenTime = GetRunTimerSeconds();
trackedEnemies[instanceID] = enemyTrack;
}
else
{
EnemyTrack enemyTrack2 = trackedEnemies[instanceID];
enemyTrack2.lastPosition = val.transform.position;
enemyTrack2.lastSeenTime = GetRunTimerSeconds();
trackedEnemies[instanceID] = enemyTrack2;
}
}
}
List<int> list = new List<int>();
foreach (KeyValuePair<int, EnemyTrack> trackedEnemy in trackedEnemies)
{
int key = trackedEnemy.Key;
if (!hashSet.Contains(key))
{
list.Add(key);
}
}
foreach (int item in list)
{
EnemyTrack enemyTrack3 = trackedEnemies[item];
trackedEnemies.Remove(item);
KillPoint killPoint = new KillPoint();
killPoint.time = GetRunTimerSeconds();
killPoint.x = enemyTrack3.lastPosition.x;
killPoint.y = enemyTrack3.lastPosition.y;
killPoint.z = enemyTrack3.lastPosition.z;
killPoint.label = "KILL: " + enemyTrack3.name;
currentKills.Add(killPoint);
}
}
private string GetCurrentWeaponName()
{
GameObject[] array = Object.FindObjectsOfType<GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (!((Object)(object)val == (Object)null) && val.activeInHierarchy)
{
string text = ((Object)val).name.ToLower();
if (text.Contains("revolver") || text.Contains("shotgun") || text.Contains("nailgun") || text.Contains("railcannon") || text.Contains("rocket") || text.Contains("sawblade"))
{
return ((Object)val).name.Replace("(Clone)", "").Trim();
}
}
}
return "WEAPON";
}
private string SaveRunTXT(bool levelFinished)
{
string text = "Run_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string text2 = Path.Combine(saveFolder, text + ".txt");
WriteRunFile(text2, text, levelFinished, defaultRunColorHex, currentPoints, currentActions, currentCheckpoints, currentKills, currentSpeedMarkers);
return text2;
}
private void WriteRunFile(string path, string displayName, bool levelFinished, string colorHex, List<RunPoint> points, List<ActionPoint> actions, List<CheckpointPoint> checkpoints, List<KillPoint> kills, List<SpeedMarkerPoint> speedMarkers)
{
//IL_0050: 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)
using StreamWriter streamWriter = new StreamWriter(path, append: false);
streamWriter.WriteLine("RUNRECORDER_V11_PLUGINCONFIGURATOR");
streamWriter.WriteLine("NAME|" + displayName.Replace("|", "/"));
streamWriter.WriteLine("COLOR|" + colorHex);
Scene activeScene = SceneManager.GetActiveScene();
streamWriter.WriteLine("SCENE|" + ((Scene)(ref activeScene)).name);
streamWriter.WriteLine("SAVED|" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
streamWriter.WriteLine("FINISHED|" + (levelFinished ? "YES" : "NO"));
streamWriter.WriteLine("POINTS|" + points.Count);
foreach (RunPoint point in points)
{
streamWriter.WriteLine("P|" + F(point.time) + "|" + F(point.x) + "|" + F(point.y) + "|" + F(point.z));
}
streamWriter.WriteLine("ACTIONS|" + actions.Count);
foreach (ActionPoint action in actions)
{
streamWriter.WriteLine("A|" + F(action.time) + "|" + F(action.x) + "|" + F(action.y) + "|" + F(action.z) + "|" + F(action.dx) + "|" + F(action.dy) + "|" + F(action.dz) + "|" + action.label.Replace("|", "/"));
}
streamWriter.WriteLine("CHECKPOINTS|" + checkpoints.Count);
foreach (CheckpointPoint checkpoint in checkpoints)
{
streamWriter.WriteLine("C|" + F(checkpoint.time) + "|" + F(checkpoint.x) + "|" + F(checkpoint.y) + "|" + F(checkpoint.z) + "|" + checkpoint.label.Replace("|", "/"));
}
streamWriter.WriteLine("KILLS|" + kills.Count);
foreach (KillPoint kill in kills)
{
streamWriter.WriteLine("K|" + F(kill.time) + "|" + F(kill.x) + "|" + F(kill.y) + "|" + F(kill.z) + "|" + kill.label.Replace("|", "/"));
}
streamWriter.WriteLine("SPEEDMARKERS|" + speedMarkers.Count);
foreach (SpeedMarkerPoint speedMarker in speedMarkers)
{
streamWriter.WriteLine("S|" + F(speedMarker.time) + "|" + F(speedMarker.x) + "|" + F(speedMarker.y) + "|" + F(speedMarker.z) + "|" + F(speedMarker.horizontalSpeed) + "|" + F(speedMarker.verticalSpeed) + "|" + speedMarker.label.Replace("|", "/"));
}
}
private void CopyToLatest(string path)
{
if (File.Exists(path))
{
File.Copy(path, latestRunPath, overwrite: true);
}
}
private void LoadLatestRunIntoSlot(string slot)
{
if (!File.Exists(latestRunPath))
{
SetStatus("NO latest_run.txt FOUND");
}
else
{
LoadRunFile(latestRunPath, slot);
}
}
private void LoadRunFile(string path, string slot)
{
if (!File.Exists(path))
{
SetStatus("RUN FILE NOT FOUND");
return;
}
ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string _, out string colorHex, out bool _);
DrawRun(points, actions, checkpoints, kills, speedMarkers, slot, displayName, colorHex);
}
private void ReadRunFile(string path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string savedTime, out string colorHex, out bool levelFinished)
{
points = new List<RunPoint>();
actions = new List<ActionPoint>();
checkpoints = new List<CheckpointPoint>();
kills = new List<KillPoint>();
speedMarkers = new List<SpeedMarkerPoint>();
displayName = Path.GetFileNameWithoutExtension(path);
savedTime = File.GetLastWriteTime(path).ToString("yyyy-MM-dd HH:mm:ss");
colorHex = defaultRunColorHex;
levelFinished = false;
string[] array = File.ReadAllLines(path);
string[] array2 = array;
foreach (string text in array2)
{
if (string.IsNullOrWhiteSpace(text))
{
continue;
}
string[] array3 = text.Split('|');
if (array3.Length != 0)
{
if (array3[0] == "NAME" && array3.Length >= 2)
{
displayName = array3[1];
}
if (array3[0] == "COLOR" && array3.Length >= 2)
{
colorHex = array3[1];
}
if (array3[0] == "SAVED" && array3.Length >= 2)
{
savedTime = array3[1];
}
if (array3[0] == "FINISHED" && array3.Length >= 2)
{
levelFinished = array3[1] == "YES";
}
if (array3[0] == "P" && array3.Length >= 5)
{
RunPoint runPoint = new RunPoint();
runPoint.time = Parse(array3[1]);
runPoint.x = Parse(array3[2]);
runPoint.y = Parse(array3[3]);
runPoint.z = Parse(array3[4]);
points.Add(runPoint);
}
if (array3[0] == "A" && array3.Length >= 9)
{
ActionPoint actionPoint = new ActionPoint();
actionPoint.time = Parse(array3[1]);
actionPoint.x = Parse(array3[2]);
actionPoint.y = Parse(array3[3]);
actionPoint.z = Parse(array3[4]);
actionPoint.dx = Parse(array3[5]);
actionPoint.dy = Parse(array3[6]);
actionPoint.dz = Parse(array3[7]);
actionPoint.label = array3[8];
actions.Add(actionPoint);
}
if (array3[0] == "C" && array3.Length >= 6)
{
CheckpointPoint checkpointPoint = new CheckpointPoint();
checkpointPoint.time = Parse(array3[1]);
checkpointPoint.x = Parse(array3[2]);
checkpointPoint.y = Parse(array3[3]);
checkpointPoint.z = Parse(array3[4]);
checkpointPoint.label = array3[5];
checkpoints.Add(checkpointPoint);
}
if (array3[0] == "K" && array3.Length >= 6)
{
KillPoint killPoint = new KillPoint();
killPoint.time = Parse(array3[1]);
killPoint.x = Parse(array3[2]);
killPoint.y = Parse(array3[3]);
killPoint.z = Parse(array3[4]);
killPoint.label = array3[5];
kills.Add(killPoint);
}
if (array3[0] == "S" && array3.Length >= 8)
{
SpeedMarkerPoint speedMarkerPoint = new SpeedMarkerPoint();
speedMarkerPoint.time = Parse(array3[1]);
speedMarkerPoint.x = Parse(array3[2]);
speedMarkerPoint.y = Parse(array3[3]);
speedMarkerPoint.z = Parse(array3[4]);
speedMarkerPoint.horizontalSpeed = Parse(array3[5]);
speedMarkerPoint.verticalSpeed = Parse(array3[6]);
speedMarkerPoint.label = array3[7];
speedMarkers.Add(speedMarkerPoint);
}
}
}
}
private void DrawRun(List<RunPoint> points, List<ActionPoint> actions, List<CheckpointPoint> checkpoints, List<KillPoint> kills, List<SpeedMarkerPoint> speedMarkers, string slot, string displayName, string colorHex)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
ClearGhostSlot(slot);
ClearGhostSlot("DIFF");
Material runMat = MakeMaterial(colorHex);
Color baseColor = HexToColor(colorHex);
SetStatus("LOADED " + slot + ": " + points.Count + " POINTS / " + actions.Count + " ACTIONS / " + kills.Count + " KILLS / " + speedMarkers.Count + " SPEED DOTS");
DrawSpeedMovementPath(points, baseColor, slot);
DrawClusteredActionDots(actions, runMat, slot, displayName);
DrawCheckpointDots(checkpoints, runMat, slot, displayName);
DrawKillDots(kills, runMat, slot, displayName);
DrawSpeedMarkerDots(speedMarkers, slot);
if (slot == "A")
{
loadedAPoints = points;
loadedA = true;
}
if (slot == "B")
{
loadedBPoints = points;
loadedB = true;
}
if (loadedA && loadedB)
{
DrawRouteDifferenceMarkers();
}
ghostVisible = true;
SetGhostVisibility(visible: true);
}
private void DrawSpeedMovementPath(List<RunPoint> points, Color baseColor, string slot)
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
if (points == null || points.Count < 2)
{
SetStatus("NO PATH POINTS RECORDED");
return;
}
Vector3 val = default(Vector3);
Vector3 val2 = default(Vector3);
for (int i = 0; i < points.Count - 1; i++)
{
RunPoint runPoint = points[i];
RunPoint runPoint2 = points[i + 1];
((Vector3)(ref val))..ctor(runPoint.x, runPoint.y, runPoint.z);
((Vector3)(ref val2))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
float num = Mathf.Max(0.01f, runPoint2.time - runPoint.time);
float num2 = Vector3.Distance(val, val2) / num;
float num3 = Mathf.InverseLerp(5f, 60f, num2);
Color val3 = baseColor * 0.35f;
val3.a = 1f;
Color color = Color.Lerp(val3, baseColor, num3);
float num4 = Mathf.Lerp(0.08f, 0.34f, num3);
GameObject val4 = new GameObject("Alien Speed Path Segment " + slot);
val4.AddComponent<GhostSlot>().slot = slot;
ghostObjects.Add(val4);
LineRenderer val5 = val4.AddComponent<LineRenderer>();
val5.positionCount = 2;
val5.startWidth = num4;
val5.endWidth = num4;
((Renderer)val5).material = MakeMaterialColor(color);
val5.useWorldSpace = true;
val5.SetPosition(0, val);
val5.SetPosition(1, val2);
}
}
private void DrawClusteredActionDots(List<ActionPoint> actions, Material runMat, string slot, string runName)
{
//IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: 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_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
if (actions == null)
{
return;
}
List<ActionCluster> list = BuildActionClusters(actions);
foreach (ActionCluster item in list)
{
Vector3 val = item.AveragePosition();
Vector3 val2 = item.AverageDirection();
if (val2 == Vector3.zero)
{
val2 = Vector3.forward;
}
Vector3 val3 = val + val2 * 5f;
GameObject val4 = new GameObject("Alien Action Direction Line " + slot);
val4.AddComponent<GhostSlot>().slot = slot;
ghostObjects.Add(val4);
LineRenderer val5 = val4.AddComponent<LineRenderer>();
val5.positionCount = 2;
val5.startWidth = 0.06f;
val5.endWidth = 0.02f;
((Renderer)val5).material = runMat;
val5.useWorldSpace = true;
val5.SetPosition(0, val);
val5.SetPosition(1, val3);
CreateHoverDot(val, Vector3.one * 0.8f, runMat, slot, "[" + slot + "] " + BuildClusterLabel(item), BuildClusterTimeText(item), 1.25f);
}
}
private void DrawCheckpointDots(List<CheckpointPoint> checkpoints, Material runMat, string slot, string runName)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
if (checkpoints == null)
{
return;
}
foreach (CheckpointPoint checkpoint in checkpoints)
{
Vector3 pos = new Vector3(checkpoint.x, checkpoint.y, checkpoint.z) + Vector3.up * 0.5f;
CreateHoverDot(pos, Vector3.one * 1f, runMat, slot, "[" + slot + "] CHECKPOINT", FormatTime(checkpoint.time), 1.35f);
}
}
private void DrawKillDots(List<KillPoint> kills, Material runMat, string slot, string runName)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
if (kills == null)
{
return;
}
Material mat = MakeMaterialColor(Color.red);
foreach (KillPoint kill in kills)
{
Vector3 pos = new Vector3(kill.x, kill.y, kill.z) + Vector3.up * 1.2f;
CreateHoverDot(pos, Vector3.one * 1.1f, mat, slot, "[" + slot + "] " + kill.label, FormatTime(kill.time), 1.45f);
}
}
private void DrawSpeedMarkerDots(List<SpeedMarkerPoint> speedMarkers, string slot)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
if (speedMarkers == null)
{
return;
}
Material mat = MakeMaterialColor(new Color(1f, 0.9f, 0.1f));
foreach (SpeedMarkerPoint speedMarker in speedMarkers)
{
Vector3 pos = new Vector3(speedMarker.x, speedMarker.y, speedMarker.z) + Vector3.up * 0.35f;
string label = "[" + slot + "] " + speedMarker.label + "\nH Speed: " + speedMarker.horizontalSpeed.ToString("0.0", CultureInfo.InvariantCulture) + "\nV Speed: " + speedMarker.verticalSpeed.ToString("0.0", CultureInfo.InvariantCulture);
CreateHoverDot(pos, Vector3.one * 0.9f, mat, slot, label, FormatTime(speedMarker.time), 1.45f);
}
}
private void DrawRouteDifferenceMarkers()
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Expected O, but got Unknown
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
ClearGhostSlot("DIFF");
if (loadedAPoints == null || loadedBPoints == null || loadedAPoints.Count < 2 || loadedBPoints.Count < 2)
{
return;
}
float num = Mathf.Max(loadedAPoints[0].time, loadedBPoints[0].time);
float num2 = Mathf.Min(loadedAPoints[loadedAPoints.Count - 1].time, loadedBPoints[loadedBPoints.Count - 1].time);
if (num2 <= num)
{
return;
}
float num3 = -999f;
Material val = MakeMaterialColor(Color.white);
for (float num4 = num; num4 <= num2; num4 += routeDifferenceSampleStep)
{
if (TryGetPositionAtTime(loadedAPoints, num4, out var position) && TryGetPositionAtTime(loadedBPoints, num4, out var position2))
{
float num5 = Vector3.Distance(position, position2);
if (!(num5 < routeDifferenceThresholdField.value) && !(num4 - num3 < routeDifferenceCooldown))
{
num3 = num4;
Vector3 val2 = (position + position2) * 0.5f;
GameObject val3 = new GameObject("Alien Route Difference Line");
val3.AddComponent<GhostSlot>().slot = "DIFF";
ghostObjects.Add(val3);
LineRenderer val4 = val3.AddComponent<LineRenderer>();
val4.positionCount = 2;
val4.startWidth = 0.12f;
val4.endWidth = 0.12f;
((Renderer)val4).material = val;
val4.useWorldSpace = true;
val4.SetPosition(0, position);
val4.SetPosition(1, position2);
CreateHoverDot(val2 + Vector3.up * 0.5f, Vector3.one * 1f, val, "DIFF", "ROUTE DIFFERENCE\nDistance: " + num5.ToString("0.0", CultureInfo.InvariantCulture) + "m", FormatTime(num4), 1.3f);
}
}
}
}
private bool TryGetPositionAtTime(List<RunPoint> points, float time, out Vector3 position)
{
//IL_0002: 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_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
position = Vector3.zero;
if (points == null || points.Count == 0)
{
return false;
}
if (time <= points[0].time)
{
position = new Vector3(points[0].x, points[0].y, points[0].z);
return true;
}
Vector3 val = default(Vector3);
Vector3 val2 = default(Vector3);
for (int i = 0; i < points.Count - 1; i++)
{
RunPoint runPoint = points[i];
RunPoint runPoint2 = points[i + 1];
if (time >= runPoint.time && time <= runPoint2.time)
{
float num = runPoint2.time - runPoint.time;
if (num <= 0.0001f)
{
num = 0.0001f;
}
float num2 = Mathf.Clamp01((time - runPoint.time) / num);
((Vector3)(ref val))..ctor(runPoint.x, runPoint.y, runPoint.z);
((Vector3)(ref val2))..ctor(runPoint2.x, runPoint2.y, runPoint2.z);
position = Vector3.Lerp(val, val2, num2);
return true;
}
}
RunPoint runPoint3 = points[points.Count - 1];
position = new Vector3(runPoint3.x, runPoint3.y, runPoint3.z);
return true;
}
private void CreateHoverDot(Vector3 pos, Vector3 scale, Material mat, string slot, string label, string timeText, float textHeight)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
((Object)val).name = "Alien Hover Dot " + slot;
val.AddComponent<GhostSlot>().slot = slot;
val.transform.position = pos;
val.transform.localScale = scale;
Renderer component = val.GetComponent<Renderer>();
if ((Object)(object)component != (Object)null)
{
component.material = mat;
}
Collider component2 = val.GetComponent<Collider>();
if ((Object)(object)component2 != (Object)null)
{
Object.Destroy((Object)(object)component2);
}
ghostObjects.Add(val);
GameObject val2 = CreateWorldText(val.transform.position + Vector3.up * textHeight, "", mat.color, 0.55f, slot);
val2.SetActive(false);
ghostObjects.Add(val2);
HoverMarker hoverMarker = new HoverMarker();
hoverMarker.slot = slot;
hoverMarker.dotObject = val;
hoverMarker.textObject = val2;
hoverMarker.textMesh = val2.GetComponent<TextMesh>();
hoverMarker.label = label;
hoverMarker.timeText = timeText;
hoverMarkers.Add(hoverMarker);
}
private GameObject CreateWorldText(Vector3 position, string textValue, Color color, float size, string slot)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Alien Dot Hover Text " + slot);
val.AddComponent<GhostSlot>().slot = slot;
val.transform.position = position;
TextMesh val2 = val.AddComponent<TextMesh>();
val2.text = textValue;
val2.characterSize = size;
val2.fontSize = 90;
val2.anchor = (TextAnchor)4;
val2.alignment = (TextAlignment)1;
val2.color = color;
return val;
}
private List<ActionCluster> BuildActionClusters(List<ActionPoint> actions)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
List<ActionCluster> list = new List<ActionCluster>();
Vector3 val = default(Vector3);
foreach (ActionPoint action in actions)
{
((Vector3)(ref val))..ctor(action.x, action.y, action.z);
bool flag = false;
foreach (ActionCluster item in list)
{
if (item.label == action.label)
{
Vector3 val2 = item.AveragePosition();
if (Vector3.Distance(val, val2) <= clusterDistance)
{
item.actions.Add(action);
flag = true;
break;
}
}
}
if (!flag)
{
ActionCluster actionCluster = new ActionCluster();
actionCluster.label = action.label;
actionCluster.actions = new List<ActionPoint>();
actionCluster.actions.Add(action);
list.Add(actionCluster);
}
}
return list;
}
private string BuildClusterLabel(ActionCluster cluster)
{
string text = cluster.label;
if (cluster.actions.Count > 1)
{
text = text + " x" + cluster.actions.Count;
}
return text;
}
private string BuildClusterTimeText(ActionCluster cluster)
{
string text = "";
for (int i = 0; i < cluster.actions.Count; i++)
{
if (i > 0)
{
text += ", ";
}
text += FormatTime(cluster.actions[i].time);
}
return text;
}
private string FormatTime(float seconds)
{
if (seconds < 0f)
{
seconds = 0f;
}
int num = Mathf.FloorToInt(seconds / 60f);
float num2 = seconds - (float)num * 60f;
return num.ToString("00") + ":" + num2.ToString("00.000", CultureInfo.InvariantCulture);
}
private void ToggleGhostVisibility()
{
ghostVisible = !ghostVisible;
SetGhostVisibility(ghostVisible);
if (!ghostVisible)
{
HideAllHoverTexts();
}
if (ghostVisible)
{
SetStatus("GHOST SHOWN");
}
else
{
SetStatus("GHOST HIDDEN");
}
}
private void SetGhostVisibility(bool visible)
{
foreach (GameObject ghostObject in ghostObjects)
{
if ((Object)(object)ghostObject != (Object)null)
{
ghostObject.SetActive(visible);
}
}
}
private void ClearGhost()
{
foreach (GameObject ghostObject in ghostObjects)
{
if ((Object)(object)ghostObject != (Object)null)
{
Object.Destroy((Object)(object)ghostObject);
}
}
ghostObjects.Clear();
hoverMarkers.Clear();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Cleared all ghost visuals.");
}
private void ClearGhostSlot(string slot)
{
List<GameObject> list = new List<GameObject>();
foreach (GameObject ghostObject in ghostObjects)
{
if (!((Object)(object)ghostObject == (Object)null))
{
GhostSlot component = ghostObject.GetComponent<GhostSlot>();
if ((Object)(object)component != (Object)null && component.slot == slot)
{
list.Add(ghostObject);
}
}
}
foreach (GameObject item in list)
{
ghostObjects.Remove(item);
if ((Object)(object)item != (Object)null)
{
Object.Destroy((Object)(object)item);
}
}
List<HoverMarker> list2 = new List<HoverMarker>();
foreach (HoverMarker hoverMarker in hoverMarkers)
{
if (hoverMarker != null && hoverMarker.slot == slot)
{
list2.Add(hoverMarker);
}
}
foreach (HoverMarker item2 in list2)
{
hoverMarkers.Remove(item2);
}
}
private void RefreshRunFiles()
{
runFiles.Clear();
if (!Directory.Exists(saveFolder))
{
return;
}
string[] files = Directory.GetFiles(saveFolder, "*.txt");
string[] array = files;
foreach (string text in array)
{
if (Path.GetFileName(text).ToLower() == "latest_run.txt")
{
continue;
}
try
{
ReadRunFile(text, out List<RunPoint> _, out List<ActionPoint> _, out List<CheckpointPoint> _, out List<KillPoint> _, out List<SpeedMarkerPoint> _, out string displayName, out string savedTime, out string colorHex, out bool levelFinished);
if (string.IsNullOrEmpty(activeColorFilter) || !(colorHex != activeColorFilter))
{
RunFileEntry runFileEntry = new RunFileEntry();
runFileEntry.path = text;
runFileEntry.fileName = Path.GetFileName(text);
runFileEntry.displayName = displayName;
runFileEntry.savedTime = savedTime;
runFileEntry.colorHex = colorHex;
runFileEntry.finishStatus = (levelFinished ? "LEVEL FINISHED" : "MANUAL / INTERRUPTED");
runFileEntry.writeTime = File.GetLastWriteTime(text);
runFiles.Add(runFileEntry);
if (!renameInputs.ContainsKey(text))
{
renameInputs[text] = displayName;
}
}
}
catch
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to read run file: " + text));
}
}
runFiles.Sort((RunFileEntry a, RunFileEntry b) => b.writeTime.CompareTo(a.writeTime));
}
private void ChangeRunColor(string path, string newColorHex)
{
if (!File.Exists(path))
{
SetStatus("COLOR CHANGE FAILED: FILE NOT FOUND");
return;
}
ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string displayName, out string _, out string _, out bool levelFinished);
WriteRunFile(path, displayName, levelFinished, newColorHex, points, actions, checkpoints, kills, speedMarkers);
}
private void RenameRun(string path, string newName)
{
if (!File.Exists(path))
{
SetStatus("RENAME FAILED: FILE NOT FOUND");
return;
}
if (string.IsNullOrWhiteSpace(newName))
{
SetStatus("RENAME FAILED: EMPTY NAME");
return;
}
ReadRunFile(path, out List<RunPoint> points, out List<ActionPoint> actions, out List<CheckpointPoint> checkpoints, out List<KillPoint> kills, out List<SpeedMarkerPoint> speedMarkers, out string _, out string _, out string colorHex, out bool levelFinished);
string text = MakeSafeFileName(newName);
string directoryName = Path.GetDirectoryName(path);
string text2 = Path.Combine(directoryName, text + ".txt");
int num = 1;
while (File.Exists(text2) && text2 != path)
{
text2 = Path.Combine(directoryName, text + "_" + num + ".txt");
num++;
}
WriteRunFile(text2, newName, levelFinished, colorHex, points, actions, checkpoints, kills, speedMarkers);
if (text2 != path)
{
File.Delete(path);
}
SetStatus("RENAMED RUN");
}
private string MakeSafeFileName(string name)
{
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
foreach (char c in invalidFileNameChars)
{
name = name.Replace(c.ToString(), "");
}
name = name.Trim();
if (string.IsNullOrEmpty(name))
{
name = "Renamed_Run";
}
return name;
}
private string F(float value)
{
return value.ToString(CultureInfo.InvariantCulture);
}
private float Parse(string value)
{
return float.Parse(value, CultureInfo.InvariantCulture);
}
}
public enum BindKey
{
None,
Semicolon,
Quote,
LeftBracket,
RightBracket,
Backslash,
Comma,
Period,
Slash,
Minus,
Equals,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Alpha0,
Alpha1,
Alpha2,
Alpha3,
Alpha4,
Alpha5,
Alpha6,
Alpha7,
Alpha8,
Alpha9,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Insert,
Delete,
Home,
End,
PageUp,
PageDown,
Keypad0,
Keypad1,
Keypad2,
Keypad3,
Keypad4,
Keypad5,
Keypad6,
Keypad7,
Keypad8,
Keypad9
}
public class ColorOption
{
public string name;
public string hex;
public ColorOption(string name, string hex)
{
this.name = name;
this.hex = hex;
}
}
public class GhostSlot : MonoBehaviour
{
public string slot;
}
public class RunPoint
{
public float time;
public float x;
public float y;
public float z;
}
public class ActionPoint
{
public float time;
public float x;
public float y;
public float z;
public float dx;
public float dy;
public float dz;
public string label;
}
public class CheckpointPoint
{
public float time;
public float x;
public float y;
public float z;
public string label;
}
public class KillPoint
{
public float time;
public float x;
public float y;
public float z;
public string label;
}
public class SpeedMarkerPoint
{
public float time;
public float x;
public float y;
public float z;
public float horizontalSpeed;
public float verticalSpeed;
public string label;
}
public class EnemyTrack
{
public int id;
public string name;
public Vector3 lastPosition;
public float lastSeenTime;
}
public class ActionCluster
{
public string label;
public List<ActionPoint> actions;
public Vector3 AveragePosition()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (actions == null || actions.Count == 0)
{
return Vector3.zero;
}
Vector3 val = Vector3.zero;
foreach (ActionPoint action in actions)
{
val += new Vector3(action.x, action.y, action.z);
}
return val / (float)actions.Count;
}
public Vector3 AverageDirection()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
if (actions == null || actions.Count == 0)
{
return Vector3.forward;
}
Vector3 val = Vector3.zero;
foreach (ActionPoint action in actions)
{
val += new Vector3(action.dx, action.dy, action.dz);
}
return ((Vector3)(ref val)).normalized;
}
}
public class HoverMarker
{
public string slot;
public GameObject dotObject;
public GameObject textObject;
public TextMesh textMesh;
public string label;
public string timeText;
}
public class RunFileEntry
{
public string path;
public string fileName;
public string displayName;
public string savedTime;
public string colorHex;
public string finishStatus;
public DateTime writeTime;
}
namespace MyFirstUltrakillMod
{
internal static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.alienpxgaming.speedrunpaths";
public const string PLUGIN_NAME = "Alien's Speedrun Paths";
public const string PLUGIN_VERSION = "1.0.1";
}
}