Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2005:
[Freeciv-Dev] Re: (PR#14969) Ressource specials are no longer modified w
Home

[Freeciv-Dev] Re: (PR#14969) Ressource specials are no longer modified w

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: guillaume.melquiond@xxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#14969) Ressource specials are no longer modified when a terrain is transformed
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 25 Dec 2005 11:09:05 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Per I. Mathisen wrote:

>>It seems clear, at least to me, we cannot let old specials remains in the
>>new terrain at risk of weirdness like the beforementioned landlocked whales
>>scenario. So in my view we only have two clean solutions. The one is removing
>>the special as you mentioned before, another is to randomly assign a new 
>>special
>>valid in that terrain, which seems IMO reasonable.
> 
> I don't know, that will make players calculate transformations from "bad"
> specials to "good" specials, knowing that by transforming a plains with
> shield into hill will with 50% chance give you coal. You can get a lot of
> coal that way, especially if you can do it again and again until you get
> it right.
> 
> I like 3 or 5 above better. Players generally shouldn't be tranforming
> valuable resources.

This patch implements #5.  Resources now have no effect on terrains that 
they aren't allowed on.  So if you have plains/wheat and you mine it to 
forest, you lose the wheat.  But if you irrigate back to plains, you'll 
get the wheat back.

I had to change pterrain->resources to be a bitvector instead of a list, 
to make terrain_has_resource into an O(1) operation.

The next step would IMO be to add relative probabilities for each 
resource for mapgen to use.  Then you could have a resource on a tile 
that has 0% probability, so it will never be generated but would be 
attainable through transformation.

-jason

Index: server/generator/mapgen.c
===================================================================
--- server/generator/mapgen.c   (revision 11381)
+++ server/generator/mapgen.c   (working copy)
@@ -1361,17 +1361,18 @@
     }
     if (!is_ocean(pterrain) || near_safe_tiles (ptile)) {
       int i = 0;
-      const struct resource **r;
 
-      for (r = pterrain->resources; *r; r++) {
-       /* This is a standard way to get a random element from the
-        * pterrain->resources list, without computing its length in
-        * advance. Note that if *(pterrain->resources) == NULL, then
-        * this loop is a no-op. */
-       if (!myrand (++i)) {
-         tile_set_resource(ptile, *r);
-       }
-      }
+      resource_type_iterate(r) {
+       if (BV_ISSET(pterrain->resources, r->index)) {
+         /* This is a standard way to get a random element from the
+          * pterrain->resources list, without computing its length in
+          * advance. Note that if *(pterrain->resources) == NULL, then
+          * this loop is a no-op. */
+         if (!myrand (++i)) {
+           tile_set_resource(ptile, r);
+         }
+       } 
+      } resource_type_iterate_end;
     }
   } whole_map_iterate_end;
   
Index: server/ruleset.c
===================================================================
--- server/ruleset.c    (revision 11381)
+++ server/ruleset.c    (working copy)
@@ -1528,16 +1528,16 @@
     } output_type_iterate_end;
 
     res = secfile_lookup_str_vec (file, &nval, "%s.resources", sec[i]);
-    pterrain->resources = fc_calloc(nval + 1,
-                                   sizeof(*pterrain->resources));
+    BV_CLR_ALL(pterrain->resources);
     for (j = 0; j < nval; j++) {
-      pterrain->resources[j] = get_resource_by_name_orig(res[j]);
-      if (!pterrain->resources[j]) {
+      struct resource *resource = get_resource_by_name_orig(res[j]);
+
+      if (!resource) {
        freelog(LOG_FATAL, "Could not find resource \"%s\".", res[j]);
        exit(EXIT_FAILURE);
       }
+      BV_SET(pterrain->resources, resource->index);
     }
-    pterrain->resources[nval] = NULL;
 
     pterrain->road_trade_incr
       = secfile_lookup_int(file, "%s.road_trade_incr", sec[i]);
@@ -2767,7 +2767,6 @@
 
   terrain_type_iterate(pterrain) {
     const int i = pterrain->index;
-    const struct resource **r;
 
     packet.id = i;
 
@@ -2782,10 +2781,7 @@
       packet.output[o] = pterrain->output[o];
     } output_type_iterate_end;
 
-    packet.num_resources = 0;
-    for (r = pterrain->resources; *r; r++) {
-      packet.resources[packet.num_resources++] = (*r)->index;
-    }
+    packet.resources = pterrain->resources;
 
     packet.road_trade_incr = pterrain->road_trade_incr;
     packet.road_time = pterrain->road_time;
Index: server/savegame.c
===================================================================
--- server/savegame.c   (revision 11381)
+++ server/savegame.c   (working copy)
@@ -738,6 +738,7 @@
 
   return hex_chars[bin];
 }
