diff --git a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs index ea7a334..d6a2e61 100644 --- a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs +++ b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs @@ -137,7 +137,7 @@ namespace CounterDrone.Core.Algorithms float cloudDiameter = effectiveR * 2f; float droneSpeed = (float)threat.Target.TypicalSpeed / 3.6f; float physicsInterval = Math.Max(candidates[0].Unit.ChannelInterval, - cloudDiameter / Math.Max(0.1f, droneSpeed)); + cloudDiameter / droneSpeed); float spacing = effectiveR * 1.5f; foreach (var c in candidates.OrderBy(c => c.EarliestInterceptTime) @@ -263,6 +263,7 @@ namespace CounterDrone.Core.Algorithms float dz = mid.Z - unit.Position.Z; float dist = (float)Math.Sqrt(dx * dx + dz * dz); + if (unit.MuzzleVelocity <= 0) return null; float maxRange = unit.MuzzleVelocity * unit.MuzzleVelocity / 9.81f; if (dist > maxRange * 0.8f) return null; @@ -290,13 +291,13 @@ namespace CounterDrone.Core.Algorithms FireUnit unit, AerosolType ammoType, AmmunitionSpec ammo, (float radius, float expTime) ammoEff, CombatScene env) { + if (unit.ReleaseAltitude <= 0 || unit.CruiseSpeed <= 0) return null; var mid = ThreatMidpoint(threat); - float releaseAlt = unit.ReleaseAltitude > 0 ? unit.ReleaseAltitude : (float)threat.Target.TypicalAltitude + 500f; + float releaseAlt = unit.ReleaseAltitude; float flightDist = Kinematics.Distance3D( unit.Position.X, unit.Position.Y, unit.Position.Z, mid.X, releaseAlt, mid.Z); - float cruiseSpd = unit.CruiseSpeed > 0.1f ? unit.CruiseSpeed : 55f; - float flightTime = flightDist / cruiseSpd; + float flightTime = flightDist / unit.CruiseSpeed; float fallTime = Kinematics.AirDropFallTime(releaseAlt, (float)threat.Target.TypicalAltitude); float totalTime = flightTime + fallTime; @@ -416,40 +417,47 @@ namespace CounterDrone.Core.Algorithms // 按目标点位置计算无人机到达时间,非中点 float droneSpeed = (float)threat.Target.TypicalSpeed / 3.6f; + if (droneSpeed <= 0) return events; float startX = (float)threat.Waypoints[0].PosX; float startZ = (float)threat.Waypoints[0].PosZ; float endX = (float)threat.Waypoints[^1].PosX; float endZ = (float)threat.Waypoints[^1].PosZ; float totalDist = Kinematics.Distance2D(startX, startZ, endX, endZ); + if (totalDist <= 0) return events; float distToTx = Kinematics.Distance2D(startX, startZ, tx, tz); - // 如果目标点在航路反向,截断到 [0, totalDist] distToTx = Math.Max(0, Math.Min(totalDist, distToTx)); - float txArrival = totalDist > 0.1f ? distToTx / Math.Max(0.1f, droneSpeed) : 0; + float txArrival = distToTx / droneSpeed; float recommendedTiming = txArrival - expansionTime; - if (recommendedTiming < 0.1f) recommendedTiming = 0.1f; + // 来不及:无人机到达时云团未形成 → 跳过此目标点 + if (recommendedTiming <= 0f) return events; float fireTime; if (unit.Type == PlatformType.AirBased) { - float releaseAlt = unit.ReleaseAltitude > 0 ? unit.ReleaseAltitude : (float)threat.Target.TypicalAltitude + 500f; + if (unit.ReleaseAltitude <= 0 || unit.CruiseSpeed <= 0) + throw new InvalidOperationException($"空基单元 {unit.Id}: ReleaseAltitude={unit.ReleaseAltitude}, CruiseSpeed={unit.CruiseSpeed} 必须>0"); + float releaseAlt = unit.ReleaseAltitude; + float cruiseSpd = unit.CruiseSpeed; float flightDist = Kinematics.Distance3D( unit.Position.X, unit.Position.Y, unit.Position.Z, tx, releaseAlt, tz); - float cruiseSpd = unit.CruiseSpeed > 0.1f ? unit.CruiseSpeed : 55f; float flightTime = flightDist / cruiseSpd; float fallTime = Kinematics.AirDropFallTime(releaseAlt, (float)threat.Target.TypicalAltitude); fireTime = recommendedTiming - flightTime - fallTime; } else { + if (unit.MuzzleVelocity <= 0) + throw new InvalidOperationException($"地基单元 {unit.Id}: MuzzleVelocity={unit.MuzzleVelocity} 必须>0"); + float mv = unit.MuzzleVelocity; float dx = tx - unit.Position.X; float dz = tz - unit.Position.Z; float dist = (float)Math.Sqrt(dx * dx + dz * dz); - float shellTime = dist / (unit.MuzzleVelocity > 0.1f ? unit.MuzzleVelocity : 800f); + float shellTime = dist / mv; fireTime = recommendedTiming - shellTime; } - if (fireTime < 0.1f) fireTime = 0.1f; + if (fireTime <= 0f) return events; // 平台来不及到达 events.Add(new FireEvent {