(svn r6291) -Feature: Vehicle lists from the station window now also got the goto depot button
authorbjarni
Fri, 01 Sep 2006 10:24:15 +0000
changeset 4506 0d8fcc0a4e49
parent 4505 f87e0c7fdda1
child 4507 7a53f49bfec4
(svn r6291) -Feature: Vehicle lists from the station window now also got the goto depot button
-Codechange: unified the code for mass goto depot to avoid duplicated code
-Fix: Vehicles already on the way to depots will not be cancelled by mass goto depot (made it really hard to send all vehicles at once)
aircraft_cmd.c
aircraft_gui.c
roadveh_cmd.c
roadveh_gui.c
ship_cmd.c
ship_gui.c
train_cmd.c
train_gui.c
vehicle.c
vehicle.h
vehicle_gui.c
vehicle_gui.h
--- a/aircraft_cmd.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/aircraft_cmd.c	Fri Sep 01 10:24:15 2006 +0000
@@ -492,30 +492,28 @@
  * @param tile unused
  * @param p1 vehicle ID to send to the hangar
  * @param p2 various bitmasked elements
- * - p2 bit 0 - aircraft will try to goto a hangar, but not stop there (service only)
- * - p2 bit 1 - send all of shared orders to depot
- * - p2 bit 2 - aircraft will try to locate another airport with a hangar if the target airport lacks one (used by helicopters for autorenew and autoreplace)
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
  */
 int32 CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
 
-	if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
-		return SendAllVehiclesToDepot(VEH_Aircraft, flags, HASBIT(p2, 0), _current_player);
+	if (p2 & DEPOT_MASS_SEND) {
+		/* Mass goto depot requested */
+		if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
+		return SendAllVehiclesToDepot(VEH_Aircraft, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
 	}
 
-	if (!IsValidVehicleID(p1)) return return_value;
+	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return return_value;
+	if (v->type != VEH_Aircraft || !CheckOwnership(v->owner)) return CMD_ERROR;
 
-	if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendAircraftToHangar(tile, flags, v->next_shared->index, p2);
-
-	if (v->current_order.type == OT_GOTO_DEPOT && p2 == 0) {
+	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
+		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
 		if (flags & DC_EXEC) {
-			if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not turn goto hangar orders off
 			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
 			v->current_order.type = OT_DUMMY;
 			v->current_order.flags = 0;
@@ -530,12 +528,12 @@
 		if (!IsValidStation(st) || st->airport_tile == 0 || GetAirport(st->airport_type)->nof_depots == 0) {
 			StationID station;
 
-			if (!HASBIT(p2, 2)) return return_value;
+			if (!(p2 & DEPOT_LOCATE_HANGAR)) return CMD_ERROR;
 			// the aircraft has to search for a hangar on its own
 			station = FindNearestHangar(v);
 
 			next_airport_has_hangar = false;
-			if (station == INVALID_STATION) return return_value;
+			if (station == INVALID_STATION) return CMD_ERROR;
 			st = GetStation(station);
 			next_airport_index = station;
 
@@ -544,11 +542,11 @@
 		if (flags & DC_EXEC) {
 			v->current_order.type = OT_GOTO_DEPOT;
 			v->current_order.flags = OF_NON_STOP;
-			if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+			if (!(p1 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 			v->current_order.dest.station = next_airport_index;
 			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
-			if (HASBIT(p2, 2) || (p2 == 0 && v->u.air.state == FLYING && !next_airport_has_hangar)) {
-			// the aircraft is now heading for a different hangar than the next in the orders
+			if (p2 & DEPOT_LOCATE_HANGAR || (p2 & DEPOT_SERVICE && v->u.air.state == FLYING && !next_airport_has_hangar)) {
+				/* The aircraft is now heading for a different hangar than the next in the orders */
 				AircraftNextAirportPos_and_Order(v);
 				v->u.air.targetairport = next_airport_index;
 			}
@@ -1601,7 +1599,7 @@
 				HASBIT(GetEngine(v->engine_type)->player_avail, _local_player))
 			)) {
 		_current_player = _local_player;
-		DoCommandP(v->tile, v->index, (1|(1 << 2)), NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
+		DoCommandP(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
 		_current_player = OWNER_NONE;
 	}
 }
@@ -1665,7 +1663,7 @@
 			(p->engine_renew && v->age - v->max_age > (p->engine_renew_months * 30))) {
 			// send the aircraft to the hangar at next airport
 			_current_player = _local_player;
-			DoCommandP(v->tile, v->index, 1, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
+			DoCommandP(v->tile, v->index, DEPOT_SERVICE, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_SHOW_NO_ERROR);
 			_current_player = OWNER_NONE;
 		}
 	}
--- a/aircraft_gui.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/aircraft_gui.c	Fri Sep 01 10:24:15 2006 +0000
@@ -596,7 +596,7 @@
 			ScrollMainWindowTo(v->x_pos, v->y_pos);
 			break;
 		case 7: /* goto hangar */
-			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_MSG(STR_A012_CAN_T_SEND_AIRCRAFT_TO));
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_AIRCRAFT_TO_HANGAR | CMD_MSG(STR_A012_CAN_T_SEND_AIRCRAFT_TO));
 			break;
 		case 8: /* refit */
 			ShowAircraftRefitWindow(v);
@@ -985,7 +985,7 @@
 {      WWT_PANEL,  RESIZE_RIGHT,    14,   248,   259,    14,    25, 0x0,                   STR_NULL },
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   247,    26,   169, 0x401,                 STR_A01F_AIRCRAFT_CLICK_ON_AIRCRAFT },
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   248,   259,    26,   169, 0x0,                   STR_0190_SCROLL_BAR_SCROLLS_LIST },
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   170,   181, STR_A003_NEW_AIRCRAFT, STR_A020_BUILD_NEW_AIRCRAFT_REQUIRES },
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   170,   181, STR_SEND_TO_HANGARS,   STR_SEND_TO_HANGARS_TIP },
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,   125,   247,   170,   181, STR_REPLACE_VEHICLES,  STR_REPLACE_HELP },
 {      WWT_PANEL,    RESIZE_RTB,    14,   248,   247,   170,   181, 0x0,                   STR_NULL },
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   248,   259,   170,   181, 0x0,                   STR_RESIZE_BUTTON },
--- a/roadveh_cmd.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/roadveh_cmd.c	Fri Sep 01 10:24:15 2006 +0000
@@ -358,33 +358,32 @@
  * @param tile unused
  * @param p1 vehicle ID to send to the depot
  * @param p2 various bitmasked elements