+
 /****************************************************************************
   Complicated helper function for reading resources from a savegame.
   This reads resources saved in the specials bitvector.
@@ -745,23 +746,33 @@
   (0 for special_1, 1 for special_2).
 ****************************************************************************/
 static void set_savegame_old_resource(const struct resource **r,
-                                     const struct terrain *terrain,
+                                     const struct terrain *pterrain,
                                      char ch, int n)
 {
+  struct resource *res[2];
+  int i = 0;
+
   assert (n == 0 || n == 1);
+
+  resource_type_iterate(r2) {
+    if (terrain_has_resource(pterrain, r2)) {
+      res[i] = r2;
+      i++;
+      if (i == 2) {
+       break;
+      }
+    }
+  } resource_type_iterate_end;
+
   /* If resource is already set to non-NULL or there is no resource found
    * in this half-byte, then abort */
-  if (*r || !(ascii_hex2bin (ch, 0) & 0x1) || !terrain->resources[0]) {
+  if (*r || !(ascii_hex2bin (ch, 0) & 0x1) || i == 0) {
     return;
   }
   /* Note that we must handle the case of special_2 set when there is
    * only one resource defined for the terrain (example, Shields on
    * Grassland terrain where both resources are identical) */
-  if (n == 0 || !terrain->resources[1]) {
-    *r = terrain->resources[0];
-  } else {
-    *r = terrain->resources[1];
-  }
+  *r = res[CLIP(0, n, i - 1)];
 }
 
 /****************************************************************************
Index: common/packets.def
===================================================================
--- common/packets.def  (revision 11381)
+++ common/packets.def  (working copy)
@@ -198,6 +198,7 @@
 type BV_FLAGS          = bitvector(bv_flags)
 type BV_ROLES          = bitvector(bv_roles)
 type BV_TERRAIN_FLAGS  = bitvector(bv_terrain_flags)
+type BV_RESOURCES       = bitvector(bv_resources)
 type BV_CITY_OPTIONS    = bitvector(bv_city_options)
 type DIPLSTATE         = diplstate(struct player_diplstate)
 type VISION            = uint32(unsigned int)
@@ -1222,8 +1223,7 @@
   SINT8 defense_bonus;
 
   UINT8 output[O_MAX];
-  UINT8 num_resources;
-  RESOURCE resources[MAX_NUM_RESOURCES:num_resources];
+  BV_RESOURCES resources;
 
   UINT8 road_trade_incr;
   UINT8 road_time;
Index: common/city.c
===================================================================
--- common/city.c       (revision 11381)
+++ common/city.c       (working copy)
@@ -597,7 +597,8 @@
   }
 
   prod = pterrain->output[otype];
-  if (ptile->resource) {
+  if (ptile->resource
+      && terrain_has_resource(ptile->terrain, ptile->resource)) {
     prod += ptile->resource->output[otype];
   }
 
Index: common/capstr.c
===================================================================
--- common/capstr.c     (revision 11381)
+++ common/capstr.c     (working copy)
@@ -82,7 +82,7 @@
  *     as long as possible.  We want to maintain network compatibility with
  *     the stable branch for as long as possible.
  */
-#define CAPABILITY "+Freeciv.Devel.2005.Dec.23b"
+#define CAPABILITY "+Freeciv.Devel.2005.Dec.25"
 
 void init_our_capability(void)
 {
Index: common/tile.c
===================================================================
--- common/tile.c       (revision 11381)
+++ common/tile.c       (working copy)
@@ -447,7 +447,8 @@
     sz_strlcat(s, get_special_name(S_RIVER));
   }
 
-  if (ptile->resource) {
+  if (ptile->resource
+      && terrain_has_resource(ptile->terrain, ptile->resource)) {
     cat_snprintf(s, sizeof(s), " (%s)", ptile->resource->name);
   }
 
Index: common/terrain.h
===================================================================
--- common/terrain.h    (revision 11381)
+++ common/terrain.h    (working copy)
@@ -74,6 +74,7 @@
 };
 
 BV_DEFINE(bv_terrain_flags, TER_MAX);
+BV_DEFINE(bv_resources, MAX_NUM_RESOURCES);
 
 enum mapgen_terrain_property {
   MG_MOUNTAINOUS,
@@ -113,7 +114,7 @@
 
   int output[O_MAX];
 
-  const struct resource **resources; /* NULL-terminated */
+  bv_resources resources;
 
   int road_trade_incr;
   int road_time;
@@ -178,6 +179,8 @@
 const char *get_name(const struct terrain *pterrain);
 enum terrain_flag_id terrain_flag_from_str(const char *s);
 #define terrain_has_flag(terr, flag) BV_ISSET((terr)->flags, flag)
+#define terrain_has_resource(terr, res) BV_ISSET((terr)->resources,        \
+                                                (res)->index)
 struct terrain *get_flag_terrain(enum terrain_flag_id flag);
 void terrains_free(void);
 
Index: common/packets_gen.c
===================================================================
--- common/packets_gen.c        (revision 11381)
+++ common/packets_gen.c        (working copy)
@@ -25245,7 +25245,7 @@
 
 #define cmp_packet_ruleset_terrain_100 cmp_const
 
-BV_DEFINE(packet_ruleset_terrain_100_fields, 26);
+BV_DEFINE(packet_ruleset_terrain_100_fields, 25);
 
 static struct packet_ruleset_terrain 
*receive_packet_ruleset_terrain_100(struct connection *pc, enum packet_type 
type)
 {
@@ -25321,41 +25321,17 @@
     }
   }
   if (BV_ISSET(fields, 8)) {
-    {
-      int readin;
-    
-      dio_get_uint8(&din, &readin);
-      real_packet->num_resources = readin;
-    }
+    DIO_BV_GET(&din, real_packet->resources);
   }
   if (BV_ISSET(fields, 9)) {
-    
     {
-      int i;
-    
-      if(real_packet->num_resources > MAX_NUM_RESOURCES) {
-        freelog(LOG_ERROR, "packets_gen.c: WARNING: truncation array");
-        real_packet->num_resources = MAX_NUM_RESOURCES;
-      }
-      for (i = 0; i < real_packet->num_resources; i++) {
-        {
       int readin;
     
-      dio_get_sint8(&din, &readin);
-      real_packet->resources[i] = readin;
-    }
-      }
-    }
-  }
-  if (BV_ISSET(fields, 10)) {
-    {
-      int readin;
-    
       dio_get_uint8(&din, &readin);
       real_packet->road_trade_incr = readin;
     }
   }
