changeset 8894:2bcad37f1d27 draft

(svn r12661) -Add: ability to send a vehicle (using default orders) to the nearest depot.
author rubidium <rubidium@openttd.org>
date Fri, 11 Apr 2008 15:58:46 +0000
parents a51ef92edbd6
children 80625432d041
files src/lang/english.txt src/order_cmd.cpp src/order_gui.cpp src/order_type.h src/timetable_gui.cpp
diffstat 5 files changed, 142 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2685,12 +2685,18 @@
 STR_ORDER_TOOLTIP_UNLOAD                                        :{BLACK}Change the unloading behaviour of the highlighted order
 STR_GO_TO_STATION                                               :{STRING} {STATION} {STRING}
 
+STR_ORDER_GO_TO_DROPDOWN_TOOLTIP                                :Insert an advanced order
+STR_ORDER_GO_TO_NEAREST_DEPOT                                   :Go to nearest depot
+STR_ORDER_GO_TO_NEAREST_HANGAR                                  :Go to nearest hangar
+STR_ORDER_NEAREST_DEPOT                                         :the nearest
+STR_ORDER_NEAREST_HANGAR                                        :the nearest Hangar
 STR_ORDER_SERVICE_AT                                            :Service at
 STR_ORDER_SERVICE_NON_STOP_AT                                   :Service non-stop at
 STR_ORDER_TRAIN_DEPOT                                           :Train Depot
 STR_ORDER_ROAD_DEPOT                                            :Road Vehicle Depot
 STR_ORDER_SHIP_DEPOT                                            :Ship Depot
 STR_GO_TO_DEPOT                                                 :{STRING} {TOWN} {STRING}
+STR_GO_TO_NEAREST_DEPOT                                         :{STRING} {STRING} {STRING}
 STR_GO_TO_HANGAR                                                :{STRING} {STATION} Hangar
 
 STR_TIMETABLE_GO_TO                                             :{STRING3} {STRING2}
--- a/src/order_cmd.cpp
+++ b/src/order_cmd.cpp
@@ -366,44 +366,48 @@
 		}
 
 		case OT_GOTO_DEPOT: {
-			if (v->type == VEH_AIRCRAFT) {
-				if (!IsValidStationID(new_order.GetDestination())) return CMD_ERROR;
+			if (new_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT) {
+				if (v->type == VEH_AIRCRAFT) {
+					if (!IsValidStationID(new_order.GetDestination())) return CMD_ERROR;
+
+					const Station *st = GetStation(new_order.GetDestination());
 
-				const Station *st = GetStation(new_order.GetDestination());
+					if (!CheckOwnership(st->owner) ||
+							!(st->facilities & FACIL_AIRPORT) ||
+							st->Airport()->nof_depots == 0 ||
+							!CanAircraftUseStation(v->engine_type, st)) {
+						return CMD_ERROR;
+					}
+				} else {
+					if (!IsValidDepotID(new_order.GetDestination())) return CMD_ERROR;
+
+					const Depot *dp = GetDepot(new_order.GetDestination());
 
-				if (!CheckOwnership(st->owner) ||
-						!(st->facilities & FACIL_AIRPORT) ||
-						st->Airport()->nof_depots == 0 ||
-						!CanAircraftUseStation(v->engine_type, st)) {
-					return CMD_ERROR;
+					if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR;
+
+					switch (v->type) {
+						case VEH_TRAIN:
+							if (!IsTileDepotType(dp->xy, TRANSPORT_RAIL)) return CMD_ERROR;
+							break;
+
+						case VEH_ROAD:
+							if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
+							break;
+
+						case VEH_SHIP:
+							if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
+							break;
+
+						default: return CMD_ERROR;
+					}
 				}
 			} else {
-				if (!IsValidDepotID(new_order.GetDestination())) return CMD_ERROR;
-
-				const Depot *dp = GetDepot(new_order.GetDestination());
-
-				if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR;
-
-				switch (v->type) {
-					case VEH_TRAIN:
-						if (!IsTileDepotType(dp->xy, TRANSPORT_RAIL)) return CMD_ERROR;
-						break;
-
-					case VEH_ROAD:
-						if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
-						break;
-
-					case VEH_SHIP:
-						if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
-						break;
-
-					default: return CMD_ERROR;
-				}
+				if (!IsPlayerBuildableVehicleType(v)) return CMD_ERROR;
 			}
 
 			if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && v->type != VEH_TRAIN) return CMD_ERROR;
 			if (new_order.GetDepotOrderType() & ~ODTFB_PART_OF_ORDERS) return CMD_ERROR;
-			if (new_order.GetDepotActionType() & ~ODATFB_HALT) return CMD_ERROR;
+			if (new_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT) return CMD_ERROR;
 			break;
 		}
 
@@ -1516,7 +1520,31 @@
 			break;
 
 		case OT_GOTO_DEPOT:
-			if (v->type != VEH_AIRCRAFT) v->dest_tile = GetDepot(order->GetDestination())->xy;
+			if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+				/* We need to search for the nearest depot (hangar). */
+				TileIndex location;
+				DestinationID destination;
+				bool reverse;
+
+				if (v->FindClosestDepot(&location, &destination, &reverse)) {
+					v->dest_tile = location;
+					v->current_order.MakeGoToDepot(destination, ODTFB_PART_OF_ORDERS);
+
+					/* If there is no depot in front, reverse automatically (trains only) */
+					if (v->type == VEH_TRAIN && reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION);
+
+					if (v->type == VEH_AIRCRAFT && v->u.air.state == FLYING && v->u.air.targetairport != destination) {
+						/* The aircraft is now heading for a different hangar than the next in the orders */
+						extern void AircraftNextAirportPos_and_Order(Vehicle *v);
+						AircraftNextAirportPos_and_Order(v);
+					}
+				} else {
+					UpdateVehicleTimetable(v, true);
+					v->cur_order_index++;
+				}
+			} else if (v->type != VEH_AIRCRAFT) {
+				v->dest_tile = GetDepot(order->GetDestination())->xy;
+			}
 			break;
 
 		case OT_GOTO_WAYPOINT:
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -41,6 +41,7 @@
 	ORDER_WIDGET_DELETE,
 	ORDER_WIDGET_NON_STOP,
 	ORDER_WIDGET_GOTO,
