Skip to content

Commit b8fa520

Browse files
committed
patch cancel-future-waves to handle absent waves
If the `cancel-future-waves` sexp is called when a wave is not present, it would previously not handle wing cleanup, such as setting flags and updating the mission log.
1 parent f087c8a commit b8fa520

3 files changed

Lines changed: 52 additions & 6 deletions

File tree

code/parse/sexp.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15480,10 +15480,16 @@ void sexp_self_destruct(int node)
1548015480

1548115481
void sexp_cancel_future_waves(int node)
1548215482
{
15483-
for (int n = node; n != -1; n = CDR(n)) {
15483+
for (int n = node; n != -1; n = CDR(n))
15484+
{
1548415485
auto wingp = eval_wing(n);
15485-
if (wingp) {
15486+
if (wingp)
15487+
{
15488+
// prevent any more waves from arriving by marking this as the last wave
1548615489
wingp->num_waves = wingp->current_wave;
15490+
15491+
// we might need to clean up this wing if there are no ships currently in the mission
15492+
wing_maybe_cleanup(wingp);
1548715493
}
1548815494
}
1548915495
}
@@ -40094,11 +40100,13 @@ SCP_vector<sexp_help_struct> Sexp_help = {
4009440100
},
4009540101

4009640102
{ OP_CANCEL_FUTURE_WAVES, "cancel-future-waves\r\n"
40097-
"\tCancel all waves of a wing which have not yet arrived. Waves that have arrived already are not affected. is-destroyed-delay, ship-type-destroyed, and similar operators behave as though the cancelled waves do not exist.\r\n\r\nIf this operator is called on a wing which has not arrived, the wing will never arrive, exactly as if its arrival cue were set to false. That wing is not marked as destroyed.\r\n\r\n"
40103+
"\tCancel all waves of a wing which have not yet arrived. Waves that have arrived already are not affected. The is-destroyed-delay, "
40104+
"ship-type-destroyed, and similar operators behave as though the cancelled waves do not exist.\r\n\r\nIf this operator is called on a wing "
40105+
"which has not arrived, the wing will never arrive, exactly as if its arrival cue were set to false; and that wing is not marked as destroyed. "
40106+
"Otherwise, wings will be marked as destroyed or departed in the same manner as they would have been if they were truly on the last wave.\r\n\r\n"
4009840107
"Takes 1 or more arguments...\r\n"
4009940108
"\tAll:\tThe name of a wing to cancel." },
4010040109

40101-
4010240110
{ OP_SHIP_VISIBLE, "ship-visible\r\n"
4010340111
"\tCauses the ships listed in this sexpression to be visible with player sensors.\r\n\r\n"
4010440112
"Takes 1 or more arguments...\r\n"

code/ship/ship.cpp

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8881,6 +8881,43 @@ void ship_wing_cleanup( int shipnum, wing *wingp )
88818881
wingp->special_ship_ship_info_index = Ships[wingp->ship_index[0]].ship_info_index;
88828882
}
88838883

8884+
wing_maybe_cleanup(wingp, team);
8885+
}
8886+
8887+
// Assume the team of the wing is the same as the team of the most recently exited ship from that wing.
8888+
// Returns -1 if no ship from that wing has exited.
8889+
int wing_determine_team(const wing *wingp)
8890+
{
8891+
int wingnum = WING_INDEX(wingp);
8892+
int team = -1;
8893+
fix latest_exit_time = -1;
8894+
8895+
// Grab the team from the most recent ship in this wing to have exited the mission. If there are no exited ships from this wing,
8896+
// that means they all vanished. In that case we must return -1, but it doesn't matter for logging because vanished wings aren't logged.
8897+
for (const auto &entry : Ships_exited)
8898+
{
8899+
if ((entry.wingnum == wingnum) && (entry.time > latest_exit_time))
8900+
{
8901+
latest_exit_time = entry.time;
8902+
team = entry.team;
8903+
}
8904+
}
8905+
8906+
return team;
8907+
}
8908+
8909+
/**
8910+
* This was originally part of ::ship_wing_cleanup, but it can now be called separately. It sets various flags and mission log entries
8911+
* associated with a wing no longer being in a mission.
8912+
*
8913+
* The team parameter is used for logging. If it is not supplied (i.e. is not >= 0), it will be derived using wing_determine_team().
8914+
*/
8915+
void wing_maybe_cleanup( wing *wingp, int team )
8916+
{
8917+
// not if the wing is already gone or has not yet arrived
8918+
if (wingp->flags[Ship::Wing_Flags::Gone] || wingp->total_arrived_count == 0)
8919+
return;
8920+
88848921
// if the current count is 0, check to see if the wing departed or was destroyed.
88858922
if (wingp->current_count == 0)
88868923
{
@@ -8905,15 +8942,15 @@ void ship_wing_cleanup( int shipnum, wing *wingp )
89058942
// first, be sure to mark a wing destroyed event if all members of wing were destroyed and on
89068943
// the last wave. This circumvents a problem where the wing could be marked as departed and
89078944
// destroyed if the last ships were destroyed after the wing's departure cue became true.
8908-
mission_log_add_entry(LOG_WING_DESTROYED, wingp->name, NULL, team);
8945+
mission_log_add_entry(LOG_WING_DESTROYED, wingp->name, nullptr, team >= 0 ? team : wing_determine_team(wingp));
89098946
}
89108947
// if some ships escaped, log it as departed
89118948
else if (wingp->total_vanished != wingp->total_arrived_count)
89128949
{
89138950
// if the wing wasn't destroyed, and it is departing, then mark it as departed -- in this
89148951
// case, there had better be ships in this wing with departure entries in the log file. The
89158952
// logfile code checks for this case.
8916-
mission_log_add_entry(LOG_WING_DEPARTED, wingp->name, NULL, team);
8953+
mission_log_add_entry(LOG_WING_DEPARTED, wingp->name, nullptr, team >= 0 ? team : wing_determine_team(wingp));
89178954
}
89188955

89198956
#ifndef NDEBUG

code/ship/ship.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,7 @@ extern void ship_subsys_set_disrupted(ship_subsys *ss, int time);
18251825
extern int ship_do_rearm_frame( object *objp, float frametime );
18261826
extern float ship_calculate_rearm_duration( object *objp );
18271827
extern void ship_wing_cleanup( int shipnum, wing *wingp );
1828+
extern void wing_maybe_cleanup( wing *wingp, int team = -1 );
18281829

18291830
extern int ship_find_repair_ship( object *requester_obj, object **ship_we_found = NULL );
18301831
extern void ship_close(); // called in game_shutdown() to free malloced memory

0 commit comments

Comments
 (0)