feat: 报告显示Per-unit发射数 + 事件标明火力单元

- 五、我方部署: 从实际发射事件统计每个火力单元发射数(非想定数据)
- 六、事件时序: 新增"火力单元"列,标注每发隶属哪个单元
- PlatformId→火力单元映射复用(去重)
This commit is contained in:
tian 2026-06-13 11:40:21 +08:00
parent 26a372ffc5
commit 0f73bbf55e
3 changed files with 30 additions and 72 deletions

View File

@ -1,63 +0,0 @@
[
{
"Id": "ground-standard",
"Name": "标准地基火力单元",
"PlatformType": 1,
"GunCount": 4,
"ChannelsPerGun": 4,
"ChannelInterval": 1.0,
"Cooldown": 5.0,
"AmmoChangeTime": 30.0,
"MuzzleVelocity": 800.0,
"AmmoTypes": [0, 1],
"RadarRange": 15000.0,
"EORange": 8000.0,
"IRRange": 5000.0
},
{
"Id": "ground-light",
"Name": "轻型地基火力单元",
"PlatformType": 1,
"GunCount": 2,
"ChannelsPerGun": 4,
"ChannelInterval": 1.0,
"Cooldown": 5.0,
"AmmoChangeTime": 30.0,
"MuzzleVelocity": 800.0,
"AmmoTypes": [0, 1],
"RadarRange": 10000.0,
"EORange": 6000.0,
"IRRange": 3000.0
},
{
"Id": "ground-heavy",
"Name": "重型地基火力单元",
"PlatformType": 1,
"GunCount": 6,
"ChannelsPerGun": 4,
"ChannelInterval": 1.0,
"Cooldown": 5.0,
"AmmoChangeTime": 30.0,
"MuzzleVelocity": 600.0,
"AmmoTypes": [0, 1, 2],
"RadarRange": 20000.0,
"EORange": 10000.0,
"IRRange": 6000.0
},
{
"Id": "air-standard",
"Name": "标准空基火力单元",
"PlatformType": 0,
"GunCount": 1,
"ChannelsPerGun": 8,
"ChannelInterval": 1.0,
"Cooldown": 5.0,
"AmmoChangeTime": 30.0,
"CruiseSpeed": 55.0,
"ReleaseAltitude": 1500.0,
"AmmoTypes": [0, 1],
"RadarRange": 0.0,
"EORange": 12000.0,
"IRRange": 8000.0
}
]

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json;
using CounterDrone.Core.Models;
namespace CounterDrone.Core namespace CounterDrone.Core
{ {

View File

@ -86,24 +86,47 @@ namespace CounterDrone.Core.Services
sb.AppendLine(); sb.AppendLine();
} }
// 构建 PlatformId → 火力单元 映射(去重,五和六共用)
var platToEquip = new Dictionary<string, int>();
var unitLaunchCounts = new Dictionary<int, int>();
int platIdx = 1, unitNum = 0;
for (int ei = 0; ei < config.Equipment.Count; ei++)
{
var eq = config.Equipment[ei];
if (eq.EquipmentRole != (int)EquipmentRole.LaunchPlatform) continue;
int channels = (eq.GunCount ?? 1) * (eq.ChannelsPerGun ?? 1);
for (int j = 0; j < eq.Quantity; j++)
{
unitNum++;
for (int c = 0; c < channels; c++)
platToEquip[$"plat_{platIdx++}"] = unitNum;
}
}
foreach (var e in events.Where(e => e.Type == SimEventType.MunitionLaunched))
{
if (platToEquip.TryGetValue(e.SourceId, out var u))
unitLaunchCounts[u] = unitLaunchCounts.GetValueOrDefault(u, 0) + 1;
}
// === 五、我方部署 === // === 五、我方部署 ===
sb.AppendLine("## 五、我方部署"); sb.AppendLine("## 五、我方部署");
sb.AppendLine(); sb.AppendLine();
sb.AppendLine($"| 装备 | 数量 |"); sb.AppendLine($"| 火力单元 | 发射数 |");
sb.AppendLine($"|------|------|"); sb.AppendLine($"|------|------|");
sb.AppendLine($"| 发射平台 | {platforms.Sum(p => p.Quantity)} 台 |"); foreach (var kv in unitLaunchCounts.OrderBy(kv => kv.Key))
sb.AppendLine($"| 云团位置 | ({config.Cloud.PositionX:F0}, {config.Cloud.PositionY:F0}, {config.Cloud.PositionZ:F0}) |"); sb.AppendLine($"| #{kv.Key} | {kv.Value} |");
sb.AppendLine($"| 释放高度 | {config.Cloud.DisperseHeight:F0} m |");
sb.AppendLine(); sb.AppendLine();
// === 六、事件时序 === // === 六、事件时序 ===
sb.AppendLine("## 六、事件时序"); sb.AppendLine("## 六、事件时序");
sb.AppendLine(); sb.AppendLine();
sb.AppendLine("| 时间(s) | 事件 | 详情 |"); sb.AppendLine("| 时间(s) | 事件 | 详情 | 火力单元 |");
sb.AppendLine("|---------|------|------|"); sb.AppendLine("|---------|------|------|:------:|");
int munitionIdx = 0, cloudIdx = 0; int munitionIdx = 0, cloudIdx = 0;
foreach (var e in events.OrderBy(e => e.OccurredAt)) foreach (var e in events.OrderBy(e => e.OccurredAt))
{ {
string unitCell = e.Type == SimEventType.MunitionLaunched && platToEquip.TryGetValue(e.SourceId, out var u)
? $"#{u}" : "-";
var desc = e.Type switch var desc = e.Type switch
{ {
SimEventType.MunitionLaunched => $"第 {++munitionIdx} 发", SimEventType.MunitionLaunched => $"第 {++munitionIdx} 发",
@ -114,7 +137,7 @@ namespace CounterDrone.Core.Services
SimEventType.SimulationEnd => "仿真结束", SimEventType.SimulationEnd => "仿真结束",
_ => e.Description, _ => e.Description,
}; };
sb.AppendLine($"| {e.OccurredAt:F1} | {TranslateEvent(e.Type)} | {desc} |"); sb.AppendLine($"| {e.OccurredAt:F1} | {TranslateEvent(e.Type)} | {desc} | {unitCell} |");
} }
sb.AppendLine(); sb.AppendLine();