[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]
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);
}
}
Message not available
|
|