-  if (BV_ISSET(fields, 11)) {
+  if (BV_ISSET(fields, 10)) {
     {
       int readin;
     
@@ -25363,7 +25339,7 @@
       real_packet->road_time = readin;
     }
   }
-  if (BV_ISSET(fields, 12)) {
+  if (BV_ISSET(fields, 11)) {
     {
       int readin;
     
@@ -25371,7 +25347,7 @@
       real_packet->irrigation_result = readin;
     }
   }
-  if (BV_ISSET(fields, 13)) {
+  if (BV_ISSET(fields, 12)) {
     {
       int readin;
     
@@ -25379,7 +25355,7 @@
       real_packet->irrigation_food_incr = readin;
     }
   }
-  if (BV_ISSET(fields, 14)) {
+  if (BV_ISSET(fields, 13)) {
     {
       int readin;
     
@@ -25387,7 +25363,7 @@
       real_packet->irrigation_time = readin;
     }
   }
-  if (BV_ISSET(fields, 15)) {
+  if (BV_ISSET(fields, 14)) {
     {
       int readin;
     
@@ -25395,7 +25371,7 @@
       real_packet->mining_result = readin;
     }
   }
-  if (BV_ISSET(fields, 16)) {
+  if (BV_ISSET(fields, 15)) {
     {
       int readin;
     
@@ -25403,7 +25379,7 @@
       real_packet->mining_shield_incr = readin;
     }
   }
-  if (BV_ISSET(fields, 17)) {
+  if (BV_ISSET(fields, 16)) {
     {
       int readin;
     
@@ -25411,7 +25387,7 @@
       real_packet->mining_time = readin;
     }
   }
-  if (BV_ISSET(fields, 18)) {
+  if (BV_ISSET(fields, 17)) {
     {
       int readin;
     
@@ -25419,7 +25395,7 @@
       real_packet->transform_result = readin;
     }
   }
-  if (BV_ISSET(fields, 19)) {
+  if (BV_ISSET(fields, 18)) {
     {
       int readin;
     
@@ -25427,7 +25403,7 @@
       real_packet->transform_time = readin;
     }
   }
-  if (BV_ISSET(fields, 20)) {
+  if (BV_ISSET(fields, 19)) {
     {
       int readin;
     
@@ -25435,7 +25411,7 @@
       real_packet->rail_time = readin;
     }
   }
-  if (BV_ISSET(fields, 21)) {
+  if (BV_ISSET(fields, 20)) {
     {
       int readin;
     
@@ -25443,7 +25419,7 @@
       real_packet->airbase_time = readin;
     }
   }
-  if (BV_ISSET(fields, 22)) {
+  if (BV_ISSET(fields, 21)) {
     {
       int readin;
     
@@ -25451,7 +25427,7 @@
       real_packet->fortress_time = readin;
     }
   }
-  if (BV_ISSET(fields, 23)) {
+  if (BV_ISSET(fields, 22)) {
     {
       int readin;
     
@@ -25459,7 +25435,7 @@
       real_packet->clean_pollution_time = readin;
     }
   }
-  if (BV_ISSET(fields, 24)) {
+  if (BV_ISSET(fields, 23)) {
     {
       int readin;
     
@@ -25467,7 +25443,7 @@
       real_packet->clean_fallout_time = readin;
     }
   }
-  if (BV_ISSET(fields, 25)) {
+  if (BV_ISSET(fields, 24)) {
     dio_get_string(&din, real_packet->helptext, sizeof(real_packet->helptext));
   }
 
@@ -25548,90 +25524,74 @@
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 7);}
 
-  differ = (old->num_resources != real_packet->num_resources);
+  differ = !BV_ARE_EQUAL(old->resources, real_packet->resources);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 8);}
 
-
-    {
-      differ = (old->num_resources != real_packet->num_resources);
-      if(!differ) {
-        int i;
-        for (i = 0; i < real_packet->num_resources; i++) {
-          if (old->resources[i] != real_packet->resources[i]) {
-            differ = TRUE;
-            break;
-          }
-        }
-      }
-    }
+  differ = (old->road_trade_incr != real_packet->road_trade_incr);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 9);}
 
-  differ = (old->road_trade_incr != real_packet->road_trade_incr);
+  differ = (old->road_time != real_packet->road_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 10);}
 
-  differ = (old->road_time != real_packet->road_time);
+  differ = (old->irrigation_result != real_packet->irrigation_result);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 11);}
 
-  differ = (old->irrigation_result != real_packet->irrigation_result);
+  differ = (old->irrigation_food_incr != real_packet->irrigation_food_incr);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 12);}
 
-  differ = (old->irrigation_food_incr != real_packet->irrigation_food_incr);
+  differ = (old->irrigation_time != real_packet->irrigation_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 13);}
 
-  differ = (old->irrigation_time != real_packet->irrigation_time);
+  differ = (old->mining_result != real_packet->mining_result);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 14);}
 
-  differ = (old->mining_result != real_packet->mining_result);
+  differ = (old->mining_shield_incr != real_packet->mining_shield_incr);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 15);}
 
