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

S2_1 r13741
S2_2 r13742
trunk r13743

Here's the patch variant applied to S2_2 and trunk:

Index: server/settlers.c
===================================================================
--- server/settlers.c   (revision 13741)
+++ server/settlers.c   (working copy)
@@ -315,7 +315,7 @@
     if (ptile->city && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
       return -1;
     }
-    ptile->terrain = new_terrain;
+    tile_change_terrain(ptile, new_terrain);
     tile_clear_special(ptile, S_MINE);
     goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
     ptile->terrain = old_terrain;
@@ -379,7 +379,7 @@
     if (ptile->city && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
       return -1;
     }
-    ptile->terrain = new_terrain;
+    tile_change_terrain(ptile, new_terrain);
     tile_clear_special(ptile, S_IRRIGATION);
     tile_clear_special(ptile, S_FARMLAND);
     goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
@@ -443,16 +443,7 @@
     return -1;
   }
 
-  ptile->terrain = new_terrain;
-
-  if (new_terrain->mining_result != new_terrain) {
-    tile_clear_special(ptile, S_MINE);
-  }
-  if (new_terrain->irrigation_result != new_terrain) {
-    tile_clear_special(ptile, S_FARMLAND);
-    tile_clear_special(ptile, S_IRRIGATION);
-  }
-    
+  tile_change_terrain(ptile, new_terrain);
   goodness = city_tile_value(pcity, city_x, city_y, 0, 0);
 
   ptile->terrain = old_terrain;
Index: server/savegame.c
===================================================================
--- server/savegame.c   (revision 13741)
+++ server/savegame.c   (working copy)
@@ -848,6 +848,16 @@
        set_savegame_old_resource(&ptile->resource, ptile->terrain, ch, 1));
   }
 
