#include "ai.h" #include #include #include #include #include #include "TeamManager.h" namespace kurator { namespace sim { static double find_worst_range(State& ctx, entt::entity ship); void setup_ai_components(State&) { // e.g., remove other actions if new one is inserted. } void pick_random_targets(State& ctx, TeamManager& manager) { auto view = ctx.registry.view(); for (auto&& [entity, team, ai] : view.each()) { if (!ctx.registry.valid(ai.target)) { ai.target = manager.random(team.id); ctx.registry.emplace_or_replace(entity, find_worst_range(ctx, entity), ai.target); } } } void keep_at_range(State& ctx) { auto view = ctx.registry.view(); for (auto&& [entity, ai, action] : view.each()) { if (!ctx.registry.valid(action.target)) continue; const auto here = ctx.registry.get(entity).position; const auto there = ctx.registry.get(action.target).position; const auto offset = there - here; ai.destination = there - offset.normalized().scale(action.distance); } } void shoot_at_targets(State& ctx) { auto view = ctx.registry.view(); for (auto&& [entity, turret] : view.each()) { if (!ctx.registry.all_of(turret.owner)) continue; const auto& [state, transform] = ctx.registry.get(turret.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 <= turret.type.effective_range()) turret.shoot_at(ctx, state.target, distance); // passing distance here is wrong } } double find_worst_range(State& ctx, entt::entity ship) { double range = 20000.0; auto turrets = ctx.registry.view(); for (const auto& [_, turret] : turrets.each()) { if (turret.owner == ship) range = std::min(range, turret.type.optimal_range); } return range; } } // namespace sim } // namespace kurator