(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
This commit is contained in:
bjarni 2006-09-27 22:44:39 +00:00
parent 64fa9a54e0
commit 2579b68e34
6 changed files with 173 additions and 29 deletions

View File

@ -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 */

View File

@ -137,6 +137,7 @@ enum {
CMD_CLONE_VEHICLE = 116,
CMD_MASS_START_STOP = 117,
CMD_DEPOT_SELL_ALL_VEHICLES = 118,
};

View File

@ -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);
}

View File

@ -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

View File

@ -439,6 +439,7 @@ enum {
WC_GENERATE_LANDSCAPE = 0x50,
WC_GENERATE_PROGRESS_WINDOW = 0x51,
WC_OK_CANCEL_QUERY = 0x52,
WC_DEPOT_SELL_ALL = 0x53,
};

View File

@ -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