diff --git a/lang/english.txt b/lang/english.txt index 203fb6519f..2fd2055b24 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -2939,6 +2939,8 @@ STR_MASS_STOP_DEPOT_TOOLTIP :{BLACK}Click to STR_MASS_START_DEPOT_TOOLTIP :{BLACK}Click to start all the vehicles inside the depot STR_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Click to stop all the aircraft inside the hangar STR_MASS_START_HANGAR_TOOLTIP :{BLACK}Click to start all the aircraft inside the hangar +STR_MASS_STOP_LIST_TIP :{BLACK}Click to stop all the vehicles in the list +STR_MASS_START_LIST_TIP :{BLACK}Click to start all the vehicles in the list STR_SHORT_DATE :{WHITE}{DATE_TINY} STR_SIGN_LIST_CAPTION :{WHITE}Sign List - {COMMA} Sign{P "" s} diff --git a/vehicle.c b/vehicle.c index b67e6cf7bf..15afae9232 100644 --- a/vehicle.c +++ b/vehicle.c @@ -1576,9 +1576,12 @@ void AgeVehicle(Vehicle *v) } /** Starts or stops a lot of vehicles - * @param tile Tile of the depot where the vehicles are started/stopped + * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots) * @param p1 Vehicle type - * @param p2 0 = start vehicles, 1 = stop vehicles + * @param p2 bitmask + * - bit 0 false = start vehicles, true = stop vehicles + * - bit 1 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case + * - bit 8-11 Vehicle List Window type (ignored unless bit 1 is set) */ int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { @@ -1590,6 +1593,7 @@ int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2 uint stop_command; byte vehicle_type = GB(p1, 0, 8); bool start_stop = HASBIT(p2, 0); + bool vehicle_list_window = HASBIT(p2, 1); switch (vehicle_type) { case VEH_Train: stop_command = CMD_START_STOP_TRAIN; break; @@ -1599,18 +1603,32 @@ int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2 default: return CMD_ERROR; } - /* Get the list of vehicles in the depot */ - BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL); + if (vehicle_list_window) { + uint16 window_type = p2 & VLW_MASK; + + vl = malloc(GetVehicleArraySize() * sizeof(vl[0])); + if (vl == NULL) { + error("Could not allocate memory for the vehicle-goto-depot-list"); + } + + engine_count = GenerateVehicleSortList((const Vehicle**)vl, vehicle_type, _current_player, INVALID_STATION, INVALID_ORDER, window_type); + } else { + /* Get the list of vehicles in the depot */ + BuildDepotVehicleList(vehicle_type, tile, &vl, &engine_list_length, &engine_count, NULL, NULL, NULL); + } for (i = 0; i < engine_count; i++) { const Vehicle *v = vl[i]; int32 ret; if (!!(v->vehstatus & VS_STOPPED) != start_stop) continue; - if (vehicle_type == VEH_Train) { - if (CheckTrainInDepot(v, false) == -1) continue; - } else { - if (!(v->vehstatus & VS_HIDDEN)) continue; + + if (!vehicle_list_window) { + if (vehicle_type == VEH_Train) { + if (CheckTrainInDepot(v, false) == -1) continue; + } else { + if (!(v->vehstatus & VS_HIDDEN)) continue; + } } ret = DoCommand(tile, v->index, 0, flags, stop_command); diff --git a/vehicle_gui.c b/vehicle_gui.c index c7a5ca6e7c..cd153df9d0 100644 --- a/vehicle_gui.c +++ b/vehicle_gui.c @@ -1224,6 +1224,8 @@ typedef enum VehicleListWindowWidgets { VLW_WIDGET_OTHER_PLAYER_FILLER, VLW_WIDGET_SEND_TO_DEPOT, VLW_WIDGET_AUTOREPLACE, + VLW_WIDGET_STOP_ALL, + VLW_WIDGET_START_ALL, VLW_WIDGET_RESIZE, } VehicleListWindowWidget; @@ -1240,6 +1242,8 @@ static const byte vehicle_list_widget_moves[] = { WIDGET_MOVE_DOWN_STRETCH_RIGHT, // VLW_WIDGET_OTHER_PLAYER_FILLER WIDGET_MOVE_DOWN, // VLW_WIDGET_SEND_TO_DEPOT WIDGET_MOVE_DOWN, // VLW_WIDGET_AUTOREPLACE + WIDGET_MOVE_DOWN_RIGHT, // VLW_WIDGET_STOP_ALL + WIDGET_MOVE_DOWN_RIGHT, // VLW_WIDGET_START_ALL WIDGET_MOVE_DOWN_RIGHT, // VLW_WIDGET_RESIZE }; @@ -1256,6 +1260,8 @@ static const Widget _vehicle_list_widgets[] = { { WWT_PANEL, RESIZE_RTB, 14, 0, 247, 170, 181, 0x0, STR_NULL}, { 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_PUSHIMGBTN, RESIZE_LRTB, 14, 224, 235, 170, 181, SPR_FLAG_VEH_STOPPED, STR_MASS_STOP_LIST_TIP}, + { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 236, 247, 170, 181, SPR_FLAG_VEH_RUNNING, STR_MASS_START_LIST_TIP}, { WWT_RESIZEBOX, RESIZE_LRTB, 14, 248, 259, 170, 181, 0x0, STR_RESIZE_BUTTON}, { WIDGETS_END}, }; @@ -1263,7 +1269,7 @@ static const Widget _vehicle_list_widgets[] = { /* Resize the bottom row of buttons to make them equal in size when resizing */ static void ResizeVehicleListWidgets(Window *w) { - w->widget[VLW_WIDGET_AUTOREPLACE].right = w->widget[VLW_WIDGET_RESIZE].left - 1; + w->widget[VLW_WIDGET_AUTOREPLACE].right = w->widget[VLW_WIDGET_STOP_ALL].left - 1; w->widget[VLW_WIDGET_SEND_TO_DEPOT].right = w->widget[VLW_WIDGET_AUTOREPLACE].right / 2; w->widget[VLW_WIDGET_AUTOREPLACE].left = w->widget[VLW_WIDGET_SEND_TO_DEPOT].right; } @@ -1284,6 +1290,8 @@ static void CreateVehicleListWindow(Window *w) } else { SETBIT(w->hidden_state, VLW_WIDGET_SEND_TO_DEPOT); SETBIT(w->hidden_state, VLW_WIDGET_AUTOREPLACE); + SETBIT(w->hidden_state, VLW_WIDGET_STOP_ALL); + SETBIT(w->hidden_state, VLW_WIDGET_START_ALL); } /* Set up the window widgets */ @@ -1376,8 +1384,8 @@ static void CreateVehicleListWindow(Window *w) * Aircraft and ships already got the right size widgets */ if (w->resize.step_height == PLY_WND_PRC__SIZE_OF_ROW_SMALL) { ResizeWindowWidgets(w, vehicle_list_widget_moves, lengthof(vehicle_list_widget_moves), vl->vehicle_type == VEH_Train ? 65 : 0, 38); - ResizeVehicleListWidgets(w); } + ResizeVehicleListWidgets(w); } static void DrawVehicleListWindow(Window *w) @@ -1548,15 +1556,20 @@ void PlayerVehWndProc(Window *w, WindowEvent *e) } } break; - case VLW_WIDGET_SEND_TO_DEPOT: // Left button + case VLW_WIDGET_SEND_TO_DEPOT: assert(vl->l.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_MASK) | DEPOT_MASS_SEND | (_ctrl_pressed ? DEPOT_SERVICE : 0), NULL, CMD_SEND_TO_DEPOT(vl->vehicle_type)); break; - case VLW_WIDGET_AUTOREPLACE: // Right button + case VLW_WIDGET_AUTOREPLACE: ShowReplaceVehicleWindow(vl->vehicle_type); break; + + case VLW_WIDGET_STOP_ALL: + case VLW_WIDGET_START_ALL: + DoCommandP(0, vl->vehicle_type, (w->window_number & VLW_MASK) | (1 << 1) | (e->we.click.widget == VLW_WIDGET_START_ALL ? 1 : 0), NULL, CMD_MASS_START_STOP); + break; } } break;