--- server/maphand.c 2010-07-25 21:53:39.000000000 +0200
+++ server/maphand.c.old 2010-08-30 21:16:58.000000000 +0200
@@ -635,33 +635,57 @@
} players_iterate_end;
}
-/**************************************************************************
- There doesn't have to be a city.
-**************************************************************************/
-void map_refog_circle(struct player *pplayer, struct tile *ptile,
- int old_radius_sq, int new_radius_sq,
- bool can_reveal_tiles,
- enum vision_layer vlayer)
+/****************************************************************************
+ Really refog the circle for the vision layer.
+****************************************************************************/
+static void real_map_refog_circle(struct player *pplayer, struct tile *ptile,
+ int old_radius_sq, int new_radius_sq,
+ bool can_reveal_tiles,
+ enum vision_layer vlayer)
{
if (old_radius_sq != new_radius_sq) {
int max_radius = MAX(old_radius_sq, new_radius_sq);
freelog(LOG_DEBUG, "Refogging circle at %d,%d from %d to %d",
- TILE_XY(ptile), old_radius_sq, new_radius_sq);
+ TILE_XY(ptile), old_radius_sq, new_radius_sq);
buffer_shared_vision(pplayer);
circle_dxyr_iterate(ptile, max_radius, tile1, dx, dy, dr) {
if (dr > old_radius_sq && dr <= new_radius_sq) {
- map_unfog_tile(pplayer, tile1, can_reveal_tiles, vlayer);
+ map_unfog_tile(pplayer, tile1, can_reveal_tiles, vlayer);
} else if (dr > new_radius_sq && dr <= old_radius_sq) {
- map_fog_tile(pplayer, tile1, vlayer);
+ map_fog_tile(pplayer, tile1, vlayer);
}
} circle_dxyr_iterate_end;
unbuffer_shared_vision(pplayer);
}
}
+/****************************************************************************
+ There doesn't have to be a city.
+ FIXME: results would be unexpected if the new_invis_radius_sq is bigger
+ than new_main_radius_sq.
+****************************************************************************/
+void map_refog_circle(struct player *pplayer, struct tile *ptile,
+ int old_main_radius_sq, int new_main_radius_sq,
+ int old_invis_radius_sq, int new_invis_radius_sq,
+ bool can_reveal_tiles)
+{
+ if (new_invis_radius_sq < old_invis_radius_sq) {
+ /* Then remove the invisible units first for the clients. */
+ real_map_refog_circle(pplayer, ptile, old_invis_radius_sq,
+ new_invis_radius_sq, can_reveal_tiles, V_INVIS);
+ real_map_refog_circle(pplayer, ptile, old_main_radius_sq,
+ new_main_radius_sq, can_reveal_tiles, V_MAIN);
+ } else {
+ real_map_refog_circle(pplayer, ptile, old_main_radius_sq,
+ new_main_radius_sq, can_reveal_tiles, V_MAIN);
+ real_map_refog_circle(pplayer, ptile, old_invis_radius_sq,
+ new_invis_radius_sq, can_reveal_tiles, V_INVIS);
+ }
+}
/****************************************************************************
+/****************************************************************************
Shows the area to the player. Unless the tile is "seen", it will remain
fogged and units will be hidden.
@@ -740,14 +764,16 @@
remove_dumb_city(pplayer, ptile);
if (map_get_seen(ptile, pplayer, V_MAIN) > 0) {
- /* Remove units. */
- vision_layer_iterate(v) {
+ /* Remove units. Using unit_list_iterate or
+ * unit_list_reverse_iterate is equivalent here, because the
+ * tile info is sent after all units went out of sight. */
+ vision_layer_reverse_iterate(v) {
unit_list_iterate(ptile->units, punit) {
if (unit_is_visible_on_layer(punit, v)) {
unit_goes_out_of_sight(pplayer, punit);
}
} unit_list_iterate_end;
- } vision_layer_iterate_end;
+ } vision_layer_reverse_iterate_end;
}
}
@@ -909,11 +935,14 @@
void map_clear_known(struct tile *ptile, struct player *pplayer)
{
BV_CLR(ptile->tile_known, player_index(pplayer));
- vision_layer_iterate(v) {
+ /* Using vision_layer_iterate or vision_layer_reverse_iterate
+ * is equivalent here, because no units are going out of sight, neither
+ * the tile info is sent to the client. */
+ vision_layer_reverse_iterate(v) {
if (0 == map_get_player_tile(ptile, pplayer)->seen_count[v]) {
BV_CLR(ptile->tile_seen[v], player_index(pplayer));
}
- } vision_layer_iterate_end;
+ } vision_layer_reverse_iterate_end;
}
/****************************************************************************
@@ -1332,7 +1361,7 @@
player_name(pplayer),
player_name(pplayer2));
whole_map_iterate(ptile) {
- vision_layer_iterate(v) {
+ vision_layer_reverse_iterate(v) {
int change = map_get_own_seen(ptile, pplayer, v);
if (change > 0) {
@@ -1340,7 +1369,7 @@
if (map_get_seen(ptile, pplayer2, v) == 0)
really_fog_tile(pplayer2, ptile, v);
}
- } vision_layer_iterate_end;
+ } vision_layer_reverse_iterate_end;
} whole_map_iterate_end;
}
} players_iterate_end;
@@ -1609,27 +1638,18 @@
if (ploser != powner) {
base_type_iterate(pbase) {
if (tile_has_base(ptile, pbase)) {
- if (pbase->vision_main_sq >= 0) {
- /* Transfer base provided vision to new owner */
- if (powner) {
- map_refog_circle(powner, ptile, -1, pbase->vision_main_sq,
- game.info.vision_reveal_tiles, V_MAIN);
- }
- if (ploser && pbase != ignore_loss) {
- map_refog_circle(ploser, ptile, pbase->vision_main_sq, -1,
- game.info.vision_reveal_tiles, V_MAIN);
- }
+ /* Transfer base provided vision to new owner */
+ if (powner) {
+ map_refog_circle(powner, ptile,
+ -1, pbase->vision_main_sq,
+ -1, pbase->vision_invis_sq,
+ game.info.vision_reveal_tiles);
}
- if (pbase->vision_invis_sq >= 0) {
- /* Transfer base provided vision to new owner */
- if (powner) {
- map_refog_circle(powner, ptile, -1, pbase->vision_invis_sq,
- game.info.vision_reveal_tiles, V_INVIS);
- }
- if (ploser && pbase != ignore_loss) {
- map_refog_circle(ploser, ptile, pbase->vision_invis_sq, -1,
- game.info.vision_reveal_tiles, V_INVIS);
- }
+ if (ploser && pbase != ignore_loss) {
+ map_refog_circle(ploser, ptile,
+ pbase->vision_main_sq, -1,
+ pbase->vision_invis_sq, -1,
+ game.info.vision_reveal_tiles);
}
}
} base_type_iterate_end;
@@ -1764,13 +1784,15 @@
See documentation in vision.h.
****************************************************************************/
-void vision_change_sight(struct vision *vision, enum vision_layer vlayer,
- int radius_sq)
+void vision_change_sight(struct vision *vision, int radius_main_sq,
+ int radius_invis_sq)
{
map_refog_circle(vision->player, vision->tile,
- vision->radius_sq[vlayer], radius_sq,
- vision->can_reveal_tiles, vlayer);
- vision->radius_sq[vlayer] = radius_sq;
+ vision->radius_sq[V_MAIN], radius_main_sq,
+ vision->radius_sq[V_INVIS], radius_invis_sq,
+ vision->can_reveal_tiles);
+ vision->radius_sq[V_MAIN] = radius_main_sq;
+ vision->radius_sq[V_INVIS] = radius_invis_sq;
}
/****************************************************************************
@@ -1780,10 +1802,7 @@
****************************************************************************/
void vision_clear_sight(struct vision *vision)
{
- /* We don't use vision_layer_iterate because we have to go in reverse
- * order. */
- vision_change_sight(vision, V_INVIS, -1);
- vision_change_sight(vision, V_MAIN, -1);
+ vision_change_sight(vision, -1, -1);
}
/****************************************************************************
@@ -1801,14 +1820,16 @@
} else {
struct player *owner = tile_owner(ptile);
- if (old_base->vision_main_sq >= 0 && owner) {
+ if (NULL != owner
+ && (0 <= old_base->vision_main_sq
+ || 0 <= old_base->vision_invis_sq)) {
/* Base provides vision, but no borders. */
- map_refog_circle(owner, ptile, old_base->vision_main_sq, -1,
- game.info.vision_reveal_tiles, V_MAIN);
- }
- if (old_base->vision_invis_sq >= 0 && owner) {
- map_refog_circle(owner, ptile, old_base->vision_invis_sq, -1,
- game.info.vision_reveal_tiles, V_INVIS);
+ map_refog_circle(owner, ptile,
+ 0 <= old_base->vision_main_sq
+ ? old_base->vision_main_sq : -1, -1,
+ 0 <= old_base->vision_invis_sq
+ ? old_base->vision_invis_sq : -1, -1,
+ game.info.vision_reveal_tiles);
}
}
tile_remove_base(ptile, old_base);
@@ -1830,13 +1851,15 @@
} else {
struct player *owner = tile_owner(ptile);
- if (pbase->vision_main_sq > 0 && owner) {
- map_refog_circle(owner, ptile, -1, pbase->vision_main_sq,
- game.info.vision_reveal_tiles, V_MAIN);
- }
- if (pbase->vision_invis_sq > 0 && owner) {
- map_refog_circle(owner, ptile, -1, pbase->vision_invis_sq,
- game.info.vision_reveal_tiles, V_INVIS);
+ if (NULL != owner
+ && (0 < pbase->vision_main_sq
+ || 0 < pbase->vision_invis_sq)) {
+ map_refog_circle(owner, ptile,
+ -1, 0 < pbase->vision_main_sq
+ ? pbase->vision_main_sq : -1,
+ -1, 0 < pbase->vision_invis_sq
+ ? pbase->vision_invis_sq : -1,
+ game.info.vision_reveal_tiles);
}
}
}