Feature #1183 ยป 0041-requirements.-ch-Improve-Coding-Style.patch
| common/requirements.c | ||
|---|---|---|
|
************************************************************************/
|
||
|
typedef enum req_item_found (*universal_found)(const struct requirement *,
|
||
|
const struct universal *);
|
||
|
static universal_found universal_found_function[VUT_COUNT] = {NULL};
|
||
|
static universal_found universal_found_function[VUT_COUNT] = {nullptr};
|
||
|
static
|
||
|
enum fc_tristate tri_req_present(const struct civ_map *nmap,
|
||
| ... | ... | |
|
const struct req_context *context,
|
||
|
const struct requirement *req)
|
||
|
{
|
||
|
if (TRI_YES != tri_req_present(nmap, context, NULL, req)) {
|
||
|
if (TRI_YES != tri_req_present(nmap, context, nullptr, req)) {
|
||
|
return REQUCH_NO;
|
||
|
}
|
||
|
return def;
|
||
| ... | ... | |
|
req_copy(&preq, req);
|
||
|
preq.range = REQ_RANGE_PLAYER;
|
||
|
if (TRI_YES != tri_req_present(nmap, context, NULL, &preq)) {
|
||
|
if (TRI_YES != tri_req_present(nmap, context, nullptr, &preq)) {
|
||
|
return REQ_RANGE_TEAM == req->range ? REQUCH_ACT : REQUCH_NO;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
fc_assert_ret_val(VUT_CITYTILE == req->source.kind, REQUCH_NO);
|
||
|
if (CITYT_CENTER == req->source.value.citytile
|
||
|
|| (CITYT_BORDERING_TCLASS_REGION != req->source.value.citytile
|
||
|
&& NULL != context->city && NULL != context->tile
|
||
|
&& NULL != city_tile(context->city)
|
||
|
&& context->city != nullptr && context->tile != nullptr
|
||
|
&& city_tile(context->city) != nullptr
|
||
|
&& are_tiles_in_range(city_tile(context->city), context->tile,
|
||
|
req->range))){
|
||
|
/* Cities don't move, and most reqs are present on city center */
|
||
| ... | ... | |
|
if (req->source.kind == VUT_IMPROVEMENT
|
||
|
&& improvement_obsolete(context->player, b, context->city)) {
|
||
|
/* FIXME: sometimes can unobsolete, but considering it
|
||
|
/* FIXME: Sometimes can unobsolete, but considering it
|
||
|
* may sometimes put the function on endless recursion */
|
||
|
return REQUCH_ACT; /* Mostly about techs */
|
||
|
}
|
||
| ... | ... | |
|
if (great_wonder_is_destroyed(b)
|
||
|
|| (!great_wonder_is_available(b)
|
||
|
&& (req->range <= REQ_RANGE_CITY && TRI_YES
|
||
|
== tri_req_present(nmap, context, NULL, req)))) {
|
||
|
== tri_req_present(nmap, context, nullptr, req)))) {
|
||
|
/* If the wonder stays somewhere, it may either remain there
|
||
|
* or be destroyed. If it is destroyed, it is nowhere. */
|
||
|
return REQUCH_SCRIPTS;
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Parse requirement type (kind) and value strings into a universal
|
||
|
structure. Passing in a NULL type is considered VUT_NONE (not an error).
|
||
|
structure. Passing in a nullptr type is considered VUT_NONE (not an error).
|
||
|
Pass this some values like "Building", "Factory".
|
||
|
FIXME: ensure that every caller checks error return!
|
||
|
FIXME: Ensure that every caller checks error return!
|
||
|
**************************************************************************/
|
||
|
struct universal universal_by_rule_name(const char *kind,
|
||
|
const char *value)
|
||
| ... | ... | |
|
static bool activity_is_valid_in_requirement(enum unit_activity act)
|
||
|
{
|
||
|
return unit_activity_is_valid(act)
|
||
|
&& act != ACTIVITY_SENTRY
|
||
|
&& act != ACTIVITY_GOTO
|
||
|
&& act != ACTIVITY_EXPLORE;
|
||
|
&& act != ACTIVITY_SENTRY
|
||
|
&& act != ACTIVITY_GOTO
|
||
|
&& act != ACTIVITY_EXPLORE;
|
||
|
}
|
||
|
/**********************************************************************//**
|
||
| ... | ... | |
|
return;
|
||
|
case VUT_ADVANCE:
|
||
|
source->value.advance = advance_by_rule_name(value);
|
||
|
if (source->value.advance != NULL) {
|
||
|
if (source->value.advance != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_GOVERNMENT:
|
||
|
source->value.govern = government_by_rule_name(value);
|
||
|
if (source->value.govern != NULL) {
|
||
|
if (source->value.govern != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_ACHIEVEMENT:
|
||
|
source->value.achievement = achievement_by_rule_name(value);
|
||
|
if (source->value.achievement != NULL) {
|
||
|
if (source->value.achievement != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_STYLE:
|
||
|
source->value.style = style_by_rule_name(value);
|
||
|
if (source->value.style != NULL) {
|
||
|
if (source->value.style != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_IMPROVEMENT:
|
||
|
case VUT_SITE:
|
||
|
source->value.building = improvement_by_rule_name(value);
|
||
|
if (source->value.building != NULL) {
|
||
|
if (source->value.building != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_EXTRA:
|
||
|
source->value.extra = extra_type_by_rule_name(value);
|
||
|
if (source->value.extra != NULL) {
|
||
|
if (source->value.extra != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_GOOD:
|
||
|
source->value.good = goods_by_rule_name(value);
|
||
|
if (source->value.good != NULL) {
|
||
|
if (source->value.good != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_NATIONGROUP:
|
||
|
source->value.nationgroup = nation_group_by_rule_name(value);
|
||
|
if (source->value.nationgroup != NULL) {
|
||
|
if (source->value.nationgroup != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_ACTION:
|
||
|
source->value.action = action_by_rule_name(value);
|
||
|
if (source->value.action != NULL) {
|
||
|
if (source->value.action != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_COUNTER:
|
||
|
source->value.counter = counter_by_rule_name(value);
|
||
|
if (source->value.counter != NULL) {
|
||
|
if (source->value.counter != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Combine values into a universal structure. This is for serialization
|
||
|
and is the opposite of universal_extraction().
|
||
|
FIXME: ensure that every caller checks error return!
|
||
|
FIXME: Ensure that every caller checks error return!
|
||
|
**************************************************************************/
|
||
|
struct universal universal_by_number(const enum universals_n kind,
|
||
|
const int value)
|
||
|
const int value)
|
||
|
{
|
||
|
struct universal source;
|
||
| ... | ... | |
|
switch (source.kind) {
|
||
|
case VUT_NONE:
|
||
|
/* Avoid compiler warning about unitialized source.value */
|
||
|
source.value.advance = NULL;
|
||
|
source.value.advance = nullptr;
|
||
|
return source;
|
||
|
case VUT_ADVANCE:
|
||
|
source.value.advance = advance_by_number(value);
|
||
|
if (source.value.advance != NULL) {
|
||
|
if (source.value.advance != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
return source;
|
||
|
case VUT_GOVERNMENT:
|
||
|
source.value.govern = government_by_number(value);
|
||
|
if (source.value.govern != NULL) {
|
||
|
if (source.value.govern != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_ACHIEVEMENT:
|
||
|
source.value.achievement = achievement_by_number(value);
|
||
|
if (source.value.achievement != NULL) {
|
||
|
if (source.value.achievement != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_STYLE:
|
||
|
source.value.style = style_by_number(value);
|
||
|
if (source.value.style != NULL) {
|
||
|
if (source.value.style != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_IMPROVEMENT:
|
||
|
case VUT_SITE:
|
||
|
source.value.building = improvement_by_number(value);
|
||
|
if (source.value.building != NULL) {
|
||
|
if (source.value.building != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
return source;
|
||
|
case VUT_TERRAIN:
|
||
|
source.value.terrain = terrain_by_number(value);
|
||
|
if (source.value.terrain != NULL) {
|
||
|
if (source.value.terrain != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
return source;
|
||
|
case VUT_NATION:
|
||
|
source.value.nation = nation_by_number(value);
|
||
|
if (source.value.nation != NULL) {
|
||
|
if (source.value.nation != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_NATIONGROUP:
|
||
|
source.value.nationgroup = nation_group_by_number(value);
|
||
|
if (source.value.nationgroup != NULL) {
|
||
|
if (source.value.nationgroup != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
break;
|
||
|
case VUT_NATIONALITY:
|
||
|
source.value.nationality = nation_by_number(value);
|
||
|
if (source.value.nationality != NULL) {
|
||
|
if (source.value.nationality != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_ORIGINAL_OWNER:
|
||
|
source.value.origowner = nation_by_number(value);
|
||
|
if (source.value.origowner != NULL) {
|
||
|
if (source.value.origowner != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
|
case VUT_UTYPE:
|
||
|
source.value.utype = utype_by_number(value);
|
||
|
if (source.value.utype != NULL) {
|
||
|
if (source.value.utype != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
return source;
|
||
|
case VUT_UCLASS:
|
||
|
source.value.uclass = uclass_by_number(value);
|
||
|
if (source.value.uclass != NULL) {
|
||
|
if (source.value.uclass != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
return source;
|
||
|
case VUT_ACTION:
|
||
|
source.value.action = action_by_number(value);
|
||
|
if (source.value.action != NULL) {
|
||
|
if (source.value.action != nullptr) {
|
||
|
return source;
|
||
|
}
|
||
|
break;
|
||
| ... | ... | |
|
/* If we reach here there's been an error. */
|
||
|
source.kind = universals_n_invalid();
|
||
|
/* Avoid compiler warning about unitialized source.value */
|
||
|
source.value.advance = NULL;
|
||
|
source.value.advance = nullptr;
|
||
|
return source;
|
||
|
}
|
||
| ... | ... | |
|
the opposite of universal_by_number().
|
||
|
**************************************************************************/
|
||
|
void universal_extraction(const struct universal *source,
|
||
|
int *kind, int *value)
|
||
|
int *kind, int *value)
|
||
|
{
|
||
|
*kind = source->kind;
|
||
|
*value = universal_number(source);
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Parse a requirement type and value string into a requirement structure.
|
||
|
Returns the invalid element for enum universal_n on error. Passing in a
|
||
|
NULL type is considered VUT_NONE (not an error).
|
||
|
Returns the invalid element for enum universal_n on error. Passing in
|
||
|
a nullptr type is considered VUT_NONE (not an error).
|
||
|
Pass this some values like "Building", "Factory".
|
||
|
**************************************************************************/
|
||
| ... | ... | |
|
{
|
||
|
struct requirement req;
|
||
|
bool invalid;
|
||
|
const char *error = NULL;
|
||
|
const char *error = nullptr;
|
||
|
req.source = universal_by_rule_name(type, value);
|
||
| ... | ... | |
|
} else {
|
||
|
/* Scan the range string to find the range. If no range is given a
|
||
|
* default fallback is used rather than giving an error. */
|
||
|
if (range != NULL) {
|
||
|
if (range != nullptr) {
|
||
|
req.range = req_range_by_name(range, fc_strcasecmp);
|
||
|
if (!req_range_is_valid(req.range)) {
|
||
|
invalid = TRUE;
|
||
| ... | ... | |
|
invalid = (req.range != REQ_RANGE_WORLD);
|
||
|
break;
|
||
|
case VUT_AGE:
|
||
|
/* FIXME: could support TRADE_ROUTE, TEAM, etc */
|
||
|
/* FIXME: Could support TRADE_ROUTE, TEAM, etc */
|
||
|
invalid = (req.range != REQ_RANGE_LOCAL
|
||
|
&& req.range != REQ_RANGE_CITY
|
||
|
&& req.range != REQ_RANGE_PLAYER);
|
||
| ... | ... | |
|
of req_get_values.
|
||
|
**************************************************************************/
|
||
|
struct requirement req_from_values(int type, int range,
|
||
|
bool survives, bool present, bool quiet,
|
||
|
int value)
|
||
|
bool survives, bool present, bool quiet,
|
||
|
int value)
|
||
|
{
|
||
|
struct requirement req;
|
||
| ... | ... | |
|
}
|
||
|
/**********************************************************************//**
|
||
|
Return the value of a req as a serializable integer. This is the opposite
|
||
|
Return the value of a req as a serializable integer. This is the opposite
|
||
|
of req_set_value.
|
||
|
**************************************************************************/
|
||
|
void req_get_values(const struct requirement *req,
|
||
|
int *type, int *range,
|
||
|
bool *survives, bool *present, bool *quiet,
|
||
|
int *value)
|
||
|
int *type, int *range,
|
||
|
bool *survives, bool *present, bool *quiet,
|
||
|
int *value)
|
||
|
{
|
||
|
universal_extraction(&req->source, type, value);
|
||
|
*range = req->range;
|
||
| ... | ... | |
|
Does not care if one is quiet and the other not.
|
||
|
**************************************************************************/
|
||
|
bool are_requirements_equal(const struct requirement *req1,
|
||
|
const struct requirement *req2)
|
||
|
const struct requirement *req2)
|
||
|
{
|
||
|
return (are_universals_equal(&req1->source, &req2->source)
|
||
|
&& req1->range == req2->range
|
||
|
&& req1->survives == req2->survives
|
||
|
&& req1->present == req2->present);
|
||
|
&& req1->range == req2->range
|
||
|
&& req1->survives == req2->survives
|
||
|
&& req1->present == req2->present);
|
||
|
}
|
||
|
/**********************************************************************//**
|
||
| ... | ... | |
|
Returns the number of buildings of a certain type owned by plr.
|
||
|
**************************************************************************/
|
||
|
static int num_player_buildings(const struct player *pplayer,
|
||
|
const struct impr_type *building)
|
||
|
const struct impr_type *building)
|
||
|
{
|
||
|
if (is_wonder(building)) {
|
||
|
return (wonder_is_built(pplayer, building) ? 1 : 0);
|
||
| ... | ... | |
|
Returns the number of buildings of a certain type on a continent.
|
||
|
**************************************************************************/
|
||
|
static int num_continent_buildings(const struct player *pplayer,
|
||
|
int continent,
|
||
|
const struct impr_type *building)
|
||
|
int continent,
|
||
|
const struct impr_type *building)
|
||
|
{
|
||
|
if (is_wonder(building)) {
|
||
|
const struct city *pcity;
|
||
| ... | ... | |
|
return BOOL_TO_TRISTATE(num_world_buildings_total(building) > 0);
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
case REQ_RANGE_TEAM:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
} players_iterate_alive_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(player_has_ever_built(context->player,
|
||
| ... | ... | |
|
return BOOL_TO_TRISTATE(num_world_buildings(building) > 0);
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
case REQ_RANGE_TEAM:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
} players_iterate_alive_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(num_player_buildings(context->player,
|
||
| ... | ... | |
|
enum fc_tristate ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (city_has_building(trade_partner, building)) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
return TRI_NO;
|
||
|
}
|
||
|
} else {
|
||
|
/* TODO: other local targets */
|
||
|
/* TODO: Other local targets */
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
case REQ_RANGE_TILE:
|
||
| ... | ... | |
|
{
|
||
|
struct player *owner;
|
||
|
if (pcity == NULL) {
|
||
|
if (pcity == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
| ... | ... | |
|
case REQ_RANGE_CITY:
|
||
|
return is_buildingflag_in_city(context->city, req->source.value.impr_flag);
|
||
|
case REQ_RANGE_TILE:
|
||
|
if (context->tile == NULL) {
|
||
|
if (context->tile == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return is_buildingflag_in_city(tile_city(context->tile),
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
return (context->player != NULL
|
||
|
return (context->player != nullptr
|
||
|
? BOOL_TO_TRISTATE(player_has_flag(context->player,
|
||
|
req->source.value.plr_flag))
|
||
|
: TRI_MAYBE);
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
return (context->player != NULL
|
||
|
return (context->player != nullptr
|
||
|
? BOOL_TO_TRISTATE(player_has_state(context->player,
|
||
|
req->source.value.plrstate))
|
||
|
: TRI_MAYBE);
|
||
| ... | ... | |
|
enum fc_tristate ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (city_culture(trade_partner) >= minculture) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
case REQ_RANGE_TEAM:
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
case REQ_RANGE_WORLD:
|
||
|
if (NULL == context->player) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
enum fc_tristate ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
foreign_pct = citizens_nation_foreign(trade_partner) * 100
|
||
| ... | ... | |
|
max_units = req->source.value.max_tile_units;
|
||
|
/* TODO: if can't see V_INVIS -> TRI_MAYBE */
|
||
|
/* TODO: If can't see V_INVIS -> TRI_MAYBE */
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_TILE:
|
||
|
if (!context->tile) {
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
}
|
||
|
return BOOL_TO_TRISTATE(city_receives_goods(context->city, pgood)
|
||
|
|| (goods_has_flag(pgood, GF_SELF_PROVIDED)
|
||
|
&& goods_can_be_provided(context->city, pgood, NULL)));
|
||
|
&& goods_can_be_provided(context->city, pgood,
|
||
|
nullptr)));
|
||
|
case REQ_RANGE_TILE:
|
||
|
case REQ_RANGE_CADJACENT:
|
||
|
case REQ_RANGE_ADJACENT:
|
||
| ... | ... | |
|
if (!context->city) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
if (pterrain != NULL) {
|
||
|
if (pterrain != nullptr) {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(context->city),
|
||
|
city_tile(context->city), ptile) {
|
||
|
if (tile_terrain(ptile) == pterrain) {
|
||
| ... | ... | |
|
if (!context->city) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
if (pterrain != NULL) {
|
||
|
if (pterrain != nullptr) {
|
||
|
enum fc_tristate ret;
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(context->city),
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
city_tile_iterate(nmap, city_map_radius_sq_get(trade_partner),
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_GOVERNMENT);
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(government_of_player(context->player)
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_STYLE);
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(context->player->style
|
||
| ... | ... | |
|
return ((game.info.global_advance_count - 1)
|
||
|
>= req->source.value.min_techs);
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
/* "None" does not count */
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
/* "None" does not count */
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_AI_LEVEL);
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(is_ai(context->player)
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(nation_of_player(context->player) == nation);
|
||
|
case REQ_RANGE_TEAM:
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
* (e.g. via /remove), rather than just dying, this 'survives'
|
||
|
* requirement will stop being true for their nation.
|
||
|
* create_command_newcomer() can also cause this to happen. */
|
||
|
return BOOL_TO_TRISTATE(NULL != nation->player
|
||
|
return BOOL_TO_TRISTATE(nation->player != nullptr
|
||
|
&& (req->survives || nation->player->is_alive));
|
||
|
case REQ_RANGE_LOCAL:
|
||
|
case REQ_RANGE_TILE:
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(nation_is_in_group(
|
||
| ... | ... | |
|
case REQ_RANGE_TEAM:
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
case REQ_RANGE_WORLD:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_CITY:
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
citizens_iterate(context->city, slot, count) {
|
||
| ... | ... | |
|
return TRI_NO;
|
||
|
case REQ_RANGE_TRADE_ROUTE:
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
citizens_iterate(context->city, slot, count) {
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else {
|
||
|
citizens_iterate(trade_partner, slot, count) {
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_CITY:
|
||
|
if (context->city == NULL || context->city->original == NULL) {
|
||
|
if (context->city == nullptr || context->city->original == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
if (player_nation(context->city->original) == nation) {
|
||
| ... | ... | |
|
{
|
||
|
switch (range) {
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (target_player == NULL) {
|
||
|
if (target_player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(is_diplrel_to_other(target_player, diplrel));
|
||
|
case REQ_RANGE_TEAM:
|
||
|
case REQ_RANGE_ALLIANCE:
|
||
|
case REQ_RANGE_WORLD:
|
||
|
if (target_player == NULL) {
|
||
|
if (target_player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
players_iterate_alive(plr2) {
|
||
| ... | ... | |
|
} players_iterate_alive_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_LOCAL:
|
||
|
if (target_player == NULL || other_player == NULL) {
|
||
|
if (target_player == nullptr || other_player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(is_diplrel_between(target_player, other_player, diplrel));
|
||
| ... | ... | |
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_DIPLREL_TILE);
|
||
|
return is_diplrel_in_range(context->tile ? tile_owner(context->tile)
|
||
|
: NULL,
|
||
|
: nullptr,
|
||
|
context->player,
|
||
|
req->range,
|
||
|
req->source.value.diplrel);
|
||
| ... | ... | |
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_DIPLREL_TILE_O);
|
||
|
return is_diplrel_in_range(context->tile ? tile_owner(context->tile)
|
||
|
: NULL,
|
||
|
: nullptr,
|
||
|
other_context->player,
|
||
|
req->range,
|
||
|
req->source.value.diplrel);
|
||
| ... | ... | |
|
{
|
||
|
enum fc_tristate out = TRI_NO;
|
||
|
if (target_tile == NULL) {
|
||
|
if (target_tile == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
| ... | ... | |
|
/* Could be asked with incomplete data.
|
||
|
* is_req_active() will handle it based on prob_type. */
|
||
|
if (context->unit == NULL) {
|
||
|
if (context->unit == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
switch (uprop) {
|
||
|
case USP_TRANSPORTED:
|
||
|
return BOOL_TO_TRISTATE(context->unit->transporter != NULL);
|
||
|
return BOOL_TO_TRISTATE(context->unit->transporter != nullptr);
|
||
|
case USP_LIVABLE_TILE:
|
||
|
return BOOL_TO_TRISTATE(
|
||
|
can_unit_exist_at_tile(nmap, context->unit,
|
||
| ... | ... | |
|
"Unsupported range \"%s\"",
|
||
|
req_range_name(req->range));
|
||
|
if (context->unit == NULL) {
|
||
|
if (context->unit == nullptr) {
|
||
|
/* FIXME: Excluding ACTIVITY_IDLE here is a bit ugly, but done because
|
||
|
* it's the zero value that context has by default - so many callers
|
||
|
* who meant not to set specific activity actually have ACTIVITY_IDLE
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MINVETERAN);
|
||
|
if (context->unit == NULL) {
|
||
|
if (context->unit == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(context->unit->veteran
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MINMOVES);
|
||
|
if (context->unit == NULL) {
|
||
|
if (context->unit == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(req->source.value.minmoves
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MINHP);
|
||
|
if (context->unit == NULL) {
|
||
|
if (context->unit == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(req->source.value.min_hit_points
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_LOCAL:
|
||
|
if (context->unit == NULL || !is_server()) {
|
||
|
if (context->unit == nullptr || !is_server()) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(
|
||
| ... | ... | |
|
}
|
||
|
break;
|
||
|
case REQ_RANGE_CITY:
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(
|
||
| ... | ... | |
|
}
|
||
|
break;
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(req->source.value.age
|
||
| ... | ... | |
|
switch (req->range) {
|
||
|
case REQ_RANGE_LOCAL:
|
||
|
if (context->unit == NULL || !is_server()) {
|
||
|
if (context->unit == nullptr || !is_server()) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
return BOOL_TO_TRISTATE(
|
||
| ... | ... | |
|
}
|
||
|
/**********************************************************************//**
|
||
|
Is center of given city in tile. If city is NULL, any city will do.
|
||
|
Is center of given city in tile. If city is nullptr, any city will do.
|
||
|
**************************************************************************/
|
||
|
static bool is_city_in_tile(const struct tile *ptile,
|
||
|
const struct city *pcity)
|
||
|
const struct city *pcity)
|
||
|
{
|
||
|
if (pcity == NULL) {
|
||
|
return tile_city(ptile) != NULL;
|
||
|
if (pcity == nullptr) {
|
||
|
return tile_city(ptile) != nullptr;
|
||
|
} else {
|
||
|
return is_city_center(pcity, ptile);
|
||
|
}
|
||
| ... | ... | |
|
citytile = req->source.value.citytile;
|
||
|
fc_assert_ret_val(req_range_is_valid(req->range), TRI_MAYBE);
|
||
|
if (context->tile == NULL) {
|
||
|
if (context->tile == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
| ... | ... | |
|
case CITYT_CLAIMED:
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_TILE:
|
||
|
return BOOL_TO_TRISTATE(context->tile->owner != NULL);
|
||
|
return BOOL_TO_TRISTATE(context->tile->owner != nullptr);
|
||
|
case REQ_RANGE_CADJACENT:
|
||
|
if (context->tile->owner != NULL) {
|
||
|
if (context->tile->owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
cardinal_adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->owner != NULL) {
|
||
|
if (adjc_tile->owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} cardinal_adjc_iterate_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_ADJACENT:
|
||
|
if (context->tile->owner != NULL) {
|
||
|
if (context->tile->owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->owner != NULL) {
|
||
|
if (adjc_tile->owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} adjc_iterate_end;
|
||
| ... | ... | |
|
case CITYT_EXTRAS_OWNED:
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_TILE:
|
||
|
return BOOL_TO_TRISTATE(context->tile->extras_owner != NULL);
|
||
|
return BOOL_TO_TRISTATE(context->tile->extras_owner != nullptr);
|
||
|
case REQ_RANGE_CADJACENT:
|
||
|
if (context->tile->extras_owner != NULL) {
|
||
|
if (context->tile->extras_owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
cardinal_adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->extras_owner != NULL) {
|
||
|
if (adjc_tile->extras_owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} cardinal_adjc_iterate_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_ADJACENT:
|
||
|
if (context->tile->extras_owner != NULL) {
|
||
|
if (context->tile->extras_owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->extras_owner != NULL) {
|
||
|
if (adjc_tile->extras_owner != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} adjc_iterate_end;
|
||
| ... | ... | |
|
case CITYT_WORKED:
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_TILE:
|
||
|
return BOOL_TO_TRISTATE(context->tile->worked != NULL);
|
||
|
return BOOL_TO_TRISTATE(context->tile->worked != nullptr);
|
||
|
case REQ_RANGE_CADJACENT:
|
||
|
if (context->tile->worked != NULL) {
|
||
|
if (context->tile->worked != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
cardinal_adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->worked != NULL) {
|
||
|
if (adjc_tile->worked != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} cardinal_adjc_iterate_end;
|
||
|
return TRI_NO;
|
||
|
case REQ_RANGE_ADJACENT:
|
||
|
if (context->tile->worked != NULL) {
|
||
|
if (context->tile->worked != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
adjc_iterate(nmap, context->tile, adjc_tile) {
|
||
|
if (adjc_tile->worked != NULL) {
|
||
|
if (adjc_tile->worked != nullptr) {
|
||
|
return TRI_YES;
|
||
|
}
|
||
|
} adjc_iterate_end;
|
||
| ... | ... | |
|
citystatus = req->source.value.citystatus;
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
| ... | ... | |
|
case CITYS_OWNED_BY_ORIGINAL:
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_CITY:
|
||
|
if (context->city->original == NULL) {
|
||
|
if (context->city->original == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(city_owner(context->city) == context->city->original);
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL || trade_partner->original == NULL) {
|
||
|
if (trade_partner == nullptr || trade_partner->original == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (city_owner(trade_partner) == trade_partner->original) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (trade_partner->had_famine) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (trade_partner->anarchy > 0) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (trade_partner->rapture > 0) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (trade_partner->acquire_t != CACQ_FOUNDED) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
{
|
||
|
IS_REQ_ACTIVE_VARIANT_ASSERT(VUT_MINSIZE);
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
if (req->range == REQ_RANGE_TRADE_ROUTE) {
|
||
| ... | ... | |
|
ret = TRI_NO;
|
||
|
trade_partners_iterate(context->city, trade_partner) {
|
||
|
if (trade_partner == NULL) {
|
||
|
if (trade_partner == nullptr) {
|
||
|
ret = TRI_MAYBE;
|
||
|
} else if (city_size_get(trade_partner) >= req->source.value.minsize) {
|
||
|
return TRI_YES;
|
||
| ... | ... | |
|
count = req->source.value.counter;
|
||
|
if (NULL == context->city) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
|
return BOOL_TO_TRISTATE(count->checkpoint <=
|
||
| ... | ... | |
|
if (req->range == REQ_RANGE_WORLD) {
|
||
|
return BOOL_TO_TRISTATE(achievement_claimed(achievement));
|
||
|
} else if (context->player == NULL) {
|
||
|
} else if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else if (req->range == REQ_RANGE_ALLIANCE
|
||
|
|| req->range == REQ_RANGE_TEAM) {
|
||
| ... | ... | |
|
{
|
||
|
int min = -MAP_MAX_LATITUDE, max = MAP_MAX_LATITUDE;
|
||
|
fc_assert_ret_val(req != NULL, TRI_MAYBE);
|
||
|
fc_assert(context != NULL);
|
||
|
fc_assert_ret_val(req != nullptr, TRI_MAYBE);
|
||
|
fc_assert(context != nullptr);
|
||
|
switch (req->source.kind) {
|
||
|
case VUT_MINLATITUDE:
|
||
| ... | ... | |
|
&& max >= MAP_MIN_REAL_LATITUDE(wld.map));
|
||
|
case REQ_RANGE_TILE:
|
||
|
if (context->tile == NULL) {
|
||
|
if (context->tile == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
int tile_lat = map_signed_latitude(context->tile);
|
||
| ... | ... | |
|
}
|
||
|
case REQ_RANGE_CADJACENT:
|
||
|
if (context->tile == NULL) {
|
||
|
if (context->tile == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
}
|
||
| ... | ... | |
|
context gives the target (or targets) to evaluate against
|
||
|
req gives the requirement itself
|
||
|
context and other_context may be NULL. This is equivalent to passing
|
||
|
context and other_context may be nullptr. This is equivalent to passing
|
||
|
empty contexts.
|
||
|
Make sure you give all aspects of the target when calling this function:
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Applies the standard evaluation of req in context, ignoring req->present.
|
||
|
context and other_context may be NULL. This is equivalent to passing
|
||
|
context and other_context may be nullptr. This is equivalent to passing
|
||
|
empty contexts.
|
||
|
Fields of context that are NULL are considered unspecified
|
||
|
Fields of context that are nullptr are considered unspecified
|
||
|
and will produce TRI_MAYBE if req needs them to evaluate.
|
||
|
**************************************************************************/
|
||
|
static
|
||
| ... | ... | |
|
return TRI_NO;
|
||
|
}
|
||
|
fc_assert_ret_val(req_definitions[req->source.kind].cb != NULL, TRI_NO);
|
||
|
fc_assert_ret_val(req_definitions[req->source.kind].cb != nullptr, TRI_NO);
|
||
|
return req_definitions[req->source.kind].cb(nmap, context,
|
||
|
other_context, req);
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Evaluates req in context to fc_tristate.
|
||
|
context and other_context may be NULL. This is equivalent to passing
|
||
|
context and other_context may be nullptr. This is equivalent to passing
|
||
|
empty contexts.
|
||
|
Fields of context that are NULL are considered unspecified
|
||
|
Fields of context that are nullptr are considered unspecified
|
||
|
and will produce TRI_MAYBE if req needs them to evaluate.
|
||
|
**************************************************************************/
|
||
|
enum fc_tristate tri_req_active(const struct req_context *context,
|
||
| ... | ... | |
|
reqs gives the requirement vector.
|
||
|
The function returns TRUE only if all requirements are active.
|
||
|
context and other_context may be NULL. This is equivalent to passing
|
||
|
context and other_context may be nullptr. This is equivalent to passing
|
||
|
empty contexts.
|
||
|
Make sure you give all aspects of the target when calling this function:
|
||
| ... | ... | |
|
const struct req_context *other_context,
|
||
|
const struct requirement *req)
|
||
|
{
|
||
|
/* FIXME: doubles code from calendar.c */
|
||
|
/* FIXME: Doubles code from calendar.c */
|
||
|
int ypt = get_world_bonus(EFT_TURN_YEARS);
|
||
|
int fpt = get_world_bonus(EFT_TURN_FRAGMENTS);
|
||
|
int fragment = game.info.fragment_count;
|
||
|
int fragment1 = fragment; /* if fragments don't advance */
|
||
|
int fragment1 = fragment; /* If fragments don't advance */
|
||
|
int year_inc, year_inc1;
|
||
|
const int slowdown = (victory_enabled(VC_SPACERACE)
|
||
|
? get_world_bonus(EFT_SLOW_DOWN_TIMELINE) : 0);
|
||
| ... | ... | |
|
case VUT_AGE:
|
||
|
switch (req->range) {
|
||
|
case REQ_RANGE_LOCAL:
|
||
|
if (context->unit == NULL || !is_server()) {
|
||
|
if (context->unit == nullptr || !is_server()) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
int ua = game.info.turn + pass - context->unit->birth_turn;
|
||
| ... | ... | |
|
}
|
||
|
break;
|
||
|
case REQ_RANGE_CITY:
|
||
|
if (context->city == NULL) {
|
||
|
if (context->city == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
int ca = game.info.turn + pass - context->city->turn_founded;
|
||
| ... | ... | |
|
}
|
||
|
break;
|
||
|
case REQ_RANGE_PLAYER:
|
||
|
if (context->player == NULL) {
|
||
|
if (context->player == nullptr) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
present = req->source.value.age
|
||
| ... | ... | |
|
}
|
||
|
break;
|
||
|
case VUT_FORM_AGE:
|
||
|
if (context->unit == NULL || !is_server()) {
|
||
|
if (context->unit == nullptr || !is_server()) {
|
||
|
return TRI_MAYBE;
|
||
|
} else {
|
||
|
int ua = game.info.turn + pass - context->unit->current_form_turn;
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Test requirements in reqs with tester according to (data, n_data)
|
||
|
and give the resulting tristate.
|
||
|
If maybe_reqs is not NULL, copies requirements that are evaluated
|
||
|
If maybe_reqs is not nullptr, copies requirements that are evaluated
|
||
|
to TRI_MAYBE into it (stops as soon as one evaluates to TRI_NO).
|
||
|
**************************************************************************/
|
||
|
enum fc_tristate
|
||
| ... | ... | |
|
bool active = TRUE;
|
||
|
bool certain = TRUE;
|
||
|
fc_assert_ret_val(NULL != tester, TRI_NO);
|
||
|
fc_assert_ret_val(tester != nullptr, TRI_NO);
|
||
|
requirement_vector_iterate(reqs, preq) {
|
||
|
switch(tester(context, other_context, preq,
|
||
|
data, n_data)) {
|
||
| ... | ... | |
|
if (can_improvement_go_obsolete(b)) {
|
||
|
if (improvement_obsolete(context->player, b, context->city)) {
|
||
|
/* FIXME: sometimes can unobsolete, but considering it
|
||
|
/* FIXME: Sometimes can unobsolete, but considering it
|
||
|
* may sometimes put the function on endless recursion */
|
||
|
return REQUCH_ACT; /* Mostly about techs */
|
||
|
} else {
|
||
|
/* NOTE: may obsoletion reqs be unchanging? Hardly but why not. */
|
||
|
/* NOTE: May obsoletion reqs be unchanging? Hardly but why not. */
|
||
|
return REQUCH_NO;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns TRUE iff the specified requirement vector has a positive
|
||
|
requirement of the specified requirement type.
|
||
|
@param reqs the requirement vector to look in
|
||
|
@param kind the requirement type to look for
|
||
|
**************************************************************************/
|
||
| ... | ... | |
|
Returns TRUE iff the specified requirement is known to be impossible to
|
||
|
fulfill. Note that this function may return FALSE even when it is
|
||
|
impossible to fulfill a requirement if it can't detect it.
|
||
|
@param req the requirement to check the possibility of.
|
||
|
@return TRUE iff the requirement never can be fulfilled.
|
||
|
**************************************************************************/
|
||
| ... | ... | |
|
Returns TRUE iff the specified requirement vector is known to be
|
||
|
impossible to fulfill. Note that this function may return FALSE even when
|
||
|
it is impossible to fulfill a requirement if it can't detect it.
|
||
|
@param reqs the requirement vector to check the possibility of.
|
||
|
@return TRUE iff the requirement vector never can be fulfilled.
|
||
|
**************************************************************************/
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns the requirement vector number of the specified requirement
|
||
|
vector in the specified requirement vector.
|
||
|
@param parent_item the item that may own the vector.
|
||
|
@param vec the requirement vector to number.
|
||
|
@return the requirement vector number the vector has in the parent item.
|
||
| ... | ... | |
|
/********************************************************************//**
|
||
|
Returns a writable pointer to the specified requirement vector in the
|
||
|
specified requirement vector or NULL if the parent item doesn't have a
|
||
|
requirement vector with that requirement vector number.
|
||
|
specified requirement vector or nullptr if the parent item doesn't have
|
||
|
a requirement vector with that requirement vector number.
|
||
|
@param parent_item the item that should have the requirement vector.
|
||
|
@param number the item's requirement vector number.
|
||
|
@return a pointer to the specified requirement vector.
|
||
| ... | ... | |
|
struct requirement_vector *
|
||
|
req_vec_by_number(const void *parent_item, req_vec_num_in_item number)
|
||
|
{
|
||
|
fc_assert_ret_val(number == 0, NULL);
|
||
|
fc_assert_ret_val(number == 0, nullptr);
|
||
|
return (struct requirement_vector *)parent_item;
|
||
|
}
|
||
| ... | ... | |
|
ready for use in the user interface.
|
||
|
N.B.: The returned string is static, so every call to this function
|
||
|
overwrites the previous.
|
||
|
@param change the requirement vector change
|
||
|
@param namer a function that returns a description of the vector to
|
||
|
change for the item the vector belongs to.
|
||
| ... | ... | |
|
static char buf[MAX_LEN_NAME * 3];
|
||
|
struct astring astr;
|
||
|
fc_assert_ret_val(change, NULL);
|
||
|
fc_assert_ret_val(change, nullptr);
|
||
|
fc_assert_ret_val(req_vec_change_operation_is_valid(change->operation),
|
||
|
NULL);
|
||
|
nullptr);
|
||
|
/* Get rid of the previous. */
|
||
|
buf[0] = '\0';
|
||
|
if (namer == NULL) {
|
||
|
if (namer == nullptr) {
|
||
|
/* TRANS: default description of a requirement vector
|
||
|
* (used in ruledit) */
|
||
|
req_vec_description = _("the requirement vector");
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns TRUE iff the specified requirement vector modification was
|
||
|
successfully applied to the specified target requirement vector.
|
||
|
@param modification the requirement vector change
|
||
|
@param getter a function that returns a pointer to the requirement
|
||
|
vector the change should be applied to given a ruleset
|
||
| ... | ... | |
|
Returns a new requirement vector problem with the specified number of
|
||
|
suggested solutions and the specified description. The suggestions are
|
||
|
added by the caller.
|
||
|
@param num_suggested_solutions the number of suggested solutions.
|
||
|
@param description the description of the problem.
|
||
|
@param description_translated the translated description of the problem.
|
||
| ... | ... | |
|
Returns a new requirement vector problem with the specified number of
|
||
|
suggested solutions and the specified description. The suggestions are
|
||
|
added by the caller.
|
||
|
@param num_suggested_solutions the number of suggested solutions.
|
||
|
@param descr the description of the problem as a format string
|
||
|
@return the new requirement vector problem.
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
De-allocates resources associated with the given requirement vector
|
||
|
problem.
|
||
|
@param issue the no longer needed problem.
|
||
|
**************************************************************************/
|
||
|
void req_vec_problem_free(struct req_vec_problem *issue)
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns the first self contradiction found in the specified requirement
|
||
|
vector with suggested solutions or NULL if no contradiction was found.
|
||
|
vector with suggested solutions or nullptr if no contradiction was found.
|
||
|
It is the responsibility of the caller to free the suggestion when it is
|
||
|
done with it.
|
||
|
@param vec the requirement vector to look in.
|
||
|
@param get_num function that returns the requirement vector's number in
|
||
|
the parent item.
|
||
| ... | ... | |
|
int i, j;
|
||
|
req_vec_num_in_item vec_num;
|
||
|
if (vec == NULL || requirement_vector_size(vec) == 0) {
|
||
|
if (vec == nullptr || requirement_vector_size(vec) == 0) {
|
||
|
/* No vector. */
|
||
|
return NULL;
|
||
|
return nullptr;
|
||
|
}
|
||
|
if (get_num == NULL || parent_item == NULL) {
|
||
|
if (get_num == nullptr || parent_item == nullptr) {
|
||
|
vec_num = 0;
|
||
|
} else {
|
||
|
vec_num = get_num(parent_item, vec);
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
return nullptr;
|
||
|
}
|
||
|
/**********************************************************************//**
|
||
|
Returns a suggestion to fix the specified requirement vector or NULL if
|
||
|
Returns a suggestion to fix the specified requirement vector or nullptr if
|
||
|
no fix is found to be needed. It is the responsibility of the caller to
|
||
|
free the suggestion when it is done with it.
|
||
|
@param vec the requirement vector to look in.
|
||
|
@param get_num function that returns the requirement vector's number in
|
||
|
the parent item.
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns the first universal known to always be absent in the specified
|
||
|
requirement vector with suggested solutions or NULL if no missing
|
||
|
requirement vector with suggested solutions or nullptr if no missing
|
||
|
universals were found.
|
||
|
It is the responsibility of the caller to free the suggestion when it is
|
||
|
done with it.
|
||
|
@param vec the requirement vector to look in.
|
||
|
@param get_num function that returns the requirement vector's number in
|
||
|
the parent item.
|
||
| ... | ... | |
|
{
|
||
|
int i;
|
||
|
req_vec_num_in_item vec_num;
|
||
|
struct req_vec_problem *problem = NULL;
|
||
|
struct req_vec_problem *problem = nullptr;
|
||
|
if (vec == NULL || requirement_vector_size(vec) == 0) {
|
||
|
if (vec == nullptr || requirement_vector_size(vec) == 0) {
|
||
|
/* No vector. */
|
||
|
return NULL;
|
||
|
return nullptr;
|
||
|
}
|
||
|
if (get_num == NULL || parent_item == NULL) {
|
||
|
if (get_num == nullptr || parent_item == nullptr) {
|
||
|
vec_num = 0;
|
||
|
} else {
|
||
|
vec_num = get_num(parent_item, vec);
|
||
| ... | ... | |
|
* requirement makes it possible to fulfill it. This is a rule
|
||
|
* change and shouldn't be "fixed" without thinking. Don't offer any
|
||
|
* automatic solution to prevent mindless "fixes". */
|
||
|
/* TRANS: ruledit warns a user about an unused requirement vector
|
||
|
/* TRANS: Ruledit warns a user about an unused requirement vector
|
||
|
* that never can be fulfilled because it asks for something that
|
||
|
* never will be there. */
|
||
|
if (problem == NULL) {
|
||
|
if (problem == nullptr) {
|
||
|
problem = req_vec_problem_new(0,
|
||
|
N_("Requirement {%s} requires %s but it will never be"
|
||
|
" there."),
|
||
| ... | ... | |
|
continue;
|
||
|
}
|
||
|
if (problem != NULL) {
|
||
|
if (problem != nullptr) {
|
||
|
/* Free previous one (one with no solution proposals) */
|
||
|
req_vec_problem_free(problem);
|
||
|
}
|
||
| ... | ... | |
|
/**********************************************************************//**
|
||
|
Returns the first redundant requirement in the specified requirement
|
||
|
vector with suggested solutions or NULL if no redundant requirements were
|
||
|
vector with suggested solutions or nullptr if no redundant requirements were
|
||
|
found.
|
||