From 2579b68e34648c2e6ad27af133def17580c6334f Mon Sep 17 00:00:00 2001 From: bjarni Date: Wed, 27 Sep 2006 22:44:39 +0000 Subject: [PATCH] (svn r6542) -Feature: [depot window] added a "sell all vehicles in depot" button It's right below the sell button (sell whole chain button for trains) It's still missing a sprite. That one will be added as soon as anybody draws something we can use To make room for this button, all depots except train depots now opens with an additional row and can't be resized shorter than that --- command.c | 2 + command.h | 1 + depot_gui.c | 136 +++++++++++++++++++++++++++++++++++++---------- lang/english.txt | 10 ++++ openttd.h | 1 + vehicle.c | 52 ++++++++++++++++++ 6 files changed, 173 insertions(+), 29 deletions(-) diff --git a/command.c b/command.c index f1f3c821c8..fc6ef7329e 100644 --- a/command.c +++ b/command.c @@ -160,6 +160,7 @@ DEF_COMMAND(CmdReplaceVehicle); DEF_COMMAND(CmdCloneVehicle); DEF_COMMAND(CmdMassStartStopVehicle); +DEF_COMMAND(CmdDepotSellAllVehicles); /* The master command table */ @@ -305,6 +306,7 @@ static const Command _command_proc_table[] = { {CmdReplaceVehicle, 0}, /* 115 */ {CmdCloneVehicle, 0}, /* 116 */ {CmdMassStartStopVehicle, 0}, /* 117 */ + {CmdDepotSellAllVehicles, 0}, /* 118 */ }; /* This function range-checks a cmd, and checks if the cmd is not NULL */ diff --git a/command.h b/command.h index b1d6a70d71..35eced22b9 100644 --- a/command.h +++ b/command.h @@ -137,6 +137,7 @@ enum { CMD_CLONE_VEHICLE = 116, CMD_MASS_START_STOP = 117, + CMD_DEPOT_SELL_ALL_VEHICLES = 118, }; diff --git a/depot_gui.c b/depot_gui.c index 8e279866bf..609c7b1819 100644 --- a/depot_gui.c +++ b/depot_gui.c @@ -50,6 +50,7 @@ typedef enum DepotWindowWidgets { DEPOT_WIDGET_STOP_ALL, DEPOT_WIDGET_START_ALL, DEPOT_WIDGET_SELL, + DEPOT_WIDGET_SELL_CHAIN, DEPOT_WIDGET_SELL_ALL, DEPOT_WIDGET_MATRIX, DEPOT_WIDGET_V_SCROLL, // Vertical scrollbar @@ -69,7 +70,8 @@ static const byte widget_moves[] = { DEPOT_MOVE_RIGHT, // DEPOT_WIDGET_STOP_ALL DEPOT_MOVE_RIGHT, // DEPOT_WIDGET_START_ALL DEPOT_MOVE_RIGHT, // DEPOT_WIDGET_SELL - DEPOT_MOVE_NONE, // DEPOT_WIDGET_SELL_ALL + DEPOT_MOVE_NONE, // DEPOT_WIDGET_SELL_CHAIN + DEPOT_MOVE_DOWN_RIGHT, // DEPOT_WIDGET_SELL_ALL DEPOT_STRETCH_DOWN_RIGHT, // DEPOT_WIDGET_MATRIX DEPOT_MOVE_RIGHT_STRETCH_DOWN, // DEPOT_WIDGET_V_SCROLL DEPOT_MOVE_NONE, // DEPOT_WIDGET_H_SCROLL @@ -96,20 +98,21 @@ static const Widget _depot_widgets[] = { { WWT_PUSHIMGBTN, RESIZE_LR, 14, 270, 280, 14, 25, SPR_FLAG_VEH_STOPPED,STR_MASS_STOP_DEPOT_TOOLTIP}, // DEPOT_WIDGET_STOP_ALL { WWT_PUSHIMGBTN, RESIZE_LR, 14, 281, 292, 14, 25, SPR_FLAG_VEH_RUNNING,STR_MASS_START_DEPOT_TOOLTIP}, // DEPOT_WIDGET_START_ALL - { WWT_IMGBTN, RESIZE_LRB, 14, 270, 292, 26, 61, 0x2A9, STR_NULL}, // DEPOT_WIDGET_SELL - { WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 0, 0, 0x2BF, STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP}, // DEPOT_WIDGET_SELL_ALL, trains only + { WWT_IMGBTN, RESIZE_LRB, 14, 270, 292, 26, 60, 0x2A9, STR_NULL}, // DEPOT_WIDGET_SELL + { WWT_PANEL, RESIZE_LRTB, 14, 326, 348, 0, 0, 0x2BF, STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP}, // DEPOT_WIDGET_SELL_CHAIN, trains only + { WWT_PUSHIMGBTN, RESIZE_LRTB, 14, 270, 292, 61, 83, 0x0, STR_DEPOT_SELL_ALL_BUTTON_TIP}, // DEPOT_WIDGET_SELL_ALL - { WWT_MATRIX, RESIZE_RB, 14, 0, 269, 14, 61, 0x0, STR_NULL}, // DEPOT_WIDGET_MATRIX - { WWT_SCROLLBAR, RESIZE_LRB, 14, 293, 304, 14, 61, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, // DEPOT_WIDGET_V_SCROLL + { WWT_MATRIX, RESIZE_RB, 14, 0, 269, 14, 83, 0x0, STR_NULL}, // DEPOT_WIDGET_MATRIX + { WWT_SCROLLBAR, RESIZE_LRB, 14, 293, 304, 14, 83, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, // DEPOT_WIDGET_V_SCROLL { WWT_HSCROLLBAR, RESIZE_RTB, 14, 0, 325, 98, 109, 0x0, STR_HSCROLL_BAR_SCROLLS_LIST}, // DEPOT_WIDGET_H_SCROLL, trains only /* The buttons in the bottom of the window. left and right is not important as they are later resized to be equal in size * This calculation is based on right in DEPOT_WIDGET_LOCATION and it presumes left of DEPOT_WIDGET_BUILD is 0 */ - { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 96, 62, 73, 0x0, STR_NULL}, // DEPOT_WIDGET_BUILD - {WWT_NODISTXTBTN, RESIZE_TB, 14, 97, 194, 62, 73, 0x0, STR_NULL}, // DEPOT_WIDGET_CLONE - { WWT_PUSHTXTBTN, RESIZE_TB, 14, 195, 292, 62, 73, STR_00E4_LOCATION, STR_NULL}, // DEPOT_WIDGET_LOCATION - { WWT_RESIZEBOX, RESIZE_LRTB, 14, 293, 304, 62, 73, 0x0, STR_RESIZE_BUTTON}, // DEPOT_WIDGET_RESIZE + { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 96, 84, 95, 0x0, STR_NULL}, // DEPOT_WIDGET_BUILD + {WWT_NODISTXTBTN, RESIZE_TB, 14, 97, 194, 84, 95, 0x0, STR_NULL}, // DEPOT_WIDGET_CLONE + { WWT_PUSHTXTBTN, RESIZE_TB, 14, 195, 292, 84, 95, STR_00E4_LOCATION, STR_NULL}, // DEPOT_WIDGET_LOCATION + { WWT_RESIZEBOX, RESIZE_LRTB, 14, 293, 304, 84, 95, 0x0, STR_RESIZE_BUTTON}, // DEPOT_WIDGET_RESIZE { WIDGETS_END}, }; @@ -124,7 +127,7 @@ static const WindowDesc _train_depot_desc = { }; static const WindowDesc _road_depot_desc = { - -1, -1, 315, 68, + -1, -1, 315, 82, WC_VEHICLE_DEPOT,0, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, _depot_widgets, @@ -132,7 +135,7 @@ static const WindowDesc _road_depot_desc = { }; static const WindowDesc _ship_depot_desc = { - -1, -1, 305, 74, + -1, -1, 305, 96, WC_VEHICLE_DEPOT,0, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, _depot_widgets, @@ -140,7 +143,7 @@ static const WindowDesc _ship_depot_desc = { }; static const WindowDesc _aircraft_depot_desc = { - -1, -1, 331, 74, + -1, -1, 331, 96, WC_VEHICLE_DEPOT,0, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE, _depot_widgets, @@ -171,6 +174,75 @@ static inline void ShowVehicleViewWindow(const Vehicle *v) } } +static void DepotSellAllWndProc(Window *w, WindowEvent *e) +{ + switch (e->event) { + case WE_PAINT: + if (WP(w, depot_d).type == VEH_Aircraft) { + SetDParam(0, GetStationIndex(w->window_number)); // Airport name + } else { + Depot *depot = GetDepotByTile(w->window_number); + assert(depot != NULL); + + SetDParam(0, depot->town_index); + } + DrawWindowWidgets(w); + + DrawStringCentered(150, 25, STR_DEPOT_SELL_ALL_VEHICLE_CONFIRM, 0); + DrawStringCentered(150, 38, STR_ARE_YOU_SURE, 0); + break; + + case WE_CLICK: + switch (e->we.click.widget) { + case 4: + DoCommandP(w->window_number, WP(w, depot_d).type, 0, NULL, CMD_DEPOT_SELL_ALL_VEHICLES); + /* Fallthought */ + case 3: + DeleteWindow(w); + break; + } + break; + } +} + +static const Widget _depot_sell_all_widgets[] = { + { WWT_CLOSEBOX, RESIZE_NONE, 5, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, + { WWT_CAPTION, RESIZE_NONE, 5, 11, 299, 0, 13, 0x0, STR_018C_WINDOW_TITLE_DRAG_THIS}, + { WWT_PANEL, RESIZE_NONE, 5, 0, 299, 14, 71, 0x0, STR_NULL}, + { WWT_PUSHTXTBTN, RESIZE_NONE, 5, 85, 144, 52, 63, STR_012E_CANCEL, STR_DEPOT_SELL_ALL_CANCEL_TIP}, + { WWT_PUSHTXTBTN, RESIZE_NONE, 4, 155, 214, 52, 63, STR_SELL, STR_DEPOT_SELL_ALL_TIP}, + { WIDGETS_END}, +}; + +static const WindowDesc _depot_sell_all_desc = { + WDP_CENTER, WDP_CENTER, 300, 72, + WC_DEPOT_SELL_ALL,0, + WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, + _depot_sell_all_widgets, + DepotSellAllWndProc +}; + +static void ShowDepotSellAllWindow(TileIndex tile, byte type) +{ + Window *w; + + w = AllocateWindowDescFront(&_depot_sell_all_desc, tile); + + if (w != NULL) { + WP(w, depot_d).type = type; + switch (type) { + case VEH_Train: w->widget[1].data = STR_8800_TRAIN_DEPOT; break; + case VEH_Road: w->widget[1].data = STR_9003_ROAD_VEHICLE_DEPOT; break; + case VEH_Ship: w->widget[1].data = STR_9803_SHIP_DEPOT; break; + case VEH_Aircraft: + w->widget[1].data = STR_A002_AIRCRAFT_HANGAR; + w->widget[3].tooltips = STR_DEPOT_SELL_ALL_CANCEL_HANGAR_TIP; + w->widget[4].tooltips = STR_DEPOT_SELL_ALL_HANGAR_TIP; + break; + } + } +} + static void DrawDepotWindow(Window *w) { Vehicle **vl = WP(w, depot_d).vehicle_list; @@ -183,7 +255,8 @@ static void DrawDepotWindow(Window *w) /* setup disabled buttons */ w->disabled_state = IsTileOwner(tile, _local_player) ? 0 : ( (1 << DEPOT_WIDGET_STOP_ALL) | (1 << DEPOT_WIDGET_START_ALL) | - (1 << DEPOT_WIDGET_SELL) | (1 << DEPOT_WIDGET_SELL_ALL) | (1 << DEPOT_WIDGET_BUILD) | (1 << DEPOT_WIDGET_CLONE)); + (1 << DEPOT_WIDGET_SELL) | (1 << DEPOT_WIDGET_SELL_CHAIN) | (1 << DEPOT_WIDGET_SELL_ALL) | + (1 << DEPOT_WIDGET_BUILD) | (1 << DEPOT_WIDGET_CLONE)); /* determine amount of items for scroller */ if (WP(w, depot_d).type == VEH_Train) { @@ -512,11 +585,11 @@ static void ResizeDepotButtons(Window *w) w->widget[DEPOT_WIDGET_CLONE].right = w->widget[DEPOT_WIDGET_LOCATION].left - 1; if (WP(w, depot_d).type == VEH_Train) { - /* Divide the size of DEPOT_WIDGET_SELL into two equally big buttons so DEPOT_WIDGET_SELL and DEPOT_WIDGET_SELL_ALL will get the same size. - * This way it will stay the same even if DEPOT_WIDGET_SELL_ALL is resized for some reason */ - w->widget[DEPOT_WIDGET_SELL_ALL].bottom = w->widget[DEPOT_WIDGET_RESIZE].top - 1; - w->widget[DEPOT_WIDGET_SELL_ALL].top = ((w->widget[DEPOT_WIDGET_SELL_ALL].bottom - w->widget[DEPOT_WIDGET_SELL].top) / 2) + w->widget[DEPOT_WIDGET_SELL].top; - w->widget[DEPOT_WIDGET_SELL].bottom = w->widget[DEPOT_WIDGET_SELL_ALL].top - 1; + /* Divide the size of DEPOT_WIDGET_SELL into two equally big buttons so DEPOT_WIDGET_SELL and DEPOT_WIDGET_SELL_CHAIN will get the same size. + * This way it will stay the same even if DEPOT_WIDGET_SELL_CHAIN is resized for some reason */ + w->widget[DEPOT_WIDGET_SELL_CHAIN].bottom = w->widget[DEPOT_WIDGET_SELL_ALL].top - 1; + w->widget[DEPOT_WIDGET_SELL_CHAIN].top = ((w->widget[DEPOT_WIDGET_SELL_CHAIN].bottom - w->widget[DEPOT_WIDGET_SELL].top) / 2) + w->widget[DEPOT_WIDGET_SELL].top; + w->widget[DEPOT_WIDGET_SELL].bottom = w->widget[DEPOT_WIDGET_SELL_CHAIN].top - 1; } } @@ -575,6 +648,10 @@ static void DepotWndProc(Window *w, WindowEvent *e) DoCommandP(w->window_number, WP(w, depot_d).type, e->we.click.widget == DEPOT_WIDGET_START_ALL ? 1 : 0, NULL, CMD_MASS_START_STOP); break; + case DEPOT_WIDGET_SELL_ALL: + ShowDepotSellAllWindow(w->window_number, WP(w, depot_d).type); + break; + } break; @@ -633,7 +710,7 @@ static void DepotWndProc(Window *w, WindowEvent *e) } } break; - case DEPOT_WIDGET_SELL: case DEPOT_WIDGET_SELL_ALL: + case DEPOT_WIDGET_SELL: case DEPOT_WIDGET_SELL_CHAIN: if (!HASBIT(w->disabled_state, DEPOT_WIDGET_SELL) && WP(w, depot_d).sel != INVALID_VEHICLE) { Vehicle *v; @@ -650,7 +727,7 @@ static void DepotWndProc(Window *w, WindowEvent *e) WP(w, depot_d).sel = INVALID_VEHICLE; SetWindowDirty(w); - sell_cmd = (v->type == VEH_Train && (e->we.click.widget == DEPOT_WIDGET_SELL_ALL || _ctrl_pressed)) ? 1 : 0; + sell_cmd = (v->type == VEH_Train && (e->we.click.widget == DEPOT_WIDGET_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; is_engine = (!(v->type == VEH_Train && !IsFrontEngine(v))); @@ -734,6 +811,7 @@ static void SetupStringsForDepotWindow(Window *w, byte type) /* Special strings only for hangars (using hangar instead of depot and so on) */ w->widget[DEPOT_WIDGET_STOP_ALL].tooltips = STR_MASS_STOP_HANGAR_TOOLTIP; w->widget[DEPOT_WIDGET_START_ALL].tooltips= STR_MASS_START_HANGAR_TOOLTIP; + w->widget[DEPOT_WIDGET_SELL_ALL].tooltips = STR_DEPOT_SELL_ALL_BUTTON_HANGAR_TIP; break; } } @@ -769,7 +847,7 @@ void ShowDepotWindow(TileIndex tile, byte type) switch (type) { case VEH_Train: horizontal = 56; - vertical = 48; + vertical = 26; w->vscroll.cap = 6; w->hscroll.cap = 10 * 29; w->resize.step_width = 1; @@ -778,15 +856,15 @@ void ShowDepotWindow(TileIndex tile, byte type) case VEH_Road: horizontal = 10; - vertical = -6; - w->vscroll.cap = 3; + vertical = - 14; + w->vscroll.cap = 4; w->hscroll.cap = 5; w->resize.step_width = 56; w->resize.step_height = 14; break; case VEH_Ship: - w->vscroll.cap = 2; + w->vscroll.cap = 3; w->hscroll.cap = 3; w->resize.step_width = 90; w->resize.step_height = 24; @@ -794,7 +872,7 @@ void ShowDepotWindow(TileIndex tile, byte type) case VEH_Aircraft: horizontal = 26; - w->vscroll.cap = 2; + w->vscroll.cap = 3; w->hscroll.cap = 4; w->resize.step_width = 74; w->resize.step_height = 24; @@ -811,7 +889,7 @@ void ShowDepotWindow(TileIndex tile, byte type) if (type != VEH_Train) { SETBIT(w->hidden_state, DEPOT_WIDGET_H_SCROLL); - SETBIT(w->hidden_state, DEPOT_WIDGET_SELL_ALL); + SETBIT(w->hidden_state, DEPOT_WIDGET_SELL_CHAIN); } /* Move the widgets to their right locations @@ -838,9 +916,9 @@ void ShowDepotWindow(TileIndex tile, byte type) w->widget[DEPOT_WIDGET_H_SCROLL].top = w->widget[DEPOT_WIDGET_MATRIX].bottom - 11; w->widget[DEPOT_WIDGET_MATRIX].bottom -= 12; - /* DEPOT_WIDGET_SELL_ALL is under DEPOT_WIDGET_SELL. They got the same left and right and height is controlled in ResizeDepotButtons() */ - w->widget[DEPOT_WIDGET_SELL_ALL].left = w->widget[DEPOT_WIDGET_SELL].left; - w->widget[DEPOT_WIDGET_SELL_ALL].right = w->widget[DEPOT_WIDGET_SELL].right; + /* DEPOT_WIDGET_SELL_CHAIN is under DEPOT_WIDGET_SELL. They got the same left and right and height is controlled in ResizeDepotButtons() */ + w->widget[DEPOT_WIDGET_SELL_CHAIN].left = w->widget[DEPOT_WIDGET_SELL].left; + w->widget[DEPOT_WIDGET_SELL_CHAIN].right = w->widget[DEPOT_WIDGET_SELL].right; } ResizeDepotButtons(w); } diff --git a/lang/english.txt b/lang/english.txt index b6dac79633..32816303b1 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -2901,6 +2901,16 @@ STR_SEND_TO_DEPOTS_TIP :{BLACK}Send al STR_SEND_TO_HANGARS :{BLACK}Send to Hangars STR_SEND_TO_HANGARS_TIP :{BLACK}Send all aircraft in list to hangar. CTRL+click will only service +STR_SELL :{BLACK}Sell +STR_DEPOT_SELL_ALL_VEHICLE_CONFIRM :{BLACK}You are about to sell all the vehicles in the depot. +STR_ARE_YOU_SURE :{BLACK}Are you sure? +STR_DEPOT_SELL_ALL_TIP :{BLACK}Confirm that you want to sell all the vehicles in the depot +STR_DEPOT_SELL_ALL_HANGAR_TIP :{BLACK}Confirm that you want to sell all the aircraft in the hangar +STR_DEPOT_SELL_ALL_CANCEL_TIP :{BLACK}Do not sell all vehicles in the depot +STR_DEPOT_SELL_ALL_CANCEL_HANGAR_TIP :{BLACK}Do not sell all aircraft in the hangar +STR_DEPOT_SELL_ALL_BUTTON_TIP :{BLACK}Sell all vehicles in the depot +STR_DEPOT_SELL_ALL_BUTTON_HANGAR_TIP :{BLACK}Sell all aircraft in the hangar + STR_REPLACE_VEHICLES :{BLACK}Replace Vehicles STR_REPLACE_VEHICLES_WHITE :{WHITE}Replace {STRING} STR_REPLACE_VEHICLES_START :{BLACK}Start Replacing Vehicles diff --git a/openttd.h b/openttd.h index 70c4cd4463..f50bbd4a7b 100644 --- a/openttd.h +++ b/openttd.h @@ -439,6 +439,7 @@ enum { WC_GENERATE_LANDSCAPE = 0x50, WC_GENERATE_PROGRESS_WINDOW = 0x51, WC_OK_CANCEL_QUERY = 0x52, + WC_DEPOT_SELL_ALL = 0x53, }; diff --git a/vehicle.c b/vehicle.c index 760ff64f23..638fdec7a6 100644 --- a/vehicle.c +++ b/vehicle.c @@ -1626,6 +1626,58 @@ int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2 return return_value; } +/** Sells all vehicles in a depot +* @param tile Tile of the depot where the depot is +* @param p1 Vehicle type +* @param p2 unused +*/ +int32 CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) +{ + Vehicle **engines = NULL; + Vehicle **wagons = NULL; + uint16 engine_list_length = 0; + uint16 engine_count = 0; + uint16 wagon_list_length = 0; + uint16 wagon_count = 0; + + int32 cost = 0; + uint i, sell_command, total_number_vehicles; + byte vehicle_type = GB(p1, 0, 8); + + switch (vehicle_type) { + case VEH_Train: sell_command = CMD_SELL_RAIL_WAGON; break; + case VEH_Road: sell_command = CMD_SELL_ROAD_VEH; break; + case VEH_Ship: sell_command = CMD_SELL_SHIP; break; + case VEH_Aircraft: sell_command = CMD_SELL_AIRCRAFT; break; + default: return CMD_ERROR; + } + + /* Get the list of vehicles in the depot */ + BuildDepotVehicleList(vehicle_type, tile, &engines, &engine_list_length, &engine_count, + &wagons, &wagon_list_length, &wagon_count); + + total_number_vehicles = engine_count + wagon_count; + for (i = 0; i < total_number_vehicles; i++) { + const Vehicle *v; + int32 ret; + + if (i < engine_count) { + v = engines[i]; + } else { + v = wagons[i - engine_count]; + } + + ret = DoCommand(tile, v->index, 1, flags, sell_command); + + if (!CmdFailed(ret)) cost += ret; + } + + free(engines); + free(wagons); + if (cost == 0) return CMD_ERROR; // no vehicles to sell + return cost; +} + /** Clone a vehicle. If it is a train, it will clone all the cars too * @param tile tile of the depot where the cloned vehicle is build * @param p1 the original vehicle's index