using KYFramework; using SimulationServer.Utils; namespace SimulationServer; public class MHRescueMission : Entity { public List aircrafts = new List(); public Action End; public bool IsRunning = false; #region 仿真程序 public int SimulationTime = 1; #endregion #region 任务信息 public string MissionId; // 任务ID public bool Success; // 任务是否成功 public double SimTime; public double InitArea; // 火场点 public FireGround FireGround; public double slope; public double area; public double tn; public List successes = new List(); #endregion #region 报告 // 灭火的 单机能力 // <机型,>> public Dictionary>>> singleReport = new (); // 灭火的 整体能力 // > public Dictionary>> totalReport = new (); //装备指标 // > public Dictionary>> equipReport = new (); #endregion public void Reset() { SimTime = 0; area = 0; tn = 0; FireGround.countArea.burnarea = InitArea; aircrafts?.ForEach(a => a.Reset()); } public void Start() { Log.Info($"{MissionId} 任务开始!"); aircrafts?.ForEach(a => a.Start()); IsRunning = true; } public void EndMission() { IsRunning = false; Log.Info($"{MissionId} 任务结束!"); // 灭火完成 任务结束 End?.Invoke(); SaveMH(); SaveTotalMH(); ReportMH(); var readyTime = aircrafts.First().TaskReadyTime; Task.Delay(TimeSpan.FromSeconds(readyTime)).ContinueWith(t => this.StartAsyncMH()); } /// /// 任务结束一次指标报告 /// public void SaveMH() { foreach (AircraftEntity aircraftEntity in aircrafts) { // 输出 area var staticCapacity = aircraftEntity.GetComponent(); var taskPerformance = aircraftEntity.GetComponent(); var economical = aircraftEntity.GetComponent(); if(staticCapacity == null || taskPerformance == null || economical == null) continue; staticCapacity.FillData(aircraftEntity.Db); taskPerformance.FillData(aircraftEntity.Db); economical.FillData(); string key = aircraftEntity.AircraftId; if (!singleReport.ContainsKey(key)) { singleReport[key] = new Dictionary>>(); } Dictionary> staticReport = staticCapacity.GetReport(); foreach (var kv in staticReport) { if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List(); singleReport[key][kv.Key][kv2.Key].Add(kv2.Value); } } Dictionary> taskReport = taskPerformance.GetReport(); foreach (var kv in taskReport) { if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List(); singleReport[key][kv.Key][kv2.Key].Add(kv2.Value); } } Dictionary> economicalReport = economical.GetReport(); foreach (var kv in economicalReport) { if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List(); singleReport[key][kv.Key][kv2.Key].Add(kv2.Value); } } } } public void SaveTotalMH() { var totalPerformance = GetComponent(); totalPerformance.FillData(); var totalPerformanceReport = totalPerformance.GetReport(); foreach (var kv in totalPerformanceReport) { if(!totalReport.ContainsKey(kv.Key)) totalReport[kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!totalReport[kv.Key].ContainsKey(kv2.Key)) totalReport[kv.Key][kv2.Key] = new List(); if(kv2.Key == "任务成功率/-") { successes.Add(kv2.Value); } totalReport[kv.Key][kv2.Key].Add(kv2.Value); } } var TotalEconomical = GetComponent(); TotalEconomical.FillData(); var totalEconomicalReport = TotalEconomical.GetReport(); foreach (var kv in totalEconomicalReport) { if(!totalReport.ContainsKey(kv.Key)) totalReport[kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!totalReport[kv.Key].ContainsKey(kv2.Key)) totalReport[kv.Key][kv2.Key] = new List(); totalReport[kv.Key][kv2.Key].Add(kv2.Value); } } var TotalEquipment = GetComponent(); TotalEquipment.FillData(); var totalEquipmentReport = TotalEquipment.GetReport(); foreach (var kv in totalEquipmentReport) { if(!equipReport.ContainsKey(kv.Key)) equipReport[kv.Key] = new Dictionary>(); foreach (var kv2 in kv.Value) { if (!equipReport[kv.Key].ContainsKey(kv2.Key)) equipReport[kv.Key][kv2.Key] = new List(); equipReport[kv.Key][kv2.Key].Add(kv2.Value); } } } public float getSuccessRate() { int count = 0; foreach (string success in successes) { if(success == "成功") { count++; } } return count / successes.Count; } public void ReportMH() { string data = DateTime.Now.ToString("yyyy-MM-dd"); string path = $"Reports/MH/{data}/{MissionId}"; if(!Directory.Exists(path)) Directory.CreateDirectory(path); foreach (var kv in singleReport) { string filePath = $"{path}/{kv.Key}灭火任务单机指标报告.xls"; DataTableExtensions.SaveToExcel(filePath, kv.Value); } foreach (KeyValuePair>> keyValuePair in totalReport) { foreach (KeyValuePair> kv in keyValuePair.Value) { if(kv.Key == "任务成功率/-") { double successRate = getSuccessRate(); kv.Value.Add((successRate * 100) + "%"); } else { List values = kv.Value; double sum = 0; foreach (string value in values) { if (double.TryParse(value, out double num)) { sum += num; } } double average = sum / values.Count; values.Add(average.ToString("#0.00")); } } } string totalPath = $"{path}/{"灭火任务总体指标报告"}.xls"; DataTableExtensions.SaveToExcel(totalPath, totalReport,true); string equicPath = $"{path}/{"装备体系评估报告"}.xls"; DataTableExtensions.SaveToExcel(equicPath, equipReport); } } [ObjectSystem] public class MhRescueMissionAwakeSystem : AwakeSystem { public override void Awake(MHRescueMission self, FireGround fire, double initArea) { self.FireGround = fire; self.InitArea = initArea; } } [ObjectSystem] public class RescueMissionUpdateSystem : UpdateSystem { public override void Update(MHRescueMission self) { if(!self.IsRunning) return; if (self.FireGround.countArea.burnarea <= 0) { self.Success = true; self.EndMission(); return; } if(self.tn >= 10 * 60 * 60) { self.Success = false; self.EndMission(); return; } self.aircrafts.Sort((a, b) => a.T.CompareTo(b.T)); self.aircrafts.ForEach(a => a.Update(self.SimTime)); self.SimTime += 1 * TaskComponent.Speed; } }