<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39564 >

 Crash was caused by ai_choose_role_unit() not updating choice.type.

 Actually ai_choose_role_unit() & its usage was buggy in other ways
too. It was not actually updating choice.want either, but callers were
expected to do that - some did not. need_boat was updated by some
callers from FALSE to TRUE, but none was updating it from TRUE to
FALSE (so when we first consider sending military unit to another
continent, and then decide to build University instead, that
University will need_boat).


 - ML

diff -Nurd -X.diff_ignore freeciv/ai/advdomestic.c freeciv/ai/advdomestic.c
--- freeciv/ai/advdomestic.c	2007-08-13 20:51:05.000000000 +0300
+++ freeciv/ai/advdomestic.c	2007-08-14 12:26:21.000000000 +0300
@@ -265,9 +265,8 @@
     if (settler_want > 0) {
       CITY_LOG(LOG_DEBUG, pcity, "desires terrain improvers with passion %d", 
                settler_want);
-      choice->want = settler_want;
-      choice->type = CT_CIVILIAN;
-      ai_choose_role_unit(pplayer, pcity, choice, F_SETTLERS, settler_want);
+      ai_choose_role_unit(pplayer, pcity, choice, CT_CIVILIAN,
+                          F_SETTLERS, settler_want, FALSE);
     }
     /* Terrain improvers don't use boats (yet) */
 
@@ -300,11 +299,10 @@
     if (founder_want > choice->want) {
       CITY_LOG(LOG_DEBUG, pcity, "desires founders with passion %d",
                founder_want);
-      choice->want = founder_want;
-      choice->need_boat = pcity->ai.founder_boat;
-      choice->type = CT_CIVILIAN;
-      ai_choose_role_unit(pplayer, pcity, choice, F_CITIES, founder_want);
-      
+      ai_choose_role_unit(pplayer, pcity, choice, CT_CIVILIAN,
+                          F_CITIES, founder_want,
+                          pcity->ai.founder_boat);
+
     } else if (founder_want < -choice->want) {
       /* We need boats to colonize! */
       /* We might need boats even if there are boats free,
@@ -314,11 +312,16 @@
       CITY_LOG(LOG_DEBUG, pcity, "desires founders with passion %d and asks"
 	       " for a new boat (%d of %d free)",
 	       -founder_want, ai->stats.available_boats, ai->stats.boats);
+
+      /* First fill choice with founder information */
       choice->want = 0 - founder_want;
       choice->type = CT_CIVILIAN;
       choice->value.utype = founder_type; /* default */
-      choice->need_boat = TRUE;
-      ai_choose_role_unit(pplayer, pcity, choice, L_FERRYBOAT, -founder_want);
+
+      /* Then try to overwrite it with ferryboat information
+       * If no ferryboat is found, above founder choice stays. */
+      ai_choose_role_unit(pplayer, pcity, choice, CT_CIVILIAN,
+                          L_FERRYBOAT, -founder_want, TRUE);
     }
   } else if (!founder_type
              && (founder_want > choice->want || founder_want < -choice->want)) {
diff -Nurd -X.diff_ignore freeciv/ai/advmilitary.c freeciv/ai/advmilitary.c
--- freeciv/ai/advmilitary.c	2007-08-13 20:51:05.000000000 +0300
+++ freeciv/ai/advmilitary.c	2007-08-14 12:26:53.000000000 +0300
@@ -1232,7 +1232,8 @@
       /* We might need a new boat even if there are boats free,
        * if they are blockaded or in inland seas*/
       assert(is_ground_unit(myunit));
-      ai_choose_role_unit(pplayer, pcity, choice, L_FERRYBOAT, choice->want);
+      ai_choose_role_unit(pplayer, pcity, choice, CT_ATTACKER,
+                          L_FERRYBOAT, choice->want, TRUE);
       if (SEA_MOVING == utype_move_type(choice->value.utype)) {
         struct ai_data *ai = ai_data_get(pplayer);
 
diff -Nurd -X.diff_ignore freeciv/ai/aitools.c freeciv/ai/aitools.c
--- freeciv/ai/aitools.c	2007-08-14 00:28:28.000000000 +0300
+++ freeciv/ai/aitools.c	2007-08-14 12:24:15.000000000 +0300
@@ -1174,14 +1174,23 @@
   Calls ai_wants_role_unit to choose the best unit with the given role and 
   set tech wants.  Sets choice->value.utype when we can build something.
 **************************************************************************/
-void ai_choose_role_unit(struct player *pplayer, struct city *pcity,
-			 struct ai_choice *choice, int role, int want)
+bool ai_choose_role_unit(struct player *pplayer, struct city *pcity,
+			 struct ai_choice *choice, enum choice_type type,
+                         int role, int want, bool need_boat)
 {
   struct unit_type *iunit = ai_wants_role_unit(pplayer, pcity, role, want);
 
   if (iunit != NULL) {
+    choice->type = type;
     choice->value.utype = iunit;
+    choice->want = want;
+
+    choice->need_boat = need_boat;
+
+    return TRUE;
   }
+
+  return FALSE;
 }
 
 /**************************************************************************
diff -Nurd -X.diff_ignore freeciv/ai/aitools.h freeciv/ai/aitools.h
--- freeciv/ai/aitools.h	2007-08-13 20:51:05.000000000 +0300
+++ freeciv/ai/aitools.h	2007-08-14 12:24:29.000000000 +0300
@@ -97,8 +97,9 @@
 void city_production_from_ai_choice(struct universal *product,
 				    struct ai_choice *choice);
 
-void ai_choose_role_unit(struct player *pplayer, struct city *pcity,
-                         struct ai_choice *choice, int role, int want);
+bool ai_choose_role_unit(struct player *pplayer, struct city *pcity,
+                         struct ai_choice *choice, enum choice_type type,
+                         int role, int want, bool need_boat);
 void ai_advisor_choose_building(struct city *pcity, struct ai_choice *choice);
 bool ai_assess_military_unhappiness(struct city *pcity);
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to