src/order_cmd.cpp
changeset 9323 9bc423363f6a
parent 9283 624272490f5a
child 9326 326baf219dda
--- a/src/order_cmd.cpp	Fri Apr 04 21:09:28 2008 +0000
+++ b/src/order_cmd.cpp	Sat Apr 05 10:55:50 2008 +0000
@@ -23,6 +23,8 @@
 #include "settings_type.h"
 #include "string_func.h"
 #include "newgrf_cargo.h"
+#include "timetable.h"
+#include "vehicle_func.h"
 
 #include "table/strings.h"
 
@@ -1275,6 +1277,118 @@
 	return (_patches.servint_ispercent) ? Clamp(index, MIN_SERVINT_PERCENT, MAX_SERVINT_PERCENT) : Clamp(index, MIN_SERVINT_DAYS, MAX_SERVINT_DAYS);
 }
 
+/**
+ * Handle the orders of a vehicle and determine the next place
+ * to go to if needed.
+ * @param v the vehicle to do this for.
+ * @return true *if* the vehicle is eligible for reversing
+ *              (basically only when leaving a station).
+ */
+bool ProcessOrders(Vehicle *v)
+{
+	switch (v->current_order.type) {
+		case OT_GOTO_DEPOT:
+			/* Let a depot order in the orderlist interrupt. */
+			if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return false;
+
+			if ((v->current_order.flags & OFB_SERVICE_IF_NEEDED) && !VehicleNeedsService(v)) {
+				UpdateVehicleTimetable(v, true);
+				v->cur_order_index++;
+			}
+			break;
+
+		case OT_LOADING:
+		case OT_LEAVESTATION:
+			return false;
+
+		default: break;
+	}
+
+	/**
+	 * Reversing because of order change is allowed only just after leaving a
+	 * station (and the difficulty setting to allowed, of course)
+	 * this can be detected because only after OT_LEAVESTATION, current_order
+	 * will be reset to nothing. (That also happens if no order, but in that case
+	 * it won't hit the point in code where may_reverse is checked)
+	 */
+	bool may_reverse = v->current_order.type == OT_NOTHING;
+
+	/* Check if we've reached the waypoint? */
+	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
+		UpdateVehicleTimetable(v, true);
+		v->cur_order_index++;
+	}
+
+	/* Check if we've reached a non-stop station while TTDPatch nonstop is enabled.. */
+	if (_patches.new_nonstop &&
+			v->current_order.flags & OFB_NON_STOP &&
+			IsTileType(v->tile, MP_STATION) &&
+			v->current_order.dest == GetStationIndex(v->tile)) {
+		UpdateVehicleTimetable(v, true);
+		v->cur_order_index++;
+	}
+
+	/* Get the current order */
+	if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0;
+
+	const Order *order = GetVehicleOrder(v, v->cur_order_index);
+
+	/* If no order, do nothing. */
+	if (order == NULL) {
+		v->current_order.Free();
+		v->dest_tile = 0;
+		if (v->type == VEH_ROAD) ClearSlot(v);
+		return false;
+	}
+
+	/* If it is unchanged, keep it. */
+	if (order->type  == v->current_order.type &&
+			order->flags == v->current_order.flags &&
+			order->dest  == v->current_order.dest &&
+			(v->type != VEH_SHIP || order->type != OT_GOTO_STATION || GetStation(order->dest)->dock_tile != 0)) {
+		return false;
+	}
+
+	/* Otherwise set it, and determine the destination tile. */
+	v->current_order = *order;
+
+	InvalidateVehicleOrder(v);
+	switch (v->type) {
+		default:
+			NOT_REACHED();
+
+		case VEH_ROAD:
+		case VEH_TRAIN:
+			break;
+
+		case VEH_SHIP:
+			InvalidateWindowClasses(v->GetVehicleListWindowClass());
+			break;
+	}
+
+	switch (order->type) {
+		case OT_GOTO_STATION:
+			if (order->dest == v->last_station_visited) {
+				v->last_station_visited = INVALID_STATION;
+			}
+			v->dest_tile = v->GetOrderStationLocation(order->dest);
+			break;
+
+		case OT_GOTO_DEPOT:
+			v->dest_tile = GetDepot(order->dest)->xy;
+			break;
+
+		case OT_GOTO_WAYPOINT:
+			v->dest_tile = GetWaypoint(order->dest)->xy;
+			break;
+
+		default:
+			v->dest_tile = 0;
+			return false;
+	}
+
+	return may_reverse;
+}
 
 /**
  *