<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