diff --git a/client/diplodlg.cpp b/client/diplodlg.cpp index fe01a8b70b..3bf4eec97c 100644 --- a/client/diplodlg.cpp +++ b/client/diplodlg.cpp @@ -39,9 +39,6 @@ #include "sprite.h" #include "top_bar.h" -typedef advance *p_advance; -typedef city *p_city; - /** Constructor for diplomacy widget */ diff --git a/client/goto.cpp b/client/goto.cpp index 2006025ea1..26291790b3 100644 --- a/client/goto.cpp +++ b/client/goto.cpp @@ -296,45 +296,6 @@ void goto_unit_killed(struct unit *punit) */ bool goto_is_active() { return !goto_finders.empty(); } -/** - Return the path length (in turns). - WARNING: not useful for determining paths of scattered groups. - */ -bool goto_get_turns(int *min, int *max) -{ - fc_assert_ret_val(min != nullptr, false); - fc_assert_ret_val(max != nullptr, false); - - *min = FC_INFINITY; - *max = -1; - - if (!goto_is_active()) { - return false; - } - if (nullptr == goto_destination) { - // Not a valid position. - return false; - } - - if (hover_state == HOVER_CONNECT) { - // FIXME unsupported - } else { - // In other modes, we want to know the turn number to reach the tile. - for (auto &[unit_id, finder] : goto_finders) { - auto destination = hover_state == HOVER_PATROL - ? game_unit_by_number(unit_id)->tile - : goto_destination; - auto path = finder.find_path(freeciv::tile_destination(destination)); - if (path) { - *min = std::max(*min, path->turns()); - *max = std::max(*max, path->turns()); - } - } - } - - return true; -} - /** Returns the state of 'ptile': turn number to print, and whether 'ptile' is a waypoint. diff --git a/client/goto.h b/client/goto.h index 3e27ba32ed..ab89a416fd 100644 --- a/client/goto.h +++ b/client/goto.h @@ -35,7 +35,6 @@ void exit_goto_state(); void goto_unit_killed(struct unit *punit); bool goto_is_active(); -bool goto_get_turns(int *min, int *max); bool goto_tile_state(const struct tile *ptile, enum goto_tile_state *state, int *turns, bool *waypoint); bool goto_add_waypoint(); @@ -45,8 +44,6 @@ bool is_valid_goto_destination(const struct tile *ptile); bool is_valid_goto_draw_line(struct tile *dest_tile); void request_orders_cleared(struct unit *punit); -void send_goto_path(struct unit *punit, PFPath *path, - struct unit_order *last_order); void send_rally_path(city *pcity, unit *punit, const PFPath &path, unit_order *final_order); bool send_goto_tile(struct unit *punit, struct tile *ptile); diff --git a/client/gui_main.cpp b/client/gui_main.cpp index 5a14a372a5..3c622eb285 100644 --- a/client/gui_main.cpp +++ b/client/gui_main.cpp @@ -46,7 +46,6 @@ const char *const gui_character_encoding = "UTF-8"; const char *client_string = "gui-qt"; static fc_client *freeciv_qt; -void reset_unit_table(); static void apply_help_font(struct option *poption); static void apply_notify_font(struct option *poption); static void apply_titlebar(struct option *poption); @@ -356,13 +355,6 @@ void gui_update_allfonts() gui_options.gui_qt_increase_fonts = 0; } -/** - Called when the tileset is changed to reset the unit pixmap table. - */ -void reset_unit_table() -{ // FIXME -} - /** Open dialog to confirm that user wants to quit client. */ diff --git a/common/metaknowledge.cpp b/common/metaknowledge.cpp index e72850f21c..4338c2f2f2 100644 --- a/common/metaknowledge.cpp +++ b/common/metaknowledge.cpp @@ -159,14 +159,9 @@ static bool can_plr_see_all_sym_diplrels_of(const struct player *pplayer, static bool is_req_knowable( const struct player *pow_player, const struct player *target_player, const struct player *other_player, const struct city *target_city, - const struct impr_type *target_building, const struct tile *target_tile, - const struct unit *target_unit, const struct output_type *target_output, - const struct specialist *target_specialist, + const struct tile *target_tile, const struct unit *target_unit, const struct requirement *req, const enum req_problem_type prob_type) { - Q_UNUSED(target_output) - Q_UNUSED(target_specialist) - Q_UNUSED(target_building) fc_assert_ret_val_msg(nullptr != pow_player, false, "No point of view"); if (req->source.kind == VUT_UTFLAG || req->source.kind == VUT_UTYPE @@ -181,7 +176,7 @@ static bool is_req_knowable( return prob_type == RPT_CERTAIN; } - return target_unit && can_player_see_unit(pow_player, target_unit); + return can_player_see_unit(pow_player, target_unit); case REQ_RANGE_CADJACENT: case REQ_RANGE_ADJACENT: case REQ_RANGE_CONTINENT: @@ -214,11 +209,11 @@ static bool is_req_knowable( case USP_NATIVE_TILE: case USP_NATIVE_EXTRA: // Known if the unit is seen by the player. - return target_unit && can_player_see_unit(pow_player, target_unit); + return can_player_see_unit(pow_player, target_unit); case USP_HAS_HOME_CITY: case USP_MOVED_THIS_TURN: // Known to the unit's owner. - return target_unit && unit_owner(target_unit) == pow_player; + return unit_owner(target_unit) == pow_player; case USP_COUNT: fc_assert_msg(req->source.value.unit_state != USP_COUNT, "Invalid unit state property."); @@ -286,7 +281,7 @@ static bool is_req_knowable( return prob_type == RPT_CERTAIN; } - if (pow_player == target_player || pow_player == other_player) { + if (pow_player == other_player) { return true; } @@ -642,8 +637,7 @@ enum fc_tristate mke_eval_req( const struct unit_type *target_unittype; if (!is_req_knowable(pow_player, target_player, other_player, target_city, - target_building, target_tile, target_unit, - target_output, target_specialist, req, prob_type)) { + target_tile, target_unit, req, prob_type)) { return TRI_MAYBE; } diff --git a/common/research.cpp b/common/research.cpp index 3e5019b17a..95ae823551 100644 --- a/common/research.cpp +++ b/common/research.cpp @@ -25,12 +25,8 @@ _ ._ Copyright (c) 1996-2021 Freeciv21 and Freeciv contributors. #include "tech.h" #include "research.h" - -struct research_iter { - struct iterator vtable; - int index; -}; -#define RESEARCH_ITER(p) ((struct research_iter *) p) +// FIXME: Dont use extern, move inside some game running class eventually +extern std::vector research_array(MAX_NUM_PLAYER_SLOTS); struct research_player_iter { struct iterator vtable; @@ -41,8 +37,6 @@ struct research_player_iter { }; #define RESEARCH_PLAYER_ITER(p) ((struct research_player_iter *) p) -static struct research research_array[MAX_NUM_PLAYER_SLOTS]; - static struct name_translation advance_unset_name = NAME_INIT; static struct name_translation advance_future_name = NAME_INIT; static struct name_translation advance_unknown_name = NAME_INIT; @@ -55,22 +49,19 @@ Q_GLOBAL_STATIC(QVector, future_name_translation); */ void researches_init() { - int i; - // Ensure we have enough space for players or teams. - fc_assert(ARRAY_SIZE(research_array) >= team_slot_count()); - fc_assert(ARRAY_SIZE(research_array) >= MAX_NUM_PLAYER_SLOTS); - - memset(research_array, 0, sizeof(research_array)); - for (i = 0; i < ARRAY_SIZE(research_array); i++) { - research_array[i].tech_goal = A_UNSET; - research_array[i].researching = A_UNSET; - research_array[i].researching_saved = A_UNKNOWN; - research_array[i].future_tech = 0; - research_array[i].inventions[A_NONE].state = TECH_KNOWN; + fc_assert(research_array.size() >= team_slot_count()); + fc_assert(research_array.size() >= MAX_NUM_PLAYER_SLOTS); + + for (auto &research : research_array) { + research.tech_goal = A_UNSET; + research.researching = A_UNSET; + research.researching_saved = A_UNKNOWN; + research.future_tech = 0; + research.inventions[A_NONE].state = TECH_KNOWN; advance_index_iterate(A_FIRST, j) { - research_array[i].inventions[j].bulbs_researched_saved = 0; + research.inventions[j].bulbs_researched_saved = 0; } advance_index_iterate_end; } @@ -97,10 +88,10 @@ void researches_free() /** Returns the index of the research in the array. */ -int research_number(const struct research *presearch) +int research_number(const research *presearch) { fc_assert_ret_val(nullptr != presearch, 0); - return presearch - research_array; + return presearch - &research_array[0]; } /** @@ -109,7 +100,7 @@ int research_number(const struct research *presearch) struct research *research_by_number(int number) { fc_assert_ret_val(0 <= number, nullptr); - fc_assert_ret_val(ARRAY_SIZE(research_array) > number, nullptr); + fc_assert_ret_val(research_array.size() > number, nullptr); return &research_array[number]; } @@ -362,24 +353,6 @@ static bool research_allowed( return false; } -/** - Returns TRUE iff researching the given tech is allowed according to its - research_reqs. - - Helper for research_update(). - */ -#define research_is_allowed(presearch, tech) \ - research_allowed(presearch, tech, are_reqs_active) - -/** - Returns TRUE iff researching the given tech may become allowed according - to its research_reqs. - - Helper for research_get_reachable_rreqs(). - */ -#define research_may_become_allowed(presearch, tech) \ - research_allowed(presearch, tech, reqs_may_activate) - /** Returns TRUE iff the given tech is ever reachable by the players sharing the research as far as research_reqs are concerned. @@ -405,7 +378,7 @@ static bool research_get_reachable_rreqs(const struct research *presearch, continue; } - if (!research_may_become_allowed(presearch, iter_tech)) { + if (!research_allowed(presearch, iter_tech, reqs_may_activate)) { /* It will always be illegal to start researching this tech because * of unchanging requirements. Since it isn't already known and can't * be researched it must be unreachable. */ @@ -522,7 +495,7 @@ void research_update(struct research *presearch) && (presearch->inventions[advance_required(i, AR_TWO)] .state == TECH_KNOWN) - && research_is_allowed(presearch, i) + && research_allowed(presearch, i, are_reqs_active) ? TECH_PREREQS_KNOWN : TECH_UNKNOWN); } @@ -676,13 +649,13 @@ bool research_invention_reachable(const struct research *presearch, } else if (presearch != nullptr) { return presearch->inventions[tech].reachable; } else { - researches_iterate(research_iter) - { - if (research_iter->inventions[tech].reachable) { - return true; + for (const auto &research_iter : research_array) { + if (team_by_number(research_number(&research_iter)) != nullptr) { + if (research_iter.inventions[tech].reachable) { + return true; + } } - } - researches_iterate_end; + }; return false; } @@ -705,15 +678,15 @@ bool research_invention_gettable(const struct research *presearch, ? presearch->inventions[tech].root_reqs_known : presearch->inventions[tech].state == TECH_PREREQS_KNOWN); } else { - researches_iterate(research_iter) - { - if (allow_holes ? research_iter->inventions[tech].root_reqs_known - : research_iter->inventions[tech].state - == TECH_PREREQS_KNOWN) { - return true; + for (const auto &research_iter : research_array) { + if (team_by_number(research_number(&research_iter)) != nullptr) { + if (allow_holes ? research_iter.inventions[tech].root_reqs_known + : research_iter.inventions[tech].state + == TECH_PREREQS_KNOWN) { + return true; + } } - } - researches_iterate_end; + }; return false; } @@ -1133,91 +1106,6 @@ int player_tech_upkeep(const struct player *pplayer) return static_cast(tech_upkeep); } -/** - Returns the real size of the player research iterator. - */ -size_t research_iter_sizeof() { return sizeof(struct research_iter); } - -/** - Returns the research structure pointed by the iterator. - */ -static void *research_iter_get(const struct iterator *it) -{ - return &research_array[RESEARCH_ITER(it)->index]; -} - -/** - Jump to next team research structure. - */ -static void research_iter_team_next(struct iterator *it) -{ - struct research_iter *rit = RESEARCH_ITER(it); - - if (team_slots_initialised()) { - do { - rit->index++; - } while (rit->index < ARRAY_SIZE(research_array) && !it->valid(it)); - } -} - -/** - Returns FALSE if there is no valid team at current index. - */ -static bool research_iter_team_valid(const struct iterator *it) -{ - struct research_iter *rit = RESEARCH_ITER(it); - - return (0 <= rit->index && ARRAY_SIZE(research_array) > rit->index - && nullptr != team_by_number(rit->index)); -} - -/** - Jump to next player research structure. - */ -static void research_iter_player_next(struct iterator *it) -{ - struct research_iter *rit = RESEARCH_ITER(it); - - if (player_slots_initialised()) { - do { - rit->index++; - } while (rit->index < ARRAY_SIZE(research_array) && !it->valid(it)); - } -} - -/** - Returns FALSE if there is no valid player at current index. - */ -static bool research_iter_player_valid(const struct iterator *it) -{ - struct research_iter *rit = RESEARCH_ITER(it); - - return (0 <= rit->index && ARRAY_SIZE(research_array) > rit->index - && nullptr != player_by_number(rit->index)); -} - -/** - Initializes a player research iterator. - */ -struct iterator *research_iter_init(struct research_iter *it) -{ - struct iterator *base = ITERATOR(it); - - base->get = research_iter_get; - it->index = -1; - - if (game.info.team_pooled_research) { - base->next = research_iter_team_next; - base->valid = research_iter_team_valid; - } else { - base->next = research_iter_player_next; - base->valid = research_iter_player_valid; - } - - base->next(base); - return base; -} - /** Returns the real size of the research player iterator. */ diff --git a/common/research.h b/common/research.h index 77e98dae69..375d7e0dbc 100644 --- a/common/research.h +++ b/common/research.h @@ -94,6 +94,7 @@ struct research { }; }; +extern std::vector research_array; // Common functions. void researches_init(); void researches_free(); @@ -140,16 +141,6 @@ int research_total_bulbs_required(const struct research *presearch, int player_tech_upkeep(const struct player *pplayer); // Iterating utilities. -struct research_iter; - -size_t research_iter_sizeof(); -struct iterator *research_iter_init(struct research_iter *it); - -#define researches_iterate(_presearch) \ - generic_iterate(struct research_iter, struct research *, _presearch, \ - research_iter_sizeof, research_iter_init) -#define researches_iterate_end generic_iterate_end - struct research_player_iter; size_t research_player_iter_sizeof(); diff --git a/server/sanitycheck.cpp b/server/sanitycheck.cpp index e69550c7db..e85e7e3e82 100644 --- a/server/sanitycheck.cpp +++ b/server/sanitycheck.cpp @@ -674,18 +674,18 @@ static void check_teams(const char *file, const char *function, int line) static void check_researches(const char *file, const char *function, int line) { - researches_iterate(presearch) - { - SANITY_CHECK(S_S_RUNNING != server_state() - || A_UNSET == presearch->researching - || is_future_tech(presearch->researching) - || (A_NONE != presearch->researching - && valid_advance_by_number(presearch->researching))); - SANITY_CHECK(A_UNSET == presearch->tech_goal - || (A_NONE != presearch->tech_goal - && valid_advance_by_number(presearch->tech_goal))); - } - researches_iterate_end; + for (const auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + SANITY_CHECK(S_S_RUNNING != server_state() + || A_UNSET == presearch.researching + || is_future_tech(presearch.researching) + || (A_NONE != presearch.researching + && valid_advance_by_number(presearch.researching))); + SANITY_CHECK(A_UNSET == presearch.tech_goal + || (A_NONE != presearch.tech_goal + && valid_advance_by_number(presearch.tech_goal))); + } + }; } /** diff --git a/server/savegame/savegame2.cpp b/server/savegame/savegame2.cpp index 49a41f8de2..6c62fb858c 100644 --- a/server/savegame/savegame2.cpp +++ b/server/savegame/savegame2.cpp @@ -4787,8 +4787,11 @@ static void sg_load_researches(struct loaddata *loading) sg_check_ret(); // Initialize all researches. - researches_iterate(pinitres) { init_tech(pinitres, false); } - researches_iterate_end; + for (auto &pinitres : research_array) { + if (team_by_number(research_number(&pinitres)) != nullptr) { + init_tech(&pinitres, false); + } + }; // May be unsaved (e.g. scenario case). count = secfile_lookup_int_default(loading->file, 0, "research.count"); @@ -4851,8 +4854,11 @@ 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 */ - researches_iterate(pupres) { research_update(pupres); } - researches_iterate_end; + for (auto &pupres : research_array) { + if (team_by_number(research_number(&pupres)) != nullptr) { + research_update(&pupres); + } + }; } /* ======================================================================= @@ -5124,29 +5130,30 @@ static void sg_load_sanitycheck(struct loaddata *loading) #endif // FREECIV_DEBUG // Check researching technologies and goals. - researches_iterate(presearch) - { - if (presearch->researching != A_UNSET - && !is_future_tech(presearch->researching) - && (valid_advance_by_number(presearch->researching) == nullptr - || (research_invention_state(presearch, presearch->researching) - != TECH_PREREQS_KNOWN))) { - log_sg(_("%s had invalid researching technology."), - research_name_translation(presearch)); - presearch->researching = A_UNSET; - } - if (presearch->tech_goal != A_UNSET - && !is_future_tech(presearch->tech_goal) - && (valid_advance_by_number(presearch->tech_goal) == nullptr - || !research_invention_reachable(presearch, presearch->tech_goal) - || (research_invention_state(presearch, presearch->tech_goal) - == TECH_KNOWN))) { - log_sg(_("%s had invalid technology goal."), - research_name_translation(presearch)); - presearch->tech_goal = A_UNSET; - } - } - researches_iterate_end; + for (auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + if (presearch.researching != A_UNSET + && !is_future_tech(presearch.researching) + && (valid_advance_by_number(presearch.researching) == nullptr + || (research_invention_state(&presearch, presearch.researching) + != TECH_PREREQS_KNOWN))) { + log_sg(_("%s had invalid researching technology."), + research_name_translation(&presearch)); + presearch.researching = A_UNSET; + } + if (presearch.tech_goal != A_UNSET + && !is_future_tech(presearch.tech_goal) + && (valid_advance_by_number(presearch.tech_goal) == nullptr + || !research_invention_reachable(&presearch, + presearch.tech_goal) + || (research_invention_state(&presearch, presearch.tech_goal) + == TECH_KNOWN))) { + log_sg(_("%s had invalid technology goal."), + research_name_translation(&presearch)); + presearch.tech_goal = A_UNSET; + } + } + }; players_iterate(pplayer) { diff --git a/server/savegame/savegame3.cpp b/server/savegame/savegame3.cpp index 906f5661de..04042a626d 100644 --- a/server/savegame/savegame3.cpp +++ b/server/savegame/savegame3.cpp @@ -7051,8 +7051,11 @@ static void sg_load_researches(struct loaddata *loading) sg_check_ret(); // Initialize all researches. - researches_iterate(pinitres) { init_tech(pinitres, false); } - researches_iterate_end; + for (auto &pinitres : research_array) { + if (team_by_number(research_number(&pinitres)) != nullptr) { + init_tech(&pinitres, false); + } + }; // May be unsaved (e.g. scenario case). count = secfile_lookup_int_default(loading->file, 0, "research.count"); @@ -7128,8 +7131,11 @@ 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 */ - researches_iterate(pupres) { research_update(pupres); } - researches_iterate_end; + for (auto &pupres : research_array) { + if (team_by_number(research_number(&pupres)) != nullptr) { + research_update(&pupres); + } + }; } /** @@ -7146,55 +7152,55 @@ static void sg_save_researches(struct savedata *saving) sg_check_ret(); if (saving->save_players) { - researches_iterate(presearch) - { - secfile_insert_int(saving->file, research_number(presearch), - "research.r%d.number", i); - technology_save(saving->file, "research.r%d.goal", i, - presearch->tech_goal); - secfile_insert_int(saving->file, presearch->techs_researched, - "research.r%d.techs", i); - secfile_insert_int(saving->file, presearch->future_tech, - "research.r%d.futuretech", i); - secfile_insert_int(saving->file, presearch->bulbs_researching_saved, - "research.r%d.bulbs_before", i); - if (game.server.multiresearch) { - vlist_research = new int[game.control.num_tech_types](); - advance_index_iterate(A_FIRST, j) + for (const auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + secfile_insert_int(saving->file, research_number(&presearch), + "research.r%d.number", i); + technology_save(saving->file, "research.r%d.goal", i, + presearch.tech_goal); + secfile_insert_int(saving->file, presearch.techs_researched, + "research.r%d.techs", i); + secfile_insert_int(saving->file, presearch.future_tech, + "research.r%d.futuretech", i); + secfile_insert_int(saving->file, presearch.bulbs_researching_saved, + "research.r%d.bulbs_before", i); + if (game.server.multiresearch) { + vlist_research = new int[game.control.num_tech_types](); + advance_index_iterate(A_FIRST, j) + { + vlist_research[j] = + presearch.inventions[j].bulbs_researched_saved; + } + advance_index_iterate_end; + secfile_insert_int_vec(saving->file, vlist_research, + game.control.num_tech_types, + "research.r%d.vbs", i); + delete[] vlist_research; + vlist_research = nullptr; + } + technology_save(saving->file, "research.r%d.saved", i, + presearch.researching_saved); + secfile_insert_int(saving->file, presearch.bulbs_researched, + "research.r%d.bulbs", i); + technology_save(saving->file, "research.r%d.now", i, + presearch.researching); + secfile_insert_bool(saving->file, presearch.got_tech, + "research.r%d.got_tech", i); + /* Save technology lists as bytevector. Note that technology order is + * saved in savefile.technology.order */ + advance_index_iterate(A_NONE, tech_id) { - vlist_research[j] = - presearch->inventions[j].bulbs_researched_saved; + invs[tech_id] = + (research_invention_state(&presearch, tech_id) == TECH_KNOWN + ? '1' + : '0'); } advance_index_iterate_end; - secfile_insert_int_vec(saving->file, vlist_research, - game.control.num_tech_types, - "research.r%d.vbs", i); - delete[] vlist_research; - vlist_research = nullptr; - } - technology_save(saving->file, "research.r%d.saved", i, - presearch->researching_saved); - secfile_insert_int(saving->file, presearch->bulbs_researched, - "research.r%d.bulbs", i); - technology_save(saving->file, "research.r%d.now", i, - presearch->researching); - secfile_insert_bool(saving->file, presearch->got_tech, - "research.r%d.got_tech", i); - /* Save technology lists as bytevector. Note that technology order is - * saved in savefile.technology.order */ - advance_index_iterate(A_NONE, tech_id) - { - invs[tech_id] = - (research_invention_state(presearch, tech_id) == TECH_KNOWN - ? '1' - : '0'); + invs[game.control.num_tech_types] = '\0'; + secfile_insert_str(saving->file, invs, "research.r%d.done", i); + i++; } - advance_index_iterate_end; - invs[game.control.num_tech_types] = '\0'; - secfile_insert_str(saving->file, invs, "research.r%d.done", i); - i++; - } - researches_iterate_end; + }; secfile_insert_int(saving->file, i, "research.count"); } } @@ -7559,29 +7565,30 @@ static void sg_load_sanitycheck(struct loaddata *loading) #endif // FREECIV_DEBUG // Check researching technologies and goals. - researches_iterate(presearch) - { - if (presearch->researching != A_UNSET - && !is_future_tech(presearch->researching) - && (valid_advance_by_number(presearch->researching) == nullptr - || (research_invention_state(presearch, presearch->researching) - != TECH_PREREQS_KNOWN))) { - log_sg(_("%s had invalid researching technology."), - research_name_translation(presearch)); - presearch->researching = A_UNSET; - } - if (presearch->tech_goal != A_UNSET - && !is_future_tech(presearch->tech_goal) - && (valid_advance_by_number(presearch->tech_goal) == nullptr - || !research_invention_reachable(presearch, presearch->tech_goal) - || (research_invention_state(presearch, presearch->tech_goal) - == TECH_KNOWN))) { - log_sg(_("%s had invalid technology goal."), - research_name_translation(presearch)); - presearch->tech_goal = A_UNSET; - } - } - researches_iterate_end; + for (auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + if (presearch.researching != A_UNSET + && !is_future_tech(presearch.researching) + && (valid_advance_by_number(presearch.researching) == nullptr + || (research_invention_state(&presearch, presearch.researching) + != TECH_PREREQS_KNOWN))) { + log_sg(_("%s had invalid researching technology."), + research_name_translation(&presearch)); + presearch.researching = A_UNSET; + } + if (presearch.tech_goal != A_UNSET + && !is_future_tech(presearch.tech_goal) + && (valid_advance_by_number(presearch.tech_goal) == nullptr + || !research_invention_reachable(&presearch, + presearch.tech_goal) + || (research_invention_state(&presearch, presearch.tech_goal) + == TECH_KNOWN))) { + log_sg(_("%s had invalid technology goal."), + research_name_translation(&presearch)); + presearch.tech_goal = A_UNSET; + } + } + }; // Check if some player has more than one of some UTYF_UNIQUE unit type players_iterate(pplayer) diff --git a/server/srv_main.cpp b/server/srv_main.cpp index a9461b682a..1b7811f5d4 100644 --- a/server/srv_main.cpp +++ b/server/srv_main.cpp @@ -617,8 +617,11 @@ 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); - researches_iterate(presearch) { send_research_info(presearch, dest); } - researches_iterate_end; + for (const auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + send_research_info(&presearch, dest); + } + }; send_map_info(dest); send_all_known_tiles(dest); send_all_known_cities(dest); @@ -1724,8 +1727,11 @@ void end_turn() send_player_all_c(nullptr, nullptr); log_debug("Sendresearchinfo"); - researches_iterate(presearch) { send_research_info(presearch, nullptr); } - researches_iterate_end; + for (const auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + send_research_info(&presearch, nullptr); + } + }; log_debug("Sendyeartoclients"); send_year_to_clients(); @@ -3017,12 +3023,12 @@ void srv_ready() /* Give initial technologies, as specified in the ruleset and the * settings. */ - researches_iterate(presearch) - { - init_tech(presearch, true); - give_initial_techs(presearch, game.info.tech); - } - researches_iterate_end; + for (auto &presearch : research_array) { + if (team_by_number(research_number(&presearch)) != nullptr) { + init_tech(&presearch, true); + give_initial_techs(&presearch, game.info.tech); + } + }; // Set up alliances based on team selections players_iterate(pplayer) diff --git a/server/techtools.cpp b/server/techtools.cpp index a660decb0e..4d56c08544 100644 --- a/server/techtools.cpp +++ b/server/techtools.cpp @@ -169,18 +169,18 @@ void do_tech_parasite_effect(struct player *pplayer) } num_teams = 0; - researches_iterate(other_research) - { - if (TECH_KNOWN == research_invention_state(other_research, i)) { - if (mod <= ++num_teams) { - if (0 == fc_rand(++num_techs)) { - tech = i; + for (const auto &other_research : research_array) { + if (team_by_number(research_number(&other_research)) != nullptr) { + if (TECH_KNOWN == research_invention_state(&other_research, i)) { + if (mod <= ++num_teams) { + if (0 == fc_rand(++num_techs)) { + tech = i; + } + break; } - break; } } - } - researches_iterate_end; + }; } advance_index_iterate_end;