<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40426 >

 This patch adds separate requirement type for military bases.


 - ML

diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c       2008-06-18 19:42:34.000000000 +0300
+++ freeciv/common/base.c       2008-08-09 14:42:35.000000000 +0300
@@ -100,6 +100,35 @@
 /**************************************************************************
   Can unit build base to given tile?
 **************************************************************************/
+struct base_type *find_base_type_by_rule_name(const char *name)
+{
+  const char *qs = Qn_(name);
+
+  base_type_iterate(pbase) {
+    if (0 == mystrcasecmp(base_rule_name(pbase), qs)) {
+      return pbase;
+    }
+  } base_type_iterate_end;
+  return NULL;
+}
+
+/****************************************************************************
+  Is there base of the given type near tile?
+****************************************************************************/
+bool is_base_near_tile(const struct tile *ptile, const struct base_type *pbase)
+{
+  adjc_iterate(ptile, adjc_tile) {
+    if (tile_has_base(adjc_tile, pbase)) {
+      return TRUE;
+    }
+  } adjc_iterate_end;
+
+  return FALSE;
+}
+
+/**************************************************************************
+  Can unit build base to given tile?
+**************************************************************************/
 bool can_build_base(const struct unit *punit, const struct base_type *pbase,
                     const struct tile *ptile)
 {
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h       2008-06-18 19:42:34.000000000 +0300
+++ freeciv/common/base.h       2008-08-09 14:42:40.000000000 +0300
@@ -76,6 +76,10 @@
 const char *base_rule_name(const struct base_type *pbase);
 const char *base_name_translation(struct base_type *pbase);
 
+struct base_type *find_base_type_by_rule_name(const char *name);
+
+bool is_base_near_tile(const struct tile *ptile, const struct base_type 
*pbase);
+
 /* Functions to operate on a base flag. */
 bool base_has_flag(const struct base_type *pbase, enum base_flag_id flag);
 bool base_has_flag_for_utype(const struct base_type *pbase,
diff -Nurd -X.diff_ignore freeciv/common/fc_types.h freeciv/common/fc_types.h
--- freeciv/common/fc_types.h   2008-06-24 01:37:50.000000000 +0300
+++ freeciv/common/fc_types.h   2008-08-09 14:33:36.000000000 +0300
@@ -236,6 +236,7 @@
   struct terrain *terrain;
   struct unit_class *uclass;
   struct unit_type *utype;
+  struct base_type *base;
 
   enum ai_level ai_level;
   int minsize;
@@ -266,6 +267,7 @@
   VUT_MINSIZE,         /* Minimum size: at city range means city size */
   VUT_AI_LEVEL,                /* AI level of the player */
   VUT_TERRAINCLASS,    /* More generic terrain type, currently "Land" or 
"Ocean" */
+  VUT_BASE,
   VUT_LAST
 };
 
diff -Nurd -X.diff_ignore freeciv/common/requirements.c 
freeciv/common/requirements.c
--- freeciv/common/requirements.c       2008-07-03 21:02:57.000000000 +0300
+++ freeciv/common/requirements.c       2008-08-09 14:44:49.000000000 +0300
@@ -46,7 +46,8 @@
   "Specialist",
   "MinSize",
   "AI",
-  "TerrainClass"
+  "TerrainClass",
+  "Base"
 };
 
 /* Names of requirement ranges. These must correspond to enum req_range in
@@ -200,6 +201,12 @@
       return source;
     }
     break;
+  case VUT_BASE:
+    source.value.base = find_base_type_by_rule_name(value);
+    if (source.value.base != NULL) {
+      return source;
+    }
+    break;
   case VUT_LAST:
   default:
     break;
@@ -291,6 +298,9 @@
   case VUT_TERRAINCLASS:
     source.value.terrainclass = value;
     return source;
+   case VUT_BASE:
+    source.value.base = base_by_number(value);
+    return source;
   case VUT_LAST:
     return source;
   default:
@@ -352,6 +362,8 @@
     return source->value.ai_level;
   case VUT_TERRAINCLASS:
     return source->value.terrainclass;
+  case VUT_BASE:
+    return base_number(source->value.base);
   case VUT_LAST:
   default:
     break;
@@ -396,6 +408,7 @@
     case VUT_OTYPE:
     case VUT_SPECIALIST:
     case VUT_TERRAINCLASS:
+    case VUT_BASE:
       req.range = REQ_RANGE_LOCAL;
       break;
     case VUT_MINSIZE:
@@ -419,6 +432,7 @@
   case VUT_SPECIAL:
   case VUT_TERRAIN:
   case VUT_TERRAINCLASS:
+  case VUT_BASE:
     invalid = (req.range != REQ_RANGE_LOCAL
               && req.range != REQ_RANGE_ADJACENT);
     break;
@@ -798,6 +812,35 @@
 }
 
 /****************************************************************************
+  Is there a source base type within range of the target?
+****************************************************************************/
+static bool is_base_type_in_range(const struct tile *target_tile,
+                                  enum req_range range, bool survives,
+                                  struct base_type *pbase)
+{
+  if (!target_tile) {
+    return FALSE;
+  }
+
+  switch (range) {
+  case REQ_RANGE_LOCAL:
+    /* The requirement is filled if the tile has base of requested type. */
+    return tile_has_base(target_tile, pbase);
+  case REQ_RANGE_ADJACENT:
+    return is_base_near_tile(target_tile, pbase);
+  case REQ_RANGE_CITY:
+  case REQ_RANGE_CONTINENT:
+  case REQ_RANGE_PLAYER:
+  case REQ_RANGE_WORLD:
+  case REQ_RANGE_LAST:
+    break;
+  }
+
+  assert(0);
+  return FALSE;
+}
+
+/****************************************************************************
   Is there a nation within range of the target?
 ****************************************************************************/
 static bool is_nation_in_range(const struct player *target_player,
@@ -1001,6 +1044,11 @@
                                      req->range, req->survives,
                                      req->source.value.terrainclass);
     break;
