28 changes: 20 additions & 8 deletions common/requirements.c
Expand Up @@ -836,14 +836,23 @@ static bool is_unittype_in_range(const struct unit_type *target_unittype,
****************************************************************************/
static bool is_unitflag_in_range(const struct unit_type *target_unittype,
enum req_range range, bool survives,
enum unit_flag_id unitflag)
enum unit_flag_id unitflag,
enum req_problem_type prob_type)
{
/* If no target_unittype is given, we allow the req to be met. This is
* to allow querying of certain effect types (like the presence of city
* walls) without actually knowing the target unit. */
return (range == REQ_RANGE_LOCAL
&& (!target_unittype
|| utype_has_flag(target_unittype, unitflag)));
if (range != REQ_RANGE_LOCAL) {
return FALSE;
}
if (!target_unittype) {
/* Unknow means TRUE for RPT_POSSIBLE
* FALSE for RPT_CERTAIN
*/
return prob_type == RPT_POSSIBLE;
}

return utype_has_flag(target_unittype, unitflag);
}

/****************************************************************************
Expand Down Expand Up @@ -894,7 +903,8 @@ bool is_req_active(const struct player *target_player,
const struct unit_type *target_unittype,
const struct output_type *target_output,
const struct specialist *target_specialist,
const struct requirement *req)
const struct requirement *req,
const enum req_problem_type prob_type)
{
bool eval = FALSE;

Expand Down Expand Up @@ -946,7 +956,8 @@ bool is_req_active(const struct player *target_player,
case VUT_UTFLAG:
eval = is_unitflag_in_range(target_unittype,
req->range, req->survives,
req->source.value.unitflag);
req->source.value.unitflag,
prob_type);
break;
case VUT_UCLASS:
eval = is_unitclass_in_range(target_unittype,
Expand Down Expand Up @@ -1011,13 +1022,14 @@ bool are_reqs_active(const struct player *target_player,
const struct unit_type *target_unittype,
const struct output_type *target_output,
const struct specialist *target_specialist,
const struct requirement_vector *reqs)
const struct requirement_vector *reqs,
const enum req_problem_type prob_type)
{
requirement_vector_iterate(reqs, preq) {
if (!is_req_active(target_player, target_city, target_building,
target_tile, target_unittype, target_output,
target_specialist,
preq)) {
preq, prob_type)) {
return FALSE;
}
} requirement_vector_iterate_end;
Expand Down
6 changes: 4 additions & 2 deletions common/requirements.h
Expand Up @@ -80,15 +80,17 @@ bool is_req_active(const struct player *target_player,
const struct unit_type *target_unittype,
const struct output_type *target_output,
const struct specialist *target_specialist,
const struct requirement *req);
const struct requirement *req,
const enum req_problem_type prob_type);
bool are_reqs_active(const struct player *target_player,
const struct city *target_city,
const struct impr_type *target_building,
const struct tile *target_tile,
const struct unit_type *target_unittype,
const struct output_type *target_output,
const struct specialist *target_specialist,
const struct requirement_vector *reqs);
const struct requirement_vector *reqs,
const enum req_problem_type prob_type);

bool is_req_unchanging(const struct requirement *req);

Expand Down
2 changes: 1 addition & 1 deletion server/citytools.c
Expand Up @@ -2134,7 +2134,7 @@ void city_landlocked_sell_coastal_improvements(struct tile *ptile)
if (VUT_TERRAIN == preq->source.kind
&& !is_req_active(city_owner(pcity), pcity, NULL,
NULL, NULL, NULL, NULL,
preq)) {
preq, TRUE)) {
do_sell_building(pplayer, pcity, impr);
notify_player(pplayer, tile1, E_IMP_SOLD,
_("You sell %s in %s (now landlocked)"
Expand Down
21 changes: 13 additions & 8 deletions server/cityturn.c
Expand Up @@ -323,7 +323,8 @@ void send_city_turn_notifications(struct conn_list *dest, struct city *pcity)
/ pcity->surplus[O_FOOD];

if (get_city_bonus(pcity, EFT_GROWTH_FOOD) == 0
&& get_current_construction_bonus(pcity, EFT_GROWTH_FOOD) > 0
&& get_current_construction_bonus(pcity, EFT_GROWTH_FOOD,
RPT_CERTAIN) > 0
&& pcity->surplus[O_SHIELD] > 0) {
/* From the check above, the surplus must always be positive. */
turns_granary = (impr_build_shield_cost(pcity->production.value)
Expand Down Expand Up @@ -475,8 +476,8 @@ static void city_increase_size(struct city *pcity)
bool rapture_grow = city_rapture_grow(pcity); /* check before size increase! */

if (!city_can_grow_to(pcity, pcity->size + 1)) { /* need improvement */
if (get_current_construction_bonus(pcity, EFT_SIZE_ADJ) > 0
|| get_current_construction_bonus(pcity, EFT_SIZE_UNLIMIT) > 0) {
if (get_current_construction_bonus(pcity, EFT_SIZE_ADJ, RPT_CERTAIN) > 0
|| get_current_construction_bonus(pcity, EFT_SIZE_UNLIMIT, RPT_CERTAIN) > 0) {
notify_player(powner, pcity->tile, E_CITY_AQ_BUILDING,
_("%s needs %s (being built) "
"to grow any further."),
Expand Down Expand Up @@ -760,7 +761,7 @@ static bool worklist_change_build_target(struct player *pplayer,
/* Nope, no use. *sigh* */
requirement_vector_iterate(&building->reqs, preq) {
if (!is_req_active(pplayer, pcity, NULL, NULL, NULL, NULL, NULL,
preq)) {
preq, RPT_POSSIBLE)) {
known = TRUE;
switch (preq->source.kind) {
case VUT_ADVANCE:
Expand Down Expand Up @@ -1160,11 +1161,14 @@ static bool city_build_building(struct player *pplayer, struct city *pcity)
}

space_part = TRUE;
if (get_current_construction_bonus(pcity, EFT_SS_STRUCTURAL) > 0) {
if (get_current_construction_bonus(pcity, EFT_SS_STRUCTURAL,
RPT_CERTAIN) > 0) {
pplayer->spaceship.structurals++;
} else if (get_current_construction_bonus(pcity, EFT_SS_COMPONENT) > 0) {
} else if (get_current_construction_bonus(pcity, EFT_SS_COMPONENT,
RPT_CERTAIN) > 0) {
pplayer->spaceship.components++;
} else if (get_current_construction_bonus(pcity, EFT_SS_MODULE) > 0) {
} else if (get_current_construction_bonus(pcity, EFT_SS_MODULE,
RPT_CERTAIN) > 0) {
pplayer->spaceship.modules++;
} else {
space_part = FALSE;
Expand Down Expand Up @@ -1199,7 +1203,8 @@ static bool city_build_building(struct player *pplayer, struct city *pcity)
* the vision range of a city */
city_refresh_vision(pcity);

if ((mod = get_current_construction_bonus(pcity, EFT_GIVE_IMM_TECH))) {
if ((mod = get_current_construction_bonus(pcity, EFT_GIVE_IMM_TECH,
RPT_CERTAIN))) {
int i;

notify_player(pplayer, NULL, E_TECH_GAIN,
Expand Down