void Behavior::doAction(bool directlyExecuted) { if (agent->isDead() || agent->isIncapacitated() || (agent->getZone() == NULL)) { agent->setFollowObject(NULL); return; } //agent->info(id, true); agent->setCurrentBehavior(id); if (!started()) this->start(); else if (!this->checkConditions()) endWithFailure(); if (finished()) { if (parent == NULL) { this->end(); result = AiMap::SUSPEND; agent->activateMovementEvent(); // this is an automatic recycle decorator for the root node } else if (directlyExecuted) { agent->setCurrentBehavior(parent->id); parent->doAction(true); } return; } int res = AiMap::INVALID; if (interface != NULL) res = interface->doAction(agent); switch(res) { case AiMap::SUCCESS: endWithSuccess(); break; case AiMap::FAILURE: endWithFailure(); break; case AiMap::INVALID: if (agent == NULL) return; agent->resetBehaviorList(); break; default: if (agent == NULL) return; break; } if (!finished() || parent == NULL) agent->activateMovementEvent(); else if (directlyExecuted) { agent->setCurrentBehavior(parent->id); parent->doAction(true); } }
void CompositeBehavior::doAction(bool directlyExecuted) { if (agent->isDead() || agent->isIncapacitated() || (agent->getZone() == NULL)) { agent->setFollowObject(NULL); return; } if (!started()) this->start(); else if (!checkConditions()) endWithFailure(); if (finished()) { Behavior::doAction(directlyExecuted); return; } Behavior* currentChild; do { currentChild = children.get(currentPos); if (currentChild == NULL) { agent->error("NULL child or empty children list in CompositeBehavior"); endWithError(); Behavior::doAction(directlyExecuted); return; } if (!currentChild->started()) currentChild->start(); else if (!currentChild->checkConditions()) // if this isn't here, I can get a single recursion where the child will call the parent's (this) doAction() endWithFailure(); if (!currentChild->finished()) currentChild->doAction(); if (currentChild->finished()) { if (currentChild->succeeded()) this->childSucceeded(); else if (currentChild->failed()) this->childFailed(); currentChild->end(); } } while (currentChild != NULL && currentChild->finished() && !this->finished() && currentPos < children.size()); if (currentChild->finished()) Behavior::doAction(directlyExecuted); }
void SequenceBehavior::childSucceeded() { if (currentPos == children.size() - 1) endWithSuccess(); else { currentPos++; Behavior* currentChild = children.get(currentPos); if (currentChild == NULL || !currentChild->checkConditions()) endWithFailure(); } }
void Behavior::start() { if (!checkConditions()) { endWithFailure(); return; } result = AiMap::RUNNING; if (interface != NULL) interface->start(agent); }
void SequenceBehavior::childFailed() { endWithFailure(); }
void ParallelSequenceBehavior::finish() { if (numFailed > 0) endWithFailure(); else endWithSuccess(); }