+  case VUT_BASE:
+    eval = is_base_type_in_range(target_tile,
+                                 req->range, req->survives,
+                                 req->source.value.base);
+    break;
   case VUT_LAST:
     assert(0);
     return FALSE;
@@ -1078,7 +1126,8 @@
   case VUT_SPECIAL:
   case VUT_TERRAIN:
   case VUT_TERRAINCLASS:
-    /* Terrains and specials aren't really unchanging; in fact they're
+  case VUT_BASE:
+    /* Terrains, specials and bases aren't really unchanging; in fact they're
      * practically guaranteed to change.  We return TRUE here for historical
      * reasons and so that the AI doesn't get confused (since the AI
      * doesn't know how to meet special and terrain requirements). */
@@ -1133,6 +1182,8 @@
     return psource1->value.ai_level == psource2->value.ai_level;
   case VUT_TERRAINCLASS:
     return psource1->value.terrainclass == psource2->value.terrainclass;
+  case VUT_BASE:
+    return psource1->value.base == psource2->value.base;
   case VUT_LAST:
     break;
   }
@@ -1190,6 +1241,8 @@
     return ai_level_name(psource->value.ai_level);
   case VUT_TERRAINCLASS:
     return terrain_class_rule_name(psource->value.terrainclass);
+  case VUT_BASE:
+    return base_rule_name(psource->value.base);
   case VUT_LAST:
   default:
     assert(0);
@@ -1267,6 +1320,11 @@
     cat_snprintf(buf, bufsz, _("%s terrain"),
                  terrain_class_name_translation(psource->value.terrainclass));
     break;
+  case VUT_BASE:
+    /* TRANS: "Fortress base" */
+    cat_snprintf(buf, bufsz, _("%s base"),
+                 base_name_translation(psource->value.base));
+    break;
   case VUT_LAST:
     assert(0);
     break;
diff -Nurd -X.diff_ignore freeciv/data/civ1/effects.ruleset 
freeciv/data/civ1/effects.ruleset
--- freeciv/data/civ1/effects.ruleset   2008-06-13 21:51:11.000000000 +0300
+++ freeciv/data/civ1/effects.ruleset   2008-08-09 14:43:40.000000000 +0300
@@ -197,7 +197,7 @@
 value  = 100
 reqs   =
     { "type", "name", "range"
-      "Special", "Fortress", "Tile"
+      "Base", "Fortress", "Tile"
       "UnitClass", "Land", "Local"
     }
 
diff -Nurd -X.diff_ignore freeciv/data/civ2/effects.ruleset 
freeciv/data/civ2/effects.ruleset
--- freeciv/data/civ2/effects.ruleset   2008-06-12 18:40:37.000000000 +0300
+++ freeciv/data/civ2/effects.ruleset   2008-08-09 14:43:28.000000000 +0300
@@ -314,7 +314,7 @@
 value  = 100
 reqs   =
     { "type", "name", "range"
-      "Special", "Fortress", "Tile"
+      "Base", "Fortress", "Tile"
       "UnitClass", "Land", "Local"
     }
 
diff -Nurd -X.diff_ignore freeciv/data/default/effects.ruleset 
freeciv/data/default/effects.ruleset
--- freeciv/data/default/effects.ruleset        2008-06-26 21:53:51.000000000 
+0300
+++ freeciv/data/default/effects.ruleset        2008-08-09 14:43:02.000000000 
+0300
@@ -77,7 +77,7 @@
 value   = 8
 reqs    =
     { "type", "name", "range"
-      "Special", "Fortress", "tile"
+      "Base", "Fortress", "tile"
       "Tech", "Invention", "player"
     }
 
@@ -88,7 +88,7 @@
 value  = 100
 reqs   =
     { "type", "name", "range"
-      "Special", "Fortress", "Tile"
+      "Base", "Fortress", "Tile"
       "UnitClass", "Land", "Local"
     }
 
diff -Nurd -X.diff_ignore freeciv/server/ruleset.c freeciv/server/ruleset.c
--- freeciv/server/ruleset.c    2008-07-25 00:24:19.000000000 +0300
+++ freeciv/server/ruleset.c    2008-08-09 17:50:15.000000000 +0300
@@ -3744,6 +3744,7 @@
 
      case VUT_SPECIAL:
      case VUT_TERRAIN:
+     case VUT_BASE:
        /* There can be only up to max_tiles requirements of these types */
        if (max_tiles != 1 && rc > max_tiles) {
          freelog(LOG_ERROR,
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to