151 lines
4.0 KiB
C#
151 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.IO;
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
public enum NoticeCategory {
|
|
Initial,
|
|
Slower,
|
|
Faster,
|
|
Fastest,
|
|
}
|
|
|
|
public class TimingNotice {
|
|
public double Seconds;
|
|
NoticeCategory Category = NoticeCategory.Initial;
|
|
|
|
public TimingNotice Compare(double comparison) {
|
|
double s = Math.Abs(comparison - Seconds);
|
|
NoticeCategory cat = comparison switch {
|
|
double c when Seconds < c => NoticeCategory.Faster,
|
|
_ => NoticeCategory.Slower,
|
|
};
|
|
|
|
return new TimingNotice {
|
|
Seconds = s,
|
|
Category = cat,
|
|
};
|
|
}
|
|
|
|
public Label ToLabel() {
|
|
Label l = Category switch {
|
|
NoticeCategory.Slower => new Label($"+{Seconds:0.000}"),
|
|
NoticeCategory.Faster => new Label($"-{Seconds:0.000}"),
|
|
NoticeCategory.Fastest => new Label($"-{Seconds:0.000}"),
|
|
NoticeCategory.Initial => new Label($"{TimeSpan.FromSeconds(Seconds):m\\:ss\\.fff}"),
|
|
};
|
|
|
|
string colourClass = Category switch {
|
|
NoticeCategory.Slower => "yellow",
|
|
NoticeCategory.Faster => "green",
|
|
NoticeCategory.Fastest => "purple",
|
|
NoticeCategory.Initial => "",
|
|
};
|
|
|
|
l.AddToClassList(colourClass);
|
|
return l;
|
|
}
|
|
}
|
|
|
|
public enum DiffColour {
|
|
Green,
|
|
Purple,
|
|
White,
|
|
Yellow,
|
|
}
|
|
|
|
[Serializable]
|
|
public class SectorTime {
|
|
public int Sector;
|
|
public double Seconds;
|
|
public override string ToString() => $"{Seconds:0.000}";
|
|
}
|
|
|
|
[Serializable]
|
|
public class Lap {
|
|
public string Map;
|
|
public List<SectorTime> Sectors;
|
|
|
|
// 0:1:39
|
|
public override string ToString() {
|
|
return $"{TimeSpan.FromSeconds(TotalTime):m\\:ss\\.fff}";
|
|
}
|
|
|
|
public double TotalTime => Sectors.Sum(s => s.Seconds);
|
|
}
|
|
|
|
|
|
[Serializable]
|
|
public class LapJSON {
|
|
public string Map;
|
|
public List<Lap> Laps = new();
|
|
}
|
|
|
|
// We can't save a dictionary with the Unity JSONUtility
|
|
// so we use this to hold a list of maps
|
|
public class LapStorage {
|
|
public List<LapJSON> Laps = new();
|
|
}
|
|
|
|
static class LapStorageService {
|
|
static Dictionary<string, LapJSON> lapsByMap = new();
|
|
static string lapStoragePath = Path.Combine(Application.persistentDataPath, "lapStorage.json");
|
|
|
|
static LapStorageService() {
|
|
LapStorage lapStorage = new LapStorage();
|
|
|
|
try {
|
|
string json = File.ReadAllText(lapStoragePath);
|
|
JsonUtility.FromJsonOverwrite(json, lapStorage);
|
|
} catch {
|
|
Debug.Log("No existing lapStorage.json");
|
|
}
|
|
|
|
lapsByMap = lapStorage.Laps.ToDictionary((lapJson) => lapJson.Map);
|
|
}
|
|
|
|
public static LapJSON GetPlayerLaps(string mapName) {
|
|
LapJSON currentLaps;
|
|
bool found = lapsByMap.TryGetValue(mapName, out currentLaps);
|
|
if (!found) return EnsureMap(mapName);
|
|
return currentLaps;
|
|
}
|
|
|
|
public static LapJSON EnsureMap(string mapName) {
|
|
LapJSON lapJson = new LapJSON { Map = mapName, Laps = new List<Lap>() };
|
|
lapsByMap[mapName] = lapJson;
|
|
return lapJson;
|
|
}
|
|
|
|
static void Persist() {
|
|
LapStorage lapStorage = new LapStorage { Laps = lapsByMap.Values.ToList() };
|
|
File.WriteAllText(lapStoragePath, JsonUtility.ToJson(lapStorage));
|
|
}
|
|
|
|
// laps.count
|
|
public static int NumberOfCompletions() { return 0; }
|
|
|
|
// finds your PB in all completions
|
|
public static int Rank() { return 1; }
|
|
|
|
public static void PersistLap(Lap lap) {
|
|
LapJSON lapJson = GetPlayerLaps(lap.Map);
|
|
lapJson.Laps.Add(lap);
|
|
lapsByMap[lap.Map] = lapJson; // not needed?
|
|
Persist();
|
|
}
|
|
|
|
public static Lap PB(string mapName) {
|
|
return lapsByMap[mapName].Laps
|
|
.MinBy(l => l.TotalTime);
|
|
}
|
|
}
|
|
|
|
// Add this magic code, you will be able to use record and init.
|
|
// I only tested in editor, not sure whether it would work on other platforms.
|
|
namespace System.Runtime.CompilerServices {
|
|
class IsExternalInit {}
|
|
} |