diff options
author | Aki <please@ignore.pl> | 2023-04-27 00:36:46 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2024-04-05 19:41:19 +0200 |
commit | 61d16477b01bcfbe8c3a481a232658ac60309f57 (patch) | |
tree | 06882f5a1b7bc987826610736a5b606883df69b9 /sim | |
parent | 94d6d863e1b78766cdb5f286e3d9f374c02c5d33 (diff) | |
download | kurator-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')
-rw-r--r-- | sim/include/kurator/sim/ai.h | 9 | ||||
-rw-r--r-- | sim/src/BaseSimulation.cpp | 2 | ||||
-rw-r--r-- | sim/src/Builder.cpp | 2 | ||||
-rw-r--r-- | sim/src/ai.cpp | 69 | ||||
-rw-r--r-- | sim/src/ai.h | 2 | ||||
-rw-r--r-- | sim/src/sim.cpp | 6 |
6 files changed, 73 insertions, 17 deletions
diff --git a/sim/include/kurator/sim/ai.h b/sim/include/kurator/sim/ai.h index f9899d6..0ffa1cc 100644 --- a/sim/include/kurator/sim/ai.h +++ b/sim/include/kurator/sim/ai.h @@ -1,9 +1,13 @@ #pragma once +#include <functional> + #include <entt/entt.hpp> #include <kurator/engine/Point.h> +#include "State.h" + namespace kurator { @@ -11,9 +15,12 @@ namespace sim { +using Action = std::function<void()>; + + struct AIShip { - double keep_at_range; + Action action; engine::Point destination; entt::entity target = entt::null; }; diff --git a/sim/src/BaseSimulation.cpp b/sim/src/BaseSimulation.cpp index b1add54..2731c67 100644 --- a/sim/src/BaseSimulation.cpp +++ b/sim/src/BaseSimulation.cpp @@ -24,7 +24,7 @@ void BaseSimulation::operator()(State& ctx) { pick_random_targets(ctx, manager); - keep_at_range(ctx); + take_actions(ctx); FloatingMovement::update(ctx); update_turrets(ctx); shoot_at_targets(ctx); diff --git a/sim/src/Builder.cpp b/sim/src/Builder.cpp index 4cf0bc6..2b2bd24 100644 --- a/sim/src/Builder.cpp +++ b/sim/src/Builder.cpp @@ -42,7 +42,7 @@ Builder::operator()(const universe::ShipType& ship_type, const int team) const ship_type.max_speed, ship_type.max_speed * 2.0, ship_type.max_speed * 3.0); - registry.emplace<AIShip>(entity, 15000.0, Point{0.0, 0.0}); + registry.emplace<AIShip>(entity); registry.emplace<HitPoints>(entity, ship_type); return entity; } 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 diff --git a/sim/src/ai.h b/sim/src/ai.h index 9173891..d1e9c29 100644 --- a/sim/src/ai.h +++ b/sim/src/ai.h @@ -13,7 +13,7 @@ namespace sim void pick_random_targets(State& ctx, TeamManager& manager); -void keep_at_range(State& ctx); +void take_actions(State& ctx); void shoot_at_targets(State& ctx); diff --git a/sim/src/sim.cpp b/sim/src/sim.cpp index 740e6af..879f7fb 100644 --- a/sim/src/sim.cpp +++ b/sim/src/sim.cpp @@ -1,7 +1,6 @@ #include <kurator/sim.h> #include <kurator/campaign/Scenario.h> -#include <kurator/sim/ai.h> #include <kurator/sim/State.h> #include <kurator/sim/System.h> #include <kurator/universe/UniqueIdentifier.h> @@ -26,11 +25,8 @@ load_scenario(const campaign::Scenario& scenario) for (const auto& ship : scenario.ships) { const auto entity = build(ship.loadout.type, ship.team); ctx.registry.emplace<universe::UniqueIdentifier>(entity, ship.identifier); - auto& state = ctx.registry.get<AIShip>(entity); - for (const auto& turret_type : ship.loadout.turrets) { + for (const auto& turret_type : ship.loadout.turrets) build(turret_type, entity); - state.keep_at_range = std::min(state.keep_at_range, turret_type.optimal_range); - } } return ctx; } |