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

Since at least one other person seems to think it's a real bug, I've
investigated further.

Looking further down the function, it becomes obvious why the temporary
setting of S_FARMLAND isn't having any effect while S_IRRIGATION is: the
effects of irrigation are "built-in" and the checking code uses the
dummy "tile" with the extra specials, whereas farmland is implemented
through the effects system, and it's the original "ptile" that gets
passed into that. So presumably this change was introduced whenever the
effects system came in.

To fix this, it's not safe to just pass "tile" as it stands into the
bowels of the effects system, since parts of that can access members of
"tile" that haven't been initialised. However, I can't see any downside
to making "tile" into a full copy of *ptile then passing that around,
since nothing called from here should be modifying *ptile or any of its
descendants.

The attached patch implements this. (I had to bracket a macro argument
in a header file as well.) It fixes the bug, and hasn't obviously messed
anything else up.

diff -uNr freeciv-2.1.4-orig/common/city.c freeciv-2.1.4/common/city.c
--- freeciv-2.1.4-orig/common/city.c    2008-04-21 01:10:49.000000000 +0100
+++ freeciv-2.1.4/common/city.c 2008-04-26 21:27:50.000000000 +0100
@@ -607,9 +607,10 @@
                                int city_x, int city_y, bool is_celebrating,
                                Output_type_id otype)
 {
-  struct tile tile;
+  /* temporary dummy tile for city center bonuses */
+  struct tile tile = *ptile;
   int prod;
-  struct terrain *pterrain = tile_get_terrain(ptile);
+  struct terrain *pterrain = tile_get_terrain(&tile);
 
   assert(otype >= 0 && otype < O_LAST);
 
@@ -620,18 +621,16 @@
   }
 
   prod = pterrain->output[otype];
-  if (tile_resource_is_valid(ptile)) {
-    prod += tile_get_resource(ptile)->output[otype];
+  if (tile_resource_is_valid(&tile)) {
+    prod += tile_get_resource(&tile)->output[otype];
   }
 
-  /* create dummy tile which has the city center bonuses. */
-  tile.terrain = pterrain;
-  tile.special = tile_get_special(ptile);
-
+  /* add city center bonuses to temporary copy of tile. */
   if (pcity && is_city_center(city_x, city_y)
       && pterrain == pterrain->irrigation_result
       && terrain_control.may_irrigate) {
-    /* The center tile is auto-irrigated. */
+    /* The center tile is auto-irrigated, for the purposes of food
+     * production. */
     tile_set_special(&tile, S_IRRIGATION);
 
     if (player_knows_techs_with_flag(city_owner(pcity), TF_FARMLAND)) {
@@ -672,21 +671,21 @@
   if (pcity) {
     const struct output_type *output = &output_types[otype];
 
-    prod += get_city_tile_output_bonus(pcity, ptile, output,
+    prod += get_city_tile_output_bonus(pcity, &tile, output,
                                       EFT_OUTPUT_ADD_TILE);
     if (prod > 0) {
-      int penalty_limit = get_city_tile_output_bonus(pcity, ptile, output,
+      int penalty_limit = get_city_tile_output_bonus(pcity, &tile, output,
                                                    EFT_OUTPUT_PENALTY_TILE);
 
       if (is_celebrating) {
-        prod += get_city_tile_output_bonus(pcity, ptile, output,
+        prod += get_city_tile_output_bonus(pcity, &tile, output,
                                            EFT_OUTPUT_INC_TILE_CELEBRATE);
         penalty_limit = 0; /* no penalty if celebrating */
       }
-      prod += get_city_tile_output_bonus(pcity, ptile, output,
+      prod += get_city_tile_output_bonus(pcity, &tile, output,
                                          EFT_OUTPUT_INC_TILE);
       prod += (prod 
-               * get_city_tile_output_bonus(pcity, ptile, output,
+               * get_city_tile_output_bonus(pcity, &tile, output,
                                             EFT_OUTPUT_PER_TILE)) 
               / 100;
       if (!is_celebrating && penalty_limit > 0 && prod > penalty_limit) {
diff -uNr freeciv-2.1.4-orig/common/tile.h freeciv-2.1.4/common/tile.h
--- freeciv-2.1.4-orig/common/tile.h    2008-04-21 01:10:49.000000000 +0100
+++ freeciv-2.1.4/common/tile.h 2008-04-26 21:27:48.000000000 +0100
@@ -74,7 +74,7 @@
 void tile_clear_special(struct tile *ptile, enum tile_special_type spe);
 void tile_clear_all_specials(struct tile *ptile);
 
-#define tile_resource_is_valid(vtile) BV_ISSET(vtile->special, 
S_RESOURCE_VALID)
+#define tile_resource_is_valid(vtile) BV_ISSET((vtile)->special, 
S_RESOURCE_VALID)
 const struct resource *tile_get_resource(const struct tile *ptile);
 void tile_set_resource(struct tile *ptile, struct resource *presource);
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to