#include "stdafx.h" #include "BehaviourTree.h" #include "SurvivalAgentPlugin.h" using namespace BT; #pragma region COMPOSITES Composite::Composite(const std::vector& childBehaviors) { m_ChildBehaviors = childBehaviors; } Composite::~Composite() { for (auto pb : m_ChildBehaviors) SAFE_DELETE(pb) m_ChildBehaviors.clear(); } //SELECTOR State Selector::Execute(Blackboard* blackboardPtr) { // Loop over all children in m_ChildBehaviors for (IBehavior* pBeh : m_ChildBehaviors) { //Every Child: Execute and store the result in m_CurrentState m_CurrentState = pBeh->Execute(blackboardPtr); //Check the currentstate and apply the selector Logic: //if a child returns Success: if (m_CurrentState == State::Success) { //stop looping over all children and return Success return m_CurrentState; } //if a child returns Running: if (m_CurrentState == State::Running) { //Running: stop looping and return Running return m_CurrentState; } //The selector fails if all children failed. } //All children failed m_CurrentState = State::Failure; return m_CurrentState; } //SEQUENCE State Sequence::Execute(Blackboard* blackboardPtr) { //Loop over all children in m_ChildBehaviors for (IBehavior* pBeh : m_ChildBehaviors) { //Every Child: Execute and store the result in m_CurrentState m_CurrentState = pBeh->Execute(blackboardPtr); //Check the currentstate and apply the sequence Logic: //if a child returns Failed: if (m_CurrentState == State::Failure) { //stop looping over all children and return Failed return m_CurrentState; } //if a child returns Running: if (m_CurrentState == State::Running) { //Running: stop looping and return Running return m_CurrentState; } //The selector succeeds if all children succeeded. } //All children succeeded m_CurrentState = State::Success; return m_CurrentState; } State PartialSequence::Execute(Blackboard* blackboardPtr) { while (m_CurrentBehaviorIndex < m_ChildBehaviors.size()) { m_CurrentState = m_ChildBehaviors[m_CurrentBehaviorIndex]->Execute(blackboardPtr); switch (m_CurrentState) { case State::Failure: m_CurrentBehaviorIndex = 0; return m_CurrentState; case State::Success: ++m_CurrentBehaviorIndex; m_CurrentState = State::Running; return m_CurrentState; case State::Running: return m_CurrentState; } } m_CurrentBehaviorIndex = 0; m_CurrentState = State::Success; return m_CurrentState; } #pragma endregion State Conditional::Execute(Blackboard* blackboardPtr) { if (m_ConditionalPtr == nullptr) return State::Failure; if (m_ConditionalPtr(blackboardPtr)) { m_CurrentState = State::Success; } else { m_CurrentState = State::Failure; } return m_CurrentState; } State Action::Execute(Blackboard* blackboardPtr) { if (m_ActionPtr == nullptr) return State::Failure; m_CurrentState = m_ActionPtr(blackboardPtr); return m_CurrentState; } BehaviorTree::~BehaviorTree() { SAFE_DELETE(m_RootBehaviorPtr) SAFE_DELETE(m_BlackboardPtr) //Takes ownership of passed blackboard! } void BehaviorTree::Update() { if (m_RootBehaviorPtr == nullptr) { m_CurrentState = State::Failure; return; } m_CurrentState = m_RootBehaviorPtr->Execute(m_BlackboardPtr); } Blackboard* BehaviorTree::GetBlackboard() const { return m_BlackboardPtr; }