(svn r8802) -Fix
authortron
Sun, 18 Feb 2007 16:24:29 +0000
changeset 6071 76b82fc24d38
parent 6070 e955cbc018ea
child 6072 2eb3e6ecba20
(svn r8802) -Fix

-Fix: When inserting an order for a ship while checking the distance between the new order and the order it is inserted after adhere the order types to determine the correct type of destination (i.e. station or depot)
Also do a better job in determining the preceding order
NOTE: 0.5 candidate
src/order_cmd.cpp
--- a/src/order_cmd.cpp	Sun Feb 18 11:45:56 2007 +0000
+++ b/src/order_cmd.cpp	Sun Feb 18 16:24:29 2007 +0000
@@ -167,6 +167,16 @@
 }
 
 
+static TileIndex GetOrderLocation(const Order& o)
+{
+	switch (o.type) {
+		default: NOT_REACHED();
+		case OT_GOTO_STATION: return GetStation(o.dest)->xy;
+		case OT_GOTO_DEPOT:   return GetDepot(o.dest)->xy;
+	}
+}
+
+
 /** Add an order to the orderlist of a vehicle.
  * @param tile unused
  * @param p1 various bitstuffed elements
@@ -343,18 +353,29 @@
 	 * handle any more then this.. */
 	if (v->num_orders >= MAX_BACKUP_ORDER_COUNT) return_cmd_error(STR_8832_TOO_MANY_ORDERS);
 
-	/* For ships, make sure that the station is not too far away from the
-	 * previous destination, for human players with new pathfinding disabled */
-	if (v->type == VEH_Ship && IsHumanPlayer(v->owner) &&
-		sel_ord != 0 && GetVehicleOrder(v, sel_ord - 1)->type == OT_GOTO_STATION
-		&& !_patches.new_pathfinding_all) {
+	if (v->type == VEH_Ship &&
+			IsHumanPlayer(v->owner) &&
+			!_patches.new_pathfinding_all) {
+		// Make sure the new destination is not too far away from the previous
+		const Order *prev = NULL;
+		uint n = 0;
 
-		int dist = DistanceManhattan(
-			GetStation(GetVehicleOrder(v, sel_ord - 1)->dest)->xy,
-			GetStation(new_order.dest)->xy // XXX type != OT_GOTO_STATION?
-		);
-		if (dist >= 130)
-			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
+		/* Find the last goto station or depot order before the insert location.
+		 * If the order is to be inserted at the beginning of the order list this
+		 * finds the last order in the list. */
+		for (const Order *o = v->orders; o != NULL; o = o->next) {
+			if (o->type == OT_GOTO_STATION || o->type == OT_GOTO_DEPOT) prev = o;
+			if (++n == sel_ord && prev != NULL) break;
+		}
+		if (prev != NULL) {
+			uint dist = DistanceManhattan(
+				GetOrderLocation(*prev),
+				GetOrderLocation(new_order)
+			);
+			if (dist >= 130) {
+				return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
+			}
+		}
 	}
 
 	if (flags & DC_EXEC) {