diff options
Diffstat (limited to 'engine-ocean/Game/Systems/AI')
-rw-r--r-- | engine-ocean/Game/Systems/AI/Actions/btaction.cpp | 6 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Actions/btaction.h | 17 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Actions/walkaction.cpp | 90 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Actions/walkaction.h | 29 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Conditions/btcondition.cpp | 6 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Conditions/btcondition.h | 18 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Conditions/proximitycondition.cpp | 43 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/Conditions/proximitycondition.h | 27 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/aibehaviorcomponent.cpp | 46 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/aibehaviorcomponent.h | 27 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btnode.cpp | 6 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btnode.h | 18 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btselector.cpp | 29 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btselector.h | 21 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btsequence.cpp | 30 | ||||
-rw-r--r-- | engine-ocean/Game/Systems/AI/btsequence.h | 20 |
16 files changed, 433 insertions, 0 deletions
diff --git a/engine-ocean/Game/Systems/AI/Actions/btaction.cpp b/engine-ocean/Game/Systems/AI/Actions/btaction.cpp new file mode 100644 index 0000000..1b35340 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Actions/btaction.cpp @@ -0,0 +1,6 @@ +#include "btaction.h" + +BTAction::BTAction() +{ + +} diff --git a/engine-ocean/Game/Systems/AI/Actions/btaction.h b/engine-ocean/Game/Systems/AI/Actions/btaction.h new file mode 100644 index 0000000..180f72c --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Actions/btaction.h @@ -0,0 +1,17 @@ +#ifndef BTACTION_H +#define BTACTION_H +#include "Game/Systems/AI/btnode.h" + +class BTAction : public BTNode +{ +public: + BTAction(); + virtual Status update(float seconds) = 0; + virtual void reset() = 0; + +private: + Status m_status; + +}; + +#endif // BTACTION_H diff --git a/engine-ocean/Game/Systems/AI/Actions/walkaction.cpp b/engine-ocean/Game/Systems/AI/Actions/walkaction.cpp new file mode 100644 index 0000000..6a6d116 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Actions/walkaction.cpp @@ -0,0 +1,90 @@ +#include "walkaction.h" +#include "Game/Components/PathfindComponent.h" +#include "Game/Components/TransformComponent.h" +#include "Game/GameObjects/GameObject.h" +#include "glm/glm.hpp" +#include <memory> + + +WalkAction::WalkAction(std::string entity_id, + std::map<std::string, BlackboardData>& global_blackboard): + m_global_blackboard(global_blackboard) +{ + + m_entity_id = entity_id; + m_path.clear(); + + m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue = false; + m_global_blackboard[m_entity_id].conditionData["atDestination"].conditionTrue = false; + m_global_blackboard[m_entity_id].conditionData["pathfound"].conditionTrue = false; + + + + +} + +void WalkAction::setPath(glm::vec3 entity_pos){ + std::cout << "---------SETTING PATHH" << std::endl; + m_destination = m_global_blackboard["player"].locationData.currPos; + m_path = m_global_blackboard["navmesh"].environment->getComponent<PathfindComponent>()->getPath(glm::vec3(-0.58249, 0, -0.0210782), glm::vec3(19.5371, 0, 1.39167)); +} + +// only activates if the previous conditions are true +Status WalkAction::update(float seconds){ + + glm::vec3 pos = m_global_blackboard[m_entity_id].locationData.currPos; + + // get a path if entity is not pathfinding + if (!m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue && + !m_global_blackboard[m_entity_id].conditionData["atDestination"].conditionTrue && + !m_global_blackboard[m_entity_id].conditionData["pathfound"].conditionTrue){ + setPath(pos); + m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue = true; + m_global_blackboard[m_entity_id].conditionData["pathfound"].conditionTrue = true; + + } + + if (!m_path.empty()){ + if (m_global_blackboard[m_entity_id].conditionData["onGround"].conditionTrue){ + //std::cout << "on ground" << std::endl; + + std::shared_ptr<ModelTransform> temp_mt = std::make_shared<ModelTransform>(); + temp_mt->setPos(pos); + glm::vec3 v = m_path.back();//glm::vec3(m_path.back().x, pos.y, m_path.back().z); + glm::vec3 dir = glm::normalize(v-temp_mt->getPos()); + temp_mt->translate(dir); + //std::cout << "v: (" << v.x << ", " << v.y << ", " << v.z << ")" << std::endl; + glm::vec3 pos_eps = v + .01f; + glm::vec3 neg_eps = v - .01f; + + // pop if entity within a certain episilon of node + if (neg_eps.x < temp_mt->getPos().x < pos_eps.x && + neg_eps.z < temp_mt->getPos().z < pos_eps.z){ + m_path.pop_back(); + } + + m_global_blackboard[m_entity_id].locationData.setToPos = temp_mt->getPos(); + } + + return Status::RUNNING; + } + + // if reached destination, then walking succeeded + if (pos.x == m_destination.x && pos.z == m_destination.z){ + m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue = false; + m_global_blackboard[m_entity_id].conditionData["atDestination"].conditionTrue = true; + std::cout << "-reached-" << std::endl; + return Status::SUCCESS; + + } + + // otherwise + m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue = false; + return Status::FAIL; + +} + +void WalkAction::reset(){} +void WalkAction::addChildren(BTNode *node){} + + diff --git a/engine-ocean/Game/Systems/AI/Actions/walkaction.h b/engine-ocean/Game/Systems/AI/Actions/walkaction.h new file mode 100644 index 0000000..2e24864 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Actions/walkaction.h @@ -0,0 +1,29 @@ +#ifndef WALKACTION_H +#define WALKACTION_H +#include "Game/Components/TransformComponent.h" +#include "Game/GameObjects/GameObject.h" +#include "Game/Systems/AI/btnode.h" +#include "glm/fwd.hpp" +#include <memory> +#include "btaction.h" + +class WalkAction : public BTNode +{ +public: + WalkAction(std::string entity_id, std::map<std::string, BlackboardData>& global_blackboard); + Status update(float seconds) override; + void reset() override; + void setPath(glm::vec3 entity_pos); + void addChildren(BTNode *node) override; + + + +private: + std::vector<glm::vec3> m_path; + glm::vec3 m_destination; + std::map<std::string, BlackboardData>& m_global_blackboard; + std::string m_entity_id; +}; + + +#endif // WALKACTION_H diff --git a/engine-ocean/Game/Systems/AI/Conditions/btcondition.cpp b/engine-ocean/Game/Systems/AI/Conditions/btcondition.cpp new file mode 100644 index 0000000..f4de4af --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Conditions/btcondition.cpp @@ -0,0 +1,6 @@ +#include "btcondition.h" + +BTCondition::BTCondition() +{ + +} diff --git a/engine-ocean/Game/Systems/AI/Conditions/btcondition.h b/engine-ocean/Game/Systems/AI/Conditions/btcondition.h new file mode 100644 index 0000000..6ded57b --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Conditions/btcondition.h @@ -0,0 +1,18 @@ +#ifndef BTCONDITION_H +#define BTCONDITION_H +#include "Game/Systems/AI/btnode.h" + + +class BTCondition : public BTNode +{ +public: + BTCondition(); + virtual Status update(float seconds) = 0; + virtual void reset() = 0; + + +private: + bool m_condition; +}; + +#endif // BTCONDITION_H diff --git a/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.cpp b/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.cpp new file mode 100644 index 0000000..2e40ce7 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.cpp @@ -0,0 +1,43 @@ +#include "proximitycondition.h" +#include "Game/Components/TransformComponent.h" +#include "glm/glm.hpp" +#include <memory> + +ProximityCondition::ProximityCondition(std::string entity_id, + std::map<std::string, BlackboardData>& global_blackboard, + float proximity): + m_global_blackboard(global_blackboard) +{ + m_proximity = proximity; + m_entity_id = entity_id; + // initialize just in case + m_global_blackboard["player"].conditionData["isJumping"].conditionTrue = false; + + +} + +// maybe can check locations from blackboard +// pass blackboard into constructor +// struct: positiondata --> getCurrentPos, setCurrentPos +bool ProximityCondition::checkProximity(){ + // unrooted distance + glm::vec3 aiPos = m_global_blackboard[m_entity_id].locationData.currPos; + glm::vec3 otherPos = m_global_blackboard["player"].locationData.currPos; + float distance = pow(aiPos.x-otherPos.x, 2) + pow(aiPos.y-otherPos.y, 2) + pow(aiPos.z-otherPos.z, 2); + + if (distance <= m_proximity) return true; + return false; +} + +// at every update, check if AIPos is near otherPos +Status ProximityCondition::update(float seconds){ + // while entity is still pathfinding, keep returning success + if (m_global_blackboard[m_entity_id].conditionData["isPathfinding"].conditionTrue) return Status::SUCCESS; + if (checkProximity() && m_global_blackboard["player"].conditionData["isJumping"].conditionTrue) return Status::SUCCESS; + + return Status::FAIL; +} + + +void ProximityCondition::reset(){} +void ProximityCondition::addChildren(BTNode *node){} diff --git a/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.h b/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.h new file mode 100644 index 0000000..e43d178 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/Conditions/proximitycondition.h @@ -0,0 +1,27 @@ +#ifndef PROXIMITYCONDITION_H +#define PROXIMITYCONDITION_H +#include "Game/Components/TransformComponent.h" +#include "btcondition.h" +#include <memory> + + +class ProximityCondition : public BTNode +{ +public: + ProximityCondition(std::string entity_id, + std::map<std::string, BlackboardData>& global_blackboard, + float proximity); + Status update(float seconds) override; + void reset() override; + void addChildren(BTNode *node) override; + + +private: + bool checkProximity(); + float m_proximity; + std::string m_entity_id; + std::map<std::string, BlackboardData>& m_global_blackboard; + +}; + +#endif // PROXIMITYCONDITION_H diff --git a/engine-ocean/Game/Systems/AI/aibehaviorcomponent.cpp b/engine-ocean/Game/Systems/AI/aibehaviorcomponent.cpp new file mode 100644 index 0000000..b43ed07 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/aibehaviorcomponent.cpp @@ -0,0 +1,46 @@ +#include "aibehaviorcomponent.h" +#include "Game/Systems/AI/Actions/walkaction.h" +#include "Game/Systems/AI/Conditions/proximitycondition.h" +#include "Game/Systems/AI/btselector.h" +#include "Game/Systems/AI/btsequence.h" + +AIBehaviorComponent::AIBehaviorComponent(std::string entity_id, + std::map<std::string, BlackboardData>& global_blackboard): + m_global_blackboard(global_blackboard) +{ + m_entity_id = entity_id; + makeBehaviorTree(); + +} + +void AIBehaviorComponent::makeBehaviorTree(){ + // leaves + //std::unique_ptr<BTNode> walk = std::make_unique<WalkAction>(m_entity_id, m_global_blackboard); + BTNode *proximCond = new ProximityCondition(m_entity_id, m_global_blackboard, 20.f); + BTNode *walk = new WalkAction(m_entity_id, m_global_blackboard); + + +// // pathfind sequence + BTNode *pathfindSeq = new BTSequence; + pathfindSeq->addChildren(proximCond); + pathfindSeq->addChildren(walk); + +// // idle sequence + +// // root + m_root = new BTSelector; + m_root->addChildren(pathfindSeq); +} + +// how might i be able to generalize the creation of the tree? +void AIBehaviorComponent::update(float seconds){ + // update root, which updates all its children + //std::cout << "---------in ai system" << std::endl; + + m_status = m_root->update(seconds); +} + +AIBehaviorComponent::~AIBehaviorComponent(){ + delete m_root; +} + diff --git a/engine-ocean/Game/Systems/AI/aibehaviorcomponent.h b/engine-ocean/Game/Systems/AI/aibehaviorcomponent.h new file mode 100644 index 0000000..5a86b88 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/aibehaviorcomponent.h @@ -0,0 +1,27 @@ +#ifndef AIBEHAVIORCOMPONENT_H +#define AIBEHAVIORCOMPONENT_H + + +#include "Game/Components/Component.h" +#include "Game/Systems/AI/btselector.h" +#include "Game/Systems/aisystem.h" +#include <map> +#include <string> +class AIBehaviorComponent : public Component +{ +public: + AIBehaviorComponent(std::string entity_id, + std::map<std::string, BlackboardData>& global_blackboard); + ~AIBehaviorComponent(); + void update(float seconds); + +private: + void makeBehaviorTree(); + + std::string m_entity_id; + std::map<std::string, BlackboardData>& m_global_blackboard; + BTNode *m_root = 0; + Status m_status = Status::SUCCESS; +}; + +#endif // AIBEHAVIORCOMPONENT_H diff --git a/engine-ocean/Game/Systems/AI/btnode.cpp b/engine-ocean/Game/Systems/AI/btnode.cpp new file mode 100644 index 0000000..2740089 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btnode.cpp @@ -0,0 +1,6 @@ +#include "btnode.h" + +BTNode::BTNode() +{ + +} diff --git a/engine-ocean/Game/Systems/AI/btnode.h b/engine-ocean/Game/Systems/AI/btnode.h new file mode 100644 index 0000000..b025da6 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btnode.h @@ -0,0 +1,18 @@ +#ifndef BTNODE_H +#define BTNODE_H + + +enum Status{ + SUCCESS, FAIL, RUNNING +}; + +class BTNode +{ +public: + BTNode(); + virtual ~BTNode() = default; + virtual Status update(float seconds) = 0; + virtual void reset() = 0; + virtual void addChildren(BTNode *node) = 0; +}; +#endif // BTNODE_H diff --git a/engine-ocean/Game/Systems/AI/btselector.cpp b/engine-ocean/Game/Systems/AI/btselector.cpp new file mode 100644 index 0000000..9652838 --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btselector.cpp @@ -0,0 +1,29 @@ +#include "btselector.h" +#include <iostream> + +BTSelector::BTSelector() +{ + +} + +void BTSelector::addChildren(BTNode* node){ + m_children.push_back(node); +} + +Status BTSelector::update(float seconds){ + // update each children until one doesnt fail + for (auto node : m_children){ + Status result = node->update(seconds); + + // select this one and return its status --> this node is currently running + if (result != Status::FAIL){ + m_selected_node = node; + return result; + } + } + + // otherwise if all children fail, then fail this selector + return Status::FAIL; +} + +void BTSelector::reset(){} diff --git a/engine-ocean/Game/Systems/AI/btselector.h b/engine-ocean/Game/Systems/AI/btselector.h new file mode 100644 index 0000000..20058ac --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btselector.h @@ -0,0 +1,21 @@ +#ifndef BTSELECTOR_H +#define BTSELECTOR_H +#include "Game/Systems/AI/btnode.h" +#include <vector> + + +class BTSelector : public BTNode +{ +public: + BTSelector(); + Status update(float seconds) override; + void reset() override; + void addChildren(BTNode *node) override; + + +private: + std::vector<BTNode *> m_children; + BTNode *m_selected_node; +}; + +#endif // BTSELECTOR_H diff --git a/engine-ocean/Game/Systems/AI/btsequence.cpp b/engine-ocean/Game/Systems/AI/btsequence.cpp new file mode 100644 index 0000000..ba6169d --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btsequence.cpp @@ -0,0 +1,30 @@ +#include "btsequence.h" +#include <vector> + +BTSequence::BTSequence() +{ + +} + +void BTSequence::addChildren(BTNode *node){ + m_sequence.push_back(node); +} + +Status BTSequence::update(float seconds){ + + for (auto node : m_sequence){ + if (node->update(seconds) == Status::FAIL){ + return Status::RUNNING; + } + // if come across any node that fails + if (node->update(seconds) == Status::FAIL){ + return Status::FAIL; + } + } + + // if no node is fail or running, sequence is completed + return Status::SUCCESS; +} + +void BTSequence::reset(){} + diff --git a/engine-ocean/Game/Systems/AI/btsequence.h b/engine-ocean/Game/Systems/AI/btsequence.h new file mode 100644 index 0000000..5ff230c --- /dev/null +++ b/engine-ocean/Game/Systems/AI/btsequence.h @@ -0,0 +1,20 @@ +#ifndef BTSEQUENCE_H +#define BTSEQUENCE_H +#include "btnode.h" +#include <vector> + + +class BTSequence : public BTNode +{ +public: + BTSequence(); + Status update(float seconds) override; + void reset() override; + void addChildren(BTNode* node) override; + + +private: + std::vector<BTNode *> m_sequence; +}; + +#endif // BTSEQUENCE_H |