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

 When unit conquers city, it first moves in and city changes owner
only after that. In between unit info is sent to players who see
inside cities of the old owner.
 This bug can manifest itself as:
 - client end assert about unit list size when city tile is later fogged
 - ghost units in enemy city tiles

 Attached patch removes conquering unit from clients who no longer can
see it, and sends to those who now can see it. This is S2_1 version.


 - ML

diff -Nurd -X.diff_ignore freeciv/server/citytools.c freeciv/server/citytools.c
--- freeciv/server/citytools.c	2007-08-31 21:24:51.000000000 +0300
+++ freeciv/server/citytools.c	2007-09-01 12:16:09.000000000 +0300
@@ -1207,6 +1207,7 @@
   int coins;
   struct player *pplayer = unit_owner(punit);
   struct player *cplayer = city_owner(pcity);
+  bv_player saw_entering;
 
   /* If not at war, may peacefully enter city. Or, if we cannot occupy
    * the city, this unit entering will not trigger the effects below. */
@@ -1221,6 +1222,16 @@
      - Kris Bubendorfer
      Also check spaceships --dwp
   */
+
+  /* Store information who saw unit entering city.
+   * This means old owner + allies + shared vision */
+  BV_CLR_ALL(saw_entering);
+  players_iterate(pplayer) {
+    if (map_is_known_and_seen(pcity->tile, pplayer, V_MAIN)) {
+      BV_SET(saw_entering, pplayer->player_no);
+    }
+  } players_iterate_end;
+
   if (is_capital(pcity)
       && (cplayer->spaceship.state == SSHIP_STARTED
           || cplayer->spaceship.state == SSHIP_LAUNCHED)) {
@@ -1313,6 +1324,21 @@
   /* We transfer the city first so that it is in a consistent state when
    * the size is reduced. */
   transfer_city(pplayer, pcity , 0, TRUE, TRUE, TRUE);
+
+  /* After city has been transferred, some players may no longer see inside. */
+  players_iterate(pplayer) {
+    if (BV_ISSET(saw_entering, pplayer->player_no)
+        && !can_player_see_unit_at(pplayer, punit, pcity->tile)) {
+      /* Player saw unit entering, but now unit is hiding inside city */
+      unit_goes_out_of_sight(pplayer, punit);
+    } else if (!BV_ISSET(saw_entering, pplayer->player_no)
+               && can_player_see_unit_at(pplayer, punit, pcity->tile)) {
+      /* Player sees inside cities of new owner */
+      send_unit_info_to_onlookers(pplayer->connections, punit,
+                                  pcity->tile, FALSE);
+    }
+  } players_iterate_end;
+
   city_reduce_size(pcity, 1);
   send_player_info(pplayer, pplayer); /* Update techs */
 
diff -Nurd -X.diff_ignore freeciv/server/unittools.c freeciv/server/unittools.c
--- freeciv/server/unittools.c	2007-08-31 23:22:51.000000000 +0300
+++ freeciv/server/unittools.c	2007-09-01 12:17:27.000000000 +0300
@@ -2823,7 +2823,11 @@
   
   /* Send updated information to anyone watching.  If the unit moves
    * in or out of a city we update the 'occupied' field.  Note there may
-   * be cities at both src and dest under some rulesets. */
+   * be cities at both src and dest under some rulesets.
+   *   If unit is about to take over enemy city, unit is seen by
+   * those players seeing inside cities of old city owner. After city
+   * has been transferred, updated info is sent inside
+   * handle_unit_enter_city() */
   send_unit_info_to_onlookers(NULL, punit, psrctile, FALSE);
     
   /* Special checks for ground units in the ocean. */
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to