diff --git a/src/ST-Commands/PlayerCommands.cs b/src/ST-Commands/PlayerCommands.cs index 251a421..bac46fd 100644 --- a/src/ST-Commands/PlayerCommands.cs +++ b/src/ST-Commands/PlayerCommands.cs @@ -75,7 +75,7 @@ public void PlayerGoToStage(CCSPlayerController? player, CommandInfo command) Server.NextFrame(() => player.PlayerPawn.Value!.Teleport(CurrentMap.StageStartZone[stage], CurrentMap.StageStartZoneAngles[stage], new Vector(0,0,0))); playerList[player.UserId ?? 0].Timer.Reset(); - playerList[player.UserId ?? 0].Timer.StageMode = true; + playerList[player.UserId ?? 0].Timer.IsStageMode = true; // To-do: If you run this while you're in the start zone, endtouch for the start zone runs after you've teleported // causing the timer to start. This needs to be fixed. diff --git a/src/ST-Player/PlayerHUD.cs b/src/ST-Player/PlayerHUD.cs index a92978c..4814453 100644 --- a/src/ST-Player/PlayerHUD.cs +++ b/src/ST-Player/PlayerHUD.cs @@ -28,11 +28,29 @@ private string FormatHUDElementHTML(string title, string body, string color, str } } - public string FormatTime(int ticks) // https://github.com/DEAFPS/SharpTimer/blob/e4ef24fff29a33c36722d23961355742d507441f/Utils.cs#L38 + /// + /// Formats the given time in ticks into a readable time string. + /// Unless specified differently, the default formatting will be `Verbose`. + /// Check for all formatting types. + /// + public string FormatTime(int ticks, PlayerTimer.TimeFormatStyle style = PlayerTimer.TimeFormatStyle.Verbose) { TimeSpan time = TimeSpan.FromSeconds(ticks / 64.0); int millis = (int)(ticks % 64 * (1000.0 / 64.0)); - return $"{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + + switch (style) + { + case PlayerTimer.TimeFormatStyle.Compact: + return time.TotalMinutes < 1 + ? $"{time.Seconds:D1}.{millis:D3}" + : $"{time.Minutes:D1}:{time.Seconds:D1}.{millis:D3}"; + case PlayerTimer.TimeFormatStyle.Full: + return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}"; + case PlayerTimer.TimeFormatStyle.Verbose: + return $"{time.Hours}h {time.Minutes}m {time.Seconds}s {millis}ms"; + default: + throw new ArgumentException("Invalid time format style"); + } } public void Display() @@ -43,7 +61,7 @@ public void Display() string timerColor = "#79d1ed"; if (_player.Timer.IsRunning) { - if (_player.Timer.PracticeMode) + if (_player.Timer.IsPracticeMode) timerColor = "#F2C94C"; else timerColor = "#2E9F65"; @@ -51,14 +69,14 @@ public void Display() string timerModule = FormatHUDElementHTML("", FormatTime(_player.Timer.Ticks), timerColor); // Velocity Module - To-do: Make velocity module configurable (XY or XYZ velocity) - float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X - + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + float velocity = (float)Math.Sqrt(_player.Controller.PlayerPawn.Value!.AbsVelocity.X * _player.Controller.PlayerPawn.Value!.AbsVelocity.X + + _player.Controller.PlayerPawn.Value!.AbsVelocity.Y * _player.Controller.PlayerPawn.Value!.AbsVelocity.Y + _player.Controller.PlayerPawn.Value!.AbsVelocity.Z * _player.Controller.PlayerPawn.Value!.AbsVelocity.Z); string velocityModule = FormatHUDElementHTML("Speed", velocity.ToString("000"), "#79d1ed") + " u/s"; // Rank Module string rankModule = FormatHUDElementHTML("Rank", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // PB & WR Modules - string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0,0] > 0 ? FormatTime(_player.Stats.PB[0,0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats + string pbModule = FormatHUDElementHTML("PB", _player.Stats.PB[0, 0] > 0 ? FormatTime(_player.Stats.PB[0, 0]) : "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats string wrModule = FormatHUDElementHTML("WR", "N/A", "#7882dd"); // IMPLEMENT IN PlayerStats // Build HUD diff --git a/src/ST-Player/PlayerTimer.cs b/src/ST-Player/PlayerTimer.cs index 97df4f4..f12d668 100644 --- a/src/ST-Player/PlayerTimer.cs +++ b/src/ST-Player/PlayerTimer.cs @@ -3,21 +3,29 @@ namespace SurfTimer; internal class PlayerTimer { // Status - public bool Enabled {get; set;} = true; // Enable toggle for entire timer - public bool Paused {get; set;} = false; // Pause toggle for timer - public bool IsRunning {get; set;} = false; // Is the timer currently running? + public bool IsEnabled { get; set; } = true; // Enable toggle for entire timer + public bool IsPaused { get; set; } = false; // Pause toggle for timer + public bool IsRunning { get; set; } = false; // Is the timer currently running? // Modes - public bool PracticeMode {get; set;} = false; // Practice mode toggle - public bool StageMode {get; set;} = false; // Stage mode toggle + public bool IsPracticeMode { get; set; } = false; // Practice mode toggle + public bool IsStageMode { get; set; } = false; // Stage mode toggle // Tracking - public int Stage {get; set;} = 0; // Current stage tracker - public int Bonus {get; set;} = 0; // Current bonus tracker - To-do: bonus implementation + public int Stage { get; set; } = 0; // Current stage tracker + public int Bonus { get; set; } = 0; // Current bonus tracker - To-do: bonus implementation // public int Style = 0; // To-do: style implementation // Timing - public int Ticks {get; set;} = 0; // To-do: sub-tick counting? This currently goes on OnTick, which is not sub-tick I believe? Needs investigating + public int Ticks { get; set; } = 0; // To-do: sub-tick counting? This currently goes on OnTick, which is not sub-tick I believe? Needs investigating + + // Time Formatting + public enum TimeFormatStyle + { + Compact, + Full, + Verbose + } // Methods public void Reset() @@ -25,19 +33,19 @@ public void Reset() this.Stop(); this.Ticks = 0; this.Stage = 0; - this.Paused = false; - this.PracticeMode = false; + this.IsPaused = false; + this.IsPracticeMode = false; } public void Pause() { - this.Paused = true; + this.IsPaused = true; } public void Start() { // Timer Start method - notes: OnStartTimerPress - if (this.Enabled) + if (this.IsEnabled) this.IsRunning = true; } @@ -51,9 +59,9 @@ public void Tick() { // Tick the timer - this checks for any restrictions, so can be conveniently called from anywhere // without worry for any timing restrictions (eg: Paused, Enabled, etc) - if (this.Paused || !this.Enabled || !this.IsRunning) + if (this.IsPaused || !this.IsEnabled || !this.IsRunning) return; - + this.Ticks++; } } \ No newline at end of file