Author: jtn Date: Tue Jun 3 00:33:25 2014 New Revision: 25032 URL: http://svn.gna.org/viewcvs/freeciv?rev=25032&view=rev Log: Logic that checks whether an effect is prevented (in AI and UI) now checks present=FALSE requirements as well as nreqs.
Reported by Emmet Hikory (persia@gna). See gna bug #21992. Modified: trunk/ai/default/aicity.c trunk/common/effects.c trunk/common/effects.h Modified: trunk/ai/default/aicity.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aicity.c?rev=25032&r1=25031&r2=25032&view=diff ============================================================================== --- trunk/ai/default/aicity.c (original) +++ trunk/ai/default/aicity.c Tue Jun 3 00:33:25 2014 @@ -1920,11 +1920,11 @@ bool present = TRUE; bool impossible_to_get = FALSE; - if (is_effect_disabled(pplayer, NULL, pcity, pimprove, - NULL, NULL, NULL, NULL, - peffect, RPT_CERTAIN)) { - /* We believe that effect if disabled only if there is no change that it - * is not. This should lead AI using wider spectrum of improvements. + if (is_effect_prevented(pplayer, NULL, pcity, pimprove, + NULL, NULL, NULL, NULL, + peffect, RPT_CERTAIN)) { + /* We believe that effect is disabled only if there is no chance that it + * is not. This should lead to AI using wider spectrum of improvements. * * TODO: Select between RPT_POSSIBLE and RPT_CERTAIN dynamically * depending how much AI can take risks. */ Modified: trunk/common/effects.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/effects.c?rev=25032&r1=25031&r2=25032&view=diff ============================================================================== --- trunk/common/effects.c (original) +++ trunk/common/effects.c Tue Jun 3 00:33:25 2014 @@ -445,25 +445,39 @@ /************************************************************************** Return TRUE iff any of the disabling requirements for this effect are - active (an effect is active if all of its enabling requirements and - none of its disabling ones are active). -**************************************************************************/ -bool is_effect_disabled(const struct player *target_player, - const struct player *other_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 effect *peffect, - const enum req_problem_type prob_type) -{ + active, which would prevent it from taking effect. + (Assumes that any requirement specified in the ruleset with a negative + sense is an impediment.) +**************************************************************************/ +bool is_effect_prevented(const struct player *target_player, + const struct player *other_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 effect *peffect, + const enum req_problem_type prob_type) +{ + requirement_list_iterate(peffect->reqs, preq) { + /* Only check present=FALSE requirements; these will return _FALSE_ + * from is_req_active() if met, and need reversed prob_type */ + if (!preq->present + && !is_req_active(target_player, other_player, target_city, + target_building, target_tile, target_unittype, + target_output, target_specialist, + preq, REVERSED_RPT(prob_type))) { + return TRUE; + } + } requirement_list_iterate_end; requirement_list_iterate(peffect->nreqs, preq) { - if (is_req_active(target_player, other_player, target_city, - target_building, target_tile, target_unittype, - target_output, target_specialist, - preq, prob_type)) { + /* Only check present=TRUE nreqs */ + if (preq->present + && is_req_active(target_player, other_player, target_city, + target_building, target_tile, target_unittype, + target_output, target_specialist, + preq, prob_type)) { return TRUE; } } requirement_list_iterate_end; @@ -471,36 +485,9 @@ } /************************************************************************** - Return TRUE iff all of the enabling requirements for this effect are - active (an effect is active if all of its enabling requirements and - none of its disabling ones are active). -**************************************************************************/ -static bool is_effect_enabled(const struct player *target_player, - const struct player *other_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 effect *peffect, - const enum req_problem_type prob_type) -{ - requirement_list_iterate(peffect->reqs, preq) { - if (!is_req_active(target_player, other_player, target_city, - target_building, target_tile, target_unittype, - target_output, target_specialist, - preq, prob_type)) { - return FALSE; - } - } requirement_list_iterate_end; - return TRUE; -} - -/************************************************************************** Is the effect active at a certain target (player, city or building)? - - This checks whether an effect's requirements are met. + An effect is active if all of its enabling requirements and none of its + disabling ones are met. target gives the type of the target (player,city,building,tile) give the exact target @@ -517,15 +504,26 @@ const struct effect *peffect, const enum req_problem_type prob_type) { - /* Reversed prob_type when checking disabling effects */ - return is_effect_enabled(target_player, other_player, target_city, - target_building, target_tile, target_unittype, - target_output, target_specialist, - peffect, prob_type) - && !is_effect_disabled(target_player, other_player, target_city, - target_building, target_tile, target_unittype, - target_output, target_specialist, - peffect, REVERSED_RPT(prob_type)); + requirement_list_iterate(peffect->reqs, preq) { + /* Requirements ANDed together => any unmet requirement disables + * effect */ + if (!is_req_active(target_player, other_player, target_city, + target_building, target_tile, target_unittype, + target_output, target_specialist, + preq, prob_type)) { + return FALSE; + } + } requirement_list_iterate_end; + requirement_list_iterate(peffect->nreqs, preq) { + /* Reversed prob_type when checking disabling effects */ + if (is_req_active(target_player, other_player, target_city, + target_building, target_tile, target_unittype, + target_output, target_specialist, + preq, REVERSED_RPT(prob_type))) { + return FALSE; + } + } requirement_list_iterate_end; + return TRUE; } /************************************************************************** @@ -556,10 +554,10 @@ * checked depends on the range of the effect. */ /* Prob_type is not reversed here. disabled is equal to replaced, not * reverse */ - if (!is_effect_disabled(city_owner(pcity), NULL, pcity, - pimprove, - NULL, NULL, NULL, NULL, - peffect, prob_type)) { + if (!is_effect_prevented(city_owner(pcity), NULL, pcity, + pimprove, + NULL, NULL, NULL, NULL, + peffect, prob_type)) { return FALSE; } } effect_list_iterate_end; Modified: trunk/common/effects.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/effects.h?rev=25032&r1=25031&r2=25032&view=diff ============================================================================== --- trunk/common/effects.h (original) +++ trunk/common/effects.h Tue Jun 3 00:33:25 2014 @@ -340,16 +340,16 @@ /* miscellaneous auxiliary effects functions */ struct effect_list *get_req_source_effects(struct universal *psource); -bool is_effect_disabled(const struct player *target_player, - const struct player *other_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 effect *peffect, - const enum req_problem_type prob_type); +bool is_effect_prevented(const struct player *target_player, + const struct player *other_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 effect *peffect, + const enum req_problem_type prob_type); int get_player_bonus_effects(struct effect_list *plist, const struct player *pplayer, enum effect_type effect_type); _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits