Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion code/network/multimsgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4046,9 +4046,17 @@ void process_endgame_packet(ubyte * /*data*/, header *hinfo)
// do any special processing for being in a state other than the gameplay state
multi_handle_state_special();

// If end-mission fired via SEXP, enter debrief immediately (skipping warp-out).
// Stats have already been received via multi_broadcast_stats() which send_endgame_packet()
// calls before sending this packet, so scoring_level_close() will see correct kill data.
if (Multi_sexp_end_mission_pending) {
Multi_sexp_end_mission_pending = false;
send_debrief_event();
}

// make sure we're not already in the debrief state
if((gameseq_get_state() != GS_STATE_DEBRIEF) && (gameseq_get_state() != GS_STATE_MULTI_DOGFIGHT_DEBRIEF)){
multi_warpout_all_players();
multi_warpout_all_players();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions code/network/multiui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8836,6 +8836,7 @@ void multi_debrief_esc_hit()
multi_sw_report(stats_saved);
}
}

}

multi_quit_game(PROMPT_HOST);
Expand Down
6 changes: 6 additions & 0 deletions code/network/multiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,12 @@ void multi_apply_ship_status(net_player *p,button_info *bi,int locally)
// send 10x a second MAX
#define MULTI_SHIP_STATUS_TIME 350
int Multi_ship_status_stamp = -1;

// Set by multi_sexp_end_mission() so that process_endgame_packet() knows to call
// send_debrief_event() immediately upon receiving MISSION_END, skipping warp-out.
// Must be checked after stats have been broadcast by the server (which happens
// in send_endgame_packet() before the MISSION_END packet is sent).
bool Multi_sexp_end_mission_pending = false;
button_info Multi_ship_status_bi;

void multi_maybe_send_ship_status()
Expand Down
4 changes: 4 additions & 0 deletions code/network/multiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ short multi_get_new_id();
// Karajorma - sends the player to the correct debrief for this game type
void send_debrief_event();

// Set by multi_sexp_end_mission() to signal that process_endgame_packet() should
// enter debrief immediately (skipping warp-out) once stats have been received.
extern bool Multi_sexp_end_mission_pending;

// Karajorma - Performs any cleanup needed by missions which don't end with a warpout.
void multi_handle_sudden_mission_end();

Expand Down
16 changes: 12 additions & 4 deletions code/parse/sexp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17216,10 +17216,18 @@ void sexp_end_mission(int n)

void multi_sexp_end_mission()
{
// This is a bit of hack, but when in a debrief state clients will skip the
// warp out sequence when the endgame packet is processed.
send_debrief_event();
// Standard way to end mission (equivalent to Alt-J)
// Signal process_endgame_packet() to skip the warp-out sequence by entering
// debrief immediately when the MISSION_END packet arrives. We cannot call
// send_debrief_event() here directly: on standalone servers the client has not
// yet received mission stats (m_okKills etc.) at this point, so
// scoring_level_close() would run with zeroed kill counts and
// Pilot.update_stats() would create no kill entries. debrief_close() would
// then try to back out entries that were never created and hit an UNREACHABLE.
//
// send_endgame_packet() broadcasts stats to clients *before* sending MISSION_END,
// so by the time process_endgame_packet() fires, the stats are already present
// and it is safe to enter debrief there.
Multi_sexp_end_mission_pending = true;
multi_handle_end_mission_request();
}

Expand Down
Loading