summaryrefslogtreecommitdiff
path: root/sim/src/ai.cpp
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2023-04-27 00:36:46 +0200
committerAki <please@ignore.pl>2024-04-05 19:41:19 +0200
commit61d16477b01bcfbe8c3a481a232658ac60309f57 (patch)
tree06882f5a1b7bc987826610736a5b606883df69b9 /sim/src/ai.cpp
parent94d6d863e1b78766cdb5f286e3d9f374c02c5d33 (diff)
downloadkurator-61d16477b01bcfbe8c3a481a232658ac60309f57.zip
kurator-61d16477b01bcfbe8c3a481a232658ac60309f57.tar.gz
kurator-61d16477b01bcfbe8c3a481a232658ac60309f57.tar.bz2
Extracted KeepAtRange action
It seems an abstraction level is of some kind is needed here. One thing to handle "AI", another to handle primitive commands and their execution.
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