Author: pepeto Date: Wed Nov 5 21:43:26 2014 New Revision: 26971 URL: http://svn.gna.org/viewcvs/freeciv?rev=26971&view=rev Log: Revert partially patch #5357 because if was breaking the stop technology root requirement propagation.
Reported by Jacob Nevins <jtn> See gna bug #22876 Modified: branches/S2_5/common/tech.c branches/S2_5/server/ruleset.c Modified: branches/S2_5/common/tech.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/tech.c?rev=26971&r1=26970&r2=26971&view=diff ============================================================================== --- branches/S2_5/common/tech.c (original) +++ branches/S2_5/common/tech.c Wed Nov 5 21:43:26 2014 @@ -293,74 +293,55 @@ const Tech_type_id tech, bool allow_prereqs) { - bv_techs done; - Tech_type_id techs[game.control.num_tech_types]; - Tech_type_id t; - enum tech_req req; - int techs_num; - int i; - - if (!valid_advance_by_number(tech)) { + if (valid_advance_by_number(tech) == NULL) { return FALSE; - } - - techs[0] = tech; - BV_CLR_ALL(done); - BV_SET(done, A_NONE); - BV_SET(done, tech); - techs_num = 1; - - if (allow_prereqs) { + } else if (advance_required(tech, AR_ROOT) != A_NONE) { + /* 'tech' has at least one root requirement. We need to check them + * all. */ + bv_techs done; + Tech_type_id techs[game.control.num_tech_types]; + Tech_type_id root; + enum tech_req req; + int techs_num; + int i; + + techs[0] = tech; + BV_CLR_ALL(done); + BV_SET(done, A_NONE); + BV_SET(done, tech); + techs_num = 1; + for (i = 0; i < techs_num; i++) { - t = advance_required(techs[i], AR_ROOT); - if (t == techs[i]) { - /* This tech requires itself; it can only be reached by special means - * (init_techs, lua script, ...). + root = advance_required(techs[i], AR_ROOT); + if (root == techs[i]) { + /* This tech requires itself; it can only be reached by special + * means (init_techs, lua script, ...). * If you already know it, you can "reach" it; if not, not. (This * case is needed for descendants of this tech.) */ - if (TECH_KNOWN == player_invention_state(pplayer, t)) { - continue; - } else { + if (player_invention_state(pplayer, root) != TECH_KNOWN) { return FALSE; } - } - - /* Check if requirements are reachable. */ - for (req = 0; req < AR_SIZE; req++) { - t = advance_required(techs[i], req); - if (!valid_advance_by_number(t)) { - return FALSE; - } else if (!BV_ISSET(done, t)) { - if (TECH_KNOWN != player_invention_state(pplayer, t)) { - fc_assert(techs_num < ARRAY_SIZE(techs)); - techs[techs_num] = t; - techs_num++; - } - BV_SET(done, t); - } - } - } - } else { - for (i = 0; i < techs_num; i++) { - t = advance_required(techs[i], AR_ROOT); - if (TECH_KNOWN != player_invention_state(pplayer, t)) { + } else if (!allow_prereqs + && player_invention_state(pplayer, root) != TECH_KNOWN) { /* This tech requires knowledge of another tech (root tech) before * being available. Prevents sharing of untransferable techs. */ return FALSE; - } - - /* Check if requirements are reachable. */ - for (req = AR_ONE; req <= AR_TWO; req++) { - t = advance_required(techs[i], req); - if (!valid_advance_by_number(t)) { - return FALSE; - } else if (!BV_ISSET(done, t)) { - if (TECH_KNOWN != player_invention_state(pplayer, t)) { - fc_assert(techs_num < ARRAY_SIZE(techs)); - techs[techs_num] = t; - techs_num++; + } else { + /* Check if requirements are reachable. */ + Tech_type_id req_tech; + + for (req = 0; req < (allow_prereqs ? AR_SIZE : AR_ROOT); req++) { + req_tech = advance_required(techs[i], req); + if (!valid_advance_by_number(req_tech)) { + return FALSE; + } else if (!BV_ISSET(done, req_tech)) { + if (advance_required(req_tech, AR_ROOT) != A_NONE) { + fc_assert(techs_num < ARRAY_SIZE(techs)); + techs[techs_num] = req_tech; + techs_num++; + } + BV_SET(done, req_tech); } - BV_SET(done, t); } } } Modified: branches/S2_5/server/ruleset.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/server/ruleset.c?rev=26971&r1=26970&r2=26971&view=diff ============================================================================== --- branches/S2_5/server/ruleset.c (original) +++ branches/S2_5/server/ruleset.c Wed Nov 5 21:43:26 2014 @@ -1280,7 +1280,39 @@ i++; } advance_iterate_end; - if (ok) { + /* Propagate a root tech up into the tech tree. Thus if a technology + * X has Y has a root tech, then any technology requiring X also has + * Y as a root tech. */ +restart: + + if (ok) { + advance_iterate(A_FIRST, a) { + if (valid_advance(a) + && A_NEVER != a->require[AR_ROOT]) { + bool out_of_order = FALSE; + + /* Now find any tech depending on this technology and update its + * root_req. */ + advance_iterate(A_FIRST, b) { + if (valid_advance(b) + && A_NEVER == b->require[AR_ROOT] + && (a == b->require[AR_ONE] || a == b->require[AR_TWO])) { + b->require[AR_ROOT] = a->require[AR_ROOT]; + if (b < a) { + out_of_order = TRUE; + } + } + } advance_iterate_end; + + if (out_of_order) { + /* HACK: If we just changed the root_tech of a lower-numbered + * technology, we need to go back so that we can propagate the + * root_tech up to that technology's parents... */ + goto restart; + } + } + } advance_iterate_end; + /* Now rename A_NEVER to A_NONE for consistency */ advance_iterate(A_NONE, a) { if (A_NEVER == a->require[AR_ROOT]) { _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits