diff options
Diffstat (limited to 'sim/src/ai.cpp')
-rw-r--r-- | sim/src/ai.cpp | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/sim/src/ai.cpp b/sim/src/ai.cpp index 1f2a4ec..7a0f637 100644 --- a/sim/src/ai.cpp +++ b/sim/src/ai.cpp @@ -1,5 +1,10 @@ #include "ai.h" +#include <algorithm> +#include <utility> + +#include <entt/entt.hpp> + #include <kurator/sim/components.h> #include <kurator/sim/State.h> #include <kurator/sim/weapons.h> @@ -13,6 +18,42 @@ 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<Transform>(self).position; + const auto there = ctx.registry.get<Transform>(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) { @@ -20,20 +61,19 @@ pick_random_targets(State& ctx, TeamManager& manager) 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 -keep_at_range(State& ctx) +take_actions(State& ctx) { - auto view = ctx.registry.view<Transform, AIShip>(); - for (auto&& [entity, self, ai] : view.each()) { - if (!ctx.registry.valid(ai.target)) - continue; - const auto target = ctx.registry.get<Transform>(ai.target); - const auto offset = target.position - self.position; - ai.destination = target.position - offset.normalized().scale(ai.keep_at_range); + auto view = ctx.registry.view<AIShip>(); + for (auto&& [_, ai] : view.each()) { + if (ai.action) + ai.action(); } } @@ -56,5 +96,18 @@ shoot_at_targets(State& ctx) } +double +find_worst_range(State& ctx, entt::entity ship) +{ + double range = 20000.0; + auto turrets = ctx.registry.view<Turret>(); + for (const auto& [_, turret] : turrets.each()) { + if (turret.owner == ship) + range = std::min(range, turret.type.optimal_range); + } + return range; +} + + } // namespace sim } // namespace kurator |