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

Reply via email to