- * - p2 bit 0 - if bit 0 is set, then the road vehicle will only service at the depot. 0 Makes it stop inside
- * - p2 bit 1 - send all of shared orders to depot
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
  */
 int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
 	const Depot *dep;
-	const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
 
-	if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
-		return SendAllVehiclesToDepot(VEH_Road, flags, HASBIT(p2, 0), _current_player);
+	if (p2 & DEPOT_MASS_SEND) {
+		/* Mass goto depot requested */
+		if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
+		return SendAllVehiclesToDepot(VEH_Road, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
 	}
 
-	if (!IsValidVehicleID(p1)) return return_value;
+	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return return_value;
+	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
 
-	if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendRoadVehToDepot(tile, flags, v->next_shared->index, p2);
-
-	if (v->vehstatus & VS_CRASHED) return return_value;
+	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 
 	/* If the current orders are already goto-depot */
 	if (v->current_order.type == OT_GOTO_DEPOT) {
+		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 		if (flags & DC_EXEC) {
-			if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not turn goto depot orders off
 			/* 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, OFB_PART_OF_ORDERS))
@@ -398,16 +397,13 @@
 	}
 
 	dep = FindClosestRoadDepot(v);
-	if (dep == NULL) {
-		if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not return error
-		return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
-	}
+	if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
 
 	if (flags & DC_EXEC) {
 		ClearSlot(v);
 		v->current_order.type = OT_GOTO_DEPOT;
 		v->current_order.flags = OF_NON_STOP;
-		if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 		v->current_order.dest.depot = dep->index;
 		v->dest_tile = dep->xy;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
--- a/roadveh_gui.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/roadveh_gui.c	Fri Sep 01 10:24:15 2006 +0000
@@ -383,7 +383,7 @@
 			ScrollMainWindowTo(v->x_pos, v->y_pos);
 			break;
 		case 7: /* goto depot */
-			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_ROADVEH_TO_DEPOT | CMD_MSG(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT));
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_ROADVEH_TO_DEPOT | CMD_MSG(STR_9018_CAN_T_SEND_VEHICLE_TO_DEPOT));
 			break;
 		case 8: /* turn around */
 			DoCommandP(v->tile, v->index, 0, NULL, CMD_TURN_ROADVEH | CMD_MSG(STR_9033_CAN_T_MAKE_VEHICLE_TURN));
@@ -913,8 +913,7 @@
 {      WWT_PANEL,  RESIZE_RIGHT,    14,   248,   259,    14,    25, 0x0,                    STR_NULL},
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   247,    26,   207, 0x701,                  STR_901A_ROAD_VEHICLES_CLICK_ON},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   248,   259,    26,   207, 0x0,                    STR_0190_SCROLL_BAR_SCROLLS_LIST},
-/* only for our road list, a 'Build Vehicle' button that opens the depot of the last built depot */
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   208,   219, STR_8815_NEW_VEHICLES,  STR_901B_BUILD_NEW_ROAD_VEHICLES},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   208,   219, STR_SEND_TO_DEPOTS,     STR_SEND_TO_DEPOTS_TIP},
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,   125,   247,   208,   219, STR_REPLACE_VEHICLES,   STR_REPLACE_HELP},
 {      WWT_PANEL,    RESIZE_RTB,    14,   248,   247,   208,   219, 0x0,                    STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   248,   259,   208,   219, 0x0,                    STR_RESIZE_BUTTON},
