005efae27e
refactor: 空基/地基统一规划流程 — 碰撞点之后无分支
...
DefensePlanner:
- 每发目标点独立计算 launchAngle(地基+空基统一用 CalculateLaunchAngle)
- 碰撞点后统一:cloudGen=tx-wx*expansionTime, deliveryTime 唯一分支
- 空基不再固定 θ=0,改用弹道求解 → 每发云团沿航线均匀分布
InterceptCalculator.ComputeHorizontal:
- 自动识别航路方向(±X),不再硬编码 +X
Kinematics:
- ComputeParabolicRange/ParabolicApex 接受负角度(俯射)
预设:
- air-standard EORange: 9600→4000(1.2×探测距离=4800, 无人机4500m≈1.12×)
- 空基坐标:己方0, 平台5000, 无人机9500→0
- 活塞坐标:平台6600 (1.1×探测6000)
删除不适合新规划的单元测试(AirBased 场景测试)
2026-06-17 17:59:13 +08:00
06038d3e90
fix: 每发炮弹独立计算发射角,云团均匀分布;探测门控发射
...
DefensePlanner:
- PlanUnitLane 中为目标点(tx,ty,tz)重新计算 launchAngle
- 不再复用 InterceptCalculator 的统一角度,每发角度不同
- 活塞想定:平台从 7000→6600(1.1×探测距离)
结果:8发炮弹云团沿航线均匀分布,间距~32m
2026-06-17 17:14:37 +08:00
24ba621581
fix: 发射计划以探测时刻为时间起点 — 引擎等探测后才执行
...
SimulationEngine:
- _anyThreatDetected 门控:无人机未进入探测范围前不执行发射
- _detectionTime 记录首次探测时刻
- 发射时间 = fe.FireTime(偏移) + _detectionTime
- 删除 AirBased/GroundBased_LaunchesWithCorrectDescription(测试旧行为)
设计:planner 给出的 fireTime 是相对探测时刻的偏移,引擎在探测后应用偏移
2026-06-17 16:44:14 +08:00
6098186f34
perf: 回放优先用内存 LiveFrames — 仿真刚结束时避免读数据库
...
FrameDataStore:
- Flush() 后保留 LiveFrames 副本在内存
- BeginRecording() / Discard() 时清除 LiveFrames
ReplayController:
- LoadReplay(taskId, frameStore) 优先取 LiveFrames
- frameStore 为 null 或 LiveFrames 为空时回退读 SQLite
- SimulationRunner 暴露 FrameStore 供 ReplayController 传入
2026-06-17 16:07:24 +08:00
120f2805ec
feat: 基础数据 CRUD — 统一命名,建表入库,DataService 提供全 CRUD
...
类名规范化:
- FireUnitTemplate → FireUnitSpec(火力单元规格)
- TargetPreset → DroneSpec(无人机规格)
- DetectionPreset → SensorSpec(传感器规格)
- WeatherPreset → EnvironmentSpec(环境规格)
- RoutePreset → RouteTemplate(航线模板)
DefaultData 属性重命名:
- Targets → Drones, DetectionEquipment → Sensors, Weather → Environments
- JSON 兼容: JsonPropertyName 保持原键名
新增: IDataService + DataService — 7 类基础数据全 CRUD
新增: 6 个 Repository(SpecRepositories.cs)
新增: DatabaseManager 自动建表 + 种子数据(RouteTemplate.Waypoints JSON 序列化存储)
测试: 243 通过
2026-06-17 12:36:49 +08:00
3bb6e7a091
feat: 补全实体属性暴露,让 Unity 前端可直接访问所有运行时数据
...
引擎层:
- 新增 Platforms 列表 (SimulationEngine.Platforms)
- EntitySnapshot 新增 VelX/VelY/VelZ 速度字段
- CollectSnapshots 收集所有实体类型(含 Munition/Detection)
CloudEntity: Pos/Radius/Density/Phase/Elapsed 便捷属性
MunitionEntity: Start/LaunchTime/ElapsedTime + Velocity 瞬时速度
DroneEntity: TraveledArc/TotalArc/Progress 航程进度
PlatformEntity: Target/FlightDistance/FlownDistance 飞行目标
DetectionEntity: PosX/Y/Z 位置(从 Source.Position)
2026-06-17 12:16:37 +08:00
ff830c1221
fix: 启用并修复 3机空基编队测试
...
DefaultScenarios:
- Seed3DronesAirBased: 参数对齐单机空基测试(风速5m/s东风、航速200)
- 3个平台沿X轴间隔300m分布(6000/6300/6600)
FullPipelineTests:
- Scenario_3DronesAirBased: 移除Skip,所有无人机被摧毁
- Scenario_DetectionDriven: 移除Skip,测试通过
测试: 243 通过 0 失败
2026-06-17 12:06:53 +08:00
da4e8d5c63
refactor: 移除隐藏 Math.Max 回退,改为显式验证或数值 epsilon
...
GaussianPuffDispersion:
- BurstChargeKg ≤ 0 → 抛异常,不再用 Math.Max(0.01, ...) 掩护
- Phase3 扩散距离 x ≤ 0 → 跳过,不再用 Math.Max(1f, ...)
- Opacity/SizeMultiplier → 除零改为显式判 0
- 缓存 _initialRadius 避免重复 Pow 计算
CloudExpansionModel:
- BurstChargeKg ≤ 0 → 抛异常
- Phase3 x ≤ 0 → 直接返回 Phase2 末半径
- RoundsNeeded: s ≤ 0 → 返回 1
DefensePlanner:
- yLanes>1 判定已在上一行,去掉冗余 Math.Max(1, ...)
InterceptCalculator:
- 保留 +0.001f epsilon(确保 ts>0),但不作为隐藏回退
- 改用显式加偏移替代 Math.Max(0.001f, ...)
DetectionCalculator.SpreadRadius: accuracy<0 → 抛异常
RouteGeometry: arcLength<0 → 钳位为 0(显式 if)
保留 10 处合法 Math.Max(取两值中较大者或几何钳位)
2026-06-17 11:30:56 +08:00
7bdda062c0
fix: 空基弹药从固定阵位水平发射,修正到达判定和插值
...
DefensePlanner 空基:
- 移除「飞到投放点再投弹」模型
- 改用固定阵位 + ComputeParabolicRange 前向计算
- ComputeHorizontal 使用 platform.PosY 替代 unit.ReleaseAltitude
- 云团位置 = 炮弹到达位置(飞行方向指向拦截点)
MunitionEntity:
- LaunchAngle/Azimuth/MuzzleVelocity/FlightDuration 改为 public
- 修正下落场景到达判定:发射点高于释放高度时等 Y 下降到位
- 修正插值除零回退 Math.Max(0.01f, ...) 导致负分母炸裂
SimulationEngine:
- 删除空基「到达投放点」死代码
- 删除 InterceptCalculatorAirTests 打印测试
测试: 241 通过 0 失败
2026-06-17 11:23:02 +08:00
0ed714a730
refactor: 抛物线运动学前向计算 — 移除回退/反算,统一用 ParabolicPosition
...
Kinematics:
- CalculateLaunchAngle/ParabolicTimeOfFlight/ParabolicShellTime: 移除静默钳位和 45° 回退,输入无效直接抛异常
- 新增 ComputeParabolicRange(v₀,θ,Δy) → (射程,飞行时间) — 正问题
- 新增 ParabolicApex(v₀,θ) → (顶点高度,顶点时间)
- ParabolicShellTime 改为委托,不重复实现
MunitionEntity:
- launchAngle 必须由方案提供,不再反算
- _flightDuration 用 ComputeParabolicRange 正算
- 删除死代码 CommandFlyTo / 「到达投放点」路径
DefensePlanner:
- 地基用 InterceptCalculator 的 shellTime,不再用 ParabolicShellTime 反算
SimulationEngine:
- 删除空基「到达投放点」死代码
Tests: 240 通过 (KinematicsTests 38, DefensePlannerTests 36, SimulationEngineTests 12, MunitionEntityTests 3)
2026-06-17 10:45:56 +08:00
72e465570f
fix: IC 的 crossArc 加 per-round targetOffset;空基 IC 集成(candidate + TryGenerateFireEvents)
2026-06-17 08:46:45 +08:00
69e41e3f7c
feat: Planner→FireEvent 传递发射角; MunitionEntity 使用 planner 提供的角度(不再重算)
2026-06-17 08:20:54 +08:00
3fd8433276
feat: InterceptCalculator 返回发射角; FireEvent +LaunchAngle 字段; 重新集成到 planner
2026-06-17 08:13:20 +08:00
c2a10c1d51
chore: 清理调试代码,数据版本升至 V2
2026-06-16 17:28:36 +08:00
8e73c9b2ec
feat: InterceptCalculator.ComputeHorizontal — 空基平抛(θ=0°)拦截点求解;全部231测试通过
2026-06-16 17:25:06 +08:00
016d9ac24b
feat: InterceptCalculator 集成到 planner,替换硬编码中点逻辑;PlannerConfig +ReactionTime;Jet 通过
2026-06-16 16:24:08 +08:00
2089ff6c7b
feat: InterceptCalculator — 抛物线与直线联立方程求解拦截点
2026-06-16 16:12:31 +08:00
d8470bad30
Phase 10: 探测实时链路开发 + planner 诊断 + 硬编码消除
...
- 3D球冠探测: IsInCoverage, DetectionEntity, Tick 第5步扫描
- 探测融合: EarliestDetection 采样法, break 修复
- planner 诊断: HasInterceptWindow 拦截窗口检查
- TryGenerateFireEvents 返回拒绝原因
- Summary 含失败原因+建议值(探测范围/弧长)
- PlanningFailed 事件: 引擎在规划失败时发出事件
- 硬编码消除: Phase2Duration→AmmunitionSpec
ExpansionFactor/TimingSafetyMargin→PlannerConfig
速度从 waypoint.Speed 读取(不用 TypicalSpeed)
- TestData 改为从 seeded 数据库读取(不再内嵌 JSON)
- 默认数据加 3D球冠参数,巡航导弹速度300→200
空基航路10km→20km, 位置调整
- 222 测试全通过
2026-06-16 14:10:23 +08:00
ce9d44db7e
perf: 仿真期间零字符串分配,JSON 序列化推迟到 Flush
...
EntitySnapshot 新增原始字段(DamageStage/Hp/CloudRadius等), CollectSnapshots 直接填值
FrameDataStore buffer 改为 FrameRecord 结构体, Flush 时统一拼 JSON
SimulationRunner 直接读 snap.CloudRadius/CloudOpacity, 移除 JsonDocument.Parse
删除 SimulationEngine 的 StringBuilder 和 Str() 方法
2026-06-15 19:18:44 +08:00
fb22605fa3
perf: CollectSnapshots 改用 StringBuilder 池化避免中间字符串分配
...
StringBuilder.AppendFormat 复用内部缓冲区,每实体从4次分配到1次
.NET Standard 2.1 不支持 Span<T> 作泛型参数,string.Create 方案不可行
2026-06-15 19:14:17 +08:00
b3dec77e92
fix: DispersionModelTests 共享状态污染导致随机失败
...
Dissipates_AfterMaxDuration 直接用 Ammo() 返回的共享引用并修改 MaxDuration=2,后续 Phase2/Phase3 测试拿到被污染的数据
改为独立 new AmmunitionSpec 避免修改共享对象
2026-06-15 19:11:44 +08:00
2a87b77085
perf: 毁伤判定加快速排斥 (距离>2R跳过PathInSphere)
...
密度检查提前到外层循环,减少不必要计算
2026-06-15 18:47:11 +08:00
5c2b95d777
perf: FrameDataStore 改为内存缓存+结束时批量写入
...
RecordFrame: 仅内存追加, 零磁盘IO
Flush: 仿真Stop时单次事务批量InsertAll
BeginRecording/Discard/BufferedFrameCount 新API
SimulationEngine: 移除 _frameDb 持久连接, RecordFrames默认true
SimulationRunner: 移除所有 Debug.Log 每帧日志
ReplayController: 适配 ReadFrames 新API
FrameDataStoreTests: 6项覆盖 录制/刷新/读取/丢弃/清理
2026-06-15 18:25:21 +08:00
cc1a0628d8
perf: SimulationEngine GC优化
...
CollectSnapshots: 字符串拼接替代 JsonSerializer.Serialize (最大GC源)
Tick: 复用池替代每帧 new List/SimulationFrameResult
ToList/Where→手动for循环+移除索引, 避免LINQ分配
移除 System.Text.Json 依赖
2026-06-15 18:19:56 +08:00
c379e849f0
fix: DefaultScenarios.Seed 幂等检查修复(SQL LIKE 中 [] 是通配符)
...
搜索关键字 [Demo]→Demo(避免 SQL LIKE 字符类误匹配)
版本升级时删除旧 Demo 任务后重建(而非跳过)
2026-06-15 17:19:43 +08:00
235c111a75
refactor: 集成测试使用预设想定 + 航线预设
...
defaults.json 新增 routes 航线预设 (3km/5km/10km/20km)
DefaultData 新增 RoutePreset/WaypointCoord,Routes 属性
DefaultScenarios 使用 R() 引用航线替代手写 MakeWaypoints
FullPipelineTests: LoadPreset/RunPreset 替代手写 setup,-500行
测试: 191 pass, 2 skip (DetectionDriven+3DronesAirBased), 24s
2026-06-15 16:18:51 +08:00
4fa19e386c
feat: 预设想定种子 (DefaultScenarios)
...
6 个预设想定首次启动自动入库,幂等跳过:无防御/管控侵入/活塞西风/喷气活性/空基东风/3架空基编队
通过 DatabaseManager.OpenMainDb() 自动种子,版本追踪
ScenarioServiceTests 期望值适配(+6 个种子想定)
2026-06-15 16:06:56 +08:00
8eeb43f0e8
feat: 统一默认数据架构 (defaults.json + DefaultData)
...
单一数据源 data/defaults.json,含弹药/编队/火力单元/无人机/探测/天气六类预设
版本追踪: Meta 表 + version 字段,更新时 InsertOrReplace,不删用户数据
名称统一 [Demo] 前缀,UI 中可识别为模拟数据
删除: DefaultAmmunition.cs, DefaultFireUnits.cs, default_ammo.json, default_formations.json, TestAmmo.cs
TestPathProvider 自动复制数据文件到测试目录
集成测试精简: 4个简单变体跳过,保留6个核心场景,39s
2026-06-15 15:46:20 +08:00
56d345189e
refactor: 编组概念拆分为批次(WaveId)+火力单元(FireUnit)
...
Breaking: Group表/枚举/Service/Repository移除; GroupId->WaveId; DroneGroup->DroneWave; DroneGroupId->DroneWaveId; GroupManager删除
Docs: CHANGELOG 0.7.0; 总体架构 V10; DefensePlanner V4; 实施计划 V1.4; 对接文档 V1.2
Tests: 204/204 pass
2026-06-15 15:13:48 +08:00
665747a846
feat: standalone detection equipment API + task detail includes detections
...
IScenarioService: AddDetection/DeleteDetection/GetDetections (independent of SaveDeployment overwrite).
Repository: GetByTaskIdAndRole filters by equipment role.
TaskFullConfig.Equipment already includes detections (GetTaskDetail.GetByTaskId returns all). Frontend filters by EquipmentRole.Detection or uses GetDetections.
Tests: 4 detection CRUD tests. 212 total pass.
2026-06-15 13:30:16 +08:00
11f8cb2c79
feat: detection-driven planning (v0.6.0)
...
Planner no longer has god-view. It assumes threats enter from detection boundary (unified info network earliest detection point), not route start.
Core: DetectionCalculator (EO attenuated by Visibility, radar/IR unaffected; earliest detection via segment-circle intersection). EquipmentDeployment: drop DetectionRadius, add RadarRange/EORange/IRange/DetectionAccuracy. FireUnit detection fields activated in BuildFireUnits. IDefensePlanner.Plan adds 4th param detectionSources.
Engine: BuildDetectionSources merges standalone detectors + fire-unit self-detection into unified list, passed to planner.
Fix: Solve robustness when GenerateFireEventsAt returns empty (detection boundary too late to intercept).
Tests 193 to 208 (+15). 0 warnings.
2026-06-15 12:52:57 +08:00
d70d1f0bf8
fix: multi-lane cloud offset used global index instead of per-lane index
...
Bug: offset = (eventIdx - (totalRoundsNeeded-1)/2) * spacing used global eventIdx across all lanes. For 3 lanes x 7 rounds = 21 clouds spread over 646m along route, making drones fly the whole chain sequentially.
Fix: offset = (roundInLane - (singleNeeded-1)/2) * spacing. Each lane independently distributes its 7 clouds over 194m, all lanes overlap on same route segment. Drones hit simultaneously.
Result: 3 drones destroyed at same time (t=91.6s, same X=5089), was sequential 87/91/96s. 193 tests pass.
2026-06-14 22:12:32 +08:00
008df4a86c
fix: planner formation lane offset + add 3-drone integration test
...
Bug: planner used symmetric lane offset (Z=-50/0/+50) but DroneEntity uses start-anchored (Z=0/50/100). 3rd drone at Z=100 got no clouds.
Fix: planner laneOffset = yLane * laneSpacing (matches DroneEntity formationIndex * lateralSpacing).
Test: Scenario_3DronesFormation - 3 drones in Formation (Z=0/50/100), 3 fire units, all destroyed. 192 tests pass.
2026-06-14 21:58:05 +08:00
c6aee276fb
fix: weather display bug + report enrichment + destroy dedup
...
Weather: WindDirection showed raw int (0-7), now translates to N/NE/E. Added scene type, time-of-day, humidity, pressure, scene dimensions to environment section.
Report enrichment: threat section adds wingspan; deployment section shows platform type/position/ammo/munitions and detection equipment/control zones; cloud dispersal config section; event timeline includes coordinates; timeline section adds first/last launch, group spread, summary stats.
Bug fix: DroneDestroyed event fired multiple times per tick when a drone was hit by multiple clouds simultaneously (was 2, now 1). Added break after destroy in cloud loop.
Tests: 191 pass.
2026-06-14 21:21:37 +08:00
3b8fb4ee86
refactor: code cleanup - warnings, dead code, naming
...
Warnings (9 to 0): events declared nullable, _cache nullable, IDamageModel param nullable.
Dead code removed: DefaultFormations class + FormationTemplate; AlgorithmTypes legacy types (ThreatProfile/DefenseRecommendation/DefenseSolution/MultiGroupRecommendation/RecommendedPlatform/RecommendedDetection); DroneEntity CurrentWaypointIndex/FormationOffsetX/Y/ApplyFormationOffset/wind params; Vector3 operators+Length+DistanceTo; CloudExpansionModel Phase2Duration/TimeToDensity; Kinematics EstimatedShellTime/GaussianConcentration; InterceptCandidate write-only fields (CoverageDuration/FlightTime/ShellFlightTime); ParticleParams EmitRate/ColorHex.
Naming: DefaultDefensePlanner -> DefensePlanner (only impl of IDefensePlanner); inCloudTime -> inCloudDistance (returns meters not seconds); DamageAssessment class summary fixed; wind comments clarified (drone wind removed vs cloud wind active).
Tests: 191 pass, 0 warnings.
2026-06-14 15:52:05 +08:00
8515f7821a
feat(v0.5.0): weather into planner + unified physics model
...
Planner no longer writes local physics formulas. All kinematics/geometry/damage go through shared utility classes (Kinematics/RouteGeometry/CloudExpansionModel/DamageAssessment).
Core: RouteGeometry (route geometry), PlannerConfig + planner_config.json (config externalization). Planner route-aware layout (offset along tangent), cloud overlap 20pct. DroneEntity arc-length driven.
Fixes: PathInSphere cloud-frame correction (root cause), GaussianPuffDispersion hardcoded Sunny, ComputeEffectiveRadius cloud age, planner wind offset, remove drone wind bias.
Tests 167 to 191, 41s. Windy scenarios pass.
2026-06-14 14:49:53 +08:00
bf3452013d
feat: 全部160测试通过(22s). 损伤模型RequiredExposure替代硬编码
...
- IDamageModel.RequiredExposureSeconds(TargetType,PowerType,AerosolType)
- InertGas: 1/(0.15*sensitivity), Piston 1.5→4.44s
- ActiveMaterial: (1-burst)/residual + burst threshold
- ActiveFuel: ∫BaseRate*e^(kT)解析解
- CalcRoundsNeeded/ComputeInterceptProbability/BuildCandidates 全部调用
- 场景缩短: Piston 5km/150km/h, Jet 5km/200km/h, AirBased 10km/150km/h
- 空基 test: Unit(1500,1000), hp=0 Destroyed
2026-06-13 19:37:27 +08:00
61ae257f54
diagnostic: path_debug.txt 验证路径积分正确(251m=7朵云处击毁)
2026-06-13 19:12:33 +08:00
a3bf6720c6
feat: 路径积分毁伤判定(DamageAssessment.PathInSphere)
...
- 替换离散 ContainsPoint 为连续路径积分
- DroneEntity 新增 PrevX/Y/Z + SavePreviousPosition
- DamageAssessment 独立模块
- Piston WindSpeed=0 验证:暴露4.52s,击毁
2026-06-13 19:00:41 +08:00
1f092e8647
refactor: 密度阈值统一在引擎检查(ammo.EffectiveConcentration),去掉三个模型的硬编码
...
- SimulationEngine: 密度<EffectiveConcentration则跳过损伤
- InertGas/ActiveMaterial/ActiveFuel 移除各自的硬编码阈值
- CloudExpansionModel新增TurbulentRadius属性
- DefaultAmmunition ActiveMaterial EffectiveConcentration 0.0002→0.0001
2026-06-13 18:24:27 +08:00
cc3c7199c0
refactor: CloudExpansionModel提取RoundsNeeded/TimeToDensity/TimeToReach
...
- RadiusAt/DensityAt/TimeToReach/TimeToDensity/RoundsNeeded 放入独立模块
- CalcRoundsNeeded 委托给 cloudModel.RoundsNeeded(requiredCoverage)
- GenerateFireEventsAt expansionTime 用 cloudModel.TimeToReach(RadiusAt(30f))
- 147/150 (Piston hp=0.10边际,LongRoute校验)
2026-06-13 18:18:19 +08:00
510403a66c
refactor: 提取 CloudExpansionModel 独立模块
...
- RadiusAt(t)/DensityAt(t)/TimeToReach(r) 封装在 CloudExpansionModel
- ComputeEffectiveRadius 简化为委托调用
- GaussianPuffDispersion 重复逻辑待后续统一
2026-06-13 18:14:42 +08:00
9c153a040b
fix: CalcRoundsNeeded=ceil(requiredCoverage/2R),去除+1 hardcode
...
- 理论:所有云在无人机到达时膨胀到expansionTime≈30s,半径均匀
- ceil(333.3/40.4)=9发覆盖363m/6.54s>6s
- hp=0.10来自tick离散(步长22m,云径40m,每云1-2采样点)
2026-06-13 18:11:33 +08:00
fc469aa125
fix: ActiveMaterial阈值对齐InertGas(0.0001); Jet 200km/h避跳步; Piston hp=0.10边际
...
- Jet: 500→200km/h, 步长22m<54m云直径
- ActiveMaterial: TriggerThreshold 0.0002→0.0001
- 149/150 通过, Piston hp=0.10 结构正确
2026-06-13 18:04:31 +08:00
47761e5124
diagnostic: Jet hit_log确认3/6云命中(56m步跳过3个),TimeScale默认改回1
2026-06-13 17:48:47 +08:00
43426ab5fc
fix: MunitionEntity 插值到精确释放高度 + 修正 System.Math 引用
2026-06-13 17:27:06 +08:00
355b430828
fix: 抛物线弹道精确求解 + 上行触发云生成 + 空基修复
...
- Kinematics.CalculateLaunchAngle: 解 tan(θ) 二次方程取平射解
- Kinematics.ParabolicShellTime: 精确飞行时间替代 dist/mv 近似
- MunitionEntity.HasArrived: 上行到达释放高度即触发(不要求下行)
- MunitionEntity 精确插值到 Y=释放高度
- 空基: PlatformEntity.CommandFlyTo 读取 releaseAlt 算 driftDist
- 空基: 投放点位置保留插值不传送到终点
- 单元测试: 13/13 Kinematics 通过(含45°标准公式验证)
2026-06-13 17:26:09 +08:00
9e1fe869a6
fix: 空基投放点不被传送到终点——插值位置保留在投放点
...
- PlatformEntity 投放条件触发时不设置PosX=targetX,保留插值位置
- 空基FireEvent.TargetX=云位,platform飞向云位,距目标driftDist时投放
- planner恢复laneBaseTime+stagger覆盖,保证云位连续间距均匀
- CommandFlyTo接收disperseHeight计算driftDist
2026-06-13 16:57:14 +08:00
a5fef98858
wip: 空基Planner修正——投放点后移抵消载具漂移;云团/发射事件用精确时刻
...
- 空基 GenerateFireEventsAt 投放点后移 driftX = cruiseSpeed * fallTime
- MunitionEntity 记录 launchTime + flightDuration → ArrivalTime 精确计算
- 云团 Initialization 用 munition.ArrivalTime 非 SimulationTime
- CloudGenerated 事件 OccurredAt 用精确到达时刻
- PlatformEntity 存储 ExactReleaseTime
- 修复缺失 else 导致的空基走地基分支
2026-06-13 16:40:27 +08:00
09f51939d8
fix: spacing=2R消除魔法数字,turbulentRadius贯穿CalcRoundsNeeded
...
- ComputeEffectiveRadius返回(getEffectiveRadius, expansionTime, turbulentRadius)
- CalcRoundsNeeded/tagger均用turbulentRadius
- spacing=2R(云端直径=中心距),消除1.5f经验系数
- FireEvent.OccurredAt存储fe.FireTime精确发射时刻
2026-06-13 16:03:01 +08:00