+	ORDER_WIDGET_GOTO_DROPDOWN,
 	ORDER_WIDGET_FULL_LOAD,
 	ORDER_WIDGET_UNLOAD,
 	ORDER_WIDGET_REFIT,
@@ -153,6 +154,18 @@
 	INVALID_STRING_ID
 };
 
+static const StringID _order_goto_dropdown[] = {
+	STR_ORDER_GO_TO,
+	STR_ORDER_GO_TO_NEAREST_DEPOT,
+	INVALID_STRING_ID
+};
+
+static const StringID _order_goto_dropdown_aircraft[] = {
+	STR_ORDER_GO_TO,
+	STR_ORDER_GO_TO_NEAREST_HANGAR,
+	INVALID_STRING_ID
+};
+
 static void DrawOrdersWindow(Window *w)
 {
 	const Vehicle *v = GetVehicle(w->window_number);
@@ -252,11 +265,22 @@
 
 				case OT_GOTO_DEPOT:
 					if (v->type == VEH_AIRCRAFT) {
-						SetDParam(1, STR_GO_TO_HANGAR);
-						SetDParam(3, order->GetDestination());
+						if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+							SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+							SetDParam(3, STR_ORDER_NEAREST_HANGAR);
+						} else {
+							SetDParam(1, STR_GO_TO_HANGAR);
+							SetDParam(3, order->GetDestination());
+						}
+						SetDParam(4, STR_EMPTY);
 					} else {
-						SetDParam(1, STR_GO_TO_DEPOT);
-						SetDParam(3, GetDepot(order->GetDestination())->town_index);
+						if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+							SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+							SetDParam(3, STR_ORDER_NEAREST_DEPOT);
+						} else {
+							SetDParam(1, STR_GO_TO_DEPOT);
+							SetDParam(3, GetDepot(order->GetDestination())->town_index);
+						}
 
 						switch (v->type) {
 							case VEH_TRAIN: SetDParam(4, STR_ORDER_TRAIN_DEPOT); break;
@@ -476,6 +500,23 @@
 }
 
 /**
+ * Handle the click on the service in nearest depot button.
+ *
+ * @param w current window
+ * @param v current vehicle
+ */
+static void OrderClick_NearestDepot(Window *w, const Vehicle *v, int i)
+{
+	Order order;
+	order.next = NULL;
+	order.index = 0;
+	order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS);
+	order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
+
+	DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), order.Pack(), NULL, CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER));
+}
+
+/**
  * Handle the click on the unload button.
  *
  * @param w current window
@@ -693,6 +734,10 @@
 					OrderClick_Goto(w, v, 0);
 					break;
 
+				case ORDER_WIDGET_GOTO_DROPDOWN:
+					ShowDropDownMenu(w, v->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO, 0, 0, w->widget[ORDER_WIDGET_GOTO_DROPDOWN].right - w->widget[ORDER_WIDGET_GOTO].left);
+					break;
+
 				case ORDER_WIDGET_FULL_LOAD:
 					ShowDropDownMenu(w, _order_full_load_drowdown, GetVehicleOrder(v, OrderGetSel(w))->GetLoadType(), ORDER_WIDGET_FULL_LOAD, 0, 2);
 					break;
@@ -732,6 +777,13 @@
 				case ORDER_WIDGET_UNLOAD:
 					OrderClick_Unload(w, v, e->we.dropdown.index);
 					break;
+
+				case ORDER_WIDGET_GOTO:
+					switch (e->we.dropdown.index) {
+						case 0: OrderClick_Goto(w, v, 0); break;
+						case 1: OrderClick_NearestDepot(w, v, 0); break;
+						default: NOT_REACHED();
+					}
 			}
 			break;
 
@@ -827,7 +879,8 @@
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   123,    88,    99, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    88,    99, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
 	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   123,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_NON_STOP},          // ORDER_WIDGET_NON_STOP
-	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   371,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 	{   WWT_DROPDOWN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
 	{   WWT_DROPDOWN,   RESIZE_TB,      14,   248,   371,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
@@ -863,7 +916,8 @@
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   123,    88,    99, STR_8823_SKIP,           STR_8853_SKIP_THE_CURRENT_ORDER},     // ORDER_WIDGET_SKIP
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,   124,   247,    88,    99, STR_8824_DELETE,         STR_8854_DELETE_THE_HIGHLIGHTED},     // ORDER_WIDGET_DELETE
 	{      WWT_EMPTY,   RESIZE_TB,      14,     0,     0,    76,    87, 0x0,                     0x0},                                 // ORDER_WIDGET_NON_STOP
-	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   371,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
+	{    WWT_TEXTBTN,   RESIZE_TB,      14,   248,   359,    88,    99, STR_8826_GO_TO,          STR_8856_INSERT_A_NEW_ORDER_BEFORE},  // ORDER_WIDGET_GOTO
+	{   WWT_DROPDOWN,   RESIZE_TB,      14,   360,   371,    88,    99, STR_EMPTY,               STR_ORDER_GO_TO_DROPDOWN_TOOLTIP},    // ORDER_WIDGET_GOTO_DROPDOWN
 	{   WWT_DROPDOWN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_FULL_LOAD},         // ORDER_WIDGET_FULL_LOAD
 	{   WWT_DROPDOWN,   RESIZE_TB,      14,   186,   372,    76,    87, STR_NULL,                STR_ORDER_TOOLTIP_UNLOAD},            // ORDER_WIDGET_UNLOAD
 	{ WWT_PUSHTXTBTN,   RESIZE_TB,      14,     0,   185,    76,    87, STR_REFIT,               STR_REFIT_TIP},                       // ORDER_WIDGET_REFIT
@@ -900,6 +954,7 @@
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_DELETE
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_NON_STOP
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO
+	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_GOTO_DROPDOWN
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_FULL_LOAD
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_UNLOAD
 	{      WWT_EMPTY,   RESIZE_NONE,    14,     0,     0,    76,    87, 0x0,                STR_NULL},                            // ORDER_WIDGET_REFIT
--- a/src/order_type.h
+++ b/src/order_type.h
@@ -82,6 +82,7 @@
 enum OrderDepotActionFlags {
 	ODATF_SERVICE_ONLY   = 0,      ///< Only service the vehicle.
 	ODATFB_HALT          = 1 << 0, ///< Service the vehicle and then halt it.
+	ODATFB_NEAREST_DEPOT = 1 << 1, ///< Send the vehicle to the nearest depot.
 };
 
 /**
--- a/src/timetable_gui.cpp
+++ b/src/timetable_gui.cpp
@@ -135,11 +135,22 @@
 
 				case OT_GOTO_DEPOT:
 					if (v->type == VEH_AIRCRAFT) {
-						SetDParam(0, STR_GO_TO_HANGAR);
-						SetDParam(2, order->GetDestination());
+						if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+							SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+							SetDParam(3, STR_ORDER_NEAREST_HANGAR);
+						} else {
+							SetDParam(1, STR_GO_TO_HANGAR);
+							SetDParam(3, order->GetDestination());
+						}
+						SetDParam(4, STR_EMPTY);
 					} else {
-						SetDParam(0, STR_GO_TO_DEPOT);
-						SetDParam(2, GetDepot(order->GetDestination())->town_index);
+						if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
+							SetDParam(1, STR_GO_TO_NEAREST_DEPOT);
+							SetDParam(3, STR_ORDER_NEAREST_DEPOT);
+						} else {
+							SetDParam(1, STR_GO_TO_DEPOT);
+							SetDParam(3, GetDepot(order->GetDestination())->town_index);
+						}
 
 						switch (v->type) {
 							case VEH_TRAIN: SetDParam(3, STR_ORDER_TRAIN_DEPOT); break;