2006-09-26 16:47:51 +00:00
/* $Id$ */
# include "stdafx.h"
# include "openttd.h"
# include "functions.h"
2006-09-27 15:47:00 +00:00
# include "train.h"
# include "roadveh.h"
2006-09-26 16:47:51 +00:00
# include "ship.h"
2006-09-27 15:40:55 +00:00
# include "aircraft.h"
2006-09-26 16:47:51 +00:00
# include "table/strings.h"
# include "table/sprites.h"
# include "gui.h"
# include "gfx.h"
# include "vehicle.h"
# include "viewport.h"
# include "command.h"
# include "depot.h"
# include "vehicle_gui.h"
# include "station_map.h"
# include "newgrf_engine.h"
2007-02-10 13:37:32 +00:00
# include "spritecache.h"
2006-09-27 13:01:56 +00: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 11:34:27 +00: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 11:34:27 +00:00
DEPOT_WIDGET_CLOSEBOX = 0 ,
DEPOT_WIDGET_CAPTION ,
DEPOT_WIDGET_STICKY ,
DEPOT_WIDGET_SELL ,
2006-09-27 22:44:39 +00:00
DEPOT_WIDGET_SELL_CHAIN ,
2006-09-27 11:34:27 +00:00
DEPOT_WIDGET_SELL_ALL ,
2006-10-01 16:02:29 +00:00
DEPOT_WIDGET_AUTOREPLACE ,
2006-09-27 11:34:27 +00:00
DEPOT_WIDGET_MATRIX ,
DEPOT_WIDGET_V_SCROLL , // Vertical scrollbar
DEPOT_WIDGET_H_SCROLL , // Horizontal scrollbar
DEPOT_WIDGET_BUILD ,
DEPOT_WIDGET_CLONE ,
DEPOT_WIDGET_LOCATION ,
2006-09-30 13:39:34 +00:00
DEPOT_WIDGET_VEHICLE_LIST ,
2006-10-01 16:02:29 +00:00
DEPOT_WIDGET_STOP_ALL ,
DEPOT_WIDGET_START_ALL ,
2006-09-27 11:34:27 +00:00
DEPOT_WIDGET_RESIZE ,
2006-09-27 13:01:56 +00:00
} ;
2006-09-26 16:47:51 +00: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 00:28:31 +00:00
* and use HideWindowWidget in ShowDepotWindow ( ) to remove it in the windows where it should not be
2006-09-26 16:47:51 +00:00
* Keep the widget numbers in sync with the enum or really bad stuff will happen ! ! ! */
2006-09-27 13:01:56 +00: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 13:53:59 +00: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 16:47:51 +00:00
static const Widget _depot_widgets [ ] = {
{ WWT_CLOSEBOX , RESIZE_NONE , 14 , 0 , 10 , 0 , 13 , STR_00C5 , STR_018B_CLOSE_WINDOW } , // DEPOT_WIDGET_CLOSEBOX
2007-02-10 13:37:32 +00:00
{ WWT_CAPTION , RESIZE_RIGHT , 14 , 11 , 23 , 0 , 13 , 0x0 , STR_018C_WINDOW_TITLE_DRAG_THIS } , // DEPOT_WIDGET_CAPTION
{ WWT_STICKYBOX , RESIZE_LR , 14 , 24 , 35 , 0 , 13 , 0x0 , STR_STICKY_BUTTON } , // DEPOT_WIDGET_STICKY
2006-09-26 19:20:35 +00:00
2006-10-24 14:15:17 +00:00
/* Widgets are set up run-time */
2007-02-10 13:37:32 +00:00
{ WWT_IMGBTN , RESIZE_LRB , 14 , 1 , 23 , 14 , - 32 , 0x0 , STR_NULL } , // DEPOT_WIDGET_SELL
{ WWT_IMGBTN , RESIZE_LRTB , 14 , 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 , 14 , 1 , 23 , - 31 , - 9 , 0x0 , STR_NULL } , // DEPOT_WIDGET_SELL_ALL
{ WWT_PUSHIMGBTN , RESIZE_LRTB , 14 , 1 , 23 , - 8 , 14 , 0x0 , STR_NULL } , // DEPOT_WIDGET_AUTOREPLACE
2006-09-26 16:47:51 +00:00
2007-02-10 13:37:32 +00:00
{ WWT_MATRIX , RESIZE_RB , 14 , 0 , 0 , 14 , 14 , 0x0 , STR_NULL } , // DEPOT_WIDGET_MATRIX
{ WWT_SCROLLBAR , RESIZE_LRB , 14 , 24 , 35 , 14 , 14 , 0x0 , STR_0190_SCROLL_BAR_SCROLLS_LIST } , // DEPOT_WIDGET_V_SCROLL
2006-09-26 16:47:51 +00:00
2007-02-10 13:37:32 +00:00
{ WWT_HSCROLLBAR , RESIZE_RTB , 14 , 0 , 0 , 3 , 14 , 0x0 , STR_HSCROLL_BAR_SCROLLS_LIST } , // DEPOT_WIDGET_H_SCROLL, trains only
2006-09-26 16:47:51 +00: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 */
2007-02-10 13:37:32 +00:00
{ WWT_PUSHTXTBTN , RESIZE_TB , 14 , 0 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_BUILD
{ WWT_TEXTBTN , RESIZE_TB , 14 , 0 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_CLONE
{ WWT_PUSHTXTBTN , RESIZE_RTB , 14 , 0 , - 12 , 15 , 26 , STR_00E4_LOCATION , STR_NULL } , // DEPOT_WIDGET_LOCATION
{ WWT_PUSHTXTBTN , RESIZE_LRTB , 14 , - 11 , 0 , 15 , 26 , 0x0 , STR_NULL } , // DEPOT_WIDGET_VEHICLE_LIST
{ WWT_PUSHIMGBTN , RESIZE_LRTB , 14 , 1 , 11 , 15 , 26 , SPR_FLAG_VEH_STOPPED , STR_NULL } , // DEPOT_WIDGET_STOP_ALL
{ WWT_PUSHIMGBTN , RESIZE_LRTB , 14 , 12 , 23 , 15 , 26 , SPR_FLAG_VEH_RUNNING , STR_NULL } , // DEPOT_WIDGET_START_ALL
{ WWT_RESIZEBOX , RESIZE_LRTB , 14 , 24 , 35 , 15 , 26 , 0x0 , STR_RESIZE_BUTTON } , // DEPOT_WIDGET_RESIZE
2006-09-26 16:47:51 +00:00
{ WIDGETS_END } ,
} ;
static void DepotWndProc ( Window * w , WindowEvent * e ) ;
static const WindowDesc _train_depot_desc = {
2007-02-10 13:37:32 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 16:47:51 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
_depot_widgets ,
DepotWndProc
} ;
static const WindowDesc _road_depot_desc = {
2007-02-10 13:37:32 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 16:47:51 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
_depot_widgets ,
DepotWndProc
} ;
static const WindowDesc _ship_depot_desc = {
2007-02-10 13:37:32 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 16:47:51 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
_depot_widgets ,
DepotWndProc
} ;
static const WindowDesc _aircraft_depot_desc = {
2007-02-10 13:37:32 +00:00
WDP_AUTO , WDP_AUTO , 36 , 27 ,
2007-02-01 15:49:12 +00:00
WC_VEHICLE_DEPOT , WC_NONE ,
2006-09-26 16:47:51 +00:00
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS | WDF_STICKY_BUTTON | WDF_RESIZABLE ,
_depot_widgets ,
DepotWndProc
} ;
extern int WagonLengthToPixels ( int len ) ;
void CcCloneVehicle ( bool success , TileIndex tile , uint32 p1 , uint32 p2 )
{
if ( ! success ) return ;
2006-09-27 15:40:55 +00:00
switch ( GetVehicle ( p1 ) - > type ) {
case VEH_Train : CcCloneTrain ( true , tile , p1 , p2 ) ; break ;
case VEH_Road : CcCloneRoadVeh ( true , tile , p1 , p2 ) ; break ;
case VEH_Ship : CcCloneShip ( true , tile , p1 , p2 ) ; break ;
case VEH_Aircraft : CcCloneAircraft ( true , tile , p1 , p2 ) ; break ;
}
2006-09-26 16:47:51 +00:00
}
static inline void ShowVehicleViewWindow ( const Vehicle * v )
{
switch ( v - > type ) {
case VEH_Train : ShowTrainViewWindow ( v ) ; break ;
case VEH_Road : ShowRoadVehViewWindow ( v ) ; break ;
case VEH_Ship : ShowShipViewWindow ( v ) ; break ;
case VEH_Aircraft : ShowAircraftViewWindow ( v ) ; break ;
default : NOT_REACHED ( ) ;
}
}
2006-12-29 17:56:34 +00:00
static void DepotSellAllConfirmationCallback ( Window * w , bool confirmed )
2006-09-27 22:44:39 +00:00
{
2006-12-29 17:56:34 +00:00
if ( confirmed ) {
TileIndex tile = w - > window_number ;
byte vehtype = WP ( w , depot_d ) . type ;
DoCommandP ( tile , vehtype , 0 , NULL , CMD_DEPOT_SELL_ALL_VEHICLES ) ;
2006-09-27 22:44:39 +00:00
}
}
2007-02-10 13:37:32 +00:00
const Sprite * GetAircraftSprite ( EngineID engine ) ;
2006-10-06 10:16:47 +00:00
/** Draw a vehicle in the depot window in the box with the top left corner at x,y
* @ 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
*/
static void DrawVehicleInDepot ( Window * w , const Vehicle * v , int x , int y )
{
byte diff_x = 0 , diff_y = 0 ;
2007-02-10 13:37:32 +00:00
int sprite_y = y + w - > resize . step_height - GetVehicleListHeight ( v - > type ) ;
2006-10-06 10:16:47 +00:00
switch ( v - > type ) {
case VEH_Train :
2007-02-10 13:37:32 +00:00
DrawTrainImage ( v , x + 21 , sprite_y , w - > widget [ DEPOT_WIDGET_MATRIX ] . right - 32 , w - > hscroll . pos , WP ( w , depot_d ) . sel ) ;
2006-10-06 10:16:47 +00:00
/* Number of wagons relative to a standard length wagon (rounded up) */
SetDParam ( 0 , ( v - > u . rail . cached_total_length + 7 ) / 8 ) ;
DrawStringRightAligned ( w - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 4 , STR_TINY_BLACK , 0 ) ; // Draw the counter
break ;
2007-02-10 13:37:32 +00:00
case VEH_Road : DrawRoadVehImage ( v , x + 24 , sprite_y , WP ( w , depot_d ) . sel ) ; break ;
case VEH_Ship : DrawShipImage ( v , x + 19 , sprite_y - 1 , WP ( w , depot_d ) . sel ) ; break ;
case VEH_Aircraft : {
const Sprite * spr = GetSprite ( GetAircraftImage ( v , DIR_W ) ) ;
2007-02-17 11:17:49 +00:00
DrawAircraftImage ( v , x + 12 ,
y + max ( spr - > height + spr - > y_offs - 14 , 0 ) , // tall sprites needs an y offset
WP ( w , depot_d ) . sel ) ;
2007-02-10 13:37:32 +00:00
} break ;
2006-10-06 10:16:47 +00:00
default : NOT_REACHED ( ) ;
}
if ( w - > 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 ;
}
2007-01-14 19:57:49 +00:00
DrawSprite ( ( v - > vehstatus & VS_STOPPED ) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING , PAL_NONE , x + diff_x , y + diff_y ) ;
2006-10-06 10:16:47 +00:00
SetDParam ( 0 , v - > unitnumber ) ;
DrawString ( x , y + 2 , ( uint16 ) ( v - > max_age - 366 ) > = v - > age ? STR_00E2 : STR_00E3 , 0 ) ;
}
2006-09-26 16:47:51 +00:00
static void DrawDepotWindow ( Window * w )
{
Vehicle * * vl = WP ( w , depot_d ) . vehicle_list ;
2006-10-03 02:08:15 +00:00
TileIndex tile = w - > window_number ;
2007-01-11 11:05:01 +00:00
int x , y , i , maxval ;
uint16 hnum ;
2006-09-26 16:47:51 +00:00
uint16 num = WP ( w , depot_d ) . engine_count ;
2006-10-06 10:16:47 +00:00
/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
uint16 rows_in_display = w - > widget [ DEPOT_WIDGET_MATRIX ] . data > > 8 ;
uint16 boxes_in_each_row = w - > widget [ DEPOT_WIDGET_MATRIX ] . data & 0xFF ;
2006-09-26 16:47:51 +00:00
/* setup disabled buttons */
2006-10-06 21:44:18 +00:00
SetWindowWidgetsDisabledState ( w , ! IsTileOwner ( tile , _local_player ) ,
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 ) ;
2006-09-26 16:47:51 +00:00
/* determine amount of items for scroller */
if ( WP ( w , depot_d ) . type = = VEH_Train ) {
hnum = 8 ;
for ( num = 0 ; num < WP ( w , depot_d ) . engine_count ; num + + ) {
const Vehicle * v = vl [ num ] ;
2007-01-11 11:05:01 +00:00
hnum = max ( hnum , v - > u . rail . cached_total_length ) ;
2006-09-26 16:47:51 +00:00
}
/* Always have 1 empty row, so people can change the setting of the train */
SetVScrollCount ( w , WP ( w , depot_d ) . engine_count + WP ( w , depot_d ) . wagon_count + 1 ) ;
SetHScrollCount ( w , WagonLengthToPixels ( hnum ) ) ;
} else {
SetVScrollCount ( w , ( num + w - > hscroll . cap - 1 ) / w - > hscroll . cap ) ;
}
/* locate the depot struct */
if ( WP ( w , depot_d ) . type = = VEH_Aircraft ) {
SetDParam ( 0 , GetStationIndex ( tile ) ) ; // Airport name
} else {
Depot * depot = GetDepotByTile ( tile ) ;
assert ( depot ! = NULL ) ;
SetDParam ( 0 , depot - > town_index ) ;
}
DrawWindowWidgets ( w ) ;
2006-10-06 10:16:47 +00:00
num = w - > vscroll . pos * boxes_in_each_row ;
2007-01-11 11:05:01 +00:00
maxval = min ( WP ( w , depot_d ) . engine_count , num + ( rows_in_display * boxes_in_each_row ) ) ;
2006-09-26 16:47:51 +00:00
2007-01-11 11:05:01 +00:00
for ( x = 2 , y = 15 ; num < maxval ; y + = w - > resize . step_height , x = 2 ) { // Draw the rows
2006-10-06 10:16:47 +00:00
byte i ;
2006-09-26 16:47:51 +00:00
2007-01-11 11:05:01 +00:00
for ( i = 0 ; i < boxes_in_each_row & & num < maxval ; i + + , num + + , x + = w - > resize . step_width ) {
2006-10-06 10:16:47 +00:00
/* Draw all vehicles in the current row */
const Vehicle * v = vl [ num ] ;
DrawVehicleInDepot ( w , v , x , y ) ;
2006-09-26 16:47:51 +00:00
}
}
2007-01-11 11:05:01 +00:00
maxval = min ( WP ( w , depot_d ) . engine_count + WP ( w , depot_d ) . wagon_count , ( w - > vscroll . pos * boxes_in_each_row ) + ( rows_in_display * boxes_in_each_row ) ) ;
2006-09-26 16:47:51 +00:00
/* draw the train wagons, that do not have an engine in front */
2007-01-11 11:05:01 +00:00
for ( ; num < maxval ; num + + , y + = 14 ) {
2006-09-26 16:47:51 +00:00
const Vehicle * v = WP ( w , depot_d ) . wagon_list [ num - WP ( w , depot_d ) . engine_count ] ;
const Vehicle * u ;
DrawTrainImage ( v , x + 50 , y , w - > hscroll . cap - 29 , 0 , WP ( w , depot_d ) . sel ) ;
DrawString ( x , y + 2 , STR_8816 , 0 ) ;
/*Draw the train counter */
i = 0 ;
u = v ;
do i + + ; while ( ( u = u - > next ) ! = NULL ) ; // Determine length of train
SetDParam ( 0 , i ) ; // Set the counter
DrawStringRightAligned ( w - > widget [ DEPOT_WIDGET_MATRIX ] . right - 1 , y + 4 , STR_TINY_BLACK , 0 ) ; // Draw the counter
}
}
typedef struct GetDepotVehiclePtData {
Vehicle * head ;
Vehicle * wagon ;
} GetDepotVehiclePtData ;
enum {
MODE_ERROR = 1 ,
MODE_DRAG_VEHICLE = 0 ,
MODE_SHOW_VEHICLE = - 1 ,
MODE_START_STOP = - 2 ,
} ;
static int GetVehicleFromDepotWndPt ( const Window * w , int x , int y , Vehicle * * veh , GetDepotVehiclePtData * d )
{
Vehicle * * vl = WP ( w , depot_d ) . vehicle_list ;
2006-09-27 00:25:27 +00:00
uint xt , row , xm = 0 , ym = 0 ;
2006-09-26 16:47:51 +00:00
int pos , skip = 0 ;
2006-10-06 22:08:37 +00:00
uint16 boxes_in_each_row = w - > widget [ DEPOT_WIDGET_MATRIX ] . data & 0xFF ;
2006-09-26 16:47:51 +00:00
if ( WP ( w , depot_d ) . type = = VEH_Train ) {
xt = 0 ;
x - = 23 ;
} else {
xt = x / w - > resize . step_width ;
xm = x % w - > resize . step_width ;
if ( xt > = w - > hscroll . cap ) return MODE_ERROR ;
ym = ( y - 14 ) % w - > resize . step_height ;
}
row = ( y - 14 ) / w - > resize . step_height ;
if ( row > = w - > vscroll . cap ) return MODE_ERROR ;
2006-10-06 22:08:37 +00:00
pos = ( ( row + w - > vscroll . pos ) * boxes_in_each_row ) + xt ;
2006-09-26 16:47:51 +00:00
2006-09-28 15:41:53 +00:00
if ( WP ( w , depot_d ) . engine_count + WP ( w , depot_d ) . wagon_count < = pos ) {
if ( WP ( w , depot_d ) . type = = VEH_Train ) {
d - > head = NULL ;
d - > wagon = NULL ;
return MODE_DRAG_VEHICLE ;
} else {
return MODE_ERROR ; // empty block, so no vehicle is selected
}
}
2006-09-26 16:47:51 +00:00
if ( WP ( w , depot_d ) . engine_count > pos ) {
* veh = vl [ pos ] ;
skip = w - > hscroll . pos ;
} else {
vl = WP ( w , depot_d ) . wagon_list ;
pos - = WP ( w , depot_d ) . engine_count ;
* veh = vl [ pos ] ;
/* free wagons don't have an initial loco. */
x - = _traininfo_vehicle_width ;
}
switch ( WP ( w , depot_d ) . type ) {
case VEH_Train : {
Vehicle * v = * veh ;
d - > head = d - > wagon = v ;
/* 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 ;
skip = ( skip * 8 ) / _traininfo_vehicle_width ;
x = ( x * 8 ) / _traininfo_vehicle_width ;
/* Skip vehicles that are scrolled off the list */
x + = skip ;
/* find the vehicle in this row that was clicked */
while ( v ! = NULL & & ( x - = v - > u . rail . cached_veh_length ) > = 0 ) v = v - > next ;
/* if an articulated part was selected, find its parent */
while ( v ! = NULL & & IsArticulatedPart ( v ) ) v = GetPrevVehicleInChain ( v ) ;
d - > wagon = v ;
return MODE_DRAG_VEHICLE ;
}
break ;
case VEH_Road :
if ( xm > = 24 ) return MODE_DRAG_VEHICLE ;
if ( xm < = 16 ) return MODE_SHOW_VEHICLE ;
break ;
case VEH_Ship :
if ( xm > = 19 ) return MODE_DRAG_VEHICLE ;
if ( ym < = 10 ) return MODE_SHOW_VEHICLE ;
break ;
case VEH_Aircraft :
if ( xm > = 12 ) return MODE_DRAG_VEHICLE ;
if ( ym < = 12 ) return MODE_SHOW_VEHICLE ;
break ;
default : NOT_REACHED ( ) ;
}
return MODE_START_STOP ;
}
static void TrainDepotMoveVehicle ( Vehicle * wagon , VehicleID sel , Vehicle * head )
{
Vehicle * v ;
v = GetVehicle ( sel ) ;
if ( v = = wagon ) return ;
if ( wagon = = NULL ) {
if ( head ! = NULL ) wagon = GetLastVehicleInChain ( head ) ;
} else {
wagon = GetPrevVehicleInChain ( wagon ) ;
if ( wagon = = NULL ) return ;
}
if ( wagon = = v ) return ;
DoCommandP ( v - > tile , v - > index + ( ( wagon = = NULL ? INVALID_VEHICLE : wagon - > index ) < < 16 ) , _ctrl_pressed ? 1 : 0 , NULL , CMD_MOVE_RAIL_VEHICLE | CMD_MSG ( STR_8837_CAN_T_MOVE_VEHICLE ) ) ;
}
static void DepotClick ( Window * w , int x , int y )
{
GetDepotVehiclePtData gdvp ;
Vehicle * v = NULL ;
int mode = GetVehicleFromDepotWndPt ( w , x , y , & v , & gdvp ) ;
/* share / copy orders */
if ( _thd . place_mode & & mode < = 0 ) {
_place_clicked_vehicle = ( WP ( w , depot_d ) . type = = VEH_Train ? gdvp . head : v ) ;
return ;
}
if ( WP ( w , depot_d ) . type = = VEH_Train ) v = gdvp . wagon ;
switch ( mode ) {
case MODE_ERROR : // invalid
return ;
case MODE_DRAG_VEHICLE : { // start dragging of vehicle
VehicleID sel = WP ( w , depot_d ) . sel ;
if ( WP ( w , depot_d ) . type = = VEH_Train & & sel ! = INVALID_VEHICLE ) {
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
TrainDepotMoveVehicle ( v , sel , gdvp . head ) ;
} else if ( v ! = NULL ) {
int image ;
switch ( WP ( w , depot_d ) . type ) {
case VEH_Train : image = GetTrainImage ( v , DIR_W ) ; break ;
case VEH_Road : image = GetRoadVehImage ( v , DIR_W ) ; break ;
case VEH_Ship : image = GetShipImage ( v , DIR_W ) ; break ;
case VEH_Aircraft : image = GetAircraftImage ( v , DIR_W ) ; break ;
default : NOT_REACHED ( ) ; image = 0 ;
}
WP ( w , depot_d ) . sel = v - > index ;
SetWindowDirty ( w ) ;
2007-01-14 19:57:49 +00:00
SetObjectToPlaceWnd ( image , GetVehiclePalette ( v ) , 4 , w ) ;
2006-09-26 16:47:51 +00:00
}
}
break ;
case MODE_SHOW_VEHICLE : // show info window
ShowVehicleViewWindow ( v ) ;
break ;
case MODE_START_STOP : { // click start/stop flag
uint command ;
switch ( WP ( w , depot_d ) . type ) {
case VEH_Train : command = CMD_START_STOP_TRAIN | CMD_MSG ( STR_883B_CAN_T_STOP_START_TRAIN ) ; break ;
case VEH_Road : command = CMD_START_STOP_ROADVEH | CMD_MSG ( STR_9015_CAN_T_STOP_START_ROAD_VEHICLE ) ; break ;
case VEH_Ship : command = CMD_START_STOP_SHIP | CMD_MSG ( STR_9818_CAN_T_STOP_START_SHIP ) ; break ;
case VEH_Aircraft : command = CMD_START_STOP_AIRCRAFT | CMD_MSG ( STR_A016_CAN_T_STOP_START_AIRCRAFT ) ; break ;
default : NOT_REACHED ( ) ; command = 0 ;
}
DoCommandP ( v - > tile , v - > index , 0 , NULL , command ) ;
}
break ;
default : NOT_REACHED ( ) ;
}
}
/**
* Clones a vehicle
* @ param * v is the original vehicle to clone
* @ param * w is the window of the depot where the clone is build
*/
static void HandleCloneVehClick ( const Vehicle * v , const Window * w )
{
uint error_str ;
if ( v = = NULL ) return ;
if ( v - > type = = VEH_Train & & ! IsFrontEngine ( v ) ) {
v = GetFirstVehicleInChain ( v ) ;
/* Do nothing when clicking on a train in depot with no loc attached */
if ( ! IsFrontEngine ( v ) ) return ;
}
switch ( v - > type ) {
case VEH_Train : error_str = CMD_MSG ( STR_882B_CAN_T_BUILD_RAILROAD_VEHICLE ) ; break ;
case VEH_Road : error_str = CMD_MSG ( STR_9009_CAN_T_BUILD_ROAD_VEHICLE ) ; break ;
case VEH_Ship : error_str = CMD_MSG ( STR_980D_CAN_T_BUILD_SHIP ) ; break ;
case VEH_Aircraft : error_str = CMD_MSG ( STR_A008_CAN_T_BUILD_AIRCRAFT ) ; break ;
default : return ;
}
DoCommandP ( w - > window_number , v - > index , _ctrl_pressed ? 1 : 0 , CcCloneVehicle , CMD_CLONE_VEHICLE | error_str ) ;
ResetObjectToPlace ( ) ;
}
static void ClonePlaceObj ( const Window * w )
{
const Vehicle * v = CheckMouseOverVehicle ( ) ;
if ( v ! = NULL ) HandleCloneVehClick ( v , w ) ;
}
2006-09-27 11:34:27 +00:00
static void ResizeDepotButtons ( Window * w )
{
2007-01-24 14:32:20 +00:00
ResizeButtons ( w , DEPOT_WIDGET_BUILD , DEPOT_WIDGET_LOCATION ) ;
2006-09-27 11:34:27 +00:00
if ( WP ( w , depot_d ) . type = = VEH_Train ) {
2006-09-27 22:44:39 +00:00
/* 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 ] . 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 ;
2006-09-27 11:34:27 +00:00
}
}
2006-12-07 00:51:20 +00: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
*/
static void SetupStringsForDepotWindow ( Window * w , byte type )
{
switch ( type ) {
case VEH_Train :
w - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_8800_TRAIN_DEPOT ;
w - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_TRAIN_TIP ;
w - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_TRAIN_TIP ;
w - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_8841_DRAG_TRAIN_VEHICLE_TO_HERE ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TIP ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . tooltips = STR_883F_TRAINS_CLICK_ON_TRAIN_FOR ;
w - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_8815_NEW_VEHICLES ;
w - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_8840_BUILD_NEW_TRAIN_VEHICLE ;
w - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_TRAIN ;
w - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_TRAIN_DEPOT_INFO ;
w - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_8842_CENTER_MAIN_VIEW_ON_TRAIN ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_TRAIN ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TIP ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_TRAIN_TIP ;
/* Sprites */
w - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_TRAIN ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_TRAIN ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_TRAIN ;
break ;
case VEH_Road :
w - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_9003_ROAD_VEHICLE_DEPOT ;
w - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_ROADVEH_TIP ;
w - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_ROADVEH_TIP ;
w - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_9024_DRAG_ROAD_VEHICLE_TO_HERE ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_ROADVEH_TIP ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . tooltips = STR_9022_VEHICLES_CLICK_ON_VEHICLE ;
w - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_9004_NEW_VEHICLES ;
w - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_9023_BUILD_NEW_ROAD_VEHICLE ;
w - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_ROAD_VEHICLE ;
w - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_ROAD_VEHICLE_DEPOT_INFO ;
w - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_9025_CENTER_MAIN_VIEW_ON_ROAD ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_LORRY ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_ROADVEH_TIP ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_ROADVEH_TIP ;
/* Sprites */
w - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_ROADVEH ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_ROADVEH ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_ROADVEH ;
break ;
case VEH_Ship :
w - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_9803_SHIP_DEPOT ;
w - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_DEPOT_SHIP_TIP ;
w - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_DEPOT_SHIP_TIP ;
w - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_9821_DRAG_SHIP_TO_HERE_TO_SELL ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_SHIP_TIP ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . tooltips = STR_981F_SHIPS_CLICK_ON_SHIP_FOR ;
w - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_9804_NEW_SHIPS ;
w - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_9820_BUILD_NEW_SHIP ;
w - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_SHIP ;
w - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_SHIP_DEPOT_INFO ;
w - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_9822_CENTER_MAIN_VIEW_ON_SHIP ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_SHIP ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TIP ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_SHIP_TIP ;
/* Sprites */
w - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_SHIP ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_SHIP ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_SHIP ;
break ;
case VEH_Aircraft :
w - > widget [ DEPOT_WIDGET_CAPTION ] . data = STR_A002_AIRCRAFT_HANGAR ;
w - > widget [ DEPOT_WIDGET_STOP_ALL ] . tooltips = STR_MASS_STOP_HANGAR_TIP ;
w - > widget [ DEPOT_WIDGET_START_ALL ] . tooltips = STR_MASS_START_HANGAR_TIP ;
w - > widget [ DEPOT_WIDGET_SELL ] . tooltips = STR_A023_DRAG_AIRCRAFT_TO_HERE_TO ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . tooltips = STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TIP ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . tooltips = STR_A021_AIRCRAFT_CLICK_ON_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_BUILD ] . data = STR_A003_NEW_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_BUILD ] . tooltips = STR_A022_BUILD_NEW_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_CLONE ] . data = STR_CLONE_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_CLONE ] . tooltips = STR_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW ;
w - > widget [ DEPOT_WIDGET_LOCATION ] . tooltips = STR_A024_CENTER_MAIN_VIEW_ON_HANGAR ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . data = STR_PLANE ;
w - > widget [ DEPOT_WIDGET_VEHICLE_LIST ] . tooltips = STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TIP ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . tooltips = STR_DEPOT_AUTOREPLACE_AIRCRAFT_TIP ;
/* Sprites */
w - > widget [ DEPOT_WIDGET_SELL ] . data = SPR_SELL_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_SELL_ALL ] . data = SPR_SELL_ALL_AIRCRAFT ;
w - > widget [ DEPOT_WIDGET_AUTOREPLACE ] . data = SPR_REPLACE_AIRCRAFT ;
break ;
}
}
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
* First part is the vehicle type , while the last is 0 = x , 1 = y */
const uint _resize_cap [ ] [ 2 ] = {
/* VEH_Train */ { 6 , 10 * 29 + 36 } , // flags, unitnumber and unit count uses a total of 36 pixels and we set default to 10 units
/* VEH_Road */ { 5 , 5 } ,
/* VEH_Ship */ { 3 , 3 } ,
/* VEH_Aircraft */ { 3 , 4 } ,
} ;
static void ResizeDefaultWindowSizeForTrains ( )
{
_block_sizes [ VEH_Train ] [ 0 ] = 1 ;
_block_sizes [ VEH_Train ] [ 1 ] = GetVehicleListHeight ( VEH_Train ) ;
}
static void ResizeDefaultWindowSizeForRoadVehicles ( )
{
_block_sizes [ VEH_Road ] [ 0 ] = 56 ;
_block_sizes [ VEH_Road ] [ 1 ] = GetVehicleListHeight ( VEH_Road ) ;
}
static void ResizeDefaultWindowSize ( byte type )
{
EngineID engine ;
uint max_width = 0 ;
uint max_height = 0 ;
FOR_ALL_ENGINEIDS_OF_TYPE ( engine , type ) {
uint x , y ;
switch ( type ) {
default : NOT_REACHED ( ) ;
case VEH_Ship : GetShipSpriteSize ( engine , x , y ) ; break ;
case VEH_Aircraft : GetAircraftSpriteSize ( engine , x , y ) ; break ;
}
if ( x > max_width ) max_width = x ;
if ( y > max_height ) max_height = y ;
}
switch ( type ) {
default : NOT_REACHED ( ) ;
case VEH_Ship :
_block_sizes [ VEH_Ship ] [ 0 ] = max ( 90U , max_width + 20 ) ; // we need 20 pixels from the right edge to the sprite
break ;
case VEH_Aircraft :
_block_sizes [ VEH_Aircraft ] [ 0 ] = max ( 74U , max_width ) ;
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 ( ) ;
ResizeDefaultWindowSize ( VEH_Ship ) ;
ResizeDefaultWindowSize ( VEH_Aircraft ) ;
}
2006-12-07 00:51:20 +00:00
static void CreateDepotListWindow ( Window * w , byte type )
{
WP ( w , depot_d ) . type = type ;
_backup_orders_tile = 0 ;
2007-02-10 13:37:32 +00:00
assert ( IsPlayerBuildableVehicleType ( type ) ) ; // ensure that we make the call with a valid type
2006-12-07 00:51:20 +00:00
/* Resize the window according to the vehicle type */
2007-02-10 13:37:32 +00:00
/* Set the number of blocks in each direction */
w - > vscroll . cap = _resize_cap [ type ] [ 0 ] ;
w - > hscroll . cap = _resize_cap [ type ] [ 1 ] ;
2006-12-07 00:51:20 +00:00
2007-02-10 13:37:32 +00:00
/* Set the block size */
w - > resize . step_width = _block_sizes [ type ] [ 0 ] ;
w - > resize . step_height = _block_sizes [ type ] [ 1 ] ;
2006-12-07 00:51:20 +00:00
2007-02-10 13:37:32 +00:00
/* Enlarge the window to fit with the selected number of blocks of the selected size */
ResizeWindow ( w ,
_block_sizes [ type ] [ 0 ] * w - > hscroll . cap ,
_block_sizes [ type ] [ 1 ] * w - > vscroll . cap ) ;
if ( type = = VEH_Train ) {
/* The train depot has a horizontal scroller so we should make room for it */
ResizeWindow ( w , 0 , 12 ) ;
/* substract the newly added space from the matrix since it was meant for the scrollbar */
w - > widget [ DEPOT_WIDGET_MATRIX ] . bottom - = 12 ;
2006-12-07 00:51:20 +00:00
}
/* Set the minimum window size to the current window size */
2007-02-10 13:37:32 +00:00
w - > resize . width = w - > width ;
2006-12-07 00:51:20 +00:00
w - > resize . height = w - > height ;
SetupStringsForDepotWindow ( w , type ) ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . data =
( w - > vscroll . cap * 0x100 ) // number of rows to draw on the background
+ ( type = = VEH_Train ? 1 : w - > hscroll . cap ) ; // number of boxes in each row. Trains always have just one
SetWindowWidgetsHiddenState ( w , type ! = VEH_Train ,
DEPOT_WIDGET_H_SCROLL ,
DEPOT_WIDGET_SELL_CHAIN ,
WIDGET_LIST_END ) ;
ResizeDepotButtons ( w ) ;
}
2006-10-05 13:11:17 +00:00
void DepotSortList ( Vehicle * * v , uint16 length ) ;
2006-09-26 16:47:51 +00:00
static void DepotWndProc ( Window * w , WindowEvent * e )
{
switch ( e - > event ) {
case WE_CREATE :
2006-12-07 00:51:20 +00:00
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
2006-10-05 12:59:28 +00:00
WP ( w , depot_d ) . vehicle_list = NULL ;
WP ( w , depot_d ) . wagon_list = NULL ;
WP ( w , depot_d ) . engine_count = 0 ;
WP ( w , depot_d ) . wagon_count = 0 ;
WP ( w , depot_d ) . generate_list = true ;
break ;
case WE_INVALIDATE_DATA :
WP ( w , depot_d ) . generate_list = true ;
2006-09-26 16:47:51 +00:00
break ;
case WE_PAINT :
2006-10-05 12:59:28 +00:00
if ( WP ( w , depot_d ) . generate_list ) {
/* Generate the vehicle list
* It ' s ok to use the wagon pointers for non - trains as they will be ignored */
BuildDepotVehicleList ( WP ( w , depot_d ) . type , w - > window_number ,
& WP ( w , depot_d ) . vehicle_list , & WP ( w , depot_d ) . engine_list_length , & WP ( w , depot_d ) . engine_count ,
& WP ( w , depot_d ) . wagon_list , & WP ( w , depot_d ) . wagon_list_length , & WP ( w , depot_d ) . wagon_count ) ;
WP ( w , depot_d ) . generate_list = false ;
2006-10-05 13:11:17 +00:00
DepotSortList ( WP ( w , depot_d ) . vehicle_list , WP ( w , depot_d ) . engine_count ) ;
2006-10-07 08:39:34 +00:00
//#ifndef NDEBUG
#if 0
/* We disabled this check for now, but will keep it to quickly make this test again later (if we change some code) */
2006-10-05 12:59:28 +00:00
} else {
/* Here we got a piece of code, that only checks if we got a different number of vehicles in the depot list and the number of vehicles actually being in the depot.
* IF they aren ' t the same , then WE_INVALIDATE_DATA should have been called somewhere , but it wasn ' t and we got a bug
* Since this is a time consuming check and not nice to memory fragmentation , it may not stay for long , but it ' s a good way to check this
* We can turn it on / off by switching between # ifndef NDEBUG and # if 0 */
Vehicle * * engines = NULL , * * wagons = NULL ;
uint16 engine_count = 0 , engine_length = 0 ;
uint16 wagon_count = 0 , wagon_length = 0 ;
BuildDepotVehicleList ( WP ( w , depot_d ) . type , w - > window_number , & engines , & engine_length , & engine_count ,
& wagons , & wagon_length , & wagon_count ) ;
assert ( engine_count = = WP ( w , depot_d ) . engine_count ) ;
assert ( wagon_count = = WP ( w , depot_d ) . wagon_count ) ;
free ( ( void * ) engines ) ;
free ( ( void * ) wagons ) ;
# endif
}
2006-09-26 16:47:51 +00:00
DrawDepotWindow ( w ) ;
break ;
case WE_CLICK :
switch ( e - > we . click . widget ) {
case DEPOT_WIDGET_MATRIX : // List
DepotClick ( w , e - > we . click . pt . x , e - > we . click . pt . y ) ;
break ;
case DEPOT_WIDGET_BUILD : // Build vehicle
ResetObjectToPlace ( ) ;
2007-01-22 02:09:51 +00:00
ShowBuildVehicleWindow ( w - > window_number , WP ( w , depot_d ) . type ) ;
2006-09-26 16:47:51 +00:00
break ;
case DEPOT_WIDGET_CLONE : // Clone button
InvalidateWidget ( w , DEPOT_WIDGET_CLONE ) ;
2006-10-05 02:29:01 +00:00
ToggleWidgetLoweredState ( w , DEPOT_WIDGET_CLONE ) ;
2006-09-26 16:47:51 +00:00
2006-10-05 02:29:01 +00:00
if ( IsWindowWidgetLowered ( w , DEPOT_WIDGET_CLONE ) ) {
2006-10-24 12:56:14 +00:00
static const CursorID clone_icons [ ] = {
SPR_CURSOR_CLONE_TRAIN , SPR_CURSOR_CLONE_ROADVEH ,
SPR_CURSOR_CLONE_SHIP , SPR_CURSOR_CLONE_AIRPLANE
} ;
2006-09-26 16:47:51 +00:00
_place_clicked_vehicle = NULL ;
2007-02-07 19:10:19 +00:00
SetObjectToPlaceWnd ( clone_icons [ WP ( w , depot_d ) . type ] , PAL_NONE , VHM_RECT , w ) ;
2006-09-26 16:47:51 +00:00
} else {
ResetObjectToPlace ( ) ;
}
break ;
case DEPOT_WIDGET_LOCATION : ScrollMainWindowToTile ( w - > window_number ) ; break ;
2006-09-26 19:20:35 +00:00
case DEPOT_WIDGET_STOP_ALL :
case DEPOT_WIDGET_START_ALL :
2006-10-07 08:24:11 +00:00
DoCommandP ( w - > window_number , 0 , WP ( w , depot_d ) . type | ( e - > we . click . widget = = DEPOT_WIDGET_START_ALL ? ( 1 < < 5 ) : 0 ) , NULL , CMD_MASS_START_STOP ) ;
2006-09-26 19:20:35 +00:00
break ;
2006-09-27 22:44:39 +00:00
case DEPOT_WIDGET_SELL_ALL :
2006-09-30 23:53:35 +00:00
/* Only open the confimation window if there are anything to sell */
if ( WP ( w , depot_d ) . engine_count ! = 0 | | WP ( w , depot_d ) . wagon_count ! = 0 ) {
2006-12-29 17:56:34 +00:00
static const StringID confirm_captions [ ] = {
STR_8800_TRAIN_DEPOT ,
STR_9003_ROAD_VEHICLE_DEPOT ,
STR_9803_SHIP_DEPOT ,
STR_A002_AIRCRAFT_HANGAR
} ;
TileIndex tile = w - > window_number ;
2007-01-01 18:54:18 +00:00
byte vehtype = WP ( w , depot_d ) . type ;
2006-12-29 17:56:34 +00:00
SetDParam ( 0 , ( vehtype = = VEH_Aircraft ) ? GetStationIndex ( tile ) : GetDepotByTile ( tile ) - > town_index ) ;
ShowQuery (
2007-02-07 19:10:19 +00:00
confirm_captions [ vehtype ] ,
2006-12-29 17:56:34 +00:00
STR_DEPOT_SELL_CONFIRMATION_TEXT ,
w ,
DepotSellAllConfirmationCallback
) ;
2006-09-30 23:53:35 +00:00
}
2006-09-27 22:44:39 +00:00
break ;
2006-09-30 13:39:34 +00:00
case DEPOT_WIDGET_VEHICLE_LIST :
2007-01-21 00:01:47 +00:00
ShowVehicleListWindow ( GetTileOwner ( w - > window_number ) , WP ( w , depot_d ) . type , ( TileIndex ) w - > window_number ) ;
2006-09-30 13:39:34 +00:00
break ;
2006-09-28 14:17:08 +00:00
case DEPOT_WIDGET_AUTOREPLACE :
DoCommandP ( w - > window_number , WP ( w , depot_d ) . type , 0 , NULL , CMD_DEPOT_MASS_AUTOREPLACE ) ;
break ;
2006-09-26 16:47:51 +00:00
}
break ;
case WE_PLACE_OBJ : {
ClonePlaceObj ( w ) ;
} break ;
case WE_ABORT_PLACE_OBJ : {
2006-10-03 20:16:20 +00:00
RaiseWindowWidget ( w , DEPOT_WIDGET_CLONE ) ;
2006-09-26 16:47:51 +00:00
InvalidateWidget ( w , DEPOT_WIDGET_CLONE ) ;
} break ;
/* check if a vehicle in a depot was clicked.. */
case WE_MOUSELOOP : {
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 */
2006-10-03 20:16:20 +00:00
if ( v ! = NULL & & IsWindowWidgetLowered ( w , DEPOT_WIDGET_CLONE ) ) {
2006-09-26 16:47:51 +00:00
_place_clicked_vehicle = NULL ;
HandleCloneVehClick ( v , w ) ;
}
} break ;
case WE_DESTROY :
DeleteWindowById ( WC_BUILD_VEHICLE , w - > window_number ) ;
free ( ( void * ) WP ( w , depot_d ) . vehicle_list ) ;
free ( ( void * ) WP ( w , depot_d ) . wagon_list ) ;
break ;
case WE_DRAGDROP :
switch ( e - > we . click . widget ) {
case DEPOT_WIDGET_MATRIX : {
Vehicle * v ;
VehicleID sel = WP ( w , depot_d ) . sel ;
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
SetWindowDirty ( w ) ;
if ( WP ( w , depot_d ) . type = = VEH_Train ) {
GetDepotVehiclePtData gdvp ;
2006-09-28 15:41:53 +00:00
if ( GetVehicleFromDepotWndPt ( w , e - > we . dragdrop . pt . x , e - > we . dragdrop . pt . y , & v , & gdvp ) = = MODE_DRAG_VEHICLE & &
2006-09-26 16:47:51 +00:00
sel ! = INVALID_VEHICLE ) {
if ( gdvp . wagon ! = NULL & & gdvp . wagon - > index = = sel & & _ctrl_pressed ) {
DoCommandP ( GetVehicle ( sel ) - > tile , GetVehicle ( sel ) - > index , true , NULL , CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG ( STR_9033_CAN_T_MAKE_VEHICLE_TURN ) ) ;
} else if ( gdvp . wagon = = NULL | | gdvp . wagon - > index ! = sel ) {
TrainDepotMoveVehicle ( gdvp . wagon , sel , gdvp . head ) ;
} else if ( gdvp . head ! = NULL & & IsFrontEngine ( gdvp . head ) ) {
ShowTrainViewWindow ( gdvp . head ) ;
}
}
2006-09-28 15:41:53 +00:00
} else if ( GetVehicleFromDepotWndPt ( w , e - > we . dragdrop . pt . x , e - > we . dragdrop . pt . y , & v , NULL ) = = MODE_DRAG_VEHICLE & &
2006-09-26 16:47:51 +00:00
v ! = NULL & &
sel = = v - > index ) {
ShowVehicleViewWindow ( v ) ;
}
} break ;
2006-09-27 22:44:39 +00:00
case DEPOT_WIDGET_SELL : case DEPOT_WIDGET_SELL_CHAIN :
2006-10-03 02:08:15 +00:00
if ( ! IsWindowWidgetDisabled ( w , DEPOT_WIDGET_SELL ) & &
2006-09-26 16:47:51 +00:00
WP ( w , depot_d ) . sel ! = INVALID_VEHICLE ) {
Vehicle * v ;
uint command ;
int sell_cmd ;
bool is_engine ;
2006-10-03 02:08:15 +00:00
if ( IsWindowWidgetDisabled ( w , e - > we . click . widget ) ) return ;
2006-09-26 16:47:51 +00:00
if ( WP ( w , depot_d ) . sel = = INVALID_VEHICLE ) return ;
HandleButtonClick ( w , e - > we . click . widget ) ;
v = GetVehicle ( WP ( w , depot_d ) . sel ) ;
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
SetWindowDirty ( w ) ;
2006-09-27 22:44:39 +00:00
sell_cmd = ( v - > type = = VEH_Train & & ( e - > we . click . widget = = DEPOT_WIDGET_SELL_CHAIN | | _ctrl_pressed ) ) ? 1 : 0 ;
2006-09-26 16:47:51 +00:00
is_engine = ( ! ( v - > type = = VEH_Train & & ! IsFrontEngine ( v ) ) ) ;
if ( is_engine ) {
_backup_orders_tile = v - > tile ;
BackupVehicleOrders ( v , _backup_orders_data ) ;
}
switch ( v - > type ) {
case VEH_Train : command = CMD_SELL_RAIL_WAGON | CMD_MSG ( STR_8839_CAN_T_SELL_RAILROAD_VEHICLE ) ; break ;
case VEH_Road : command = CMD_SELL_ROAD_VEH | CMD_MSG ( STR_9014_CAN_T_SELL_ROAD_VEHICLE ) ; break ;
case VEH_Ship : command = CMD_SELL_SHIP | CMD_MSG ( STR_980C_CAN_T_SELL_SHIP ) ; break ;
case VEH_Aircraft : command = CMD_SELL_AIRCRAFT | CMD_MSG ( STR_A01C_CAN_T_SELL_AIRCRAFT ) ; break ;
default : NOT_REACHED ( ) ; command = 0 ;
}
if ( ! DoCommandP ( v - > tile , v - > index , sell_cmd , NULL , command ) & & is_engine ) _backup_orders_tile = 0 ;
}
break ;
default :
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
SetWindowDirty ( w ) ;
}
break ;
case WE_RESIZE :
w - > vscroll . cap + = e - > we . sizing . diff . y / ( int ) w - > resize . step_height ;
w - > hscroll . cap + = e - > we . sizing . diff . x / ( int ) w - > resize . step_width ;
w - > widget [ DEPOT_WIDGET_MATRIX ] . data = ( w - > vscroll . cap < < 8 ) + ( WP ( w , depot_d ) . type = = VEH_Train ? 1 : w - > hscroll . cap ) ;
2006-09-27 11:34:27 +00:00
ResizeDepotButtons ( w ) ;
2006-09-26 16:47:51 +00:00
break ;
}
}
/** Opens a depot window
* @ param tile The tile where the depot / hangar is located
* @ param type The type of vehicles in the depot
*/
void ShowDepotWindow ( TileIndex tile , byte type )
{
Window * w ;
switch ( type ) {
2006-12-07 00:51:20 +00:00
default : NOT_REACHED ( ) ;
case VEH_Train :
w = AllocateWindowDescFront ( & _train_depot_desc , tile ) ; break ;
case VEH_Road :
w = AllocateWindowDescFront ( & _road_depot_desc , tile ) ; break ;
case VEH_Ship :
w = AllocateWindowDescFront ( & _ship_depot_desc , tile ) ; break ;
case VEH_Aircraft :
w = AllocateWindowDescFront ( & _aircraft_depot_desc , tile ) ; break ;
2006-09-26 16:47:51 +00:00
}
if ( w ! = NULL ) {
w - > caption_color = GetTileOwner ( tile ) ;
2006-12-07 00:51:20 +00:00
CreateDepotListWindow ( w , type ) ;
2006-09-26 16:47:51 +00: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 )
{
2006-12-06 17:31:16 +00:00
Window * 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
* If that is the case , we can skip looping though the windows and save time */
if ( _special_mouse_mode ! = WSM_DRAGDROP ) return ;
2006-12-06 17:31:16 +00:00
w = FindWindowById ( WC_VEHICLE_DEPOT , v - > tile ) ;
if ( w ! = NULL ) {
WP ( w , depot_d ) . sel = INVALID_VEHICLE ;
ResetObjectToPlace ( ) ;
2006-12-05 22:40:42 +00:00
}
}