Requirements are elementary rules of Freeciv ruleset. Each of them represents a statement that can be true, false, or sometimes undefined (that can be resolved to either true or false in specific cases). Requirements typically are bundled into requirement vectors that represent complex statements that are true if and only if each requirement inside them is true. These vectors are found in effects, action enablers, disaster causes and other elements of the ruleset.
Elements of a requirement
type
The property of something that is checked, e.g. wether we are interested in a number of units on a tile, an extra on it, its owning player etc.
Requirement type | Supported Ranges | Explanation |
---|---|---|
"None" | (default) | |
"Special" i Replaced by "Extra" in 2.6 |
??? | |
"Building" | World, Alliance, Team, Player, Continent, Traderoute, City, Local | |
"Gov" | Player | |
"MinSize" | Traderoute, City | Minimum size of a city required. |
"Nation" | World, Alliance, Team, Player | |
"OutputType" | Local | |
"Tech" | World, Alliance, Team, Player | |
"Terrain" | Local, Adjacent, CAdjacent, Traderoute, City | |
"UnitClass" | Local | Effect Types "Veteran_Combat" and "Defend_Bonus" only. "Defend_Bonus" evaluates Attacker only. |
"UnitFlag" | Local | Effect Types "Veteran_Combat" and "Defend_Bonus" only. "Defend_Bonus" evaluates Attacker only. |
"UnitType" | Local | Effect Types "Veteran_Combat" and "Defend_Bonus" only. "Defend_Bonus" evaluates Attacker only. |
Requirement type | Supported Ranges i New in 2.? |
Explanation |
"CityTile" | Local, Adjacent, CAdjacent | |
"MinYear" | World | |
"TerrainAlter" | Local | |
"UnitClassFlag" | Local | Effect Types "Veteran_Combat" and "Defend_Bonus" only. "Defend_Bonus" evaluates Attacker only. |
Requirement type | Supported Ranges i New in 2.2 |
Explanation |
"Base" i Replaced by "Extra" in 2.6 |
??? | |
"AI" | Player | AI player difficulty level |
"TerrainClass" | Local, Adjacent, CAdjacent, Traderoute, City | Either "Land" or "Oceanic" |
Requirement type | Supported Ranges i New in 2.5 |
Explanation |
"Road" i Replaced by "Extra" in 2.6 |
??? | |
"Resource" i Replaced by "Extra" in 3.0 |
Local, Adjacent, CAdjacent, Traderoute, City | |
"Nationality" | Traderoute, City | |
RoadFlag" | Local, Adjacent, CAdjacent, Traderoute, City | |
"TechFlag" | World, Alliance, Team, Player | |
"TerrainFlag" | Local, Adjacent, CAdjacent, Traderoute, City | |
Requirement type | Supported Ranges i New in 2.6 |
Explanation |
"Achievement" | World, Alliance, Team, Player | |
"BaseFlag" | Local, Adjacent, CAdjacent, Traderoute, City | |
"DiplRel" | World, Alliance, Team, Player, Local | |
"Extra" | Local, Adjacent, CAdjacent, Traderoute, City | |
"ExtraFlag" | Local, Adjacent, CAdjacent, Traderoute, City | |
"MinCulture" | World, Alliance, Team, Player, Traderoute, City | |
"MinMoveFrags" | Local | Minimum move fragments the unit must have left |
"Style" | Player | Civilization Style |
"UnitState" | Local | "Transported", "OnLivableTile",
i New in 3.0: "Transporting", "OnDomesticTile", "HasHomeCity" |
Requirement type | Supported Ranges i New in 3.0 |
Explanation |
"Action" | Local | "Attack", "Bombard"... |
"BuildingGenus" | Local | "Wonder", "SmallWonder", "Improvement", "Special" |
"MinTechs" | Player, Team, Alliance, World | |
Requirement type | Supported Ranges i ??? |
Explanation |
"Age" | Local, City | Unknown |
"Specialist" | Local | Unknown |
"Topology" | World | Unknown: overhead, isometric, hexagonal, isohex? |
range
Kind of target we are checking, e.g. a player, a city, any city trading with a city, or the whole world. Ranges are limited for specific requirement types and targets (e.g. you can't get DiplRel of a continent).
Requirement range | Explanation |
---|---|
"None" | |
"Adjacent" | |
"City" | |
"Continent" | |
"Local" | |
"Player" | |
"World" | |
i New in 2.4 | |
"CAdjacent" | Cardinally Adjacent omits diagnally adjacent tiles on tetragonal maps |
i New in 2.6 | |
"Alliance" | Players allied with the target one including him/herself, not necessarily with each other. |
"Team" | |
"Traderoute" | Tests both ends of the route. |
name
Not necessarily something you would call "name", but a value of the property for the target.
Flags
- survives
- The requirement is met even after the target (must be a wonder) is destroyed.
- quiet
- Do not generate automatic help for the requirement.
- present (2.6+)/negated (2.5)
- Wether the requirement value should be negated.
Example of a requirement vector
Consider a definition of an effect:
[effect_hydro_plant] name = "Output_Bonus" value = 25 reqs = {"type", "name", "range" "Building", "Factory", "City" "Building", "Hydro Plant", "City" "OutputType", "Shield", "Local" }
Here reqs
is the requirement vector for the effect. First line lists the elements of the requirement, and all the other lines list their values in the same order. The flags are optional and can be omitted from the header line if they are never set in the vector ("survives", "quiet" and (2.5 only) "negated" default to FALSE and "present" (2.6 and later) to TRUE) and from any value line where they are default. The requirements tell that the effect of increasing output on 25 % happens in cities where there are buildings Factory and HydroPlant for Shield-type output.
Programming realization
Requirements are described in common/requirements.[ch]. Each requirement is stored in struct requirement
which contains, among others, struct universal source
field in which the effect's type and name are stored; possible types are listed in specenum universals_n (VUT_...)
(in common/fc_types.h) while possible ranges are in req_range (REQ_RANGE_...)
. The main function that calculates a requirement (redirecting necessary information to a function appropriate for specific requirement type and range) is
is_req_active(const struct player *target_player, // Player and upper ranges
const struct player *other_player, // To whom calculate DiplRel
const struct city *target_city, // City and base of Traderoute range
const struct impr_type *target_building,
const struct tile *target_tile,// All the rest is referred as "Local" range
const struct unit *target_unit,
const struct unit_type *target_unittype,// If not specified, calculated from target_unit
const struct output_type *target_output,// shields/sienxe/etc.
const struct specialist *target_specialist,
const struct action *target_action,//new in 3.0
const struct requirement *req,// The requirement itself
const enum req_problem_type prob_type)// Wether resolve uncertainity to true or false
This function is usually called through are_reqs_active()
that has the same parameters except being applied to a vector of requirements that are tested in order (it had been suggested to reorder them for optimisation but that is not actually done).
When and how the parameters are filled can be seen from certain places of the code; there are multiple wrapping functions to call this one that mask irrelevant parameters. For World-range effects, all parameters are NULLs.