(svn r12593) -Codechange: hide Order's flags in most of the code.
authorrubidium
Sun, 06 Apr 2008 15:09:45 +0000
changeset 8843 45fdf630deaa
parent 8842 ed3fb21d71c6
child 8844 acb298434295
(svn r12593) -Codechange: hide Order's flags in most of the code.
src/ai/default/default.cpp
src/ai/trolly/trolly.cpp
src/aircraft_cmd.cpp
src/economy.cpp
src/industry_cmd.cpp
src/openttd.cpp
src/order_base.h
src/order_cmd.cpp
src/order_gui.cpp
src/order_type.h
src/roadveh_cmd.cpp
src/ship_cmd.cpp
src/timetable_cmd.cpp
src/timetable_gui.cpp
src/train_cmd.cpp
src/vehicle.cpp
src/vehicle_gui.cpp
--- a/src/ai/default/default.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/ai/default/default.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -2554,9 +2554,9 @@
 
 		order.MakeGoToStation(AiGetStationIdByDef(aib->use_tile, aib->cur_building_rule));
 
-		if (!is_pass && i == 1) order.flags |= OFB_UNLOAD;
+		if (!is_pass && i == 1) order.SetUnloadType(OFB_UNLOAD);
 		if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0))
-			order.flags |= OFB_FULL_LOAD;
+			order.SetLoadType(OFB_FULL_LOAD);
 
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
@@ -3289,9 +3289,9 @@
 
 		order.MakeGoToStation(AiGetStationIdFromRoadBlock(aib->use_tile, aib->cur_building_rule));
 
-		if (!is_pass && i == 1) order.flags |= OFB_UNLOAD;
+		if (!is_pass && i == 1) order.SetUnloadType(OFB_UNLOAD);
 		if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0))
-			order.flags |= OFB_FULL_LOAD;
+			order.SetLoadType(OFB_FULL_LOAD);
 
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
@@ -3568,9 +3568,9 @@
 
 		order.MakeGoToStation(AiGetStationIdFromAircraftBlock(aib->use_tile, aib->cur_building_rule));
 
-		if (!is_pass && i == 1) order.flags |= OFB_UNLOAD;
+		if (!is_pass && i == 1) order.SetUnloadType(OFB_UNLOAD);
 		if (_players_ai[p->index].num_want_fullload != 0 && (is_pass || i == 0))
