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

Reply via email to