198 lines
5.5 KiB
C#
198 lines
5.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using System.IO;
|
|
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class Timing: MonoBehaviour {
|
|
TimingUI ui;
|
|
LapService lapService;
|
|
|
|
public List<SectorTime> sectorTimes;
|
|
public bool timerEnabled;
|
|
|
|
[SerializeField]
|
|
ShipAudio audio;
|
|
|
|
public string mapName;
|
|
public double sectorTime;
|
|
public double lapTime;
|
|
public Sector[] sectors;
|
|
|
|
double sectorStart;
|
|
double lapStart;
|
|
|
|
IEnumerator noticeLifecycle;
|
|
IEnumerator msgLifecycle;
|
|
|
|
void Awake() {
|
|
ui = GetComponent<TimingUI>();
|
|
sectorTimes = new List<SectorTime>();
|
|
sectorStart = 0.0;
|
|
sectorTime = 0.0;
|
|
sectors = FindObjectsByType<Sector>(FindObjectsSortMode.None).OrderBy(s => s.sector).ToArray();
|
|
|
|
// set map name
|
|
Scene scene = SceneManager.GetActiveScene();
|
|
mapName = scene.name;
|
|
Debug.Log("Track Sector Count - " + sectors.Length);
|
|
|
|
// just poke the timing ui cause sometimes it fires early and misses that we actually have sectors
|
|
ui.Init();
|
|
|
|
lapService = new LapService(mapName);
|
|
}
|
|
|
|
void Start() {
|
|
Debug.Log("Timing Starting...");
|
|
StartCoroutine(lapService.GetLapTimes());
|
|
}
|
|
|
|
void Update() {
|
|
// hmr
|
|
if (lapService == null) {
|
|
Awake();
|
|
Start();
|
|
}
|
|
|
|
if (timerEnabled) {
|
|
sectorTime = Time.timeAsDouble - sectorStart;
|
|
lapTime = Time.timeAsDouble - lapStart;
|
|
}
|
|
}
|
|
|
|
public void StartTimer() {
|
|
if (sectors.Length == 0) {
|
|
Debug.LogWarning("No Sectors found in timing");
|
|
return;
|
|
}
|
|
|
|
Debug.Log("Started Timer");
|
|
|
|
timerEnabled = true;
|
|
lapStart = Time.timeAsDouble;
|
|
sectorStart = Time.timeAsDouble;
|
|
}
|
|
|
|
public void StopTimer() {
|
|
sectorTimes = new List<SectorTime>();
|
|
timerEnabled = false;
|
|
sectorTime = 0;
|
|
lapTime = 0;
|
|
Debug.Log("Timer Stopped");
|
|
}
|
|
|
|
public void NextSector(int sector) {
|
|
if (!timerEnabled)
|
|
return;
|
|
|
|
// they turned around or somethin?
|
|
if (sectorTimes.Any(s => s.Sector == sector))
|
|
return;
|
|
|
|
// this basically makes sure the timer doesn't do anything weird
|
|
// due to respawns, driving in the wrong direction etc
|
|
// you have to hit the sectors in numbered order
|
|
// ---------------
|
|
// make sure sectors are only accessible by being hit by following
|
|
// the track correctly!
|
|
if (sector != sectorTimes.Count + 1)
|
|
return;
|
|
|
|
// alright they legitimately finished a sector...
|
|
double sTime = Time.timeAsDouble - sectorStart;
|
|
SectorTime s = new SectorTime { Sector = sector, Seconds = sTime };
|
|
sectorTimes.Add(s);
|
|
Debug.Log($"{sectorTimes.Count} / {sectors.Length}");
|
|
|
|
// play a sound :)
|
|
if (audio != null) audio.PlayNoise();
|
|
|
|
// restart the timer for the next sector
|
|
sectorStart = Time.timeAsDouble;
|
|
|
|
|
|
// they finished a lap!
|
|
if (sectorTimes.Count == sectors.Length) {
|
|
EndLap();
|
|
NextLap();
|
|
}
|
|
}
|
|
|
|
void NextLap() {
|
|
sectorTimes = new List<SectorTime>();
|
|
StartTimer();
|
|
}
|
|
|
|
public void EndLap() {
|
|
// when live reloading this happens
|
|
if (sectorTimes == null)
|
|
Awake();
|
|
|
|
Debug.Log($"Ending lap Sectors={sectorTimes.Count} Name={mapName}");
|
|
Lap l = new Lap { Map = mapName, Sectors = sectorTimes };
|
|
Debug.Log($"EndLap {l}");
|
|
|
|
// have to show this before we persist the lap in case it is the pb
|
|
if (noticeLifecycle != null) StopCoroutine(noticeLifecycle);
|
|
noticeLifecycle = RecentLapLifecycle(l);
|
|
StartCoroutine(noticeLifecycle);
|
|
StartCoroutine(lapService?.PostLap(l));
|
|
}
|
|
|
|
IEnumerator RecentLapLifecycle(Lap l) {
|
|
ui.ShowRecentLap(l);
|
|
yield return new WaitForSeconds(10);
|
|
ui.HideRecentLap();
|
|
}
|
|
|
|
public void Message(string msg) {
|
|
if (msgLifecycle != null) StopCoroutine(msgLifecycle);
|
|
msgLifecycle = ShowMessage(msg);
|
|
StartCoroutine(msgLifecycle);
|
|
}
|
|
|
|
IEnumerator ShowMessage(string msg) {
|
|
ui.ShowMessage(msg);
|
|
yield return new WaitForSeconds(5);
|
|
ui.HideMessage();
|
|
}
|
|
|
|
// these can be null after HMR
|
|
public Lap LapRecord => lapService?.LapRecord;
|
|
public Lap Pb => lapService?.Pb;
|
|
public string Position => $"{lapService?.Position} / {lapService?.Completions}";
|
|
|
|
public TimingNotice CompareLap(Lap lap) {
|
|
double? lrSeconds = LapRecord != null ? LapRecord.TotalTime : null;
|
|
double? pbSeconds = Pb != null ? Pb.TotalTime : null;
|
|
return TimingNotice.Compare(lap.TotalTime, pbSeconds, lrSeconds);
|
|
}
|
|
|
|
public TimingNotice CompareSector(SectorTime s) {
|
|
double? lrSeconds = LapRecord switch {
|
|
null => null,
|
|
Lap lr => lr.Sectors.SingleOrDefault(lrs => lrs.Sector == s.Sector) switch {
|
|
SectorTime lrSector => lrSector.Seconds,
|
|
_ => null,
|
|
},
|
|
};
|
|
|
|
double? pbSeconds = Pb switch {
|
|
null => null,
|
|
Lap pb => pb.Sectors.SingleOrDefault(pbs => pbs.Sector == s.Sector) switch {
|
|
SectorTime pbSector => pbSector.Seconds,
|
|
_ => null,
|
|
},
|
|
};
|
|
|
|
return TimingNotice.Compare(s.Seconds, pbSeconds, lrSeconds);
|
|
}
|
|
}
|
|
|