-			order.flags |= OFB_FULL_LOAD;
+			order.SetLoadType(OFB_FULL_LOAD);
 
 		DoCommand(0, loco_id + (i << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 	}
--- a/src/ai/trolly/trolly.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/ai/trolly/trolly.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -1191,13 +1191,13 @@
 	idx = 0;
 	order.MakeGoToStation(GetStationIndex(_players_ainew[p->index].to_tile));
 	if (_players_ainew[p->index].tbt == AI_TRUCK && _players_ainew[p->index].to_deliver)
-		order.flags |= OFB_FULL_LOAD;
+		order.SetLoadType(OFB_FULL_LOAD);
 	AI_DoCommand(0, _players_ainew[p->index].veh_id + (idx << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 
 	idx = 0;
 	order.MakeGoToStation(GetStationIndex(_players_ainew[p->index].from_tile));
 	if (_players_ainew[p->index].tbt == AI_TRUCK && _players_ainew[p->index].from_deliver)
-		order.flags |= OFB_FULL_LOAD;
+		order.SetLoadType(OFB_FULL_LOAD);
 	AI_DoCommand(0, _players_ainew[p->index].veh_id + (idx << 16), order.Pack(), DC_EXEC, CMD_INSERT_ORDER);
 
 	// Start the engines!
--- a/src/aircraft_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/aircraft_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -570,13 +570,14 @@
 	if (v->type != VEH_AIRCRAFT || !CheckOwnership(v->owner) || v->IsInDepot()) return CMD_ERROR;
 
 	if (v->current_order.IsType(OT_GOTO_DEPOT) && !(p2 & DEPOT_LOCATE_HANGAR)) {
-		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
+		bool halt_in_depot = HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT);
+		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
 			/* We called with a different DEPOT_SERVICE setting.
 			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
 			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
 			if (flags & DC_EXEC) {
-				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
-				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+				v->current_order.SetDepotOrderType(OFB_MANUAL_ORDER);
+				v->current_order.SetDepotActionType(halt_in_depot ? OFB_NORMAL_ACTION : OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 			}
 			return CommandCost();
@@ -584,7 +585,10 @@
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
 		if (flags & DC_EXEC) {
-			if (v->current_order.flags & OFB_UNLOAD) v->cur_order_index++;
+			/* If the orders to 'goto depot' are in the orders list (forced servicing),
+			 * then skip to the next order; effectively cancelling this forced service */
+			if (v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS) v->cur_order_index++;
+
 			v->current_order.MakeDummy();
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 		}
@@ -606,7 +610,7 @@
 			if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
 
 			v->current_order.MakeGoToDepot(next_airport_index, false);
-			if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+			if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(OFB_HALT_IN_DEPOT);
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 			if (v->u.air.state == FLYING && !next_airport_has_hangar) {
 				/* The aircraft is now heading for a different hangar than the next in the orders */
--- a/src/economy.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/economy.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -1489,7 +1489,7 @@
 			if (!cp->paid_for &&
 					cp->source != last_visited &&
 					HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) &&
-					(front_v->current_order.flags & OFB_TRANSFER) == 0) {
+					(front_v->current_order.GetUnloadType() & OFB_TRANSFER) == 0) {
 				/* Deliver goods to the station */
 				st->time_since_unload = 0;
 
@@ -1502,8 +1502,8 @@
 				result |= 1;
 
 				SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
-			} else if (front_v->current_order.flags & (OFB_UNLOAD | OFB_TRANSFER)) {
-				if (!cp->paid_for && (front_v->current_order.flags & OFB_TRANSFER) != 0) {
+			} else if (front_v->current_order.GetUnloadType() & (OFB_UNLOAD | OFB_TRANSFER)) {
+				if (!cp->paid_for && (front_v->current_order.GetUnloadType() & OFB_TRANSFER) != 0) {
 					Money profit = GetTransportedGoodsIncome(
 						cp->count,
 						/* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */
@@ -1556,7 +1556,7 @@
 
 	/* We have not waited enough time till the next round of loading/unloading */
 	if (--v->load_unload_time_rem != 0) {
-		if (_patches.improved_load && HasBit(v->current_order.flags, OF_FULL_LOAD)) {
+		if (_patches.improved_load && HasBit(v->current_order.GetLoadType(), OF_FULL_LOAD)) {
 			/* 'Reserve' this cargo for this vehicle, because we were first. */
 			for (; v != NULL; v = v->Next()) {
 				if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
@@ -1604,12 +1604,12 @@
 			uint amount_unloaded = _patches.gradual_loading ? min(cargo_count, load_amount) : cargo_count;
 			bool remaining; // Are there cargo entities in this vehicle that can still be unloaded here?
 
-			if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.flags & OFB_TRANSFER)) {
+			if (HasBit(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE) && !(u->current_order.GetUnloadType() & OFB_TRANSFER)) {
 				/* The cargo has reached it's final destination, the packets may now be destroyed */
 				remaining = v->cargo.MoveTo(NULL, amount_unloaded, CargoList::MTA_FINAL_DELIVERY, last_visited);
 
 				result |= 1;
-			} else if (u->current_order.flags & (OFB_UNLOAD | OFB_TRANSFER)) {
+			} else if (u->current_order.GetUnloadType() & (OFB_UNLOAD | OFB_TRANSFER)) {
 				remaining = v->cargo.MoveTo(&ge->cargo, amount_unloaded);
 				SetBit(ge->acceptance_pickup, GoodsEntry::PICKUP);
 
@@ -1638,7 +1638,7 @@
 		}
 
 		/* Do not pick up goods that we unloaded */
-		if (u->current_order.flags & OFB_UNLOAD) continue;
+		if (u->current_order.GetUnloadType() & OFB_UNLOAD) continue;
 
 		/* update stats */
 		int t;
@@ -1710,7 +1710,7 @@
 	 * all wagons at the same time instead of using the same 'improved'
 	 * loading algorithm for the wagons (only fill wagon when there is
 	 * enough to fill the previous wagons) */
-	if (_patches.improved_load && HasBit(u->current_order.flags, OF_FULL_LOAD)) {
+	if (_patches.improved_load && HasBit(u->current_order.GetLoadType(), OF_FULL_LOAD)) {
 		/* Update left cargo */
 		for (v = u; v != NULL; v = v->Next()) {
 			if (v->cargo_cap != 0) cargo_left[v->cargo_type] -= v->cargo_cap - v->cargo.Count();
@@ -1729,7 +1729,7 @@
 		}
 	} else {
 		bool finished_loading = true;
-		if (HasBit(v->current_order.flags, OF_FULL_LOAD)) {
+		if (HasBit(v->current_order.GetLoadType(), OF_FULL_LOAD)) {
 			if (_patches.full_load_any) {
 				/* if the aircraft carries passengers and is NOT full, then
 				 * continue loading, no matter how much mail is in */
--- a/src/industry_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/industry_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -1967,13 +1967,13 @@
 		 */
 		const Order *o;
 		FOR_VEHICLE_ORDERS(v, o) {
-			if (o->IsType(OT_GOTO_STATION) && !HasBit(o->flags, OF_TRANSFER)) {
+			if (o->IsType(OT_GOTO_STATION) && !HasBit(o->GetUnloadType(), OF_TRANSFER)) {
 				/* Vehicle visits a station to load or unload */
 				Station *st = GetStation(o->GetDestination());
 				if (!st->IsValid()) continue;
 
 				/* Same cargo produced by industry is dropped here => not serviced by vehicle v */
-				if (HasBit(o->flags, OF_UNLOAD) && !c_accepts) break;
+				if (HasBit(o->GetUnloadType(), OF_UNLOAD) && !c_accepts) break;
 
 				if (stations.find(st) != stations.end()) {
 					if (v->owner == _local_player) return 2; // Player services industry
--- a/src/openttd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/openttd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -2306,7 +2306,8 @@
 		Order *order;
 		FOR_ALL_ORDERS(order) {
 			if (order->IsType(OT_GOTO_STATION) && GetStation(order->GetDestination())->IsBuoy()) {
-				order->flags = 0;
+				order->SetLoadType(0);
+				order->SetUnloadType(0);
 			}
 		}
 
--- a/src/order_base.h	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/order_base.h	Sun Apr 06 15:09:45 2008 +0000
@@ -36,7 +36,7 @@
 public:
 	Order *next;          ///< Pointer to next order. If NULL, end of list
 
-	uint8  flags;
+	uint8 flags;          ///< 'Sub'type of order
 
 	uint16 wait_time;    ///< How long in ticks to wait at the destination.
 	uint16 travel_time;  ///< How long in ticks the journey to this destination should take.
@@ -98,8 +98,9 @@
 
 	/**
 	 * Makes this order a Loading order.
+	 * @param ordered is this an ordered stop?
 	 */
-	void MakeLoading();
+	void MakeLoading(bool ordered);
 
 	/**
 	 * Makes this order a Leave Station order.
@@ -160,6 +161,28 @@
 	 */
 	void SetRefit(CargoID cargo, byte subtype = 0);
 
+	/** How must the consist be loaded? */
+	inline byte GetLoadType() const { return this->flags & OFB_FULL_LOAD; }
+	/** How must the consist be unloaded? */
+	inline byte GetUnloadType() const { return GB(this->flags, 0, 2); }
+	/** Where must we stop? */
+	inline byte GetNonStopType() const { return this->flags & OFB_NON_STOP; }
+	/** What caused us going to the depot? */
+	inline byte GetDepotOrderType() const { return this->flags; }
+	/** What are we going to do when in the depot. */
+	inline byte GetDepotActionType() const { return this->flags; }
+
+	/** Set how the consist must be loaded. */
+	inline void SetLoadType(byte load_type) { SB(this->flags, 2, 1, !!load_type); }
+	/** Set how the consist must be unloaded. */
+	inline void SetUnloadType(byte unload_type) { SB(this->flags, 0, 2, unload_type); }
+	/** Set whether we must stop at stations or not. */
+	inline void SetNonStopType(byte non_stop_type) { SB(this->flags, 3, 1, !!non_stop_type); }
+	/** Set the cause to go to the depot. */
+	inline void SetDepotOrderType(byte depot_order_type) { this->flags = depot_order_type; }
+	/** Set what we are going to do in the depot. */
+	inline void SetDepotActionType(byte depot_service_type) { this->flags = depot_service_type; }
+
 	bool ShouldStopAtStation(const Vehicle *v, StationID station) const;
 
 	/**
--- a/src/order_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/order_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -70,9 +70,10 @@
 	this->dest = destination;
 }
 
-void Order::MakeLoading()
+void Order::MakeLoading(bool ordered)
 {
 	this->type = OT_LOADING;
+	if (!ordered) this->flags = 0;
 }
 
 void Order::MakeLeaveStation()
@@ -160,7 +161,7 @@
 	 * Sanity check
 	 * TTD stores invalid orders as OT_NOTHING with non-zero flags/station
 	 */
-	if (!order.IsValid() && (order.flags != 0 || order.GetDestination() != 0)) {
+	if (!order.IsValid() && (order.GetLoadType() != 0 || order.GetUnloadType() != 0 || order.GetDestination() != 0)) {
 		order.MakeDummy();
 	}
 
@@ -393,8 +394,8 @@
 			/* Order flags can be any of the following for waypoints:
 			 * [non-stop]
 			 * non-stop orders (if any) are only valid for trains */
-			switch (new_order.flags) {
-				case 0: break;
+			switch (new_order.GetNonStopType()) {
+				case OFB_NO_NON_STOP: break;
 
 				case OFB_NON_STOP:
 					if (v->type != VEH_TRAIN) return CMD_ERROR;
@@ -595,9 +596,8 @@
 
 			/* NON-stop flag is misused to see if a train is in a station that is
 			 * on his order list or not */
-			if (sel_ord == u->cur_order_index && u->current_order.IsType(OT_LOADING) &&
-					HasBit(u->current_order.flags, OF_NON_STOP)) {
-				u->current_order.flags = 0;
+			if (sel_ord == u->cur_order_index && u->current_order.IsType(OT_LOADING)) {
+				u->current_order.SetNonStopType(OFB_NO_NON_STOP);
 			}
 
 			/* Update any possible open window of the vehicle */
@@ -634,12 +634,7 @@
 
 		if (v->type == VEH_ROAD) ClearSlot(v);
 
-		if (v->current_order.IsType(OT_LOADING)) {
-			v->LeaveStation();
-			/* NON-stop flag is misused to see if a train is in a station that is
-			 * on his order list or not */
-			if (HasBit(v->current_order.flags, OF_NON_STOP)) v->current_order.flags = 0;
-		}
+		if (v->current_order.IsType(OT_LOADING)) v->LeaveStation();
 
 		InvalidateVehicleOrder(v);
 	}
@@ -808,8 +803,8 @@
 				 */
 				if (sel_ord == u->cur_order_index &&
 						!u->current_order.IsType(OT_GOTO_DEPOT) &&
-						HasBit(u->current_order.flags, OF_FULL_LOAD) != HasBit(order->flags, OF_FULL_LOAD)) {
-					ToggleBit(u->current_order.flags, OF_FULL_LOAD);
+						u->current_order.GetLoadType() != order->GetLoadType()) {
+					u->current_order.SetLoadType(order->GetLoadType());
 				}
 				InvalidateVehicleOrder(u);
 			}
@@ -990,7 +985,7 @@
 			InvalidateVehicleOrder(u);
 
 			/* If the vehicle already got the current depot set as current order, then update current order as well */
-			if (u->cur_order_index == order_number && HasBit(u->current_order.flags, OF_PART_OF_ORDERS)) {
+			if (u->cur_order_index == order_number && HasBit(u->current_order.GetDepotOrderType(), OF_PART_OF_ORDERS)) {
 				u->current_order.SetRefit(cargo, subtype);
 			}
 		}
@@ -1373,9 +1368,9 @@
 	switch (v->current_order.GetType()) {
 		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.GetDepotOrderType() & OFB_PART_OF_ORDERS)) return false;
 
-			if ((v->current_order.flags & OFB_SERVICE_IF_NEEDED) && !VehicleNeedsService(v)) {
+			if ((v->current_order.GetDepotOrderType() & OFB_SERVICE_IF_NEEDED) && !VehicleNeedsService(v)) {
 				UpdateVehicleTimetable(v, true);
 				v->cur_order_index++;
 			}
@@ -1408,7 +1403,7 @@
 
 	/* 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 &&
+			v->current_order.GetNonStopType() & OFB_NON_STOP &&
 			IsTileType(v->tile, MP_STATION) &&
 			v->current_order.GetDestination() == GetStationIndex(v->tile)) {
 		v->last_station_visited = v->current_order.GetDestination();
--- a/src/order_gui.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/order_gui.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -215,14 +215,14 @@
 						SetDParam(2, GetDepot(order->GetDestination())->town_index);
 
 						switch (v->type) {
-							case VEH_TRAIN: s = (order->flags & OFB_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
+							case VEH_TRAIN: s = (order->GetNonStopType() & OFB_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
 							case VEH_ROAD:  s = STR_GO_TO_ROADVEH_DEPOT; break;
 							case VEH_SHIP:  s = STR_GO_TO_SHIP_DEPOT; break;
 							default: break;
 						}
 					}
 
-					if (order->flags & OFB_FULL_LOAD) s++; /* service at */
+					if (order->GetDepotOrderType() & OFB_SERVICE_IF_NEEDED) s++; /* service at */
 
 					SetDParam(1, s);
 					if (order->IsRefit()) {
@@ -235,7 +235,7 @@
 				}
 
 				case OT_GOTO_WAYPOINT:
-					SetDParam(1, (order->flags & OFB_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
+					SetDParam(1, (order->GetNonStopType() & OFB_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
 					SetDParam(2, order->GetDestination());
 					break;
 
--- a/src/order_type.h	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/order_type.h	Sun Apr 06 15:09:45 2008 +0000
@@ -52,8 +52,10 @@
 
 	//Flags for depots:
 	/** The current depot-order was initiated because it was in the vehicle's order list */
+	OFB_MANUAL_ORDER       = 0x0,
 	OFB_PART_OF_ORDERS     = 0x2,
 	/** if OFB_PART_OF_ORDERS is not set, this will cause the vehicle to be stopped in the depot */
+ 	OFB_NORMAL_ACTION      = 0x0,
 	OFB_HALT_IN_DEPOT      = 0x4,
 	/** if OFB_PART_OF_ORDERS is set, this will cause the order only be come active if the vehicle needs servicing */
 	OFB_SERVICE_IF_NEEDED  = 0x4, //used when OFB_PART_OF_ORDERS is set.
@@ -61,6 +63,7 @@
 	//Common flags
 	/** This causes the vehicle not to stop at intermediate OR the destination station (depending on patch settings)
 	  * @todo make this two different flags */
+	OFB_NO_NON_STOP        = 0x0,
 	OFB_NON_STOP           = 0x8
 };
 
--- a/src/roadveh_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/roadveh_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -477,13 +477,14 @@
 
 	/* If the current orders are already goto-depot */
 	if (v->current_order.IsType(OT_GOTO_DEPOT)) {
-		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
+		bool halt_in_depot = HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT);
+		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
 			/* We called with a different DEPOT_SERVICE setting.
 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
 			if (flags & DC_EXEC) {
-				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
-				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+				v->current_order.SetDepotOrderType(OFB_MANUAL_ORDER);
+				v->current_order.SetDepotActionType(halt_in_depot ? OFB_NORMAL_ACTION : OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 			}
 			return CommandCost();
@@ -493,8 +494,7 @@
 		if (flags & DC_EXEC) {
 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
 			 * then skip to the next order; effectively cancelling this forced service */
-			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS))
-				v->cur_order_index++;
+			if (v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS) v->cur_order_index++;
 
 			v->current_order.MakeDummy();
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
@@ -510,7 +510,7 @@
 
 		ClearSlot(v);
 		v->current_order.MakeGoToDepot(dep->index, false);
-		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(OFB_HALT_IN_DEPOT);
 		v->dest_tile = dep->xy;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 	}
@@ -1929,7 +1929,7 @@
 	}
 
 	if (v->current_order.IsType(OT_GOTO_DEPOT) &&
-			v->current_order.flags & OFB_NON_STOP &&
+			v->current_order.GetNonStopType() & OFB_NON_STOP &&
 			!Chance16(1, 20)) {
 		return;
 	}
--- a/src/ship_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/ship_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -943,13 +943,14 @@
 
 	/* If the current orders are already goto-depot */
 	if (v->current_order.IsType(OT_GOTO_DEPOT)) {
-		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
+		bool halt_in_depot = HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT);
+		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
 			/* We called with a different DEPOT_SERVICE setting.
 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 			if (flags & DC_EXEC) {
-				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
-				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+				v->current_order.SetDepotOrderType(OFB_MANUAL_ORDER);
+				v->current_order.SetDepotActionType(halt_in_depot ? OFB_NORMAL_ACTION : OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 			}
 			return CommandCost();
@@ -959,8 +960,7 @@
 		if (flags & DC_EXEC) {
 			/* If the orders to 'goto depot' are in the orders list (forced servicing),
 			 * then skip to the next order; effectively cancelling this forced service */
-			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS))
-				v->cur_order_index++;
+			if (v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS) v->cur_order_index++;
 
 			v->current_order.MakeDummy();
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
@@ -976,7 +976,7 @@
 
 		v->dest_tile = dep->xy;
 		v->current_order.MakeGoToDepot(dep->index, false);
-		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(OFB_HALT_IN_DEPOT);
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 	}
 
--- a/src/timetable_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/timetable_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -24,7 +24,7 @@
 		order->wait_time = time;
 	}
 
-	if (v->cur_order_index == order_number && HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
+	if (v->cur_order_index == order_number && HasBit(v->current_order.GetDepotOrderType(), OF_PART_OF_ORDERS)) {
 		if (is_journey) {
 			v->current_order.travel_time = time;
 		} else {
@@ -70,7 +70,7 @@
 	bool is_journey = HasBit(p1, 24) || packed_time;
 	if (!is_journey) {
 		if (!order->IsType(OT_GOTO_STATION)) return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
-		if (_patches.new_nonstop && (order->flags & OFB_NON_STOP)) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
+		if (_patches.new_nonstop && (order->GetNonStopType() & OFB_NON_STOP)) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
 	}
 
 	if (flags & DC_EXEC) {
--- a/src/timetable_gui.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/timetable_gui.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -79,7 +79,7 @@
 			w->EnableWidget(TTV_CLEAR_TIME);
 		} else {
 			const Order *order = GetVehicleOrder(v, (selected + 1) / 2);
-			bool disable = order == NULL || !order->IsType(OT_GOTO_STATION) || (_patches.new_nonstop && (order->flags & OFB_NON_STOP));
+			bool disable = order == NULL || !order->IsType(OT_GOTO_STATION) || (_patches.new_nonstop && (order->GetNonStopType() & OFB_NON_STOP));
 
 			w->SetWidgetDisabledState(TTV_CHANGE_TIME, disable);
 			w->SetWidgetDisabledState(TTV_CLEAR_TIME, disable);
@@ -119,7 +119,7 @@
 					break;
 
 				case OT_GOTO_STATION:
-					SetDParam(0, (order->flags & OFB_NON_STOP) ? STR_880A_GO_NON_STOP_TO : STR_8806_GO_TO);
+					SetDParam(0, (order->GetNonStopType() & OFB_NON_STOP) ? STR_880A_GO_NON_STOP_TO : STR_8806_GO_TO);
 					SetDParam(1, order->GetDestination());
 
 					if (order->wait_time > 0) {
@@ -139,20 +139,20 @@
 						SetDParam(1, GetDepot(order->GetDestination())->town_index);
 
 						switch (v->type) {
-							case VEH_TRAIN: string = (order->flags & OFB_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
+							case VEH_TRAIN: string = (order->GetNonStopType() & OFB_NON_STOP) ? STR_880F_GO_NON_STOP_TO_TRAIN_DEPOT : STR_GO_TO_TRAIN_DEPOT; break;
 							case VEH_ROAD:  string = STR_GO_TO_ROADVEH_DEPOT; break;
 							case VEH_SHIP:  string = STR_GO_TO_SHIP_DEPOT; break;
 							default: break;
 						}
 					}
 
-					if (order->flags & OFB_FULL_LOAD) string++; // Service at orders
+					if (order->GetDepotOrderType() & OFB_SERVICE_IF_NEEDED) string++; /* service at */
 
 					SetDParam(0, string);
 				} break;
 
 				case OT_GOTO_WAYPOINT:
-					SetDParam(0, (order->flags & OFB_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
+					SetDParam(0, (order->GetNonStopType() & OFB_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
 					SetDParam(1, order->GetDestination());
 					break;
 
@@ -197,7 +197,7 @@
 		for (const Order *order = GetVehicleOrder(v, 0); order != NULL; order = order->next) {
 			total_time += order->travel_time + order->wait_time;
 			if (order->travel_time == 0) complete = false;
-			if (order->wait_time == 0 && order->IsType(OT_GOTO_STATION) && !(_patches.new_nonstop && (order->flags & OFB_NON_STOP))) complete = false;
+			if (order->wait_time == 0 && order->IsType(OT_GOTO_STATION) && !(_patches.new_nonstop && (order->GetNonStopType() & OFB_NON_STOP))) complete = false;
 		}
 
 		if (total_time != 0) {
--- a/src/train_cmd.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/train_cmd.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -2108,13 +2108,14 @@
 	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 
 	if (v->current_order.IsType(OT_GOTO_DEPOT)) {
-		if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) {
+		bool halt_in_depot = HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT);
+		if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) {
 			/* We called with a different DEPOT_SERVICE setting.
 			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 			if (flags & DC_EXEC) {
-				ClrBit(v->current_order.flags, OF_PART_OF_ORDERS);
-				ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+				v->current_order.SetDepotOrderType(OFB_MANUAL_ORDER);
+				v->current_order.SetDepotActionType(halt_in_depot ? OFB_NORMAL_ACTION : OFB_HALT_IN_DEPOT);
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 			}
 			return CommandCost();
@@ -2122,9 +2123,9 @@
 
 		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 		if (flags & DC_EXEC) {
-			if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
-				v->cur_order_index++;
-			}
+			/* If the orders to 'goto depot' are in the orders list (forced servicing),
+			 * then skip to the next order; effectively cancelling this forced service */
+			if (v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS) v->cur_order_index++;
 
 			v->current_order.MakeDummy();
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
@@ -2144,7 +2145,7 @@
 
 		v->dest_tile = tfdd.tile;
 		v->current_order.MakeGoToDepot(GetDepotByTile(tfdd.tile)->index, false);
-		if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(OFB_HALT_IN_DEPOT);
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
 		/* If there is no depot in front, reverse automatically */
 		if (tfdd.reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
--- a/src/vehicle.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/vehicle.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -120,10 +120,10 @@
 bool VehicleNeedsService(const Vehicle *v)
 {
 	if (v->vehstatus & (VS_STOPPED | VS_CRASHED))       return false;
-	if (!v->current_order.IsType(OT_GOTO_DEPOT) || !(v->current_order.flags & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list
+	if (!v->current_order.IsType(OT_GOTO_DEPOT) || !(v->current_order.GetDepotOrderType() & OFB_PART_OF_ORDERS)) { // Don't interfere with a depot visit by the order list
 		if (_patches.gotodepot && VehicleHasDepotOrders(v)) return false;
 		if (v->current_order.IsType(OT_LOADING))            return false;
-		if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.flags & OFB_HALT_IN_DEPOT) return false;
+		if (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() & OFB_HALT_IN_DEPOT) return false;
 	}
 
 	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
@@ -631,7 +631,7 @@
 {
 	/* We need to set v->leave_depot_instantly as we have no control of it's contents at this time.
 	 * Vehicle should stop in the depot if it was in 'stopping' state - train intered depot while slowing down. */
-	if ((HasBit(v->current_order.flags, OF_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OF_PART_OF_ORDERS) && v->current_order.IsType(OT_GOTO_DEPOT)) ||
+	if ((HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT) && !HasBit(v->current_order.GetDepotOrderType(), OF_PART_OF_ORDERS) && v->current_order.IsType(OT_GOTO_DEPOT)) ||
 			(v->vehstatus & VS_STOPPED)) {
 		/* we keep the vehicle in the depot since the user ordered it to stay */
 		v->leave_depot_instantly = false;
@@ -2174,7 +2174,7 @@
 		max += v->cargo_cap;
 		if (v->cargo_cap != 0) {
 			unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0;
-			loading |= (u->current_order.flags & OFB_UNLOAD) == 0 && st->goods[v->cargo_type].days_since_pickup != 255;
+			loading |= !HasBit(u->current_order.GetUnloadType(), OF_UNLOAD) && st->goods[v->cargo_type].days_since_pickup != 255;
 			cars++;
 		}
 	}
@@ -2262,11 +2262,11 @@
 			}
 		}
 
-		if (HasBit(t.flags, OF_PART_OF_ORDERS)) {
+		if (HasBit(t.GetDepotOrderType(), OF_PART_OF_ORDERS)) {
 			/* Part of orders */
 			UpdateVehicleTimetable(v, true);
 			v->cur_order_index++;
-		} else if (HasBit(t.flags, OF_HALT_IN_DEPOT)) {
+		} else if (HasBit(t.GetDepotActionType(), OF_HALT_IN_DEPOT)) {
 			/* Force depot visit */
 			v->vehstatus |= VS_STOPPED;
 			if (v->owner == _local_player) {
@@ -3132,23 +3132,20 @@
 
 	if (this->current_order.IsType(OT_GOTO_STATION) &&
 			this->current_order.GetDestination() == this->last_station_visited) {
-		/* Arriving at the ordered station.
-		 * Keep the load/unload flags, as we (obviously) still need them. */
-		this->current_order.flags &= OFB_FULL_LOAD | OFB_UNLOAD | OFB_TRANSFER;
-
 		/* Furthermore add the Non Stop flag to mark that this station
 		 * is the actual destination of the vehicle, which is (for example)
 		 * necessary to be known for HandleTrainLoading to determine
 		 * whether the train is lost or not; not marking a train lost
 		 * that arrives at random stations is bad. */
-		this->current_order.flags |= OFB_NON_STOP;
+		this->current_order.SetNonStopType(OFB_NON_STOP);
+
+		current_order.MakeLoading(true);
 		UpdateVehicleTimetable(this, true);
 	} else {
-		/* This is just an unordered intermediate stop */
-		this->current_order.flags = 0;
+		this->current_order.SetNonStopType(OFB_NO_NON_STOP);
+		current_order.MakeLoading(false);
 	}
 
-	current_order.MakeLoading();
 	GetStation(this->last_station_visited)->loading_vehicles.push_back(this);
 
 	VehiclePayment(this);
@@ -3167,7 +3164,7 @@
 	assert(current_order.IsType(OT_LOADING));
 
 	/* Only update the timetable if the vehicle was supposed to stop here. */
-	if (current_order.flags & OFB_NON_STOP) UpdateVehicleTimetable(this, false);
+	if (current_order.GetNonStopType() != OFB_NO_NON_STOP) UpdateVehicleTimetable(this, false);
 
 	current_order.MakeLeaveStation();
 	GetStation(this->last_station_visited)->loading_vehicles.remove(this);
@@ -3193,7 +3190,7 @@
 			this->LeaveStation();
 
 			/* If this was not the final order, don't remove it from the list. */
-			if (!(b.flags & OFB_NON_STOP)) return;
+			if (!(b.GetNonStopType() & OFB_NON_STOP)) return;
 			break;
 		}
 
--- a/src/vehicle_gui.cpp	Sun Apr 06 14:50:47 2008 +0000
+++ b/src/vehicle_gui.cpp	Sun Apr 06 15:09:45 2008 +0000
@@ -1969,7 +1969,7 @@
 					SetDParam(0, depot->town_index);
 					SetDParam(1, v->GetDisplaySpeed());
 				}
-				if (HasBit(v->current_order.flags, OF_HALT_IN_DEPOT) && !HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
+				if (HasBit(v->current_order.GetDepotActionType(), OF_HALT_IN_DEPOT) && !HasBit(v->current_order.GetDepotOrderType(), OF_PART_OF_ORDERS)) {
 					str = _heading_for_depot_strings[v->type] + _patches.vehicle_speed;
 				} else {
 					str = _heading_for_depot_service_strings[v->type] + _patches.vehicle_speed;