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

On 21/04/2008, Marko Lindqvist wrote:
>
>  On 21/04/2008, Marko Lindqvist  wrote:
>  >
>  >   Goto tile will be set to NULL, but ai_unit_new_role() later attempts
>  >  to access it in order to cancel city build mission.
>
>   Attached patch fixes all similar crashes and some related non-crash
>  issues as well.

 ...and then I found another related crash from server logs.

 - Changed overzealous assert not to fail when clearing unit ai_role
after AI -> Human change


 - ML

diff -Nurd -X.diff_ignore freeciv/ai/aitools.c freeciv/ai/aitools.c
--- freeciv/ai/aitools.c	2008-01-15 04:04:30.000000000 +0200
+++ freeciv/ai/aitools.c	2008-04-21 20:57:16.000000000 +0300
@@ -802,8 +802,9 @@
 {
   struct unit *bodyguard = aiguard_guard_of(punit);
 
-  /* If the unit is under (human) orders we shouldn't control it. */
-  assert(!unit_has_orders(punit));
+  /* If the unit is under (human) orders we shouldn't control it.
+   * Allow removal of old role with AIUNIT_NONE. */
+  assert(!unit_has_orders(punit) || task == AIUNIT_NONE);
 
   UNIT_LOG(LOG_DEBUG, punit, "changing role from %s to %s",
            get_ai_role_str(punit->ai.ai_role), get_ai_role_str(task));
@@ -819,7 +820,16 @@
   }
 
   if (punit->ai.ai_role == AIUNIT_BUILD_CITY) {
-    citymap_free_city_spot(punit->goto_tile, punit->id);
+    if (punit->goto_tile) {
+      citymap_free_city_spot(punit->goto_tile, punit->id);
+    } else {
+      /* Print error message instead of crashing in citymap_free_city_spot()
+       * This probably means that some city spot reservation has not been
+       * properly cleared; bad for the AI, as it will leave that area
+       * uninhabited. */
+      freelog(LOG_ERROR, "%s was on city founding mission without target tile.",
+              unit_rule_name(punit));
+    }
   }
 
   if (punit->ai.ai_role == AIUNIT_HUNTER) {
diff -Nurd -X.diff_ignore freeciv/server/unithand.c freeciv/server/unithand.c
--- freeciv/server/unithand.c	2008-03-29 07:02:25.000000000 +0200
+++ freeciv/server/unithand.c	2008-04-21 20:22:57.000000000 +0300
@@ -579,7 +579,7 @@
 }
 
 /**************************************************************************
-...
+  Handle change in unit activity.
 **************************************************************************/
 void handle_unit_change_activity(struct player *pplayer, int unit_id,
 				 enum unit_activity activity,
@@ -600,6 +600,12 @@
     return;
   }
 
+  /* Remove city spot reservations for AI settlers on city founding
+   * mission, before goto_tile reset. */
+  if (punit->ai.ai_role != AIUNIT_NONE) {
+    ai_unit_new_role(punit, AIUNIT_NONE, NULL);
+  }
+
   punit->ai.control = FALSE;
   punit->goto_tile = NULL;
 
@@ -1752,6 +1758,14 @@
     }
   }
 
+  /* This must be before old orders are freed. If this is is
+   * settlers on city founding mission, city spot reservation
+   * from goto_tile must be freed, and free_unit_orders() loses
+   * goto_tile information */
+  if (punit->ai.ai_role != AIUNIT_NONE) {
+    ai_unit_new_role(punit, AIUNIT_NONE, NULL);
+  }
+
   free_unit_orders(punit);
 
   if (packet->length == 0) {
@@ -1760,10 +1774,6 @@
     return;
   }
 
-  if (punit->ai.ai_role != AIUNIT_NONE) {
-    ai_unit_new_role(punit, AIUNIT_NONE, NULL);
-  }
-
   punit->has_orders = TRUE;
   punit->orders.length = packet->length;
   punit->orders.index = 0;
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2008-01-22 03:47:20.000000000 +0200
+++ freeciv/server/unittools.c	2008-04-21 20:36:42.000000000 +0300
@@ -1329,9 +1329,8 @@
   /* Since settlers plot in new cities in the minimap before they
      are built, so that no two settlers head towards the same city
      spot, we need to ensure this reservation is cleared should
-     the settler die on the way. */
-  if ((unit_owner(punit)->ai.control || punit->ai.control)
-      && punit->ai.ai_role != AIUNIT_NONE) {
+     the settler disappear on the way. */
+  if (punit->ai.ai_role != AIUNIT_NONE) {
     ai_unit_new_role(punit, AIUNIT_NONE, NULL);
   }
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to