2006-09-26 17:47:51 +01:00
/* $Id$ */
2008-05-06 16:11:33 +01:00
/** @file depot_gui.cpp The GUI for depots. */
2007-02-23 18:55:07 +00:00
2006-09-27 16:47:00 +01:00
# include "train.h"
2006-09-26 17:47:51 +01:00
# include "ship.h"
2006-09-27 16:40:55 +01:00
# include "aircraft.h"
2006-09-26 17:47:51 +01:00
# include "gui.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2008-01-09 09:45:45 +00:00
# include "viewport_func.h"
# include "gfx_func.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2008-04-17 20:10:30 +01:00
# include "depot_base.h"
2006-09-26 17:47:51 +01:00
# include "vehicle_gui.h"
# include "newgrf_engine.h"
2007-02-10 13:37:32 +00:00
# include "spritecache.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-25 11:26:07 +00:00
# include "window_func.h"
2007-12-27 13:35:39 +00:00
# include "vehicle_func.h"
2008-09-30 21:51:04 +01:00
# include "company_func.h"
2008-05-07 14:10:15 +01:00
# include "tilehighlight_func.h"
2008-05-17 14:01:30 +01:00
# include "window_gui.h"
2008-05-28 12:56:21 +01:00
# include "vehiclelist.h"
2006-09-27 14:01:56 +01:00
2008-01-13 01:21:35 +00:00
# include "table/strings.h"
# include "table/sprites.h"
2006-09-27 14:01:56 +01:00
/*
* Since all depot window sizes aren ' t the same , we need to modify sizes a little .
* It ' s done with the following arrays of widget indexes . Each of them tells if a widget side should be moved and in what direction .
* How long they should be moved and for what window types are controlled in ShowDepotWindow ( )
*/
2006-09-27 12:34:27 +01:00
/* Names of the widgets. Keep them in the same order as in the widget array */
2006-12-07 00:51:20 +00:00
enum DepotWindowWidgets {
2006-09-27 12:34:27 +01:00
DEPOT_WIDGET_CLOSEBOX = 0 ,
DEPOT_WIDGET_CAPTION ,
DEPOT_WIDGET_STICKY ,
DEPOT_WIDGET_SELL ,
2006-09-27 23:44:39 +01:00
DEPOT_WIDGET_SELL_CHAIN ,
2006-09-27 12:34:27 +01:00
DEPOT_WIDGET_SELL_ALL ,
2006-10-01 17:02:29 +01:00
DEPOT_WIDGET_AUTOREPLACE ,
2006-09-27 12:34:27 +01:00
DEPOT_WIDGET_MATRIX ,
2007-02-23 18:55:07 +00:00
DEPOT_WIDGET_V_SCROLL , ///< Vertical scrollbar
DEPOT_WIDGET_H_SCROLL , ///< Horizontal scrollbar
2006-09-27 12:34:27 +01:00
DEPOT_WIDGET_BUILD ,
DEPOT_WIDGET_CLONE ,
DEPOT_WIDGET_LOCATION ,
2006-09-30 14:39:34 +01:00
DEPOT_WIDGET_VEHICLE_LIST ,
2006-10-01 17:02:29 +01:00
DEPOT_WIDGET_STOP_ALL ,
DEPOT_WIDGET_START_ALL ,
2006-09-27 12:34:27 +01:00
DEPOT_WIDGET_RESIZE ,
2006-09-27 14:01:56 +01:00
} ;
2006-09-26 17:47:51 +01:00
/* Widget array for all depot windows.
* If a widget is needed in some windows only ( like train specific ) , add it for all windows
2006-10-02 01:28:31 +01:00
* and use HideWindowWidget in ShowDepotWindow ( ) to remove it in the windows where it should not be
2006-09-26 17:47:51 +01:00
* Keep the widget numbers in sync with the enum or really bad stuff will happen ! ! ! */
2006-09-27 14:01:56 +01:00
/* When adding widgets, place them as you would place them for the ship depot and define how you want it to move in widget_moves[]
2006-09-27 14:53:59 +01:00
* If you want a widget for one window only , set it to be hidden in ShowDepotWindow ( ) for the windows where you don ' t want it
* NOTE : the train only widgets are moved / resized in ShowDepotWindow ( ) so they follow certain other widgets if they are moved to ensure that they stick together .
* Changing the size of those here will not have an effect at all . It should be done in ShowDepotWindow ( )
*/
2007-02-10 13:37:32 +00:00
/*
* Some of the widgets are placed outside the window ( negative coordinates ) .
* The reason is that they are placed relatively to the matrix and the matrix is just one pixel ( in 0 , 14 ) .
* The matrix and the rest of the window will be resized when the size of the boxes is set and then all the widgets will be inside the window .
*/
2006-09-26 17:47:51 +01:00
static const Widget _depot_widgets [ ] = {
2009-04-22 00:40:56 +01:00
{ WWT_CLOSEBOX , RESIZE_NONE , COLOUR_GREY , 0 , 10 , 0 , 13 , STR_BLACK_CROSS , STR_TOOLTIP_CLOSE_WINDOW } , // DEPOT_WIDGET_CLOSEBOX
{ WWT_CAPTION , RESIZE_RIGHT , COLOUR_GREY , 11 , 23 , 0 , 13 , 0x0 , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS } , // DEPOT_WIDGET_CAPTION
{ WWT_STICKYBOX , RESIZE_LR , COLOUR_GREY , 24 , 35 , 0 , 13 , 0x0 , STR_STICKY_BUTTON } , // DEPOT_WIDGET_STICKY
2006-09-26 20:20:35 +01:00
2006-10-24 15:15:17 +01:00
/* Widgets are set up run-time */
2008-07-31 03:36:01 +01:00
{ WWT_IMGBTN , RESIZE_LRB , COLOUR_GREY , 1 , 23 , 14 , - 32 , 0x0 , STR_NULL } , // DEPOT_WIDGET_SELL
{ WWT_IMGBTN , RESIZE_LRTB , COLOUR_GREY , 1 , 23 , - 55 , - 32 , SPR_SELL_CHAIN_TRAIN , STR_DRAG_WHOLE_TRAIN_TO_SELL_TIP } , // DEPOT_WIDGET_SELL_CHAIN, trains only
{ WWT_PUSHIMGBTN , RESIZE_LRTB , COLOUR_GREY , 1 , 23 , - 31 , - 9 , 0x0 , STR_NULL } , // DEPOT_WIDGET_SELL_ALL
{ WWT_PUSHIMGBTN , RESIZE_LRTB , COLOUR_GREY , 1 , 23 , - 8 , 14 , 0x0 , STR_NULL } , // DEPOT_WIDGET_AUTOREPLACE
2006-09-26 17:47:51 +01:00
2008-07-31 03:36:01 +01:00
{ WWT_MATRIX , RESIZE_RB , COLOUR_GREY , 0 , 0 , 14 , 14 , 0x0 , STR_NULL } , // DEPOT_WIDGET_MATRIX
2009-04-22 00:40:56 +01:00
{ WWT_SCROLLBAR , RESIZE_LRB , COLOUR_GREY , 24 , 35 , 14 , 14 , 0x0 , STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST } , // DEPOT_WIDGET_V_SCROLL
2006-09-26 17:47:51 +01:00
2009-04-22 00:40:56 +01:00
{ WWT_HSCROLLBAR , RESIZE_RTB , COLOUR_GREY , 0 , 0 , 3 , 14 , 0x0 , STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST } , // DEPOT_WIDGET_H_SCROLL, trains only
2006-09-26 17:47:51 +01:00
/* 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 */
2008-07-31 03:36:01 +01:00
{ WWT_PUSHTXTBTN , RESIZE_TB , COLOUR_GREY , 0 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_BUILD
{ WWT_TEXTBTN , RESIZE_TB , COLOUR_GREY , 0 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_CLONE
2009-04-22 00:40:56 +01:00
{ WWT_PUSHTXTBTN , RESIZE_RTB , COLOUR_GREY , 0 , - 12 , 15 , 26 , STR_BUTTON_LOCATION , STR_NULL } , // DEPOT_WIDGET_LOCATION
2008-07-31 03:36:01 +01:00
{ WWT_PUSHTXTBTN , RESIZE_LRTB , COLOUR_GREY , - 11 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_VEHICLE_LIST
{ WWT_PUSHIMGBTN , RESIZE_LRTB , COLOUR_GREY , 1 , 11 , 15 , 26 , SPR_FLAG_VEH_STOPPED , STR_NULL } , // DEPOT_WIDGET_STOP_ALL
{ WWT_PUSHIMGBTN , RESIZE_LRTB , COLOUR_GREY , 12 , 23 , 15 , 26 , SPR_FLAG_VEH_RUNNING , STR_NULL } , // DEPOT_WIDGET_START_ALL
{ WWT_RESIZEBOX , RESIZE_LRTB , COLOUR_GREY , 24 , 35 , 15 , 26 , 0x0 , STR_RESIZE_BUTTON } , // DEPOT_WIDGET_RESIZE
2006-09-26 17:47:51 +01:00
{ WIDGETS_END } ,
} ;
2008-05-11 19:17:56 +01:00
2009-03-15 15:12:06 +00:00
static const WindowDesc _train_depot_desc (
2008-12-28 20:53:19 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 , 362 , 123 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 17:47:51 +01:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
2009-03-15 15:12:06 +00:00
_depot_widgets
) ;
2006-09-26 17:47:51 +01:00
2009-03-15 15:12:06 +00:00
static const WindowDesc _road_depot_desc (
2008-12-28 20:53:19 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 , 316 , 97 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 17:47:51 +01:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
2009-03-15 15:12:06 +00:00
_depot_widgets
) ;
2006-09-26 17:47:51 +01:00
2009-03-15 15:12:06 +00:00
static const WindowDesc _ship_depot_desc (
2008-12-28 20:53:19 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 , 306 , 99 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 17:47:51 +01:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
2009-03-15 15:12:06 +00:00
_depot_widgets
) ;
2006-09-26 17:47:51 +01:00
2009-03-15 15:12:06 +00:00
static const WindowDesc _aircraft_depot_desc (
2008-12-28 20:53:19 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 , 332 , 99 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 17:47:51 +01:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
2009-03-15 15:12:06 +00:00
_depot_widgets
) ;
2006-09-26 17:47:51 +01:00
extern int WagonLengthToPixels ( int len ) ;
2008-05-25 18:22:49 +01:00
extern void DepotSortList ( VehicleList * list ) ;
2006-09-26 17:47:51 +01:00
2007-08-26 22:21:59 +01:00
/**
* This is the Callback method after the cloning attempt of a vehicle
* @ param success indicates completion ( or not ) of the operation
* @ param tile unused
* @ param p1 unused
* @ param p2 unused
*/
2006-09-26 17:47:51 +01:00
void CcCloneVehicle ( bool success , TileIndex tile , uint32 p1 , uint32 p2 )
{
if ( ! success ) return ;
2007-08-26 22:21:59 +01:00
2009-05-17 00:34:14 +01:00
const Vehicle * v = Vehicle : : Get ( _new_vehicle_id ) ;
2007-08-26 22:21:59 +01:00
2007-08-29 21:50:58 +01:00
ShowVehicleViewWindow ( v ) ;
2006-09-26 17:47:51 +01:00
}
2008-05-25 10:40:44 +01:00
static void TrainDepotMoveVehicle ( const Vehicle * wagon , VehicleID sel , const Vehicle * head )
2006-09-26 17:47:51 +01:00
{
2009-05-17 00:34:14 +01:00
const Vehicle * v = Vehicle : : Get ( sel ) ;
2006-09-26 17:47:51 +01:00
if ( v = = wagon ) return ;
if ( wagon = = NULL ) {
if ( head ! = NULL ) wagon = GetLastVehicleInChain ( head ) ;
} else {
2007-08-30 22:11:12 +01:00
wagon = wagon - > Previous ( ) ;
2006-09-26 17:47:51 +01:00
if ( wagon = = NULL ) return ;
}
if ( wagon = = v ) return ;
2009-04-22 00:40:56 +01:00
DoCommandP ( v - > tile , v - > index + ( ( wagon = = NULL ? INVALID_VEHICLE : wagon - > index ) < < 16 ) , _ctrl_pressed ? 1 : 0 , CMD_MOVE_RAIL_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_MOVE_VEHICLE ) ) ;
2006-09-26 17:47:51 +01:00
}
2007-02-10 13:37:32 +00:00
/* Array to hold the block sizes
* First part is the vehicle type , while the last is 0 = x , 1 = y */
uint _block_sizes [ 4 ] [ 2 ] ;
/* Array to hold the default resize capacities
2009-03-14 18:16:29 +00:00
* First part is the vehicle type , while the last is 0 = x , 1 = y */
2007-02-10 13:37:32 +00:00
const uint _resize_cap [ ] [ 2 ] = {
2007-03-31 09:24:05 +01:00
/* VEH_TRAIN */ { 6 , 10 * 29 } ,
2007-03-08 16:27:54 +00:00
/* VEH_ROAD */ { 5 , 5 } ,
/* VEH_SHIP */ { 3 , 3 } ,
/* VEH_AIRCRAFT */ { 3 , 4 } ,
2007-02-10 13:37:32 +00:00
} ;
static void ResizeDefaultWindowSizeForTrains ( )
{
2007-03-08 16:27:54 +00:00
_block_sizes [ VEH_TRAIN ] [ 0 ] = 1 ;
_block_sizes [ VEH_TRAIN ] [ 1 ] = GetVehicleListHeight ( VEH_TRAIN ) ;
2007-02-10 13:37:32 +00:00
}
static void ResizeDefaultWindowSizeForRoadVehicles ( )
{
2007-03-08 16:27:54 +00:00
_block_sizes [ VEH_ROAD ] [ 0 ] = 56 ;
_block_sizes [ VEH_ROAD ] [ 1 ] = GetVehicleListHeight ( VEH_ROAD ) ;
2007-02-10 13:37:32 +00:00
}
2007-05-18 18:31:41 +01:00
static void ResizeDefaultWindowSize ( VehicleType type )
2007-02-10 13:37:32 +00:00
{
uint max_width = 0 ;
uint max_height = 0 ;
2008-04-29 22:31:29 +01:00
const Engine * e ;
FOR_ALL_ENGINES_OF_TYPE ( e , type ) {
EngineID eid = e - > index ;
2007-02-10 13:37:32 +00:00
uint x , y ;
switch ( type ) {
default : NOT_REACHED ( ) ;
2008-04-29 08:11:54 +01:00
case VEH_SHIP : GetShipSpriteSize ( eid , x , y ) ; break ;
case VEH_AIRCRAFT : GetAircraftSpriteSize ( eid , x , y ) ; break ;
2007-02-10 13:37:32 +00:00
}
if ( x > max_width ) max_width = x ;
if ( y > max_height ) max_height = y ;
}
switch ( type ) {
default : NOT_REACHED ( ) ;
2007-03-08 16:27:54 +00:00
case VEH_SHIP :
_block_sizes [ VEH_SHIP ] [ 0 ] = max ( 90U , max_width + 20 ) ; // we need 20 pixels from the right edge to the sprite
2007-02-10 13:37:32 +00:00
break ;
2007-03-08 16:27:54 +00:00
case VEH_AIRCRAFT :
_block_sizes [ VEH_AIRCRAFT ] [ 0 ] = max ( 74U , max_width ) ;
2007-02-10 13:37:32 +00:00
break ;
}
_block_sizes [ type ] [ 1 ] = max ( GetVehicleListHeight ( type ) , max_height ) ;
}
/* Set the size of the blocks in the window so we can be sure that they are big enough for the vehicle sprites in the current game
* We will only need to call this once for each game */
void InitDepotWindowBlockSizes ( )
{
ResizeDefaultWindowSizeForTrains ( ) ;
ResizeDefaultWindowSizeForRoadVehicles ( ) ;
2007-03-08 16:27:54 +00:00
ResizeDefaultWindowSize ( VEH_SHIP ) ;
ResizeDefaultWindowSize ( VEH_AIRCRAFT ) ;
2007-02-10 13:37:32 +00:00
}
2008-05-13 14:39:50 +01:00
static void DepotSellAllConfirmationCallback ( Window * w , bool confirmed ) ;
const Sprite * GetAircraftSprite ( EngineID engine ) ;
struct DepotWindow : Window {
VehicleID sel ;
VehicleType type ;
bool generate_list ;
2008-05-25 18:22:49 +01:00
VehicleList vehicle_list ;
VehicleList wagon_list ;
2006-12-07 00:51:20 +00:00
2008-12-28 20:53:19 +00:00
DepotWindow ( const WindowDesc * desc , TileIndex tile , VehicleType type ) : Window ( desc , tile )
2008-05-13 14:39:50 +01:00
{
this - > sel = INVALID_VEHICLE ;
this - > generate_list = true ;
2007-02-10 13:37:32 +00:00
2009-02-09 02:33:10 +00:00
this - > owner = GetTileOwner ( tile ) ;
2008-12-28 20:53:19 +00:00
this - > CreateDepotListWindow ( type ) ;
2008-05-13 14:39:50 +01:00
this - > FindWindowPlacementAndResize ( desc ) ;
}
~ DepotWindow ( )
{
DeleteWindowById ( WC_BUILD_VEHICLE , this - > window_number ) ;
}
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
/** Draw a vehicle in the depot window in the box with the top left corner at x,y
2009-03-14 18:16:29 +00:00
* @ param * w Window to draw in
* @ param * v Vehicle to draw
* @ param x Left side of the box to draw in
* @ param y Top of the box to draw in
*/
2008-05-13 14:39:50 +01:00
void DrawVehicleInDepot ( Window * w , const Vehicle * v , int x , int y )
{
byte diff_x = 0 , diff_y = 0 ;
int sprite_y = y + this - > resize . step_height - GetVehicleListHeight ( v - > type ) ;
switch ( v - > type ) {
case VEH_TRAIN :
DrawTrainImage ( v , x + 21 , sprite_y , this - > sel , this - > hscroll . cap + 4 , this - > hscroll . pos ) ;
/* Number of wagons relative to a standard length wagon (rounded up) */
SetDParam ( 0 , ( v - > u . rail . cached_total_length + 7 ) / 8 ) ;
2009-03-21 22:22:00 +00:00
DrawString ( this - > widget [ DEPOT_WIDGET_MATRIX ] . left , this - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 4 , STR_TINY_BLACK , TC_FROMSTRING , SA_RIGHT ) ; // Draw the counter
2008-05-13 14:39:50 +01:00
break ;
case VEH_ROAD : DrawRoadVehImage ( v , x + 24 , sprite_y , this - > sel , 1 ) ; break ;
case VEH_SHIP : DrawShipImage ( v , x + 19 , sprite_y - 1 , this - > sel ) ; break ;
case VEH_AIRCRAFT : {
2008-09-02 16:20:38 +01:00
const Sprite * spr = GetSprite ( v - > GetImage ( DIR_W ) , ST_NORMAL ) ;
2008-05-13 14:39:50 +01:00
DrawAircraftImage ( v , x + 12 ,
y + max ( spr - > height + spr - > y_offs - 14 , 0 ) , // tall sprites needs an y offset
this - > sel ) ;
} break ;
default : NOT_REACHED ( ) ;
}
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
if ( this - > resize . step_height = = 14 ) {
/* VEH_TRAIN and VEH_ROAD, which are low */
diff_x = 15 ;
} else {
/* VEH_SHIP and VEH_AIRCRAFT, which are tall */
diff_y = 12 ;
}
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
DrawSprite ( ( v - > vehstatus & VS_STOPPED ) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING , PAL_NONE , x + diff_x , y + diff_y ) ;
2007-02-10 13:37:32 +00:00
2008-05-13 14:39:50 +01:00
SetDParam ( 0 , v - > unitnumber ) ;
2009-04-26 15:52:56 +01:00
DrawString ( x , this - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 2 , ( uint16 ) ( v - > max_age - DAYS_IN_LEAP_YEAR ) > = v - > age ? STR_BLACK_COMMA : STR_RED_COMMA ) ;
2006-12-07 00:51:20 +00:00
}
2008-05-13 14:39:50 +01:00
void DrawDepotWindow ( Window * w )
{
TileIndex tile = this - > window_number ;
int x , y , i , maxval ;
uint16 hnum ;
/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
uint16 rows_in_display = this - > widget [ DEPOT_WIDGET_MATRIX ] . data > > 8 ;
uint16 boxes_in_each_row = this - > widget [ DEPOT_WIDGET_MATRIX ] . data & 0xFF ;
/* setup disabled buttons */
2008-09-30 21:39:50 +01:00
this - > SetWidgetsDisabledState ( ! IsTileOwner ( tile , _local_company ) ,
2008-05-13 14:39:50 +01:00
DEPOT_WIDGET_STOP_ALL ,
DEPOT_WIDGET_START_ALL ,
DEPOT_WIDGET_SELL ,
DEPOT_WIDGET_SELL_CHAIN ,
DEPOT_WIDGET_SELL_ALL ,
DEPOT_WIDGET_BUILD ,
DEPOT_WIDGET_CLONE ,
DEPOT_WIDGET_AUTOREPLACE ,
WIDGET_LIST_END ) ;
/* determine amount of items for scroller */
if ( this - > type = = VEH_TRAIN ) {
hnum = 8 ;
2008-05-25 18:22:49 +01:00
for ( uint num = 0 ; num < this - > vehicle_list . Length ( ) ; num + + ) {
const Vehicle * v = this - > vehicle_list [ num ] ;
2008-05-13 14:39:50 +01:00
hnum = max ( hnum , v - > u . rail . cached_total_length ) ;
}
/* Always have 1 empty row, so people can change the setting of the train */
2008-05-25 18:22:49 +01:00
SetVScrollCount ( w , this - > vehicle_list . Length ( ) + this - > wagon_list . Length ( ) + 1 ) ;
2008-05-13 14:39:50 +01:00
SetHScrollCount ( w , WagonLengthToPixels ( hnum ) ) ;
} else {
2008-05-25 18:22:49 +01:00
SetVScrollCount ( w , ( this - > vehicle_list . Length ( ) + this - > hscroll . cap - 1 ) / this - > hscroll . cap ) ;
2008-05-13 14:39:50 +01:00
}
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
/* locate the depot struct */
if ( this - > type = = VEH_AIRCRAFT ) {
SetDParam ( 0 , GetStationIndex ( tile ) ) ; // Airport name
} else {
Depot * depot = GetDepotByTile ( tile ) ;
assert ( depot ! = NULL ) ;
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
SetDParam ( 0 , depot - > town_index ) ;
}
2006-12-07 00:51:20 +00:00
2008-05-17 13:48:06 +01:00
w - > DrawWidgets ( ) ;
2006-12-07 00:51:20 +00:00
2008-05-25 18:22:49 +01:00
uint16 num = this - > vscroll . pos * boxes_in_each_row ;
maxval = min ( this - > vehicle_list . Length ( ) , num + ( rows_in_display * boxes_in_each_row ) ) ;
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
for ( x = 2 , y = 15 ; num < maxval ; y + = this - > resize . step_height , x = 2 ) { // Draw the rows
byte i ;
2006-12-07 00:51:20 +00:00
2008-05-13 14:39:50 +01:00
for ( i = 0 ; i < boxes_in_each_row & & num < maxval ; i + + , num + + , x + = this - > resize . step_width ) {
/* Draw all vehicles in the current row */
2008-05-25 18:22:49 +01:00
const Vehicle * v = this - > vehicle_list [ num ] ;
2008-05-13 14:39:50 +01:00
DrawVehicleInDepot ( w , v , x , y ) ;
}
}
2006-10-05 14:11:17 +01:00
2008-05-25 18:22:49 +01:00
maxval = min ( this - > vehicle_list . Length ( ) + this - > wagon_list . Length ( ) , ( this - > vscroll . pos * boxes_in_each_row ) + ( rows_in_display * boxes_in_each_row ) ) ;
2006-10-05 13:59:28 +01:00
2008-05-13 14:39:50 +01:00
/* draw the train wagons, that do not have an engine in front */
for ( ; num < maxval ; num + + , y + = 14 ) {
2008-05-25 18:22:49 +01:00
const Vehicle * v = this - > wagon_list [ num - this - > vehicle_list . Length ( ) ] ;
2008-05-13 14:39:50 +01:00
const Vehicle * u ;
DrawTrainImage ( v , x + 50 , y , this - > sel , this - > hscroll . cap - 29 , 0 ) ;
2009-04-26 15:52:56 +01:00
DrawString ( x , this - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 2 , STR_DEPOT_NO_ENGINE ) ;
2006-09-26 17:47:51 +01:00
2009-03-15 00:32:18 +00:00
/* Draw the train counter */
2008-05-13 14:39:50 +01:00
i = 0 ;
u = v ;
do i + + ; while ( ( u = u - > Next ( ) ) ! = NULL ) ; // Determine length of train
SetDParam ( 0 , i ) ; // Set the counter
2009-03-21 22:22:00 +00:00
DrawString ( this - > widget [ DEPOT_WIDGET_MATRIX ] . left , this - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 4 , STR_TINY_BLACK , TC_FROMSTRING , SA_RIGHT ) ; // Draw the counter
2008-05-13 14:39:50 +01:00
}
}
struct GetDepotVehiclePtData {
2008-05-25 10:40:44 +01:00
const Vehicle * head ;
const Vehicle * wagon ;
2008-05-13 14:39:50 +01:00
} ;
enum DepotGUIAction {
MODE_ERROR ,
MODE_DRAG_VEHICLE ,
MODE_SHOW_VEHICLE ,
MODE_START_STOP ,
} ;
2008-05-25 10:40:44 +01:00
DepotGUIAction GetVehicleFromDepotWndPt ( int x , int y , const Vehicle * * veh , GetDepotVehiclePtData * d ) const
2008-05-13 14:39:50 +01:00
{
uint xt , row , xm = 0 , ym = 0 ;
int pos , skip = 0 ;
uint16 boxes_in_each_row = this - > widget [ DEPOT_WIDGET_MATRIX ] . data & 0xFF ;
if ( this - > type = = VEH_TRAIN ) {
xt = 0 ;
x - = 23 ;
} else {
xt = x / this - > resize . step_width ;
xm = x % this - > resize . step_width ;
if ( xt > = this - > hscroll . cap ) return MODE_ERROR ;
ym = ( y - 14 ) % this - > resize . step_height ;
}
row = ( y - 14 ) / this - > resize . step_height ;
if ( row > = this - > vscroll . cap ) return MODE_ERROR ;
pos = ( ( row + this - > vscroll . pos ) * boxes_in_each_row ) + xt ;
2008-05-25 18:22:49 +01:00
if ( ( int ) ( this - > vehicle_list . Length ( ) + this - > wagon_list . Length ( ) ) < = pos ) {
2008-05-13 14:39:50 +01:00
if ( this - > type = = VEH_TRAIN ) {
d - > head = NULL ;
d - > wagon = NULL ;
return MODE_DRAG_VEHICLE ;
2006-10-05 13:59:28 +01:00
} else {
2008-05-13 14:39:50 +01:00
return MODE_ERROR ; // empty block, so no vehicle is selected
2006-10-05 13:59:28 +01:00
}
2008-05-13 14:39:50 +01:00
}
2006-09-26 17:47:51 +01:00
2008-05-25 18:22:49 +01:00
if ( ( int ) this - > vehicle_list . Length ( ) > pos ) {
* veh = this - > vehicle_list [ pos ] ;
2008-05-13 14:39:50 +01:00
skip = this - > hscroll . pos ;
} else {
2008-05-25 18:22:49 +01:00
pos - = this - > vehicle_list . Length ( ) ;
* veh = this - > wagon_list [ pos ] ;
2008-05-13 14:39:50 +01:00
/* free wagons don't have an initial loco. */
x - = _traininfo_vehicle_width ;
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
switch ( this - > type ) {
case VEH_TRAIN : {
2008-05-25 10:40:44 +01:00
const Vehicle * v = * veh ;
2008-05-13 14:39:50 +01:00
d - > head = d - > wagon = v ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
/* either pressed the flag or the number, but only when it's a loco */
if ( x < 0 & & IsFrontEngine ( v ) ) return ( x > = - 10 ) ? MODE_START_STOP : MODE_SHOW_VEHICLE ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
skip = ( skip * 8 ) / _traininfo_vehicle_width ;
x = ( x * 8 ) / _traininfo_vehicle_width ;
2006-10-24 13:56:14 +01:00
2008-05-13 14:39:50 +01:00
/* Skip vehicles that are scrolled off the list */
x + = skip ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
/* find the vehicle in this row that was clicked */
while ( v ! = NULL & & ( x - = v - > u . rail . cached_veh_length ) > = 0 ) v = v - > Next ( ) ;
2006-09-26 20:20:35 +01:00
2008-05-13 14:39:50 +01:00
/* if an articulated part was selected, find its parent */
while ( v ! = NULL & & IsArticulatedPart ( v ) ) v = v - > Previous ( ) ;
2006-09-26 20:20:35 +01:00
2008-05-13 14:39:50 +01:00
d - > wagon = v ;
2006-09-27 23:44:39 +01:00
2008-05-13 14:39:50 +01:00
return MODE_DRAG_VEHICLE ;
}
break ;
2006-09-30 14:39:34 +01:00
2008-05-13 14:39:50 +01:00
case VEH_ROAD :
if ( xm > = 24 ) return MODE_DRAG_VEHICLE ;
if ( xm < = 16 ) return MODE_SHOW_VEHICLE ;
break ;
2006-09-28 15:17:08 +01:00
2008-05-13 14:39:50 +01:00
case VEH_SHIP :
if ( xm > = 19 ) return MODE_DRAG_VEHICLE ;
if ( ym < = 10 ) return MODE_SHOW_VEHICLE ;
break ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
case VEH_AIRCRAFT :
if ( xm > = 12 ) return MODE_DRAG_VEHICLE ;
if ( ym < = 12 ) return MODE_SHOW_VEHICLE ;
break ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
default : NOT_REACHED ( ) ;
}
return MODE_START_STOP ;
}
2008-02-17 12:21:05 +00:00
2008-05-13 14:39:50 +01:00
void DepotClick ( int x , int y )
{
2008-05-13 23:02:14 +01:00
GetDepotVehiclePtData gdvp = { NULL , NULL } ;
2008-05-25 10:40:44 +01:00
const Vehicle * v = NULL ;
2008-05-13 14:39:50 +01:00
DepotGUIAction mode = this - > GetVehicleFromDepotWndPt ( x , y , & v , & gdvp ) ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
/* share / copy orders */
2009-04-19 11:31:30 +01:00
if ( _thd . place_mode ! = HT_NONE & & mode ! = MODE_ERROR ) {
2008-05-13 14:39:50 +01:00
_place_clicked_vehicle = ( this - > type = = VEH_TRAIN ? gdvp . head : v ) ;
return ;
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
if ( this - > type = = VEH_TRAIN ) v = gdvp . wagon ;
switch ( mode ) {
case MODE_ERROR : // invalid
return ;
case MODE_DRAG_VEHICLE : { // start dragging of vehicle
VehicleID sel = this - > sel ;
if ( this - > type = = VEH_TRAIN & & sel ! = INVALID_VEHICLE ) {
this - > sel = INVALID_VEHICLE ;
TrainDepotMoveVehicle ( v , sel , gdvp . head ) ;
} else if ( v ! = NULL ) {
int image = v - > GetImage ( DIR_W ) ;
this - > sel = v - > index ;
this - > SetDirty ( ) ;
2009-04-19 11:31:30 +01:00
SetObjectToPlaceWnd ( image , GetVehiclePalette ( v ) , HT_DRAG , this ) ;
2008-07-20 20:21:18 +01:00
switch ( v - > type ) {
case VEH_TRAIN :
_cursor . short_vehicle_offset = 16 - v - > u . rail . cached_veh_length * 2 ;
break ;
case VEH_ROAD :
_cursor . short_vehicle_offset = 16 - v - > u . road . cached_veh_length * 2 ;
break ;
default :
_cursor . short_vehicle_offset = 0 ;
break ;
}
2008-05-13 14:39:50 +01:00
_cursor . vehchain = _ctrl_pressed ;
}
} break ;
case MODE_SHOW_VEHICLE : // show info window
ShowVehicleViewWindow ( v ) ;
break ;
case MODE_START_STOP : { // click start/stop flag
uint command ;
switch ( this - > type ) {
2009-04-22 00:40:56 +01:00
case VEH_TRAIN : command = CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_TRAIN ) ; break ;
case VEH_ROAD : command = CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE ) ; break ;
case VEH_SHIP : command = CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_SHIP ) ; break ;
case VEH_AIRCRAFT : command = CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_AIRCRAFT ) ; break ;
2008-05-13 14:39:50 +01:00
default : NOT_REACHED ( ) ; command = 0 ;
}
2008-12-28 14:37:19 +00:00
DoCommandP ( v - > tile , v - > index , 0 , command ) ;
2008-05-13 14:39:50 +01:00
} break ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
default : NOT_REACHED ( ) ;
}
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
/**
2009-03-14 18:16:29 +00:00
* Clones a vehicle
* @ param * v is the original vehicle to clone
* @ param * w is the window of the depot where the clone is build
*/
2008-05-13 14:39:50 +01:00
void HandleCloneVehClick ( const Vehicle * v , const Window * w )
{
2009-05-13 17:52:51 +01:00
StringID error_str ;
2008-05-13 14:39:50 +01:00
if ( v = = NULL ) return ;
if ( ! v - > IsPrimaryVehicle ( ) ) {
v = v - > First ( ) ;
/* Do nothing when clicking on a train in depot with no loc attached */
if ( v - > type = = VEH_TRAIN & & ! IsFrontEngine ( v ) ) return ;
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
switch ( v - > type ) {
2009-05-13 17:52:51 +01:00
case VEH_TRAIN : error_str = STR_ERROR_CAN_T_BUILD_RAILROAD_VEHICLE ; break ;
case VEH_ROAD : error_str = STR_ERROR_CAN_T_BUILD_ROAD_VEHICLE ; break ;
case VEH_SHIP : error_str = STR_ERROR_CAN_T_BUILD_SHIP ; break ;
case VEH_AIRCRAFT : error_str = STR_ERROR_CAN_T_BUILD_AIRCRAFT ; break ;
2008-05-13 14:39:50 +01:00
default : return ;
}
2006-09-26 17:47:51 +01:00
2009-05-13 17:52:51 +01:00
DoCommandP ( this - > window_number , v - > index , _ctrl_pressed ? 1 : 0 , CMD_CLONE_VEHICLE | CMD_MSG ( error_str ) , CcCloneVehicle ) ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
ResetObjectToPlace ( ) ;
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
void ResizeDepotButtons ( Window * w )
{
ResizeButtons ( w , DEPOT_WIDGET_BUILD , DEPOT_WIDGET_LOCATION ) ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
if ( this - > type = = VEH_TRAIN ) {
/* 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.
2009-03-14 18:16:29 +00:00
* This way it will stay the same even if DEPOT_WIDGET_SELL_CHAIN is resized for some reason */
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_SELL_CHAIN ] . top = ( ( this - > widget [ DEPOT_WIDGET_SELL_CHAIN ] . bottom - this - > widget [ DEPOT_WIDGET_SELL ] . top ) / 2 ) + this - > widget [ DEPOT_WIDGET_SELL ] . top ;
this - > widget [ DEPOT_WIDGET_SELL ] . bottom = this - > widget [ DEPOT_WIDGET_SELL_CHAIN ] . top - 1 ;
}
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
/* Function to set up vehicle specific sprites and strings
* Only use this if it ' s the same widget , that ' s used for more than one vehicle type and it needs different text / sprites
* Vehicle specific text / sprites , that ' s in a widget , that ' s only shown for one vehicle type ( like sell whole train ) is set in the widget array
*/
void SetupStringsForDepotWindow ( VehicleType type )
{
switch ( type ) {
default : NOT_REACHED ( ) ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
case VEH_TRAIN :
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_DEPOT_TRAIN_CAPTION ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_TRAIN_TIP ;
this - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_TRAIN_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_DEPOT_TRAIN_SELL_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON ;
this - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_TRAIN ;
this - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_TRAIN_DEPOT_INFO ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_DEPOT_TRAIN_LOCATION_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_TRAIN ;
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_TRAIN_TIP ;
/* Sprites */
this - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_TRAIN ;
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_TRAIN ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_TRAIN ;
break ;
case VEH_ROAD :
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_DEPOT_ROAD_CAPTION ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_ROADVEH_TIP ;
this - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_ROADVEH_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_DEPOT_ROAD_SELL_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_DEPOT_ROAD_NEW_VEHICLES_BUTTON ;
this - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_DEPOT_ROAD_NEW_VEHICLES_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_ROAD_VEHICLE ;
this - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_ROAD_VEHICLE_DEPOT_INFO ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_DEPOT_ROAD_LOCATION_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_LORRY ;
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_ROADVEH_TIP ;
/* Sprites */
this - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_ROADVEH ;
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_ROADVEH ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_ROADVEH ;
break ;
case VEH_SHIP :
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_DEPOT_SHIP_CAPTION ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_SHIP_TIP ;
this - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_SHIP_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_DEPOT_SHIP_SELL_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON ;
this - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_SHIP ;
this - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_SHIP_DEPOT_INFO ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_DEPOT_SHIP_LOCATION_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_SHIP ;
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_SHIP_TIP ;
/* Sprites */
this - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_SHIP ;
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_SHIP ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_SHIP ;
break ;
case VEH_AIRCRAFT :
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_DEPOT_AIRCRAFT_CAPTION ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_HANGAR_TIP ;
this - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_HANGAR_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_DEPOT_AIRCRAFT_SELL_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON ;
this - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_AIRCRAFT ;
this - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW ;
2009-04-22 00:40:56 +01:00
this - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP ;
2008-05-13 14:39:50 +01:00
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_PLANE ;
this - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP ;
/* Sprites */
this - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_AIRCRAFT ;
this - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_AIRCRAFT ;
this - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_AIRCRAFT ;
break ;
}
}
void CreateDepotListWindow ( VehicleType type )
{
this - > type = type ;
_backup_orders_tile = 0 ;
2008-09-30 21:39:50 +01:00
assert ( IsCompanyBuildableVehicleType ( type ) ) ; // ensure that we make the call with a valid type
2008-05-13 14:39:50 +01:00
/* Resize the window according to the vehicle type */
/* Set the number of blocks in each direction */
this - > vscroll . cap = _resize_cap [ type ] [ 0 ] ;
this - > hscroll . cap = _resize_cap [ type ] [ 1 ] ;
/* Set the block size */
this - > resize . step_width = _block_sizes [ type ] [ 0 ] ;
this - > resize . step_height = _block_sizes [ type ] [ 1 ] ;
/* Enlarge the window to fit with the selected number of blocks of the selected size */
ResizeWindow ( this ,
_block_sizes [ type ] [ 0 ] * this - > hscroll . cap ,
_block_sizes [ type ] [ 1 ] * this - > vscroll . cap ) ;
if ( type = = VEH_TRAIN ) {
/* Make space for the horizontal scrollbar vertically, and the unit
* number , flag , and length counter horizontally . */
ResizeWindow ( this , 36 , 12 ) ;
/* substract the newly added space from the matrix since it was meant for the scrollbar */
this - > widget [ DEPOT_WIDGET_MATRIX ] . bottom - = 12 ;
}
/* Set the minimum window size to the current window size */
this - > resize . width = this - > width ;
this - > resize . height = this - > height ;
this - > SetupStringsForDepotWindow ( type ) ;
this - > widget [ DEPOT_WIDGET_MATRIX ] . data =
( this - > vscroll . cap * 0x100 ) // number of rows to draw on the background
+ ( type = = VEH_TRAIN ? 1 : this - > hscroll . cap ) ; // number of boxes in each row. Trains always have just one
this - > SetWidgetsHiddenState ( type ! = VEH_TRAIN ,
DEPOT_WIDGET_H_SCROLL ,
DEPOT_WIDGET_SELL_CHAIN ,
WIDGET_LIST_END ) ;
ResizeDepotButtons ( this ) ;
}
virtual void OnInvalidateData ( int data )
{
this - > generate_list = true ;
}
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
virtual void OnPaint ( )
{
if ( this - > generate_list ) {
/* Generate the vehicle list
* It ' s ok to use the wagon pointers for non - trains as they will be ignored */
2008-05-25 18:22:49 +01:00
BuildDepotVehicleList ( this - > type , this - > window_number , & this - > vehicle_list , & this - > wagon_list ) ;
2008-05-13 14:39:50 +01:00
this - > generate_list = false ;
2008-05-25 18:22:49 +01:00
DepotSortList ( & this - > vehicle_list ) ;
2008-05-13 14:39:50 +01:00
}
DrawDepotWindow ( this ) ;
}
virtual void OnClick ( Point pt , int widget )
{
switch ( widget ) {
case DEPOT_WIDGET_MATRIX : // List
this - > DepotClick ( pt . x , pt . y ) ;
break ;
case DEPOT_WIDGET_BUILD : // Build vehicle
ResetObjectToPlace ( ) ;
ShowBuildVehicleWindow ( this - > window_number , this - > type ) ;
break ;
case DEPOT_WIDGET_CLONE : // Clone button
this - > InvalidateWidget ( DEPOT_WIDGET_CLONE ) ;
this - > ToggleWidgetLoweredState ( DEPOT_WIDGET_CLONE ) ;
if ( this - > IsWidgetLowered ( DEPOT_WIDGET_CLONE ) ) {
static const CursorID clone_icons [ ] = {
SPR_CURSOR_CLONE_TRAIN , SPR_CURSOR_CLONE_ROADVEH ,
SPR_CURSOR_CLONE_SHIP , SPR_CURSOR_CLONE_AIRPLANE
} ;
_place_clicked_vehicle = NULL ;
2009-04-19 11:31:30 +01:00
SetObjectToPlaceWnd ( clone_icons [ this - > type ] , PAL_NONE , HT_RECT , this ) ;
2008-05-13 14:39:50 +01:00
} else {
ResetObjectToPlace ( ) ;
}
break ;
case DEPOT_WIDGET_LOCATION :
if ( _ctrl_pressed ) {
ShowExtraViewPortWindow ( this - > window_number ) ;
} else {
ScrollMainWindowToTile ( this - > window_number ) ;
}
break ;
case DEPOT_WIDGET_STOP_ALL :
case DEPOT_WIDGET_START_ALL :
2008-12-28 14:37:19 +00:00
DoCommandP ( this - > window_number , 0 , this - > type | ( widget = = DEPOT_WIDGET_START_ALL ? ( 1 < < 5 ) : 0 ) , CMD_MASS_START_STOP ) ;
2008-05-13 14:39:50 +01:00
break ;
case DEPOT_WIDGET_SELL_ALL :
/* Only open the confimation window if there are anything to sell */
2008-05-25 18:22:49 +01:00
if ( this - > vehicle_list . Length ( ) ! = 0 | | this - > wagon_list . Length ( ) ! = 0 ) {
2008-05-13 14:39:50 +01:00
static const StringID confirm_captions [ ] = {
2009-04-22 00:40:56 +01:00
STR_DEPOT_TRAIN_CAPTION ,
STR_DEPOT_ROAD_CAPTION ,
STR_DEPOT_SHIP_CAPTION ,
STR_DEPOT_AIRCRAFT_CAPTION
2008-05-13 14:39:50 +01:00
} ;
TileIndex tile = this - > window_number ;
byte vehtype = this - > type ;
SetDParam ( 0 , ( vehtype = = VEH_AIRCRAFT ) ? GetStationIndex ( tile ) : GetDepotByTile ( tile ) - > town_index ) ;
ShowQuery (
confirm_captions [ vehtype ] ,
STR_DEPOT_SELL_CONFIRMATION_TEXT ,
this ,
DepotSellAllConfirmationCallback
) ;
}
break ;
case DEPOT_WIDGET_VEHICLE_LIST :
ShowVehicleListWindow ( GetTileOwner ( this - > window_number ) , this - > type , ( TileIndex ) this - > window_number ) ;
break ;
case DEPOT_WIDGET_AUTOREPLACE :
2008-12-28 14:37:19 +00:00
DoCommandP ( this - > window_number , this - > type , 0 , CMD_DEPOT_MASS_AUTOREPLACE ) ;
2008-05-13 14:39:50 +01:00
break ;
}
}
2008-08-02 13:43:45 +01:00
virtual void OnRightClick ( Point pt , int widget )
{
if ( widget ! = DEPOT_WIDGET_MATRIX ) return ;
GetDepotVehiclePtData gdvp = { NULL , NULL } ;
const Vehicle * v = NULL ;
DepotGUIAction mode = this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , & gdvp ) ;
if ( this - > type = = VEH_TRAIN ) v = gdvp . wagon ;
if ( v ! = NULL & & mode = = MODE_DRAG_VEHICLE ) {
AcceptedCargo capacity , loaded ;
memset ( capacity , 0 , sizeof ( capacity ) ) ;
memset ( loaded , 0 , sizeof ( loaded ) ) ;
/* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
bool whole_chain = ( this - > type = = VEH_TRAIN & & _ctrl_pressed ) ;
/* loop through vehicle chain and collect cargos */
uint num = 0 ;
for ( const Vehicle * w = v ; w ! = NULL ; w = w - > Next ( ) ) {
if ( w - > cargo_cap > 0 & & w - > cargo_type < NUM_CARGO ) {
capacity [ w - > cargo_type ] + = w - > cargo_cap ;
loaded [ w - > cargo_type ] + = w - > cargo . Count ( ) ;
}
if ( w - > type = = VEH_TRAIN & & ! EngineHasArticPart ( w ) ) {
num + + ;
if ( ! whole_chain ) break ;
}
}
/* Build tooltipstring */
static char details [ 1024 ] ;
details [ 0 ] = ' \0 ' ;
char * pos = details ;
for ( CargoID cargo_type = 0 ; cargo_type < NUM_CARGO ; cargo_type + + ) {
if ( capacity [ cargo_type ] = = 0 ) continue ;
SetDParam ( 0 , cargo_type ) ; // {CARGO} #1
SetDParam ( 1 , loaded [ cargo_type ] ) ; // {CARGO} #2
SetDParam ( 2 , cargo_type ) ; // {SHORTCARGO} #1
SetDParam ( 3 , capacity [ cargo_type ] ) ; // {SHORTCARGO} #2
pos = GetString ( pos , STR_DEPOT_VEHICLE_TOOLTIP_CARGO , lastof ( details ) ) ;
}
/* Show tooltip window */
uint64 args [ 2 ] ;
args [ 0 ] = ( whole_chain ? num : v - > engine_type ) ;
2008-08-03 00:30:50 +01:00
args [ 1 ] = ( uint64 ) ( size_t ) details ;
2008-08-02 13:43:45 +01:00
GuiShowTooltips ( whole_chain ? STR_DEPOT_VEHICLE_TOOLTIP_CHAIN : STR_DEPOT_VEHICLE_TOOLTIP , 2 , args ) ;
} else {
/* Show tooltip help */
StringID tooltip = INVALID_STRING_ID ;
switch ( this - > type ) {
2009-04-22 00:40:56 +01:00
case VEH_TRAIN : tooltip = STR_DEPOT_TRAIN_LIST_TOOLTIP ; break ;
case VEH_ROAD : tooltip = STR_DEPOT_ROAD_LIST_TOOLTIP ; break ;
case VEH_SHIP : tooltip = STR_DEPOT_SHIP_LIST_TOOLTIP ; break ;
case VEH_AIRCRAFT : tooltip = STR_DEPOT_AIRCRAFT_LIST_TOOLTIP ; break ;
2008-08-02 13:43:45 +01:00
default : NOT_REACHED ( ) ;
}
GuiShowTooltips ( tooltip ) ;
}
}
2008-05-13 14:39:50 +01:00
virtual void OnPlaceObject ( Point pt , TileIndex tile )
{
const Vehicle * v = CheckMouseOverVehicle ( ) ;
if ( v ! = NULL ) HandleCloneVehClick ( v , this ) ;
}
virtual void OnPlaceObjectAbort ( )
{
/* abort clone */
this - > RaiseWidget ( DEPOT_WIDGET_CLONE ) ;
this - > InvalidateWidget ( DEPOT_WIDGET_CLONE ) ;
/* abort drag & drop */
this - > sel = INVALID_VEHICLE ;
this - > InvalidateWidget ( DEPOT_WIDGET_MATRIX ) ;
} ;
/* check if a vehicle in a depot was clicked.. */
virtual void OnMouseLoop ( )
{
const Vehicle * v = _place_clicked_vehicle ;
/* since OTTD checks all open depot windows, we will make sure that it triggers the one with a clicked clone button */
if ( v ! = NULL & & this - > IsWidgetLowered ( DEPOT_WIDGET_CLONE ) ) {
_place_clicked_vehicle = NULL ;
HandleCloneVehClick ( v , this ) ;
}
}
virtual void OnDragDrop ( Point pt , int widget )
{
switch ( widget ) {
case DEPOT_WIDGET_MATRIX : {
2008-05-25 10:40:44 +01:00
const Vehicle * v = NULL ;
2008-05-13 14:39:50 +01:00
VehicleID sel = this - > sel ;
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
if ( this - > type = = VEH_TRAIN ) {
2008-05-14 19:35:15 +01:00
GetDepotVehiclePtData gdvp = { NULL , NULL } ;
2008-05-13 14:39:50 +01:00
if ( this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , & gdvp ) = = MODE_DRAG_VEHICLE & &
sel ! = INVALID_VEHICLE ) {
if ( gdvp . wagon ! = NULL & & gdvp . wagon - > index = = sel & & _ctrl_pressed ) {
2009-05-17 00:34:14 +01:00
DoCommandP ( Vehicle : : Get ( sel ) - > tile , Vehicle : : Get ( sel ) - > index , true , CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG ( STR_ERROR_CAN_T_MAKE_VEHICLE_TURN ) ) ;
2008-05-13 14:39:50 +01:00
} else if ( gdvp . wagon = = NULL | | gdvp . wagon - > index ! = sel ) {
TrainDepotMoveVehicle ( gdvp . wagon , sel , gdvp . head ) ;
} else if ( gdvp . head ! = NULL & & IsFrontEngine ( gdvp . head ) ) {
ShowVehicleViewWindow ( gdvp . head ) ;
2006-09-26 17:47:51 +01:00
}
2008-05-13 14:39:50 +01:00
}
} else if ( this - > GetVehicleFromDepotWndPt ( pt . x , pt . y , & v , NULL ) = = MODE_DRAG_VEHICLE & &
v ! = NULL & &
sel = = v - > index ) {
ShowVehicleViewWindow ( v ) ;
}
} break ;
case DEPOT_WIDGET_SELL : case DEPOT_WIDGET_SELL_CHAIN :
if ( ! this - > IsWidgetDisabled ( DEPOT_WIDGET_SELL ) & &
this - > sel ! = INVALID_VEHICLE ) {
uint command ;
if ( this - > IsWidgetDisabled ( widget ) ) return ;
if ( this - > sel = = INVALID_VEHICLE ) return ;
2006-09-26 17:47:51 +01:00
2008-05-13 14:39:50 +01:00
this - > HandleButtonClick ( widget ) ;
2009-05-17 00:34:14 +01:00
const Vehicle * v = Vehicle : : Get ( this - > sel ) ;
2008-05-13 14:39:50 +01:00
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
2008-05-25 10:40:44 +01:00
int sell_cmd = ( v - > type = = VEH_TRAIN & & ( widget = = DEPOT_WIDGET_SELL_CHAIN | | _ctrl_pressed ) ) ? 1 : 0 ;
2008-05-13 14:39:50 +01:00
2008-05-25 10:40:44 +01:00
bool is_engine = ( ! ( v - > type = = VEH_TRAIN & & ! IsFrontEngine ( v ) ) ) ;
2008-05-13 14:39:50 +01:00
if ( is_engine ) {
_backup_orders_tile = v - > tile ;
BackupVehicleOrders ( v ) ;
2006-09-26 17:47:51 +01:00
}
2008-05-13 14:39:50 +01:00
switch ( v - > type ) {
2009-04-22 00:40:56 +01:00
case VEH_TRAIN : command = CMD_SELL_RAIL_WAGON | CMD_MSG ( STR_ERROR_CAN_T_SELL_RAILROAD_VEHICLE ) ; break ;
case VEH_ROAD : command = CMD_SELL_ROAD_VEH | CMD_MSG ( STR_ERROR_CAN_T_SELL_ROAD_VEHICLE ) ; break ;
case VEH_SHIP : command = CMD_SELL_SHIP | CMD_MSG ( STR_ERROR_CAN_T_SELL_SHIP ) ; break ;
case VEH_AIRCRAFT : command = CMD_SELL_AIRCRAFT | CMD_MSG ( STR_ERROR_CAN_T_SELL_AIRCRAFT ) ; break ;
2008-05-13 14:39:50 +01:00
default : NOT_REACHED ( ) ; command = 0 ;
}
2008-04-05 12:27:50 +01:00
2008-12-28 14:37:19 +00:00
if ( ! DoCommandP ( v - > tile , v - > index , sell_cmd , command ) & & is_engine ) _backup_orders_tile = 0 ;
2008-05-13 14:39:50 +01:00
}
break ;
default :
this - > sel = INVALID_VEHICLE ;
this - > SetDirty ( ) ;
}
_cursor . vehchain = false ;
}
2009-03-29 10:49:11 +01:00
virtual void OnResize ( Point delta )
2008-05-13 14:39:50 +01:00
{
this - > vscroll . cap + = delta . y / ( int ) this - > resize . step_height ;
this - > hscroll . cap + = delta . x / ( int ) this - > resize . step_width ;
this - > widget [ DEPOT_WIDGET_MATRIX ] . data = ( this - > vscroll . cap < < 8 ) + ( this - > type = = VEH_TRAIN ? 1 : this - > hscroll . cap ) ;
ResizeDepotButtons ( this ) ;
}
2008-05-18 00:11:06 +01:00
virtual EventState OnCTRLStateChange ( )
2008-05-13 14:39:50 +01:00
{
if ( this - > sel ! = INVALID_VEHICLE ) {
_cursor . vehchain = _ctrl_pressed ;
this - > InvalidateWidget ( DEPOT_WIDGET_MATRIX ) ;
2008-08-16 19:01:23 +01:00
return ES_HANDLED ;
2008-05-13 14:39:50 +01:00
}
2008-08-16 19:01:23 +01:00
return ES_NOT_HANDLED ;
2008-05-13 14:39:50 +01:00
}
} ;
static void DepotSellAllConfirmationCallback ( Window * win , bool confirmed )
{
if ( confirmed ) {
DepotWindow * w = ( DepotWindow * ) win ;
TileIndex tile = w - > window_number ;
byte vehtype = w - > type ;
2008-12-28 14:37:19 +00:00
DoCommandP ( tile , vehtype , 0 , CMD_DEPOT_SELL_ALL_VEHICLES ) ;
2006-09-26 17:47:51 +01:00
}
}
/** Opens a depot window
* @ param tile The tile where the depot / hangar is located
* @ param type The type of vehicles in the depot
*/
2007-05-18 18:31:41 +01:00
void ShowDepotWindow ( TileIndex tile , VehicleType type )
2006-09-26 17:47:51 +01:00
{
2008-12-28 20:53:19 +00:00
if ( BringWindowToFrontById ( WC_VEHICLE_DEPOT , tile ) ! = NULL ) return ;
2006-09-26 17:47:51 +01:00
2008-12-28 20:53:19 +00:00
const WindowDesc * desc ;
2006-09-26 17:47:51 +01:00
switch ( type ) {
2006-12-07 00:51:20 +00:00
default : NOT_REACHED ( ) ;
2008-12-28 20:53:19 +00:00
case VEH_TRAIN : desc = & _train_depot_desc ; break ;
case VEH_ROAD : desc = & _road_depot_desc ; break ;
case VEH_SHIP : desc = & _ship_depot_desc ; break ;
case VEH_AIRCRAFT : desc = & _aircraft_depot_desc ; break ;
2006-09-26 17:47:51 +01:00
}
2008-12-28 20:53:19 +00:00
new DepotWindow ( desc , tile , type ) ;
2006-09-26 17:47:51 +01:00
}
2006-12-05 22:40:42 +00:00
/** Removes the highlight of a vehicle in a depot window
* @ param * v Vehicle to remove all highlights from
*/
void DeleteDepotHighlightOfVehicle ( const Vehicle * v )
{
2008-05-13 14:39:50 +01:00
DepotWindow * w ;
2006-12-05 22:40:42 +00:00
2006-12-06 00:03:24 +00:00
/* If we haven't got any vehicles on the mouse pointer, we haven't got any highlighted in any depots either
2008-05-13 14:39:50 +01:00
* If that is the case , we can skip looping though the windows and save time
*/
2006-12-06 00:03:24 +00:00
if ( _special_mouse_mode ! = WSM_DRAGDROP ) return ;
2008-05-13 14:39:50 +01:00
w = dynamic_cast < DepotWindow * > ( FindWindowById ( WC_VEHICLE_DEPOT , v - > tile ) ) ;
2006-12-06 17:31:16 +00:00
if ( w ! = NULL ) {
2009-01-08 21:13:20 +00:00
if ( w - > sel = = v - > index ) ResetObjectToPlace ( ) ;
2006-12-05 22:40:42 +00:00
}
}