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

Reply via email to