Author: jtn Date: Mon Apr 21 15:56:18 2014 New Revision: 24786 URL: http://svn.gna.org/viewcvs/freeciv?rev=24786&view=rev Log: Requirements with Adjacent/CAdjacent ranges always check the centre tile too. Fixed the TerrainClass, Base, Road, TerrainFlag, and CityTile requirements. Also, TerrainClass/TerrainFlag City-ranged requirements now cope with unknown terrain within the city radius.
See gna bug #21470. Modified: branches/S2_5/common/base.c branches/S2_5/common/map.h branches/S2_5/common/requirements.c branches/S2_5/common/requirements.h branches/S2_5/common/road.c branches/S2_5/common/terrain.c Modified: branches/S2_5/common/base.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/base.c?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/base.c (original) +++ branches/S2_5/common/base.c Mon Apr 21 15:56:18 2014 @@ -128,6 +128,7 @@ /**************************************************************************** Is there base of the given type cardinally near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_base_card_near(const struct tile *ptile, const struct base_type *pbase) { @@ -142,6 +143,7 @@ /**************************************************************************** Is there base of the given type near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_base_near_tile(const struct tile *ptile, const struct base_type *pbase) { Modified: branches/S2_5/common/map.h URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/map.h?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/map.h (original) +++ branches/S2_5/common/map.h Mon Apr 21 15:56:18 2014 @@ -377,10 +377,10 @@ extern struct terrain_misc terrain_control; -/* This iterates outwards from the starting point. Every tile within max_dist - * will show up exactly once, in an outward (based on real map distance) - * order. The returned values are always real and are normalized. The - * starting position must be normal. +/* This iterates outwards from the starting point. Every tile within max_dist + * (including the starting tile) will show up exactly once, in an outward + * (based on real map distance) order. The returned values are always real + * and are normalized. The starting position must be normal. * * See also iterate_outward() */ #define iterate_outward_dxy(start_tile, max_dist, _tile, _x, _y) \ @@ -469,8 +469,9 @@ } square_dxy_iterate_end; \ } -/* Iterate through all map positions adjacent to the given center map - * position, with normalization. The order of positions is unspecified. */ +/* Iterate itr_tile through all map tiles adjacent to the given center map + * position, with normalization. Does not include the center position. + * The order of positions is unspecified. */ #define adjc_iterate(center_tile, itr_tile) \ { \ /* Written as a wrapper to adjc_dir_iterate since it's the cleanest and \ @@ -481,12 +482,14 @@ } adjc_dir_iterate_end; \ } +/* As adjc_iterate() but also set direction8 iterator variable dir_itr */ #define adjc_dir_iterate(center_tile, itr_tile, dir_itr) \ adjc_dirlist_iterate(center_tile, itr_tile, dir_itr, \ map.valid_dirs, map.num_valid_dirs) #define adjc_dir_iterate_end adjc_dirlist_iterate_end +/* Only set direction8 dir_itr (not tile) */ #define adjc_dir_base_iterate(center_tile, dir_itr) \ adjc_dirlist_base_iterate(center_tile, dir_itr, \ map.valid_dirs, map.num_valid_dirs) @@ -494,18 +497,23 @@ #define adjc_dir_base_iterate_end \ adjc_dirlist_base_iterate_end +/* Iterate itr_tile through all map tiles cardinally adjacent to the given + * center map position, with normalization. Does not include the center + * position. The order of positions is unspecified. */ #define cardinal_adjc_iterate(center_tile, itr_tile) \ adjc_dirlist_iterate(center_tile, itr_tile, _dir_itr, \ map.cardinal_dirs, map.num_cardinal_dirs) #define cardinal_adjc_iterate_end adjc_dirlist_iterate_end +/* As cardinal_adjc_iterate but also set direction8 variable dir_itr */ #define cardinal_adjc_dir_iterate(center_tile, itr_tile, dir_itr) \ adjc_dirlist_iterate(center_tile, itr_tile, dir_itr, \ map.cardinal_dirs, map.num_cardinal_dirs) #define cardinal_adjc_dir_iterate_end adjc_dirlist_iterate_end +/* Only set direction8 dir_itr (not tile) */ #define cardinal_adjc_dir_base_iterate(center_tile, dir_itr) \ adjc_dirlist_base_iterate(center_tile, dir_itr, \ map.cardinal_dirs, map.num_cardinal_dirs) @@ -526,10 +534,11 @@ /* Iterate through all tiles adjacent to a tile using the given list of * directions. _dir is the directional value, (center_x, center_y) is - * the center tile (which must be normalized). + * the center tile (which must be normalized). The center tile is not + * included in the iteration. * - * This macro should not be used directly. Instead, use adjc_dir_iterate - * or cartesian_adjacent_iterate. */ + * This macro should not be used directly. Instead, use adjc_iterate, + * cardinal_adjc_iterate, or related iterators. */ #define adjc_dirlist_iterate(center_tile, _tile, _dir, \ dirlist, dircount) \ { \ Modified: branches/S2_5/common/requirements.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/requirements.c?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/requirements.c (original) +++ branches/S2_5/common/requirements.c Mon Apr 21 15:56:18 2014 @@ -1046,19 +1046,23 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_terrain_class_card_near(target_tile, pclass)); + return BOOL_TO_TRISTATE(terrain_type_terrain_class(tile_terrain(target_tile)) == pclass + || is_terrain_class_card_near(target_tile, pclass)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_terrain_class_near_tile(target_tile, pclass)); + return BOOL_TO_TRISTATE(terrain_type_terrain_class(tile_terrain(target_tile)) == pclass + || is_terrain_class_near_tile(target_tile, pclass)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; } city_tile_iterate(city_map_radius_sq_get(target_city), city_tile(target_city), ptile) { - if (terrain_type_terrain_class(tile_terrain(ptile)) == pclass) { + const struct terrain *pterrain = tile_terrain(ptile); + if (pterrain != T_UNKNOWN + && terrain_type_terrain_class(pterrain) == pclass) { return TRI_YES; } } city_tile_iterate_end; @@ -1086,28 +1090,38 @@ { switch (range) { case REQ_RANGE_LOCAL: - /* The requirement is filled if the tile has the terrain with correct flag. */ + /* The requirement is fulfilled if the tile has a terrain with + * correct flag. */ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(terrain_has_flag(tile_terrain(target_tile), terrflag)); + return BOOL_TO_TRISTATE(terrain_has_flag(tile_terrain(target_tile), + terrflag)); case REQ_RANGE_CADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_terrain_flag_card_near(target_tile, terrflag)); + return BOOL_TO_TRISTATE(terrain_has_flag(tile_terrain(target_tile), + terrflag) + || is_terrain_flag_card_near(target_tile, + terrflag)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_terrain_flag_near_tile(target_tile, terrflag)); + return BOOL_TO_TRISTATE(terrain_has_flag(tile_terrain(target_tile), + terrflag) + || is_terrain_flag_near_tile(target_tile, + terrflag)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; } city_tile_iterate(city_map_radius_sq_get(target_city), city_tile(target_city), ptile) { - if (terrain_has_flag(tile_terrain(ptile), terrflag)) { + const struct terrain *pterrain = tile_terrain(ptile); + if (pterrain != T_UNKNOWN + && terrain_has_flag(pterrain, terrflag)) { return TRI_YES; } } city_tile_iterate_end; @@ -1144,12 +1158,14 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_base_card_near(target_tile, pbase)); + return BOOL_TO_TRISTATE(tile_has_base(target_tile, pbase) + || is_base_card_near(target_tile, pbase)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_base_near_tile(target_tile, pbase)); + return BOOL_TO_TRISTATE(tile_has_base(target_tile, pbase) + || is_base_near_tile(target_tile, pbase)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; @@ -1230,12 +1246,14 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_road_card_near(target_tile, proad)); + return BOOL_TO_TRISTATE(tile_has_road(target_tile, proad) + || is_road_card_near(target_tile, proad)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_road_near_tile(target_tile, proad)); + return BOOL_TO_TRISTATE(tile_has_road(target_tile, proad) + || is_road_near_tile(target_tile, proad)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; @@ -1452,6 +1470,9 @@ case REQ_RANGE_LOCAL: return BOOL_TO_TRISTATE(is_city_in_tile(target_tile, target_city)); case REQ_RANGE_CADJACENT: + if (is_city_in_tile(target_tile, target_city)) { + return TRI_YES; + } cardinal_adjc_iterate(target_tile, adjc_tile) { if (is_city_in_tile(adjc_tile, target_city)) { return TRI_YES; @@ -1460,6 +1481,9 @@ return TRI_NO; case REQ_RANGE_ADJACENT: + if (is_city_in_tile(target_tile, target_city)) { + return TRI_YES; + } adjc_iterate(target_tile, adjc_tile) { if (is_city_in_tile(adjc_tile, target_city)) { return TRI_YES; @@ -1636,10 +1660,10 @@ req->range, req->survives, req->source.value.base); break; - case VUT_ROAD: - eval = is_road_type_in_range(target_tile, target_city, - req->range, req->survives, - req->source.value.road); + case VUT_ROAD: + eval = is_road_type_in_range(target_tile, target_city, + req->range, req->survives, + req->source.value.road); break; case VUT_MINYEAR: eval = BOOL_TO_TRISTATE(game.info.year >= req->source.value.minyear); Modified: branches/S2_5/common/requirements.h URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/requirements.h?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/requirements.h (original) +++ branches/S2_5/common/requirements.h Mon Apr 21 15:56:18 2014 @@ -27,7 +27,11 @@ /* Range of requirements. * Used in the network protocol. * Order is important -- wider ranges should come later -- some code - * assumes a total order, or tests for e.g. >= REQ_RANGE_PLAYER. */ + * assumes a total order, or tests for e.g. >= REQ_RANGE_PLAYER. + * Ranges of similar types should be supersets: the set of Adjacent tiles + * contains the set of CAdjacent tiles, and both contain the center + * Local tile (a requirement on the local tile is also within Adjacent + * range). */ #define SPECENUM_NAME req_range #define SPECENUM_VALUE0 REQ_RANGE_LOCAL #define SPECENUM_VALUE0NAME "Local" Modified: branches/S2_5/common/road.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/road.c?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/road.c (original) +++ branches/S2_5/common/road.c Mon Apr 21 15:56:18 2014 @@ -366,6 +366,7 @@ /**************************************************************************** Is there road of the given type cardinally near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_road_card_near(const struct tile *ptile, const struct road_type *proad) { @@ -380,6 +381,7 @@ /**************************************************************************** Is there road of the given type near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_road_near_tile(const struct tile *ptile, const struct road_type *proad) { Modified: branches/S2_5/common/terrain.c URL: http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/terrain.c?rev=24786&r1=24785&r2=24786&view=diff ============================================================================== --- branches/S2_5/common/terrain.c (original) +++ branches/S2_5/common/terrain.c Mon Apr 21 15:56:18 2014 @@ -735,7 +735,7 @@ /**************************************************************************** Returns TRUE iff any cardinally adjacent tile contains terrain with the - given flag. + given flag (does not check ptile itself). ****************************************************************************/ bool is_terrain_flag_card_near(const struct tile *ptile, enum terrain_flag_id flag) @@ -752,7 +752,8 @@ } /**************************************************************************** - Returns TRUE iff any adjacent tile contains terrain with the given flag. + Returns TRUE iff any adjacent tile contains terrain with the given flag + (does not check ptile itself). ****************************************************************************/ bool is_terrain_flag_near_tile(const struct tile *ptile, enum terrain_flag_id flag) @@ -769,7 +770,8 @@ } /**************************************************************************** - Return the number of adjacent tiles that have terrain with the given flag. + Return the number of adjacent tiles that have terrain with the given flag + (not including ptile itself). ****************************************************************************/ int count_terrain_flag_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, @@ -918,6 +920,7 @@ /**************************************************************************** Is there terrain of the given class cardinally near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_terrain_class_card_near(const struct tile *ptile, enum terrain_class tclass) @@ -937,6 +940,7 @@ /**************************************************************************** Is there terrain of the given class near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_terrain_class_near_tile(const struct tile *ptile, enum terrain_class tclass) @@ -955,7 +959,8 @@ } /**************************************************************************** - Return the number of adjacent tiles that have given terrain class. + Return the number of adjacent tiles that have given terrain class + (not including ptile itself). ****************************************************************************/ int count_terrain_class_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits