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

After more testing, the previous patch still expanded the range much too
quickly, so I've scaled it some more, with every size having some effect.
Here's the list for borders 4:

City   2.1    now
Size  r**2   r**2
   1      4      2  unit
   2      9      4
   3     16      6
   4     16      8  city
   5     16     12
   6     25     16
   7     25     20
   8     36     24
               (26) AWACS
   9     36     28
  10     49     32
  11     49     36
  12     64     40
  13     64     44
  14     81     48
  15     81     52
  16    100     56

Committed revision 14403.
Committed revision 14404, patch as committed:

Index: server/citytools.c
===================================================================
--- server/citytools.c  (revision 14403)
+++ 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,8 +2230,26 @@
 ****************************************************************************/
 void city_refresh_vision(struct city *pcity)
 {
+  struct tile *pcenter = city_tile(pcity);
+  struct player *powner = city_owner(pcity);
+  struct vision_site *psite = map_get_player_site(pcenter, powner);
   int radius_sq = get_city_bonus(pcity, EFT_CITY_VISION_RADIUS_SQ);
 
+  if (NULL != psite) {
+    int delta = psite->size - game.info.borders;
+
+    /* TODO: city size effect or ruleset steps instead */
+    if (0 >= delta) {
+      psite->border_radius_sq = 2 * psite->size;
+    } else {
+      psite->border_radius_sq = (2 + delta) * game.info.borders;
+    }
+
+    if (radius_sq < psite->border_radius_sq) {
+      radius_sq = psite->border_radius_sq;
+    }
+  }
+
   vision_change_sight(pcity->server.vision, V_MAIN, radius_sq);
   vision_change_sight(pcity->server.vision, V_INVIS, 2);
 
Index: server/maphand.c
===================================================================
--- server/maphand.c    (revision 14403)
+++ 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,14 +1833,17 @@
 
 /*************************************************************************
   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)
 {
   struct city *pcity = tile_city(ptile);
   struct vision_site *psite = map_get_player_site(ptile, powner);
-  int range = game.info.borders;
 
-  if (0 == range) {
+  if (0 == game.info.borders) {
     /* no borders */
     return;
   }
@@ -1850,28 +1864,18 @@
     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 *= range; /* due to sq dist */
-
   if (NULL != pcity) {
     freelog(LOG_VERBOSE, "(%2d,%2d) border %2d \"%s\"[%d]",
             TILE_XY(ptile),
-            range,
+            psite->border_radius_sq,
             city_name(pcity), pcity->size);
   } else {
     freelog(LOG_VERBOSE, "(%2d,%2d) border %2d",
             TILE_XY(ptile),
-            range);
+            psite->border_radius_sq);
   }
 
-  circle_dxyr_iterate(ptile, range, dtile, dx, dy, dr) {
+  circle_dxyr_iterate(ptile, psite->border_radius_sq, dtile, dx, dy, dr) {
     struct city *dcity = tile_city(dtile);
     struct player *downer = tile_owner(dtile);
 
@@ -1881,7 +1885,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 14403)
+++ 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 14403)
+++ common/vision.h     (working copy)
@@ -114,7 +114,11 @@
   struct player *owner;                        /* May be NULL, always check! */
 
   int identity;                                /* city > IDENTITY_NUMBER_ZERO 
*/
-  unsigned short size;
+  int size;                            /* city, or base pseudo-size */
+
+  /* The radius of the border source. */
+  int border_radius_sq;
+
   bool occupied;
   bool walls;
   bool happy;
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to