-  differ = (old->mining_shield_incr != real_packet->mining_shield_incr);
+  differ = (old->mining_time != real_packet->mining_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 16);}
 
-  differ = (old->mining_time != real_packet->mining_time);
+  differ = (old->transform_result != real_packet->transform_result);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 17);}
 
-  differ = (old->transform_result != real_packet->transform_result);
+  differ = (old->transform_time != real_packet->transform_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 18);}
 
-  differ = (old->transform_time != real_packet->transform_time);
+  differ = (old->rail_time != real_packet->rail_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 19);}
 
-  differ = (old->rail_time != real_packet->rail_time);
+  differ = (old->airbase_time != real_packet->airbase_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 20);}
 
-  differ = (old->airbase_time != real_packet->airbase_time);
+  differ = (old->fortress_time != real_packet->fortress_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 21);}
 
-  differ = (old->fortress_time != real_packet->fortress_time);
+  differ = (old->clean_pollution_time != real_packet->clean_pollution_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 22);}
 
-  differ = (old->clean_pollution_time != real_packet->clean_pollution_time);
+  differ = (old->clean_fallout_time != real_packet->clean_fallout_time);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 23);}
 
-  differ = (old->clean_fallout_time != real_packet->clean_fallout_time);
+  differ = (strcmp(old->helptext, real_packet->helptext) != 0);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 24);}
 
