using System; using System.Collections.Generic; using System.Drawing.Printing; using System.IO; using System.IO.Compression; using System.Runtime.Serialization.Formatters.Binary; namespace TeslaConsole.BattleTech; /// /// The recorded outcome of one BattleTech mission, saved as a gzip'd /// BinaryFormatter blob (.btm) exactly like the RP .rpm mechanism. Mirrors /// RPMissionResults minus the football branches (BT battle modes have /// no teams, so every ranking entry is a single pilot). /// [Serializable] internal class BTMissionResults { private BTMission mMission; internal DateTime mMissionStart; internal TimeSpan mActuallMissionTime; internal readonly List mEvents = new List(); internal readonly Dictionary mFinalScores = new Dictionary(); public BTMission Mission => mMission; public DateTime MissionStart => mMissionStart; public TimeSpan ActuallMissionTime => mActuallMissionTime; public IEnumerable Events => mEvents; internal BTMissionResults(BTMission mission) { mMission = mission; } public static string GetBTMissionsDirectory() { string text = Path.Combine(Program.GetCommonAppDataDirectory(), "BT Missions"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } return text; } public static BTMissionResults Load(string file) { using GZipStream gZipStream = new GZipStream(File.OpenRead(file), CompressionMode.Decompress); BinaryFormatter binaryFormatter = new BinaryFormatter(); BTMissionResults result = (BTMissionResults)binaryFormatter.Deserialize(gZipStream); gZipStream.Close(); return result; } public void Save() { string path = Path.Combine(GetBTMissionsDirectory(), mMissionStart.ToString("yyyy-MM-dd HH-mm-ss.ffff") + ".btm"); using GZipStream gZipStream = new GZipStream(File.OpenWrite(path), CompressionMode.Compress); BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(gZipStream, this); gZipStream.Close(); } public int GetScore(BTPlayer player) { return GetScore(player, TimeSpan.MaxValue); } public int GetScore(BTPlayer player, TimeSpan gameTime) { if (gameTime == TimeSpan.MaxValue && mFinalScores.ContainsKey(player)) { return mFinalScores[player]; } int result = 1000; TimeSpan timeSpan = TimeSpan.MinValue; foreach (BTMissionEvent mEvent in mEvents) { if (mEvent is BTScoreUpdateEvent && mEvent.ReportingPilot == player && mEvent.GameTime > timeSpan && mEvent.GameTime <= gameTime) { result = ((BTScoreUpdateEvent)mEvent).Score; timeSpan = mEvent.GameTime; } } return result; } public int GetFinalPlace(BTPlayer player) { int num = 1; int score = GetScore(player, TimeSpan.MaxValue); foreach (BTPlayer player2 in mMission.Players) { if (player2 != player && GetScore(player2, TimeSpan.MaxValue) > score) { num++; } } return num; } public BTPlayer[][] GetChartOrder() { return GetChartOrder(TimeSpan.MaxValue); } public BTPlayer[][] GetChartOrder(TimeSpan gameTime) { List> list = new List>(); foreach (BTPlayer player in Mission.Players) { list.Add(new Tuple(new BTPlayer[1] { player }, GetScore(player, gameTime))); } for (int i = 0; i < list.Count - 1; i++) { for (int j = i + 1; j < list.Count; j++) { if (list[i].B < list[j].B || (list[i].B == list[j].B && string.CompareOrdinal(list[i].A[0].Name, list[j].A[0].Name) > 0)) { Tuple value = list[i]; list[i] = list[j]; list[j] = value; } } } List list2 = new List(); foreach (Tuple item in list) { list2.Add(item.A); } return list2.ToArray(); } public PrintDocument GetPrintDocument() { return new BTPrintDocument(this); } }