From 705ad54daf42c05ed57a5ec88ed196beb4530356 Mon Sep 17 00:00:00 2001 From: Louis Moureaux Date: Tue, 27 Dec 2022 02:02:40 +0100 Subject: [PATCH] Take team_pooled_research into account when looping over research The number of valid research objects is the number of teams when team_pooled_research is enabled, and the number of players when it is disabled. The code was always assuming the first case, which created bugs in team games without pooled research. Fixes 22c0c4b47ed3ed239358933af15818c7b4873c49. --- common/research.cpp | 16 ++++++++++++++-- common/research.h | 1 + server/sanitycheck.cpp | 2 +- server/savegame/savegame2.cpp | 6 +++--- server/savegame/savegame3.cpp | 8 ++++---- server/srv_main.cpp | 6 +++--- server/techtools.cpp | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/common/research.cpp b/common/research.cpp index 966a6145fc..2715c33ab3 100644 --- a/common/research.cpp +++ b/common/research.cpp @@ -119,6 +119,18 @@ struct research *research_get(const struct player *pplayer) } } +/** + * Checks whether the research object is valid in the current game. + */ +bool research_is_valid(const struct research &presearch) +{ + if (game.info.team_pooled_research) { + return research_is_valid(presearch); + } else { + return player_by_number(research_number(&presearch)) != nullptr; + } +} + /** Returns the name of the research owner: a player name or a team name. */ @@ -653,7 +665,7 @@ bool research_invention_reachable(const struct research *presearch, return presearch->inventions[tech].reachable; } else { for (const auto &research_iter : research_array) { - if (team_by_number(research_number(&research_iter)) != nullptr) { + if (research_is_valid(research_iter)) { if (research_iter.inventions[tech].reachable) { return true; } @@ -682,7 +694,7 @@ bool research_invention_gettable(const struct research *presearch, : presearch->inventions[tech].state == TECH_PREREQS_KNOWN); } else { for (const auto &research_iter : research_array) { - if (team_by_number(research_number(&research_iter)) != nullptr) { + if (research_is_valid(research_iter)) { if (allow_holes ? research_iter.inventions[tech].root_reqs_known : research_iter.inventions[tech].state == TECH_PREREQS_KNOWN) { diff --git a/common/research.h b/common/research.h index 375d7e0dbc..c2ede43ef6 100644 --- a/common/research.h +++ b/common/research.h @@ -107,6 +107,7 @@ int research_pretty_name(const struct research *presearch, char *buf, struct research *research_by_number(int number); struct research *research_get(const struct player *pplayer); +bool research_is_valid(const struct research &presearch); QString research_advance_rule_name(const struct research *presearch, Tech_type_id tech); diff --git a/server/sanitycheck.cpp b/server/sanitycheck.cpp index 4ca2b75213..40dde8b827 100644 --- a/server/sanitycheck.cpp +++ b/server/sanitycheck.cpp @@ -673,7 +673,7 @@ static void check_researches(const char *file, const char *function, int line) { for (const auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { SANITY_CHECK(S_S_RUNNING != server_state() || A_UNSET == presearch.researching || is_future_tech(presearch.researching) diff --git a/server/savegame/savegame2.cpp b/server/savegame/savegame2.cpp index ccc3094d35..51afa8a82d 100644 --- a/server/savegame/savegame2.cpp +++ b/server/savegame/savegame2.cpp @@ -4782,7 +4782,7 @@ static void sg_load_researches(struct loaddata *loading) // Initialize all researches. for (auto &pinitres : research_array) { - if (team_by_number(research_number(&pinitres)) != nullptr) { + if (research_is_valid(pinitres)) { init_tech(&pinitres, false); } }; @@ -4849,7 +4849,7 @@ static void sg_load_researches(struct loaddata *loading) /* In case of tech_leakage, we can update research only after all the * researches have been loaded */ for (auto &pupres : research_array) { - if (team_by_number(research_number(&pupres)) != nullptr) { + if (research_is_valid(pupres)) { research_update(&pupres); } }; @@ -5125,7 +5125,7 @@ static void sg_load_sanitycheck(struct loaddata *loading) // Check researching technologies and goals. for (auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { if (presearch.researching != A_UNSET && !is_future_tech(presearch.researching) && (valid_advance_by_number(presearch.researching) == nullptr diff --git a/server/savegame/savegame3.cpp b/server/savegame/savegame3.cpp index dbc66d7cef..c5a3f6bfb6 100644 --- a/server/savegame/savegame3.cpp +++ b/server/savegame/savegame3.cpp @@ -7045,7 +7045,7 @@ static void sg_load_researches(struct loaddata *loading) // Initialize all researches. for (auto &pinitres : research_array) { - if (team_by_number(research_number(&pinitres)) != nullptr) { + if (research_is_valid(pinitres)) { init_tech(&pinitres, false); } }; @@ -7125,7 +7125,7 @@ static void sg_load_researches(struct loaddata *loading) /* In case of tech_leakage, we can update research only after all the * researches have been loaded */ for (auto &pupres : research_array) { - if (team_by_number(research_number(&pupres)) != nullptr) { + if (research_is_valid(pupres)) { research_update(&pupres); } }; @@ -7146,7 +7146,7 @@ static void sg_save_researches(struct savedata *saving) if (saving->save_players) { for (const auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { secfile_insert_int(saving->file, research_number(&presearch), "research.r%d.number", i); technology_save(saving->file, "research.r%d.goal", i, @@ -7559,7 +7559,7 @@ static void sg_load_sanitycheck(struct loaddata *loading) // Check researching technologies and goals. for (auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { if (presearch.researching != A_UNSET && !is_future_tech(presearch.researching) && (valid_advance_by_number(presearch.researching) == nullptr diff --git a/server/srv_main.cpp b/server/srv_main.cpp index 408d1f6d30..ecbe84820d 100644 --- a/server/srv_main.cpp +++ b/server/srv_main.cpp @@ -619,7 +619,7 @@ void send_all_info(struct conn_list *dest) // Resend player info because it could have more infos (e.g. embassy). send_player_all_c(nullptr, dest); for (const auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { send_research_info(&presearch, dest); } }; @@ -1752,7 +1752,7 @@ void end_turn() log_debug("Sendresearchinfo"); for (const auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { send_research_info(&presearch, nullptr); } }; @@ -3048,7 +3048,7 @@ void srv_ready() /* Give initial technologies, as specified in the ruleset and the * settings. */ for (auto &presearch : research_array) { - if (team_by_number(research_number(&presearch)) != nullptr) { + if (research_is_valid(presearch)) { init_tech(&presearch, true); give_initial_techs(&presearch, game.info.tech); } diff --git a/server/techtools.cpp b/server/techtools.cpp index 3a3d4d5141..bd2b686aae 100644 --- a/server/techtools.cpp +++ b/server/techtools.cpp @@ -170,7 +170,7 @@ void do_tech_parasite_effect(struct player *pplayer) num_teams = 0; for (const auto &other_research : research_array) { - if (team_by_number(research_number(&other_research)) != nullptr) { + if (research_is_valid(other_research)) { if (TECH_KNOWN == research_invention_state(&other_research, i)) { if (mod <= ++num_teams) { if (0 == fc_rand(++num_techs)) {