summaryrefslogtreecommitdiff
path: root/sim/src/ai.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sim/src/ai.cpp')
-rw-r--r--sim/src/ai.cpp69
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