#include "ai.h" #include #include #include #include #include #include #include "TeamManager.h" namespace kurator { namespace sim { static double find_worst_range(State& ctx, entt::entity ship); class KeepAtRange { public: KeepAtRange(State& ctx_, AIShip& ai_, entt::entity self_, entt::entity target_, double distance_) : ctx {ctx_}, ai {ai_}, self {std::move(self_)}, target {std::move(target_)}, distance {distance_} { } void operator()() { if (!ctx.registry.valid(target)) { if (ctx.registry.valid(ai.target)) ai.action = KeepAtRange(ctx, ai, self, ai.target, distance); return; } const auto here = ctx.registry.get(self).position; const auto there = ctx.registry.get(target).position; const auto offset = there - here; ai.destination = there - offset.normalized().scale(distance); } private: State& ctx; AIShip& ai; entt::entity self; entt::entity target; double distance; }; 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); if (!ai.action) ai.action = KeepAtRange(ctx, ai, entity, ai.target, find_worst_range(ctx, entity)); } } void take_actions(State& ctx) { auto view = ctx.registry.view(); for (auto&& [_, ai] : view.each()) { if (ai.action) ai.action(); } } 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