#include #include #include #include #include #include #include namespace kurator { namespace sim { bool consume(float& dt, double& target); void TurretControl::update(State& ctx) { auto view = ctx.registry.view(); for (auto&& [entity, control, def] : view.each()) { if (!ctx.registry.valid(control.owner)) { ctx.registry.destroy(entity); continue; } if (!ctx.registry.all_of(control.owner)) continue; const auto& [state, transform] = ctx.registry.get(control.owner); if (!ctx.registry.valid(state.target)) continue; const auto& target = ctx.registry.get(state.target); const auto distance = transform.position.distance(target.position); if (distance > def.effective_range()) continue; auto remaining_dt = ctx.clock.dt; while (remaining_dt > 0.0) { if (control.rounds < 1 && consume(remaining_dt, control.reload)) control.rounds = def.rounds; if (control.rounds > 0 && consume(remaining_dt, control.delay)) { auto& target_points = ctx.registry.get(state.target); const auto& movement = ctx.registry.get(state.target); auto damage = def.effective_damage(distance, movement.speed.magnitude()); if (damage > 0.0) { damage = target_points.deal(damage); ctx.dispatcher.trigger(Hit{damage, control.owner, state.target}); } control.delay = def.rate_of_fire; if (--control.rounds < 1) control.reload = def.reload; } } } } bool consume(float& dt, double& target) { if (target <= 0.0) return true; const auto _dt = dt; dt -= target; target -= _dt; return target <= 0.0; } } // namespace sim } // namespace kurator