aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/system
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/system')
-rw-r--r--src/crepe/system/AISystem.cpp78
-rw-r--r--src/crepe/system/AISystem.h23
-rw-r--r--src/crepe/system/CMakeLists.txt2
3 files changed, 103 insertions, 0 deletions
diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp
new file mode 100644
index 0000000..3c61c78
--- /dev/null
+++ b/src/crepe/system/AISystem.cpp
@@ -0,0 +1,78 @@
+#include "api/LoopTimer.h"
+#include "api/Transform.h"
+#include "manager/ComponentManager.h"
+#include "manager/Mediator.h"
+#include "types.h"
+
+#include "AISystem.h"
+
+using namespace crepe;
+
+void AISystem::update() {
+ const Mediator & mediator = this->mediator;
+ ComponentManager & mgr = mediator.component_manager;
+ RefVector<AI> ai_components = mgr.get_components_by_type<AI>();
+
+ double dt = LoopTimer::get_instance().get_delta_time();
+
+ for (AI & ai : ai_components) {
+ vec2 force = this->calculate(ai);
+ vec2 acceleration = force / ai.mass;
+ ai.velocity += acceleration * dt;
+ ai.velocity.truncate(ai.max_speed);
+
+ // Update the position
+ RefVector<Transform> transforms
+ = mgr.get_components_by_id<Transform>(ai.game_object_id);
+ Transform & transform = transforms.front().get();
+ transform.position += ai.velocity * dt;
+ }
+}
+
+vec2 AISystem::calculate(AI & ai) {
+ vec2 force;
+
+ if (ai.on(AI::BehaviorType::SEEK)) {
+ vec2 force_to_add = this->seek(ai);
+
+ if (!this->accumulate_force(force, force_to_add)) {
+ return force;
+ }
+ }
+ if (ai.on(AI::BehaviorType::FLEE)) {
+ // Flee from the target
+ }
+ if (ai.on(AI::BehaviorType::ARRIVE)) {
+ // Arrive at the target
+ }
+ if (ai.on(AI::BehaviorType::PATH_FOLLOW)) {
+ // Follow the path
+ }
+
+ return force;
+}
+
+bool AISystem::accumulate_force(vec2 & running_total, vec2 force_to_add) {
+ double magnitude_remaining = running_total.length();
+ double magnitude_to_add = force_to_add.length();
+
+ if (magnitude_remaining + magnitude_to_add > 0) {
+ running_total += force_to_add;
+ return true;
+ }
+
+ return false;
+}
+
+vec2 AISystem::seek(const AI & ai) {
+ const Mediator & mediator = this->mediator;
+ ComponentManager & mgr = mediator.component_manager;
+ RefVector<Transform> transforms = mgr.get_components_by_id<Transform>(ai.game_object_id);
+ Transform & transform = transforms.front().get();
+
+ vec2 desired_velocity = ai.seek_target - transform.position;
+ desired_velocity.normalize();
+ desired_velocity *= ai.max_speed;
+
+ return desired_velocity - ai.velocity;
+}
diff --git a/src/crepe/system/AISystem.h b/src/crepe/system/AISystem.h
new file mode 100644
index 0000000..5e94ccb
--- /dev/null
+++ b/src/crepe/system/AISystem.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "api/AI.h"
+
+#include "System.h"
+#include "types.h"
+
+namespace crepe {
+
+class AISystem : public System {
+public:
+ using System::System;
+
+ void update() override;
+
+private:
+ vec2 calculate(AI & ai);
+ bool accumulate_force(vec2 & running_total, vec2 force_to_add);
+
+ vec2 seek(const AI & ai);
+};
+
+} // namespace crepe
diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt
index 95f6e33..7de5198 100644
--- a/src/crepe/system/CMakeLists.txt
+++ b/src/crepe/system/CMakeLists.txt
@@ -7,6 +7,7 @@ target_sources(crepe PUBLIC
RenderSystem.cpp
AnimatorSystem.cpp
InputSystem.cpp
+ AISystem.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -17,4 +18,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
RenderSystem.h
AnimatorSystem.h
InputSystem.h
+ AISystem.h
)