Skip to content

Commit eca894e

Browse files
committed
add flag to automatically cancel future waves if a mothership is destroyed
Infamously, in FSO, a wing whose mothership is destroyed will not, itself, be considered destroyed if it has more waves remaining, because wing cleanup and logging typically only happen when the last ship in the last wave exits the mission. Instead, with no mothership to arrive from, waves will simply no longer arrive. Events that check to see if the wing is destroyed or departed will never fire. This PR fixes that behavior, ensuring that the wing is cleaned up and logged properly, by using the same logic as the enhanced `cancel-future-waves` SEXP operator. This is tied to a new `$cancel future waves of any wing launched from an exited ship:` AI profiles flag which is enabled by default on 25.0+.
1 parent beaeafe commit eca894e

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed

code/ai/ai_flags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ namespace AI {
188188
Do_not_clear_goals_when_running_stay_still,
189189
Do_not_set_override_when_assigning_form_on_wing,
190190
Purge_player_issued_form_on_wing_after_subsequent_order,
191+
Cancel_future_waves_of_any_wing_launched_from_an_exited_ship,
191192

192193
NUM_VALUES
193194
};

code/ai/ai_profiles.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,8 @@ void parse_ai_profiles_tbl(const char *filename)
742742

743743
set_flag(profile, "$purge player-issued form-on-wing after subsequent order:", AI::Profile_Flags::Purge_player_issued_form_on_wing_after_subsequent_order);
744744

745+
set_flag(profile, "$cancel future waves of any wing launched from an exited ship:", AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship);
746+
745747

746748
// end of options ----------------------------------------
747749

@@ -963,5 +965,6 @@ void ai_profile_t::reset()
963965
if (mod_supports_version(25, 0, 0)) {
964966
flags.set(AI::Profile_Flags::Fix_avoid_shockwave_bugs);
965967
flags.set(AI::Profile_Flags::Purge_player_issued_form_on_wing_after_subsequent_order);
968+
flags.set(AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship);
966969
}
967970
}

code/parse/sexp.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4218,19 +4218,23 @@ int check_sexp_potential_issues(int node, int *bad_node, SCP_string &issue_msg)
42184218
case OP_IS_DESTROYED:
42194219
case OP_TIME_WING_DESTROYED:
42204220
{
4221-
for (int n = first_arg_node; n >= 0; n = CDR(n))
4221+
if (!The_mission.ai_profile->flags[AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship])
42224222
{
4223-
int wingnum = wing_lookup(CTEXT(n));
4224-
if (wingnum >= 0)
4223+
for (int n = first_arg_node; n >= 0; n = CDR(n))
42254224
{
4226-
auto wingp = &Wings[wingnum];
4227-
if (wingp->num_waves > 1 && wingp->arrival_location == ArrivalLocation::FROM_DOCK_BAY)
4225+
int wingnum = wing_lookup(CTEXT(n));
4226+
if (wingnum >= 0)
42284227
{
4229-
issue_msg = "Wing ";
4230-
issue_msg += wingp->name;
4231-
issue_msg += " has more than one wave and arrives from a docking bay. Be careful when checking for this wing's destruction. If the "
4232-
"mothership is destroyed before all waves have arrived, the wing will not be considered destroyed.";
4233-
return SEXP_CHECK_POTENTIAL_ISSUE;
4228+
auto wingp = &Wings[wingnum];
4229+
if (wingp->num_waves > 1 && wingp->arrival_location == ArrivalLocation::FROM_DOCK_BAY)
4230+
{
4231+
issue_msg = "Wing ";
4232+
issue_msg += wingp->name;
4233+
issue_msg += " has more than one wave and arrives from a docking bay. Be careful when checking for this wing's destruction. If the "
4234+
"mothership is destroyed before all waves have arrived, the wing will not be considered destroyed. Note that the "
4235+
"$cancel future waves of any wing launched from an exited ship: flag can be used to fix this.";
4236+
return SEXP_CHECK_POTENTIAL_ISSUE;
4237+
}
42344238
}
42354239
}
42364240
}

code/ship/ship.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9267,6 +9267,20 @@ void ship_cleanup(int shipnum, int cleanup_mode)
92679267
ship_wing_cleanup(shipnum, wingp);
92689268
}
92699269

9270+
// maybe clean up any wings that arrived from this ship
9271+
if (The_mission.ai_profile->flags[AI::Profile_Flags::Cancel_future_waves_of_any_wing_launched_from_an_exited_ship]) {
9272+
for (int child_wingnum = 0; child_wingnum < Num_wings; ++child_wingnum) {
9273+
auto child_wingp = &Wings[child_wingnum];
9274+
if (child_wingp->arrival_location == ArrivalLocation::FROM_DOCK_BAY && child_wingp->arrival_anchor == shipnum) {
9275+
// prevent any more waves from arriving by marking this as the last wave
9276+
child_wingp->num_waves = child_wingp->current_wave;
9277+
9278+
// we might need to clean up this wing if there are no ships currently in the mission
9279+
wing_maybe_cleanup(child_wingp);
9280+
}
9281+
}
9282+
}
9283+
92709284
// Note, this call to ai_ship_destroy() must come after ship_wing_cleanup for guarded wings to
92719285
// properly note the destruction of a ship in their wing.
92729286
ai_ship_destroy(shipnum); // Do AI stuff for destruction/leave of ship.

0 commit comments

Comments
 (0)