#include #include #include #include #include #include namespace kurator { namespace sim { bool consume(float& dt, double& target); void TurretControl::update(entt::registry& registry, entt::dispatcher& dispatcher, const float dt) { auto view = registry.view(); for (auto&& [entity, control, def] : view.each()) { if (!registry.valid(control.owner)) { registry.destroy(entity); continue; } const auto& [state, transform] = registry.get(control.owner); // no checks if (!registry.valid(state.target)) continue; const auto& target = registry.get(state.target); const auto distance = transform.position.distance(target.position); if (distance > def.optimal_range * 2.5) continue; auto remaining_dt = 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 = registry.get(state.target); const auto damage = def.effective_damage(distance); if (damage > 0.0) { target_points.health -= damage; 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