fix: stagger=roundInLane*speed 替代 ch*speed——通道展开为1后ch永远为0
- roundInLane = singleNeeded - laneNeeded[currentLane] - 跨度从 0.125s → 7.39s - Piston: 2/3 击毁
This commit is contained in:
parent
c5c1b79946
commit
0c9cdb7b82
@ -162,14 +162,12 @@ namespace CounterDrone.Core.Algorithms
|
||||
int remaining = remainingMunitions.GetValueOrDefault(c.Unit.Id, 0);
|
||||
if (remaining <= 0) continue;
|
||||
|
||||
// 找下一个有需求的车道
|
||||
while (currentLane < yLanes && laneNeeded[currentLane] <= 0) currentLane++;
|
||||
if (currentLane >= yLanes) break;
|
||||
|
||||
int toTake = Math.Min(Math.Min(c.Unit.TotalChannels, remaining), laneNeeded[currentLane]);
|
||||
if (toTake <= 0) continue;
|
||||
|
||||
// 此单元的所有弹药锁定同一个 Y 车道
|
||||
int yLane = currentLane;
|
||||
var refEvt = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, 0, yLane, yLanes, formationWidth);
|
||||
float unitBaseTime = refEvt[0].FireTime;
|
||||
@ -180,8 +178,10 @@ namespace CounterDrone.Core.Algorithms
|
||||
{
|
||||
float offset = (eventIdx - (totalRoundsNeeded - 1) / 2f) * spacing;
|
||||
var fe = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, offset, yLane, yLanes, formationWidth);
|
||||
// 车道内序号 = 该车道已分配的弹药数
|
||||
int roundInLane = singleNeeded - laneNeeded[currentLane];
|
||||
foreach (var e in fe)
|
||||
e.FireTime = unitBaseTime + ch * stagger;
|
||||
e.FireTime = unitBaseTime + roundInLane * stagger;
|
||||
fevents.AddRange(fe);
|
||||
eventIdx++;
|
||||
}
|
||||
|
||||
@ -52,6 +52,21 @@ namespace CounterDrone.Core.Tests
|
||||
var engine = new SimulationEngine(_scenario, _frameStore, new DamageModelRouter(), _paths, new DefaultDefensePlanner(_ammoCatalog));
|
||||
|
||||
engine.Initialize(_taskId);
|
||||
|
||||
// 诊断:检查 _fireSchedule 的时序
|
||||
var fld = typeof(SimulationEngine).GetField("_fireSchedule", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (fld != null)
|
||||
{
|
||||
var schedule = fld.GetValue(engine) as System.Collections.IList;
|
||||
if (schedule != null && schedule.Count > 0)
|
||||
{
|
||||
var ftimes = schedule.Cast<object>().Select(e => ((dynamic)e).FireTime).Cast<float>().ToList();
|
||||
System.IO.File.WriteAllText(@"C:\Users\Tellme\Desktop\schedule_dump.txt",
|
||||
$"count={schedule.Count} first={ftimes.Min():F3} last={ftimes.Max():F3} span={ftimes.Max()-ftimes.Min():F3}\n" +
|
||||
string.Join("\n", ftimes.Select((t,i) => $"{t:F3}")));
|
||||
}
|
||||
}
|
||||
|
||||
engine.TimeScale = 8f; // 8倍速加速
|
||||
for (int i = 0; i < maxTicks; i++)
|
||||
{
|
||||
@ -212,12 +227,15 @@ namespace CounterDrone.Core.Tests
|
||||
var launched = eng.Events.Count(e => e.Type == SimEventType.MunitionLaunched);
|
||||
var clouds = eng.Events.Count(e => e.Type == SimEventType.CloudGenerated);
|
||||
|
||||
var msg = $"Piston: launched={launched} clouds={clouds} drones={eng.Drones.Count}";
|
||||
var times = eng.Events.Where(e => e.Type == SimEventType.MunitionLaunched).Select(e => e.OccurredAt).OrderBy(t => t).ToList();
|
||||
var timeInfo = $"times=[{times.First():F2}..{times.Last():F2}] span={times.Last()-times.First():F2}s";
|
||||
|
||||
var msg = $"Piston: launched={launched} clouds={clouds} drones={eng.Drones.Count} {timeInfo}";
|
||||
foreach (var d in eng.Drones)
|
||||
msg += $" [{d.Status} hp={d.Hp:F2}]";
|
||||
VerifyAndExportReport(eng, eng.Drones[0]);
|
||||
Assert.True(launched > 0, msg);
|
||||
Assert.All(eng.Drones, d => Assert.Equal(DroneStatus.Destroyed, d.Status));
|
||||
Assert.True(eng.Drones.All(d => d.Status == DroneStatus.Destroyed), msg);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════
|
||||
|
||||
Loading…
Reference in New Issue
Block a user