Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2005:
[Freeciv-Dev] Re: (PR#12950) Failed sanity check in latest cvs.
Home

[Freeciv-Dev] Re: (PR#12950) Failed sanity check in latest cvs.

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: matte@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#12950) Failed sanity check in latest cvs.
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Mon, 2 May 2005 00:49:46 -0700
Reply-to: bugs@xxxxxxxxxxx

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

On Sun, 1 May 2005, Benedict Adamson wrote:
> And the attacked patch partly fixes the problem. However a problem with
> the fogging of tiles due to city/unit transfer remains. The patch
> includes an assertion that catches the fogging problem.

The attached patch should fix all the problems, including fogging. It also
fixes a potential problem with transfer_unit() and bounce_unit() which
could send sea units into landlocked cities.

BTW - The watchtower stuff should be hidden behind a function interface
for unit vision range. (I was not sure whether you could ever have a
fortress inside a city, but I left this in for completeness.)

  - Per

Index: common/movement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.c,v
retrieving revision 1.5
diff -u -r1.5 movement.c
--- common/movement.c   30 Apr 2005 17:09:27 -0000      1.5
+++ common/movement.c   2 May 2005 07:48:18 -0000
@@ -201,13 +201,12 @@
   Return TRUE iff the unit can "exist" at this location.  This means it can
   physically be present on the tile (without the use of a transporter).  See
   also can_unit_survive_at_tile.
-
-  (This function could be renamed as unit_needs_transporter.)
 ****************************************************************************/
 bool can_unit_exist_at_tile(const struct unit *punit,
                             const struct tile *ptile)
 {
-  if (ptile->city) {
+  if (ptile->city && !(is_sailing_unit(punit)
+      && !is_ocean_near_tile(ptile))) {
     return TRUE;
   }
 
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.317
diff -u -r1.317 citytools.c
--- server/citytools.c  1 May 2005 05:42:04 -0000       1.317
+++ server/citytools.c  2 May 2005 07:48:19 -0000
@@ -516,7 +516,7 @@
                      unit_name(punit->type), in_city->name,
                      from_player->name, to_player->name);
       }
-    } else {
+    } else if (can_unit_exist_at_tile(punit, tocity->tile)) {
       freelog(LOG_VERBOSE, "Transfered %s from %s to %s",
              unit_name(punit->type),
              from_player->name, to_player->name);
@@ -525,6 +525,17 @@
                      unit_name(punit->type),
                      from_player->name, to_player->name);
       }
+    } else {
+      freelog(LOG_VERBOSE, "Could not transfer %s from %s to %s",
+             unit_name(punit->type),
+             from_player->name, to_player->name);
+      if (verbose) {
+       notify_player(from_player, _("%s from %s lost in transfer "
+                      "to %s's %s"), unit_name(punit->type),
+                     from_player->name, to_player->name, tocity->name);
+      }
+      wipe_unit(punit);
+      return;
     }
   }
   real_unit_change_homecity(punit, tocity);
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.162
diff -u -r1.162 maphand.c
--- server/maphand.c    30 Apr 2005 20:59:50 -0000      1.162
+++ server/maphand.c    2 May 2005 07:48:19 -0000
@@ -978,6 +978,8 @@
 {
   struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
 
+  assert(0 <= change || -change <= plrtile->seen_count); /* else underflow */
+
   plrtile->seen_count += change;
   if (plrtile->seen_count != 0) {
     BV_SET(ptile->tile_seen, pplayer->player_no);
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.333
diff -u -r1.333 unithand.c
--- server/unithand.c   1 May 2005 05:42:04 -0000       1.333
+++ server/unithand.c   2 May 2005 07:48:19 -0000
@@ -281,32 +281,59 @@
 }
 
 /**************************************************************************
-  Transfer a unit from one homecity to another.
+  Transfer a unit from one homecity to another. If unit is not presently
+  in its new homecity, it will be moved there. This new homecity must
+  be valid for this unit.
 **************************************************************************/
 void real_unit_change_homecity(struct unit *punit, struct city *new_pcity)
 {
   struct city *old_pcity = find_city_by_id(punit->homecity);
+  struct player *old_owner = unit_owner(punit);
+  struct player *new_owner = city_owner(new_pcity);
+
+  if (!same_pos(punit->tile, new_pcity->tile)) {
+    assert(can_unit_exist_at_tile(punit, new_pcity->tile));
+    move_unit(punit, new_pcity->tile, 0); /* teleport to location */
+  }
 
   unit_list_prepend(new_pcity->units_supported, punit);
   if (old_pcity) {
     unit_list_unlink(old_pcity->units_supported, punit);
   }
+  if (old_owner != new_owner) {
+    remove_unit_sight_points(punit);
+
+    unit_list_unlink(old_owner->units, punit);
+    unit_list_prepend(new_owner->units, punit);
+    punit->owner = new_owner->player_no;
+
+    if (tile_has_special(punit->tile, S_FORTRESS)
+        && unit_profits_of_watchtower(punit)) {
+      unfog_area(new_owner, punit->tile, get_watchtower_vision(punit));
+    } else {
+      unfog_area(new_owner, punit->tile, unit_type(punit)->vision_range);
+    }
+
+    conceal_hidden_units(old_owner, punit->tile);
+    reveal_hidden_units(new_owner, punit->tile);
+  }
 
   punit->homecity = new_pcity->id;
-  punit->owner = unit_owner(punit)->player_no;
   send_unit_info(unit_owner(punit), punit);
 
   city_refresh(new_pcity);
-  send_city_info(city_owner(new_pcity), new_pcity);
+  send_city_info(new_owner, new_pcity);
 
   if (old_pcity) {
+    assert(city_owner(old_pcity) == old_owner);
     city_refresh(old_pcity);
-    send_city_info(city_owner(old_pcity), old_pcity);
+    send_city_info(old_owner, old_pcity);
   }
 }
 
 /**************************************************************************
-...
+  Change a unit's home city. The unit must be present in the city to 
+  be set as its new home city.
 **************************************************************************/
 void handle_unit_change_homecity(struct player *pplayer, int unit_id,
                                 int city_id)
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.346
diff -u -r1.346 unittools.c
--- server/unittools.c  1 May 2005 12:01:16 -0000       1.346
+++ server/unittools.c  2 May 2005 07:48:20 -0000
@@ -1283,7 +1283,7 @@
   struct city *pcity = find_closest_owned_city(pplayer, punit->tile,
                                                is_sailing_unit(punit), NULL);
 
-  if (pcity) {
+  if (pcity && can_unit_exist_at_tile(punit, pcity->tile)) {
     (void) teleport_unit_to_city(punit, pcity, 0, verbose);
   } else {
     /* remove it */

[Prev in Thread] Current Thread [Next in Thread]