Skip to content

Commit 7124916

Browse files
authored
Merge pull request #7080 from Goober5000/patch_cancel_future_waves
patch cancel-future-waves to handle absent waves
2 parents 7eff790 + b8fa520 commit 7124916

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
@@ -8909,6 +8909,43 @@ void ship_wing_cleanup( int shipnum, wing *wingp )
89098909
wingp->special_ship_ship_info_index = Ships[wingp->ship_index[0]].ship_info_index;
89108910
}
89118911

8912+
wing_maybe_cleanup(wingp, team);
8913+
}
8914+
8915+
// Assume the team of the wing is the same as the team of the most recently exited ship from that wing.
8916+
// Returns -1 if no ship from that wing has exited.
8917+
int wing_determine_team(const wing *wingp)
8918+
{
8919+
int wingnum = WING_INDEX(wingp);
8920+
int team = -1;
8921+
fix latest_exit_time = -1;
8922+
8923+
// 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,
8924+
// 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.
8925+
for (const auto &entry : Ships_exited)
8926+
{
8927+
if ((entry.wingnum == wingnum) && (entry.time > latest_exit_time))
8928+
{
8929+
latest_exit_time = entry.time;
8930+
team = entry.team;
8931+
}
8932+
}
8933+
8934+
return team;
8935+
}
8936+
8937+
/**
8938+
* This was originally part of ::ship_wing_cleanup, but it can now be called separately. It sets various flags and mission log entries
8939+
* associated with a wing no longer being in a mission.
8940+
*
8941+
* 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().
8942+
*/
8943+
void wing_maybe_cleanup( wing *wingp, int team )
8944+
{
8945+
// not if the wing is already gone or has not yet arrived
8946+
if (wingp->flags[Ship::Wing_Flags::Gone] || wingp->total_arrived_count == 0)
8947+
return;
8948+
89128949
// if the current count is 0, check to see if the wing departed or was destroyed.
89138950
if (wingp->current_count == 0)
89148951
{
@@ -8933,15 +8970,15 @@ void ship_wing_cleanup( int shipnum, wing *wingp )
89338970
// first, be sure to mark a wing destroyed event if all members of wing were destroyed and on
89348971
// the last wave. This circumvents a problem where the wing could be marked as departed and
89358972
// destroyed if the last ships were destroyed after the wing's departure cue became true.
8936-
mission_log_add_entry(LOG_WING_DESTROYED, wingp->name, NULL, team);
8973+
mission_log_add_entry(LOG_WING_DESTROYED, wingp->name, nullptr, team >= 0 ? team : wing_determine_team(wingp));
89378974
}
89388975
// if some ships escaped, log it as departed
89398976
else if (wingp->total_vanished != wingp->total_arrived_count)
89408977
{
89418978
// if the wing wasn't destroyed, and it is departing, then mark it as departed -- in this
89428979
// case, there had better be ships in this wing with departure entries in the log file. The
89438980
// logfile code checks for this case.
8944-
mission_log_add_entry(LOG_WING_DEPARTED, wingp->name, NULL, team);
8981+
mission_log_add_entry(LOG_WING_DEPARTED, wingp->name, nullptr, team >= 0 ? team : wing_determine_team(wingp));
89458982
}
89468983

89478984
#ifndef NDEBUG

code/ship/ship.h

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

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

0 commit comments

Comments
 (0)