--- a/ship_cmd.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/ship_cmd.c	Fri Sep 01 10:24:15 2006 +0000
@@ -996,33 +996,32 @@
  * @param tile unused
  * @param p1 vehicle ID to send to the depot
  * @param p2 various bitmasked elements
- * - p2 bit 0 - if bit 0 is set, then the ship will only service at the depot. 0 Makes it stop inside
- * - p2 bit 1 - send all of shared orders to depot
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
  */
 int32 CmdSendShipToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
 	const Depot *dep;
-	const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
 
-	if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
-		return SendAllVehiclesToDepot(VEH_Ship, flags, HASBIT(p2, 0), _current_player);
+	if (p2 & DEPOT_MASS_SEND) {
+		/* Mass goto depot requested */
+		if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
+		return SendAllVehiclesToDepot(VEH_Ship, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
 	}
 
-	if (!IsValidVehicleID(p1)) return return_value;
+	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return return_value;
+	if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
 
-	if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendShipToDepot(tile, flags, v->next_shared->index, p2);
-
-	if (v->vehstatus & VS_CRASHED) return return_value;
+	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 
 	/* If the current orders are already goto-depot */
 	if (v->current_order.type == OT_GOTO_DEPOT) {
+		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 		if (flags & DC_EXEC) {
-			if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not turn goto depot orders off
 			/* 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, OFB_PART_OF_ORDERS))
@@ -1036,16 +1035,13 @@
 	}
 
 	dep = FindClosestShipDepot(v);
-	if (dep == NULL) {
-		if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not return error
-		return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
-	}
+	if (dep == NULL) return_cmd_error(STR_981A_UNABLE_TO_FIND_LOCAL_DEPOT);
 
 	if (flags & DC_EXEC) {
 		v->dest_tile = dep->xy;
 		v->current_order.type = OT_GOTO_DEPOT;
 		v->current_order.flags = OF_NON_STOP;
-		if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 		v->current_order.dest.depot = dep->index;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 	}
--- a/ship_gui.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/ship_gui.c	Fri Sep 01 10:24:15 2006 +0000
@@ -524,7 +524,7 @@
 					ScrollMainWindowTo(v->x_pos, v->y_pos);
 					break;
 				case 7: /* goto hangar */
-					DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
+					DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_SHIP_TO_DEPOT | CMD_MSG(STR_9819_CAN_T_SEND_SHIP_TO_DEPOT));
 					break;
 				case 8: /* refit */
 					ShowShipRefitWindow(v);
@@ -926,7 +926,7 @@
 {      WWT_PANEL,  RESIZE_RIGHT,    14,   248,   259,    14,    25, 0x0,                  STR_NULL},
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   247,    26,   169, 0x401,                STR_9823_SHIPS_CLICK_ON_SHIP_FOR},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   248,   259,    26,   169, 0x0,                  STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   170,   181, STR_9804_NEW_SHIPS,   STR_9824_BUILD_NEW_SHIPS_REQUIRES},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   124,   170,   181, STR_SEND_TO_DEPOTS,   STR_SEND_TO_DEPOTS_TIP},
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,   125,   247,   170,   181, STR_REPLACE_VEHICLES, STR_REPLACE_HELP},
 {      WWT_PANEL,    RESIZE_RTB,    14,   248,   247,   170,   181, 0x0,                  STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   248,   259,   170,   181, 0x0,                  STR_RESIZE_BUTTON},
