From 5f04cbaecb1d17a740a9f9d5924eac57b9f077d6 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 8 Dec 2022 17:30:24 -0800 Subject: [PATCH] fix results screen for final tournament match --- src/CommandFormats.hh | 12 +++++++----- src/Episode3/Server.cc | 2 ++ src/Episode3/Tournament.cc | 4 ++++ src/Episode3/Tournament.hh | 1 + src/SendCommands.cc | 14 ++++++++++---- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 0d8cad6d..a860c03d 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -5496,11 +5496,13 @@ struct G_TournamentMatchResult_GC_Ep3_6xB4x51 { parray, 2> player_names; } __packed__; parray names_entries; - struct ResultEntry { - le_uint16_t num_players; - le_uint16_t is_winner_team; - } __packed__; - parray result_entries; + le_uint16_t unused1 = 0; + // If round_num is equal to 6, the "On to the next battle..." text is replaced + // with "Congratulations!" and some flashier graphics. This is used for the + // final match. + le_uint16_t round_num = 0; + le_uint16_t num_players_per_team = 0; + le_uint16_t winner_team_id = 0; le_uint32_t meseta_amount = 0; // This field apparently is supposed to contain a %s token (as for printf) // that is replaced with meseta_amount. diff --git a/src/Episode3/Server.cc b/src/Episode3/Server.cc index 1f8ee99c..bc879699 100644 --- a/src/Episode3/Server.cc +++ b/src/Episode3/Server.cc @@ -145,6 +145,8 @@ shared_ptr Server::base() const { } int8_t Server::get_winner_team_id() const { + // Note: This function is not part of the original implementation. + parray team_player_counts(0); parray team_win_flag_counts(0); for (size_t client_id = 0; client_id < 4; client_id++) { diff --git a/src/Episode3/Tournament.cc b/src/Episode3/Tournament.cc index a1ab810b..271da5df 100644 --- a/src/Episode3/Tournament.cc +++ b/src/Episode3/Tournament.cc @@ -345,6 +345,10 @@ shared_ptr Tournament::next_match_for_team( return nullptr; } +shared_ptr Tournament::get_final_match() const { + return this->final_match; +} + void Tournament::start() { if (this->current_state != State::REGISTRATION) { throw runtime_error("tournament has already started"); diff --git a/src/Episode3/Tournament.hh b/src/Episode3/Tournament.hh index 91c6ee83..d7678d1e 100644 --- a/src/Episode3/Tournament.hh +++ b/src/Episode3/Tournament.hh @@ -104,6 +104,7 @@ public: std::shared_ptr get_team(size_t index) const; std::shared_ptr get_winner_team() const; std::shared_ptr next_match_for_team(std::shared_ptr team) const; + std::shared_ptr get_final_match() const; void start(); void print_bracket(FILE* stream) const; diff --git a/src/SendCommands.cc b/src/SendCommands.cc index baff325e..982cf8de 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2108,6 +2108,11 @@ void send_ep3_tournament_match_result( return; } + if ((match->winner_team != match->preceding_a->winner_team) && + (match->winner_team != match->preceding_b->winner_team)) { + throw logic_error("cannot send tournament result without valid winner team"); + } + unordered_map> serial_number_to_client; for (auto client : l->clients) { if (client) { @@ -2133,10 +2138,11 @@ void send_ep3_tournament_match_result( write_player_names(cmd.names_entries[0], match->preceding_a->winner_team); cmd.names_entries[1].team_name = match->preceding_b->winner_team->name; write_player_names(cmd.names_entries[1], match->preceding_b->winner_team); - cmd.result_entries[0].num_players = match->preceding_a->winner_team->max_players; - cmd.result_entries[0].is_winner_team = (match->preceding_a->winner_team == match->winner_team); - cmd.result_entries[1].num_players = match->preceding_a->winner_team->max_players; - cmd.result_entries[1].is_winner_team = (match->preceding_b->winner_team == match->winner_team); + // The value 6 here causes the client to show the "Congratulations" text + // instead of "On to the next round" + cmd.round_num = (match == tourn->get_final_match()) ? 6 : match->round_num; + cmd.num_players_per_team = match->preceding_a->winner_team->max_players; + cmd.winner_team_id = (match->preceding_b->winner_team == match->winner_team); // TODO: This amount should vary depending on the match level / round number, // but newserv doesn't currently implement meseta at all - we just always give // the player 1000000 and never charge for anything.