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

With the recent changes that being to deviate from 2.1 border behavior,
it's about time to add expanded vision to the mix.

This should expand to the same limit as the borders, or where the borders
would be over the ocean.  But it does some slightly odd things....

The existing range progression (for borders 4) seemed a little strange, so
I've made it somewhat more uniform.

City   2.1    this
Size  range  range
  1      2      2
  2      3      3
  3      4      4
  4      4      5
  5      4      5
  6      5      6
  7      5      6
  8      6      7
  9      6      7
10      7      8

The same value is calculated once and stored.

Index: server/citytools.c
===================================================================
--- server/citytools.c  (revision 14402)
+++ server/citytools.c  (working copy)
@@ -42,6 +42,7 @@
 #include "tech.h"
 #include "unit.h"
 #include "unitlist.h"
+#include "vision.h"
 
 #include "script.h"
 
@@ -845,10 +846,10 @@
   /* Has to follow the unfog call above. */
   city_list_unlink(pgiver->cities, pcity);
   pcity->owner = ptaker;
+  map_claim_ownership(pcity->tile, ptaker, pcity->tile);
   city_list_prepend(ptaker->cities, pcity);
 
   /* Update the national borders. */
-  map_claim_ownership(pcity->tile, ptaker, pcity->tile);
   map_claim_border(pcity->tile, ptaker);
 
   transfer_city_units(ptaker, pgiver, old_city_units,
@@ -997,17 +998,21 @@
     }
   }
 
+  /* Claim the ground we stand on */
+  tile_set_worked(ptile, pcity); /* partly redundant to server_set_tile_city() 
*/
+  tile_set_owner(ptile, saved_owner);
+  map_claim_ownership(ptile, pplayer, ptile);
+
   /* Before arranging workers to show unknown land */
   pcity->server.vision = vision_new(pplayer, ptile);
   vision_reveal_tiles(pcity->server.vision, game.info.city_reveal_tiles);
   city_refresh_vision(pcity);
-
-  tile_set_worked(ptile, pcity); /* partly redundant to server_set_tile_city() 
*/
   city_list_prepend(pplayer->cities, pcity);
 