--- a/train_cmd.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/train_cmd.c	Fri Sep 01 10:24:15 2006 +0000
@@ -1925,32 +1925,31 @@
  * @param tile unused
  * @param p1 train to send to the depot
  * @param p2 various bitmasked elements
- * - p2 bit 0 - if bit 0 is set, then the train will only service at the depot. 0 Makes it stop inside
- * - p2 bit 1 - send all of shared orders to depot
+ * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h)
+ * - p2 bit 8-10 - VLW flag (for mass goto depot)
  */
 int32 CmdSendTrainToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
 	TrainFindDepotData tfdd;
-	const int32 return_value = HASBIT(p2, 1) ? 0 : CMD_ERROR;
-
-	if (HASBIT(p2, 1) && (p2 & VLW_FLAGS) == VLW_STANDARD) {
-		return SendAllVehiclesToDepot(VEH_Train, flags, HASBIT(p2, 0), _current_player);
+
+	if (p2 & DEPOT_MASS_SEND) {
+		/* Mass goto depot requested */
+		if (!ValidVLWFlags(p2 & VLW_FLAGS)) return CMD_ERROR;
+		return SendAllVehiclesToDepot(VEH_Train, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_FLAGS), p1);
 	}
 
-	if (!IsValidVehicleID(p1)) return return_value;
+	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return return_value;
-
-	if (HASBIT(p2, 1) && v->next_shared != NULL) CmdSendTrainToDepot(tile, flags, v->next_shared->index, p2);
-
-	if (v->vehstatus & VS_CRASHED) return return_value;
+	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+
+	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 
 	if (v->current_order.type == OT_GOTO_DEPOT) {
+		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 		if (flags & DC_EXEC) {
-			if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not turn goto depot orders off
 			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
 				v->u.rail.days_since_order_progr = 0;
 				v->cur_order_index++;
@@ -1964,16 +1963,13 @@
 	}
 
 	tfdd = FindClosestTrainDepot(v, 0);
-	if (tfdd.best_length == (uint)-1) {
-		if (HASBIT(p2, 1)) return 0;	// Mass ordering goto depot should not return error
-		return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
-	}
+	if (tfdd.best_length == (uint)-1) return_cmd_error(STR_883A_UNABLE_TO_FIND_ROUTE_TO);
 
 	if (flags & DC_EXEC) {
 		v->dest_tile = tfdd.tile;
 		v->current_order.type = OT_GOTO_DEPOT;
 		v->current_order.flags = OF_NON_STOP;
-		if (!HASBIT(p2,0)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
+		if (!(p2 & DEPOT_SERVICE)) SETBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 		v->current_order.dest.depot = GetDepotByTile(tfdd.tile)->index;
 		InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 		/* If there is no depot in front, reverse automatically */
--- a/train_gui.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/train_gui.c	Fri Sep 01 10:24:15 2006 +0000
@@ -1025,7 +1025,7 @@
 			break;
 		case 7: /* goto depot */
 			/* TrainGotoDepot has a nice randomizer in the pathfinder, which causes desyncs... */
-			DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, NULL, CMD_SEND_TRAIN_TO_DEPOT | CMD_NO_TEST_IF_IN_NETWORK | CMD_MSG(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT));
+			DoCommandP(v->tile, v->index, _ctrl_pressed ? DEPOT_SERVICE : 0, NULL, CMD_SEND_TRAIN_TO_DEPOT | CMD_NO_TEST_IF_IN_NETWORK | CMD_MSG(STR_8830_CAN_T_SEND_TRAIN_TO_DEPOT));
 			break;
 		case 8: /* force proceed */
 			DoCommandP(v->tile, v->index, 0, NULL, CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_8862_CAN_T_MAKE_TRAIN_PASS_SIGNAL));
@@ -1383,7 +1383,7 @@
 {      WWT_PANEL,  RESIZE_RIGHT,    14,   248,   324,    14,    25, 0x0,                   STR_NULL},
 {     WWT_MATRIX,     RESIZE_RB,    14,     0,   312,    26,   207, 0x701,                 STR_883D_TRAINS_CLICK_ON_TRAIN_FOR},
 {  WWT_SCROLLBAR,    RESIZE_LRB,    14,   313,   324,    26,   207, 0x0,                   STR_0190_SCROLL_BAR_SCROLLS_LIST},
-{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   156,   208,   219, STR_8815_NEW_VEHICLES, STR_883E_BUILD_NEW_TRAINS_REQUIRES},
+{ WWT_PUSHTXTBTN,     RESIZE_TB,    14,     0,   156,   208,   219, STR_SEND_TO_DEPOTS,    STR_SEND_TO_DEPOTS_TIP},
 { WWT_PUSHTXTBTN,     RESIZE_TB,    14,   157,   312,   208,   219, STR_REPLACE_VEHICLES,  STR_REPLACE_HELP},
 {      WWT_PANEL,    RESIZE_RTB,    14,   313,   312,   208,   219, 0x0,                   STR_NULL},
 {  WWT_RESIZEBOX,   RESIZE_LRTB,    14,   313,   324,   208,   219, 0x0,                   STR_RESIZE_BUTTON},
--- a/vehicle.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/vehicle.c	Fri Sep 01 10:24:15 2006 +0000
@@ -1969,24 +1969,26 @@
 * @param flags the flags used for DoCommand()
 * @param service should the vehicles only get service in the depots
 * @param owner PlayerID of owner of the vehicles to send
+* @param VLW_flag tells what kind of list requested the goto depot
 * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
 */
-int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner)
+int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
 {
 	const Vehicle** sort_list;
 	uint n, i;
 
 	sort_list = malloc(GetVehicleArraySize() * sizeof(sort_list[0]));
 	if (sort_list == NULL) {
-		error("Could not allocate memory for the vehicle-sorting-list");
+		error("Could not allocate memory for the vehicle-goto-depot-list");
 	}
 
-	n = GenerateVehicleSortList(sort_list, type, owner, INVALID_STATION, INVALID_ORDER, VLW_STANDARD);
+	n = GenerateVehicleSortList(sort_list, type, owner, (vlw_flag == VLW_STATION_LIST) ? id : INVALID_STATION, (vlw_flag == VLW_SHARED_ORDERS) ? id : INVALID_ORDER, vlw_flag);
 
 	/* Send all the vehicles to a depot */
 	for (i = 0; i < n; i++) {
 		const Vehicle *v = sort_list[i];
-		if (!DoCommand(v->tile, v->index, service, flags, CMD_SEND_TO_DEPOT(type)) && !(flags & DC_EXEC)) {
+		if (!DoCommand(v->tile, v->index, service | DEPOT_DONT_CANCEL, flags, CMD_SEND_TO_DEPOT(type)) && !(flags & DC_EXEC)) {
+			/* At least one vehicle is valid to send the command to, so the mass goto depot is valid. No need to check the rest */
 			free((void*)sort_list);
 			return 0;
 		}
--- a/vehicle.h	Fri Sep 01 08:06:11 2006 +0000
+++ b/vehicle.h	Fri Sep 01 10:24:15 2006 +0000
@@ -315,7 +315,16 @@
 bool VehicleNeedsService(const Vehicle *v);
 
 uint GenerateVehicleSortList(const Vehicle** sort_list, byte type, PlayerID owner, StationID station, OrderID order, uint16 window_type);
-int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner);
+int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
+
+/* Flags to add to p2 for goto depot commands */
+/* Note: bits 8-10 are used for VLW flags */
+enum {
+	DEPOT_SERVICE       = (1 << 0),	// The vehicle will leave the depot right after arrival (serivce only)
+	DEPOT_MASS_SEND     = (1 << 1), // Tells that it's a mass send to depot command (type in VLW flag)
+	DEPOT_DONT_CANCEL   = (1 << 2), // Don't cancel current goto depot command if any
+	DEPOT_LOCATE_HANGAR = (1 << 3), // Find another airport if the target one lacks a hangar
+};
 
 typedef struct GetNewVehiclePosResult {
 	int x,y;
--- a/vehicle_gui.c	Fri Sep 01 08:06:11 2006 +0000
+++ b/vehicle_gui.c	Fri Sep 01 10:24:15 2006 +0000
@@ -1188,17 +1188,9 @@
 					SetDParam(0, w->vscroll.count);
 					w->widget[1].unkA  = STR_VEH_WITH_SHARED_ORDERS_LIST;
 
-					if (owner != _local_player) break;	// only set up buttons for local player
+					if (owner != _local_player) break; // only set up buttons for local player
 					w->widget[10].unkA = STR_EMPTY;
 					SETBIT(w->disabled_state, 10);
-
-					if (vehicle_type == VEH_Aircraft) {
-						w->widget[9].unkA = STR_SEND_TO_HANGARS;
-						w->widget[9].tooltips = STR_SEND_TO_HANGARS_TIP;
-					} else {
-						w->widget[9].unkA = STR_SEND_TO_DEPOTS;
-						w->widget[9].tooltips = STR_SEND_TO_DEPOTS_TIP;
-					}
 					break;
 
 				case VLW_STANDARD:
@@ -1215,15 +1207,8 @@
 						default: NOT_REACHED(); break;
 					}
 
-					if (owner != _local_player) break;	// only set up buttons for local player
+					if (owner != _local_player) break; // only set up buttons for local player
 					if (vl->list_length == 0) SETBIT(w->disabled_state, 9);
-						if (vehicle_type == VEH_Aircraft) {
-							w->widget[9].unkA = STR_SEND_TO_HANGARS;
-							w->widget[9].tooltips = STR_SEND_TO_HANGARS_TIP;
-						} else {
-							w->widget[9].unkA = STR_SEND_TO_DEPOTS;
-							w->widget[9].tooltips = STR_SEND_TO_DEPOTS_TIP;
-						}
 					break;
 
 				case VLW_STATION_LIST:
@@ -1237,6 +1222,8 @@
 						case VEH_Aircraft: w->widget[1].unkA = STR_SCHEDULED_AIRCRAFT;      break;
 						default: NOT_REACHED(); break;
 					}
+					if (owner != _local_player) break; // only set up buttons for local player
+					if (vl->list_length == 0) SETBIT(w->disabled_state, 9);
 					break;
 
 				default: NOT_REACHED(); break;
@@ -1345,36 +1332,14 @@
 					}
 				} break;
 
