Author: jtn
Date: Fri Jun 27 21:09:29 2014
New Revision: 25290

URL: http://svn.gna.org/viewcvs/freeciv?rev=25290&view=rev
Log:
Prevent tech loss of tech which is root_req for some other known tech.

Reported by Matthias Pfafferodt (syntron@gna).

See gna bug #19176.

Modified:
    trunk/server/techtools.c

Modified: trunk/server/techtools.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/techtools.c?rev=25290&r1=25289&r2=25290&view=diff
==============================================================================
--- trunk/server/techtools.c    (original)
+++ trunk/server/techtools.c    Fri Jun 27 21:09:29 2014
@@ -641,16 +641,26 @@
 static Tech_type_id pick_random_tech_to_lose(struct player* plr)
 {
   bv_techs eligible_techs;
-  int chosen, eligible = 0;
-
-  BV_CLR_ALL(eligible_techs);
+  int chosen, eligible = advance_count();
+
+  BV_SET_ALL(eligible_techs);
 
   advance_index_iterate(A_FIRST, i) {
-    /* Never lose self root_req techs */
-    if (advance_required(i, AR_ROOT) != i
-        && player_invention_state(plr, i) == TECH_KNOWN) {
-      BV_SET(eligible_techs, i);
-      eligible++;
+    if (player_invention_state(plr, i) != TECH_KNOWN) {
+      if (BV_ISSET(eligible_techs, i)) {
+        eligible--;
+        BV_CLR(eligible_techs, i);
+      }
+    } else {
+      /* Never lose techs that are root_req for a currently known tech
+       * (including self root_req) */
+      Tech_type_id root = advance_required(i, AR_ROOT);
+      if (root != A_NONE) {
+        if (BV_ISSET(eligible_techs, root)) {
+          eligible--;
+          BV_CLR(eligible_techs, root);
+        }
+      }
     }
   } advance_index_iterate_end;
 
@@ -1294,8 +1304,20 @@
 bool tech_transfer(struct player *plr_recv, struct player *plr_donor,
                    Tech_type_id tech)
 {
-  if (fc_rand(100) < game.server.techlost_donor) {
-    forget_tech_transfered(plr_donor, tech);
+  if (game.server.techlost_donor > 0) {
+    /* Don't let donor lose tech if it's root_req for some other known
+     * tech */
+    bool donor_can_lose = TRUE;
+    advance_index_iterate(A_FIRST, i) {
+      if (player_invention_state(plr_donor, i) == TECH_KNOWN
+          && advance_required(i, AR_ROOT) == tech) {
+        donor_can_lose = FALSE;
+        break;
+      }
+    } advance_index_iterate_end;
+    if (donor_can_lose && fc_rand(100) < game.server.techlost_donor) {
+      forget_tech_transfered(plr_donor, tech);
+    }
   }
 
   if (fc_rand(100) < game.server.techlost_recv) {


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to