-  /* Claim the ground we stand on */
-  tile_set_owner(ptile, saved_owner);
-  map_claim_ownership(ptile, pplayer, ptile);
+  /* This is dependent on the current vision, and affects the citymap
+   * tile status, so must be done after vision is prepared and before
+   * arranging workers. */
+  map_claim_border(ptile, pplayer);
 
   if (terrain_control.may_road) {
     tile_set_special(ptile, S_ROAD);
@@ -1046,10 +1051,6 @@
    * ptile->worked does not point to it, it will give tile up. */
   server_set_tile_city(pcity, CITY_MAP_SIZE/2, CITY_MAP_SIZE/2, C_TILE_WORKER);
 
-  /* Update the national borders.  This affects the citymap tile status,
-   * so must be done after the above and before arranging workers. */
-  map_claim_border(ptile, pplayer);
-
   /* Refresh the city.  First a city refresh is done (this shouldn't
    * send any packets to the client because the city has no supported units)
    * then rearrange the workers.  Note that auto_arrange_workers does its
@@ -2002,16 +2003,16 @@
     return FALSE;
   }
 
-  if (tile_owner(ptile) && tile_owner(ptile) != powner) {
+  if (NULL != tile_owner(ptile) && tile_owner(ptile) != powner) {
     return FALSE;
   }
   /* TODO: civ3-like option for borders */
 
-  if (ptile->worked && ptile->worked != pcity) {
+  if (NULL != ptile->worked && ptile->worked != pcity) {
     return FALSE;
   }
 
-  if (!map_is_known(ptile, powner)) {
+  if (!map_is_known_and_seen(ptile, powner, V_MAIN)) {
     return FALSE;
   }
 
@@ -2229,9 +2230,30 @@
 ****************************************************************************/
 void city_refresh_vision(struct city *pcity)
 {
-  int radius_sq = get_city_bonus(pcity, EFT_CITY_VISION_RADIUS_SQ);
+  struct tile *pcenter = city_tile(pcity);
+  struct player *powner = city_owner(pcity);
+  struct vision_site *psite = map_get_player_site(pcenter, powner);
+  int border_radius_sq = game.info.borders;
+  int vision_radius_sq = get_city_bonus(pcity, EFT_CITY_VISION_RADIUS_SQ);
 
-  vision_change_sight(pcity->server.vision, V_MAIN, radius_sq);
+  if (0 < border_radius_sq
+   && NULL != psite
+   && IDENTITY_NUMBER_ZERO < psite->identity) {
+    /* TODO: city size effect instead */
+    if (psite->size > game.info.borders) {
+      /* TODO: expansion stages based on ruleset */
+      border_radius_sq += 1 + (psite->size - game.info.borders) / 2;
+    } else {
+      border_radius_sq = 1 + psite->size;
+    }
+    psite->border_radius_sq = border_radius_sq;
+
+    if (vision_radius_sq < border_radius_sq) {
+      vision_radius_sq = border_radius_sq;
+    }
+  }
+
+  vision_change_sight(pcity->server.vision, V_MAIN, vision_radius_sq);
   vision_change_sight(pcity->server.vision, V_INVIS, 2);
 
   ASSERT_VISION(pcity->server.vision);
Index: server/maphand.c
===================================================================
--- server/maphand.c    (revision 14402)
+++ server/maphand.c    (working copy)
@@ -1763,6 +1763,13 @@
 
 /*************************************************************************
   Claim ownership of a single tile.
+
+  This is called for two reasons:
+  (1) Set a base or city.  The tile_owner() MUST be any previous owner.
+      Because of update_city_tile_status_map() above, the city SHOULD NOT
+      be in the cities list yet.  Also, before city_refresh_vision() as
+      that now depends on the vision_site.
+  (2) map_claim_border(), only after (1) has setup the vision_site.
 *************************************************************************/
 void map_claim_ownership(struct tile *ptile, struct player *powner,
                          struct tile *psource)
@@ -1784,24 +1791,28 @@
   if (NULL != powner && NULL != psource) {
     struct city *pcity = tile_city(ptile);
     struct player_tile *playtile = map_get_player_tile(psource, powner);
+    struct vision_site *psite = playtile->site;
 
-    if (NULL != playtile->site) {
+    if (NULL != psite) {
       if (ptile != psource) {
-        map_get_player_tile(ptile, powner)->site = playtile->site;
+        map_get_player_tile(ptile, powner)->site = psite;
       } else if (NULL != pcity) {
-        update_vision_site_from_city(playtile->site, pcity);
+        update_vision_site_from_city(psite, pcity);
       } else {
         /* has new owner */
-        playtile->site->owner = powner;
+        psite->owner = powner;
       }
     } else {
       assert(ptile == psource);
       assert(NULL != pcity); /* FIXME: temporary IDENTITY_NUMBER_ZERO */
+
       if (NULL != pcity) {
-        playtile->site = create_vision_site_from_city(pcity);
+        psite = create_vision_site_from_city(pcity);
       } else {
-        playtile->site = create_vision_site(IDENTITY_NUMBER_ZERO, psource, 
powner);
+        psite = create_vision_site(IDENTITY_NUMBER_ZERO, psource, powner);
       }
+
+      playtile->site = psite;
     }
   } else {
     assert(NULL == powner && NULL == psource);
@@ -1822,6 +1833,10 @@
 
 /*************************************************************************
   Update borders for this source.  Call this for each new source.
+
+  This is dependent on the current vision, and affects the citymap
+  tile status, so must be done after city_refresh_vision() and before
+  (re-)arranging workers.
 *************************************************************************/
 void map_claim_border(struct tile *ptile, struct player *powner)
 {
@@ -1850,14 +1865,7 @@
     return;
   }
 
-  if (IDENTITY_NUMBER_ZERO < psite->identity) {
-    /* city expansion */
-    range = MIN(psite->size + 1, game.info.borders);
-    /* TODO: expansion stages based on ruleset */
-    if (psite->size > game.info.borders) {
-      range += (psite->size - game.info.borders) / 2;
-    }
-  }
+  range = psite->border_radius_sq;
   range *= range; /* due to sq dist */
 
   if (NULL != pcity) {
@@ -1881,7 +1889,7 @@
     }
 
     if (!map_is_known_and_seen(dtile, powner, V_MAIN)) {
-      /* TODO: border should expand vision */
+      /* without city_reveal_tiles option */
       continue;
     }
 
Index: server/savegame.c
===================================================================
--- server/savegame.c   (revision 14402)
+++ server/savegame.c   (working copy)
@@ -2467,11 +2467,6 @@
        map_set_known(tile1, plr);
       } map_city_radius_iterate_end;
     }
-    
-    /* adding the cities contribution to fog-of-war */
-    pcity->server.vision = vision_new(city_owner(pcity), pcity->tile);
-    vision_reveal_tiles(pcity->server.vision, game.info.city_reveal_tiles);
-    city_refresh_vision(pcity);
 
     pcity->units_supported = unit_list_new();
 
@@ -2661,10 +2656,15 @@
                                   plrno, i);
 
     /* After all the set_worker_city() and everything is loaded. */
-    city_list_append(plr->cities, pcity);
     tile_set_owner(pcenter, past);
     map_claim_ownership(pcenter, plr, pcenter);
-    map_claim_border(pcenter, plr);
+
+    /* adding the city contribution to fog-of-war */
+    pcity->server.vision = vision_new(plr, pcity->tile);
+    vision_reveal_tiles(pcity->server.vision, game.info.city_reveal_tiles);
+    city_refresh_vision(pcity);
+
+    city_list_append(plr->cities, pcity);
   }
 }
 
@@ -4351,6 +4351,9 @@
     initialize_globals();
     apply_unit_ordering();
 
+    /* all vision is ready */
+    map_calculate_borders();
+
     /* Make sure everything is consistent. */
     players_iterate(pplayer) {
       unit_list_iterate(pplayer->units, punit) {
Index: common/vision.h
===================================================================
--- common/vision.h     (revision 14402)
+++ common/vision.h     (working copy)
@@ -113,6 +113,8 @@
   struct tile *location;               /* Cannot be NULL */
   struct player *owner;                        /* May be NULL, always check! */
 
+  int border_radius_sq;
+
   int identity;                                /* city > IDENTITY_NUMBER_ZERO 
*/
   unsigned short size;
   bool occupied;
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to