From cebe2001ba37fc7fb246404329063d324125faa7 Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 11 Apr 2008 15:58:46 +0000 Subject: [PATCH] (svn r12661) -Add: ability to send a vehicle (using default orders) to the nearest depot. --- src/lang/english.txt | 6 +++ src/order_cmd.cpp | 90 ++++++++++++++++++++++++++++--------------- src/order_gui.cpp | 67 +++++++++++++++++++++++++++++--- src/order_type.h | 1 + src/timetable_gui.cpp | 19 +++++++-- 5 files changed, 142 insertions(+), 41 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 48e306e54a..1db6e49c50 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 a1c5f76f77..7682ba6607 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; + 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(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 @@ 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 519457c2d2..46ed659bd7 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; @@ -475,6 +499,23 @@ static void OrderClick_Service(Window *w, const Vehicle *v, int i) DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), MOF_DEPOT_ACTION, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER)); } +/** + * 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. * @@ -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 b2d3ac67e0..a6273e6849 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 78de82f6d1..372897841e 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;