diff --git a/code/ai/aigoals.cpp b/code/ai/aigoals.cpp index 9402b7f7b0b..9c0dbf50ddd 100644 --- a/code/ai/aigoals.cpp +++ b/code/ai/aigoals.cpp @@ -825,7 +825,8 @@ void ai_add_goal_sub_player(ai_goal_type type, ai_goal_mode mode, int submode, c // friendlies want to rearm at the same time. The support ship forgets what it's doing and flies // off to repair somebody while still docked. I reproduced this with retail, so it's not a bug in // my new docking code. :) -int ai_goal_find_empty_slot( ai_goal *goals, int active_goal ) +// Note that this function is now where Purge_when_new_goal_added is checked to set the Purge flag. +int ai_goal_allocate_slot( ai_goal *goals, int active_goal ) { int oldest_index = -1, first_empty_index = -1; @@ -915,7 +916,7 @@ void ai_add_ship_goal_scripting(ai_goal_mode mode, int submode, int priority, co int empty_index; ai_goal *aigp; - empty_index = ai_goal_find_empty_slot(aip->goals, aip->active_goal); + empty_index = ai_goal_allocate_slot(aip->goals, aip->active_goal); aigp = &aip->goals[empty_index]; ai_add_goal_sub_scripting(ai_goal_type::PLAYER_SHIP, mode, submode, priority, shipname, aigp, int_data, float_data); @@ -939,7 +940,7 @@ void ai_add_ship_goal_player(ai_goal_type type, ai_goal_mode mode, int submode, int empty_index; ai_goal *aigp; - empty_index = ai_goal_find_empty_slot( aip->goals, aip->active_goal ); + empty_index = ai_goal_allocate_slot( aip->goals, aip->active_goal ); aigp = &aip->goals[empty_index]; ai_add_goal_sub_player( type, mode, submode, shipname, aigp, int_data, float_data, lua_target ); @@ -973,7 +974,7 @@ void ai_add_wing_goal_player(ai_goal_type type, ai_goal_mode mode, int submode, // add the sexpression index into the wing's list of goal sexpressions if // there are more waves to come. We use the same method here as when adding a goal to // a ship -- find the first empty entry. If none exists, take the oldest entry and replace it. - empty_index = ai_goal_find_empty_slot( wingp->ai_goals, -1 ); + empty_index = ai_goal_allocate_slot( wingp->ai_goals, -1 ); ai_add_goal_sub_player( type, mode, submode, shipname, &wingp->ai_goals[empty_index], int_data, float_data, lua_target ); } @@ -1613,7 +1614,7 @@ void ai_add_ship_goal_sexp( int sexp, ai_goal_type type, ai_info *aip ) { int gindex; - gindex = ai_goal_find_empty_slot( aip->goals, aip->active_goal ); + gindex = ai_goal_allocate_slot( aip->goals, aip->active_goal ); ai_add_goal_sub_sexp( sexp, type, aip, &aip->goals[gindex], Ships[aip->shipnum].ship_name ); } @@ -1637,7 +1638,7 @@ void ai_add_wing_goal_sexp(int sexp, ai_goal_type type, wing *wingp) if ((wingp->num_waves - wingp->current_wave > 0) || Fred_running) { int gindex; - gindex = ai_goal_find_empty_slot( wingp->ai_goals, -1 ); + gindex = ai_goal_allocate_slot( wingp->ai_goals, -1 ); ai_add_goal_sub_sexp( sexp, type, nullptr, &wingp->ai_goals[gindex], wingp->name ); } } @@ -1660,7 +1661,7 @@ void ai_add_goal_ship_internal( ai_info *aip, int goal_type, char *name, int /* Assertion(strcmp(name, Ships[aip->shipnum].ship_name) != 0, "The goals apply to the actor in ai_add_goal_ship_internal for ship %s, please report to the SCP!", name); // find an empty slot to put this goal in. - gindex = ai_goal_find_empty_slot( aip->goals, aip->active_goal ); + gindex = ai_goal_allocate_slot( aip->goals, aip->active_goal ); aigp = &(aip->goals[gindex]); ai_goal_reset(aigp, true); @@ -1789,7 +1790,7 @@ ai_achievability ai_mission_goal_achievable( int objnum, ai_goal *aigp ) if (!target_ship_entry || !target_ship_entry->has_shipp()) return ai_achievability::NOT_ACHIEVABLE; - // the override flag is now set in the calling function, ai_mission_goal_achievable + // the override flag is now set in the calling function, validate_mission_goals return ai_achievability::ACHIEVABLE; } diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp index 3c3cda2c890..8982e41b8e9 100644 --- a/code/parse/sexp.cpp +++ b/code/parse/sexp.cpp @@ -2689,7 +2689,10 @@ int check_sexp_syntax(int node, int desired_return_type, int recursive, int *bad } break; } - Assert(ship_node >= 0); + if (ship_node < 0) { + Warning(LOCATION, "Could not find ship node for operator %s!", Operators[op_index].text.c_str()); + return SEXP_CHECK_INVALID_SHIP; + } if (is_node_value_dynamic(ship_node)) { const int dyn_val_check = check_dynamic_value_node_type(ship_node, true, false); @@ -4034,7 +4037,10 @@ int check_sexp_syntax(int node, int desired_return_type, int recursive, int *bad } p_container = get_sexp_container(Sexp_nodes[node].text); - Assertion(p_container, "Attempt to use unknown container %s. Please report!", Sexp_nodes[node].text); + if (!p_container) { + Warning(LOCATION, "Attempt to use unknown container %s. Please report!", Sexp_nodes[node].text); + return SEXP_CHECK_TYPE_MISMATCH; + } if ((desired_argument_type == OPF_LIST_CONTAINER_NAME && !p_container->is_list()) || (desired_argument_type == OPF_MAP_CONTAINER_NAME && !p_container->is_map())) { @@ -4044,10 +4050,10 @@ int check_sexp_syntax(int node, int desired_return_type, int recursive, int *bad } case OPF_CONTAINER_VALUE: - Assertion(p_container, - "Attempt to check value arg for null container for SEXP operator %d at arg %d. Please report!", - op_const, - argnum); + if (!p_container) { + Warning(LOCATION, "Attempt to check value arg for null container for SEXP operator %s at arg %d. Please report!", Operators[op_index].text.c_str(), argnum); + return SEXP_CHECK_TYPE_MISMATCH; + } z = check_container_value_data_type(op_const, argnum, p_container->type, @@ -4063,9 +4069,10 @@ int check_sexp_syntax(int node, int desired_return_type, int recursive, int *bad if (node_subtype == SEXP_ATOM_CONTAINER_NAME) { // only list containers of strings or map containers with string keys are allowed const auto *p_str_container = get_sexp_container(Sexp_nodes[node].text); - Assertion(p_str_container, - "Attempt to use unknown container %s. Please report!", - Sexp_nodes[node].text); + if (!p_str_container) { + Warning(LOCATION, "Attempt to use unknown container %s. Please report!", Sexp_nodes[node].text); + return SEXP_CHECK_TYPE_MISMATCH; + } const auto &str_container = *p_str_container; if (str_container.is_list() && none(str_container.type & ContainerType::STRING_DATA)) {