Author: sveinung Date: Mon Mar 10 12:02:14 2014 New Revision: 24644 URL: http://svn.gna.org/viewcvs/freeciv?rev=24644&view=rev Log: AI: Check that a city isn't immune to a spy action because of action enablers
when thinking about targeting it. See patch #4587 Modified: trunk/ai/default/aidiplomat.c trunk/common/actions.c trunk/common/actions.h Modified: trunk/ai/default/aidiplomat.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aidiplomat.c?rev=24644&r1=24643&r2=24644&view=diff ============================================================================== --- trunk/ai/default/aidiplomat.c (original) +++ trunk/ai/default/aidiplomat.c Mon Mar 10 12:02:14 2014 @@ -216,6 +216,8 @@ } incite_cost = city_incite_cost(pplayer, acity); if (HOSTILE_PLAYER(ait, pplayer, city_owner(acity)) + && is_action_possible_on_city(ACTION_SPY_INCITE_CITY, + pplayer, acity) && (incite_cost < INCITE_IMPOSSIBLE_COST) && (incite_cost < pplayer->economic.gold - expenses)) { /* incite gain (FIXME: we should count wonders too but need to @@ -230,6 +232,10 @@ } if ((player_research_get(city_owner(acity))->techs_researched < player_research_get(pplayer)->techs_researched) + && (is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH, + pplayer, acity) + || is_action_possible_on_city(ACTION_SPY_STEAL_TECH, + pplayer, acity)) && !pplayers_allied(pplayer, city_owner(acity))) { /* tech theft gain */ gain_theft = total_bulbs_required(pplayer) * TRADE_WEIGHTING; @@ -258,7 +264,9 @@ utype_build_shield_cost(ut)); if (!player_has_embassy(pplayer, city_owner(acity)) - && want < 99) { + && want < 99 + && is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY, + pplayer, acity)) { log_base(LOG_DIPLOMAT_BUILD, "A diplomat desired in %s to establish an embassy with %s " "in %s", @@ -422,6 +430,7 @@ struct city *acity; struct player *aplayer; bool can_incite; + bool can_steal; acity = tile_city(ptile); @@ -438,18 +447,27 @@ } incite_cost = city_incite_cost(pplayer, acity); - can_incite = (incite_cost < INCITE_IMPOSSIBLE_COST); + can_incite = (incite_cost < INCITE_IMPOSSIBLE_COST) + && is_action_possible_on_city(ACTION_SPY_INCITE_CITY, + pplayer, acity); + + can_steal = is_action_possible_on_city(ACTION_SPY_STEAL_TECH, + pplayer, acity) + || is_action_possible_on_city(ACTION_SPY_TARGETED_STEAL_TECH, + pplayer, acity); dipldef = (count_diplomats_on_tile(acity->tile) > 0); /* Three actions to consider: * 1. establishing embassy OR * 2. stealing techs OR * 3. inciting revolt */ - if (!has_embassy + if ((!has_embassy + && is_action_possible_on_city(ACTION_ESTABLISH_EMBASSY, + pplayer, acity)) || (acity->server.steal == 0 + && !dipldef && can_steal && (player_research_get(pplayer)->techs_researched - < player_research_get(aplayer)->techs_researched) - && !dipldef) + < player_research_get(aplayer)->techs_researched)) || (incite_cost < (pplayer->economic.gold - expenses) && can_incite && !dipldef)) { if (!is_city_surrounded_by_our_spies(pplayer, acity)) { Modified: trunk/common/actions.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=24644&r1=24643&r2=24644&view=diff ============================================================================== --- trunk/common/actions.c (original) +++ trunk/common/actions.c Mon Mar 10 12:02:14 2014 @@ -649,3 +649,47 @@ return TRUE; } + +/************************************************************************** + Returns TRUE if the wanted action can be done to the target. +**************************************************************************/ +static bool is_target_possible(const enum gen_action wanted_action, + const struct player *actor_player, + 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) +{ + action_enabler_list_iterate(action_enablers_for_action(wanted_action), + enabler) { + if (are_reqs_active(target_player, actor_player, target_city, + target_building, target_tile, target_unittype, + target_output, target_specialist, + &enabler->target_reqs, RPT_CERTAIN)) { + return TRUE; + } + } action_enabler_list_iterate_end; + + return FALSE; +} + +/************************************************************************** + Returns TRUE if the wanted action can be done to the target city. +**************************************************************************/ +bool is_action_possible_on_city(const enum gen_action action_id, + const struct player *actor_player, + struct city* target_city) +{ + fc_assert_ret_val_msg(ATK_CITY == action_get_target_kind(action_id), + FALSE, "Action %s is against %s not cities", + gen_action_name(action_id), + action_target_kind_name( + action_get_target_kind(action_id))); + + return is_target_possible(action_id, actor_player, + city_owner(target_city), target_city, NULL, + city_tile(target_city), NULL, NULL, NULL); +} Modified: trunk/common/actions.h URL: http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.h?rev=24644&r1=24643&r2=24644&view=diff ============================================================================== --- trunk/common/actions.h (original) +++ trunk/common/actions.h Mon Mar 10 12:02:14 2014 @@ -182,6 +182,10 @@ /* Reasoning about actions */ bool action_immune_government(struct government *gov, int act); +bool is_action_possible_on_city(const enum gen_action action_id, + const struct player *actor_player, + struct city* target_city); + #ifdef __cplusplus } #endif /* __cplusplus */ _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits