From 975339d07aeb193564221adff31b55a913d92a1e Mon Sep 17 00:00:00 2001 From: Aki Date: Sun, 23 Apr 2023 12:54:14 +0200 Subject: Separated Turret from AI, shuffled their units --- sim/CMakeLists.txt | 3 +- sim/include/kurator/sim/TurretControl.h | 25 ---------- sim/include/kurator/sim/ai.h | 23 ++++++++++ sim/include/kurator/sim/components.h | 8 ---- sim/include/kurator/sim/weapons.h | 31 +++++++++++++ sim/src/BaseSimulation.cpp | 7 +-- sim/src/Builder.cpp | 8 ++-- sim/src/FloatingMovement.cpp | 3 +- sim/src/TurretControl.cpp | 72 ----------------------------- sim/src/ai.cpp | 60 ++++++++++++++++++++++++ sim/src/ai.h | 21 +++++++++ sim/src/sim.cpp | 4 +- sim/src/systems.cpp | 25 ---------- sim/src/systems.h | 2 - sim/src/weapons.cpp | 81 +++++++++++++++++++++++++++++++++ 15 files changed, 230 insertions(+), 143 deletions(-) delete mode 100644 sim/include/kurator/sim/TurretControl.h create mode 100644 sim/include/kurator/sim/ai.h create mode 100644 sim/include/kurator/sim/weapons.h delete mode 100644 sim/src/TurretControl.cpp create mode 100644 sim/src/ai.cpp create mode 100644 sim/src/ai.h create mode 100644 sim/src/weapons.cpp (limited to 'sim') diff --git a/sim/CMakeLists.txt b/sim/CMakeLists.txt index 9713d96..f5af416 100644 --- a/sim/CMakeLists.txt +++ b/sim/CMakeLists.txt @@ -1,6 +1,7 @@ project(sim) add_library( ${PROJECT_NAME} STATIC + src/ai.cpp src/BaseSimulation.cpp src/Builder.cpp src/FloatingMovement.cpp @@ -9,7 +10,7 @@ add_library( src/sim.cpp src/systems.cpp src/TeamManager.cpp - src/TurretControl.cpp + src/weapons.cpp ) target_include_directories( ${PROJECT_NAME} diff --git a/sim/include/kurator/sim/TurretControl.h b/sim/include/kurator/sim/TurretControl.h deleted file mode 100644 index ecafb90..0000000 --- a/sim/include/kurator/sim/TurretControl.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -#include "State.h" - - -namespace kurator -{ -namespace sim -{ - - -struct TurretControl -{ - double delay; - double reload; - int rounds; - entt::entity owner; - static void update(State& ctx); -}; - - -} // namespace sim -} // namespace kurator diff --git a/sim/include/kurator/sim/ai.h b/sim/include/kurator/sim/ai.h new file mode 100644 index 0000000..f9899d6 --- /dev/null +++ b/sim/include/kurator/sim/ai.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include + + +namespace kurator +{ +namespace sim +{ + + +struct AIShip +{ + double keep_at_range; + engine::Point destination; + entt::entity target = entt::null; +}; + + +} // namespace sim +} // namespace kurator diff --git a/sim/include/kurator/sim/components.h b/sim/include/kurator/sim/components.h index f329c0e..c4d8abc 100644 --- a/sim/include/kurator/sim/components.h +++ b/sim/include/kurator/sim/components.h @@ -25,13 +25,5 @@ struct Team }; -struct AIState -{ - double keep_at_range; - engine::Point destination; - entt::entity target = entt::null; -}; - - } // namespace sim } // namespace kurator diff --git a/sim/include/kurator/sim/weapons.h b/sim/include/kurator/sim/weapons.h new file mode 100644 index 0000000..7dd5b3b --- /dev/null +++ b/sim/include/kurator/sim/weapons.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include + +#include "State.h" + + +namespace kurator +{ +namespace sim +{ + + +struct Turret +{ + entt::entity owner; + universe::TurretType type; + double delay = 0.0; + double reload = 0.0; + int rounds = type.rounds; + void shoot_at(State& ctx, const entt::entity& target, double distance); +}; + + +void update_turrets(State& ctx); + + +} // namespace sim +} // namespace kurator diff --git a/sim/src/BaseSimulation.cpp b/sim/src/BaseSimulation.cpp index 545e9ce..b1add54 100644 --- a/sim/src/BaseSimulation.cpp +++ b/sim/src/BaseSimulation.cpp @@ -2,10 +2,10 @@ #include #include -#include +#include +#include "ai.h" #include "systems.h" -#include "TeamManager.h" namespace kurator @@ -26,7 +26,8 @@ BaseSimulation::operator()(State& ctx) pick_random_targets(ctx, manager); keep_at_range(ctx); FloatingMovement::update(ctx); - TurretControl::update(ctx); + update_turrets(ctx); + shoot_at_targets(ctx); kill_off_dead(ctx); manager.update(ctx); } diff --git a/sim/src/Builder.cpp b/sim/src/Builder.cpp index af19974..4cf0bc6 100644 --- a/sim/src/Builder.cpp +++ b/sim/src/Builder.cpp @@ -3,10 +3,11 @@ #include #include +#include #include #include #include -#include +#include #include #include @@ -41,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(entity, 15000.0, Point{0.0, 0.0}); + registry.emplace(entity, 15000.0, Point{0.0, 0.0}); registry.emplace(entity, ship_type); return entity; } @@ -51,8 +52,7 @@ entt::entity Builder::operator()(const universe::TurretType& turret_type, const entt::entity& owner) const { const auto entity = registry.create(); - registry.emplace(entity, turret_type); - registry.emplace(entity, 0.0, 0.0, turret_type.rounds, owner); + registry.emplace(entity, owner, turret_type); registry.emplace(entity, Point{0.0, 0.0}, 0.0, owner); return entity; } diff --git a/sim/src/FloatingMovement.cpp b/sim/src/FloatingMovement.cpp index 39ec17c..4aebb9b 100644 --- a/sim/src/FloatingMovement.cpp +++ b/sim/src/FloatingMovement.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -13,7 +14,7 @@ namespace sim void FloatingMovement::update(State& ctx) { - auto view = ctx.registry.view(); + auto view = ctx.registry.view(); for (auto&& [entity, transform, movement, ai] : view.each()) { const auto offset = ai.destination - transform.position; const auto at_destination = offset.magnitude() > movement.destination_boundary; diff --git a/sim/src/TurretControl.cpp b/sim/src/TurretControl.cpp deleted file mode 100644 index 51f2a46..0000000 --- a/sim/src/TurretControl.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - - -namespace kurator -{ -namespace sim -{ - - -bool consume(float& dt, double& target); - - -void -TurretControl::update(State& ctx) -{ - auto view = ctx.registry.view(); - for (auto&& [entity, control, def] : view.each()) { - if (!ctx.registry.valid(control.owner)) { - ctx.registry.destroy(entity); - continue; - } - if (!ctx.registry.all_of(control.owner)) - continue; - const auto& [state, transform] = ctx.registry.get(control.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 > def.effective_range()) - continue; - auto remaining_dt = ctx.clock.dt; - while (remaining_dt > 0.0) { - if (control.rounds < 1 && consume(remaining_dt, control.reload)) - control.rounds = def.rounds; - if (control.rounds > 0 && consume(remaining_dt, control.delay)) { - auto& target_points = ctx.registry.get(state.target); - const auto& movement = ctx.registry.get(state.target); - auto damage = def.effective_damage(distance, movement.speed.magnitude()); - if (damage > 0.0) { - damage = target_points.deal(damage); - ctx.dispatcher.trigger(Hit{damage, control.owner, state.target}); - } - control.delay = def.rate_of_fire; - if (--control.rounds < 1) - control.reload = def.reload; - } - } - } -} - - -bool -consume(float& dt, double& target) -{ - if (target <= 0.0) - return true; - const auto _dt = dt; - dt -= target; - target -= _dt; - return target <= 0.0; -} - - -} // namespace sim -} // namespace kurator diff --git a/sim/src/ai.cpp b/sim/src/ai.cpp new file mode 100644 index 0000000..1f2a4ec --- /dev/null +++ b/sim/src/ai.cpp @@ -0,0 +1,60 @@ +#include "ai.h" + +#include +#include +#include + +#include "TeamManager.h" + + +namespace kurator +{ +namespace sim +{ + + +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); + } +} + + +void +keep_at_range(State& ctx) +{ + auto view = ctx.registry.view(); + for (auto&& [entity, self, ai] : view.each()) { + if (!ctx.registry.valid(ai.target)) + continue; + const auto target = ctx.registry.get(ai.target); + const auto offset = target.position - self.position; + ai.destination = target.position - offset.normalized().scale(ai.keep_at_range); + } +} + + +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 + } +} + + +} // namespace sim +} // namespace kurator diff --git a/sim/src/ai.h b/sim/src/ai.h new file mode 100644 index 0000000..9173891 --- /dev/null +++ b/sim/src/ai.h @@ -0,0 +1,21 @@ +#pragma once + +#include // Propagate public header to users since both are sim/ai.h +#include + +#include "TeamManager.h" + + +namespace kurator +{ +namespace sim +{ + + +void pick_random_targets(State& ctx, TeamManager& manager); +void keep_at_range(State& ctx); +void shoot_at_targets(State& ctx); + + +} // namespace sim +} // namespace kurator diff --git a/sim/src/sim.cpp b/sim/src/sim.cpp index 4cb7467..740e6af 100644 --- a/sim/src/sim.cpp +++ b/sim/src/sim.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include @@ -26,7 +26,7 @@ load_scenario(const campaign::Scenario& scenario) for (const auto& ship : scenario.ships) { const auto entity = build(ship.loadout.type, ship.team); ctx.registry.emplace(entity, ship.identifier); - auto& state = ctx.registry.get(entity); + auto& state = ctx.registry.get(entity); 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); diff --git a/sim/src/systems.cpp b/sim/src/systems.cpp index c6f997a..ce4a6b4 100644 --- a/sim/src/systems.cpp +++ b/sim/src/systems.cpp @@ -15,31 +15,6 @@ namespace sim 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); - } -} - - -void -keep_at_range(State& ctx) -{ - auto view = ctx.registry.view(); - for (auto&& [entity, self, ai] : view.each()) { - if (!ctx.registry.valid(ai.target)) - continue; - const auto target = ctx.registry.get(ai.target); - const auto offset = target.position - self.position; - ai.destination = target.position - offset.normalized().scale(ai.keep_at_range); - } -} - - -void kill_off_dead(State& ctx) { auto view = ctx.registry.view(); diff --git a/sim/src/systems.h b/sim/src/systems.h index 396ebb2..2ec9ba4 100644 --- a/sim/src/systems.h +++ b/sim/src/systems.h @@ -11,8 +11,6 @@ namespace sim { -void pick_random_targets(State& ctx, TeamManager& manager); -void keep_at_range(State& ctx); void kill_off_dead(State& ctx); diff --git a/sim/src/weapons.cpp b/sim/src/weapons.cpp new file mode 100644 index 0000000..bd130dc --- /dev/null +++ b/sim/src/weapons.cpp @@ -0,0 +1,81 @@ +#include + +#include + +#include +#include +#include +#include +#include + + +namespace kurator +{ +namespace sim +{ + + +static bool consume(float& dt, double& target); +static bool reload_(float& dt, Turret& turret); + + +void +Turret::shoot_at(State& ctx, const entt::entity& target, const double distance) +{ + float remaining_dt = ctx.clock.dt; + while (reload_(remaining_dt, *this)) { + auto& target_points = ctx.registry.get(target); + const auto& movement = ctx.registry.get(target); + auto damage = type.effective_damage(distance, movement.speed.magnitude()); + if (damage > 0.0) { + damage = target_points.deal(damage); + ctx.dispatcher.trigger(Hit{damage, owner, target}); + } + delay = type.rate_of_fire; + if (--rounds < 1) + reload = type.reload; + } +} + + +void +update_turrets(State& ctx) +{ + auto turrets = ctx.registry.view(); + for (auto&& [entity, turret] : turrets.each()) { + if (!ctx.registry.valid(turret.owner)) { + ctx.registry.destroy(entity); + continue; + } + float remaining_dt = ctx.clock.dt; + while (remaining_dt > 0.0) { + if (reload_(remaining_dt, turret)) + break; + } + } +} + + +bool +consume(float& dt, double& target) +{ + if (target <= 0.0) + return true; + const auto _dt = dt; + dt -= target; + target -= _dt; + return target <= 0.0; +} + + +bool +reload_(float& dt, Turret& turret) // at this point move it to the class? +{ + if (turret.rounds < 1 && consume(dt, turret.reload)) + turret.rounds = turret.type.rounds; + return turret.rounds > 0 && consume(dt, turret.delay); +} + + +} // namespace sim +} // namespace kurator -- cgit v1.1