Author: jtn Date: Mon Apr 21 15:47:08 2014 New Revision: 24785 URL: http://svn.gna.org/viewcvs/freeciv?rev=24785&view=rev Log: Requirements with Adjacent/CAdjacent ranges always check the centre tile too. Fixed the TerrainClass, Extra, TerrainFlag, BaseFlag, RoadFlag, CityTile, and MaxUnitsOnTile requirements. Also, TerrainClass/TerrainFlag City-ranged requirements now cope with unknown terrain within the city radius.
See gna bug #21470. Modified: trunk/common/base.c trunk/common/extras.c trunk/common/map.h trunk/common/metaknowledge.c trunk/common/requirements.c trunk/common/requirements.h trunk/common/road.c trunk/common/terrain.c Modified: trunk/common/base.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/base.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/base.c (original) +++ trunk/common/base.c Mon Apr 21 15:47:08 2014 @@ -38,7 +38,7 @@ /**************************************************************************** Returns TRUE iff any cardinally adjacent tile contains a base with - the given flag + the given flag (does not check ptile itself) ****************************************************************************/ bool is_base_flag_card_near(const struct tile *ptile, enum base_flag_id flag) { @@ -55,6 +55,7 @@ /**************************************************************************** Returns TRUE iff any adjacent tile contains a base with the given flag + (does not check ptile itself) ****************************************************************************/ bool is_base_flag_near_tile(const struct tile *ptile, enum base_flag_id flag) { Modified: trunk/common/extras.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/extras.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/extras.c (original) +++ trunk/common/extras.c Mon Apr 21 15:47:08 2014 @@ -314,6 +314,7 @@ /**************************************************************************** Is there extra of the given type cardinally near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_extra_card_near(const struct tile *ptile, const struct extra_type *pextra) { @@ -328,6 +329,7 @@ /**************************************************************************** Is there extra of the given type near tile? + (Does not check ptile itself.) ****************************************************************************/ bool is_extra_near_tile(const struct tile *ptile, const struct extra_type *pextra) { Modified: trunk/common/map.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/map.h?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/map.h (original) +++ trunk/common/map.h Mon Apr 21 15:47:08 2014 @@ -376,10 +376,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) \ @@ -468,8 +468,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 \ @@ -480,12 +481,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) @@ -493,18 +496,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) @@ -525,10 +533,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: trunk/common/metaknowledge.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/metaknowledge.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/metaknowledge.c (original) +++ trunk/common/metaknowledge.c Mon Apr 21 15:47:08 2014 @@ -130,6 +130,9 @@ case REQ_RANGE_LOCAL: return can_player_see_hypotetic_units_at(pow_player, target_tile); case REQ_RANGE_CADJACENT: + if (!can_player_see_hypotetic_units_at(pow_player, target_tile)) { + return FALSE; + } cardinal_adjc_iterate(target_tile, adjc_tile) { if (!can_player_see_hypotetic_units_at(pow_player, adjc_tile)) { return FALSE; @@ -138,6 +141,9 @@ return TRUE; case REQ_RANGE_ADJACENT: + if (!can_player_see_hypotetic_units_at(pow_player, target_tile)) { + return FALSE; + } adjc_iterate(target_tile, adjc_tile) { if (!can_player_see_hypotetic_units_at(pow_player, adjc_tile)) { return FALSE; Modified: trunk/common/requirements.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/requirements.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/requirements.c (original) +++ trunk/common/requirements.c Mon Apr 21 15:47:08 2014 @@ -1078,6 +1078,9 @@ if (!target_tile) { return TRI_MAYBE; } + if (unit_list_size(target_tile->units) <= maxUnits) { + return TRI_YES; + } cardinal_adjc_iterate(target_tile, adjc_tile) { if (unit_list_size(adjc_tile->units) <= maxUnits) { return TRI_YES; @@ -1087,6 +1090,9 @@ case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; + } + if (unit_list_size(target_tile->units) <= maxUnits) { + return TRI_YES; } adjc_iterate(target_tile, adjc_tile) { if (unit_list_size(adjc_tile->units) <= maxUnits) { @@ -1127,12 +1133,14 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_extra_card_near(target_tile, pextra)); + return BOOL_TO_TRISTATE(tile_has_extra(target_tile, pextra) + || is_extra_card_near(target_tile, pextra)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_extra_near_tile(target_tile, pextra)); + return BOOL_TO_TRISTATE(tile_has_extra(target_tile, pextra) + || is_extra_near_tile(target_tile, pextra)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; @@ -1280,19 +1288,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; @@ -1321,28 +1333,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 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; @@ -1380,12 +1402,14 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_base_flag_card_near(target_tile, baseflag)); + return BOOL_TO_TRISTATE(tile_has_base_flag(target_tile, baseflag) + || is_base_flag_card_near(target_tile, baseflag)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_base_flag_near_tile(target_tile, baseflag)); + return BOOL_TO_TRISTATE(tile_has_base_flag(target_tile, baseflag) + || is_base_flag_near_tile(target_tile, baseflag)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; @@ -1430,12 +1454,14 @@ if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_road_flag_card_near(target_tile, roadflag)); + return BOOL_TO_TRISTATE(tile_has_road_flag(target_tile, roadflag) + || is_road_flag_card_near(target_tile, roadflag)); case REQ_RANGE_ADJACENT: if (!target_tile) { return TRI_MAYBE; } - return BOOL_TO_TRISTATE(is_road_flag_near_tile(target_tile, roadflag)); + return BOOL_TO_TRISTATE(tile_has_road_flag(target_tile, roadflag) + || is_road_flag_near_tile(target_tile, roadflag)); case REQ_RANGE_CITY: if (!target_city) { return TRI_MAYBE; @@ -1712,6 +1738,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; @@ -1720,6 +1749,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; Modified: trunk/common/requirements.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/requirements.h?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/requirements.h (original) +++ trunk/common/requirements.h Mon Apr 21 15:47:08 2014 @@ -27,7 +27,13 @@ /* 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, for example: + * - 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); + * - World contains Alliance contains Player (a requirement we ourselves + * have is also within Alliance range). */ #define SPECENUM_NAME req_range #define SPECENUM_VALUE0 REQ_RANGE_LOCAL #define SPECENUM_VALUE0NAME "Local" Modified: trunk/common/road.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/road.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/road.c (original) +++ trunk/common/road.c Mon Apr 21 15:47:08 2014 @@ -436,7 +436,7 @@ /**************************************************************************** Returns TRUE iff any cardinally adjacent tile contains a road with - the given flag + the given flag (does not check ptile itself). ****************************************************************************/ bool is_road_flag_card_near(const struct tile *ptile, enum road_flag_id flag) { @@ -453,6 +453,7 @@ /**************************************************************************** Returns TRUE iff any adjacent tile contains a road with the given flag + (does not check ptile itself). ****************************************************************************/ bool is_road_flag_near_tile(const struct tile *ptile, enum road_flag_id flag) { Modified: trunk/common/terrain.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/terrain.c?rev=24785&r1=24784&r2=24785&view=diff ============================================================================== --- trunk/common/terrain.c (original) +++ trunk/common/terrain.c Mon Apr 21 15:47:08 2014 @@ -537,7 +537,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) @@ -554,7 +554,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) @@ -571,7 +572,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, @@ -682,6 +684,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) @@ -701,6 +704,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) @@ -719,7 +723,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