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

On 22/08/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
>
> 1: Bad move_type in init_warmap().
> 0: Detected fatal error in ../../src.test/server/gotohand.c line 807:
> 0: Bad move_type in find_the_shortest_path().

 This was caused by dead autosettler (memory reused) still in city
founding mission.

 It had displaced another settler for city founding. When this
displaced settler tried to find something else to do, it somehow
caused death of this settler.
 Attached patch checks that settler is still alive after
auto_settler_findwork() for displaced settler. It also changes auto
settler iteration to use unit_list_iterate_safe, as autosettlers can
die or disappear for many reasons.
 S2_0 has no settler displacing mechanism.


 - ML

Binary files freeciv/data/freeciv-server.png and freeciv/data/freeciv-server.png differ
diff -Nurd -X.diff_ignore freeciv/server/settlers.c freeciv/server/settlers.c
--- freeciv/server/settlers.c	2007-08-09 12:57:36.000000000 +0300
+++ freeciv/server/settlers.c	2007-08-25 15:25:05.000000000 +0300
@@ -1130,8 +1130,16 @@
       state[best_tile->index].eta = completion_time;
       
       if (displaced) {
+        int saved_id = punit->id;
+
 	displaced->goto_tile = NULL;
 	auto_settler_findwork(pplayer, displaced, state, recursion + 1);
+        if (player_find_unit_by_id(pplayer, saved_id) == NULL) {
+          /* Actions of the displaced settler somehow caused this settler
+           * to die. (maybe by recursively giving control back to this unit)
+           */
+          return;
+        }
       }
     } else {
       UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
@@ -1275,7 +1283,7 @@
    * player auto-settler mode) or if the player is an AI.  But don't
    * auto-settle with a unit under orders even for an AI player - these come
    * from the human player and take precedence. */
-  unit_list_iterate(pplayer->units, punit) {
+  unit_list_iterate_safe(pplayer->units, punit) {
     if ((punit->ai.control || pplayer->ai.control)
 	&& (unit_has_type_flag(punit, F_SETTLERS)
 	    || unit_has_type_flag(punit, F_CITIES))
@@ -1293,7 +1301,7 @@
         auto_settler_findwork(pplayer, punit, state, 0);
       }
     }
-  } unit_list_iterate_end;
+  } unit_list_iterate_safe_end;
 
   if (timer_in_use(t)) {
     freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
Binary files freeciv/win32/client.ico and freeciv/win32/client.ico differ
Binary files freeciv/win32/server.ico and freeciv/win32/server.ico differ
diff -Nurd -X.diff_ignore freeciv/server/settlers.c freeciv/server/settlers.c
--- freeciv/server/settlers.c	2007-08-09 12:57:41.000000000 +0300
+++ freeciv/server/settlers.c	2007-08-25 15:34:51.000000000 +0300
@@ -1101,8 +1101,16 @@
     state[best_tile->index].eta = completion_time;
       
     if (displaced) {
+      int saved_id = punit->id;
+
       displaced->goto_tile = NULL;
       auto_settler_findwork(pplayer, displaced, state, recursion + 1);
+      if (player_find_unit_by_id(pplayer, saved_id) == NULL) {
+        /* Actions of the displaced settler somehow caused this settler
+         * to die. (maybe by recursively giving control back to this unit)
+         */
+        return;
+      }
     }
 
     pft_fill_unit_parameter(&parameter, punit);
@@ -1258,7 +1266,7 @@
    * player auto-settler mode) or if the player is an AI.  But don't
    * auto-settle with a unit under orders even for an AI player - these come
    * from the human player and take precedence. */
-  unit_list_iterate(pplayer->units, punit) {
+  unit_list_iterate_safe(pplayer->units, punit) {
     if ((punit->ai.control || pplayer->ai.control)
 	&& (unit_has_type_flag(punit, F_SETTLERS)
 	    || unit_has_type_flag(punit, F_CITIES))
@@ -1276,7 +1284,7 @@
         auto_settler_findwork(pplayer, punit, state, 0);
       }
     }
-  } unit_list_iterate_end;
+  } unit_list_iterate_safe_end;
 
   if (timer_in_use(t)) {
     freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
diff -Nurd -X.diff_ignore freeciv/server/settlers.c freeciv/server/settlers.c
--- freeciv/server/settlers.c	2007-03-05 19:15:25.000000000 +0200
+++ freeciv/server/settlers.c	2007-08-25 15:39:20.000000000 +0300
@@ -1259,7 +1259,7 @@
    * player auto-settler mode) or if the player is an AI.  But don't
    * auto-settle with a unit under orders even for an AI player - these come
    * from the human player and take precedence. */
-  unit_list_iterate(pplayer->units, punit) {
+  unit_list_iterate_safe(pplayer->units, punit) {
     if ((punit->ai.control || pplayer->ai.control)
 	&& (unit_flag(punit, F_SETTLERS)
 	    || unit_flag(punit, F_CITIES))
@@ -1277,7 +1277,7 @@
       }
     }
   }
-  unit_list_iterate_end;
+  unit_list_iterate_safe_end;
   if (timer_in_use(t)) {
     freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
  	    pplayer->name, 1000.0*read_timer_seconds(t));
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to