Author: sveinung
Date: Wed May 13 15:39:08 2015
New Revision: 29077

URL: http://svn.gna.org/viewcvs/freeciv?rev=29077&view=rev
Log:
Add moves left can unit type act test

Add the function utype_may_act_move_frags() to make it easy to test if a
unit of the specified type can perform an action when it has a certain
amount of move fragments left.

See patch #6083

Modified:
    trunk/common/unittype.c
    trunk/common/unittype.h

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=29077&r1=29076&r2=29077&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Wed May 13 15:39:08 2015
@@ -492,6 +492,37 @@
   }
 }
 
+struct range {
+  int min;
+  int max;
+};
+
+#define MOVES_LEFT_INFINITY -1
+
+/**************************************************************************
+  Get the legal range of move fragments left of the specified requirement
+  vector.
+**************************************************************************/
+static struct range *moves_left_range(struct requirement_vector *reqs)
+{
+  struct range *prange = fc_malloc(sizeof(prange));
+
+  prange->min = 0;
+  prange->max = MOVES_LEFT_INFINITY;
+
+  requirement_vector_iterate(reqs, preq) {
+    if (preq->source.kind == VUT_MINMOVES) {
+      if (preq->present) {
+        prange->min = preq->source.value.minmoves;
+      } else {
+        prange->max = preq->source.value.minmoves;
+      }
+    }
+  } requirement_vector_iterate_end;
+
+  return prange;
+}
+
 /**************************************************************************
   Cache if any action may be possible for a unit of the type putype given
   the property tested for. Since a it could be ignored both present and
@@ -559,6 +590,52 @@
 
   return BV_ISSET(dipl_rel_action_cache[utype_id][action_id],
       requirement_diplrel_ereq(prop, REQ_RANGE_LOCAL, is_there));
+}
+
+/**************************************************************************
+  Return TRUE iff the given (action enabler controlled) action may be
+  performed by a unit of the given type that has the given number of move
+  fragments left.
+
+  Note: Values aren't cached. If a performance critical user appears it
+  would be a good idea to cache the (merged) ranges of move fragments
+  where a unit of the given type can perform the specified action.
+**************************************************************************/
+bool utype_may_act_move_frags(struct unit_type *punit_type,
+                              const int action_id,
+                              const int move_fragments)
+{
+  struct range *ml_range;
+
+  if (action_get_actor_kind(action_id) != AAK_UNIT) {
+    /* This action isn't performed by any unit at all so this unit type
+     * can't do it. */
+    return FALSE;
+  }
+
+  action_enabler_list_iterate(action_enablers_for_action(action_id),
+                              enabler) {
+    if (!requirement_fulfilled_by_unit_type(punit_type,
+                                            &(enabler->actor_reqs))) {
+      /* This action can't be performed by this unit type at all. */
+      continue;
+    }
+
+    ml_range = moves_left_range(&(enabler->actor_reqs));
+    if (ml_range->min <= move_fragments
+        && (ml_range->max == MOVES_LEFT_INFINITY
+            || ml_range->max > move_fragments)) {
+      /* The number of move fragments is in range of the action enabler. */
+
+      free(ml_range);
+
+      return TRUE;
+    }
+
+    free(ml_range);
+  } action_enabler_list_iterate_end;
+
+  return FALSE;
 }
 
 /****************************************************************************

Modified: trunk/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.h?rev=29077&r1=29076&r2=29077&view=diff
==============================================================================
--- trunk/common/unittype.h     (original)
+++ trunk/common/unittype.h     Wed May 13 15:39:08 2015
@@ -538,6 +538,10 @@
                                      const int prop,
                                      const bool is_there);
 
+bool utype_may_act_move_frags(struct unit_type *punit_type,
+                              const int action_id,
+                              const int move_fragments);
+
 /* Functions to operate on various flag and roles. */
 typedef bool (*role_unit_callback)(struct unit_type *ptype, void *data);
 


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

Reply via email to