diff options
author | JAROWMR <jarorutjes07@gmail.com> | 2024-12-11 20:12:12 +0100 |
---|---|---|
committer | JAROWMR <jarorutjes07@gmail.com> | 2024-12-11 20:12:12 +0100 |
commit | c90423d5c9d38ae426c168e52994a4fd63e6f266 (patch) | |
tree | fa18eae598cf0fccbb0f2dffd3e1d76fedaed53a /src/crepe/api/AI.h | |
parent | 9b4f6f24f29e8873a14989ba8c9fccfbc460af7f (diff) | |
parent | 194ee3f192c3343c3ccc28dfa97fed180503ffd4 (diff) |
merge master
Diffstat (limited to 'src/crepe/api/AI.h')
-rw-r--r-- | src/crepe/api/AI.h | 111 |
1 files changed, 85 insertions, 26 deletions
diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h index 35b8998..c780a91 100644 --- a/src/crepe/api/AI.h +++ b/src/crepe/api/AI.h @@ -5,10 +5,16 @@ namespace crepe { +/** + * \brief The AI component is used to control the movement of an entity using AI. + * + * The AI component can be used to control the movement of an entity. The AI component can be used + * to implement different behaviors such as seeking, fleeing, arriving, and path following. + */ class AI : public Component { public: - enum BehaviorType { - NONE = 0x00000, + //! The different types of behaviors that can be used + enum BehaviorTypeMask { SEEK = 0x00002, FLEE = 0x00004, ARRIVE = 0x00008, @@ -16,54 +22,107 @@ public: }; public: + /** + * \param id The id of the game object + * \param max_force The maximum force that can be applied to the entity + */ AI(game_object_id_t id, float max_force); - bool on(BehaviorType behavior) const { return (flags & behavior) == behavior; } + /** + * \brief Check if a behavior is on (aka activated) + * + * \param behavior The behavior to check + * \return true if the behavior is on, false otherwise + */ + bool on(BehaviorTypeMask behavior) const { return (flags & behavior); } + //! Turn on the seek behavior void seek_on() { flags |= SEEK; } - void seek_off() { - if (on(SEEK)) flags ^= SEEK; - } + //! Turn off the seek behavior + void seek_off() { flags &= ~SEEK; } + //! Turn on the flee behavior void flee_on() { flags |= FLEE; } - void flee_off() { - if (on(FLEE)) flags ^= FLEE; - } + //! Turn off the flee behavior + void flee_off() { flags &= ~FLEE; } + //! Turn on the arrive behavior void arrive_on() { flags |= ARRIVE; } - void arrive_off() { - if (on(ARRIVE)) flags ^= ARRIVE; - } + //! Turn off the arrive behavior + void arrive_off() { flags &= ~ARRIVE; } + //! Turn on the path follow behavior void path_follow_on() { flags |= PATH_FOLLOW; } - void path_follow_off() { - if (on(PATH_FOLLOW)) flags ^= PATH_FOLLOW; - } + //! Turn off the path follow behavior + void path_follow_off() { flags &= ~PATH_FOLLOW; } - void add_path_node(vec2 node) { path.push_back(node); } + /** + * \brief Add a path node (for the path following behavior) + * + * \note The path is not relative to the entity's position (it is an absolute path) + * + * \param node The path node to add + */ + void add_path_node(const vec2 & node) { path.push_back(node); } + /** + * \brief Make a circle path (for the path following behavior) + * + * \note The path is not relative to the entity's position (it is an absolute path) + * + * \param radius The radius of the circle (in game units) + * \param center The center of the circle (in game units) + * \param start_angle The start angle of the circle (in radians) + * \param clockwise The direction of the circle + */ + void make_circle_path(float radius, const vec2 & center = {0, 0}, float start_angle = 0, + bool clockwise = true); + /** + * \brief Make an oval path (for the path following behavior) + * + * \note The path is not relative to the entity's position (it is an absolute path) + * + * \param radius_x The x radius of the oval (in game units) + * \param radius_y The y radius of the oval (in game units) + * \param center The center of the oval (in game units) + * \param start_angle The start angle of the oval (in radians) + * \param clockwise The direction of the oval + * \param rotation The rotation of the oval (in radians) + */ + void make_oval_path(float radius_x, float radius_y, const vec2 & center = {0, 0}, + float start_angle = 0, bool clockwise = true, float rotation = 0); public: + //! The maximum force that can be applied to the entity (higher values will make the entity adjust faster) float max_force; - // The target to seek or arrive at + //! The target to seek at vec2 seek_target; - // The target to flee from + //! The target to arrive at + vec2 arrive_target; + //! The target to flee from vec2 flee_target; - // The distance at which the entity will start to flee from the target + //! The distance at which the entity will start to flee from the target float square_flee_panic_distance = 200.0f * 200.0f; - // The deceleration rate for the arrive behavior (higher values will make the entity decelerate faster (less overshoot)) + //! The deceleration rate for the arrive behavior (higher values will make the entity decelerate faster (less overshoot)) float arrive_deceleration = 40.0f; - // The path to follow + //! The path to follow (for the path following behavior) std::vector<vec2> path; - // The distance from the path node at which the entity will move to the next node + //! The distance from the path node at which the entity will move to the next node (automatically set by make_circle_path()) float path_node_distance = 400.0f; - // Looping behavior for the path + //! Looping behavior for the path bool path_loop = true; private: - // The flags for the behaviors + //! The flags for the behaviors int flags = 0; - // The current path index + //! The current path index size_t path_index = 0; - // The AISystem is the only class that can access the private members of AI + //! The AISystem is the only class that should access the flags and path_index variables friend class AISystem; + + //! The minimum amount of steps for the path following behavior + static constexpr int MIN_STEP = 16; + //! The radius to step size ratio for the path following behavior + static constexpr float RADIUS_TO_STEP = 400.0f; + //! The path node distance factor for the path following behavior + static constexpr float PATH_NODE_DISTANCE_FACTOR = 0.75f; }; } // namespace crepe |