summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang/english.txt6
-rw-r--r--src/order_cmd.cpp80
-rw-r--r--src/order_gui.cpp67
-rw-r--r--src/order_type.h1
-rw-r--r--src/timetable_gui.cpp19
5 files changed, 137 insertions, 36 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index 48e306e54..1db6e49c5 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2685,12 +2685,18 @@ STR_ORDER_TOOLTIP_FULL_LOAD :{BLACK}Change t
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}
diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp
index a1c5f76f7..7682ba660 100644
--- a/src/order_cmd.cpp
+++ b/src/order_cmd.cpp
@@ -366,44 +366,48 @@ CommandCost CmdInsertOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
}
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;
+ 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());
+ const Depot *dp = GetDepot(new_order.GetDestination());
- if (!CheckOwnership(GetTileOwner(dp->xy))) 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;
+ 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_ROAD:
+ if (!IsTileDepotType(dp->xy, TRANSPORT_ROAD)) return CMD_ERROR;
+ break;
- case VEH_SHIP:
- if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
- break;
+ case VEH_SHIP:
+ if (!IsTileDepotType(dp->xy, TRANSPORT_WATER)) return CMD_ERROR;
+ break;
- default: return CMD_ERROR;
+ default: return CMD_ERROR;
+ }
}
+ } else {
+ 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 @@ bool ProcessOrders(Vehicle *v)
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:
diff --git a/src/order_gui.cpp b/src/order_gui.cpp
index 519457c2d..46ed659bd 100644
--- a/src/order_gui.cpp
+++ b/src/order_gui.cpp
@@ -41,6 +41,7 @@ enum OrderWindowWidgets {
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 @@ static const StringID _order_unload_drowdown[] = {
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 @@ static void DrawOrdersWindow(Window *w)
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 @@ static void OrderClick_Service(Window *w, const Vehicle *v, int i)
}
/**
+ * 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 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
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 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
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 @@ static const Widget _orders_train_widgets[] = {
{ 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 @@ static const Widget _orders_widgets[] = {
{ 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 @@ static const Widget _other_orders_widgets[] = {
{ 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
diff --git a/src/order_type.h b/src/order_type.h
index b2d3ac67e..a6273e684 100644
--- a/src/order_type.h
+++ b/src/order_type.h
@@ -82,6 +82,7 @@ enum OrderDepotTypeFlags {
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.
};
/**
diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp
index 78de82f6d..372897841 100644
--- a/src/timetable_gui.cpp
+++ b/src/timetable_gui.cpp
@@ -135,11 +135,22 @@ static void DrawTimetableWindow(Window *w)
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;