MHRescueMission.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. using KYFramework;
  2. using SimulationServer.Utils;
  3. namespace SimulationServer;
  4. public class MHRescueMission : Entity
  5. {
  6. public List<AircraftEntity> aircrafts = new List<AircraftEntity>();
  7. public Action End;
  8. public bool IsRunning = false;
  9. #region 仿真程序
  10. public int SimulationTime = 1;
  11. #endregion
  12. #region 任务信息
  13. public string MissionId; // 任务ID
  14. public bool Success; // 任务是否成功
  15. public double SimTime;
  16. public double InitArea;
  17. // 火场点
  18. public FireGround FireGround;
  19. public double slope;
  20. public double area;
  21. public double tn;
  22. public List<string> successes = new List<string>();
  23. #endregion
  24. #region 报告
  25. // 灭火的 单机能力
  26. // <机型,<sheet,<指标名,值列表>>>
  27. public Dictionary<string,Dictionary<string,Dictionary<string,List<string>>>> singleReport = new ();
  28. // 灭火的 整体能力
  29. // <sheet,<指标名,值列表>>
  30. public Dictionary<string, Dictionary<string, List<string>>> totalReport = new ();
  31. //装备指标
  32. // <sheet,<指标名,值列表>>
  33. public Dictionary<string, Dictionary<string, List<string>>> equipReport = new ();
  34. #endregion
  35. public void Reset()
  36. {
  37. SimTime = 0;
  38. area = 0;
  39. tn = 0;
  40. FireGround.countArea.burnarea = InitArea;
  41. aircrafts?.ForEach(a => a.Reset());
  42. }
  43. public void Start()
  44. {
  45. Log.Info($"{MissionId} 任务开始!");
  46. aircrafts?.ForEach(a => a.Start());
  47. IsRunning = true;
  48. }
  49. public void EndMission()
  50. {
  51. IsRunning = false;
  52. Log.Info($"{MissionId} 任务结束!");
  53. // 灭火完成 任务结束
  54. End?.Invoke();
  55. SaveMH();
  56. SaveTotalMH();
  57. ReportMH();
  58. var readyTime = aircrafts.First().TaskReadyTime;
  59. Task.Delay(TimeSpan.FromSeconds(readyTime)).ContinueWith(t => this.StartAsyncMH());
  60. }
  61. /// <summary>
  62. /// 任务结束一次指标报告
  63. /// </summary>
  64. public void SaveMH()
  65. {
  66. foreach (AircraftEntity aircraftEntity in aircrafts)
  67. {
  68. // 输出 area
  69. var staticCapacity = aircraftEntity.GetComponent<StaticCapacityComponent>();
  70. var taskPerformance = aircraftEntity.GetComponent<TaskPerformanceComponent>();
  71. var economical = aircraftEntity.GetComponent<EconomicalComponent>();
  72. if(staticCapacity == null || taskPerformance == null || economical == null) continue;
  73. staticCapacity.FillData(aircraftEntity.Db);
  74. taskPerformance.FillData(aircraftEntity.Db);
  75. economical.FillData();
  76. string key = aircraftEntity.AircraftId;
  77. if (!singleReport.ContainsKey(key))
  78. {
  79. singleReport[key] = new Dictionary<string, Dictionary<string, List<string>>>();
  80. }
  81. Dictionary<string, Dictionary<string, string>> staticReport = staticCapacity.GetReport();
  82. foreach (var kv in staticReport)
  83. {
  84. if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
  85. foreach (var kv2 in kv.Value)
  86. {
  87. if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
  88. singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
  89. }
  90. }
  91. Dictionary<string, Dictionary<string, string>> taskReport = taskPerformance.GetReport();
  92. foreach (var kv in taskReport)
  93. {
  94. if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
  95. foreach (var kv2 in kv.Value)
  96. {
  97. if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
  98. singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
  99. }
  100. }
  101. Dictionary<string, Dictionary<string, string>> economicalReport = economical.GetReport();
  102. foreach (var kv in economicalReport)
  103. {
  104. if(!singleReport[key].ContainsKey(kv.Key)) singleReport[key][kv.Key] = new Dictionary<string, List<string>>();
  105. foreach (var kv2 in kv.Value)
  106. {
  107. if (!singleReport[key][kv.Key].ContainsKey(kv2.Key)) singleReport[key][kv.Key][kv2.Key] = new List<string>();
  108. singleReport[key][kv.Key][kv2.Key].Add(kv2.Value);
  109. }
  110. }
  111. }
  112. }
  113. public void SaveTotalMH()
  114. {
  115. var totalPerformance = GetComponent<TotalTaskPerformanceComponent>();
  116. totalPerformance.FillData();
  117. var totalPerformanceReport = totalPerformance.GetReport();
  118. foreach (var kv in totalPerformanceReport)
  119. {
  120. if(!totalReport.ContainsKey(kv.Key)) totalReport[kv.Key] = new Dictionary<string, List<string>>();
  121. foreach (var kv2 in kv.Value)
  122. {
  123. if (!totalReport[kv.Key].ContainsKey(kv2.Key)) totalReport[kv.Key][kv2.Key] = new List<string>();
  124. if(kv2.Key == "任务成功率/-")
  125. {
  126. successes.Add(kv2.Value);
  127. }
  128. totalReport[kv.Key][kv2.Key].Add(kv2.Value);
  129. }
  130. }
  131. var TotalEconomical = GetComponent<TotalEconomicalComponent>();
  132. TotalEconomical.FillData();
  133. var totalEconomicalReport = TotalEconomical.GetReport();
  134. foreach (var kv in totalEconomicalReport)
  135. {
  136. if(!totalReport.ContainsKey(kv.Key)) totalReport[kv.Key] = new Dictionary<string, List<string>>();
  137. foreach (var kv2 in kv.Value)
  138. {
  139. if (!totalReport[kv.Key].ContainsKey(kv2.Key)) totalReport[kv.Key][kv2.Key] = new List<string>();
  140. totalReport[kv.Key][kv2.Key].Add(kv2.Value);
  141. }
  142. }
  143. var TotalEquipment = GetComponent<EquipmentComponent>();
  144. TotalEquipment.FillData();
  145. var totalEquipmentReport = TotalEquipment.GetReport();
  146. foreach (var kv in totalEquipmentReport)
  147. {
  148. if(!equipReport.ContainsKey(kv.Key)) equipReport[kv.Key] = new Dictionary<string, List<string>>();
  149. foreach (var kv2 in kv.Value)
  150. {
  151. if (!equipReport[kv.Key].ContainsKey(kv2.Key)) equipReport[kv.Key][kv2.Key] = new List<string>();
  152. equipReport[kv.Key][kv2.Key].Add(kv2.Value);
  153. }
  154. }
  155. }
  156. public float getSuccessRate()
  157. {
  158. int count = 0;
  159. foreach (string success in successes)
  160. {
  161. if(success == "成功")
  162. {
  163. count++;
  164. }
  165. }
  166. return count / successes.Count;
  167. }
  168. public void ReportMH()
  169. {
  170. string data = DateTime.Now.ToString("yyyy-MM-dd");
  171. string path = $"Reports/MH/{data}/{MissionId}";
  172. if(!Directory.Exists(path)) Directory.CreateDirectory(path);
  173. foreach (var kv in singleReport)
  174. {
  175. string filePath = $"{path}/{kv.Key}灭火任务单机指标报告.xls";
  176. DataTableExtensions.SaveToExcel(filePath, kv.Value);
  177. }
  178. foreach (KeyValuePair<string,Dictionary<string,List<string>>> keyValuePair in totalReport)
  179. {
  180. foreach (KeyValuePair<string,List<string>> kv in keyValuePair.Value)
  181. {
  182. if(kv.Key == "任务成功率/-")
  183. {
  184. double successRate = getSuccessRate();
  185. kv.Value.Add((successRate * 100) + "%");
  186. }
  187. else
  188. {
  189. List<string> values = kv.Value;
  190. double sum = 0;
  191. foreach (string value in values)
  192. {
  193. if (double.TryParse(value, out double num))
  194. {
  195. sum += num;
  196. }
  197. }
  198. double average = sum / values.Count;
  199. values.Add(average.ToString("#0.00"));
  200. }
  201. }
  202. }
  203. string totalPath = $"{path}/{"灭火任务总体指标报告"}.xls";
  204. DataTableExtensions.SaveToExcel(totalPath, totalReport,true);
  205. string equicPath = $"{path}/{"装备体系评估报告"}.xls";
  206. DataTableExtensions.SaveToExcel(equicPath, equipReport);
  207. }
  208. }
  209. [ObjectSystem]
  210. public class MhRescueMissionAwakeSystem : AwakeSystem<MHRescueMission,FireGround,double>
  211. {
  212. public override void Awake(MHRescueMission self, FireGround fire, double initArea)
  213. {
  214. self.FireGround = fire;
  215. self.InitArea = initArea;
  216. }
  217. }
  218. [ObjectSystem]
  219. public class RescueMissionUpdateSystem : UpdateSystem<MHRescueMission>
  220. {
  221. public override void Update(MHRescueMission self)
  222. {
  223. if(!self.IsRunning) return;
  224. if (self.FireGround.countArea.burnarea <= 0)
  225. {
  226. self.Success = true;
  227. self.EndMission();
  228. return;
  229. }
  230. if(self.tn >= 10 * 60 * 60)
  231. {
  232. self.Success = false;
  233. self.EndMission();
  234. return;
  235. }
  236. self.aircrafts.Sort((a, b) => a.T.CompareTo(b.T));
  237. self.aircrafts.ForEach(a => a.Update(self.SimTime));
  238. self.SimTime += 1 * TaskComponent.Speed;
  239. }
  240. }