Fix decorator having no children crash

This commit is contained in:
Serhii Snitsaruk 2022-09-21 12:37:19 +02:00
parent a3cac93174
commit 8b1b0dd754
12 changed files with 13 additions and 3 deletions

View File

@ -3,7 +3,7 @@
#include "bt_always_fail.h" #include "bt_always_fail.h"
int BTAlwaysFail::_tick(float p_delta) { int BTAlwaysFail::_tick(float p_delta) {
if (get_child(0)->execute(p_delta) == RUNNING) { if (get_child_count() > 0 && get_child(0)->execute(p_delta) == RUNNING) {
return RUNNING; return RUNNING;
} }
return FAILURE; return FAILURE;

View File

@ -3,7 +3,7 @@
#include "bt_always_succeed.h" #include "bt_always_succeed.h"
int BTAlwaysSucceed::_tick(float p_delta) { int BTAlwaysSucceed::_tick(float p_delta) {
if (get_child(0)->execute(p_delta) == RUNNING) { if (get_child_count() > 0 && get_child(0)->execute(p_delta) == RUNNING) {
return RUNNING; return RUNNING;
} }
return SUCCESS; return SUCCESS;

View File

@ -3,6 +3,7 @@
#include "bt_delay.h" #include "bt_delay.h"
#include "core/array.h" #include "core/array.h"
#include "core/class_db.h" #include "core/class_db.h"
#include "core/error_macros.h"
#include "core/object.h" #include "core/object.h"
#include "core/variant.h" #include "core/variant.h"
@ -15,6 +16,7 @@ void BTDelay::_enter() {
} }
int BTDelay::_tick(float p_delta) { int BTDelay::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
time_passed += p_delta; time_passed += p_delta;
if (time_passed <= seconds) { if (time_passed <= seconds) {
return RUNNING; return RUNNING;

View File

@ -3,6 +3,7 @@
#include "bt_invert.h" #include "bt_invert.h"
int BTInvert::_tick(float p_delta) { int BTInvert::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
int status = get_child(0)->execute(p_delta); int status = get_child(0)->execute(p_delta);
if (status == SUCCESS) { if (status == SUCCESS) {
status = FAILURE; status = FAILURE;

View File

@ -14,7 +14,7 @@ void BTNewScope::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard
} }
int BTNewScope::_tick(float p_delta) { int BTNewScope::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator doesn't have a child."); ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
return get_child(0)->execute(p_delta); return get_child(0)->execute(p_delta);
} }

View File

@ -8,6 +8,7 @@ String BTProbability::_generate_name() const {
} }
int BTProbability::_tick(float p_delta) { int BTProbability::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
if (get_child(0)->get_status() == RUNNING or Math::randf() <= run_chance) { if (get_child(0)->get_status() == RUNNING or Math::randf() <= run_chance) {
return get_child(0)->execute(p_delta); return get_child(0)->execute(p_delta);
} }

View File

@ -13,6 +13,7 @@ void BTRepeat::_enter() {
} }
int BTRepeat::_tick(float p_delta) { int BTRepeat::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
int status = get_child(0)->execute(p_delta); int status = get_child(0)->execute(p_delta);
if (status == RUNNING) { if (status == RUNNING) {
return RUNNING; return RUNNING;

View File

@ -3,6 +3,7 @@
#include "bt_repeat_until_failure.h" #include "bt_repeat_until_failure.h"
int BTRepeatUntilFailure::_tick(float p_delta) { int BTRepeatUntilFailure::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
if (get_child(0)->execute(p_delta) == FAILURE) { if (get_child(0)->execute(p_delta) == FAILURE) {
return SUCCESS; return SUCCESS;
} }

View File

@ -3,6 +3,7 @@
#include "bt_repeat_until_success.h" #include "bt_repeat_until_success.h"
int BTRepeatUntilSuccess::_tick(float p_delta) { int BTRepeatUntilSuccess::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
if (get_child(0)->execute(p_delta) == SUCCESS) { if (get_child(0)->execute(p_delta) == SUCCESS) {
return SUCCESS; return SUCCESS;
} }

View File

@ -7,6 +7,7 @@ String BTRunLimit::_generate_name() const {
} }
int BTRunLimit::_tick(float p_delta) { int BTRunLimit::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
if (get_child(0)->get_status() != RUNNING) { if (get_child(0)->get_status() != RUNNING) {
if (_num_runs >= run_limit) { if (_num_runs >= run_limit) {
return FAILURE; return FAILURE;

View File

@ -29,6 +29,7 @@ Ref<BTTask> BTSubtree::clone() const {
if (!Engine::get_singleton()->is_editor_hint()) { if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_COND_V_MSG(!subtree.is_valid(), copy, "Subtree is not assigned."); ERR_FAIL_COND_V_MSG(!subtree.is_valid(), copy, "Subtree is not assigned.");
ERR_FAIL_COND_V_MSG(!subtree->get_root_task().is_valid(), copy, "Subtree root task is not valid."); ERR_FAIL_COND_V_MSG(!subtree->get_root_task().is_valid(), copy, "Subtree root task is not valid.");
ERR_FAIL_COND_V_MSG(get_child_count() != 0, copy, "Subtree prototype shouldn't have children.");
copy->add_child(subtree->get_root_task()->clone()); copy->add_child(subtree->get_root_task()->clone());
} }

View File

@ -11,6 +11,7 @@ void BTTimeLimit::_enter() {
} }
int BTTimeLimit::_tick(float p_delta) { int BTTimeLimit::_tick(float p_delta) {
ERR_FAIL_COND_V_MSG(get_child_count() == 0, FAILURE, "BT decorator has no child.");
_time_passed += p_delta; _time_passed += p_delta;
int status = get_child(0)->execute(p_delta); int status = get_child(0)->execute(p_delta);
if (status == RUNNING and _time_passed >= time_limit) { if (status == RUNNING and _time_passed >= time_limit) {