<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40426 >
2008/8/9 Marko Lindqvist <[EMAIL PROTECTED]>:
>
> This patch adds separate requirement type for military bases.
- Corrected comment
- ML
diff -Nurd -X.diff_ignore freeciv/common/base.c freeciv/common/base.c
--- freeciv/common/base.c 2008-08-12 16:29:26.000000000 +0300
+++ freeciv/common/base.c 2008-08-12 16:42:53.000000000 +0300
@@ -98,6 +98,37 @@
}
/**************************************************************************
+ Returns base type matching rule name or NULL if there is no base type
+ with such name.
+**************************************************************************/
+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,
diff -Nurd -X.diff_ignore freeciv/common/base.h freeciv/common/base.h
--- freeciv/common/base.h 2008-08-12 16:21:02.000000000 +0300
+++ freeciv/common/base.h 2008-08-12 16:42:02.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-08-12 16:21:02.000000000 +0300
+++ freeciv/common/fc_types.h 2008-08-12 16:42:02.000000000 +0300
@@ -229,6 +229,7 @@
struct terrain *terrain;
struct unit_class *uclass;
struct unit_type *utype;
+ struct base_type *base;
enum ai_level ai_level;
int minsize;
@@ -259,6 +260,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-08-12 16:21:02.000000000 +0300
+++ freeciv/common/requirements.c 2008-08-12 16:42:02.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-08-12 16:21:02.000000000 +0300
+++ freeciv/data/civ1/effects.ruleset 2008-08-12 16:42:02.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-08-12 16:21:02.000000000 +0300
+++ freeciv/data/civ2/effects.ruleset 2008-08-12 16:42:02.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-08-12 16:21:02.000000000
+0300
+++ freeciv/data/default/effects.ruleset 2008-08-12 16:42: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-08-12 16:21:02.000000000 +0300
+++ freeciv/server/ruleset.c 2008-08-12 16:42:02.000000000 +0300
@@ -3773,6 +3773,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
[email protected]
https://mail.gna.org/listinfo/freeciv-dev