Пример #1
0
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();
	}
}
Пример #4
0
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();
}