-				case 9: { /* Left button */
-					uint16 window_type = w->window_number & VLW_FLAGS;
+				case 9: // Left button
 					if (GB(w->window_number, 0, 8) /* OwnerID */ != _local_player) break;
-					switch (window_type) {
-						case VLW_STANDARD:
-						case VLW_SHARED_ORDERS: {
-							/* Send to depot */
-							const Vehicle *v;
-							assert(vl->list_length != 0);
-							v = vl->sort_list[0];
-							DoCommandP(v->tile, v->index, window_type | _ctrl_pressed ? 3 : 2, NULL, CMD_SEND_TO_DEPOT(vehicle_type));
-							break;
-						}
+					assert(vl->list_length != 0);
+					DoCommandP(0, GB(w->window_number, 16, 16) /* StationID or OrderID (depending on VLW). Nomatter which one it is, it's needed here */,
+						(w->window_number & VLW_FLAGS) | DEPOT_MASS_SEND | (_ctrl_pressed ? DEPOT_SERVICE : 0), NULL, CMD_SEND_TO_DEPOT(vehicle_type));
+					break;
 
-						case VLW_STATION_LIST:
-							/* Build new Vehicle */
-							switch (vehicle_type) {
-								case VEH_Train:	   ShowBuildTrainWindow(0);    break;
-								case VEH_Road:     ShowBuildRoadVehWindow(0);  break;
-								case VEH_Ship:     ShowBuildShipWindow(0);     break;
-								case VEH_Aircraft: ShowBuildAircraftWindow(0); break;
-								default: NOT_REACHED(); break;
-							}
-							break;
-						default: NOT_REACHED(); break;
-					}
-					break;
-				}
-
-				case 10: /* Right button */
+				case 10: // Right button
 					ShowReplaceVehicleWindow(vehicle_type);
 					break;
 			}
--- a/vehicle_gui.h	Fri Sep 01 08:06:11 2006 +0000
+++ b/vehicle_gui.h	Fri Sep 01 10:24:15 2006 +0000
@@ -47,6 +47,11 @@
 	VLW_STATION_LIST  = 2 << 8,
 };
 
+static inline bool ValidVLWFlags(uint16 flags)
+{
+	return (flags == VLW_STANDARD || flags == VLW_SHARED_ORDERS || flags == VLW_STATION_LIST);
+}
+
 void PlayerVehWndProc(Window *w, WindowEvent *e);
 
 void ShowReplaceVehicleWindow(byte vehicletype);