+  /* after the resources are loaded, indicate those currently valid */
+  whole_map_iterate(ptile) {
+    if (NULL != ptile->terrain
+     && NULL != ptile->resource
+     && terrain_has_resource(ptile->terrain, ptile->resource)) {
+      /* cannot use set_special() for internal values */
+      BV_SET(ptile->special, S_RESOURCE_VALID);
+    }
+  } whole_map_iterate_end;
+
   /* Owner and ownership source are stored as plain numbers */
   if (has_capability("new_owner_map", savefile_options)) {
     int x, y;
Index: common/city.c
===================================================================
--- common/city.c       (revision 13741)
+++ common/city.c       (working copy)
@@ -688,30 +688,29 @@
                                int city_x, int city_y, bool is_celebrating,
                                Output_type_id otype)
 {
-  const struct terrain *pterrain = ptile->terrain;
   struct tile tile;
   int prod;
-  const struct output_type *output = &output_types[otype];
+  struct terrain *pterrain = tile_get_terrain(ptile);
 
   assert(otype >= 0 && otype < O_LAST);
 
-  if (ptile->terrain == T_UNKNOWN) {
+  if (T_UNKNOWN == pterrain) {
     /* Special case for the client.  The server doesn't allow unknown tiles
      * to be worked but we don't necessarily know what player is involved. */
     return 0;
   }
 
   prod = pterrain->output[otype];
-  if (ptile->resource) {
-    prod += ptile->resource->output[otype];
+  if (tile_resource_is_valid(ptile)) {
+    prod += tile_get_resource(ptile)->output[otype];
   }
 
   /* create dummy tile which has the city center bonuses. */
-  tile.terrain = tile_get_terrain(ptile);
+  tile.terrain = pterrain;
   tile.special = tile_get_special(ptile);
 
   if (pcity && is_city_center(city_x, city_y)
-      && ptile->terrain == pterrain->irrigation_result
+      && pterrain == pterrain->irrigation_result
       && terrain_control.may_irrigate) {
     /* The center tile is auto-irrigated. */
     tile_set_special(&tile, S_IRRIGATION);
@@ -752,6 +751,8 @@
   }
 
   if (pcity) {
+    const struct output_type *output = &output_types[otype];
+
     prod += get_city_tile_output_bonus(pcity, ptile, output,
                                       EFT_OUTPUT_ADD_TILE);
     if (prod > 0) {
Index: common/tile.c
===================================================================
--- common/tile.c       (revision 13741)
+++ common/tile.c       (working copy)
@@ -69,6 +69,14 @@
 void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
 {
   ptile->terrain = pterrain;
+  if (NULL != pterrain
+   && NULL != ptile->resource
+   && terrain_has_resource(pterrain, ptile->resource)) {
+    /* cannot use set_special() for internal values */
+    BV_SET(ptile->special, S_RESOURCE_VALID);
+  } else {
+    BV_CLR(ptile->special, S_RESOURCE_VALID);
+  }
 }
 
 /****************************************************************************
@@ -225,6 +233,14 @@
 void tile_set_resource(struct tile *ptile, struct resource *presource)
 {
   ptile->resource = presource;
+  if (NULL != ptile->terrain
+   && NULL != presource
+   && terrain_has_resource(ptile->terrain, presource)) {
+    /* cannot use set_special() for internal values */
+    BV_SET(ptile->special, S_RESOURCE_VALID);
+  } else {
+    BV_CLR(ptile->special, S_RESOURCE_VALID);
+  }
 }
 
 /****************************************************************************
@@ -408,7 +424,7 @@
   case S_RIVER:
   case S_AIRBASE:
   case S_FALLOUT:
-  case S_LAST:
+  default:
     break;
   }
 }
@@ -438,7 +454,7 @@
   case S_FARMLAND:
   case S_AIRBASE:
   case S_FALLOUT:
-  case S_LAST:
+  default:
     break;
   }
 }
@@ -593,12 +609,10 @@
 const char *tile_get_info_text(const struct tile *ptile, int linebreaks)
 {
   static char s[256];
-  int bufsz;
   bool pollution;
   bool lb = FALSE;
+  int bufsz = sizeof(s);
 
-  bufsz = sizeof(s);
-
   sz_strlcpy(s, terrain_name_translation(ptile->terrain));
   if (linebreaks & TILE_LB_TERRAIN_RIVER) {
     /* Linebreak needed before next text */
@@ -619,14 +633,15 @@
     lb = TRUE;
   }
 
-  if (ptile->resource) {
+  if (tile_resource_is_valid(ptile)) {
     if (lb) {
       sz_strlcat(s, "\n");
       lb = FALSE;
     } else {
       sz_strlcat(s, " ");
     }
-    cat_snprintf(s, sizeof(s), "(%s)", 
resource_name_translation(ptile->resource));
+    cat_snprintf(s, sizeof(s), "(%s)",
+                resource_name_translation(ptile->resource));
   }
   if (linebreaks & TILE_LB_RESOURCE_POLL) {
     /* New linebreak requested */
Index: common/tile.h
===================================================================
--- common/tile.h       (revision 13741)
+++ common/tile.h       (working copy)
@@ -29,14 +29,14 @@
   int x, y; /* Cartesian (map) coordinates of the tile. */
   int nat_x, nat_y; /* Native coordinates of the tile. */
   int index; /* Index coordinate of the tile. */
-  struct terrain *terrain; /* May be NULL for unknown tiles. */
+  Continent_id continent;
+  bv_player tile_known, tile_seen[V_COUNT];
   bv_special special;
   struct resource *resource; /* available resource, or NULL */
+  struct terrain *terrain; /* May be NULL for unknown tiles. */
   struct city *city;        /* city standing on the tile, NULL if none */
   struct unit_list *units;
-  bv_player tile_known, tile_seen[V_COUNT];
   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;
@@ -54,15 +54,28 @@
 /* Tile accessor functions. */
 struct player *tile_get_owner(const struct tile *ptile);
 void tile_set_owner(struct tile *ptile, struct player *pplayer);
+
 struct city *tile_get_city(const struct tile *ptile);
 void tile_set_city(struct tile *ptile, struct city *pcity);
+
 struct terrain *tile_get_terrain(const struct tile *ptile);
 void tile_set_terrain(struct tile *ptile, struct terrain *pterrain);
+
 bv_special tile_get_special(const struct tile *ptile);
 bool tile_has_special(const struct tile *ptile,
                      enum tile_special_type to_test_for);
 bool tile_has_any_specials(const struct tile *ptile);
 void tile_set_special(struct tile *ptile, enum tile_special_type spe);
+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)
+const struct resource *tile_get_resource(const struct tile *ptile);
+void tile_set_resource(struct tile *ptile, struct resource *presource);
+
+Continent_id tile_get_continent(const struct tile *ptile);
+void tile_set_continent(struct tile *ptile, Continent_id val);
+
 struct base_type *tile_get_base(const struct tile *ptile);
 void tile_add_base(struct tile *ptile, const struct base_type *pbase);
 void tile_remove_base(struct tile *ptile);
@@ -72,12 +85,7 @@
                                  enum base_flag_id flag);
 bool tile_has_native_base(const struct tile *ptile,
                           const struct unit_type *punittype);
-const struct resource *tile_get_resource(const struct tile *ptile);
-void tile_set_resource(struct tile *ptile, struct resource *presource);
-void tile_clear_special(struct tile *ptile, enum tile_special_type spe);
-void tile_clear_all_specials(struct tile *ptile);
-void tile_set_continent(struct tile *ptile, Continent_id val);
-Continent_id tile_get_continent(const struct tile *ptile);
+
 enum known_type tile_get_known(const struct tile *ptile,
                              const struct player *pplayer);
 
Index: common/terrain.c
===================================================================
--- common/terrain.c    (revision 13741)
+++ common/terrain.c    (working copy)
@@ -251,6 +251,27 @@
   return TER_LAST;
 }
 
+/****************************************************************************
+  Check for resource in terrain resources list.
+****************************************************************************/
+bool terrain_has_resource(const struct terrain *pterrain,
+                         const struct resource *presource)
+{
+  struct resource **r = pterrain->resources;
+
+  if (game.info.is_edit_mode) {
+    return TRUE;
+  }
+
+  while (NULL != *r) {
+    if (*r == presource) {
+      return TRUE;
+    }
+    r++;
+  }
+  return FALSE;
+}
+
 /**************************************************************************
   Return the first item of resources.
 **************************************************************************/
Index: common/terrain.h
===================================================================
--- common/terrain.h    (revision 13741)
+++ common/terrain.h    (working copy)
@@ -40,16 +40,20 @@
   S_FARMLAND,
   S_AIRBASE,
   S_FALLOUT,
-  S_LAST
+
+  /* internal values not saved */
+  S_LAST,
+  S_RESOURCE_VALID = S_LAST,
+
+  /* internal values not saved and never set */
+  S_LAST_PLUS,
+  S_PILLAGE_BASE = S_LAST_PLUS,
 };
 
