Author: sveinung
Date: Tue Aug  4 13:27:53 2015
New Revision: 29321

URL: http://svn.gna.org/viewcvs/freeciv?rev=29321&view=rev
Log:
Help: A unit type can't perform an action when a hard requirement prevents it

See patch #6162

Modified:
    trunk/client/helpdata.c
    trunk/common/actions.c
    trunk/common/actions.h

Modified: trunk/client/helpdata.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/helpdata.c?rev=29321&r1=29320&r2=29321&view=diff
==============================================================================
--- trunk/client/helpdata.c     (original)
+++ trunk/client/helpdata.c     Tue Aug  4 13:27:53 2015
@@ -4003,8 +4003,9 @@
     }
 
     action_enabler_list_iterate(action_enablers_for_action(act), enabler) {
-      if (requirement_fulfilled_by_unit_type(utype,
-                                             &(enabler->actor_reqs))) {
+      if (action_actor_utype_hard_reqs_ok(act, utype)
+          && requirement_fulfilled_by_unit_type(utype,
+                                                &(enabler->actor_reqs))) {
         switch (act) {
         case ACTION_HELP_WONDER:
           cat_snprintf(buf, bufsz,

Modified: trunk/common/actions.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=29321&r1=29320&r2=29321&view=diff
==============================================================================
--- trunk/common/actions.c      (original)
+++ trunk/common/actions.c      Tue Aug  4 13:27:53 2015
@@ -428,6 +428,41 @@
 }
 
 /**************************************************************************
+  Returns TRUE if the specified unit type can perform the wanted action
+  given that an action enabler later will enable it.
+
+  This is done by checking the action's hard requirements. Hard
+  requirements must be TRUE before an action can be done. The reason why
+  is usually that code dealing with the action assumes that the
+  requirements are true. A requirement may also end up here if it can't be
+  expressed in a requirement vector or if its absence makes the action
+  pointless.
+
+  When adding a new hard requirement here:
+   * explain why it is a hard requirement in a comment.
+**************************************************************************/
+bool
+action_actor_utype_hard_reqs_ok(const enum gen_action wanted_action,
+                                const struct unit_type *actor_unittype)
+{
+  if (wanted_action == ACTION_JOIN_CITY) {
+    if (utype_pop_value(actor_unittype) <= 0) {
+      /* Reason: Must have population to add. */
+      return FALSE;
+    }
+  }
+
+  if (wanted_action == ACTION_BOMBARD) {
+    if (actor_unittype->bombard_rate <= 0) {
+      /* Reason: Can't bombard if it never fires. */
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+/**************************************************************************
   Returns TRUE if the wanted action is possible given that an action
   enabler later will enable it.
 
@@ -472,6 +507,13 @@
                     && target_unit != NULL),
                 "Missing target!");
 
+  if (!action_actor_utype_hard_reqs_ok(wanted_action, actor_unittype)) {
+    /* Info leak: The actor player knows the type of his unit. */
+    /* The actor unit type can't perform the action because of hard
+     * unit type requirements. */
+    return FALSE;
+  }
+
   if (action_get_actor_kind(wanted_action) == AAK_UNIT) {
     /* The Freeciv code for all actions controlled by enablers assumes that
      * an acting unit is on the same tile as its target or on the tile next
@@ -624,12 +666,6 @@
       return FALSE;
     }
 
-    if (unit_pop_value(actor_unit) <= 0) {
-      /* Reason: Must have population to add. */
-      /* Info leak: The actor player knows the type of his unit. */
-      return FALSE;
-    }
-
     /* TODO: Move more individual requirements to the action enabler. */
     if (!unit_can_add_to_city(actor_unit)) {
       return FALSE;
@@ -637,12 +673,6 @@
   }
 
   if (wanted_action == ACTION_BOMBARD) {
-    if (actor_unittype->bombard_rate <= 0) {
-      /* Reason: Can't bombard if it never fires. */
-      /* Info leak: This is about unit type so it is safe. */
-      return FALSE;
-    }
-
     /* TODO: Move to the ruleset. */
     if (!pplayers_at_war(unit_owner(target_unit), actor_player)) {
       return FALSE;

Modified: trunk/common/actions.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.h?rev=29321&r1=29320&r2=29321&view=diff
==============================================================================
--- trunk/common/actions.h      (original)
+++ trunk/common/actions.h      Tue Aug  4 13:27:53 2015
@@ -248,6 +248,10 @@
 
 bool action_prob_possible(action_probability probability);
 
+bool
+action_actor_utype_hard_reqs_ok(const enum gen_action wanted_action,
+                                const struct unit_type *actor_unittype);
+
 /* Reasoning about actions */
 bool action_immune_government(struct government *gov, int act);
 


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to