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

Reply via email to