summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/CMakeLists.txt3
-rw-r--r--sim/include/kurator/sim/TurretControl.h25
-rw-r--r--sim/include/kurator/sim/ai.h23
-rw-r--r--sim/include/kurator/sim/components.h8
-rw-r--r--sim/include/kurator/sim/weapons.h31
-rw-r--r--sim/src/BaseSimulation.cpp7
-rw-r--r--sim/src/Builder.cpp8
-rw-r--r--sim/src/FloatingMovement.cpp3
-rw-r--r--sim/src/TurretControl.cpp72
-rw-r--r--sim/src/ai.cpp60
-rw-r--r--sim/src/ai.h21
-rw-r--r--sim/src/sim.cpp4
-rw-r--r--sim/src/systems.cpp25
-rw-r--r--sim/src/systems.h2
-rw-r--r--sim/src/weapons.cpp81
15 files changed, 230 insertions, 143 deletions
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 <entt/entt.hpp>
-
-#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 <entt/entt.hpp>
+
+#include <kurator/engine/Point.h>
+
+
+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 <entt/entt.hpp>
+
+#include <kurator/universe/TurretType.h>
+
+#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 <kurator/sim/State.h>
#include <kurator/sim/FloatingMovement.h>
-#include <kurator/sim/TurretControl.h>
+#include <kurator/sim/weapons.h>
+#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 <entt/entt.hpp>
#include <kurator/engine/Point.h>
+#include <kurator/sim/ai.h>
#include <kurator/sim/components.h>
#include <kurator/sim/FloatingMovement.h>
#include <kurator/sim/HitPoints.h>
-#include <kurator/sim/TurretControl.h>
+#include <kurator/sim/weapons.h>
#include <kurator/universe/ShipType.h>
#include <kurator/universe/TurretType.h>
@@ -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<AIState>(entity, 15000.0, Point{0.0, 0.0});
+ registry.emplace<AIShip>(entity, 15000.0, Point{0.0, 0.0});
registry.emplace<HitPoints>(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<universe::TurretType>(entity, turret_type);
- registry.emplace<TurretControl>(entity, 0.0, 0.0, turret_type.rounds, owner);
+ registry.emplace<Turret>(entity, owner, turret_type);
registry.emplace<Transform>(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 <kurator/sim/FloatingMovement.h>
+#include <kurator/sim/ai.h>
#include <kurator/sim/components.h>
#include <kurator/sim/State.h>
@@ -13,7 +14,7 @@ namespace sim
void
FloatingMovement::update(State& ctx)
{
- auto view = ctx.registry.view<Transform, FloatingMovement, AIState>();
+ auto view = ctx.registry.view<Transform, FloatingMovement, AIShip>();
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 <kurator/sim/TurretControl.h>
-
-#include <kurator/sim/components.h>
-#include <kurator/sim/FloatingMovement.h>
-#include <kurator/sim/HitPoints.h>
-#include <kurator/sim/events.h>
-#include <kurator/sim/State.h>
-#include <kurator/universe/TurretType.h>
-
-
-namespace kurator
-{
-namespace sim
-{
-
-
-bool consume(float& dt, double& target);
-
-
-void
-TurretControl::update(State& ctx)
-{
- auto view = ctx.registry.view<TurretControl, universe::TurretType>();
- for (auto&& [entity, control, def] : view.each()) {
- if (!ctx.registry.valid(control.owner)) {
- ctx.registry.destroy(entity);
- continue;
- }
- if (!ctx.registry.all_of<AIState, Transform>(control.owner))
- continue;
- const auto& [state, transform] = ctx.registry.get<AIState, Transform>(control.owner);
- if (!ctx.registry.valid(state.target))
- continue;
- const auto& target = ctx.registry.get<Transform>(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<HitPoints>(state.target);
- const auto& movement = ctx.registry.get<FloatingMovement>(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 <kurator/sim/components.h>
+#include <kurator/sim/State.h>
+#include <kurator/sim/weapons.h>
+
+#include "TeamManager.h"
+
+
+namespace kurator
+{
+namespace sim
+{
+
+
+void
+pick_random_targets(State& ctx, TeamManager& manager)
+{
+ auto view = ctx.registry.view<Team, AIShip>();
+ 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<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);
+ }
+}
+
+
+void
+shoot_at_targets(State& ctx)
+{
+ auto view = ctx.registry.view<Turret>();
+ for (auto&& [entity, turret] : view.each()) {
+ if (!ctx.registry.all_of<AIShip, Transform>(turret.owner))
+ continue;
+ const auto& [state, transform] = ctx.registry.get<AIShip, Transform>(turret.owner);
+ if (!ctx.registry.valid(state.target))
+ continue;
+ const auto& target = ctx.registry.get<Transform>(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 <kurator/sim/ai.h> // Propagate public header to users since both are sim/ai.h
+#include <kurator/sim/State.h>
+
+#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 <kurator/sim.h>
#include <kurator/campaign/Scenario.h>
-#include <kurator/sim/components.h>
+#include <kurator/sim/ai.h>
#include <kurator/sim/State.h>
#include <kurator/sim/System.h>
#include <kurator/universe/UniqueIdentifier.h>
@@ -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<universe::UniqueIdentifier>(entity, ship.identifier);
- auto& state = ctx.registry.get<AIState>(entity);
+ auto& state = ctx.registry.get<AIShip>(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<Team, AIState>();
- 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<Transform, AIState>();
- 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);
- }
-}
-
-
-void
kill_off_dead(State& ctx)
{
auto view = ctx.registry.view<HitPoints>();
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 <kurator/sim/weapons.h>
+
+#include <entt/entt.hpp>
+
+#include <kurator/sim/events.h>
+#include <kurator/sim/FloatingMovement.h>
+#include <kurator/sim/HitPoints.h>
+#include <kurator/sim/State.h>
+#include <kurator/universe/TurretType.h>
+
+
+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<HitPoints>(target);
+ const auto& movement = ctx.registry.get<FloatingMovement>(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<Turret>();
+ 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