Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2003:
[Freeciv-Dev] Re: (PR#2789) Units sometimes remain displayed in fog of w
Home

[Freeciv-Dev] Re: (PR#2789) Units sometimes remain displayed in fog of w

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: kenn@xxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#2789) Units sometimes remain displayed in fog of war
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxx>
Date: Sat, 15 Feb 2003 11:44:27 -0800
Reply-to: rt@xxxxxxxxxxxxxx

Quoting Gregory Berkolaiko <Gregory.Berkolaiko@xxxxxxxxxxxx>:

> Hopefully I can hunt it down, with the savegame Kenn provided.

Done.  The logic of what to send and what not to send is highly confusing, but I
am pretty sure we got it this time.  Thanks to Kenn for the savegame.

The bug would only occur if a unit leaves a visible enemy city to move into
fogged territory.

With the patch, units can sneak in and out of a city unnoticed if they move from
the city straight into the FoW or unknown.  I think this is the correct 
behaviour.

Best wishes,
G.



? mmm.gz
? saves
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.211
diff -u -r1.211 unittools.c
--- server/unittools.c  2003/02/12 21:15:50     1.211
+++ server/unittools.c  2003/02/15 19:37:29
@@ -1936,8 +1936,36 @@
 }
 
 /**************************************************************************
+  A helper function for send_info_to_onlookers below.  
+  Checks if a unit can be seen by pplayer at (x,y).
+  A player can see a unit if he:
+  (a) can see the tile AND
+  (b) can see the unit at the tile (i.e. unit not invisible at this tile) AND
+  (c) the unit is not in an unallied city
+
+  TODO: the name is confusingly similar to player_can_see_unit_at_location
+  But we need to rename p_c_s_u_a_t because it is really 
+  is_unit_visible_to_player_at.
+**************************************************************************/
+static bool can_player_see_unit_at(struct player *pplayer, struct unit *punit,
+                                   int x, int y)
+{
+  if (!pplayer) {
+    freelog(LOG_ERROR, "NULL pointer in can_player_see_unit_at");
+    return FALSE;
+  } else {
+    bool see_tile = map_get_known_and_seen(x, y, pplayer);
+    bool see_unit = player_can_see_unit_at_location(pplayer, punit, x, y);
+    bool not_in_city = (pplayers_allied(unit_owner(punit), pplayer)
+                            || !map_get_city(x, y));
+
+    return (see_tile && see_unit && not_in_city);
+  }
+}
+
+/**************************************************************************
   Send the unit into to those connections in dest which can see the units
-  position, or the specified (x,y) (if different).
+  at it's position, or the specified (x,y) (if different).
   Eg, use x and y as where the unit came from, so that the info can be
   sent if the other players can see either the target or destination tile.
   dest = NULL means all connections (game.game_connections)
@@ -1954,19 +1982,13 @@
 
   conn_list_iterate(*dest, pconn) {
     struct player *pplayer = pconn->player;
-    bool can_see_tile = (map_get_known_and_seen(info.x, info.y, pplayer)
-                        || map_get_known_and_seen(x, y, pplayer));
-    bool can_see_unit = (player_can_see_unit(pplayer, punit)
-                        || player_can_see_unit_at_location(pplayer, punit,
-                                                           x, y));
-    bool outside_city =
-       ((pplayer && pplayers_allied(unit_owner(punit), pplayer))
-        || (!map_get_city(punit->x, punit->y) || !map_get_city(x, y)));
+    bool see_pos = can_player_see_unit_at(pplayer, punit, punit->x, punit->y);
+    bool see_xy = see_pos;
 
-    if (!pplayer && !pconn->observer) {
-      continue;
+    if(!same_pos(x, y, punit->x, punit->y)) {
+      see_xy = can_player_see_unit_at(pplayer, punit, x, y);
     }
-    if (!pplayer || (can_see_tile && can_see_unit && outside_city)) {
+    if ((!pplayer && pconn->observer) || see_pos || see_xy) {
       send_packet_unit_info(pconn, &info);
     }
   }

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