Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2005:
[Freeciv-Dev] (PR#11311) death to smallpox?
Home

[Freeciv-Dev] (PR#11311) death to smallpox?

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11311) death to smallpox?
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 27 Sep 2005 08:03:59 -0700
Reply-to: bugs@xxxxxxxxxxx

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

Here is an updated version of the patch.  Almost every line of code had
to be updated since every place this patch touches has been cleaned up
since it was originally written (all inspired by this patch of course).

The main problem remaining is an ugly one: with the "covered" value. 
Currently:

* ptile->covered gives the number of cities that have access to the free
output and bonuses from this tile
* It is updated when cities are built or destroyed, and recalculated on
game load.  If citymap size were to change during the course of a game,
it would have to be updated then too.
* It does not respect borders.  Doing so makes things substantially more
complicated, since it has to be updated when borders change and this
already coincides with founding of cities.  The end result is the "long"
caluclation would have to be done, that is O(n^2) in the citymap size of
a city.

Of course there may be other bugs as well.  It also includes a modified
ruleset - this isn't intended to be balanced but is just a demo of the
new options in action.

-jason



? diff
Index: ai/aisettler.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aisettler.c,v
retrieving revision 1.29
diff -p -u -r1.29 aisettler.c
--- ai/aisettler.c      18 Aug 2005 06:44:26 -0000      1.29
+++ ai/aisettler.c      27 Sep 2005 06:15:01 -0000
@@ -152,15 +152,21 @@ void cityresult_fill(struct player *ppla
 
       /* Food */
       result->citymap[i][j].food
-       = base_city_get_output_tile(i, j, pcity, FALSE, O_FOOD);
+       = (base_city_get_output_tile(i, j, pcity, FALSE, O_FOOD)
+          + 4 * tile_get_output_add(ptile, O_FOOD));
 
       /* Shields */
       result->citymap[i][j].shield
-       = base_city_get_output_tile(i, j, pcity, FALSE, O_SHIELD);
+       = (base_city_get_output_tile(i, j, pcity, FALSE, O_SHIELD)
+          + 4 * tile_get_output_add(ptile, O_SHIELD));
 
       /* Trade */
       result->citymap[i][j].trade
-       = base_city_get_output_tile(i, j, pcity, FALSE, O_TRADE);
+       = (base_city_get_output_tile(i, j, pcity, FALSE, O_TRADE)
+          + 4 * tile_get_output_add(ptile, O_TRADE)
+          + 4 * tile_get_output_add(ptile, O_GOLD)
+          + 4 * tile_get_output_add(ptile, O_LUXURY)
+          + 4 * tile_get_output_add(ptile, O_SCIENCE));
 
       sum = result->citymap[i][j].food * ai->food_priority
             + result->citymap[i][j].trade * ai->science_priority
@@ -168,7 +174,8 @@ void cityresult_fill(struct player *ppla
 
       /* Balance perfection */
       sum *= PERFECTION / 2;
-      if (result->citymap[i][j].food >= 2) {
+      if (result->citymap[i][j].food >= 2
+         || tile_get_output_add(ptile, O_FOOD) > 0) {
         sum *= 2; /* we need this to grow */
       }
 
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.85
diff -p -u -r1.85 citydlg_common.c
--- client/citydlg_common.c     1 Aug 2005 23:09:35 -0000       1.85
+++ client/citydlg_common.c     27 Sep 2005 06:15:01 -0000
@@ -394,6 +394,12 @@ void get_city_dialog_output_text(const s
 
   buf[0] = '\0';
 
+  if (pcity->free[otype] != 0) {
+    cat_snprintf(buf, bufsz,
+                _("%+4d : Free from terrain\n"), pcity->free[otype]);
+    total += pcity->free[otype];
+  }
+
   cat_snprintf(buf, bufsz,
               _("%+4d : Citizens\n"), pcity->citizen_base[otype]);
   total += pcity->citizen_base[otype];
@@ -434,6 +440,17 @@ void get_city_dialog_output_text(const s
     }
   }
 
+  if (priority == 0 && terrain_control.terrain_bonuses[otype]) {
+    const int base = total, bonus = get_city_terrain_bonus(pcity, otype);
+
+    total = total * bonus / 100;
+    if (total != base) {
+      cat_snprintf(buf, bufsz,
+                  _("%+4d : Bonus from terrain\n"),
+                  total - base);
+    }
+  }
+
   for (priority = 0; priority < 2; priority++) {
     enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2};
 
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.550
diff -p -u -r1.550 packhand.c
--- client/packhand.c   26 Sep 2005 22:03:09 -0000      1.550
+++ client/packhand.c   27 Sep 2005 06:15:02 -0000
@@ -451,6 +451,7 @@ void handle_city_info(struct packet_city
   }
 
   output_type_iterate(o) {
+    pcity->free[o] = packet->free[o];
     pcity->surplus[o] = packet->surplus[o];
     pcity->waste[o] = packet->waste[o];
     pcity->unhappy_penalty[o] = packet->unhappy_penalty[o];
@@ -590,7 +591,6 @@ static void handle_city_packet_common(st
     }
   }
 
-
   if (can_client_change_view()) {
     refresh_city_mapcanvas(pcity, pcity->tile, FALSE, FALSE);
   }
@@ -1966,6 +1966,8 @@ void handle_tile_info(struct packet_tile
     unit_list_unlink_all(ptile->units);
   }
 
+  ptile->covered = packet->covered;
+
   /* update continents */
   if (ptile->continent != packet->continent && ptile->continent != 0
       && packet->continent > 0) {
@@ -2294,6 +2296,12 @@ void handle_ruleset_terrain(struct packe
     pterrain->output[o] = p->output[o];
     pterrain->special[0].output[o] = p->output_special_1[o];
     pterrain->special[1].output[o] = p->output_special_2[o];
+    pterrain->bonus[o] = p->bonus[o];
+    pterrain->add[o] = p->add[o];
+    pterrain->special[0].bonus[o] = p->bonus_special_1[o];
+    pterrain->special[0].add[o] = p->add_special_1[o];
+    pterrain->special[1].bonus[o] = p->bonus_special_2[o];
+    pterrain->special[1].add[o] = p->add_special_2[o];
   } output_type_iterate_end;
 
   sz_strlcpy(pterrain->special[0].name_orig, p->special_1_name);
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.364
diff -p -u -r1.364 city.c
--- common/city.c       18 Aug 2005 06:44:27 -0000      1.364
+++ common/city.c       27 Sep 2005 06:15:03 -0000
@@ -1456,18 +1456,37 @@ static int content_citizens(const struct
   return content;
 }
 
+int get_city_terrain_bonus(const struct city *pcity, Output_type_id otype)
+{
+  int bonus = 0;
+
+  if (terrain_control.terrain_bonuses[otype]) {
+    const int factor = 420; /* Avoid rounding errors.  lcm(2..7) == 420. */
+
+    map_city_radius_iterate(pcity->tile, ptile) {
+      if (tile_get_known(ptile, pcity->owner) != TILE_UNKNOWN) {
+       bonus += tile_get_output_bonus(ptile, otype) * factor / ptile->covered;
+      }
+    } map_city_radius_iterate_end;
+
+    bonus /= factor;
+  }
+  return 100 + bonus;
+}
+
 /**************************************************************************
  Return the factor (in %) by which the city's output should be multiplied.
 **************************************************************************/
 int get_city_output_bonus(const struct city *pcity, Output_type_id otype)
 {
   struct output_type *output = &output_types[otype];
+  int bonus0 = get_city_terrain_bonus(pcity, otype);
   int bonus1 = 100 + get_city_tile_output_bonus(pcity, NULL, output,
                                                EFT_OUTPUT_BONUS);
   int bonus2 = 100 + get_city_tile_output_bonus(pcity, NULL, output,
                                                EFT_OUTPUT_BONUS_2);
 
-  return bonus1 * bonus2 / 100;
+  return (bonus0 * bonus1 / 100) * bonus2 / 100;
 }
 
 /**************************************************************************
@@ -1586,6 +1605,24 @@ static inline void set_city_bonuses(stru
 }
 
 /****************************************************************************
+  Calculate the free output received by the city.
+****************************************************************************/
+static void city_get_free_output(const struct city *pcity, int *output)
+{
+  const int factor = 420; /* lcm(2..7) */
+
+  memset(output, 0, O_COUNT * sizeof(*output));
+  map_city_radius_iterate(pcity->tile, ptile) {
+    output_type_iterate(o) {
+      output[o] += factor * tile_get_output_add(ptile, o) / ptile->covered;
+    } output_type_iterate_end;
+  } map_city_radius_iterate_end;
+  output_type_iterate(o) {
+    output[o] /= factor;
+  } output_type_iterate_end;
+}
+
+/****************************************************************************
   This function sets all the values in the pcity->tile_output[] array. This
   should be called near the beginning of generic_city_refresh.  It doesn't
   depend on anything else in the refresh and doesn't change when workers are
@@ -1936,7 +1973,7 @@ static inline void set_city_production(s
    */
 
   output_type_iterate(o) {
-    pcity->prod[o] = pcity->citizen_base[o];
+    pcity->prod[o] = pcity->citizen_base[o] + pcity->free[o];
   } output_type_iterate_end;
 
   /* Add on special extra incomes: trade routes and tithes. */
@@ -2120,6 +2157,7 @@ void generic_city_refresh(struct city *p
     set_city_bonuses(pcity);   /* Calculate the bonus[] array values. */
     set_city_tile_output(pcity); /* Calculate the tile_output[] values. */
     city_support(pcity, send_unit_info); /* manage settlers, and units */
+    city_get_free_output(pcity, pcity->free);
   }
 
   /* Calculate output from citizens. */
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.223
diff -p -u -r1.223 city.h
--- common/city.h       1 Aug 2005 23:09:36 -0000       1.223
+++ common/city.h       27 Sep 2005 06:15:03 -0000
@@ -221,6 +221,7 @@ struct city {
   int trade[NUM_TRADEROUTES], trade_value[NUM_TRADEROUTES];
 
   /* the productions */
+  int free[O_MAX]; /* Free output received by the city. */
   int surplus[O_MAX]; /* Final surplus in each category. */
   int waste[O_MAX]; /* Waste/corruption in each category. */
   int unhappy_penalty[O_MAX]; /* Penalty from unhappy cities. */
@@ -500,6 +501,7 @@ int city_waste(const struct city *pcity,
 int city_specialists(const struct city *pcity);                 /* 
elv+tax+scie */
 Specialist_type_id best_specialist(Output_type_id otype,
                                   const struct city *pcity);
+int get_city_terrain_bonus(const struct city *pcity, Output_type_id otype);
 int get_city_output_bonus(const struct city *pcity, Output_type_id otype);
 bool city_built_last_turn(const struct city *pcity);
 
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.232
diff -p -u -r1.232 map.c
--- common/map.c        14 Jul 2005 19:25:45 -0000      1.232
+++ common/map.c        27 Sep 2005 06:15:03 -0000
@@ -272,6 +272,7 @@ static void tile_init(struct tile *ptile
   BV_CLR_ALL(ptile->tile_seen);
   ptile->continent = 0;
   ptile->city     = NULL;
+  ptile->covered = 0;
   ptile->units    = unit_list_new();
   ptile->worked   = NULL; /* pointer to city working tile */
   ptile->owner    = NULL; /* Tile not claimed by any nation. */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.158
diff -p -u -r1.158 packets.def
--- common/packets.def  26 Sep 2005 18:59:11 -0000      1.158
+++ common/packets.def  27 Sep 2005 06:15:03 -0000
@@ -335,6 +335,7 @@ PACKET_TILE_INFO=14; sc,lsend
 
   TERRAIN type;
   UINT8 known;
+  UINT8 covered;
   BOOL special[S_LAST];
   PLAYER owner;
   CONTINENT continent;
@@ -498,6 +499,7 @@ PACKET_CITY_INFO=21; sc,lsend
   UINT8 specialists_size;
   UINT8 specialists[SP_MAX:specialists_size];
 
+  SINT16 free[O_MAX];
   SINT16 surplus[O_MAX];
   UINT16 waste[O_MAX];
   SINT16 unhappy_penalty[O_MAX];
@@ -1144,6 +1146,7 @@ PACKET_RULESET_TERRAIN_CONTROL=101;sc,ls
   BOOL may_irrigate;   /* may build irrigation/farmland */
   BOOL may_mine;       /* may build mines */
   BOOL may_transform;  /* may transform terrain */
+  BOOL terrain_bonuses[O_MAX];
 
   /* parameters */
   UINT8 ocean_reclaim_requirement_pct; /* # adjacent land tiles for reclaim */
@@ -1229,14 +1232,20 @@ PACKET_RULESET_TERRAIN=105;sc,lsend
   SINT8 defense_bonus;
 
   UINT8 output[O_MAX];
+  SINT8 bonus[O_MAX];
+  SINT8 add[O_MAX];
 
   STRING special_1_name[MAX_LEN_NAME];
   UINT8 output_special_1[O_MAX];
+  SINT8 bonus_special_1[O_MAX];
+  SINT8 add_special_1[O_MAX];
   STRING graphic_str_special_1[MAX_LEN_NAME];
   STRING graphic_alt_special_1[MAX_LEN_NAME];
 
   STRING special_2_name[MAX_LEN_NAME];
   UINT8 output_special_2[O_MAX];
+  SINT8 bonus_special_2[O_MAX];
+  SINT8 add_special_2[O_MAX];
   STRING graphic_str_special_2[MAX_LEN_NAME];
   STRING graphic_alt_special_2[MAX_LEN_NAME];
 
Index: common/terrain.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.h,v
retrieving revision 1.41
diff -p -u -r1.41 terrain.h
--- common/terrain.h    1 Aug 2005 22:38:25 -0000       1.41
+++ common/terrain.h    27 Sep 2005 06:15:04 -0000
@@ -113,12 +113,16 @@ struct terrain {
   int defense_bonus; /* % defense bonus - defaults to zero */
 
   int output[O_MAX];
+  int bonus[O_MAX];
+  int add[O_MAX];
 
 #define MAX_NUM_SPECIALS 2
   struct {
     const char *name; /* Translated string - doesn't need freeing. */
     char name_orig[MAX_LEN_NAME];
     int output[O_MAX];
+    int bonus[O_MAX];
+    int add[O_MAX];
     char graphic_str[MAX_LEN_NAME];
     char graphic_alt[MAX_LEN_NAME];
   } special[MAX_NUM_SPECIALS];
Index: common/tile.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tile.c,v
retrieving revision 1.13
diff -p -u -r1.13 tile.c
--- common/tile.c       13 Aug 2005 05:22:55 -0000      1.13
+++ common/tile.c       27 Sep 2005 06:15:05 -0000
@@ -158,6 +158,43 @@ enum known_type tile_get_known(const str
 }
 
 /****************************************************************************
+  The bonus multiplier provided by this tile.  This free bonus should be
+  split between all cities for whom the tile is inside the citymap of
+  (see map_tile_get_coverage).  It works identically to
+  the EFT_OUTPUT_BONUS.
+****************************************************************************/
+int tile_get_output_bonus(const struct tile *ptile, Output_type_id output)
+{
+  if (!ptile->terrain) {
+    return 0;
+  } else if (tile_has_special(ptile, S_SPECIAL_1)) {
+    return ptile->terrain->special[0].bonus[output];
+  } else if (tile_has_special(ptile, S_SPECIAL_2)) {
+    return ptile->terrain->special[1].bonus[output];
+  } else {
+    return ptile->terrain->bonus[output];
+  }
+}
+
+/****************************************************************************
+  The free output provided by this tile.  This free output should be
+  split between all cities for whom the tile is inside the citymap of
+  (see map_tile_get_coverage).
+****************************************************************************/
+int tile_get_output_add(const struct tile *ptile, Output_type_id output)
+{
+  if (!ptile->terrain) {
+    return 0;
+  } else if (tile_has_special(ptile, S_SPECIAL_1)) {
+    return ptile->terrain->special[0].add[output];
+  } else if (tile_has_special(ptile, S_SPECIAL_2)) {
+    return ptile->terrain->special[1].add[output];
+  } else {
+    return ptile->terrain->add[output];
+  }
+}
+
+/****************************************************************************
   Time to complete the given activity on the given tile.
 ****************************************************************************/
 int tile_activity_time(enum unit_activity activity, const struct tile *ptile)
Index: common/tile.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tile.h,v
retrieving revision 1.12
diff -p -u -r1.12 tile.h
--- common/tile.h       11 Aug 2005 04:51:09 -0000      1.12
+++ common/tile.h       27 Sep 2005 06:15:05 -0000
@@ -34,6 +34,7 @@ struct tile {
   struct unit_list *units;
   bv_player tile_known, tile_seen;
   struct city *worked;      /* city working tile, or NULL if none */
+  int covered; /* Number of cities whose citymaps cover the tile. */
   Continent_id continent;
   struct player *owner;     /* Player owning this tile, or NULL. */
   char *spec_sprite;
@@ -66,6 +67,9 @@ Continent_id tile_get_continent(const st
 enum known_type tile_get_known(const struct tile *ptile,
                              const struct player *pplayer);
 
+int tile_get_output_bonus(const struct tile *ptile, Output_type_id otype);
+int tile_get_output_add(const struct tile *ptile, Output_type_id otype);
+
 /* An arbitrary somewhat integer value.  Activity times are multiplied by
  * this amount, and divided by them later before being used.  This may
  * help to avoid rounding errors; however it should probably be removed. */
Index: data/default/terrain.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/terrain.ruleset,v
retrieving revision 1.41
diff -p -u -r1.41 terrain.ruleset
--- data/default/terrain.ruleset        1 Aug 2005 22:38:26 -0000       1.41
+++ data/default/terrain.ruleset        27 Sep 2005 06:15:05 -0000
@@ -207,12 +207,15 @@ graphic_special_1    = "ts.arctic_ivory"
 graphic_special_1a   = "-"
 food_special_1       = 1
 shield_special_1     = 1
-trade_special_1      = 4
+trade_special_1      = 2
+gold_special_1_bonus = 5
+luxury_special_1_bonus = 5
 special_2_name       = _("Oil")
 graphic_special_2    = "ts.arctic_oil"
 graphic_special_2a   = "ts.oil"
 food_special_2       = 0
-shield_special_2     = 4
+shield_special_2     = 2
+shield_special_2_bonus = 10
 trade_special_2      = 0
 road_trade_incr      = 0
 road_time            = 4
@@ -251,17 +254,22 @@ defense_bonus        = 0
 food                 = 0
 shield               = 1
 trade                = 0
+shield_bonus         = 1
+gold_bonus           = 1
 special_1_name       = _("Oasis")
 graphic_special_1    = "ts.oasis"
 graphic_special_1a   = "-"
-food_special_1       = 3
+food_special_1       = 2
 shield_special_1     = 1
 trade_special_1      = 0
+food_special_1_add   = 1
+luxury_special_1_bonus = 5
 special_2_name       = _("Oil")
 graphic_special_2    = "ts.oil"
 graphic_special_2a   = "-"
 food_special_2       = 0
-shield_special_2     = 4
+shield_special_2     = 3
+shield_special_2_bonus = 5
 trade_special_2      = 0
 road_trade_incr      = 1
 road_time            = 2
@@ -300,18 +308,25 @@ defense_bonus        = 50
 food                 = 1
 shield               = 2
 trade                = 0
+shield_bonus         = 3
 special_1_name       = _("Pheasant")
 graphic_special_1    = "ts.pheasant"
 graphic_special_1a   = "-"
-food_special_1       = 3
-shield_special_1     = 2
+food_special_1       = 2
+shield_special_1     = 1
+shield_special_1_bonus = 10
+food_special_1_add   = 1
 trade_special_1      = 0
 special_2_name       = _("Silk")
 graphic_special_2    = "ts.silk"
 graphic_special_2a   = "-"
 food_special_2       = 1
 shield_special_2     = 2
-trade_special_2      = 3
+trade_special_2      = 1
+luxury_special_1_bonus = 7
+gold_special_1_bonus = 7
+science_special_1_bonus = 7
+trade_special_2_add  = 1
 road_trade_incr      = 0
 road_time            = 4
 irrigation_result    = "Plains"
@@ -397,18 +412,22 @@ defense_bonus        = 100
 food                 = 1
 shield               = 0
 trade                = 0
+shield_bonus         = 5
 special_1_name       = _("Coal")
 graphic_special_1    = "ts.coal"
 graphic_special_1a   = "-"
 food_special_1       = 1
-shield_special_1     = 2
+shield_special_1     = 1
+shield_special_1_bonus = 15
 trade_special_1      = 0
 special_2_name       = _("Wine")
 graphic_special_2    = "ts.wine"
 graphic_special_2a   = "-"
 food_special_2       = 1
 shield_special_2     = 0
-trade_special_2      = 4
+trade_special_2      = 1
+luxury_special_1_bonus = 20
+luxury_special_1_add = 2
 road_trade_incr      = 0
 road_time            = 4
 irrigation_result    = "yes"
@@ -451,13 +470,17 @@ graphic_special_1    = "ts.gems"
 graphic_special_1a   = "-"
 food_special_1       = 1
 shield_special_1     = 0
-trade_special_1      = 4
+trade_special_1      = 1
+gold_special_1_add   = 2
+gold_special_1_bonus = 10
+luxury_special_1_bonus = 12
 special_2_name       = _("Fruit")
 graphic_special_2    = "ts.fruit"
 graphic_special_2a   = "-"
-food_special_2       = 4
+food_special_2       = 3
 shield_special_2     = 0
 trade_special_2      = 1
+food_special_2_add   = 1
 road_trade_incr      = 0
 road_time            = 4
 irrigation_result    = "Grassland"
@@ -496,17 +519,22 @@ defense_bonus        = 200
 food                 = 0
 shield               = 1
 trade                = 0
+shield_bonus         = 7
 special_1_name       = _("Gold")
 graphic_special_1    = "ts.gold"
 graphic_special_1a   = "-"
 food_special_1       = 0
 shield_special_1     = 1
-trade_special_1      = 6
+trade_special_1      = 2
+gold_special_1_add   = 2
+gold_special_1_bonus = 30
+luxury_special_1_bonus = 20
 special_2_name       = _("Iron")
 graphic_special_2    = "ts.iron"
 graphic_special_2a   = "-"
 food_special_2       = 0
-shield_special_2     = 4
+shield_special_2     = 2
+shield_special_2_bonus = 20
 trade_special_2      = 0
 road_trade_incr      = 0
 road_time            = 6
@@ -544,18 +572,23 @@ defense_bonus        = 0
 food                 = 1
 shield               = 0
 trade                = 2
+gold_bonus           = 1
+science_bonus        = 1
+luxury_bonus         = 1
 special_1_name       = _("Fish")
 graphic_special_1    = "ts.fish"
 graphic_special_1a   = "-"
 food_special_1       = 3
 shield_special_1     = 0
 trade_special_1      = 2
+food_special_1_add   = 1
 special_2_name       = _("Whales")
 graphic_special_2    = "ts.whales"
 graphic_special_2a   = "-"
 food_special_2       = 2
 shield_special_2     = 1
 trade_special_2      = 2
+shield_special_2_bonus = 10
 road_trade_incr      = 0
 road_time            = 0
 irrigation_result    = "no"
@@ -598,14 +631,16 @@ special_1_name       = _("Buffalo")
 graphic_special_1    = "ts.buffalo"
 graphic_special_1a   = "-"
 food_special_1       = 1
-shield_special_1     = 3
+shield_special_1     = 2
 trade_special_1      = 0
+shield_special_1_bonus = 10
 special_2_name       = _("Wheat")
 graphic_special_2    = "ts.wheat"
 graphic_special_2a   = "-"
-food_special_2       = 3
+food_special_2       = 2
 shield_special_2     = 1
 trade_special_2      = 0
+food_special_2_add   = 2
 road_trade_incr      = 1
 road_time            = 2
 irrigation_result    = "yes"
@@ -647,14 +682,19 @@ special_1_name       = _("Peat")
 graphic_special_1    = "ts.peat"
 graphic_special_1a   = "-"
 food_special_1       = 1
-shield_special_1     = 4
+shield_special_1     = 2
 trade_special_1      = 0
+shield_special_1_bonus = 15
 special_2_name       = _("Spice")
 graphic_special_2    = "ts.spice"
 graphic_special_2a   = "-"
 food_special_2       = 3
 shield_special_2     = 0
-trade_special_2      = 4
+trade_special_2      = 2
+food_special_2_add   = 1
+gold_special_2_bonus = 10
+science_special_2_bonus = 10
+luxury_special_2_bonus = 10
 road_trade_incr      = 0
 road_time            = 4
 irrigation_result    = "Grassland"
@@ -697,13 +737,15 @@ graphic_special_1    = "ts.tundra_game"
 graphic_special_1a   = "-"
 food_special_1       = 3
 shield_special_1     = 1
+food_special_1_add   = 1
 trade_special_1      = 0
 special_2_name       = _("Furs")
 graphic_special_2    = "ts.furs"
 graphic_special_2a   = "-"
 food_special_2       = 2
 shield_special_2     = 0
-trade_special_2      = 3
+trade_special_2      = 2
+trade_special_2_add  = 1
 road_trade_incr      = 0
 road_time            = 2
 irrigation_result    = "yes"
Index: data/default/units.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/units.ruleset,v
retrieving revision 1.72
diff -p -u -r1.72 units.ruleset
--- data/default/units.ruleset  21 Sep 2005 03:15:43 -0000      1.72
+++ data/default/units.ruleset  27 Sep 2005 06:15:05 -0000
@@ -213,9 +213,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 0
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 1
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Settlers", "NonMil", "AddToCity", "Cities", "NoVeteran"
 roles         = "Cities"
 helptext      = _("\
@@ -257,9 +257,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 0
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Settlers", "NonMil", "Airbase", "NoVeteran"
 roles         = "Settlers"
 helptext      = _("\
@@ -298,9 +298,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 0
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Settlers", "NonMil", "Transform", "Airbase", "NoVeteran"
 roles         = "Settlers"
 helptext      = _("\
@@ -339,9 +339,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendOk", "FirstBuild"
 helptext      = _("\
@@ -371,9 +371,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendGood", "FirstBuild"
 
@@ -399,9 +399,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendOk"
 
@@ -427,9 +427,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendOk", "Hut", "BarbarianBuild", "BarbarianSea"
 
@@ -455,9 +455,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Pikemen"
 roles         = "DefendGood", "FirstBuild"
 
@@ -483,9 +483,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendGood", "FirstBuild", "HutTech",
                 "BarbarianTech", "BarbarianBuildTech", "BarbarianSeaTech"
@@ -512,9 +512,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "IgTer", "IgZOC"
 roles         = "DefendGood", "Partisan", "BarbarianTech"
 helptext      = _("\
@@ -552,9 +552,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "IgTer"
 roles         = "DefendGood"
 
@@ -580,9 +580,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "DefendGood", "FirstBuild"
 
@@ -608,9 +608,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Marines"
 roles         = "DefendOk", "BarbarianSeaTech"
 
@@ -636,9 +636,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Paratroopers"
 roles         = "DefendOk"
 
@@ -668,9 +668,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = ""
 roles         = "DefendGood"
 helptext      = _("\
@@ -701,9 +701,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Horse"
 roles         = "AttackFast", "Hut", "Barbarian", "Hunter"
 
@@ -729,9 +729,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Horse"
 roles         = "AttackFast", "Hut", "Hunter"
 
@@ -757,9 +757,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Horse"
 roles         = "AttackFast", "HutTech", "BarbarianTech",
                 "BarbarianBuildTech", "BarbarianSeaTech", "Hunter"
@@ -786,9 +786,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Horse"
 roles         = "AttackFast", "BarbarianBuildTech", "BarbarianSeaTech",
                 "Hunter"
@@ -815,9 +815,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "AttackFast", "Hunter"
 
@@ -843,9 +843,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = ""
 roles         = "AttackFast", "Hunter"
 
@@ -871,9 +871,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "AttackStrong"
 
@@ -899,9 +899,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "AttackStrong", "BarbarianTech", "BarbarianBuildTech"
 
@@ -927,9 +927,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = "AttackStrong"
 
@@ -955,9 +955,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "IgWall"
 roles         = "AttackStrong"
 
@@ -983,9 +983,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 1
 uk_happy      = 0
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "Fighter"
 roles         = ""
 
@@ -1011,9 +1011,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 2
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "FieldUnit", "OneAttack"
 roles         = ""
 
@@ -1039,9 +1039,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "FieldUnit", "OneAttack"
 roles         = ""
 helptext      = _("\
@@ -1073,9 +1073,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 1
 uk_happy      = 0
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "Partial_Invis", "Fighter"
 roles         = ""
 helptext      = _("\
@@ -1105,9 +1105,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 2
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "Partial_Invis", "FieldUnit", "OneAttack"
 roles         = ""
 helptext      = _("\
@@ -1137,9 +1137,9 @@ vision_range  = 1
 transport_cap = 2
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "Trireme", "BadCityDefender"
 roles         = "Ferryboat"
 
@@ -1165,9 +1165,9 @@ vision_range  = 1
 transport_cap = 3
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "BadCityDefender"
 roles         = "Ferryboat", "BarbarianBoat"
 
@@ -1193,9 +1193,9 @@ vision_range  = 1
 transport_cap = 4
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "BadCityDefender"
 roles         = "Ferryboat", "BarbarianBoat"
 
@@ -1221,9 +1221,9 @@ vision_range  = 1
 transport_cap = 2
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "BadCityDefender"
 roles         = "Hunter"
 
@@ -1249,9 +1249,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "BadCityDefender"
 roles         = "Hunter"
 
@@ -1277,9 +1277,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "BadCityDefender"
 roles         = "Hunter"
 helptext      = _("\
@@ -1309,9 +1309,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 3
 flags         = "BadCityDefender"
 roles         = "DefendGood"
 
@@ -1337,9 +1337,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 3
 flags         = "AEGIS", "BadCityDefender"
 roles         = "DefendGood"
 
@@ -1365,9 +1365,9 @@ vision_range  = 2
 transport_cap = 0
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 4
 flags         = "BadCityDefender"
 roles         = ""
 
@@ -1393,9 +1393,9 @@ vision_range  = 2
 transport_cap = 8
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 2
 flags         = "Partial_Invis", "BadCityDefender",
                "Missile_Carrier", "No_Land_Attack"
 roles         = "Hunter"
@@ -1426,9 +1426,9 @@ vision_range  = 2
 transport_cap = 8
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 5
 flags         = "Carrier", "BadCityDefender"
 roles         = ""
 helptext      = _("\
@@ -1459,9 +1459,9 @@ vision_range  = 2
 transport_cap = 8
 fuel          = 0
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "BadCityDefender"
 roles         = "Ferryboat"
 
@@ -1487,9 +1487,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 1
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = "FieldUnit", "OneAttack", "Missile"
 roles         = ""
 helptext      = _("\
@@ -1519,9 +1519,9 @@ vision_range  = 1
 transport_cap = 0
 fuel          = 1
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 5
 flags         = "FieldUnit", "OneAttack", "Missile", "Nuclear"
 roles         = ""
 helptext      = _("\
@@ -1823,9 +1823,9 @@ vision_range  = 5
 transport_cap = 0
 fuel          = 2
 uk_happy      = 1
-uk_shield     = 1
+uk_shield     = 0
 uk_food       = 0
-uk_gold       = 0
+uk_gold       = 1
 flags         = ""
 roles         = ""
 helptext      = _("\
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.348
diff -p -u -r1.348 citytools.c
--- server/citytools.c  8 Sep 2005 19:51:23 -0000       1.348
+++ server/citytools.c  27 Sep 2005 06:15:06 -0000
@@ -990,7 +990,14 @@ void create_city(struct player *pplayer,
   /* 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. */
-  server_set_tile_city(pcity, CITY_MAP_SIZE/2, CITY_MAP_SIZE/2, C_TILE_WORKER);
+  city_map_checked_iterate(pcity->tile, x, y, ptile) {
+    ptile->covered++;
+    assert(ptile->covered == map_tile_get_coverage(ptile));
+    send_tile_info(NULL, ptile);
+    if (is_free_worked_tile(x, y)) {
+      server_set_tile_city(pcity, x, y, C_TILE_WORKER);
+    }
+  } city_map_checked_iterate_end;
 
   /* 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)
@@ -1152,6 +1159,12 @@ void remove_city(struct city *pcity)
 
   /* Update available tiles in adjacent cities. */
   map_city_radius_iterate(ptile, tile1) {
+    if (TRUE) {
+      assert(tile1->covered > 0);
+      tile1->covered--;
+      send_tile_info(NULL, tile1);
+      assert(tile1->covered == map_tile_get_coverage(tile1));
+    }
     /* For every tile the city could have used. */
     map_city_radius_iterate(tile1, tile2) {
       /* We see what cities are inside reach of the tile. */
@@ -1582,6 +1595,7 @@ void package_city(struct city *pcity, st
   }
 
   output_type_iterate(o) {
+    packet->free[o] = pcity->free[o];
     packet->surplus[o] = pcity->surplus[o];
     packet->waste[o] = pcity->waste[o];
     packet->unhappy_penalty[o] = pcity->unhappy_penalty[o];
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.177
diff -p -u -r1.177 maphand.c
--- server/maphand.c    15 Sep 2005 17:34:40 -0000      1.177
+++ server/maphand.c    27 Sep 2005 06:15:23 -0000
@@ -466,6 +466,7 @@ void send_tile_info(struct conn_list *de
   } else {
     info.spec_sprite[0] = '\0';
   }
+  info.covered = ptile->covered; /* Minor cheating. */
 
   conn_list_iterate(dest, pconn) {
     struct player *pplayer = pconn->player;
@@ -1793,6 +1794,35 @@ void map_calculate_borders(void)
 }
 
 /*************************************************************************
+  Calculate how many cities have access to this tile.
+
+  Currently this doesn't restrict coverage by borders, because doing so
+  would make the updating logic substantially more complicated.
+*************************************************************************/
+int map_tile_get_coverage(const struct tile *ptile)
+{
+  int covered = 0;
+
+  city_map_checked_iterate(ptile, cx, cy, itr_tile) {
+    if (itr_tile->city) {
+      covered++;
+    }
+  } city_map_checked_iterate_end;
+
+  return covered;
+}
+
+/*************************************************************************
+  Calculate how many cities have access to each tile.
+*************************************************************************/
+void map_calculate_coverage(void)
+{
+  whole_map_iterate(ptile) {
+    ptile->covered = map_tile_get_coverage(ptile);
+  } whole_map_iterate_end;
+}
+
+/*************************************************************************
   Return size in tiles of the given continent(not ocean)
 *************************************************************************/
 int get_continent_size(Continent_id id)
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.61
diff -p -u -r1.61 maphand.h
--- server/maphand.h    13 Aug 2005 05:27:24 -0000      1.61
+++ server/maphand.h    27 Sep 2005 06:15:23 -0000
@@ -102,6 +102,9 @@ void map_update_borders_city_change(stru
 void map_update_borders_landmass_change(struct tile *ptile);
 void map_calculate_borders(void);
 
+int map_tile_get_coverage(const struct tile *ptile);
+void map_calculate_coverage(void);
+
 void check_terrain_change(struct tile *ptile, struct terrain *oldter);
 int get_continent_size(Continent_id id);
 int get_ocean_size(Continent_id id);
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.285
diff -p -u -r1.285 ruleset.c
--- server/ruleset.c    21 Sep 2005 06:45:25 -0000      1.285
+++ server/ruleset.c    27 Sep 2005 06:15:24 -0000
@@ -1496,6 +1496,9 @@ static void load_ruleset_terrain(struct 
 
   /* terrain details */
 
+  output_type_iterate(o) {
+    terrain_control.terrain_bonuses[o] = FALSE;
+  } output_type_iterate_end;
   terrain_type_iterate(pterrain) {
     char **slist;
     const int i = pterrain->index;
@@ -1532,6 +1535,14 @@ static void load_ruleset_terrain(struct 
       pterrain->output[o]
        = secfile_lookup_int_default(file, 0, "%s.%s", sec[i],
                                     get_output_identifier(o));
+      pterrain->add[o]
+       = secfile_lookup_int_default(file, 0, "%s.%s_add", sec[i],
+                                    get_output_identifier(o));
+      pterrain->bonus[o]
+       = secfile_lookup_int_default(file, 0, "%s.%s_bonus",
+                                    sec[i],
+                                    get_output_identifier(o));
+      terrain_control.terrain_bonuses[o] |= (pterrain->bonus[o] > 0);
     } output_type_iterate_end;
 
     for (j = 0; j < MAX_NUM_SPECIALS; j++) {
@@ -1547,6 +1558,16 @@ static void load_ruleset_terrain(struct 
        pterrain->special[j].output[o]
          = secfile_lookup_int_default(file, 0, "%s.%s_special_%d", sec[i],
                                       get_output_identifier(o), j + 1);
+       pterrain->special[j].add[o]
+         = secfile_lookup_int_default(file, 0, "%s.%s_special_%d_add",
+                                      sec[i],
+                                      get_output_identifier(o), j + 1);
+       pterrain->special[j].bonus[o]
+         = secfile_lookup_int_default(file, 0, "%s.%s_special_%d_bonus",
+                                      sec[i],
+                                      get_output_identifier(o), j + 1);
+       terrain_control.terrain_bonuses[o]
+         |= (pterrain->special[j].bonus[o] > 0);
       } output_type_iterate_end;
 
       sz_strlcpy(pterrain->special[j].graphic_str,
@@ -2821,8 +2842,14 @@ static void send_ruleset_terrain(struct 
 
     output_type_iterate(o) {
       packet.output[o] = pterrain->output[o];
+      packet.bonus[o] = pterrain->bonus[o];
+      packet.add[o] = pterrain->add[o];
       packet.output_special_1[o] = pterrain->special[0].output[o];
+      packet.bonus_special_1[o] = pterrain->special[0].bonus[o];
+      packet.add_special_1[o] = pterrain->special[0].add[o];
       packet.output_special_2[o] = pterrain->special[1].output[o];
+      packet.bonus_special_2[o] = pterrain->special[1].bonus[o];
+      packet.add_special_2[o] = pterrain->special[1].add[o];
     } output_type_iterate_end;
 
     sz_strlcpy(packet.special_1_name, pterrain->special[0].name_orig);
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.75
diff -p -u -r1.75 sanitycheck.c
--- server/sanitycheck.c        5 Sep 2005 15:55:47 -0000       1.75
+++ server/sanitycheck.c        27 Sep 2005 06:15:34 -0000
@@ -161,6 +161,8 @@ static void check_map(void)
       } adjc_iterate_end;
     }
 
+    SANITY_CHECK(ptile->covered == map_tile_get_coverage(ptile));
+
     if (pcity) {
       SANITY_CHECK(same_pos(pcity->tile, ptile));
     }
@@ -267,11 +269,12 @@ void real_sanity_check_city(struct city 
 
   /* Sanity check city size versus worker and specialist counts. */
   city_map_iterate(x, y) {
-    if (get_worker_city(pcity, x, y) == C_TILE_WORKER) {
+    if (get_worker_city(pcity, x, y) == C_TILE_WORKER
+       && !is_free_worked_tile(x, y)) {
       workers++;
     }
   } city_map_iterate_end;
-  if (workers + city_specialists(pcity) != pcity->size + 1) {
+  if (workers + city_specialists(pcity) != pcity->size) {
     int diff = pcity->size + 1 - workers - city_specialists(pcity);
 
     SANITY_CHECK(workers + city_specialists(pcity) == pcity->size + 1);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.278
diff -p -u -r1.278 savegame.c
--- server/savegame.c   26 Sep 2005 18:59:12 -0000      1.278
+++ server/savegame.c   27 Sep 2005 06:15:42 -0000
@@ -3659,6 +3659,7 @@ void game_load(struct section_file *file
 
     /* Rebuild national borders. */
     map_calculate_borders();
+    map_calculate_coverage(); /* AFTER borders are done. */
 
     /* Make sure everything is consistent. */
     players_iterate(pplayer) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#11311) death to smallpox?, Jason Short <=