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

Reply via email to