? gen_capab.diff
Index: common/registry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/registry.c,v
retrieving revision 1.34
diff -u -r1.34 registry.c
--- common/registry.c 2001/08/13 15:13:35 1.34
+++ common/registry.c 2001/12/05 17:33:14
@@ -717,13 +717,13 @@
if(!(pentry=section_file_lookup_internal(my_section_file, buf))) {
freelog(LOG_FATAL, "sectionfile %s doesn't contain a '%s' entry",
secfile_filename(my_section_file), buf);
- exit(1);
+ exit(0);
}
if(!pentry->svalue) {
freelog(LOG_FATAL, "sectionfile %s entry '%s' doesn't contain a string",
secfile_filename(my_section_file), buf);
- exit(1);
+ exit(0);
}
return pentry->svalue;
Index: common/unittype.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.c,v
retrieving revision 1.8
diff -u -r1.8 unittype.c
--- common/unittype.c 2001/09/15 15:31:25 1.8
+++ common/unittype.c 2001/12/05 17:33:15
@@ -30,11 +30,14 @@
#include "unittype.h"
-struct unit_type unit_types[U_LAST];
-/* the unit_types array is now setup in:
- server/ruleset.c (for the server)
- client/packhand.c (for the client)
+/**
+ * The unit_types array is now setup in:
+ *
+ * - \e server - server/ruleset.c
+ *
- \e client - client/packhand.c
+ *
*/
+struct unit_type unit_types[U_LAST];
static const char *move_type_names[] = {
"Land", "Sea", "Heli", "Air"
@@ -63,6 +66,67 @@
"Sea"
};
+/*
+ * unit type capability categories
+ * This section contains string declarators for flag values
+ * and categories.
+ */
+static const char *utype_category_names[] = {
+ "capab_move",
+ "capab_class",
+ "capab_combat",
+ "capab_build",
+ "capab_improve",
+ "capab_intel"
+};
+
+/*
+ * This structure is used to maintain a mapping between
+ * configured flag name and the
+ */
+struct _named_bit_value
+{
+ const char *name; /* name of flag */
+ unsigned value; /* flag value */
+};
+
+/*
+ * unit type capability flag values
+ */
+static struct _named_bit_value utype_flag_values[]= {
+ { "move_land", CAPAB_MOVE_LAND },
+ { "move_sea", CAPAB_MOVE_SEA },
+ { "move_hover", CAPAB_MOVE_HOVER },
+ { "move_ranged", CAPAB_MOVE_RANGED },
+ { "move_orbit", CAPAB_MOVE_ORBIT },
+ { "pikemen", CAPAB_PIKEMEN },
+ { "horse", CAPAB_HORSE },
+ { "attack_melee", CAPAB_ATTACK_MELEE },
+ { "attack_bombard", CAPAB_ATTACK_BOMBARD },
+ { "attack_bomb", CAPAB_ATTACK_BOMB },
+ { "attack_nuke", CAPAB_ATTACK_NUKE },
+ { "transport_any", CAPAB_TRANSPORT_ANY },
+ { "build_city", CAPAB_BUILD_CITY },
+ { "build_fortress", CAPAB_BUILD_FORTRESS },
+ { "build_airbase", CAPAB_BUILD_AIRBASE },
+ { "build_colony", CAPAB_BUILD_COLONY },
+ { "improve_irrigate", CAPAB_IMPROVE_IRRIGATE },
+ { "improve_mine", CAPAB_IMPROVE_MINE },
+ { "improve_road", CAPAB_IMPROVE_ROAD },
+ { "improve_rail", CAPAB_IMPROVE_RAIL },
+ { "intel_embassy", CAPAB_INTEL_EMBASSY },
+ { "intel_bribe", CAPAB_INTEL_BRIBE },
+ { "intel_sabotage", CAPAB_INTEL_SABOTAGE },
+ { "intel_steal", CAPAB_INTEL_STEAL },
+ { "intel_incite", CAPAB_INTEL_INCITE },
+ { "intel_move", CAPAB_INTEL_MOVE },
+ { "intel_poison", CAPAB_INTEL_MOVE },
+
+ /* ... */
+
+ { 0, 0 }
+};
+
/**************************************************************************
Returns 1 if the unit_type "exists" in this game, 0 otherwise.
A unit_type doesn't exist if one of:
@@ -276,15 +340,15 @@
if(count==1) {
char *and_str = _(" and ");
- astr_minsize(&astr,astr.n+strlen(and_str));
- strcat(astr.str, and_str);
+ astr_minsize(&astr,astr.n+strlen(and_str));
+ strcat(astr.str, and_str);
}
else {
- if(count != 0) {
- astr_minsize(&astr,astr.n+strlen(", "));
- strcat(astr.str,", ");
- }
- else return astr.str;
+ if(count != 0) {
+ astr_minsize(&astr,astr.n+strlen(", "));
+ strcat(astr.str,", ");
+ }
+ else return astr.str;
}
}
}
@@ -438,7 +502,7 @@
return 0;
while(unit_type_exists((id = unit_types[id].obsoleted_by)))
if (can_player_build_unit_direct(p, id))
- return 0;
+ return 0;
return 1;
}
@@ -453,7 +517,7 @@
return 0;
while(unit_type_exists((id = unit_types[id].obsoleted_by)))
if (can_player_build_unit_direct(p, id))
- return 0;
+ return 0;
return 1;
}
@@ -562,3 +626,88 @@
return U_LAST;
}
+
+/*@
+ * @brief Get the name of a flag category.
+ *
+ * This method is used to get the configurable name
+ * of a unit type. This is called from the server
+ * ruleset configuration to assign flag values to
+ * categories.
+ *
+ * @param category The category identifier.
+ * @return A pointer to the string containing the category
+ * name.
+ */
+const char *
+utype_get_category_name( enum utype_category category )
+{
+ /* make sure we have a null string on invalid an category. */
+ if( ( category < 0 ) || ( category >= CAT_LAST ) ) {
+ return 0;
+ }
+ return utype_category_names[ category ];
+}
+
+/*@
+ * @brief Get the value of a flag.
+ *
+ * This method returns the value of a flag based on the
+ * text string given. This is used during ruleset parsing
+ * to assign values to category flags.
+ */
+unsigned
+utype_get_flag_value( const char *flag )
+{
+ unsigned i = 0;
+
+ while( utype_flag_values[ i ].name )
+ {
+ if( !strcmp( flag, utype_flag_values[ i ].name ) )
+ {
+ return utype_flag_values[ i ].value;
+ }
+ i++;
+ }
+ return 0;
+}
+
+/*@
+ * @brief Add a caapbility to a unit.
+ *
+ * Set a flag in the capability vector of the specified
+ * unit.
+ *
+ * @param punit A pointer to the unit to test.
+ * @param cat The category id of the capab to add.
+ * @param capab The capab to add.
+ */
+void
+utype_add_capab( struct unit_type *ptype,
+ enum utype_category cat,
+ unsigned capab )
+{
+ ptype->flag_set[ cat ] |= capab;
+}
+
+/*@
+ * @brief Test a unit for subscription to a flag.
+ *
+ * This method is used to test a unit for subscription to
+ * a subset of flags set. A category is specified to lookup
+ * the flag set. Only flags from one category may be tested
+ * per call.
+ *
+ * @param punit A pointer to the unit to test.
+ * @param cat The category id of the flag set to test.
+ * @param capab An integer representing the flags to test
+ * for.
+ * @return 1 if the flags are set, 0 otherwise.
+ */
+int
+utype_has_capab( struct unit_type *ptype,
+ enum utype_category cat,
+ unsigned capab )
+{
+ return ptype->flag_set[ cat ] & capab;
+}
Index: common/unittype.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.h,v
retrieving revision 1.7
diff -u -r1.7 unittype.h
--- common/unittype.h 2001/09/15 15:31:25 1.7
+++ common/unittype.h 2001/12/05 17:33:15
@@ -143,18 +143,128 @@
L_LAST
};
+/*@
+ * @brief Enumeration of category ids.
+ *
+ * The unit_category_id enumeration describes the identifiers
+ * of the set of categories used to describe properties of a
+ * unit. Each category defines a subset of identifiable properties
+ * of a unit. Each category is represented by a 32 bit field
+ * that uses bit flags to represent values for each possible
+ * value.
+ *
+ * Under this model, a unit essentially subscribes to properties
+ * in each category. For example, a combat unit can both bomb
+ * and perform tactical strikes. A hover craft should be able to
+ * travel over both land and sea.
+ *
+ * This model gains three benifits over the previous information
+ * model. First, it localizes all basic unit informaiton into a
+ * single attribute. Secondly, it provides a much more extensible
+ * model for defining unit capabilities, and finally, with the
+ * extended bit space, it allows individual definition of
+ * capabilities instead of grouping capabilties as before.
+ *
+ * Values of these categories are actually defined as bits, not
+ * as enums that are shifted to bit values.
+ *
+ * The integer value of the unit_category id corresponds to the
+ * index of an array in the unit_flags value.
+ */
+enum utype_category
+{
+ CAT_MOVE, /*@< Movement */
+ CAT_CLASS, /*@< Basic unit type */
+ CAT_ATTACK, /*@< Combat capabilities */
+ CAT_TRANSPORT, /*@< Transport capabilities */
+ CAT_BUILD, /*@< Construction */
+ CAT_IMPROVE, /*@< Improvements */
+ CAT_INTEL, /*@< Diplomacy and spying */
+ CAT_LAST /*@< Unused */
+};
+
+/*@
+ * @brief Specification of the unit_flags type.
+ *
+ * The unit_flags type is an array of unsigned integers. Each
+ * index of the array corresponds to a unit_category and each
+ * value within the array contains a 32 bit flag field.
+ */
+typedef unsigned utype_flags[ CAT_LAST ];
+
+/* movement class flags */
+#define CAPAB_MOVE_LAND 0x01
+#define CAPAB_MOVE_SEA 0x02
+#define CAPAB_MOVE_HOVER 0x03
+#define CAPAB_MOVE_RANGED 0x07
+#define CAPAB_MOVE_ORBIT 0x0f
+
+/* combat class flags */
+#define CAPAB_PIKEMEN 0x01
+#define CAPAB_HORSE 0x02
+
+/* combat operations flags */
+#define CAPAB_ATTACK_MELEE 0x01
+#define CAPAB_ATTACK_BOMBARD 0x02
+#define CAPAB_ATTACK_BOMB 0x04
+#define CAPAB_ATTACK_NUKE 0x08
+
+/* transport options */
+#define CAPAB_TRANSPORT_ANY 0x01
+
+/* construction operation flags */
+#define CAPAB_BUILD_CITY 0x01
+#define CAPAB_BUILD_FORTRESS 0x02
+#define CAPAB_BUILD_AIRBASE 0x04
+#define CAPAB_BUILD_COLONY 0x08
+
+/* improvment operation flags */
+#define CAPAB_IMPROVE_IRRIGATE 0x01
+#define CAPAB_IMPROVE_MINE 0x02
+#define CAPAB_IMPROVE_ROAD 0x04
+#define CAPAB_IMPROVE_RAIL 0x08
+
+/* inteligence operations */
+#define CAPAB_INTEL_EMBASSY 0x01
+#define CAPAB_INTEL_BRIBE 0x02
+#define CAPAB_INTEL_SABOTAGE 0x04
+#define CAPAB_INTEL_STEAL 0x08
+#define CAPAB_INTEL_INCITE 0x10
+#define CAPAB_INTEL_MOVE 0x20
+#define CAPAB_INTEL_POISON 0x01
+
+/*@
+ * @brief Type information for a unit.
+ *
+ * The unit_type structure encapsulates information about
+ * a type of unit. There is one unit_type instance for \e type
+ * of unit (as opposed to per unit).
+ *
+ * @todo Need better descriptions of some fields.
+ */
struct unit_type {
- char name[MAX_LEN_NAME];
- char name_orig[MAX_LEN_NAME]; /* untranslated */
+ char name[MAX_LEN_NAME]; /*@< Name of unit */
+ char name_orig[MAX_LEN_NAME]; /*@< Untranslated - what is this? */
+
+ /* graphics information */
char graphic_str[MAX_LEN_NAME];
char graphic_alt[MAX_LEN_NAME];
struct Sprite *sprite;
+
enum unit_move_type move_type;
int build_cost;
- int pop_cost; /* number of workers the unit contains (e.g., settlers, engineers)*/
- int attack_strength;
- int defense_strength;
- int move_rate;
+
+ /*@
+ * Number of workers the unit contains (e.g., settlers, engineers)
+ *
+ * @todo This needs a more thorough explanation.
+ */
+ int pop_cost;
+
+ int attack_strength; /*@< Attack rating of unit. */
+ int defense_strength; /*@< Defense rating of unit. */
+ int move_rate; /*@< Number of moves. */
+
int tech_requirement;
int vision_range;
int transport_capacity;
@@ -163,22 +273,28 @@
int obsoleted_by;
int fuel;
- unsigned int flags;
+ unsigned int flags; /*@< Obsolete */
unsigned int roles;
+
+ utype_flags flag_set; /*@< Set of flags for unit type */
- int happy_cost; /* unhappy people in home city */
- int shield_cost; /* normal upkeep cost */
- int food_cost; /* settler food cost */
- int gold_cost; /* gold upkeep (n/a now, maybe later) */
+ int happy_cost; /*@< Unhappy people in home city */
+ int shield_cost; /*@< Normal upkeep cost */
+ int food_cost; /*@< Unit food cost */
+ int gold_cost; /*@< Gold upkeep (n/a now, maybe later) */
- int paratroopers_range; /* only valid for F_PARATROOPERS */
+ int paratroopers_range; /*@< only valid for F_PARATROOPERS */
int paratroopers_mr_req;
int paratroopers_mr_sub;
+ /*@
+ * The helptext field defines in game help for the unit.
+ * This is displayed in the online help browser when the unit
+ * is queried for help.
+ */
char *helptext;
};
-
extern struct unit_type unit_types[U_LAST];
int unit_type_exists(Unit_Type_id id);
@@ -227,5 +343,81 @@
int num_role_units(int role);
Unit_Type_id get_role_unit(int role, int index);
Unit_Type_id best_role_unit(struct city *pcity, int role);
+
+/* extended unit flag test */
+/* configuration interface */
+const char *utype_get_category_name( enum utype_category );
+unsigned utype_get_flag_value( const char * );
+
+/* caapbility interface interface */
+void utype_add_capab( struct unit_type *,
+ enum utype_category,
+ unsigned );
+int utype_has_caapb( struct unit_type *,
+ enum utype_category,
+ unsigned );
+
+/*@
+ * @def CAPAB_MOVE_LAND
+ * Units with this property can travel over land.
+ *
+ * @def CAPAB_MOVE_SEA
+ * Units with this property can travel over sea.
+ *
+ * @def CAPAB_MOVE_HOVER
+ * Hovering units can move over land or sea without restriction.
+ *
+ * @def CAPAB_MOVE_RANGED
+ * Units with a ranged travel capability have a limited
+ * distance they can move in one turn. Units with this capability
+ * typically have a fuel parameter associated with them.
+ *
+ * @def CAPAB_MOVE_ORBIT
+ * Units capable of orbital travel can go to any tile on
+ * the map in a single turn.
+ *
+ * @def CAPAB_PIKEMEN
+ * @def CAPAB_HORSE
+ *
+ * @def CAPAB_ATTACK_MELEE
+ * Units with this flag set can participate in melee combat.
+ * If a unit does not define this flag, then it cannot perform
+ * melee attack (e.g. settlers). Units without this flag will
+ * be captured without a fight if they are attacked in a melee.
+ *
+ * @def CAPAB_ATTACK_BOMBARD
+ * Units with this flag set are capable of bombarding enemy
+ * units. A bombard attack allows the attacker to attack from
+ * some range. Enemy units passing within the bombard range
+ * of a bombard unit shall be bombarded without cost to the
+ * bombarding unit.
+ *
+ * @def CAPAB_ATTACK_BOMB
+ * @def CAPAB_ATTACK_NUKE
+ *
+ * @def CAPAB_TRANSPORT_ANY
+ * Units with this flag set are capable of transport
+ * any land units.
+ *
+ * @def CAPAB_BUILD_CITY
+ * @def CAPAB_BUILD_FORTRESS
+ * @def CAPAB_BUILD_AIRBASE
+ * @def CAPAB_IMPROVE_IRRIGATE
+ * @def CAPAB_IMPROVE_MINE
+ * @def CAPAB_IMPROVE_ROAD
+ * @def CAPAB_IMPROVE_RAIL
+ * @def CAPAB_INTEL_EMBASSY
+ *
+ * @def CAPAB_INTEL_BRIBE
+ * This capability allows a unit to bribe enemy units, bringing
+ * them onto the bribing units side.
+ * @todo Should this be an attack?
+ *
+ * @def CAOAB_INTEL_SABOTAGE
+ * @def CAPAB_INTEL_STEAL
+ * @def CAPAB_INTEL_INCITE
+ * @def CAPAB_INTEL_MOVE
+ * @def CAPAB_INTEL_POISON
+ */
#endif /* FC__UNITTYPE_H */
Index: data/default/units.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/units.ruleset,v
retrieving revision 1.28
diff -u -r1.28 units.ruleset
--- data/default/units.ruleset 2001/08/29 16:11:50 1.28
+++ data/default/units.ruleset 2001/12/05 17:33:16
@@ -82,6 +82,8 @@
uk_food = 1
uk_gold = 0
flags = "Settlers", "NonMil", "Airbase", "AddToCity", "Cities"
+capab_move = "move_land"
+capab_build = "build_city", "build_airbase", "build_fortress", "build_colony"
roles = ""
helptext = _("\
Settlers are one of the key units in the game. They can be used to\
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.82
diff -u -r1.82 ruleset.c
--- server/ruleset.c 2001/10/26 07:33:23 1.82
+++ server/ruleset.c 2001/12/05 17:33:19
@@ -598,11 +598,15 @@
{
char *datafile_options;
struct unit_type *u;
- int i, j, ival, nval;
+ int i, j, k, ival, nval;
int max_hp, max_firepower;
char *sval, **slist, **sec;
const char *filename = secfile_filename(file);
+ int n_flags; /* number of flags */
+ char **flags; /* list of names for flags */
+ const char *name; /* used to get category names */
+
datafile_options =
check_ruleset_capabilities(file, "+1.9", filename);
@@ -613,6 +617,7 @@
game.firepower_factor =
secfile_lookup_int_default(file, 1, "units_adjust.firepower_factor");
+ /* get the names of all the unit sections in the ruleset */
sec = secfile_get_secnames_prefix(file, "unit_", &nval);
/* Tech requirement is used to flag removed unit_types, which
@@ -733,6 +738,53 @@
}
}
free(slist);
+
+ /* extended category/flag selection */
+ /* this works a little differently than the rest of the ruleset
+ * parsing stuff. it iterates thru all possible category id's
+ * and looks up the name of the specifc category for each unit.
+ */
+ for( i = 0; i < game.num_unit_types; i++ ) {
+ u = &unit_types[ i ];
+
+ /* set the flag set to empty for all categories */
+ memset( u->flag_set, 0, sizeof( utype_flags ) );
+
+ /*
+ * iterate thru known categories and get the config
+ * directive for each.
+ */
+ for( j = 0; j < CAT_LAST; j++ ) {
+ /* get the category name */
+ name = utype_get_category_name( j );
+
+ /*
+ * get the configuration value for the category.
+ * this lookup is for ..
+ * this should return a vector of flags
+ */
+ n_flags = 0;
+ flags = secfile_lookup_str_vec( file,
+ &n_flags,
+ "%s.%s",
+ sec[ i ],
+ name );
+ if( !flags ) {
+ /* this is okay. flags haven't been defined */
+ continue;
+ }
+ else {
+ for( k = 0; k < n_flags; k++ ) {
+ unsigned flag = utype_get_flag_value( flags[ k ] );
+ utype_add_capab(u, j, flag );
+ }
+
+ /* free the flag list */
+ free( flags );
+ }
+
+ }
+ }
}
/* roles */