-/* Special value for pillaging bases */
-#define S_PILLAGE_BASE (S_LAST + 1)
-
 /* S_LAST-terminated */
 extern enum tile_special_type infrastructure_specials[];
 
-BV_DEFINE(bv_special, S_LAST);
+BV_DEFINE(bv_special, S_LAST_PLUS);
 
 /* currently only used in edithand.c */
 #define tile_special_type_iterate(special)                                 \
@@ -236,6 +240,9 @@
 #define count_ocean_near_tile(ptile, cardinal_only, percentage)                
\
   count_terrain_flag_near_tile(ptile, cardinal_only, percentage, TER_OCEANIC)
 
+bool terrain_has_resource(const struct terrain *pterrain,
+                         const struct resource *presource);
+
 /* Functions to operate on a general terrain type. */
 bool is_terrain_near_tile(const struct tile *ptile,
                          const struct terrain *pterrain);
Index: client/packhand.c
===================================================================
--- client/packhand.c   (revision 13741)
+++ client/packhand.c   (working copy)
@@ -2030,7 +2030,6 @@
 {
   struct tile *ptile = map_pos_to_tile(packet->x, packet->y);
   enum known_type old_known = client_tile_get_known(ptile);
-  int old_resource;
   bool tile_changed = FALSE;
   bool known_changed = FALSE;
   enum tile_special_type spe;
@@ -2053,17 +2052,15 @@
     }
   }
 
-  if (ptile->resource) {
-    old_resource = resource_number(ptile->resource);
+  if (NULL != ptile->resource) {
+    tile_changed = (resource_number(ptile->resource) != packet->resource);
   } else {
-    old_resource = -1;
+    tile_changed = (-1 != packet->resource);
   }
 
-  if (old_resource != packet->resource) {
-    tile_changed = TRUE;
-  }
+  /* always called after setting terrain */
+  tile_set_resource(ptile, resource_by_number(packet->resource));
 
-  ptile->resource = resource_by_number(packet->resource);
   if (packet->owner == MAP_TILE_OWNER_NULL) {
     if (ptile->owner) {
       ptile->owner = NULL;
@@ -2098,7 +2095,9 @@
     case TILE_UNKNOWN:
       break;
     default:
-      freelog(LOG_NORMAL, "Unknown tile value %d.", packet->known);
+      freelog(LOG_ERROR,
+              "handle_tile_info() unknown tile value %d.",
+              packet->known);
       break;
     }
   }
Index: client/tilespec.c
===================================================================
--- client/tilespec.c   (revision 13741)
+++ client/tilespec.c   (working copy)
@@ -4352,8 +4352,8 @@
   case LAYER_SPECIAL1:
     if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
       if (draw_specials) {
-       if (ptile->resource) {
-         
ADD_SPRITE_SIMPLE(t->sprites.resource[resource_index(ptile->resource)]);
+       if (tile_resource_is_valid(ptile)) {
+         
ADD_SPRITE_SIMPLE(t->sprites.resource[resource_index(tile_get_resource(ptile))]);
        }
       }
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to