Author: sveinung
Date: Fri May 15 13:33:08 2015
New Revision: 29092

URL: http://svn.gna.org/viewcvs/freeciv?rev=29092&view=rev
Log:
Order execution waiting: Consider action enabler move fragment requirements

The order execution code will wait a turn if a unit don't have enough
movement points to execute its order this turn but will have it next turn.
An action enabler controlled action may require that the actor has a minimum
(or, if !present, maximum) amount of movement fragments left.
Some orders cause an action enabler controlled action to be performed.

Order execution waiting was done by consulting a hard coded information
about what orders required the unit to have at least one move fragment and
what orders didn't care about movement. This information could be wrong
since Freeciv no longer hard codes the move fragment left requirement of
some actions. A ruleset may make an order that used to require at least one
move fragment require two move fragments or ignore move fragments all
together.

Stop assuming that the action enablers of the action an order will result in
implements the rules that used to be hard coded. Only wait if an order that
currently is impossible because of move fragments may become possible next
turn.

See bug #23589

Modified:
    branches/S2_6/server/unittools.c

Modified: branches/S2_6/server/unittools.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/server/unittools.c?rev=29092&r1=29091&r2=29092&view=diff
==============================================================================
--- branches/S2_6/server/unittools.c    (original)
+++ branches/S2_6/server/unittools.c    Fri May 15 13:33:08 2015
@@ -3703,6 +3703,46 @@
   return cancel;
 }
 
+/**************************************************************************
+  Returns TRUE iff punit currently don't have enough move fragments to
+  perform the specified action but will have it next turn.
+**************************************************************************/
+static bool should_wait_for_mp(struct unit *punit, int action_id)
+{
+  return !utype_may_act_move_frags(unit_type(punit),
+                                   action_id,
+                                   punit->moves_left)
+      && utype_may_act_move_frags(unit_type(punit),
+                                  action_id,
+                                  unit_move_rate(punit));
+}
+
+/**************************************************************************
+  Returns the action id corresponding to the specified order id.
+**************************************************************************/
+static int order_to_action(struct unit *punit, enum unit_orders order)
+{
+  switch (order) {
+  case ORDER_BUILD_WONDER:
+    return ACTION_HELP_WONDER;
+  case ORDER_TRADE_ROUTE:
+    return ACTION_TRADE_ROUTE;
+  case ORDER_MOVE:
+  case ORDER_ACTION_MOVE:
+  case ORDER_FULL_MP:
+  case ORDER_BUILD_CITY:
+  case ORDER_ACTIVITY:
+  case ORDER_DISBAND:
+  case ORDER_HOMECITY:
+  case ORDER_LAST:
+    /* Not action enabler controlled. */
+    break;
+  }
+
+  fc_assert_msg(FALSE, "No action to map order to.");
+  return ACTION_COUNT;
+}
+
 /****************************************************************************
   Executes a unit's orders stored in punit->orders.  The unit is put on idle
   if an action fails or if "patrol" is set and an enemy unit is encountered.
@@ -3767,23 +3807,30 @@
     moves_made++;
 
     order = punit->orders.list[punit->orders.index];
-    if (0 == punit->moves_left) {
-      switch (order.order) {
-      case ORDER_MOVE:
-      case ORDER_ACTION_MOVE:
-      case ORDER_FULL_MP:
-      case ORDER_BUILD_CITY:
+
+    switch (order.order) {
+    case ORDER_MOVE:
+    case ORDER_ACTION_MOVE:
+    case ORDER_FULL_MP:
+    case ORDER_BUILD_CITY:
+      if (0 == punit->moves_left) {
         log_debug("  stopping because of no more move points");
         return TRUE;
-      case ORDER_ACTIVITY:
-      case ORDER_DISBAND:
-      case ORDER_BUILD_WONDER:
-      case ORDER_TRADE_ROUTE:
-      case ORDER_HOMECITY:
-      case ORDER_LAST:
-        /* Those actions don't require moves left. */
-        break;
-      }
+      }
+      break;
+    case ORDER_BUILD_WONDER:
+    case ORDER_TRADE_ROUTE:
+      if (should_wait_for_mp(punit, order_to_action(punit, order.order))) {
+        log_debug("  stopping. Not enough move points this turn");
+        return TRUE;
+      }
+      break;
+    case ORDER_ACTIVITY:
+    case ORDER_DISBAND:
+    case ORDER_HOMECITY:
+    case ORDER_LAST:
+      /* Those actions don't require moves left. */
+      break;
     }
 
     last_order = (!punit->orders.repeat


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

Reply via email to