-  differ = (strcmp(old->helptext, real_packet->helptext) != 0);
-  if(differ) {different++;}
-  if(differ) {BV_SET(fields, 25);}
-
   if (different == 0 && !force_send_of_unchanged) {
     return 0;
   }
@@ -25670,64 +25630,54 @@
     } 
   }
   if (BV_ISSET(fields, 8)) {
-    dio_put_uint8(&dout, real_packet->num_resources);
+  DIO_BV_PUT(&dout, packet->resources);
   }
   if (BV_ISSET(fields, 9)) {
-  
-    {
-      int i;
-
-      for (i = 0; i < real_packet->num_resources; i++) {
-        dio_put_sint8(&dout, real_packet->resources[i]);
-      }
-    } 
-  }
-  if (BV_ISSET(fields, 10)) {
     dio_put_uint8(&dout, real_packet->road_trade_incr);
   }
-  if (BV_ISSET(fields, 11)) {
+  if (BV_ISSET(fields, 10)) {
     dio_put_uint8(&dout, real_packet->road_time);
   }
-  if (BV_ISSET(fields, 12)) {
+  if (BV_ISSET(fields, 11)) {
     dio_put_sint16(&dout, real_packet->irrigation_result);
   }
-  if (BV_ISSET(fields, 13)) {
+  if (BV_ISSET(fields, 12)) {
     dio_put_uint8(&dout, real_packet->irrigation_food_incr);
   }
-  if (BV_ISSET(fields, 14)) {
+  if (BV_ISSET(fields, 13)) {
     dio_put_uint8(&dout, real_packet->irrigation_time);
   }
-  if (BV_ISSET(fields, 15)) {
+  if (BV_ISSET(fields, 14)) {
     dio_put_sint16(&dout, real_packet->mining_result);
   }
-  if (BV_ISSET(fields, 16)) {
+  if (BV_ISSET(fields, 15)) {
     dio_put_uint8(&dout, real_packet->mining_shield_incr);
   }
-  if (BV_ISSET(fields, 17)) {
+  if (BV_ISSET(fields, 16)) {
     dio_put_uint8(&dout, real_packet->mining_time);
   }
-  if (BV_ISSET(fields, 18)) {
+  if (BV_ISSET(fields, 17)) {
     dio_put_sint16(&dout, real_packet->transform_result);
   }
-  if (BV_ISSET(fields, 19)) {
+  if (BV_ISSET(fields, 18)) {
     dio_put_uint8(&dout, real_packet->transform_time);
   }
-  if (BV_ISSET(fields, 20)) {
+  if (BV_ISSET(fields, 19)) {
     dio_put_uint8(&dout, real_packet->rail_time);
   }
-  if (BV_ISSET(fields, 21)) {
+  if (BV_ISSET(fields, 20)) {
     dio_put_uint8(&dout, real_packet->airbase_time);
   }
-  if (BV_ISSET(fields, 22)) {
+  if (BV_ISSET(fields, 21)) {
     dio_put_uint8(&dout, real_packet->fortress_time);
   }
-  if (BV_ISSET(fields, 23)) {
+  if (BV_ISSET(fields, 22)) {
     dio_put_uint8(&dout, real_packet->clean_pollution_time);
   }
-  if (BV_ISSET(fields, 24)) {
+  if (BV_ISSET(fields, 23)) {
     dio_put_uint8(&dout, real_packet->clean_fallout_time);
   }
-  if (BV_ISSET(fields, 25)) {
+  if (BV_ISSET(fields, 24)) {
     dio_put_string(&dout, real_packet->helptext);
   }
 
Index: common/packets_gen.h
===================================================================
--- common/packets_gen.h        (revision 11381)
+++ common/packets_gen.h        (working copy)
@@ -928,8 +928,7 @@
   int movement_cost;
   int defense_bonus;
   int output[O_MAX];
-  int num_resources;
-  Resource_type_id resources[MAX_NUM_RESOURCES];
+  bv_resources resources;
   int road_trade_incr;
   int road_time;
   Terrain_type_id irrigation_result;
Index: manual/civmanual.c
===================================================================
--- manual/civmanual.c  (revision 11381)
+++ manual/civmanual.c  (working copy)
@@ -225,8 +225,6 @@
       fprintf(doc, _("<th>Transform to</th>"));
       fprintf(doc, "</tr>\n");
       terrain_type_iterate(pterrain) {
-       const struct resource **r;
-
        if (pterrain->defense_bonus == 0) {
          /* Must be a disabled piece of terrain */
          continue;
@@ -240,10 +238,12 @@
                pterrain->output[O_TRADE]);
 
        fprintf (doc, "<td>");
-       for (r = pterrain->resources; *r; r++) {
-         fprintf (doc, "%s%s%s %s", IMAGE_BEGIN,
-                  (*r)->graphic_str, IMAGE_END, (*r)->name);
-       }
+       resource_type_iterate(r) {
+         if (terrain_has_resource(pterrain, r)) {
+           fprintf(doc, "%s%s%s %s", IMAGE_BEGIN,
+                   r->graphic_str, IMAGE_END, r->name);
+         }
+       } resource_type_iterate_end;
        fprintf (doc, "</td>");
 
        fprintf(doc, "<td>%d</td>\n", pterrain->movement_cost);
Index: client/gui-gtk-2.0/helpdlg.c
===================================================================
--- client/gui-gtk-2.0/helpdlg.c        (revision 11381)
+++ client/gui-gtk-2.0/helpdlg.c        (working copy)
@@ -1028,7 +1028,8 @@
 static void help_update_terrain(const struct help_item *pitem,
                                char *title, struct terrain *pterrain)
 {
-  char *buf = &long_buffer[0];
+  char buf[10240];
+  int rcount = 0;
 
   create_help_page(HELP_TERRAIN);
 
@@ -1046,16 +1047,17 @@
     gtk_label_set_text(GTK_LABEL(help_tlabel[0][4]), buf);
 
     buf[0] = '\0';
-    if (pterrain->resources[0]) {
-      const struct resource **r;
-
-      for (r = pterrain->resources; *r; r++) {
-       sprintf (buf + strlen (buf), " %s,", _((*r)->name));
+    resource_type_iterate(r) {
+      if (terrain_has_resource(pterrain, r)) {
+       cat_snprintf(buf, sizeof(buf), " %s,", r->name);
+       rcount++;
       }
-      buf[strlen (buf) - 1] = '.';
+    } resource_type_iterate_end;
+    if (rcount > 0) {
+      cat_snprintf(buf, sizeof(buf), ".");
     } else {
       /* TRANS: (none) as in "Resources: (none)". */
-      sprintf (buf + strlen (buf), _("(none)"));
+      cat_snprintf(buf, sizeof(buf), _("(none)"));
     }
     gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), buf);
 
Index: client/packhand.c
===================================================================
--- client/packhand.c   (revision 11381)
+++ client/packhand.c   (working copy)
@@ -2307,7 +2307,6 @@
 void handle_ruleset_terrain(struct packet_ruleset_terrain *p)
 {
   struct terrain *pterrain = get_terrain(p->id);
-  int j;
 
   if (!pterrain) {
     freelog(LOG_ERROR,
@@ -2327,16 +2326,7 @@
     pterrain->output[o] = p->output[o];
   } output_type_iterate_end;
 
-  pterrain->resources = fc_calloc(p->num_resources + 1,
-                                 sizeof(*pterrain->resources));
-  for (j = 0; j < p->num_resources; j++) {
-    pterrain->resources[j] = get_resource(p->resources[j]);
-    if (!pterrain->resources[j]) {
-      freelog(LOG_ERROR, "Mismatched resource for terrain %s.",
-             pterrain->name_orig);
-    }
-  }
-  pterrain->resources[p->num_resources] = NULL;
+  pterrain->resources = p->resources;
 
   pterrain->road_time = p->road_time;
   pterrain->road_trade_incr = p->road_trade_incr;
Index: client/tilespec.c
===================================================================
--- client/tilespec.c   (revision 11382)
+++ client/tilespec.c   (working copy)
@@ -4028,7 +4028,8 @@
   case LAYER_SPECIAL1:
     if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
       if (draw_specials) {
-       if (ptile->resource) {
+       if (ptile->resource
+           && terrain_has_resource(ptile->terrain, ptile->resource)) {
          ADD_SPRITE_SIMPLE(t->sprites.resource[ptile->resource->index]);
        }
       }

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