(svn r955) Replace uint16 for orders with struct Order
authortron
Sun, 05 Dec 2004 12:43:04 +0000
changeset 555 eec6c0294435
parent 554 670b089d7772
child 556 d6b9bbfe0596
(svn r955) Replace uint16 for orders with struct Order
This adds no functionality, but is a stepping stone for future improvement (like 16bit order indices) and is easier to read.
This changes preserves binary compatibility wrt savegames.
ai.c
ai_new.c
aircraft_cmd.c
aircraft_gui.c
disaster_cmd.c
economy.c
engine.c
oldloader.c
order_cmd.c
order_gui.c
rail_cmd.c
roadveh_cmd.c
roadveh_gui.c
ship_cmd.c
ship_gui.c
station_cmd.c
train_cmd.c
train_gui.c
vehicle.c
vehicle.h
--- a/ai.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/ai.c	Sun Dec 05 12:43:04 2004 +0000
@@ -248,7 +248,7 @@
 
 static void AiHandleGotoDepot(Player *p, int cmd)
 {
-	if ((p->ai.cur_veh->next_order & OT_MASK) != OT_GOTO_DEPOT)
+	if (p->ai.cur_veh->current_order.type != OT_GOTO_DEPOT)
 		DoCommandByTile(0, p->ai.cur_veh->index, 0, DC_EXEC, cmd);
 
 	if (++p->ai.state_counter <= 1387) {
@@ -256,18 +256,20 @@
 		return;
 	}
 
-	if ((p->ai.cur_veh->next_order&OT_MASK) == OT_GOTO_DEPOT) {
-		p->ai.cur_veh->next_order = OT_DUMMY;
+	if (p->ai.cur_veh->current_order.type == OT_GOTO_DEPOT) {
+		p->ai.cur_veh->current_order.type = OT_DUMMY;
+		p->ai.cur_veh->current_order.flags = 0;
 		InvalidateWindow(WC_VEHICLE_VIEW, p->ai.cur_veh->index);
 	}
 }
 
 static void AiRestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
 {
-	uint16 *os = bak->order, ord;
+	const Order *os = bak->order;
 	int ind = 0;
-	while ((ord = *os++) != 0) {
-		if (DoCommandByTile(0, v->index + (ind << 16), ord, DC_EXEC, CMD_INSERT_ORDER) == CMD_ERROR)
+
+	while (os++->type != OT_NOTHING) {
+		if (DoCommandByTile(0, v->index + (ind << 16), PackOrder(os), DC_EXEC, CMD_INSERT_ORDER) == CMD_ERROR)
 			break;
 		ind++;
 	}
@@ -3519,7 +3521,7 @@
 		if (v->type == VEH_Train) {
 
 			if (!IsTrainDepotTile(v->tile) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
-				if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
+				if (v->current_order.type != OT_GOTO_DEPOT)
 					DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_TRAIN_GOTO_DEPOT);
 				goto going_to_depot;
 			}
@@ -3529,7 +3531,7 @@
 
 		} else if (v->type == VEH_Road) {
 			if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
-				if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
+				if (v->current_order.type != OT_GOTO_DEPOT)
 					DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
 				goto going_to_depot;
 			}
@@ -3537,7 +3539,7 @@
 			DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
 		} else if (v->type == VEH_Aircraft) {
 			if (!IsAircraftHangarTile(v->tile) && !(v->vehstatus&VS_STOPPED)) {
-				if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
+				if (v->current_order.type != OT_GOTO_DEPOT)
 					DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
 				goto going_to_depot;
 			}
@@ -3554,8 +3556,9 @@
 	if (++p->ai.state_counter <= 832)
 		return;
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
-		v->next_order = OT_DUMMY;
+	if (v->current_order.type == OT_GOTO_DEPOT) {
+		v->current_order.type = OT_DUMMY;
+		v->current_order.flags = 0;
 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 	}
 return_to_loop:;
@@ -3566,7 +3569,7 @@
 {
 	// Remove stations that aren't in use by any vehicle
 	byte in_use[256], *used;
-	uint16 *ord;
+	Order *ord;
 	Station *st;
 	uint tile;
 
@@ -3575,9 +3578,9 @@
 
 	// Get a list of all stations that are in use by a vehicle
 	memset(in_use, 0, sizeof(in_use));
-	for(ord=_order_array; ord != _ptr_to_next_order; ord++) {
-		if ((*ord & OT_MASK) == OT_GOTO_STATION)
-			in_use[*ord >> 8] = 1;
+	for (ord = _order_array; ord != _ptr_to_next_order; ++ord) {
+		if (ord->type == OT_GOTO_STATION)
+			in_use[ord->station] = 1;
 	}
 
 	// Go through all stations and delete those that aren't in use
--- a/ai_new.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/ai_new.c	Sun Dec 05 12:43:04 2004 +0000
@@ -497,17 +497,18 @@
 static bool AiNew_CheckVehicleStation(Player *p, Station *st) {
 	int count = 0;
 	Vehicle *v;
-	uint16 *sched;
-	uint16 ord;
 
 	// Also check if we don't have already a lot of busses to this city...
 	FOR_ALL_VEHICLES(v) {
 		if (v->owner == _current_player) {
-			sched = v->schedule_ptr;
-			while (sched != NULL && (ord=*sched++) != 0) {
-				if ((ord & OT_MASK) == OT_GOTO_STATION && DEREF_STATION(ord >> 8) == st) {
-					// This vehicle has this city in his list
-					count++;
+			const Order *sched = v->schedule_ptr;
+			if (sched != NULL) {
+				for (; sched->type != OT_NOTHING; ++sched) {
+					if (sched->type == OT_GOTO_STATION &&
+							DEREF_STATION(sched->station) == st) {
+						// This vehicle has this city in his list
+						count++;
+					}
 				}
 			}
 		}
--- a/aircraft_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/aircraft_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -198,7 +198,9 @@
 
 		_new_aircraft_id = v->index;
 
-		*(v->schedule_ptr = _ptr_to_next_order++) = 0;
+		_ptr_to_next_order->type = OT_NOTHING;
+		_ptr_to_next_order->flags = 0;
+		v->schedule_ptr = _ptr_to_next_order++;
 		// the AI doesn't click on a tile to build airplanes, so the below code will
 		// never work. Therefore just assume the AI's planes always come from Hangar0
 		// On hold for NewAI
@@ -361,11 +363,11 @@
 	if (!CheckOwnership(v->owner))
 		return CMD_ERROR;
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
 		if (flags & DC_EXEC) {
- 			if (v->next_order&OF_UNLOAD)
- 				{ v->cur_order_index++; }
-			v->next_order = OT_DUMMY;
+			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 	} else {
@@ -376,8 +378,9 @@
 					return CMD_ERROR;
 
 		if (flags & DC_EXEC) {
-			v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
-			v->next_order_param = v->u.air.targetairport;
+			v->current_order.type = OT_GOTO_DEPOT;
+			v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
+			v->current_order.station = v->u.air.targetairport;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 	}
@@ -466,21 +469,24 @@
 	if (v->vehstatus & VS_STOPPED)
 		return;
 
-	if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD))
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			v->current_order.flags & OF_FULL_LOAD)
 		return;
 
  	if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
  		return;
 
-	st = DEREF_STATION(v->next_order_param);
+	st = DEREF_STATION(v->current_order.station);
 	// only goto depot if the target airport has terminals (eg. it is airport)
 	if (st->xy != 0 && st->airport_tile != 0 && GetAirport(st->airport_type)->nofterminals != 0) {
 //		printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
 //		v->u.air.targetairport = st->index;
-		v->next_order = OF_NON_STOP | OT_GOTO_DEPOT;
+		v->current_order.type = OT_GOTO_DEPOT;
+		v->current_order.flags = OF_NON_STOP;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
-	} else if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
-		v->next_order = OT_DUMMY;
+	} else if (v->current_order.type == OT_GOTO_DEPOT) {
+		v->current_order.type = OT_DUMMY;
+		v->current_order.flags = 0;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 	}
 }
@@ -552,7 +558,7 @@
 
 	// if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
 	// loading/unloading at a terminal or stopped
-	if ((v->next_order&OT_MASK) == OT_LOADING || (v->vehstatus&VS_STOPPED)) {
+	if (v->current_order.type == OT_LOADING || (v->vehstatus & VS_STOPPED)) {
 		if (u->cur_speed != 0) {
 			u->cur_speed++;
 			if (u->cur_speed >= 0x80 && u->cur_image == 0xF40) {
@@ -983,15 +989,18 @@
 
 static void ProcessAircraftOrder(Vehicle *v)
 {
-	uint order;
+	Order order;
 
 	// OT_GOTO_DEPOT, OT_LOADING
- 	if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LOADING) {
- 		if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
+	if (v->current_order.type >= OT_GOTO_DEPOT &&
+			v->current_order.type <= OT_LOADING) {
+		if (v->current_order.type != OT_GOTO_DEPOT ||
+				!(v->current_order.flags & OF_UNLOAD))
  			return;
  	}
 
- 	if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
  			SERVICE_INTERVAL) {
  		v->cur_order_index++;
  	}
@@ -1001,21 +1010,23 @@
 
 	order = v->schedule_ptr[v->cur_order_index];
 
-	if (order == 0) {
-		v->next_order = OT_NOTHING;
+	if (order.type == OT_NOTHING) {
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 		return;
 	}
 
-	if (order == (uint)((v->next_order | (v->next_order_param<<8))))
+	if (order.type == v->current_order.type &&
+			order.flags == v->current_order.flags &&
+			order.station == v->current_order.station)
 		return;
 
-	v->next_order = (byte)order;
-	v->next_order_param = (byte)(order >> 8);
+	v->current_order = order;
 
 	// orders are changed in flight, ensure going to the right station
-	if ((order & OT_MASK) == OT_GOTO_STATION && v->u.air.state == FLYING) {
+	if (order.type == OT_GOTO_STATION && v->u.air.state == FLYING) {
 		AircraftNextAirportPos_and_Order(v);
-		v->u.air.targetairport = order >> 8;
+		v->u.air.targetairport = order.station;
 	}
 
 	InvalidateVehicleOrderWidget(v);
@@ -1023,11 +1034,11 @@
 
 static void HandleAircraftLoading(Vehicle *v, int mode)
 {
-	if (v->next_order == OT_NOTHING)
+	if (v->current_order.type == OT_NOTHING)
 		return;
 
-	if (v->next_order != OT_DUMMY) {
-		if ((v->next_order&OT_MASK) != OT_LOADING)
+	if (v->current_order.type != OT_DUMMY) {
+		if (v->current_order.type != OT_LOADING)
 			return;
 
 		if (mode != 0)
@@ -1036,16 +1047,17 @@
 		if (--v->load_unload_time_rem)
 			return;
 
-		if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
+		if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
 			SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
 			LoadUnloadVehicle(v);
 			return;
 		}
 
 		{
-			byte b = v->next_order;
-			v->next_order = OT_NOTHING;
-			if (!(b & OF_NON_STOP))
+			Order b = v->current_order;
+			v->current_order.type = OT_NOTHING;
+			v->current_order.flags = 0;
+			if (!(b.flags & OF_NON_STOP))
 				return;
 		}
 	}
@@ -1105,9 +1117,9 @@
 static void AircraftEntersTerminal(Vehicle *v)
 {
 	Station *st;
-	byte old_order;
+	Order old_order;
 
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT)
+	if (v->current_order.type == OT_GOTO_DEPOT)
 		return;
 
 	st = DEREF_STATION(v->u.air.targetairport);
@@ -1128,12 +1140,14 @@
 			0);
 	}
 
-	old_order = v->next_order;
-	v->next_order = OT_LOADING;
+	old_order = v->current_order;
+	v->current_order.type = OT_LOADING;
+	v->current_order.flags = 0;
 
-	if ((old_order & OT_MASK) == OT_GOTO_STATION &&
-			v->next_order_param == v->last_station_visited) {
-		v->next_order = OT_LOADING | (old_order & (OF_UNLOAD|OF_FULL_LOAD)) | OF_NON_STOP;
+	if (old_order.type == OT_GOTO_STATION &&
+			v->current_order.station == v->last_station_visited) {
+		v->current_order.flags =
+			(old_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) | OF_NON_STOP;
 	}
 
 	SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
@@ -1143,7 +1157,7 @@
 
 static void AircraftEnterHangar(Vehicle *v)
 {
-	byte old_order;
+	Order old_order;
 
 	ServiceAircraft(v);
 
@@ -1151,15 +1165,16 @@
 
 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
-		old_order = v->next_order;
-		v->next_order = OT_NOTHING;
+		old_order = v->current_order;
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 
- 			if (old_order & OF_UNLOAD) { v->cur_order_index++; }
-
- 			else if (old_order & OF_FULL_LOAD) { // force depot visit
+		if (old_order.flags & OF_UNLOAD) {
+			v->cur_order_index++;
+		} else if (old_order.flags & OF_FULL_LOAD) { // force depot visit
 			v->vehstatus |= VS_STOPPED;
 
 			if (v->owner == _local_player) {
@@ -1192,9 +1207,9 @@
 	Station *st;
 	const AirportFTAClass *Airport;
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_STATION ||
-			(v->next_order&OT_MASK) == OT_GOTO_DEPOT)
-			v->u.air.targetairport = v->next_order_param;
+	if (v->current_order.type == OT_GOTO_STATION ||
+			v->current_order.type == OT_GOTO_DEPOT)
+		v->u.air.targetairport = v->current_order.station;
 
 	st = DEREF_STATION(v->u.air.targetairport);
 	Airport = GetAirport(st->airport_type);
@@ -1248,19 +1263,22 @@
 		return;
 	}
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT && (v->vehstatus&VS_STOPPED)) { // if we were sent to the depot, stay there
-		v->next_order = OT_NOTHING;
+	// if we were sent to the depot, stay there
+	if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) {
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 		return;
 	}
 
-	if ((v->next_order&OT_MASK) != OT_GOTO_STATION && (v->next_order&OT_MASK) != OT_GOTO_DEPOT)
+	if (v->current_order.type != OT_GOTO_STATION &&
+			v->current_order.type != OT_GOTO_DEPOT)
 		return;
 
 	// if the block of the next position is busy, stay put
 	if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {return;}
 
 	// We are already at the target airport, we need to find a terminal
-	if (v->next_order_param == v->u.air.targetairport) {
+	if (v->current_order.station == v->u.air.targetairport) {
 		// FindFreeTerminal:
 		// 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal
 		if (v->subtype != 0) {if(!AirportFindFreeTerminal(v, Airport)) {return;}} // airplane
@@ -1294,8 +1312,7 @@
 		return;
 	}
 
-	// removed &0x1F
-	if (v->next_order == OT_NOTHING) {return;}
+	if (v->current_order.type == OT_NOTHING) return;
 
 	// if the block of the next position is busy, stay put
 	if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {
@@ -1305,19 +1322,20 @@
 	// airport-road is free. We either have to go to another airport, or to the hangar
 	// ---> start moving
 
-	switch (v->next_order&OT_MASK) {
+	switch (v->current_order.type) {
 		case OT_GOTO_STATION: // ready to fly to another airport
 			// airplane goto state takeoff, helicopter to helitakeoff
 			v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
 			break;
 		case OT_GOTO_DEPOT:   // visit hangar for serivicing, sale, etc.
-			if (v->next_order_param == v->u.air.targetairport)
+			if (v->current_order.station == v->u.air.targetairport)
 				v->u.air.state = HANGAR;
 			else
 				v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
 			break;
 		default:  // orders have been deleted (no orders), goto depot and don't bother us
-			v->next_order  = OT_NOTHING;
+			v->current_order.type = OT_NOTHING;
+			v->current_order.flags = 0;
 			v->u.air.state = HANGAR;
 	}
 	AirportMove(v, Airport);
@@ -1423,7 +1441,7 @@
 	// 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
 	// 2. not going for terminal (but depot, no order),
 	// --> get out of the way to the hangar.
-	if ((v->next_order&OT_MASK) == OT_GOTO_STATION) {
+	if (v->current_order.type == OT_GOTO_STATION) {
 		if (AirportFindFreeTerminal(v, Airport)) {return;}
 	}
 	v->u.air.state = HANGAR;
@@ -1442,7 +1460,7 @@
 	// --> else TAKEOFF
 	// the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
 	// must go to a hangar.
-	if ((v->next_order&OT_MASK) == OT_GOTO_STATION) {
+	if (v->current_order.type == OT_GOTO_STATION) {
 		if (AirportFindFreeHelipad(v, Airport)) {return;}
 	}
 	v->u.air.state = (Airport->nofterminals != 0) ? HANGAR : HELITAKEOFF;
@@ -1720,7 +1738,7 @@
 	ProcessAircraftOrder(v);
 	HandleAircraftLoading(v, loop);
 
-	if ((v->next_order&OT_MASK) >= OT_LOADING)
+	if (v->current_order.type >= OT_LOADING)
 		return;
 
 	// pass the right airport structure to the functions
--- a/aircraft_gui.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/aircraft_gui.c	Sun Dec 05 12:43:04 2004 +0000
@@ -547,15 +547,15 @@
 		} else if (v->vehstatus & VS_STOPPED) {
 			str = STR_8861_STOPPED;
 		} else {
-			switch(v->next_order & OT_MASK) {
+			switch (v->current_order.type) {
 			case OT_GOTO_STATION: {
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				SetDParam(1, v->cur_speed * 8);
 				str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
 			} break;
 
 			case OT_GOTO_DEPOT: {
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				SetDParam(1, v->cur_speed * 8);
 				str = STR_HEADING_FOR_HANGAR + _patches.vehicle_speed;
 			} break;
@@ -857,15 +857,15 @@
 }
 
 static void DrawSmallSchedule(Vehicle *v, int x, int y) {
-	uint16 *sched;
+	const Order *sched;
 	int sel;
-	uint ord;
+	Order ord;
 	int i = 0;
 
 	sched = v->schedule_ptr;
 	sel = v->cur_order_index;
 
-	while ((ord=*sched++) != 0) {
+	while ((ord = *sched++).type != OT_NOTHING) {
 		if (sel == 0) {
 			_stringwidth_base = 0xE0;
 			DoDrawString( "\xAF", x-6, y, 16);
@@ -873,8 +873,8 @@
 		}
 		sel--;
 
-		if ((ord & OT_MASK) == OT_GOTO_STATION) {
-			SetDParam(0, ord >> 8);
+		if (ord.type == OT_GOTO_STATION) {
+			SetDParam(0, ord.station);
 			DrawString(x, y, STR_A036, 0);
 
 			y += 6;
--- a/disaster_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/disaster_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -79,7 +79,9 @@
 	v->owner = OWNER_NONE;
 	v->vehstatus = VS_UNCLICKABLE;
 	v->u.disaster.image_override = 0;
-	v->next_order = 0;
+	v->current_order.type = OT_NOTHING;
+	v->current_order.flags = 0;
+	v->current_order.station = 0;
 
 	DisasterVehicleUpdateImage(v);
 	VehiclePositionChanged(v);
@@ -141,7 +143,7 @@
 
 	++v->tick_counter;
 
-	if (v->next_order < 2) {
+	if (v->current_order.station < 2) {
 		if (v->tick_counter&1)
 			return;
 
@@ -149,23 +151,23 @@
 
 		SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
 
-		if (v->next_order == 1) {
+		if (v->current_order.station == 1) {
 			if (++v->age == 38) {
-				v->next_order = 2;
+				v->current_order.station = 2;
 				v->age = 0;
 			}
 
 			if ((v->tick_counter&7)==0) {
 				CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
 			}
-		} else if (v->next_order == 0) {
+		} else if (v->current_order.station == 0) {
 			tile = v->tile; /**/
 
 			if (IS_TILETYPE(tile, MP_STATION) &&
 				IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
 				IS_HUMAN_PLAYER(_map_owner[tile])) {
 
-				v->next_order = 1;
+				v->current_order.station = 1;
 				v->age = 0;
 
 				SetDParam(0, _map2[tile]);
@@ -180,7 +182,7 @@
 		return;
 	}
 
-	if (v->next_order > 2) {
+	if (v->current_order.station > 2) {
 		if (++v->age <= 13320)
 			return;
 
@@ -223,7 +225,7 @@
 				EV_DEMOLISH);
 		}
 	} else if (v->age == 350) {
-		v->next_order = 3;
+		v->current_order.station = 3;
 		v->age = 0;
 	}
 
@@ -248,7 +250,7 @@
 
 	v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
 
-	if (v->next_order == 0) {
+	if (v->current_order.station == 0) {
 // fly around randomly
 		int x = GET_TILE_X(v->dest_tile)*16;
 		int y = GET_TILE_Y(v->dest_tile)*16;
@@ -262,7 +264,7 @@
 			v->dest_tile = TILE_MASK(Random());
 			return;
 		}
-		v->next_order = 1;
+		v->current_order.station = 1;
 
 		FOR_ALL_VEHICLES(u) {
 			if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
@@ -336,7 +338,8 @@
 	GetNewVehiclePosResult gp;
 
 	v->tick_counter++;
-	v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF4F : 0;
+	v->u.disaster.image_override =
+		(v->current_order.station == 1 && v->tick_counter&4) ? 0xF4F : 0;
 
 	GetNewVehiclePos(v, &gp);
 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
@@ -346,7 +349,7 @@
 		return;
 	}
 
-	if (v->next_order == 2) {
+	if (v->current_order.station == 2) {
 		if (!(v->tick_counter&3)) {
 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
 			int x = GET_TILE_X(i->xy)*16;
@@ -360,13 +363,13 @@
 				EV_DEMOLISH);
 
 			if (++v->age >= 55)
-				v->next_order = 3;
+				v->current_order.station = 3;
 		}
-	} else if (v->next_order == 1) {
+	} else if (v->current_order.station == 1) {
 		if (++v->age == 112) {
 			Industry *i;
 
-			v->next_order = 2;
+			v->current_order.station = 2;
 			v->age = 0;
 
 			i = DEREF_INDUSTRY(v->dest_tile);
@@ -376,7 +379,7 @@
 			AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
 		}
-	} else if (v->next_order == 0) {
+	} else if (v->current_order.station == 0) {
 		int x,y;
 		uint tile;
 		int ind;
@@ -394,7 +397,7 @@
 		v->dest_tile = ind = _map2[tile];
 
 		if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
-			v->next_order = 1;
+			v->current_order.station = 1;
 			v->age = 0;
 		}
 	}
@@ -406,7 +409,8 @@
 	GetNewVehiclePosResult gp;
 
 	v->tick_counter++;
-	v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF53 : 0;
+	v->u.disaster.image_override =
+		(v->current_order.station == 1 && v->tick_counter&4) ? 0xF53 : 0;
 
 	GetNewVehiclePos(v, &gp);
 	SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
@@ -416,7 +420,7 @@
 		return;
 	}
 
-	if (v->next_order == 2) {
+	if (v->current_order.station == 2) {
 		if (!(v->tick_counter&3)) {
 			Industry *i = DEREF_INDUSTRY(v->dest_tile);
 			int x = GET_TILE_X(i->xy)*16;
@@ -430,13 +434,13 @@
 				EV_DEMOLISH);
 
 			if (++v->age >= 55)
-				v->next_order = 3;
+				v->current_order.station = 3;
 		}
-	} else if (v->next_order == 1) {
+	} else if (v->current_order.station == 1) {
 		if (++v->age == 112) {
 			Industry *i;
 
-			v->next_order = 2;
+			v->current_order.station = 2;
 			v->age = 0;
 
 			i = DEREF_INDUSTRY(v->dest_tile);
@@ -446,7 +450,7 @@
 			AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
 			SndPlayTileFx(SND_12_EXPLOSION, i->xy);
 		}
-	} else if (v->next_order == 0) {
+	} else if (v->current_order.station == 0) {
 		int x,y;
 		uint tile;
 		int ind;
@@ -464,7 +468,7 @@
 		v->dest_tile = ind = _map2[tile];
 
 		if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
-			v->next_order = 1;
+			v->current_order.station = 1;
 			v->age = 0;
 		}
 	}
@@ -496,7 +500,7 @@
 
 	v->tick_counter++;
 
-	if (v->next_order == 1) {
+	if (v->current_order.station == 1) {
 		int x = GET_TILE_X(v->dest_tile)*16 + 8;
 		int y = GET_TILE_Y(v->dest_tile)*16 + 8;
 		if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
@@ -513,7 +517,7 @@
 			return;
 		}
 
-		v->next_order = 2;
+		v->current_order.station = 2;
 
 		FOR_ALL_VEHICLES(u) {
 			if (u->type == VEH_Train || u->type == VEH_Road) {
@@ -547,7 +551,7 @@
 		u->next = w;
 		InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
 		w->vehstatus |= VS_DISASTER;
-	} else if (v->next_order < 1) {
+	} else if (v->current_order.station < 1) {
 
 		int x = GET_TILE_X(v->dest_tile)*16;
 		int y = GET_TILE_Y(v->dest_tile)*16;
@@ -562,7 +566,7 @@
 			v->dest_tile = TILE_MASK(Random());
 			return;
 		}
-		v->next_order = 1;
+		v->current_order.station = 1;
 
 		tile_org = tile = TILE_MASK(Random());
 		do {
@@ -594,11 +598,11 @@
 		return;
 	}
 
-	if (v->next_order == 0) {
+	if (v->current_order.station == 0) {
 		u = &_vehicles[v->u.disaster.unk2];
 		if (abs(v->x_pos - u->x_pos) > 16)
 			return;
-		v->next_order = 1;
+		v->current_order.station = 1;
 
 		CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
 		SndPlayVehicleFx(SND_12_EXPLOSION, u);
--- a/economy.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/economy.c	Sun Dec 05 12:43:04 2004 +0000
@@ -1231,7 +1231,7 @@
 	const Vehicle *x;
 	bool has_any_cargo = false;
 
-	if (!(u->next_order & OF_FULL_LOAD)) return false;
+	if (!(u->current_order.flags & OF_FULL_LOAD)) return false;
 
 	for (w = u; w != NULL; w = w->next) {
 		if (w->cargo_count != 0) {
@@ -1246,7 +1246,7 @@
 		if ((x->type != VEH_Train || x->subtype == 0) && // for all locs
 				u->last_station_visited == x->last_station_visited && // at the same station
 				!(x->vehstatus & VS_STOPPED) && // not stopped
-				(x->next_order & OT_MASK) == OT_LOADING && // loading
+				x->current_order.type == OT_LOADING && // loading
 				u != x) { // not itself
 			bool other_has_any_cargo = false;
 			bool has_space_for_same_type = false;
@@ -1288,7 +1288,7 @@
 	byte old_player;
 	bool completely_empty = true;
 
-	assert((v->next_order&0x1F) == OT_LOADING);
+	assert(v->current_order.type == OT_LOADING);
 
 	v->cur_speed = 0;
 	old_player = _current_player;
@@ -1309,7 +1309,7 @@
 				profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
 				result |= 1;
 				v->cargo_count = 0;
-			} else if (u->next_order & OF_UNLOAD) {
+			} else if (u->current_order.flags & OF_UNLOAD) {
 				/* unload goods and let it wait at the station */
 				st->time_since_unload = 0;
 
@@ -1335,7 +1335,7 @@
 		}
 
 		/* don't pick up goods that we unloaded */
-		if (u->next_order & OF_UNLOAD) continue;
+		if (u->current_order.flags & OF_UNLOAD) continue;
 
 		/* update stats */
 		ge->days_since_pickup = 0;
--- a/engine.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/engine.c	Sun Dec 05 12:43:04 2004 +0000
@@ -314,14 +314,14 @@
 					// TTDPatch runs on little-endian arch;
 					// Variable is 0x80 + offset in TTD's vehicle structure
 					switch (dsg->variable - 0x80) {
-#define veh_prop(id_, value_) case id_: value = value_; break
+#define veh_prop(id_, value_) case (id_): value = (value_); break
 						veh_prop(0x00, veh->type);
 						veh_prop(0x01, veh->subtype);
 						veh_prop(0x04, veh->index);
 						veh_prop(0x05, veh->index & 0xFF);
 						/* XXX? Is THIS right? */
-						veh_prop(0x0A, veh->next_order_param << 8 | veh->next_order);
-						veh_prop(0x0B, veh->next_order);
+						veh_prop(0x0A, PackOrder(&veh->current_order));
+						veh_prop(0x0B, PackOrder(&veh->current_order) & 0xff);
 						veh_prop(0x0C, veh->num_orders);
 						veh_prop(0x0D, veh->cur_order_index);
 						veh_prop(0x10, veh->load_unload_time_rem);
--- a/oldloader.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/oldloader.c	Sun Dec 05 12:43:04 2004 +0000
@@ -736,8 +736,9 @@
 			assert(n->schedule_ptr >= _order_array && n->schedule_ptr < _ptr_to_next_order);
 		}
 
-		n->next_order = o->next_order;
-		n->next_order_param = o->next_order_param;
+		n->current_order.type = o->next_order & 0x0f;
+		n->current_order.flags = o->next_order >> 4;
+		n->current_order.station = o->next_order_param;
 		n->num_orders = o->num_orders;
 		n->cur_order_index = o->cur_order_index;
 		n->dest_tile = o->dest_tile;
--- a/order_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/order_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -15,7 +15,7 @@
 {
 	Vehicle *v = &_vehicles[p1 & 0xFFFF];
 	int sel = p1 >> 16;
-	int t;
+	Order new_order = UnpackOrder(p2);
 
 	if (sel > v->num_orders) return_cmd_error(STR_EMPTY);
 	if (_ptr_to_next_order == endof(_order_array)) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
@@ -23,21 +23,25 @@
 
 	// for ships, make sure that the station is not too far away from the previous destination.
 	if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
-			sel != 0 && ((t=v->schedule_ptr[sel-1])&OT_MASK) == OT_GOTO_STATION) {
+			sel != 0 && v->schedule_ptr[sel - 1].type == OT_GOTO_STATION) {
 
-		int dist = GetTileDist(DEREF_STATION(t >> 8)->xy, DEREF_STATION(p2 >> 8)->xy);
+		int dist = GetTileDist(
+			DEREF_STATION(v->schedule_ptr[sel - 1].station)->xy,
+			DEREF_STATION(new_order.station)->xy
+		);
 		if (dist >= 130)
 			return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
 	}
 
 	if (flags & DC_EXEC) {
-		uint16 *s1, *s2;
+		Order *s1;
+		Order *s2;
 		Vehicle *u;
 
 		s1 = &v->schedule_ptr[sel];
 		s2 = _ptr_to_next_order++;
 		do s2[1] = s2[0]; while (--s2 >= s1);
-		s1[0] = (uint16)p2;
+		*s1 = new_order;
 
 		s1 = v->schedule_ptr;
 
@@ -72,7 +76,9 @@
 		DeleteVehicleSchedule(dst);
 
 		dst->num_orders = 0;
-		*(dst->schedule_ptr = _ptr_to_next_order++) = 0;
+		_ptr_to_next_order->type = OT_NOTHING;
+		_ptr_to_next_order->flags = 0;
+		dst->schedule_ptr = _ptr_to_next_order++;
 
 		InvalidateWindow(WC_VEHICLE_ORDERS, dst->index);
 	}
@@ -92,9 +98,7 @@
 		return DecloneOrder(v, flags);
 
 	if (flags & DC_EXEC) {
-		uint16 *s1;
-
-		s1 = &v->schedule_ptr[sel];
+		Order *s1 = &v->schedule_ptr[sel];
 
 		// copy all orders to get rid of the hole
 		do s1[0] = s1[1]; while (++s1 != _ptr_to_next_order);
@@ -111,8 +115,11 @@
 					if ((byte)sel < u->cur_order_index)
 						u->cur_order_index--;
 
-					if ((byte)sel == u->cur_order_index && (u->next_order&(OT_MASK|OF_NON_STOP)) == (OT_LOADING|OF_NON_STOP))
-						u->next_order = OT_LOADING;
+					if ((byte)sel == u->cur_order_index &&
+							u->current_order.type == OT_LOADING &&
+							u->current_order.flags & OF_NON_STOP) {
+						u->current_order.flags = 0;
+					}
 
 					InvalidateWindow(WC_VEHICLE_VIEW, u->index);
 					InvalidateWindow(WC_VEHICLE_ORDERS, u->index);
@@ -139,8 +146,10 @@
 				v->u.rail.days_since_order_progr = 0;
 		}
 
-		if ((v->next_order&(OT_MASK|OF_NON_STOP)) == (OT_LOADING|OF_NON_STOP))
-			v->next_order = OT_LOADING;
+		if (v->current_order.type == OT_LOADING &&
+				v->current_order.flags & OF_NON_STOP) {
+			v->current_order.flags = 0;
+		}
 
 		InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
 	}
@@ -155,29 +164,28 @@
 {
 	Vehicle *v = &_vehicles[p1];
 	byte sel = (byte)p2;
-	uint16 *sched;
+	Order *sched;
 
 	if (sel >= v->num_orders)
 		return CMD_ERROR;
 
 	sched = &v->schedule_ptr[sel];
-	if (!((*sched & OT_MASK) == OT_GOTO_STATION ||
-			((*sched & OT_MASK) == OT_GOTO_DEPOT &&  (p2>>8) != 1)))
+	if (sched->type != OT_GOTO_STATION &&
+			(sched->type != OT_GOTO_DEPOT || (p2 >> 8) == 1))
 		return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
-		switch(p2 >> 8) {
+		switch (p2 >> 8) {
 		case 0: // full load
-			*sched ^= OF_FULL_LOAD;
-			if ((*sched & OT_MASK) != OT_GOTO_DEPOT)
-				*sched &= ~OF_UNLOAD;
+			sched->flags ^= OF_FULL_LOAD;
+			if (sched->type != OT_GOTO_DEPOT) sched->flags &= ~OF_UNLOAD;
 			break;
 		case 1: // unload
-			*sched ^= OF_UNLOAD;
-			*sched &= ~OF_FULL_LOAD;
+			sched->flags ^= OF_UNLOAD;
+			sched->flags &= ~OF_FULL_LOAD;
 			break;
 		case 2: // non stop
-			*sched ^= OF_NON_STOP;
+			sched->flags ^= OF_NON_STOP;
 			break;
 		}
 		sched = v->schedule_ptr;
@@ -247,14 +255,12 @@
 
 		// let's see what happens with road vehicles
 		if (src->type == VEH_Road) {
-			uint16 ord;
-			int i;
-			Station *st;
+			const Order *i;
 			TileIndex required_dst;
 
-			for (i=0; (ord = src->schedule_ptr[i]) != 0; i++) {
-				if ( ( ord & OT_MASK ) == OT_GOTO_STATION ) {
-					st = DEREF_STATION(ord >> 8);
+			for (i = src->schedule_ptr; i->type != OT_NOTHING; ++i) {
+				if (i->type == OT_GOTO_STATION) {
+					const Station *st = DEREF_STATION(i->station);
 					required_dst = (dst->cargo_type == CT_PASSENGERS) ? st->bus_tile : st->lorry_tile;
 					if ( !required_dst )
 						return CMD_ERROR;
@@ -289,7 +295,6 @@
 void BackupVehicleOrders(Vehicle *v, BackuppedOrders *bak)
 {
 	Vehicle *u = IsScheduleShared(v);
-	uint16 *sched, ord, *os;
 
 	bak->orderindex = v->cur_order_index;
 	bak->service_interval = v->service_interval;
@@ -300,25 +305,24 @@
 		GetName(v->string_id & 0x7FF, bak->name);
 	}
 
-	os = bak->order;
 	// stored shared orders in this special way?
-	if (u) {
-		os[0] = 0xFFFF;
-		os[1] = u->index;
-		return;
+	if (u != NULL) {
+		bak->clone = u->index;
+	} else {
+		Order *sched = v->schedule_ptr;
+		Order *os = bak->order;
+
+		bak->clone = INVALID_VEHICLE;
+
+		do {
+			*os++ = *sched++;
+		} while (sched->type != OT_NOTHING);
 	}
-
-	sched = v->schedule_ptr;
-	do {
-		ord = *sched++;
-		*os++ = ord;
-	} while (ord != 0);
 }
 
 void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
 {
-	uint16 ord, *os;
-	int ind;
+	int i;
 
 	if (bak->name[0]) {
 		strcpy((char*)_decode_parameters, bak->name);
@@ -327,9 +331,8 @@
 
 	DoCommandP(0, v->index, bak->orderindex|(bak->service_interval<<16) , NULL, CMD_RESTORE_ORDER_INDEX);
 
-	os = bak->order;
-	if (os[0] == 0xFFFF) {
-		DoCommandP(0, v->index | os[1]<<16, 0, NULL, CMD_CLONE_ORDER);
+	if (bak->clone != INVALID_VEHICLE) {
+		DoCommandP(0, v->index | bak->clone << 16, 0, NULL, CMD_CLONE_ORDER);
 		return;
 	}
 
@@ -337,12 +340,9 @@
 	//  order number is one more then the current amount of orders, and because
 	//  in network the commands are queued before send, the second insert always
 	//  fails in test mode. By bypassing the test-mode, that no longer is a problem.
-	ind = 0;
-	while ((ord = *os++) != 0) {
-		if (!DoCommandP(0, v->index + (ind << 16), ord, NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
+	for (i = 0; bak->order[i].type != OT_NOTHING; ++i)
+		if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
 			break;
-		ind++;
-	}
 }
 
 /*	p1 = vehicle
@@ -370,8 +370,8 @@
 
 	/* only check every 20 days, so that we don't flood the message log */
 	if ( ( ( v->day_counter % 20) == 0 ) && (v->owner == _local_player) ) {
-
-		uint16 order, old_order;
+		Order order;
+		Order old_order;
 		int i, n_st, problem_type = -1;
 		Station *st;
 		int message=0;
@@ -381,21 +381,25 @@
 		order = v->schedule_ptr[0];
 		n_st = 0;
 
- 		for (old_order = i = 0; order!=0; i++ ) {
+		old_order.type = OT_NOTHING;
+		old_order.flags = 0;
+		for (i = 0; order.type != OT_NOTHING; i++) {
 			order = v->schedule_ptr[i];
-			if (order == old_order) {
+			if (order.type == old_order.type &&
+					order.flags == old_order.flags &&
+					order.station == old_order.station) {
 				problem_type = 2;
 				break;
 			}
-			if ( (order & OT_MASK) == OT_DUMMY ) {
+			if (order.type == OT_DUMMY) {
 				problem_type = 1;
 				break;
 			}
-			if ( ( (order & OT_MASK) == OT_GOTO_STATION ) /*&& (order != old_order) */) {
+			if (order.type == OT_GOTO_STATION /*&& (order != old_order) */) {
 				//I uncommented this in order not to get two error messages
 				//when two identical entries are in the list
 				n_st++;
-				st = DEREF_STATION(order >> 8);
+				st = DEREF_STATION(order.station);
 				required_tile = GetStationTileForVehicle(v,st);
 				if (!required_tile) problem_type = 3;
 			}
@@ -404,9 +408,11 @@
 
 		//Now, check the last and the first order
 		//as the last order is the end of order marker, jump back 2
-		if ( (v->schedule_ptr[0] == v->schedule_ptr[i-2]) && ( i-2 != 0 ) ) {
+		if (i > 2 &&
+				v->schedule_ptr[0].type == v->schedule_ptr[i - 2].type &&
+				v->schedule_ptr[0].flags == v->schedule_ptr[i - 2].flags &&
+				v->schedule_ptr[0].station == v->schedule_ptr[i - 2].station)
 			problem_type = 2;
-		}
 
 		if ( (n_st < 2) && (problem_type == -1) ) problem_type = 0;
 
--- a/order_gui.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/order_gui.c	Sun Dec 05 12:43:04 2004 +0000
@@ -13,14 +13,14 @@
 static int OrderGetSel(Window *w)
 {
 	Vehicle *v = &_vehicles[w->window_number];
-	uint16 *sched = v->schedule_ptr;
+	const Order *sched = v->schedule_ptr;
 	int num = WP(w,order_d).sel;
 	int count = 0;
 
 	if (num == 0)
 		return 0;
 
-	while (*sched != 0) {
+	while (sched->type != OT_NOTHING) {
 		sched++;
 		count++;
 		if (--num == 0)
@@ -34,7 +34,8 @@
 {
 	Vehicle *v;
 	int num, sel;
-	uint16 *sched, ord;
+	const Order *sched;
+	Order ord;
 	int y, i;
 	StringID str;
 	bool shared_schedule;
@@ -47,8 +48,10 @@
 
 	sched = v->schedule_ptr;
 	num=0;
-	while (*sched != 0)
-		sched++,num++;
+	while (sched->type != OT_NOTHING) {
+		sched++;
+		num++;
+	}
 
 	if ((uint)num + shared_schedule <= (uint)WP(w,order_d).sel)
 		SETBIT(w->disabled_state, 5); /* delete */
@@ -61,7 +64,7 @@
 	sel = OrderGetSel(w);
 
 	SetDParam(2,STR_8827_FULL_LOAD);
-	switch(v->schedule_ptr[sel] & 0x1F) {
+	switch (v->schedule_ptr[sel].type) {
 	case OT_GOTO_STATION:
 		break;
 	case OT_GOTO_DEPOT:
@@ -88,43 +91,43 @@
 
 		if ( (uint)(i - w->vscroll.pos) < 6) {
 
-			if (ord == 0) {
+			if (ord.type == OT_NOTHING) {
 				str = shared_schedule ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
 			} else {
 				SetDParam(1, 6);
 
-				if ( (ord & OT_MASK) == OT_GOTO_STATION) {
-					SetDParam(1, STR_8806_GO_TO + ((ord >> 5) & 7));
-					SetDParam(2, ord >> 8);
-				} else if ((ord & OT_MASK) == OT_GOTO_DEPOT) {
+				if (ord.type == OT_GOTO_STATION) {
+					SetDParam(1, STR_8806_GO_TO + (ord.flags >> 1));
+					SetDParam(2, ord.station);
+				} else if (ord.type == OT_GOTO_DEPOT) {
 					StringID s = STR_NULL;
 					if (v->type == VEH_Aircraft) {
 						s = STR_GO_TO_AIRPORT_HANGAR;
-					  SetDParam(2, ord>>8);
+					  SetDParam(2, ord.station);
 					} else {
-						SetDParam(2, _depots[ord >> 8].town_index);
+						SetDParam(2, _depots[ord.station].town_index);
 						switch (v->type) {
 						case VEH_Train:	s = STR_880E_GO_TO_TRAIN_DEPOT; break;
 						case VEH_Road:	s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
 						case VEH_Ship:	s = STR_GO_TO_SHIP_DEPOT; break;
 						}
 					}
-					if (v->type == VEH_Train)
-						s += (ord>>6)&2;
-					SetDParam(1, s + ((ord>>6)&1) );
-				} else if ((ord & OT_MASK) == OT_GOTO_WAYPOINT) {
-					SetDParam(2, ord >> 8);
+					if (v->type == VEH_Train && ord.flags & OF_NON_STOP) s += 2;
+					if (ord.flags & OF_FULL_LOAD) ++s; /* XXX service */
+					SetDParam(1, s);
+				} else if (ord.type == OT_GOTO_WAYPOINT) {
+					SetDParam(2, ord.station);
 					SetDParam(1, STR_GO_TO_WAYPOINT);
 				}
 			}
 			{
 				byte color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
 				SetDParam(0, i+1);
-				if ((ord & OT_MASK) != OT_DUMMY) {
+				if (ord.type != OT_DUMMY) {
 					DrawString(2, y, str, color);
 				} else {
 					SetDParam(1, STR_INVALID_ORDER);
-					SetDParam(2, ord >> 8);
+					SetDParam(2, ord.station);
 					DrawString(2, y, str, color);
 				}
 			}
@@ -133,7 +136,7 @@
 
 		i++;
 
-		if (ord == 0)
+		if (ord.type == OT_NOTHING)
 			break;
 	}
 }
@@ -288,17 +291,17 @@
 			sel += w->vscroll.pos;
 
 			if (_ctrl_pressed && sel < v->num_orders) { // watch out for schedule_ptr overflow
-				int ord = v->schedule_ptr[sel];
+				Order ord = v->schedule_ptr[sel];
 				int xy = 0;
-				switch (ord & OT_MASK) {
+				switch (ord.type) {
 				case OT_GOTO_STATION:			/* station order */
-					xy = _stations[ord >> 8].xy ;
+					xy = _stations[ord.station].xy ;
 					break;
 				case OT_GOTO_DEPOT:				/* goto depot order */
-					xy = _depots[ord >> 8].xy;
+					xy = _depots[ord.station].xy;
 					break;
 				case OT_GOTO_WAYPOINT:	/* goto waypoint order */
-					xy = _waypoints[ord >> 8].xy;
+					xy = _waypoints[ord.station].xy;
 				}
 
 				if (xy)
@@ -352,7 +355,7 @@
 	case WE_RCLICK: {
 		Vehicle *v = &_vehicles[w->window_number];
 		if (e->click.widget != 8) break;
-		if ((v->schedule_ptr[OrderGetSel(w)] & OT_MASK) == OT_GOTO_DEPOT)
+		if (v->schedule_ptr[OrderGetSel(w)].type == OT_GOTO_DEPOT)
 			GuiShowTooltips(STR_SERVICE_HINT);
 		else
 			GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER);
--- a/rail_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/rail_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -760,8 +760,12 @@
 
 static void DoDeleteWaypoint(Waypoint *cp)
 {
+	Order order;
 	cp->xy = 0;
-	DeleteCommandFromVehicleSchedule(((cp-_waypoints) << 8) + OT_GOTO_WAYPOINT);
+	order.type = OT_GOTO_WAYPOINT;
+	order.flags = 0;
+	order.station = cp - _waypoints;
+	DeleteCommandFromVehicleSchedule(order);
 	if (~cp->town_or_string & 0xC000) DeleteName(cp->town_or_string);
 	RedrawWaypointSign(cp);
 }
--- a/roadveh_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/roadveh_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -169,7 +169,9 @@
 		_new_roadveh_id = v->index;
 
 		v->string_id = STR_SV_ROADVEH_NAME;
-		*(v->schedule_ptr = _ptr_to_next_order++) = 0;
+		_ptr_to_next_order->type = OT_NOTHING;
+		_ptr_to_next_order->flags = 0;
+		v->schedule_ptr = _ptr_to_next_order++;
 
 		v->service_interval = _patches.servint_roadveh;
 
@@ -300,11 +302,12 @@
 	if (v->type != VEH_Road || !CheckOwnership(v->owner))
 		return CMD_ERROR;
 
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
 		if (flags & DC_EXEC) {
-			if (v->next_order & OF_UNLOAD)
+			if (v->current_order.flags & OF_UNLOAD)
 				v->cur_order_index++;
-			v->next_order = OT_DUMMY;
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 		return 0;
@@ -315,8 +318,9 @@
 		return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
 
 	if (flags & DC_EXEC) {
-		v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
-		v->next_order_param = (byte)depot;
+		v->current_order.type = OT_GOTO_DEPOT;
+		v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
+		v->current_order.station = (byte)depot;
 		v->dest_tile = _depots[depot].xy;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 	}
@@ -556,16 +560,18 @@
 
 static void ProcessRoadVehOrder(Vehicle *v)
 {
-	uint order;
+	Order order;
 	Station *st;
 
-	if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
+	if (v->current_order.type >= OT_GOTO_DEPOT && v->current_order.type <= OT_LEAVESTATION) {
 		// Let a depot order in the schedule interrupt.
-		if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
+		if (v->current_order.type != OT_GOTO_DEPOT ||
+				!(v->current_order.flags & OF_UNLOAD))
 			return;
 	}
 
-	if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
 			SERVICE_INTERVAL ) {
 		v->cur_order_index++;
 	}
@@ -575,27 +581,29 @@
 
 	order = v->schedule_ptr[v->cur_order_index];
 
-	if (order == 0) {
-		v->next_order = OT_NOTHING;
+	if (order.type == OT_NOTHING) {
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 		v->dest_tile = 0;
 		return;
 	}
 
-	if (order == (uint)((v->next_order | (v->next_order_param<<8))))
+	if (order.type == v->current_order.type &&
+			order.flags == v->current_order.flags &&
+			order.station == v->current_order.station)
 		return;
 
-	v->next_order = (byte)order;
-	v->next_order_param = (byte)(order >> 8);
+	v->current_order = order;
 
 	v->dest_tile = 0;
 
-	if ((order & OT_MASK) == OT_GOTO_STATION) {
-		if ( (byte)(order >> 8) == v->last_station_visited)
+	if (order.type == OT_GOTO_STATION) {
+		if (order.station == v->last_station_visited)
 			v->last_station_visited = 0xFF;
-		st = DEREF_STATION(order >> 8);
+		st = DEREF_STATION(order.station);
 		v->dest_tile = v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile;
-	} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
-		v->dest_tile = _depots[order >> 8].xy;
+	} else if (order.type == OT_GOTO_DEPOT) {
+		v->dest_tile = _depots[order.station].xy;
 	}
 
 	InvalidateVehicleOrderWidget(v);
@@ -603,17 +611,17 @@
 
 static void HandleRoadVehLoading(Vehicle *v)
 {
-	if (v->next_order == OT_NOTHING)
+	if (v->current_order.type == OT_NOTHING)
 		return;
 
-	if (v->next_order != OT_DUMMY) {
-		if ((v->next_order&OT_MASK) != OT_LOADING)
+	if (v->current_order.type != OT_DUMMY) {
+		if (v->current_order.type != OT_LOADING)
 			return;
 
 		if (--v->load_unload_time_rem)
 			return;
 
-		if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
+		if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
 			SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
 			if (LoadUnloadVehicle(v)) {
 				InvalidateWindow(WC_ROADVEH_LIST, v->owner);
@@ -623,9 +631,10 @@
 		}
 
 		{
-			byte b = v->next_order;
-			v->next_order = OT_LEAVESTATION;
-			if (!(b & OF_NON_STOP))
+			Order b = v->current_order;
+			v->current_order.type = OT_LEAVESTATION;
+			v->current_order.flags = 0;
+			if (!(b.flags & OF_NON_STOP))
 				return;
 		}
 	}
@@ -1052,7 +1061,7 @@
 static void RoadVehEventHandler(Vehicle *v)
 {
 	GetNewVehiclePosResult gp;
-	byte new_dir,old_dir,old_order;
+	byte new_dir, old_dir;
 	RoadDriveEntry rd;
 	int x,y;
 	Station *st;
@@ -1088,7 +1097,7 @@
 	ProcessRoadVehOrder(v);
 	HandleRoadVehLoading(v);
 
-	if ((v->next_order & OT_MASK) == OT_LOADING)
+	if (v->current_order.type == OT_LOADING)
 		return;
 
 	if (v->u.road.state == 254) {
@@ -1305,8 +1314,9 @@
 		st = DEREF_STATION(_map2[v->tile]);
 		b = IS_BYTE_INSIDE(_map5[v->tile], 0x43, 0x47) ? &st->truck_stop_status : &st->bus_stop_status;
 
-		if ( (v->next_order&OT_MASK) != OT_LEAVESTATION &&
-				(v->next_order&OT_MASK) != OT_GOTO_DEPOT) {
+		if (v->current_order.type != OT_LEAVESTATION &&
+				v->current_order.type != OT_GOTO_DEPOT) {
+			Order old_order;
 
 			*b &= ~0x80;
 
@@ -1314,12 +1324,14 @@
 
 			RoadVehArrivesAt(v, st);
 
-			old_order = v->next_order;
-			v->next_order = OT_LOADING;
+			old_order = v->current_order;
+			v->current_order.type = OT_LOADING;
+			v->current_order.flags = 0;
 
-			if ((old_order & OT_MASK) == OT_GOTO_STATION &&
-					v->next_order_param == v->last_station_visited) {
-				v->next_order = OT_LOADING | OF_NON_STOP | (old_order & (OF_FULL_LOAD|OF_UNLOAD));
+			if (old_order.type == OT_GOTO_STATION &&
+					v->current_order.station == v->last_station_visited) {
+				v->current_order.flags =
+					(old_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) | OF_NON_STOP;
 			}
 
 			SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
@@ -1331,12 +1343,13 @@
 			return;
 		}
 
-		if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT) {
+		if (v->current_order.type != OT_GOTO_DEPOT) {
 			if (*b&0x80) {
 				v->cur_speed = 0;
 				return;
 			}
-			v->next_order = 0;
+			v->current_order.type = OT_NOTHING;
+			v->current_order.flags = 0;
 		}
 		*b |= 0x80;
 
@@ -1361,8 +1374,6 @@
 
 void RoadVehEnterDepot(Vehicle *v)
 {
-	byte t;
-
 	v->u.road.state = 254;
 	v->vehstatus |= VS_HIDDEN;
 
@@ -1375,16 +1386,19 @@
 
 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
+		Order t;
+
 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
-		t = v->next_order;
-		v->next_order = OT_DUMMY;
+		t = v->current_order;
+		v->current_order.type = OT_DUMMY;
+		v->current_order.flags = 0;
 
 		// Part of the schedule?
-		if (t & OF_UNLOAD) { v->cur_order_index++; }
-
-		else if (t & OF_FULL_LOAD) {
+		if (t.flags & OF_UNLOAD) {
+			v->cur_order_index++;
+		} else if (t.flags & OF_FULL_LOAD) {
 			v->vehstatus |= VS_STOPPED;
 			if (v->owner == _local_player) {
 				SetDParam(0, v->unitnumber);
@@ -1432,25 +1446,29 @@
 
 	// Don't interfere with a depot visit scheduled by the user, or a
 	// depot visit by the order list.
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT &&
-			(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) != 0)
 		return;
 
 	i = FindClosestRoadDepot(v);
 
 	if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
-		if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
-			v->next_order = OT_DUMMY;
+		if (v->current_order.type == OT_GOTO_DEPOT) {
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 		return;
 	}
 
-	if (v->next_order == (OT_GOTO_DEPOT | OF_NON_STOP) && !CHANCE16(1,20))
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			v->current_order.flags & OF_NON_STOP &&
+			!CHANCE16(1,20))
 		return;
 
-	v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
-	v->next_order_param = (byte)i;
+	v->current_order.type = OT_GOTO_DEPOT;
+	v->current_order.flags = OF_NON_STOP;
+	v->current_order.station = (byte)i;
 	v->dest_tile = (&_depots[i])->xy;
 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 }
@@ -1473,8 +1491,8 @@
 	CheckOrders(v);
 
 	/* update destination */
-	if ((v->next_order & OT_MASK) == OT_GOTO_STATION) {
-		st = DEREF_STATION(v->next_order_param);
+	if (v->current_order.type == OT_GOTO_STATION) {
+		st = DEREF_STATION(v->current_order.station);
 		if ((tile=(v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile)) != 0)
 			v->dest_tile = tile;
 	}
--- a/roadveh_gui.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/roadveh_gui.c	Sun Dec 05 12:43:04 2004 +0000
@@ -204,15 +204,15 @@
 		} else if (v->vehstatus & VS_STOPPED) {
 			str = STR_8861_STOPPED;
 		} else {
-			switch(v->next_order & OT_MASK) {
+			switch (v->current_order.type) {
 			case OT_GOTO_STATION: {
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				SetDParam(1, v->cur_speed * 10 >> 5);
 				str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
 			} break;
 
 			case OT_GOTO_DEPOT: {
-				Depot *dep = &_depots[v->next_order_param];
+				Depot *dep = &_depots[v->current_order.station];
 				SetDParam(0, dep->town_index);
 				SetDParam(1, v->cur_speed * 10 >> 5);
 				str = STR_HEADING_FOR_ROAD_DEPOT + _patches.vehicle_speed;
--- a/ship_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/ship_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -95,7 +95,8 @@
 	if (v->vehstatus & VS_STOPPED)
 		return;
 
-	if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD))
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			v->current_order.flags & OF_FULL_LOAD)
 		return;
 
 	if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
@@ -104,15 +105,17 @@
 	i = FindClosestShipDepot(v);
 
 	if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
-		if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
-			v->next_order = OT_DUMMY;
+		if (v->current_order.type == OT_GOTO_DEPOT) {
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 		return;
 	}
 
-	v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
-	v->next_order_param = (byte)i;
+	v->current_order.type = OT_GOTO_DEPOT;
+	v->current_order.flags = OF_NON_STOP;
+	v->current_order.station = (byte)i;
 	v->dest_tile = (&_depots[i])->xy;
 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 }
@@ -199,15 +202,18 @@
 
 static void ProcessShipOrder(Vehicle *v)
 {
-	uint order;
+	Order order;
 	Station *st;
 
-	if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
-		if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
+	if (v->current_order.type >= OT_GOTO_DEPOT &&
+			v->current_order.type <= OT_LEAVESTATION) {
+		if (v->current_order.type != OT_GOTO_DEPOT ||
+				!(v->current_order.flags & OF_UNLOAD))
 			return;
 	}
 
-	if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
 			SERVICE_INTERVAL) {
 		v->cur_order_index++;
 	}
@@ -218,28 +224,30 @@
 
 	order = v->schedule_ptr[v->cur_order_index];
 
-	if (order == 0) {
-		v->next_order = OT_NOTHING;
+	if (order.type == OT_NOTHING) {
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 		v->dest_tile = 0;
 		return;
 	}
 
-	if (order == (uint)((v->next_order | (v->next_order_param<<8))))
+	if (order.type == v->current_order.type &&
+			order.flags == v->current_order.flags &&
+			order.station == v->current_order.station)
 		return;
 
-	v->next_order = (byte)order;
-	v->next_order_param = (byte)(order >> 8);
+	v->current_order = order;
 
-	if ((order & OT_MASK) == OT_GOTO_STATION) {
-		if ( (byte)(order >> 8) == v->last_station_visited)
+	if (order.type == OT_GOTO_STATION) {
+		if (order.station == v->last_station_visited)
 			v->last_station_visited = 0xFF;
 
-		st = DEREF_STATION(order >> 8);
+		st = DEREF_STATION(order.station);
 		if (st->dock_tile != 0) {
 			v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]);
 		}
-	} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
-		v->dest_tile = _depots[order >> 8].xy;
+	} else if (order.type == OT_GOTO_DEPOT) {
+		v->dest_tile = _depots[order.station].xy;
 	} else {
 		v->dest_tile = 0;
 	}
@@ -248,17 +256,17 @@
 
 static void HandleShipLoading(Vehicle *v)
 {
-	if (v->next_order == OT_NOTHING)
+	if (v->current_order.type == OT_NOTHING)
 		return;
 
-	if (v->next_order != OT_DUMMY) {
-		if ((v->next_order&OT_MASK) != OT_LOADING)
+	if (v->current_order.type != OT_DUMMY) {
+		if (v->current_order.type != OT_LOADING)
 			return;
 
 		if (--v->load_unload_time_rem)
 			return;
 
-		if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
+		if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
 			SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
 			if (LoadUnloadVehicle(v)) {
 				InvalidateWindow(WC_SHIPS_LIST, v->owner);
@@ -269,9 +277,10 @@
 		PlayShipSound(v);
 
 		{
-			byte b = v->next_order;
-			v->next_order = OT_LEAVESTATION;
-			if (!(b & OF_NON_STOP))
+			Order b = v->current_order;
+			v->current_order.type = OT_LEAVESTATION;
+			v->current_order.flags = 0;
+			if (!(b.flags & OF_NON_STOP))
 				return;
 		}
 	}
@@ -380,8 +389,6 @@
 
 static void ShipEnterDepot(Vehicle *v)
 {
-	byte t;
-
 	v->u.ship.state = 0x80;
 	v->vehstatus |= VS_HIDDEN;
 	v->cur_speed = 0;
@@ -396,15 +403,18 @@
 
 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
+		Order t;
+
 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
-		t = v->next_order;
-		v->next_order = OT_DUMMY;
+		t = v->current_order;
+		v->current_order.type = OT_DUMMY;
+		v->current_order.flags = 0;
 
-		if (t&OF_UNLOAD) { v->cur_order_index++; }
-
-		else if (t & 0x40) {
+		if (t.flags & OF_UNLOAD) {
+			v->cur_order_index++;
+		} else if (t.flags & OF_FULL_LOAD) {
 			v->vehstatus |= VS_STOPPED;
 			if (v->owner == _local_player) {
 				SetDParam(0, v->unitnumber);
@@ -636,7 +646,7 @@
 	ProcessShipOrder(v);
 	HandleShipLoading(v);
 
-	if ((v->next_order & OT_MASK) == OT_LOADING)
+	if (v->current_order.type == OT_LOADING)
 		return;
 
 	CheckShipLeaveDepot(v);
@@ -657,21 +667,23 @@
 			if (r & 0x8) goto reverse_direction;
 
 			if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) {
-				if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
+				if (v->current_order.type == OT_GOTO_DEPOT) {
 					if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
 						ShipEnterDepot(v);
 						return;
 					}
-				} else if ((v->next_order & OT_MASK) == OT_GOTO_STATION) {
+				} else if (v->current_order.type == OT_GOTO_STATION) {
 					Station *st;
 
-					v->last_station_visited = v->next_order_param;
+					v->last_station_visited = v->current_order.station;
 
 					/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
-					st = DEREF_STATION(v->next_order_param);
+					st = DEREF_STATION(v->current_order.station);
 					if (!(st->had_vehicle_of_type & HVOT_BUOY) 
 							&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
-						v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING;
+						v->current_order.type = OT_LOADING;
+						v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
+						v->current_order.flags |= OF_NON_STOP;
 						ShipArrivesAt(v, st);
 
 						SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
@@ -681,7 +693,8 @@
 						}
 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 					} else { /* leave buoys right aways */
-						v->next_order = OT_LEAVESTATION;
+						v->current_order.type = OT_LEAVESTATION;
+						v->current_order.flags = 0;
 						v->cur_order_index++;
 						InvalidateVehicleOrderWidget(v);
 					}
@@ -689,8 +702,9 @@
 				}
 			}
 
-			if (v->next_order == OT_LEAVESTATION) {
-				v->next_order = OT_NOTHING;
+			if (v->current_order.type == OT_LEAVESTATION) {
+				v->current_order.type = OT_NOTHING;
+				v->current_order.flags = 0;
 				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 			}
 		}
@@ -843,7 +857,9 @@
 
 		v->string_id = STR_SV_SHIP_NAME;
 		v->u.ship.state = 0x80;
-		*(v->schedule_ptr = _ptr_to_next_order++) = 0;
+		_ptr_to_next_order->type = OT_NOTHING;
+		_ptr_to_next_order->flags = 0;
+		v->schedule_ptr = _ptr_to_next_order++;
 
 		v->service_interval = _patches.servint_ships;
 		v->date_of_last_service = _date;
@@ -917,10 +933,11 @@
 	if (!CheckOwnership(v->owner))
 		return CMD_ERROR;
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
 		if (flags & DC_EXEC) {
-			if (v->next_order&OF_UNLOAD) {v->cur_order_index++;}
-			v->next_order = OT_DUMMY;
+			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 	} else {
@@ -930,8 +947,9 @@
 
 		if (flags & DC_EXEC) {
 			v->dest_tile = _depots[depot].xy;
-			v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
-			v->next_order_param = depot;
+			v->current_order.type = OT_GOTO_DEPOT;
+			v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
+			v->current_order.station = depot;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 	}
--- a/ship_gui.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/ship_gui.c	Sun Dec 05 12:43:04 2004 +0000
@@ -498,15 +498,15 @@
 		} else if (v->vehstatus & VS_STOPPED) {
 			str = STR_8861_STOPPED;
 		} else {
-			switch(v->next_order & OT_MASK) {
+			switch (v->current_order.type) {
 			case OT_GOTO_STATION: {
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				SetDParam(1, v->cur_speed * 10 >> 5);
 				str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
 			} break;
 
 			case OT_GOTO_DEPOT: {
-				Depot *dep = &_depots[v->next_order_param];
+				Depot *dep = &_depots[v->current_order.station];
 				SetDParam(0, dep->town_index);
 				SetDParam(1, v->cur_speed * 10 >> 5);
 				str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
@@ -836,16 +836,14 @@
 
 
 static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
-	uint16 *sched;
+	Order *sched;
 	int sel;
-	uint ord;
 	Station *st;
 	int i = 0;
 
-	sched = v->schedule_ptr;
 	sel = v->cur_order_index;
 
-	while ((ord=*sched++) != 0) {
+	for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
 		if (sel == 0) {
 			_stringwidth_base = 0xE0;
 			DoDrawString( "\xAF", x-6, y, 16);
@@ -853,11 +851,11 @@
 		}
 		sel--;
 
-		if ((ord & OT_MASK) == OT_GOTO_STATION) {
-			st = DEREF_STATION(ord >> 8);
+		if (sched->type == OT_GOTO_STATION) {
+			st = DEREF_STATION(sched->station);
 
 			if (!(st->had_vehicle_of_type & HVOT_BUOY)) {
-				SetDParam(0, ord >> 8);
+				SetDParam(0, sched->station);
 				DrawString(x, y, STR_A036, 0);
 
 				y += 6;
--- a/station_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/station_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -2139,10 +2139,12 @@
 			!IsTrainStationTile(tile + _tileoffs_by_dir[v->direction >> 1])) {
 
 			station_id = _map2[tile];
-			if ((!(v->next_order & OF_NON_STOP) && !_patches.new_nonstop) ||
-					 (((v->next_order & OT_MASK) == OT_GOTO_STATION && v->next_order_param == station_id))) {
-
-				if (!(_patches.new_nonstop && (v->next_order & OF_NON_STOP)) && v->next_order != OT_LEAVESTATION && v->last_station_visited != station_id) {
+			if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
+					(v->current_order.type == OT_GOTO_STATION && v->current_order.station == station_id)) {
+
+				if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
+						v->current_order.type != OT_LEAVESTATION &&
+						v->last_station_visited != station_id) {
 					x &= 0xF;
 					y &= 0xF;
 
@@ -2199,6 +2201,7 @@
 
 static void DeleteStation(Station *st)
 {
+	Order order;
 	int index;
 	st->xy = 0;
 
@@ -2209,7 +2212,10 @@
 
 	index = st->index;
 	DeleteWindowById(WC_STATION_VIEW, index);
-	DeleteCommandFromVehicleSchedule((index << 8) + OT_GOTO_STATION);
+	order.type = OT_GOTO_STATION;
+	order.flags = 0;
+	order.station = index;
+	DeleteCommandFromVehicleSchedule(order);
 	DeleteSubsidyWithStation(index);
 }
 
--- a/train_cmd.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/train_cmd.c	Sun Dec 05 12:43:04 2004 +0000
@@ -425,7 +425,7 @@
 //			v->cargo_count = 0;
 			v->value = value;
 //			v->day_counter = 0;
-//			v->next_order = 0;
+//			v->current_order = 0;
 //			v->next_station = 0;
 //			v->load_unload_time_rem = 0;
 //			v->progress = 0;
@@ -451,7 +451,9 @@
 //			v->cur_order_index = 0;
 //			v->num_orders = 0;
 
-			*(v->schedule_ptr = _ptr_to_next_order++) = 0;
+			_ptr_to_next_order->type = OT_NOTHING;
+			_ptr_to_next_order->flags = 0;
+			v->schedule_ptr = _ptr_to_next_order++;
 //			v->next_in_chain = 0xffff;
 //			v->next = NULL;
 
@@ -682,7 +684,9 @@
 					// setting the type to 0 also involves setting up the schedule_ptr field.
 					src->subtype = 0;
 					assert(src->schedule_ptr == NULL);
-					*(src->schedule_ptr = _ptr_to_next_order++) = 0;
+					_ptr_to_next_order->type = OT_NOTHING;
+					_ptr_to_next_order->flags = 0;
+					src->schedule_ptr = _ptr_to_next_order++;
 					src->num_orders = 0;
 				}
 				dst_head = src;
@@ -1138,14 +1142,15 @@
 	Vehicle *v = &_vehicles[p1];
 	TrainFindDepotData tfdd;
 
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
 		if (flags & DC_EXEC) {
-			if (v->next_order & OF_UNLOAD) {
+			if (v->current_order.flags & OF_UNLOAD) {
 				v->u.rail.days_since_order_progr = 0;
 				v->cur_order_index++;
 			}
 
-			v->next_order = OT_DUMMY;
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 		return 0;
@@ -1157,8 +1162,9 @@
 
 	if (flags & DC_EXEC) {
 		v->dest_tile = tfdd.tile;
-		v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
-		v->next_order_param = GetDepotByTile(tfdd.tile);
+		v->current_order.type = OT_GOTO_DEPOT;
+		v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
+		v->current_order.station = GetDepotByTile(tfdd.tile);
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 	}
 
@@ -1364,8 +1370,8 @@
 static void FillWithStationData(TrainTrackFollowerData *fd, Vehicle *v)
 {
         fd->dest_coords = v->dest_tile;
-        if ((v->next_order & OT_MASK) == OT_GOTO_STATION)
-                fd->station_index = v->next_order_param;
+        if (v->current_order.type == OT_GOTO_STATION)
+                fd->station_index = v->current_order.station;
         else
                 fd->station_index = -1;
 
@@ -1570,29 +1576,32 @@
 
 static bool ProcessTrainOrder(Vehicle *v)
 {
-	uint order;
+	Order order;
 	bool result;
 
 	// These are un-interruptible
-	if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
-
+	if (v->current_order.type >= OT_GOTO_DEPOT &&
+			v->current_order.type <= OT_LEAVESTATION) {
 		// Let a depot order in the schedule interrupt.
-		if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
+		if (v->current_order.type != OT_GOTO_DEPOT ||
+				!(v->current_order.flags & OF_UNLOAD))
 			return false;
 	}
 
-	if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) ==  (OF_UNLOAD | OF_FULL_LOAD) &&
 			SERVICE_INTERVAL) {
 		v->cur_order_index++;
 	}
 
 	// check if we've reached the waypoint?
-	if ((v->next_order & OT_MASK) == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
+	if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
 		v->cur_order_index++;
 	}
 
 	// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
-	if (_patches.new_nonstop && (v->next_order & OF_NON_STOP) && v->next_order_param == _map2[v->tile]) {
+	if (_patches.new_nonstop && v->current_order.flags & OF_NON_STOP &&
+			v->current_order.station == _map2[v->tile]) {
 		v->cur_order_index++;
 	}
 
@@ -1602,33 +1611,35 @@
 	order = v->schedule_ptr[v->cur_order_index];
 
 	// If no order, do nothing.
-	if (order == 0) {
-		v->next_order = OT_NOTHING;
+	if (order.type == OT_NOTHING) {
+		v->current_order.type = OT_NOTHING;
+		v->current_order.flags = 0;
 		v->dest_tile = 0;
 		return false;
 	}
 
 	// If it is unchanged, keep it.
-	if (order == (uint)((v->next_order | (v->next_order_param<<8))))
+	if (order.type == v->current_order.type &&
+			order.flags == v->current_order.flags &&
+			order.station == v->current_order.station)
 		return false;
 
 	// Otherwise set it, and determine the destination tile.
-	v->next_order = (byte)order;
-	v->next_order_param = (byte)(order >> 8);
+	v->current_order = order;
 
 	v->dest_tile = 0;
 
 	result = false;
-	if ((order & OT_MASK) == OT_GOTO_STATION) {
-		if ( (byte)(order >> 8) == v->last_station_visited)
+	if (order.type == OT_GOTO_STATION) {
+		if (order.station == v->last_station_visited)
 			v->last_station_visited = 0xFF;
-		v->dest_tile = DEREF_STATION(order >> 8)->xy;
+		v->dest_tile = DEREF_STATION(order.station)->xy;
 		result = CheckReverseTrain(v);
-	} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
-		v->dest_tile = _depots[order >> 8].xy;
+	} else if (order.type == OT_GOTO_DEPOT) {
+		v->dest_tile = _depots[order.station].xy;
 		result = CheckReverseTrain(v);
-	} else if ((order & OT_MASK) == OT_GOTO_WAYPOINT) {
-		v->dest_tile = _waypoints[order >> 8].xy;
+	} else if (order.type == OT_GOTO_WAYPOINT) {
+		v->dest_tile = _waypoints[order.station].xy;
 		result = CheckReverseTrain(v);
 	}
 
@@ -1647,24 +1658,24 @@
 
 static void HandleTrainLoading(Vehicle *v, bool mode)
 {
-	if (v->next_order == OT_NOTHING)
+	if (v->current_order.type == OT_NOTHING)
 		return;
 
-	if (v->next_order != OT_DUMMY) {
-		if ((v->next_order&OT_MASK) != OT_LOADING)
+	if (v->current_order.type != OT_DUMMY) {
+		if (v->current_order.type != OT_LOADING)
 			return;
 
 		if (mode)
 			return;
 
 		// don't mark the train as lost if we're loading on the final station.
-		if (v->next_order & OF_NON_STOP)
+		if (v->current_order.flags & OF_NON_STOP)
 			v->u.rail.days_since_order_progr = 0;
 
 		if (--v->load_unload_time_rem)
 			return;
 
-		if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
+		if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
 			SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
 			if (LoadUnloadVehicle(v)) {
 				InvalidateWindow(WC_TRAINS_LIST, v->owner);
@@ -1679,11 +1690,12 @@
 		TrainPlayLeaveStationSound(v);
 
 		{
-			byte b = v->next_order;
-			v->next_order = OT_LEAVESTATION;
+			Order b = v->current_order;
+			v->current_order.type = OT_LEAVESTATION;
+			v->current_order.flags = 0;
 
 			// If this was not the final order, don't remove it from the list.
-			if (!(b & OF_NON_STOP))
+			if (!(b.flags & OF_NON_STOP))
 				return;
 		}
 	}
@@ -1739,15 +1751,19 @@
 	}
 
 	// Did we reach the final destination?
-	if ((v->next_order&OT_MASK) == OT_GOTO_STATION && v->next_order_param == (byte)station) {
+	if (v->current_order.type == OT_GOTO_STATION &&
+			v->current_order.station == (byte)station) {
 		// Yeah, keep the load/unload flags
 		// Non Stop now means if the order should be increased.
-		v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING;
+		v->current_order.type = OT_LOADING;
+		v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
+		v->current_order.flags |= OF_NON_STOP;
 	} else {
 		// No, just do a simple load
-		v->next_order = OT_LOADING;
+		v->current_order.type = OT_LOADING;
+		v->current_order.flags = 0;
 	}
-	v->next_order_param = 0;
+	v->current_order.station = 0;
 
 	SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
 	if (LoadUnloadVehicle(v) != 0) {
@@ -2059,8 +2075,9 @@
 						return;
 					}
 
-					if (v->next_order == OT_LEAVESTATION) {
-						v->next_order = OT_NOTHING;
+					if (v->current_order.type == OT_LEAVESTATION) {
+						v->current_order.type = OT_NOTHING;
+						v->current_order.flags = 0;
 						InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 					}
 				}
@@ -2484,7 +2501,7 @@
 
 	HandleTrainLoading(v, mode);
 
-	if ((v->next_order & OT_MASK) == OT_LOADING)
+	if (v->current_order.type == OT_LOADING)
 		return;
 
 	if (CheckTrainStayInDepot(v))
@@ -2532,8 +2549,6 @@
 
 void TrainEnterDepot(Vehicle *v, uint tile)
 {
-	byte t;
-
 	SetSignalsOnBothDir(tile, _depot_track_ind[_map5[tile]&3]);
 
 	if (v->subtype != 0)
@@ -2551,17 +2566,19 @@
 
 	TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
 
-	if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
+	if (v->current_order.type == OT_GOTO_DEPOT) {
+		Order t;
+
 		InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 
-		t = v->next_order;
-		v->next_order = OT_DUMMY;
-
-		// Part of the schedule?
-		if (t & OF_UNLOAD) { v->u.rail.days_since_order_progr = 0; v->cur_order_index++; }
-
-		// User initiated?
-		else if (t & OF_FULL_LOAD) {
+		t = v->current_order;
+		v->current_order.type = OT_DUMMY;
+		v->current_order.flags = 0;
+
+		if (t.flags & OF_UNLOAD) { // Part of the schedule?
+			v->u.rail.days_since_order_progr = 0;
+			v->cur_order_index++;
+		} else if (t.flags & OF_FULL_LOAD) { // User initiated?
 			v->vehstatus |= VS_STOPPED;
 			if (v->owner == _local_player) {
 				SetDParam(0, v->unitnumber);
@@ -2594,18 +2611,19 @@
 
 	// Don't interfere with a depot visit scheduled by the user, or a
 	// depot visit by the order list.
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT &&
-			(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			(v->current_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) != 0)
 		return;
 
 	tfdd = FindClosestTrainDepot(v);
 	/* Only go to the depot if it is not too far out of our way. */
 	if (tfdd.best_length == (uint)-1 || tfdd.best_length > 16 ) {
-		if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
+		if (v->current_order.type == OT_GOTO_DEPOT) {
 			/* If we were already heading for a depot but it has
 			 * suddenly moved farther away, we continue our normal
 			 * schedule? */
-			v->next_order = OT_DUMMY;
+			v->current_order.type = OT_DUMMY;
+			v->current_order.flags = 0;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 		}
 		return;
@@ -2613,11 +2631,14 @@
 
 	depot = GetDepotByTile(tfdd.tile);
 
-	if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT && v->next_order_param != depot && !CHANCE16(3,16))
+	if (v->current_order.type == OT_GOTO_DEPOT &&
+			v->current_order.station != depot &&
+			!CHANCE16(3,16))
 		return;
 
-	v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
-	v->next_order_param = depot;
+	v->current_order.type = OT_GOTO_DEPOT;
+	v->current_order.flags = OF_NON_STOP;
+	v->current_order.station = depot;
 	v->dest_tile = tfdd.tile;
 	InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
 }
@@ -2662,8 +2683,8 @@
 		CheckOrders(v);
 
 		/* update destination */
-		if ((v->next_order & OT_MASK) == OT_GOTO_STATION &&
-				(tile=DEREF_STATION(v->next_order_param)->train_tile) != 0)
+		if (v->current_order.type == OT_GOTO_STATION &&
+				(tile = DEREF_STATION(v->current_order.station)->train_tile) != 0)
 					v->dest_tile = tile;
 
 		if ((v->vehstatus & VS_STOPPED) == 0) {
@@ -2719,10 +2740,10 @@
 	_age_cargo_skip_counter = 1;
 }
 
-int ScheduleHasDepotOrders(uint16 *schedule)
+int ScheduleHasDepotOrders(const Order *schedule)
 {
-	for (;*schedule!=0;schedule++)
-		if ((*schedule&OT_MASK) == OT_GOTO_DEPOT)
+	for (; schedule->type != OT_NOTHING; schedule++)
+		if (schedule->type == OT_GOTO_DEPOT)
 			return true;
 	return false;
 }
--- a/train_gui.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/train_gui.c	Sun Dec 05 12:43:04 2004 +0000
@@ -778,15 +778,15 @@
 				str = STR_TRAIN_STOPPING + _patches.vehicle_speed;
 			}
 		} else {
-			switch(v->next_order & OT_MASK) {
+			switch (v->current_order.type) {
 			case OT_GOTO_STATION: {
 				str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				SetDParam(1, v->u.rail.last_speed * 10 >> 4);
 			} break;
 
 			case OT_GOTO_DEPOT: {
-				Depot *dep = &_depots[v->next_order_param];
+				Depot *dep = &_depots[v->current_order.station];
 				SetDParam(0, dep->town_index);
 				str = STR_HEADING_FOR_TRAIN_DEPOT + _patches.vehicle_speed;
 				SetDParam(1, v->u.rail.last_speed * 10 >> 4);
@@ -798,7 +798,7 @@
 				break;
 
 			case OT_GOTO_WAYPOINT: {
-				SetDParam(0, v->next_order_param);
+				SetDParam(0, v->current_order.station);
 				str = STR_HEADING_FOR_WAYPOINT + _patches.vehicle_speed;
 				SetDParam(1, v->u.rail.last_speed * 10 >> 4);
 				break;
--- a/vehicle.c	Sun Dec 05 12:25:25 2004 +0000
+++ b/vehicle.c	Sun Dec 05 12:43:04 2004 +0000
@@ -402,7 +402,7 @@
 
 Vehicle *IsScheduleShared(Vehicle *u)
 {
-	uint16 *sched = u->schedule_ptr;
+	const Order *sched = u->schedule_ptr;
 	Vehicle *v;
 
 	FOR_ALL_VEHICLES(v) {
@@ -414,7 +414,8 @@
 
 void DeleteVehicleSchedule(Vehicle *v)
 {
-	uint16 *sched, *cur;
+	Order *sched;
+	Order *cur;
 	int num;
 	Vehicle *u;
 
@@ -446,32 +447,33 @@
 	}
 }
 
-void DeleteCommandFromVehicleSchedule(uint cmd)
+void DeleteCommandFromVehicleSchedule(Order cmd)
 {
 	Vehicle *v;
-	uint16 *sched;
-	uint order;
 	bool need_invalidate;
 
 	FOR_ALL_VEHICLES(v) {
 		if (v->type != 0 && v->schedule_ptr != NULL) {
+			Order *sched;
 
 			// clear last station visited
-			if (v->last_station_visited == (cmd>>8) && (cmd & OT_MASK) == OT_GOTO_STATION)
+			if (v->last_station_visited == cmd.station && cmd.type == OT_GOTO_STATION)
 				v->last_station_visited = 0xFF;
 
 			// check the next order
-			if ( (uint)((v->next_order&OT_MASK) | (v->next_order_param<<8)) == cmd) {
-				v->next_order = OT_DUMMY;
+			if (v->current_order.type == cmd.type &&
+					v->current_order.station == cmd.station) {
+				v->current_order.type = OT_DUMMY;
+				v->current_order.flags = 0;
 				InvalidateWindow(WC_VEHICLE_VIEW, v->index);
 			}
 
 			// clear the order list
 			need_invalidate = false;
-			sched = v->schedule_ptr;
-			while ((order=*sched++) != 0) {
-				if ( (order & (OT_MASK|0xFF00)) == cmd) {
-					sched[-1] = OT_DUMMY;
+			for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
+				if (sched->type == cmd.type && sched->station == cmd.station) {
+					sched->type = OT_DUMMY;
+					sched->flags = 0;
 					need_invalidate = true;
 				}
 			}
@@ -484,6 +486,7 @@
 
 void DoDeleteDepot(uint tile)
 {
+	Order order;
 	byte dep_index;
 	Depot *d;
 
@@ -494,7 +497,10 @@
 	for(d=_depots,dep_index=0; d->xy != (TileIndex)tile; d++) {dep_index++;}
 	d->xy = 0;
 
-	DeleteCommandFromVehicleSchedule((dep_index << 8) + OT_GOTO_DEPOT);
+	order.type = OT_GOTO_DEPOT;
+	order.flags = 0;
+	order.station = dep_index;
+	DeleteCommandFromVehicleSchedule(order);
 
 	// Delete the depot
 	DeleteWindowById(WC_VEHICLE_DEPOT, tile);
@@ -1586,8 +1592,8 @@
 
 	SLE_VAR(Vehicle,cur_order_index,	SLE_UINT8),
 	SLE_VAR(Vehicle,num_orders,				SLE_UINT8),
-	SLE_VAR(Vehicle,next_order,				SLE_UINT8),
-	SLE_VAR(Vehicle,next_order_param,	SLE_UINT8),
+	SLE_VAR(Vehicle,current_order,		SLE_UINT8), /* XXX hack to avoid version bump */
+	SLE_VAR(Vehicle,current_order.station, SLE_UINT8),
 	SLE_REF(Vehicle,schedule_ptr,			REF_SCHEDULE),
 
 	SLE_VAR(Vehicle,age,							SLE_UINT16),
@@ -1731,7 +1737,7 @@
 	SLE_VAR(Vehicle,z_height,					SLE_UINT8),
 	SLE_VAR(Vehicle,owner,						SLE_UINT8),
 	SLE_VAR(Vehicle,vehstatus,				SLE_UINT8),
-	SLE_VAR(Vehicle,next_order,				SLE_UINT8),
+	SLE_VAR(Vehicle,current_order.station, SLE_UINT8),
 
 	SLE_VAR(Vehicle,cur_image,				SLE_UINT16),
 	SLE_VAR(Vehicle,age,							SLE_UINT16),
@@ -1858,15 +1864,31 @@
 
 static void Save_ORDR()
 {
+	uint16 orders[lengthof(_order_array)];
 	uint len = _ptr_to_next_order - _order_array;
-	SlArray(_order_array, len, SLE_UINT16);
+	uint i;
+
+	assert (len <= lengthof(orders));
+
+	for (i = 0; i < len; ++i)
+		orders[i] = PackOrder(&_order_array[i]);
+
+	SlArray(orders, len, SLE_UINT16);
 }
 
 static void Load_ORDR()
 {
+	uint16 orders[lengthof(_order_array)];
 	uint len = SlGetFieldLength() >> 1;
+	uint i;
+
+	assert (len <= lengthof(orders));
+
 	_ptr_to_next_order = _order_array + len;
-	SlArray(_order_array, len, SLE_UINT16);
+	SlArray(orders, len, SLE_UINT16);
+
+	for (i = 0; i < len; ++i)
+		_order_array[i] = UnpackOrder(orders[i]);
 }
 
 const ChunkHandler _veh_chunk_handlers[] = {
--- a/vehicle.h	Sun Dec 05 12:25:25 2004 +0000
+++ b/vehicle.h	Sun Dec 05 12:43:04 2004 +0000
@@ -3,6 +3,27 @@
 
 #include "vehicle_gui.h"
 
+typedef struct Order {
+	uint8 type:4;
+	uint8 flags:4;
+	uint8 station;
+} Order;
+
+static inline uint16 PackOrder(const Order *order)
+{
+	return order->station << 8 | order->flags << 4 | order->type;
+}
+
+static inline Order UnpackOrder(uint16 packed)
+{
+	Order order = {
+		(packed & 0x000f),
+		(packed & 0x00f0) >> 4,
+		(packed & 0xff00) >> 8
+	};
+	return order;
+}
+
 typedef struct VehicleRail {
 	uint16 last_speed;		// NOSAVE: only used in UI
 	uint16 crash_anim_pos;
@@ -145,9 +166,8 @@
 	// related to the current order
 	byte cur_order_index;
 	byte num_orders;
-	byte next_order;
-	byte next_order_param;
-	uint16 *schedule_ptr;
+	Order current_order;
+	Order *schedule_ptr;
 
 	// Boundaries for the current position in the world and a next hash link.
 	// NOSAVE: All of those can be updated with VehiclePositionChanged()
@@ -220,16 +240,13 @@
 	OT_LEAVESTATION = 4,
 	OT_DUMMY = 5,
 	OT_GOTO_WAYPOINT = 6,
-
-	OT_MASK = 0x1F,
 };
 
 /* Order flags */
 enum {
-	OF_UNLOAD = 0x20,
-	OF_FULL_LOAD = 0x40, // Also used when to force an aircraft into a depot.
-	OF_NON_STOP = 0x80,
-	OF_MASK = 0xE0,
+	OF_UNLOAD    = 0x2,
+	OF_FULL_LOAD = 0x4, // Also used when to force an aircraft into a depot
+	OF_NON_STOP  = 0x8
 };
 
 
@@ -269,8 +286,9 @@
 typedef void *VehicleFromPosProc(Vehicle *v, void *data);
 
 typedef struct {
+	VehicleID clone;
 	byte orderindex;
-	uint16 order[41];
+	Order order[41];
 	uint16 service_interval;
 	char name[32];
 } BackuppedOrders;
@@ -337,7 +355,7 @@
 void AgeVehicle(Vehicle *v);
 void MaybeRenewVehicle(Vehicle *v, int32 build_cost);
 
-void DeleteCommandFromVehicleSchedule(uint cmd);
+void DeleteCommandFromVehicleSchedule(Order cmd);
 
 void BeginVehicleMove(Vehicle *v);
 void EndVehicleMove(Vehicle *v);
@@ -361,7 +379,7 @@
 
 int CheckStoppedInDepot(Vehicle *v);
 
-int ScheduleHasDepotOrders(uint16 *schedule);
+int ScheduleHasDepotOrders(const Order *schedule);
 int CheckOrders(Vehicle *v);
 
 typedef struct GetNewVehiclePosResult {
@@ -389,8 +407,8 @@
 
 VARDEF Vehicle _vehicles[NUM_VEHICLES];
 
-VARDEF uint16 _order_array[5000];
-VARDEF uint16 *_ptr_to_next_order;
+VARDEF Order _order_array[5000];
+VARDEF Order *_ptr_to_next_order;
 
 VARDEF Depot _depots[255];