Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2005:
[Freeciv-Dev] Re: (PR#13718) New borders behaviour
Home

[Freeciv-Dev] Re: (PR#13718) New borders behaviour

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: per@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#13718) New borders behaviour
From: "Per I. Mathisen" <per@xxxxxx>
Date: Thu, 1 Sep 2005 14:25:55 -0700
Reply-to: bugs@xxxxxxxxxxx

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

New patch, fixes crash reported by Jason when units take over enemy
cities, and stops settlers from settling on territory that is owned by
someone else.

The latter is to avoid border fragmentation and unbelievable
owns-only-one-tile cities. You now must take territory by arms (or
subversion) before settlers dare set their foot there.

This still holds:
> TODO: Savegame support. This will not be implemented before this
> approach has a thumbs up.
>
> Please test this and let me know what you think. I consider it simply
> superior to existing borders.

  - Per

Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.364
diff -u -r1.364 city.c
--- common/city.c       18 Aug 2005 06:44:27 -0000      1.364
+++ common/city.c       1 Sep 2005 21:18:54 -0000
@@ -753,6 +753,12 @@
     return FALSE;
   }
 
+  if (ptile->owner && ptile->owner != punit->owner) {
+    /* Cannot steal borders by settling. This has to be settled by
+     * force of arms. */
+    return FALSE;
+  }
+
   /* game.info.min_dist_bw_cities minimum is 1, meaning adjacent is okay */
   citymindist = game.info.citymindist;
   if (citymindist == 0) {
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.198
diff -u -r1.198 game.h
--- common/game.h       18 Aug 2005 06:44:28 -0000      1.198
+++ common/game.h       1 Sep 2005 21:18:54 -0000
@@ -207,11 +207,10 @@
 
 #define GAME_DEFAULT_FOGOFWAR        TRUE
 
-/* 0 means no national borders.  Performance dropps quickly as the border
- * distance increases (o(n^2) or worse). */
-#define GAME_DEFAULT_BORDERS         7
+/* 0 means no national borders. */
+#define GAME_DEFAULT_BORDERS         4
 #define GAME_MIN_BORDERS             0
-#define GAME_MAX_BORDERS             24
+#define GAME_MAX_BORDERS             12
 
 #define GAME_DEFAULT_HAPPYBORDERS    TRUE
 
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.232
diff -u -r1.232 map.c
--- common/map.c        14 Jul 2005 19:25:45 -0000      1.232
+++ common/map.c        1 Sep 2005 21:18:55 -0000
@@ -276,6 +276,7 @@
   ptile->worked   = NULL; /* pointer to city working tile */
   ptile->owner    = NULL; /* Tile not claimed by any nation. */
   ptile->spec_sprite = NULL;
+  ptile->owner_source = NULL;
 }
 
 /****************************************************************************
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.251
diff -u -r1.251 map.h
--- common/map.h        18 Jul 2005 22:46:28 -0000      1.251
+++ common/map.h        1 Sep 2005 21:18:56 -0000
@@ -321,12 +321,13 @@
  * radius.  Positions returned will have adjusted (x, y); unreal
  * positions will be automatically discarded. 
  */
-#define circle_iterate(center_tile, sq_radius, tile_itr)                   \
+#define circle_iterate(center_tile, sq_radius, tile_itr, dist)             \
 {                                                                           \
   int _sq_radius = (sq_radius);                                                
    \
   int _cr_radius = (int)sqrt((double)_sq_radius);                          \
   square_dxy_iterate(center_tile, _cr_radius, tile_itr, _dx, _dy) {        \
-    if (map_vector_to_sq_distance(_dx, _dy) <= _sq_radius) {
+    int dist = map_vector_to_sq_distance(_dx, _dy);                         \
+    if (dist <= _sq_radius) {
 
 #define circle_iterate_end                                                  \
     }                                                                       \
Index: common/tile.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tile.h,v
retrieving revision 1.12
diff -u -r1.12 tile.h
--- common/tile.h       11 Aug 2005 04:51:09 -0000      1.12
+++ common/tile.h       1 Sep 2005 21:18:56 -0000
@@ -36,6 +36,7 @@
   struct city *worked;      /* city working tile, or NULL if none */
   Continent_id continent;
   struct player *owner;     /* Player owning this tile, or NULL. */
+  struct tile *owner_source; /* what makes it owned by owner */
   char *spec_sprite;
 };
 
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.345
diff -u -r1.345 citytools.c
--- server/citytools.c  29 Aug 2005 12:59:57 -0000      1.345
+++ server/citytools.c  1 Sep 2005 21:18:59 -0000
@@ -811,11 +811,9 @@
   /* 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_update_borders_city_change(pcity);
-
   transfer_city_units(ptaker, pgiver, old_city_units,
                      pcity, NULL,
                      kill_outside, transfer_unit_verbose);
@@ -927,6 +925,9 @@
 
   freelog(LOG_DEBUG, "Creating city %s", name);
 
+  /* Ensure that we claim the ground we stand on */
+  map_claim_ownership(ptile, pplayer, ptile);
+
   if (terrain_control.may_road) {
     tile_set_special(ptile, S_ROAD);
     if (player_knows_techs_with_flag(pplayer, TF_RAILROAD)) {
@@ -983,10 +984,6 @@
     }
   }
 
-  /* Update the national borders.  This updates the citymap tile
-   * status and so must be done after the above. */
-  map_update_borders_city_change(pcity);
-
   /* Place a worker at the city center; this is the free-worked tile.
    * This must be done before the city refresh (below) so that the city
    * is in a sane state. */
@@ -1140,7 +1137,6 @@
      acceptable. */
 
   game_remove_city(pcity);
-  map_update_borders_city_destroyed(ptile);
 
   players_iterate(other_player) {
     if (map_is_known_and_seen(ptile, other_player)) {
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.167
diff -u -r1.167 gamehand.c
--- server/gamehand.c   26 Aug 2005 19:40:26 -0000      1.167
+++ server/gamehand.c   1 Sep 2005 21:18:59 -0000
@@ -80,7 +80,7 @@
   }
 
   /* Expose visible area. */
-  circle_iterate(ptile, game.info.init_vis_radius_sq, ctile) {
+  circle_iterate(ptile, game.info.init_vis_radius_sq, ctile, dist) {
     show_area(pplayer, ctile, 0);
   } circle_iterate_end;
 
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.175
diff -u -r1.175 maphand.c
--- server/maphand.c    29 Aug 2005 12:59:58 -0000      1.175
+++ server/maphand.c    1 Sep 2005 21:19:00 -0000
@@ -474,6 +474,7 @@
     if (!pplayer && !pconn->observer) {
       continue;
     }
+    info.owner = ptile->owner ? ptile->owner->player_no : MAP_TILE_OWNER_NULL;
     if (!pplayer || map_is_known_and_seen(ptile, pplayer)) {
       info.known = TILE_KNOWN;
       info.type = ptile->terrain->index;
@@ -481,7 +482,6 @@
        info.special[spe] = BV_ISSET(ptile->special, spe);
       }
       info.continent = ptile->continent;
-      info.owner = ptile->owner ? ptile->owner->player_no : 
MAP_TILE_OWNER_NULL;
       send_packet_tile_info(pconn, &info);
     } else if (pplayer && map_is_known(ptile, pplayer)
               && map_get_seen(ptile, pplayer) == 0) {
@@ -489,7 +489,6 @@
 
       info.known = TILE_KNOWN_FOGGED;
       info.type = plrtile->terrain->index;
-      info.owner = plrtile->owner >= 0 ? plrtile->owner : MAP_TILE_OWNER_NULL;
       for (spe = 0; spe < S_LAST; spe++) {
        info.special[spe] = BV_ISSET(plrtile->special, spe);
       }
@@ -1078,7 +1077,6 @@
 
   plrtile->last_updated = GAME_START_YEAR;
   plrtile->own_seen = plrtile->seen_count;
-  plrtile->owner = -1;
 }
 
 /****************************************************************************
@@ -1106,16 +1104,9 @@
 
   if (plrtile->terrain != ptile->terrain
       || memcmp(&plrtile->special, &ptile->special,
-               sizeof(plrtile->special)) != 0
-      || (ptile->owner && plrtile->owner != ptile->owner->player_no)
-      || (!ptile->owner && plrtile->owner >= 0)) {
+                sizeof(plrtile->special)) != 0) {
     plrtile->terrain = ptile->terrain;
     plrtile->special = ptile->special;
-    if (ptile->owner) {
-      plrtile->owner = ptile->owner->player_no;
-    } else {
-      plrtile->owner = -1;
-    }
     return TRUE;
   }
   return FALSE;
@@ -1127,12 +1118,14 @@
 
   Note this only checks for changing of the terrain or special for the
   tile, since these are the only values held in the playermap.
+
+  A tile's owner always can see terrain changes in his or her territory.
 ****************************************************************************/
 void update_tile_knowledge(struct tile *ptile)
 {
   /* Players */
   players_iterate(pplayer) {
-    if (map_is_known_and_seen(ptile, pplayer)) {
+    if (map_is_known_and_seen(ptile, pplayer) || ptile->owner == pplayer) {
       if (update_player_tile_knowledge(pplayer, ptile)) {
         send_tile_info(pplayer->connections, ptile);
       }
@@ -1183,7 +1176,6 @@
       map_set_known(ptile, pdest);
       dest_tile->terrain = from_tile->terrain;
       dest_tile->special = from_tile->special;
-      dest_tile->owner = from_tile->owner;
       dest_tile->last_updated = from_tile->last_updated;
       send_tile_info(pdest->connections, ptile);
        
@@ -1522,71 +1514,44 @@
 
     /* New continent numbers for all tiles to all players */
     send_all_known_tiles(NULL);
-    
-    map_update_borders_landmass_change(ptile);
   }
 }
 
 /*************************************************************************
-  Return pointer to the oldest adjacent city to this tile.  If
-  there is a city on the exact tile, that is returned instead.
-*************************************************************************/
-static struct city *map_get_adjc_city(struct tile *ptile)
-{
-  struct city *closest = NULL;   /* Closest city */
-
-  if (ptile->city) {
-    return ptile->city;
-  }
-
-  adjc_iterate(ptile, tile1) {
-    if (tile1->city && 
-         (!closest || tile1->city->turn_founded < closest->turn_founded)) {
-      closest = tile1->city;
-    }
-  } adjc_iterate_end;
-
-  return closest;
-}
-
-/*************************************************************************
   Ocean tile can be claimed iff one of the following conditions stands:
   a) it is an inland lake not larger than MAXIMUM_OCEAN_SIZE
   b) it is adjacent to only one continent and not more than two ocean tiles
-  c) It is one tile away from a city (This function doesn't check it)
-  The city, which claims the ocean has to be placed on the correct continent.
+  c) It is one tile away from a city
+  The source which claims the ocean has to be placed on the correct continent.
   in case a) The continent which surrounds the inland lake
   in case b) The only continent which is adjacent to the tile
   The correct continent is returned in *contp.
 *************************************************************************/
-static bool is_claimed_ocean(struct tile *ptile, Continent_id *contp)
+static bool is_claimable_ocean(struct tile *ptile, struct tile *source)
 {
   Continent_id cont = tile_get_continent(ptile);
-  Continent_id cont2, other;
+  Continent_id source_cont = tile_get_continent(source);
+  Continent_id cont2;
   int ocean_tiles;
-  
-  if (get_ocean_size(-cont) <= MAXIMUM_CLAIMED_OCEAN_SIZE &&
-      lake_surrounders[-cont] > 0) {
-    *contp = lake_surrounders[-cont];
+
+  if (get_ocean_size(-cont) <= MAXIMUM_CLAIMED_OCEAN_SIZE
+      && lake_surrounders[-cont] == source_cont) {
     return TRUE;
   }
   
-  other = 0;
   ocean_tiles = 0;
   adjc_iterate(ptile, tile2) {
     cont2 = tile_get_continent(tile2);
+    if (tile2 == source) {
+      return TRUE;
+    }
     if (cont2 == cont) {
       ocean_tiles++;
-    } else {
-      if (other == 0) {
-        other = cont2;
-      } else if (other != cont2) {
-        return FALSE;
-      }
+    } else if (cont2 != source_cont) {
+      return FALSE; /* two land continents adjacent, punt! */
     }
   } adjc_iterate_end;
   if (ocean_tiles <= 2) {
-    *contp = other;
     return TRUE;
   } else {
     return FALSE;
@@ -1594,48 +1559,6 @@
 }
 
 /*************************************************************************
-  Return pointer to the closest city to this tile, which must be
-  on the same continent if the city is not immediately adjacent.
-  If two or more cities are equally distant, then return the
-  oldest (i.e. the one with the lowest id). This also correctly
-  works for water bases in SMAC mode, and allows coastal cities
-  to claim one square of ocean. Inland lakes and long inlets act in
-  the same way as the surrounding continent's land tiles. If no cities
-  are within game.info.borders distance, returns NULL.
-
-  NOTE: The behaviour of this function will eventually depend
-  upon some planned ruleset options.
-*************************************************************************/
-static struct city *map_get_closest_city(struct tile *ptile)
-{
-  struct city *closest;  /* Closest city */
-
-  closest = map_get_adjc_city(ptile);
-  if (!closest) {
-    int distsq;                /* Squared distance to city */
-    /* integer arithmetic equivalent of (borders+0.5)**2 */
-    int cldistsq = game.info.borders * (game.info.borders + 1);
-    Continent_id cont = tile_get_continent(ptile);
-
-    if (!is_ocean(tile_get_terrain(ptile)) || is_claimed_ocean(ptile, &cont)) {
-      cities_iterate(pcity) {
-       if (tile_get_continent(pcity->tile) == cont) {
-          distsq = sq_map_distance(pcity->tile, ptile);
-          if (distsq < cldistsq ||
-               (distsq == cldistsq &&
-                (!closest || closest->turn_founded > pcity->turn_founded))) {
-            closest = pcity;
-            cldistsq = distsq;
-          } 
-        }
-      } cities_iterate_end;
-    }
-  }
-
-  return closest;
-}
-
-/*************************************************************************
   Update tile worker states for all cities that have the given map tile
   within their radius. Does not sync with client.
 
@@ -1652,143 +1575,156 @@
 }
 
 /*************************************************************************
-  Recalculate the borders around a given position.
+  Add any unique home city not found in list but found on tile to the 
+  list.
 *************************************************************************/
-static void map_update_borders_recalculate_position(struct tile *ptile)
+static void add_unique_homecities(struct city_list *cities_to_refresh, 
+                           struct tile *tile1)
 {
-  struct city_list* cities_to_refresh = NULL;
-  
-  if (game.info.happyborders > 0) {
-    cities_to_refresh = city_list_new();
-  }
-  
-  if (game.info.borders > 0) {
-    iterate_outward(ptile, game.info.borders, tile1) {
-      struct city *pccity = map_get_closest_city(tile1);
-      struct player *new_owner = pccity ? pccity->owner : NULL;
-
-      if (new_owner != tile_get_owner(tile1)) {
-       tile_set_owner(tile1, new_owner);
-        update_tile_knowledge(tile1);
-       tile_update_owner(tile1);
-       /* Update happiness */
-       if (game.info.happyborders > 0) {
-         unit_list_iterate(tile1->units, unit) {
-           struct city* homecity = find_city_by_id(unit->homecity);
-           bool already_listed = FALSE;
+  /* Update happiness */
+       unit_list_iterate(tile1->units, unit) {
+    struct city* homecity = find_city_by_id(unit->homecity);
+         bool already_listed = FALSE;
            
-           if (!homecity) {
-             continue;
-           }
-           
-           city_list_iterate(cities_to_refresh, city2) {
-             if (city2 == homecity) {
-               already_listed = TRUE;
-               break;
-             }
-           } city_list_iterate_end;
-           
-           if (!already_listed) {
-             city_list_prepend(cities_to_refresh, homecity);
-           }
-
-         } unit_list_iterate_end;
-       }
+    if (!homecity) {
+      continue;
+    }
+         city_list_iterate(cities_to_refresh, city2) {
+      if (city2 == homecity) {
+        already_listed = TRUE;
+        break;
       }
-    } iterate_outward_end;
-  }
- 
-  /* Update happiness in all homecities we have collected */ 
-  if (game.info.happyborders > 0) {
-    city_list_iterate(cities_to_refresh, to_refresh) {
-      city_refresh(to_refresh);
-      send_city_info(city_owner(to_refresh), to_refresh);
     } city_list_iterate_end;
-    
-    city_list_unlink_all(cities_to_refresh);
-    city_list_free(cities_to_refresh);
-  }
-}
 
-/*************************************************************************
-  Modify national territories as resulting from a city being destroyed.
-  x,y coords for (already deleted) city's location.
-  Tile worker states are updated as necessary, but not sync'd with client.
-*************************************************************************/
-void map_update_borders_city_destroyed(struct tile *ptile)
-{
-  map_update_borders_recalculate_position(ptile);
+         if (!already_listed) {
+          city_list_prepend(cities_to_refresh, homecity);
+         }
+  } unit_list_iterate_end;
 }
 
 /*************************************************************************
-  Modify national territories resulting from a change of landmass.
-  Tile worker states are updated as necessary, but not sync'd with client.
+  Claim ownership of a single tile.  This does no checks.
 *************************************************************************/
-void map_update_borders_landmass_change(struct tile *ptile)
+void map_claim_ownership(struct tile *ptile, struct player *owner,
+                         struct tile *source)
 {
-  map_update_borders_recalculate_position(ptile);
+  ptile->owner_source = source;
+  tile_set_owner(ptile, owner);
+  send_tile_info(NULL, ptile);
+  tile_update_owner(ptile);
 }
 
 /*************************************************************************
-  Modify national territories resulting from new city or change of city
-  ownership.
-  Tile worker states are updated as necessary, but not sync'd with client.
-*************************************************************************/
-void map_update_borders_city_change(struct city *pcity)
-{
-  map_update_borders_recalculate_position(pcity->tile);
-}
+  Update borders for all sources.  Call this on turn end.
 
-/*************************************************************************
-  Delete the territorial claims to all tiles.
+  We will remove claim to land whose source is gone, and claim
+  more land to sources in range, unless there are enemy units within
+  this range.
 *************************************************************************/
-static void map_clear_borders(void)
+void map_calculate_borders()
 {
-  whole_map_iterate(ptile) {
-    tile_set_owner(ptile, NULL);
-  } whole_map_iterate_end;
-}
+  struct city_list *cities_to_refresh = NULL;
 
-/*************************************************************************
-  Minimal code that calculates all national territories from scratch.
-*************************************************************************/
-static void map_calculate_territory(void)
-{
-  /* Clear any old territorial claims. */
-  map_clear_borders();
-
-  if (game.info.borders > 0) {
-    /* Loop over all cities and claim territory. */
-    cities_iterate(pcity) {
-      /* Loop over all map tiles within this city's sphere of influence. */
-      iterate_outward(pcity->tile, game.info.borders, ptile) {
-       struct city *pccity = map_get_closest_city(ptile);
+  if (game.info.borders == 0) {
+    return;
+  }
 
-       if (pccity) {
-         tile_set_owner(ptile, pccity->owner);
-       }
-      } iterate_outward_end;
-    } cities_iterate_end;
+  if (game.info.happyborders > 0) {
+    cities_to_refresh = city_list_new();
   }
-}
 
-/*************************************************************************
-  Calculate all national territories from scratch.  This can be slow, but
-  is only performed occasionally, i.e. after loading a saved game. Doesn't
-  send any tile information to the clients. Tile worker states are updated
-  as necessary, but not sync'd with client.
-*************************************************************************/
-void map_calculate_borders(void)
-{
-  if (game.info.borders > 0) {
-    map_calculate_territory();
+  /* First remove undue ownership */
+  whole_map_iterate(ptile) {
+    if (ptile->owner
+        && (ptile->owner != ptile->owner_source->owner
+            || (!ptile->owner_source->city
+                && !tile_has_special(ptile->owner_source, S_FORTRESS)))) {
+      /* Ownership source gone */
+      map_claim_ownership(ptile, NULL, NULL);
+    }
+  } whole_map_iterate_end;
 
-    /* Fix tile worker states. */
-    cities_iterate(pcity) {
-      map_city_radius_iterate(pcity->tile, tile1) {
-        update_city_tile_status_map(pcity, tile1);
-      } map_city_radius_iterate_end;
-    } cities_iterate_end;
+  /* Now claim ownership of unclaimed tiles for all sources; we
+   * grab one circle each turn as long as we have range left
+   * to better visually displaying expansion hurdles. */
+  whole_map_iterate(ptile) {
+    if (ptile->city || tile_has_special(ptile, S_FORTRESS)) {
+      /* Ensure that we own our ownership source */
+      if (ptile->owner == NULL) {
+        // savegames problem.......
+        freelog(LOG_ERROR, "city or fortress at (%d, %d) has no owner",
+                ptile->x, ptile->y);
+        assert(FALSE);
+        continue;
+      }
+    }
+    if (ptile->owner
+        && (ptile->city || tile_has_special(ptile, S_FORTRESS))) {
+      /* We have an ownership source */
+      int range, expand_range = 99;
+      int found_unclaimed = 99;
+
+      freelog(LOG_NORMAL, "source at %d,%d", ptile->x, ptile->y);
+      if (ptile->city) {
+        range = MIN(ptile->city->size + 1, game.info.borders);
+        if (ptile->city->size > game.info.borders) {
+          range += (ptile->city->size - game.info.borders) / 2;
+        }
+      } else {
+        range = game.info.borders;
+      }
+      range *= range; /* due to sq dist */
+      freelog(LOG_DEBUG, "borders range for source is %d", range);
+
+      circle_iterate(ptile, range, atile, dist) {
+        if (expand_range > dist) {
+          unit_list_iterate(atile->units, punit) {
+            if (!pplayers_allied(unit_owner(punit), ptile->owner)) {
+              /* We cannot expand borders further when enemy units are
+               * standing in the way. */
+              expand_range = dist - 1;
+            }
+          } unit_list_iterate_end;
+        }
+        if (found_unclaimed > dist
+            && atile->owner == NULL
+            && map_is_known(atile, ptile->owner)
+            && (!is_ocean(atile->terrain)
+                || is_claimable_ocean(atile, ptile))) {
+          found_unclaimed = dist;
+        }
+      } circle_iterate_end;
+      freelog(LOG_DEBUG, "expand_range=%d found_unclaimed=%d", expand_range,
+              found_unclaimed);
+
+      circle_iterate(ptile, range, atile, dist) {
+        if (dist > expand_range || dist > found_unclaimed) {
+          continue; /* only expand one extra circle radius each turn */
+        }
+        if (map_is_known(atile, ptile->owner) 
+            && atile->owner == NULL) {
+          if (!is_ocean(atile->terrain)
+              || is_claimable_ocean(atile, ptile)) {
+            map_claim_ownership(atile, ptile->owner, ptile);
+            atile->owner_source = ptile;
+            if (game.info.happyborders > 0) {
+              add_unique_homecities(cities_to_refresh, atile);
+            }
+          }
+        }
+      } circle_iterate_end;
+    }
+  } whole_map_iterate_end;
+
+  /* Update happiness in all homecities we have collected */ 
+  if (game.info.happyborders > 0) {
+    city_list_iterate(cities_to_refresh, to_refresh) {
+      city_refresh(to_refresh);
+      send_city_info(city_owner(to_refresh), to_refresh);
+    } city_list_iterate_end;
+    
+    city_list_unlink_all(cities_to_refresh);
+    city_list_free(cities_to_refresh);
   }
 }
 
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.61
diff -u -r1.61 maphand.h
--- server/maphand.h    13 Aug 2005 05:27:24 -0000      1.61
+++ server/maphand.h    1 Sep 2005 21:19:00 -0000
@@ -39,7 +39,6 @@
 struct player_tile {
   struct terrain *terrain; /* May be NULL for unknown tiles. */
   bv_special special;
-  signed char owner;
   unsigned short seen_count;
   unsigned short own_seen;
   /* If you build a city with an unknown square within city radius
@@ -97,10 +96,9 @@
 void enable_fog_of_war(void);
 void disable_fog_of_war(void);
 
-void map_update_borders_city_destroyed(struct tile *ptile);
-void map_update_borders_city_change(struct city *pcity);
-void map_update_borders_landmass_change(struct tile *ptile);
 void map_calculate_borders(void);
+void map_claim_ownership(struct tile *ptile, struct player *owner,
+                         struct tile *source);
 
 void check_terrain_change(struct tile *ptile, struct terrain *oldter);
 int get_continent_size(Continent_id id);
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.73
diff -u -r1.73 sanitycheck.c
--- server/sanitycheck.c        25 Aug 2005 19:21:20 -0000      1.73
+++ server/sanitycheck.c        1 Sep 2005 21:19:01 -0000
@@ -75,6 +75,10 @@
     }
 
     SANITY_CHECK(pterrain->index >= T_FIRST && pterrain->index < T_COUNT);
+
+    if (contains_special(special, S_FORTRESS)) {
+      SANITY_CHECK(ptile->owner != NULL);
+    }
   } whole_map_iterate_end;
 }
 
@@ -139,6 +143,13 @@
     CHECK_MAP_POS(ptile->x, ptile->y);
     CHECK_NATIVE_POS(ptile->nat_x, ptile->nat_y);
 
+    if (ptile->city) {
+//      SANITY_CHECK(ptile->owner != NULL);
+    }
+    if (ptile->owner != NULL) {
+//      SANITY_CHECK(ptile->owner_source != NULL);
+    }
+
     index_to_map_pos(&x, &y, ptile->index);
     SANITY_CHECK(x == ptile->x && y == ptile->y);
 
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.275
diff -u -r1.275 savegame.c
--- server/savegame.c   18 Aug 2005 06:44:29 -0000      1.275
+++ server/savegame.c   1 Sep 2005 21:19:04 -0000
@@ -185,8 +185,7 @@
 #define SAVEFILE_OPTIONS "startoptions spacerace2 rulesets" \
 " diplchance_percent map_editor known32fix turn " \
 "attributes watchtower rulesetdir client_worklists orders " \
-"startunits turn_last_built improvement_order technology_order embassies " \
-"owner_player_map"
+"startunits turn_last_built improvement_order technology_order embassies "
 
 static const char hex_chars[] = "0123456789abcdef";
 
@@ -2291,7 +2290,6 @@
                            char** improvement_order,
                            int improvement_order_size)
 {
-  char *savefile_options = secfile_lookup_str(file, "savefile.options");
   int i;
 
   if (!plr->is_alive)
@@ -2353,29 +2351,6 @@
                  map_get_player_tile(ptile, plr)->last_updated |=
                  ascii_hex2bin(ch, 3));
 
-    /* get 4-bit segments of 8-bit "owner" field */
-    if (has_capability("owner_player_map", savefile_options)) {
-      LOAD_MAP_DATA(ch, nat_y, ptile,
-                    secfile_lookup_str
-                    (file, "player%d.map_oa%03d", plrno, nat_y),
-                    map_get_player_tile(ptile, plr)->owner =
-                    ascii_hex2bin(ch, 0));
-      LOAD_MAP_DATA(ch, nat_y, ptile,
-                    secfile_lookup_str
-                    (file, "player%d.map_ob%03d", plrno, nat_y),
-                    map_get_player_tile(ptile, plr)->owner =
-                    ascii_hex2bin(ch, 1));
-    } else {
-      int nat_x, nat_y;
-      for (nat_y = 0; nat_y < map.ysize; nat_y++) {
-        for (nat_x = 0; nat_x < map.xsize; nat_x++) {
-          struct tile *ptile = native_pos_to_tile(nat_x, nat_y);
-          map_get_player_tile(ptile, plr)->owner =
-            ptile->owner ? ptile->owner->player_no : -1;
-        }
-      }
-    }
-
     {
       int j;
       struct dumb_city *pdcity;
@@ -2952,14 +2927,6 @@
                         bin2ascii_hex(map_get_player_tile
                                       (ptile, plr)->last_updated, 3));
 
-    /* put 4-bit segments of 8-bit "owner" field */
-    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_oa%03d", plrno,
-                         bin2ascii_hex(map_get_player_tile
-                                       (ptile, plr)->owner, 0));
-    SAVE_PLAYER_MAP_DATA(ptile, file, "player%d.map_ob%03d", plrno,
-                         bin2ascii_hex(map_get_player_tile
-                                       (ptile, plr)->owner, 1));
-
     if (TRUE) {
       struct dumb_city *pdcity;
       char impr_buf[MAX_NUM_ITEMS + 1];
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.288
diff -u -r1.288 srv_main.c
--- server/srv_main.c   26 Aug 2005 19:40:26 -0000      1.288
+++ server/srv_main.c   1 Sep 2005 21:19:05 -0000
@@ -667,6 +667,8 @@
     } players_iterate_end;
   }
 
+  map_calculate_borders();
+
   freelog(LOG_DEBUG, "Season of native unrests");
   summon_barbarians(); /* wild guess really, no idea where to put it, but
                          I want to give them chance to move their units */
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.381
diff -u -r1.381 unittools.c
--- server/unittools.c  1 Sep 2005 02:32:41 -0000       1.381
+++ server/unittools.c  1 Sep 2005 21:19:08 -0000
@@ -746,6 +746,7 @@
     if (total_activity (ptile, ACTIVITY_FORTRESS)
        >= tile_activity_time(ACTIVITY_FORTRESS, ptile)) {
       tile_set_special(ptile, S_FORTRESS);
+      map_claim_ownership(ptile, unit_owner(punit), ptile);
       unit_activity_done = TRUE;
       /* watchtower becomes effective */
       /* This could be a helper function. */
@@ -2684,6 +2685,12 @@
     unfog_area(pplayer, pdesttile, unit_type(punit)->vision_range);
   }
 
+  /* Claim ownership of fortress? */
+  if (tile_has_special(pdesttile, S_FORTRESS)
+      && pplayers_at_war(pdesttile->owner, pplayer)) {
+    map_claim_ownership(pdesttile, pplayer, pdesttile);
+  }
+
   unit_list_unlink(psrctile->units, punit);
   punit->tile = pdesttile;
   punit->moved = TRUE;

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