2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 15:11:33 +00:00
/** @file vehicle_gui.cpp The base GUI for all vehicles. */
2007-04-04 04:08:47 +00:00
2004-09-06 18:15:13 +00:00
# include "stdafx.h"
2005-02-05 15:58:59 +00:00
# include "debug.h"
2008-09-30 20:51:04 +00:00
# include "company_func.h"
2005-01-02 17:23:04 +00:00
# include "gui.h"
2007-12-19 20:45:46 +00:00
# include "textbuf_gui.h"
2007-12-21 21:50:46 +00:00
# include "command_func.h"
2008-09-13 10:04:36 +00:00
# include "vehicle_gui_base.h"
2008-01-09 09:45:45 +00:00
# include "viewport_func.h"
2006-04-23 22:33:10 +00:00
# include "newgrf_text.h"
2010-04-24 13:39:11 +00:00
# include "newgrf_debug.h"
2006-08-29 17:41:13 +00:00
# include "roadveh.h"
2009-05-22 22:22:46 +00:00
# include "train.h"
2009-07-13 16:37:27 +00:00
# include "aircraft.h"
2010-08-26 22:01:16 +00:00
# include "depot_map.h"
2007-12-21 07:38:36 +00:00
# include "group_gui.h"
2007-12-21 19:49:27 +00:00
# include "strings_func.h"
2007-12-27 13:35:39 +00:00
# include "vehicle_func.h"
2008-01-07 09:19:53 +00:00
# include "autoreplace_gui.h"
2008-01-07 14:23:25 +00:00
# include "string_func.h"
2008-01-14 16:10:58 +00:00
# include "widgets/dropdown_func.h"
2008-05-06 22:17:12 +00:00
# include "timetable.h"
2009-02-27 20:40:39 +00:00
# include "articulated_vehicles.h"
2009-11-17 15:05:12 +00:00
# include "spritecache.h"
2010-01-15 16:41:15 +00:00
# include "core/geometry_func.hpp"
# include "company_base.h"
# include "engine_func.h"
2010-06-11 00:18:28 +00:00
# include "station_base.h"
2010-09-06 14:14:09 +00:00
# include "tilehighlight_func.h"
2011-11-24 12:38:48 +00:00
# include "zoom_func.h"
2005-07-21 22:15:02 +00:00
2014-04-23 20:13:33 +00:00
# include "safeguards.h"
2019-01-11 08:09:37 +00:00
# include <algorithm>
BaseVehicleListWindow : : GroupBy _grouping [ VLT_END ] [ VEH_COMPANY_END ] ;
Sorting _sorting [ BaseVehicleListWindow : : GB_END ] ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleNumberSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleNameSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleAgeSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleProfitThisYearSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleProfitLastYearSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleCargoSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleReliabilitySorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleMaxSpeedSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleModelSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleValueSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleLengthSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleTimeToLiveSorter ;
static BaseVehicleListWindow : : VehicleIndividualSortFunction VehicleTimetableDelaySorter ;
/** Wrapper to convert a VehicleIndividualSortFunction to a VehicleGroupSortFunction */
template < BaseVehicleListWindow : : VehicleIndividualSortFunction func >
static bool VehicleIndividualToGroupSorterWrapper ( GUIVehicleGroup const & a , GUIVehicleGroup const & b )
{
return func ( * ( a . vehicles_begin ) , * ( b . vehicles_begin ) ) ;
}
2008-01-13 01:21:35 +00:00
2019-01-11 08:09:37 +00:00
BaseVehicleListWindow : : VehicleGroupSortFunction * const BaseVehicleListWindow : : vehicle_group_none_sorter_funcs [ ] = {
& VehicleIndividualToGroupSorterWrapper < VehicleNumberSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleNameSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleAgeSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleProfitThisYearSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleProfitLastYearSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleCargoSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleReliabilitySorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleMaxSpeedSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleModelSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleValueSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleLengthSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleTimeToLiveSorter > ,
& VehicleIndividualToGroupSorterWrapper < VehicleTimetableDelaySorter > ,
2004-11-25 06:05:47 +00:00
} ;
2019-01-11 08:09:37 +00:00
const StringID BaseVehicleListWindow : : vehicle_group_none_sorter_names [ ] = {
2004-11-25 06:05:47 +00:00
STR_SORT_BY_NUMBER ,
2009-07-23 19:31:50 +00:00
STR_SORT_BY_NAME ,
2004-11-25 06:05:47 +00:00
STR_SORT_BY_AGE ,
STR_SORT_BY_PROFIT_THIS_YEAR ,
STR_SORT_BY_PROFIT_LAST_YEAR ,
STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE ,
STR_SORT_BY_RELIABILITY ,
STR_SORT_BY_MAX_SPEED ,
2006-02-03 18:32:59 +00:00
STR_SORT_BY_MODEL ,
STR_SORT_BY_VALUE ,
2008-04-18 10:58:11 +00:00
STR_SORT_BY_LENGTH ,
2008-09-17 02:30:24 +00:00
STR_SORT_BY_LIFE_TIME ,
2009-08-15 10:51:33 +00:00
STR_SORT_BY_TIMETABLE_DELAY ,
2004-11-25 06:05:47 +00:00
INVALID_STRING_ID
} ;
2010-07-17 14:53:46 +00:00
const StringID BaseVehicleListWindow : : vehicle_depot_name [ ] = {
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT ,
STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR
} ;
2019-01-11 08:09:37 +00:00
BaseVehicleListWindow : : BaseVehicleListWindow ( WindowDesc * desc , WindowNumber wno ) : Window ( desc ) , vli ( VehicleListIdentifier : : UnPack ( wno ) )
{
this - > grouping = _grouping [ vli . type ] [ vli . vtype ] ;
this - > UpdateSortingFromGrouping ( ) ;
}
/**
* Get the number of digits of space required for the given number .
* @ param number The number .
* @ return The number of digits to allocate space for .
*/
uint CountDigitsForAllocatingSpace ( uint number )
{
if ( number > = 10000 ) return 5 ;
if ( number > = 1000 ) return 4 ;
if ( number > = 100 ) return 3 ;
/*
* When the smallest unit number is less than 10 , it is
* quite likely that it will expand to become more than
* 10 quite soon .
*/
return 2 ;
}
2014-10-14 11:23:41 +00:00
/**
* Get the number of digits the biggest unit number of a set of vehicles has .
* @ param vehicles The list of vehicles .
* @ return The number of digits to allocate space for .
*/
uint GetUnitNumberDigits ( VehicleList & vehicles )
{
uint unitnumber = 0 ;
2019-02-17 11:20:52 +00:00
for ( const Vehicle * v : vehicles ) {
unitnumber = max < uint > ( unitnumber , v - > unitnumber ) ;
2014-10-14 11:23:41 +00:00
}
2019-01-11 08:09:37 +00:00
return CountDigitsForAllocatingSpace ( unitnumber ) ;
2014-10-14 11:23:41 +00:00
}
2010-09-09 14:40:39 +00:00
void BaseVehicleListWindow : : BuildVehicleList ( )
2004-12-10 18:16:08 +00:00
{
2019-01-11 08:09:37 +00:00
if ( ! this - > vehgroups . NeedRebuild ( ) ) return ;
2004-12-10 18:16:08 +00:00
2010-09-09 14:40:39 +00:00
DEBUG ( misc , 3 , " Building vehicle list type %d for company %d given index %d " , this - > vli . type , this - > vli . company , this - > vli . index ) ;
2004-12-10 18:16:08 +00:00
2019-01-11 08:09:37 +00:00
this - > vehgroups . clear ( ) ;
2010-09-09 14:40:39 +00:00
GenerateVehicleSortList ( & this - > vehicles , this - > vli ) ;
2004-12-10 18:16:08 +00:00
2019-01-11 08:09:37 +00:00
uint max_unitnumber = 0 ;
for ( auto it = this - > vehicles . begin ( ) ; it ! = this - > vehicles . end ( ) ; + + it ) {
this - > vehgroups . emplace_back ( it , it + 1 , ( * it ) - > GetDisplayProfitThisYear ( ) , ( * it ) - > GetDisplayProfitLastYear ( ) , ( * it ) - > age ) ;
max_unitnumber = max < uint > ( max_unitnumber , ( * it ) - > unitnumber ) ;
}
this - > unitnumber_digits = CountDigitsForAllocatingSpace ( max_unitnumber ) ;
2009-11-17 09:09:20 +00:00
2019-01-11 08:09:37 +00:00
this - > vehgroups . RebuildDone ( ) ;
this - > vscroll - > SetCount ( this - > vehgroups . size ( ) ) ;
2004-12-10 18:16:08 +00:00
}
2010-07-17 14:47:54 +00:00
/**
* Compute the size for the Action dropdown .
2010-07-17 14:58:35 +00:00
* @ param show_autoreplace If true include the autoreplace item .
2010-07-17 14:47:54 +00:00
* @ param show_group If true include group - related stuff .
* @ return Required size .
*/
2010-07-17 14:58:35 +00:00
Dimension BaseVehicleListWindow : : GetActionDropdownSize ( bool show_autoreplace , bool show_group )
2010-07-17 14:47:54 +00:00
{
Dimension d = { 0 , 0 } ;
2010-07-17 14:58:35 +00:00
if ( show_autoreplace ) d = maxdim ( d , GetStringBoundingBox ( STR_VEHICLE_LIST_REPLACE_VEHICLES ) ) ;
2010-07-17 14:47:54 +00:00
d = maxdim ( d , GetStringBoundingBox ( STR_VEHICLE_LIST_SEND_FOR_SERVICING ) ) ;
2010-09-09 14:40:39 +00:00
d = maxdim ( d , GetStringBoundingBox ( this - > vehicle_depot_name [ this - > vli . vtype ] ) ) ;
2010-07-17 14:47:54 +00:00
if ( show_group ) {
d = maxdim ( d , GetStringBoundingBox ( STR_GROUP_ADD_SHARED_VEHICLE ) ) ;
d = maxdim ( d , GetStringBoundingBox ( STR_GROUP_REMOVE_ALL_VEHICLES ) ) ;
}
return d ;
}
2010-07-17 14:36:36 +00:00
/**
* Display the Action dropdown window .
2010-07-17 14:58:35 +00:00
* @ param show_autoreplace If true include the autoreplace item .
2010-07-17 14:36:36 +00:00
* @ param show_group If true include group - related stuff .
* @ return Itemlist for dropdown
*/
2019-04-02 19:31:24 +00:00
DropDownList BaseVehicleListWindow : : BuildActionDropdownList ( bool show_autoreplace , bool show_group )
2010-07-17 14:36:36 +00:00
{
2019-04-02 19:31:24 +00:00
DropDownList list ;
2010-07-17 14:36:36 +00:00
2019-04-02 19:31:24 +00:00
if ( show_autoreplace ) list . emplace_back ( new DropDownListStringItem ( STR_VEHICLE_LIST_REPLACE_VEHICLES , ADI_REPLACE , false ) ) ;
list . emplace_back ( new DropDownListStringItem ( STR_VEHICLE_LIST_SEND_FOR_SERVICING , ADI_SERVICE , false ) ) ;
list . emplace_back ( new DropDownListStringItem ( this - > vehicle_depot_name [ this - > vli . vtype ] , ADI_DEPOT , false ) ) ;
2010-07-17 14:36:36 +00:00
if ( show_group ) {
2019-04-02 19:31:24 +00:00
list . emplace_back ( new DropDownListStringItem ( STR_GROUP_ADD_SHARED_VEHICLE , ADI_ADD_SHARED , false ) ) ;
list . emplace_back ( new DropDownListStringItem ( STR_GROUP_REMOVE_ALL_VEHICLES , ADI_REMOVE_ALL , false ) ) ;
2010-07-17 14:36:36 +00:00
}
return list ;
}
2008-03-02 00:25:54 +00:00
/* cached values for VehicleNameSorter to spare many GetString() calls */
2019-04-10 21:07:06 +00:00
static const Vehicle * _last_vehicle [ 2 ] = { nullptr , nullptr } ;
2008-03-02 00:25:54 +00:00
2008-09-13 10:04:36 +00:00
void BaseVehicleListWindow : : SortVehicleList ( )
2004-12-10 18:16:08 +00:00
{
2019-01-11 08:09:37 +00:00
if ( this - > vehgroups . Sort ( ) ) return ;
2004-12-10 18:16:08 +00:00
2008-03-02 00:25:54 +00:00
/* invalidate cached values for name sorter - vehicle names could change */
2019-04-10 21:07:06 +00:00
_last_vehicle [ 0 ] = _last_vehicle [ 1 ] = nullptr ;
2004-12-10 18:16:08 +00:00
}
2008-05-25 17:22:49 +00:00
void DepotSortList ( VehicleList * list )
2006-10-05 13:11:17 +00:00
{
2018-09-23 11:23:54 +00:00
if ( list - > size ( ) < 2 ) return ;
2019-04-11 19:26:02 +00:00
std : : sort ( list - > begin ( ) , list - > end ( ) , & VehicleNumberSorter ) ;
2006-10-05 13:11:17 +00:00
}
2004-12-10 18:16:08 +00:00
2007-04-04 04:08:47 +00:00
/** draw the vehicle profit button in the vehicle list window. */
2019-01-11 08:09:37 +00:00
static void DrawVehicleProfitButton ( Date age , Money display_profit_last_year , uint num_vehicles , int x , int y )
2004-09-06 18:15:13 +00:00
{
2010-09-02 20:00:48 +00:00
SpriteID spr ;
2004-09-06 18:15:13 +00:00
2009-02-09 02:57:15 +00:00
/* draw profit-based coloured icons */
2019-01-11 08:09:37 +00:00
if ( age < = VEHICLE_PROFIT_MIN_AGE ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_NA ;
2019-01-11 08:09:37 +00:00
} else if ( display_profit_last_year < 0 ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_NEGATIVE ;
2019-01-11 08:09:37 +00:00
} else if ( display_profit_last_year < VEHICLE_PROFIT_THRESHOLD * num_vehicles ) {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_SOME ;
2005-11-14 19:48:04 +00:00
} else {
2010-09-02 20:00:48 +00:00
spr = SPR_PROFIT_LOT ;
2005-11-14 19:48:04 +00:00
}
2010-09-02 20:00:48 +00:00
DrawSprite ( spr , PAL_NONE , x , y ) ;
2004-09-06 18:15:13 +00:00
}
2010-01-10 20:33:10 +00:00
/** Maximum number of refit cycles we try, to prevent infinite loops. And we store only a byte anyway */
static const uint MAX_REFIT_CYCLE = 256 ;
2009-12-13 22:19:19 +00:00
2009-12-14 19:17:18 +00:00
/**
2011-12-10 21:09:21 +00:00
* Get the best fitting subtype when ' cloning ' / ' replacing ' \ a v_from with \ a v_for .
* All articulated parts of both vehicles are tested to find a possibly shared subtype .
* For \ a v_for only vehicle refittable to \ a dest_cargo_type are considered .
2009-12-14 19:17:18 +00:00
* @ param v_from the vehicle to match the subtype from
* @ param v_for the vehicle to get the subtype for
2011-12-10 21:09:21 +00:00
* @ param dest_cargo_type Destination cargo type .
2009-12-14 19:17:18 +00:00
* @ return the best sub type
*/
2011-11-04 15:04:24 +00:00
byte GetBestFittingSubType ( Vehicle * v_from , Vehicle * v_for , CargoID dest_cargo_type )
2009-12-14 19:17:18 +00:00
{
2011-12-10 21:09:21 +00:00
v_from = v_from - > GetFirstEnginePart ( ) ;
v_for = v_for - > GetFirstEnginePart ( ) ;
/* Create a list of subtypes used by the various parts of v_for */
2019-03-03 17:30:09 +00:00
static std : : vector < StringID > subtypes ;
2018-09-20 22:44:14 +00:00
subtypes . clear ( ) ;
2019-04-10 21:07:06 +00:00
for ( ; v_from ! = nullptr ; v_from = v_from - > HasArticulatedPart ( ) ? v_from - > GetNextArticulatedPart ( ) : nullptr ) {
2011-12-10 21:09:21 +00:00
const Engine * e_from = v_from - > GetEngine ( ) ;
if ( ! e_from - > CanCarryCargo ( ) | | ! HasBit ( e_from - > info . callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) continue ;
2019-02-20 21:35:41 +00:00
include ( subtypes , GetCargoSubtypeText ( v_from ) ) ;
2009-12-14 19:17:18 +00:00
}
byte ret_refit_cyc = 0 ;
2011-12-10 21:09:21 +00:00
bool success = false ;
2018-09-23 11:23:54 +00:00
if ( subtypes . size ( ) > 0 ) {
2011-12-10 21:09:21 +00:00
/* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */
2019-04-10 21:07:06 +00:00
for ( Vehicle * v = v_for ; v ! = nullptr ; v = v - > HasArticulatedPart ( ) ? v - > GetNextArticulatedPart ( ) : nullptr ) {
2011-12-10 21:09:21 +00:00
const Engine * e = v - > GetEngine ( ) ;
if ( ! e - > CanCarryCargo ( ) | | ! HasBit ( e - > info . callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) continue ;
if ( ! HasBit ( e - > info . refit_mask , dest_cargo_type ) & & v - > cargo_type ! = dest_cargo_type ) continue ;
CargoID old_cargo_type = v - > cargo_type ;
byte old_cargo_subtype = v - > cargo_subtype ;
/* Set the 'destination' cargo */
v - > cargo_type = dest_cargo_type ;
/* Cycle through the refits */
for ( uint refit_cyc = 0 ; refit_cyc < MAX_REFIT_CYCLE ; refit_cyc + + ) {
v - > cargo_subtype = refit_cyc ;
/* Make sure we don't pick up anything cached. */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
2013-02-24 16:42:30 +00:00
StringID subtype = GetCargoSubtypeText ( v ) ;
if ( subtype = = STR_EMPTY ) break ;
2011-12-10 21:09:21 +00:00
2019-02-12 22:59:12 +00:00
if ( std : : find ( subtypes . begin ( ) , subtypes . end ( ) , subtype ) = = subtypes . end ( ) ) continue ;
2011-12-10 21:09:21 +00:00
/* We found something matching. */
ret_refit_cyc = refit_cyc ;
success = true ;
break ;
}
/* Reset the vehicle's cargo type */
v - > cargo_type = old_cargo_type ;
v - > cargo_subtype = old_cargo_subtype ;
/* Make sure we don't taint the vehicle. */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
if ( success ) break ;
2011-11-08 17:24:43 +00:00
}
2009-12-14 19:17:18 +00:00
}
return ret_refit_cyc ;
}
2010-01-10 21:45:32 +00:00
/** Option to refit a vehicle chain */
2007-03-07 12:11:48 +00:00
struct RefitOption {
2010-01-10 21:45:32 +00:00
CargoID cargo ; ///< Cargo to refit to
byte subtype ; ///< Subcargo to use
2013-02-24 16:42:30 +00:00
StringID string ; ///< GRF-local String to display for the cargo
2006-10-01 12:00:32 +00:00
2010-08-13 14:24:47 +00:00
/**
* Inequality operator for # RefitOption .
* @ param other Compare to this # RefitOption .
* @ return True if both # RefitOption are different .
*/
2011-12-20 17:57:56 +00:00
inline bool operator ! = ( const RefitOption & other ) const
2010-01-10 21:45:32 +00:00
{
2013-02-24 16:42:30 +00:00
return other . cargo ! = this - > cargo | | other . string ! = this - > string ;
2010-01-10 21:45:32 +00:00
}
2010-04-02 12:28:08 +00:00
2010-08-13 14:24:47 +00:00
/**
* Equality operator for # RefitOption .
* @ param other Compare to this # RefitOption .
* @ return True if both # RefitOption are equal .
*/
2011-12-20 17:57:56 +00:00
inline bool operator = = ( const RefitOption & other ) const
2010-04-02 12:28:08 +00:00
{
2013-02-24 16:42:30 +00:00
return other . cargo = = this - > cargo & & other . string = = this - > string ;
2010-04-02 12:28:08 +00:00
}
2007-03-07 12:11:48 +00:00
} ;
2006-10-01 12:00:32 +00:00
2019-03-03 17:30:09 +00:00
typedef std : : vector < RefitOption > SubtypeList ; ///< List of refit subtypes associated to a cargo.
2010-01-10 21:45:32 +00:00
2010-08-01 19:22:34 +00:00
/**
* Draw the list of available refit options for a consist and highlight the selected refit option ( if any ) .
2010-08-13 14:28:51 +00:00
* @ param list List of subtype options for each ( sorted ) cargo .
2009-10-24 21:10:57 +00:00
* @ param sel Selected refit cargo - type in the window
* @ param pos Position of the selected item in caller widow
* @ param rows Number of rows ( capacity ) in caller window
* @ param delta Step height in caller window
* @ param r Rectangle of the matrix widget .
2005-05-14 12:36:16 +00:00
*/
2013-02-24 16:43:45 +00:00
static void DrawVehicleRefitWindow ( const SubtypeList list [ NUM_CARGO ] , const int sel [ 2 ] , uint pos , uint rows , uint delta , const Rect & r )
2005-05-14 12:36:16 +00:00
{
2009-10-24 21:10:57 +00:00
uint y = r . top + WD_MATRIX_TOP ;
2010-08-13 14:28:51 +00:00
uint current = 0 ;
2013-03-02 12:38:40 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
uint iconwidth = max ( GetSpriteSize ( SPR_CIRCLE_FOLDED ) . width , GetSpriteSize ( SPR_CIRCLE_UNFOLDED ) . width ) ;
uint iconheight = GetSpriteSize ( SPR_CIRCLE_FOLDED ) . height ;
int linecolour = _colour_gradient [ COLOUR_ORANGE ] [ 4 ] ;
int iconleft = rtl ? r . right - WD_MATRIX_RIGHT - iconwidth : r . left + WD_MATRIX_LEFT ;
int iconcenter = rtl ? r . right - WD_MATRIX_RIGHT - iconwidth / 2 : r . left + WD_MATRIX_LEFT + iconwidth / 2 ;
int iconinner = rtl ? r . right - WD_MATRIX_RIGHT - iconwidth : r . left + WD_MATRIX_LEFT + iconwidth ;
int textleft = r . left + WD_MATRIX_LEFT + ( rtl ? 0 : iconwidth + 4 ) ;
int textright = r . right - WD_MATRIX_RIGHT - ( rtl ? iconwidth + 4 : 0 ) ;
2010-08-13 14:28:51 +00:00
/* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
for ( uint i = 0 ; current < pos + rows & & i < NUM_CARGO ; i + + ) {
2018-09-23 11:23:54 +00:00
for ( uint j = 0 ; current < pos + rows & & j < list [ i ] . size ( ) ; j + + ) {
2013-02-24 16:43:45 +00:00
const RefitOption & refit = list [ i ] [ j ] ;
/* Hide subtypes if sel[0] does not match */
if ( sel [ 0 ] ! = ( int ) i & & refit . subtype ! = 0xFF ) continue ;
2010-08-13 14:28:51 +00:00
/* Refit options with a position smaller than pos don't have to be drawn. */
if ( current < pos ) {
current + + ;
continue ;
}
2018-09-23 11:23:54 +00:00
if ( list [ i ] . size ( ) > 1 ) {
2013-03-02 12:38:40 +00:00
if ( refit . subtype ! = 0xFF ) {
/* Draw tree lines */
int ycenter = y + FONT_HEIGHT_NORMAL / 2 ;
2018-09-23 11:23:54 +00:00
GfxDrawLine ( iconcenter , y - WD_MATRIX_TOP , iconcenter , j = = list [ i ] . size ( ) - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1 , linecolour ) ;
2013-03-02 12:38:40 +00:00
GfxDrawLine ( iconcenter , ycenter , iconinner , ycenter , linecolour ) ;
} else {
/* Draw expand/collapse icon */
DrawSprite ( sel [ 0 ] = = ( int ) i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED , PAL_NONE , iconleft , y + ( FONT_HEIGHT_NORMAL - iconheight ) / 2 ) ;
}
}
2013-02-24 16:43:45 +00:00
TextColour colour = ( sel [ 0 ] = = ( int ) i & & ( uint ) sel [ 1 ] = = j ) ? TC_WHITE : TC_BLACK ;
2010-08-13 14:28:51 +00:00
/* Get the cargo name. */
SetDParam ( 0 , CargoSpec : : Get ( refit . cargo ) - > name ) ;
2013-02-24 16:42:30 +00:00
SetDParam ( 1 , refit . string ) ;
2013-03-02 12:38:40 +00:00
DrawString ( textleft , textright , y , STR_JUST_STRING_STRING , colour ) ;
2009-11-16 13:19:39 +00:00
2010-08-13 14:28:51 +00:00
y + = delta ;
current + + ;
}
2006-02-14 09:31:05 +00:00
}
2005-05-14 12:36:16 +00:00
}
2009-10-24 20:26:18 +00:00
/** Refit cargo window. */
2008-05-16 23:23:38 +00:00
struct RefitWindow : public Window {
2013-02-24 16:43:45 +00:00
int sel [ 2 ] ; ///< Index in refit options, sel[0] == -1 if nothing is selected.
2012-01-01 17:36:19 +00:00
RefitOption * cargo ; ///< Refit option selected by #sel.
2010-08-13 14:28:51 +00:00
SubtypeList list [ NUM_CARGO ] ; ///< List of refit subtypes available for each sorted cargo.
VehicleOrderID order ; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
2011-12-15 21:56:00 +00:00
uint information_width ; ///< Width required for correctly displaying all cargoes in the information panel.
2010-12-21 13:58:09 +00:00
Scrollbar * vscroll ; ///< The main scrollbar.
Scrollbar * hscroll ; ///< Only used for long vehicles.
int vehicle_width ; ///< Width of the vehicle being drawn.
int sprite_left ; ///< Left position of the vehicle sprite.
int sprite_right ; ///< Right position of the vehicle sprite.
2010-12-21 13:59:16 +00:00
uint vehicle_margin ; ///< Margin to use while selecting vehicles when the vehicle image is centered.
int click_x ; ///< Position of the first click while dragging.
VehicleID selected_vehicle ; ///< First vehicle in the current selection.
uint8 num_vehicles ; ///< Number of selected vehicles.
2011-11-04 00:38:59 +00:00
bool auto_refit ; ///< Select cargo for auto-refitting.
2008-05-16 23:23:38 +00:00
2010-08-13 14:26:29 +00:00
/**
* Collects all ( cargo , subcargo ) refit options of a vehicle chain .
*/
void BuildRefitList ( )
{
2018-09-20 22:44:14 +00:00
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) this - > list [ i ] . clear ( ) ;
2010-08-13 14:26:29 +00:00
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2010-12-21 13:59:16 +00:00
/* Check only the selected vehicles. */
VehicleSet vehicles_to_refit ;
GetVehicleSet ( vehicles_to_refit , Vehicle : : Get ( this - > selected_vehicle ) , this - > num_vehicles ) ;
2010-08-13 14:26:29 +00:00
do {
2019-02-12 22:59:12 +00:00
if ( v - > type = = VEH_TRAIN & & std : : find ( vehicles_to_refit . begin ( ) , vehicles_to_refit . end ( ) , v - > index ) = = vehicles_to_refit . end ( ) ) continue ;
2011-11-01 00:21:08 +00:00
const Engine * e = v - > GetEngine ( ) ;
2018-05-21 21:08:39 +00:00
CargoTypes cmask = e - > info . refit_mask ;
2010-08-13 14:26:29 +00:00
byte callback_mask = e - > info . callback_mask ;
/* Skip this engine if it does not carry anything */
if ( ! e - > CanCarryCargo ( ) ) continue ;
2011-11-04 00:38:59 +00:00
/* Skip this engine if we build the list for auto-refitting and engine doesn't allow it. */
if ( this - > auto_refit & & ! HasBit ( e - > info . misc_flags , EF_AUTO_REFIT ) ) continue ;
2010-08-13 14:26:29 +00:00
2011-12-15 21:56:00 +00:00
/* Loop through all cargoes in the refit mask */
2010-08-13 14:28:51 +00:00
int current_index = 0 ;
2010-08-13 14:26:29 +00:00
const CargoSpec * cs ;
FOR_ALL_SORTED_CARGOSPECS ( cs ) {
CargoID cid = cs - > Index ( ) ;
/* Skip cargo type if it's not listed */
2010-08-13 14:28:51 +00:00
if ( ! HasBit ( cmask , cid ) ) {
current_index + + ;
continue ;
}
2010-08-13 14:26:29 +00:00
2018-09-23 11:23:54 +00:00
bool first_vehicle = this - > list [ current_index ] . size ( ) = = 0 ;
2013-02-24 16:43:24 +00:00
if ( first_vehicle ) {
/* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */
2019-02-18 22:39:06 +00:00
this - > list [ current_index ] . push_back ( { cid , 0xFF , STR_EMPTY } ) ;
2013-02-24 16:43:24 +00:00
}
2013-02-24 16:41:51 +00:00
/* Check the vehicle's callback mask for cargo suffixes.
* This is not supported for ordered refits , since subtypes only have a meaning
* for a specific vehicle at a specific point in time , which conflicts with shared orders ,
* autoreplace , autorenew , clone , order restoration , . . . */
if ( this - > order = = INVALID_VEH_ORDER_ID & & HasBit ( callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) {
2010-08-13 14:26:29 +00:00
/* Make a note of the original cargo type. It has to be
* changed to test the cargo & subtype . . . */
CargoID temp_cargo = v - > cargo_type ;
byte temp_subtype = v - > cargo_subtype ;
v - > cargo_type = cid ;
for ( uint refit_cyc = 0 ; refit_cyc < MAX_REFIT_CYCLE ; refit_cyc + + ) {
v - > cargo_subtype = refit_cyc ;
/* Make sure we don't pick up anything cached. */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
2013-02-24 16:42:30 +00:00
StringID subtype = GetCargoSubtypeText ( v ) ;
2010-08-13 14:26:29 +00:00
2013-02-24 16:43:24 +00:00
if ( first_vehicle ) {
/* Append new subtype (don't add duplicates though) */
if ( subtype = = STR_EMPTY ) break ;
RefitOption option ;
option . cargo = cid ;
option . subtype = refit_cyc ;
option . string = subtype ;
2019-02-20 21:35:41 +00:00
include ( this - > list [ current_index ] , option ) ;
2013-02-24 16:43:24 +00:00
} else {
/* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */
if ( subtype = = STR_EMPTY ) {
/* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */
SubtypeList & l = this - > list [ current_index ] ;
/* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */
2018-09-23 11:23:54 +00:00
for ( uint i = 1 ; i < l . size ( ) ; i + + ) {
2013-02-24 16:43:24 +00:00
if ( l [ i ] . subtype > = refit_cyc ) {
2018-09-23 15:43:00 +00:00
l . resize ( i ) ;
2013-02-24 16:43:24 +00:00
break ;
}
}
break ;
} else {
/* Check whether the subtype matches with the subtype of earlier vehicles. */
uint pos = 1 ;
SubtypeList & l = this - > list [ current_index ] ;
2018-09-23 11:23:54 +00:00
while ( pos < l . size ( ) & & l [ pos ] . subtype ! = refit_cyc ) pos + + ;
if ( pos < l . size ( ) & & l [ pos ] . string ! = subtype ) {
2013-02-24 16:43:24 +00:00
/* String mismatch, remove item keeping the order */
2018-09-24 19:24:40 +00:00
l . erase ( l . begin ( ) + pos ) ;
2013-02-24 16:43:24 +00:00
}
}
}
2010-08-13 14:26:29 +00:00
}
/* Reset the vehicle's cargo type */
v - > cargo_type = temp_cargo ;
v - > cargo_subtype = temp_subtype ;
/* And make sure we haven't tainted the cache */
v - > First ( ) - > InvalidateNewGRFCache ( ) ;
v - > InvalidateNewGRFCache ( ) ;
}
2010-08-13 14:28:51 +00:00
current_index + + ;
2010-08-13 14:26:29 +00:00
}
2019-04-10 21:07:06 +00:00
} while ( v - > IsGroundVehicle ( ) & & ( v = v - > Next ( ) ) ! = nullptr ) ;
2013-02-24 16:43:45 +00:00
}
/**
* Refresh scrollbar after selection changed
*/
void RefreshScrollbar ( )
{
uint scroll_row = 0 ;
uint row = 0 ;
2010-08-13 14:28:51 +00:00
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
2018-09-23 11:23:54 +00:00
for ( uint j = 0 ; j < this - > list [ i ] . size ( ) ; j + + ) {
2013-02-24 16:43:45 +00:00
const RefitOption & refit = this - > list [ i ] [ j ] ;
/* Hide subtypes if sel[0] does not match */
if ( this - > sel [ 0 ] ! = ( int ) i & & refit . subtype ! = 0xFF ) continue ;
if ( this - > sel [ 0 ] = = ( int ) i & & ( uint ) this - > sel [ 1 ] = = j ) scroll_row = row ;
row + + ;
}
2010-08-13 14:28:51 +00:00
}
2013-02-24 16:43:45 +00:00
this - > vscroll - > SetCount ( row ) ;
2013-06-24 20:57:50 +00:00
if ( scroll_row < row ) this - > vscroll - > ScrollTowards ( scroll_row ) ;
2010-08-13 14:28:51 +00:00
}
/**
2013-02-24 16:43:45 +00:00
* Select a row .
* @ param click_row Clicked row
2010-08-13 14:28:51 +00:00
*/
2013-02-24 16:43:45 +00:00
void SetSelection ( uint click_row )
2010-08-13 14:28:51 +00:00
{
2013-02-24 16:43:45 +00:00
uint row = 0 ;
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
2018-09-23 11:23:54 +00:00
for ( uint j = 0 ; j < this - > list [ i ] . size ( ) ; j + + ) {
2013-02-24 16:43:45 +00:00
const RefitOption & refit = this - > list [ i ] [ j ] ;
/* Hide subtypes if sel[0] does not match */
if ( this - > sel [ 0 ] ! = ( int ) i & & refit . subtype ! = 0xFF ) continue ;
if ( row = = click_row ) {
this - > sel [ 0 ] = i ;
this - > sel [ 1 ] = j ;
return ;
2010-08-13 14:28:51 +00:00
}
2013-02-24 16:43:45 +00:00
row + + ;
2010-08-13 14:28:51 +00:00
}
}
2013-02-24 16:43:45 +00:00
this - > sel [ 0 ] = - 1 ;
this - > sel [ 1 ] = 0 ;
}
/**
* Gets the # RefitOption placed in the selected index .
* @ return Pointer to the # RefitOption currently in use .
*/
RefitOption * GetRefitOption ( )
{
2019-04-10 21:07:06 +00:00
if ( this - > sel [ 0 ] < 0 ) return nullptr ;
2013-02-24 16:43:45 +00:00
SubtypeList & l = this - > list [ this - > sel [ 0 ] ] ;
2019-04-10 21:07:06 +00:00
if ( ( uint ) this - > sel [ 1 ] > = l . size ( ) ) return nullptr ;
2013-02-24 16:43:45 +00:00
return & l [ this - > sel [ 1 ] ] ;
2010-08-13 14:26:29 +00:00
}
2013-05-26 19:23:42 +00:00
RefitWindow ( WindowDesc * desc , const Vehicle * v , VehicleOrderID order , bool auto_refit ) : Window ( desc )
2008-05-16 23:23:38 +00:00
{
2013-02-24 16:43:45 +00:00
this - > sel [ 0 ] = - 1 ;
this - > sel [ 1 ] = 0 ;
2011-11-04 00:38:59 +00:00
this - > auto_refit = auto_refit ;
2013-02-24 16:41:51 +00:00
this - > order = order ;
2013-05-26 19:23:42 +00:00
this - > CreateNestedTree ( ) ;
2009-10-24 20:26:18 +00:00
2011-12-16 16:58:55 +00:00
this - > vscroll = this - > GetScrollbar ( WID_VR_SCROLLBAR ) ;
2019-04-10 21:07:06 +00:00
this - > hscroll = ( v - > IsGroundVehicle ( ) ? this - > GetScrollbar ( WID_VR_HSCROLLBAR ) : nullptr ) ;
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VR_SELECT_HEADER ) - > tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VR_MATRIX ) - > tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v - > type ;
NWidgetCore * nwi = this - > GetWidget < NWidgetCore > ( WID_VR_REFIT ) ;
2009-10-24 20:26:18 +00:00
nwi - > widget_data = STR_REFIT_TRAIN_REFIT_BUTTON + v - > type ;
nwi - > tool_tip = STR_REFIT_TRAIN_REFIT_TOOLTIP + v - > type ;
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetStacked > ( WID_VR_SHOW_HSCROLLBAR ) - > SetDisplayedPlane ( v - > IsGroundVehicle ( ) ? 0 : SZSP_HORIZONTAL ) ;
this - > GetWidget < NWidgetCore > ( WID_VR_VEHICLE_PANEL_DISPLAY ) - > tool_tip = ( v - > type = = VEH_TRAIN ) ? STR_REFIT_SELECT_VEHICLES_TOOLTIP : STR_NULL ;
2009-10-24 20:26:18 +00:00
2013-05-26 19:23:42 +00:00
this - > FinishInitNested ( v - > index ) ;
2009-02-09 02:33:10 +00:00
this - > owner = v - > owner ;
2008-05-16 23:23:38 +00:00
2013-02-24 16:43:45 +00:00
this - > SetWidgetDisabledState ( WID_VR_REFIT , this - > sel [ 0 ] < 0 ) ;
2008-05-16 23:23:38 +00:00
}
2019-03-04 07:49:37 +00:00
void OnInit ( ) override
2010-04-02 12:28:08 +00:00
{
2019-04-10 21:07:06 +00:00
if ( this - > cargo ! = nullptr ) {
2010-04-02 12:28:08 +00:00
/* Store the RefitOption currently in use. */
RefitOption current_refit_option = * ( this - > cargo ) ;
/* Rebuild the refit list */
2010-08-13 14:26:29 +00:00
this - > BuildRefitList ( ) ;
2013-02-24 16:43:45 +00:00
this - > sel [ 0 ] = - 1 ;
this - > sel [ 1 ] = 0 ;
2019-04-10 21:07:06 +00:00
this - > cargo = nullptr ;
for ( uint i = 0 ; this - > cargo = = nullptr & & i < NUM_CARGO ; i + + ) {
2018-09-23 11:23:54 +00:00
for ( uint j = 0 ; j < list [ i ] . size ( ) ; j + + ) {
2010-08-13 14:28:51 +00:00
if ( list [ i ] [ j ] = = current_refit_option ) {
2013-02-24 16:43:45 +00:00
this - > sel [ 0 ] = i ;
this - > sel [ 1 ] = j ;
2010-08-13 14:28:51 +00:00
this - > cargo = & list [ i ] [ j ] ;
break ;
}
2010-04-02 12:28:08 +00:00
}
}
2013-02-24 16:43:45 +00:00
this - > SetWidgetDisabledState ( WID_VR_REFIT , this - > sel [ 0 ] < 0 ) ;
this - > RefreshScrollbar ( ) ;
2010-04-02 12:28:08 +00:00
} else {
/* Rebuild the refit list */
2012-12-20 19:44:02 +00:00
this - > OnInvalidateData ( VIWD_CONSIST_CHANGED ) ;
2010-04-02 12:28:08 +00:00
}
}
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2010-12-21 13:58:09 +00:00
{
/* Determine amount of items for scroller. */
2019-04-10 21:07:06 +00:00
if ( this - > hscroll ! = nullptr ) this - > hscroll - > SetCount ( this - > vehicle_width ) ;
2010-12-21 13:58:09 +00:00
/* Calculate sprite position. */
2011-12-16 16:58:55 +00:00
NWidgetCore * vehicle_panel_display = this - > GetWidget < NWidgetCore > ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 13:58:09 +00:00
int sprite_width = max ( 0 , ( ( int ) vehicle_panel_display - > current_x - this - > vehicle_width ) / 2 ) ;
this - > sprite_left = vehicle_panel_display - > pos_x ;
this - > sprite_right = vehicle_panel_display - > pos_x + vehicle_panel_display - > current_x - 1 ;
if ( _current_text_dir = = TD_RTL ) {
this - > sprite_right - = sprite_width ;
2010-12-21 13:59:16 +00:00
this - > vehicle_margin = vehicle_panel_display - > current_x - sprite_right ;
2010-12-21 13:58:09 +00:00
} else {
this - > sprite_left + = sprite_width ;
2010-12-21 13:59:16 +00:00
this - > vehicle_margin = sprite_left ;
2010-12-21 13:58:09 +00:00
}
this - > DrawWidgets ( ) ;
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-10-24 20:26:18 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VR_MATRIX :
2009-10-24 20:26:18 +00:00
resize - > height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM ;
size - > height = resize - > height * 8 ;
break ;
2010-10-15 10:22:04 +00:00
2011-12-16 16:58:55 +00:00
case WID_VR_VEHICLE_PANEL_DISPLAY :
2015-02-01 20:54:24 +00:00
size - > height = ScaleGUITrad ( GetVehicleHeight ( Vehicle : : Get ( this - > window_number ) - > type ) ) ;
2010-12-21 13:58:09 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VR_INFO :
2010-10-15 10:22:04 +00:00
size - > width = WD_FRAMERECT_LEFT + this - > information_width + WD_FRAMERECT_RIGHT ;
break ;
2009-10-24 20:26:18 +00:00
}
}
2006-09-27 07:23:38 +00:00
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-10-24 20:26:18 +00:00
{
2011-12-16 16:58:55 +00:00
if ( widget = = WID_VR_CAPTION ) SetDParam ( 0 , Vehicle : : Get ( this - > window_number ) - > index ) ;
2009-10-24 20:26:18 +00:00
}
2006-09-27 07:23:38 +00:00
2010-11-16 20:56:04 +00:00
/**
* Gets the # StringID to use for displaying capacity .
2018-10-28 02:17:36 +00:00
* @ param option Cargo and cargo subtype to check for capacity .
2010-11-16 20:56:04 +00:00
* @ return INVALID_STRING_ID if there is no capacity . StringID to use in any other case .
* @ post String parameters have been set .
*/
StringID GetCapacityString ( RefitOption * option ) const
{
2011-02-23 20:54:55 +00:00
assert ( _current_company = = _local_company ) ;
2010-11-16 20:56:04 +00:00
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2019-01-29 19:15:49 +00:00
CommandCost cost = DoCommand ( v - > tile , this - > selected_vehicle , option - > cargo | option - > subtype < < 8 | this - > num_vehicles < < 16 |
( int ) this - > auto_refit < < 24 , DC_QUERY_COST , GetCmdRefitVeh ( v - > type ) ) ;
2010-11-16 20:56:04 +00:00
if ( cost . Failed ( ) ) return INVALID_STRING_ID ;
SetDParam ( 0 , option - > cargo ) ;
SetDParam ( 1 , _returned_refit_capacity ) ;
2012-09-22 16:19:52 +00:00
Money money = cost . GetCost ( ) ;
2010-11-16 20:56:04 +00:00
if ( _returned_mail_refit_capacity > 0 ) {
SetDParam ( 2 , CT_MAIL ) ;
SetDParam ( 3 , _returned_mail_refit_capacity ) ;
2015-10-30 17:27:21 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) {
/* No predictable cost */
return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY ;
} else if ( money < = 0 ) {
2012-09-22 16:19:52 +00:00
SetDParam ( 4 , - money ) ;
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT ;
} else {
SetDParam ( 4 , money ) ;
return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT ;
}
2010-11-16 20:56:04 +00:00
} else {
2015-10-30 17:27:21 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) {
/* No predictable cost */
SetDParam ( 2 , STR_EMPTY ) ;
return STR_PURCHASE_INFO_CAPACITY ;
} else if ( money < = 0 ) {
2012-09-22 16:19:52 +00:00
SetDParam ( 2 , - money ) ;
return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT ;
} else {
SetDParam ( 2 , money ) ;
return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT ;
}
2010-11-16 20:56:04 +00:00
}
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-24 20:26:18 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VR_VEHICLE_PANEL_DISPLAY : {
2010-12-21 13:58:09 +00:00
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
DrawVehicleImage ( v , this - > sprite_left + WD_FRAMERECT_LEFT , this - > sprite_right - WD_FRAMERECT_RIGHT ,
2019-04-10 21:07:06 +00:00
r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , this - > hscroll ! = nullptr ? this - > hscroll - > GetPosition ( ) : 0 ) ;
2010-12-21 13:58:09 +00:00
2010-12-21 14:00:14 +00:00
/* Highlight selected vehicles. */
2011-01-23 13:00:50 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
2010-12-21 14:00:14 +00:00
int x = 0 ;
switch ( v - > type ) {
case VEH_TRAIN : {
VehicleSet vehicles_to_refit ;
GetVehicleSet ( vehicles_to_refit , Vehicle : : Get ( this - > selected_vehicle ) , this - > num_vehicles ) ;
int left = INT32_MIN ;
int width = 0 ;
2019-04-10 21:07:06 +00:00
for ( Train * u = Train : : From ( v ) ; u ! = nullptr ; u = u - > Next ( ) ) {
2010-12-21 14:00:14 +00:00
/* Start checking. */
2019-02-12 22:59:12 +00:00
const bool contained = std : : find ( vehicles_to_refit . begin ( ) , vehicles_to_refit . end ( ) , u - > index ) ! = vehicles_to_refit . end ( ) ;
if ( contained & & left = = INT32_MIN ) {
2010-12-21 14:00:14 +00:00
left = x - this - > hscroll - > GetPosition ( ) + r . left + this - > vehicle_margin ;
width = 0 ;
}
/* Draw a selection. */
2019-04-10 21:07:06 +00:00
if ( ( ! contained | | u - > Next ( ) = = nullptr ) & & left ! = INT32_MIN ) {
if ( u - > Next ( ) = = nullptr & & contained ) {
2010-12-21 14:00:14 +00:00
int current_width = u - > GetDisplayImageWidth ( ) ;
width + = current_width ;
x + = current_width ;
}
int right = Clamp ( left + width , 0 , r . right ) ;
left = max ( 0 , left ) ;
if ( _current_text_dir = = TD_RTL ) {
2011-12-16 16:58:55 +00:00
right = this - > GetWidget < NWidgetCore > ( WID_VR_VEHICLE_PANEL_DISPLAY ) - > current_x - left ;
2010-12-21 14:00:14 +00:00
left = right - width ;
}
if ( left ! = right ) {
2015-02-01 20:54:24 +00:00
DrawFrameRect ( left , r . top + WD_FRAMERECT_TOP , right , r . top + WD_FRAMERECT_TOP + ScaleGUITrad ( 14 ) - 1 , COLOUR_WHITE , FR_BORDERONLY ) ;
2010-12-21 14:00:14 +00:00
}
left = INT32_MIN ;
}
int current_width = u - > GetDisplayImageWidth ( ) ;
width + = current_width ;
x + = current_width ;
}
break ;
}
default : break ;
}
2010-12-21 13:58:09 +00:00
break ;
}
2011-12-16 16:58:55 +00:00
case WID_VR_MATRIX :
2010-08-12 08:37:01 +00:00
DrawVehicleRefitWindow ( this - > list , this - > sel , this - > vscroll - > GetPosition ( ) , this - > vscroll - > GetCapacity ( ) , this - > resize . step_height , r ) ;
2009-10-24 20:26:18 +00:00
break ;
2007-02-17 17:12:19 +00:00
2011-12-16 16:58:55 +00:00
case WID_VR_INFO :
2019-04-10 21:07:06 +00:00
if ( this - > cargo ! = nullptr ) {
2010-11-16 20:56:04 +00:00
StringID string = this - > GetCapacityString ( this - > cargo ) ;
if ( string ! = INVALID_STRING_ID ) {
2009-10-24 20:26:18 +00:00
DrawStringMultiLine ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT ,
2010-11-16 20:56:04 +00:00
r . top + WD_FRAMERECT_TOP , r . bottom - WD_FRAMERECT_BOTTOM , string ) ;
2009-10-24 20:26:18 +00:00
}
}
break ;
2008-05-16 23:23:38 +00:00
}
}
2006-09-27 07:23:38 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
2019-03-04 07:49:37 +00:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2010-04-23 17:29:53 +00:00
{
switch ( data ) {
2012-12-20 19:44:02 +00:00
case VIWD_AUTOREPLACE : // Autoreplace replaced the vehicle; selected_vehicle became invalid.
case VIWD_CONSIST_CHANGED : { // The consist has changed; rebuild the entire list.
2010-12-21 13:59:16 +00:00
/* Clear the selection. */
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
this - > selected_vehicle = v - > index ;
this - > num_vehicles = UINT8_MAX ;
2017-08-15 15:56:34 +00:00
FALLTHROUGH ;
2010-12-21 13:59:16 +00:00
}
case 2 : { // The vehicle selection has changed; rebuild the entire list.
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) break ;
2010-08-13 14:26:29 +00:00
this - > BuildRefitList ( ) ;
2010-12-21 13:59:16 +00:00
2010-12-21 13:58:09 +00:00
/* The vehicle width has changed too. */
2011-11-01 16:51:47 +00:00
this - > vehicle_width = GetVehicleWidth ( Vehicle : : Get ( this - > window_number ) , EIT_IN_DETAILS ) ;
2010-10-15 10:22:04 +00:00
uint max_width = 0 ;
/* Check the width of all cargo information strings. */
for ( uint i = 0 ; i < NUM_CARGO ; i + + ) {
2018-09-23 11:23:54 +00:00
for ( uint j = 0 ; j < this - > list [ i ] . size ( ) ; j + + ) {
2010-11-16 20:56:04 +00:00
StringID string = this - > GetCapacityString ( & list [ i ] [ j ] ) ;
if ( string ! = INVALID_STRING_ID ) {
Dimension dim = GetStringBoundingBox ( string ) ;
2010-10-15 10:22:04 +00:00
max_width = max ( dim . width , max_width ) ;
}
}
}
if ( this - > information_width < max_width ) {
this - > information_width = max_width ;
this - > ReInit ( ) ;
}
2017-08-15 15:56:34 +00:00
FALLTHROUGH ;
2010-04-23 17:29:53 +00:00
}
case 1 : // A new cargo has been selected.
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) break ;
2010-08-13 14:28:51 +00:00
this - > cargo = GetRefitOption ( ) ;
2013-02-24 16:43:45 +00:00
this - > RefreshScrollbar ( ) ;
2010-04-23 17:29:53 +00:00
break ;
}
}
2010-12-21 13:59:16 +00:00
int GetClickPosition ( int click_x )
{
2011-12-16 16:58:55 +00:00
const NWidgetCore * matrix_widget = this - > GetWidget < NWidgetCore > ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 13:59:16 +00:00
if ( _current_text_dir = = TD_RTL ) click_x = matrix_widget - > current_x - click_x ;
click_x - = this - > vehicle_margin ;
2019-04-10 21:07:06 +00:00
if ( this - > hscroll ! = nullptr ) click_x + = this - > hscroll - > GetPosition ( ) ;
2010-12-21 13:59:16 +00:00
return click_x ;
}
void SetSelectedVehicles ( int drag_x )
{
drag_x = GetClickPosition ( drag_x ) ;
int left_x = min ( this - > click_x , drag_x ) ;
int right_x = max ( this - > click_x , drag_x ) ;
this - > num_vehicles = 0 ;
Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
/* Find the vehicle part that was clicked. */
switch ( v - > type ) {
case VEH_TRAIN : {
/* Don't select anything if we are not clicking in the vehicle. */
if ( left_x > = 0 ) {
const Train * u = Train : : From ( v ) ;
bool start_counting = false ;
2019-04-10 21:07:06 +00:00
for ( ; u ! = nullptr ; u = u - > Next ( ) ) {
2010-12-21 13:59:16 +00:00
int current_width = u - > GetDisplayImageWidth ( ) ;
left_x - = current_width ;
right_x - = current_width ;
if ( left_x < 0 & & ! start_counting ) {
this - > selected_vehicle = u - > index ;
start_counting = true ;
2011-01-23 14:58:54 +00:00
/* Count the first vehicle, even if articulated part */
this - > num_vehicles + + ;
} else if ( start_counting & & ! u - > IsArticulatedPart ( ) ) {
/* Do not count articulated parts */
this - > num_vehicles + + ;
2010-12-21 13:59:16 +00:00
}
if ( right_x < 0 ) break ;
}
}
/* If the selection is not correct, clear it. */
2010-12-21 14:01:44 +00:00
if ( this - > num_vehicles ! = 0 ) {
if ( _ctrl_pressed ) this - > num_vehicles = UINT8_MAX ;
break ;
}
2017-08-15 15:56:34 +00:00
FALLTHROUGH ;
2010-12-21 13:59:16 +00:00
}
default :
/* Clear the selection. */
this - > selected_vehicle = v - > index ;
this - > num_vehicles = UINT8_MAX ;
break ;
}
}
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-16 23:23:38 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VR_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
2010-12-21 13:59:16 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
2011-12-16 16:58:55 +00:00
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 13:59:16 +00:00
this - > click_x = GetClickPosition ( pt . x - nwi - > pos_x ) ;
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
2011-12-16 16:58:55 +00:00
this - > SetWidgetDirty ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2011-02-20 18:32:42 +00:00
if ( ! _ctrl_pressed ) {
SetObjectToPlaceWnd ( SPR_CURSOR_MOUSE , PAL_NONE , HT_DRAG , this ) ;
} else {
/* The vehicle selection has changed. */
this - > InvalidateData ( 2 ) ;
}
2010-12-21 13:59:16 +00:00
break ;
}
2011-12-16 16:58:55 +00:00
case WID_VR_MATRIX : { // listbox
2013-02-24 16:43:45 +00:00
this - > SetSelection ( this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_VR_MATRIX ) ) ;
this - > SetWidgetDisabledState ( WID_VR_REFIT , this - > sel [ 0 ] < 0 ) ;
2010-07-26 13:08:48 +00:00
this - > InvalidateData ( 1 ) ;
2010-04-23 17:29:53 +00:00
2010-01-30 18:34:48 +00:00
if ( click_count = = 1 ) break ;
2017-08-15 15:56:34 +00:00
FALLTHROUGH ;
2006-09-27 07:23:38 +00:00
}
2010-08-01 20:52:11 +00:00
2011-12-16 16:58:55 +00:00
case WID_VR_REFIT : // refit button
2019-04-10 21:07:06 +00:00
if ( this - > cargo ! = nullptr ) {
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-16 23:23:38 +00:00
if ( this - > order = = INVALID_VEH_ORDER_ID ) {
2010-12-21 14:00:58 +00:00
bool delete_window = this - > selected_vehicle = = v - > index & & this - > num_vehicles = = UINT8_MAX ;
2011-01-23 13:25:26 +00:00
if ( DoCommandP ( v - > tile , this - > selected_vehicle , this - > cargo - > cargo | this - > cargo - > subtype < < 8 | this - > num_vehicles < < 16 , GetCmdRefitVeh ( v ) ) & & delete_window ) delete this ;
2008-05-16 23:23:38 +00:00
} else {
2013-02-24 16:41:51 +00:00
if ( DoCommandP ( v - > tile , v - > index , this - > cargo - > cargo | this - > order < < 16 , CMD_ORDER_REFIT ) ) delete this ;
2006-09-27 07:23:38 +00:00
}
2008-05-16 23:23:38 +00:00
}
break ;
}
}
2006-10-01 12:00:32 +00:00
2019-03-04 07:49:37 +00:00
void OnMouseDrag ( Point pt , int widget ) override
2010-12-21 14:00:14 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VR_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
2010-12-21 14:00:14 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
2011-12-16 16:58:55 +00:00
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 14:00:14 +00:00
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
2011-12-16 16:58:55 +00:00
this - > SetWidgetDirty ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 14:00:14 +00:00
break ;
}
}
}
2019-03-04 07:49:37 +00:00
void OnDragDrop ( Point pt , int widget ) override
2010-12-21 13:59:16 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VR_VEHICLE_PANEL_DISPLAY : { // Vehicle image.
2010-12-21 13:59:16 +00:00
if ( this - > order ! = INVALID_VEH_ORDER_ID ) break ;
2011-12-16 16:58:55 +00:00
NWidgetBase * nwi = this - > GetWidget < NWidgetBase > ( WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2010-12-21 13:59:16 +00:00
this - > SetSelectedVehicles ( pt . x - nwi - > pos_x ) ;
this - > InvalidateData ( 2 ) ;
break ;
}
}
}
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2008-05-16 23:23:38 +00:00
{
2011-11-01 16:51:47 +00:00
this - > vehicle_width = GetVehicleWidth ( Vehicle : : Get ( this - > window_number ) , EIT_IN_DETAILS ) ;
2011-12-16 16:58:55 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_VR_MATRIX ) ;
2019-04-10 21:07:06 +00:00
if ( this - > hscroll ! = nullptr ) this - > hscroll - > SetCapacityFromWidget ( this , WID_VR_VEHICLE_PANEL_DISPLAY ) ;
2006-09-27 07:23:38 +00:00
}
2008-05-16 23:23:38 +00:00
} ;
2006-09-27 07:23:38 +00:00
2009-04-13 14:09:56 +00:00
static const NWidgetPart _nested_vehicle_refit_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_VR_CAPTION ) , SetDataTip ( STR_REFIT_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2010-12-21 13:58:09 +00:00
/* Vehicle display + scrollbar. */
NWidget ( NWID_VERTICAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VR_VEHICLE_PANEL_DISPLAY ) , SetMinimalSize ( 228 , 14 ) , SetResize ( 1 , 0 ) , SetScrollbar ( WID_VR_HSCROLLBAR ) , EndContainer ( ) ,
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_VR_SHOW_HSCROLLBAR ) ,
NWidget ( NWID_HSCROLLBAR , COLOUR_GREY , WID_VR_HSCROLLBAR ) ,
2010-12-21 13:58:09 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_TEXTBTN , COLOUR_GREY , WID_VR_SELECT_HEADER ) , SetDataTip ( STR_REFIT_TITLE , STR_NULL ) , SetResize ( 1 , 0 ) ,
2009-04-13 14:09:56 +00:00
/* Matrix + scrollbar. */
NWidget ( NWID_HORIZONTAL ) ,
2013-06-30 14:36:31 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_VR_MATRIX ) , SetMinimalSize ( 228 , 112 ) , SetResize ( 1 , 14 ) , SetFill ( 1 , 1 ) , SetMatrixDataTip ( 1 , 0 , STR_NULL ) , SetScrollbar ( WID_VR_SCROLLBAR ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_VR_SCROLLBAR ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VR_INFO ) , SetMinimalTextLines ( 2 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-04-13 14:09:56 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VR_REFIT ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
} ;
2013-05-26 19:23:42 +00:00
static WindowDesc _vehicle_refit_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " view_vehicle_refit " , 240 , 174 ,
2007-04-18 22:10:36 +00:00
WC_VEHICLE_REFIT , WC_VEHICLE_VIEW ,
2012-11-11 16:10:43 +00:00
WDF_CONSTRUCTION ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_refit_widgets , lengthof ( _nested_vehicle_refit_widgets )
2009-03-15 15:12:06 +00:00
) ;
2006-09-27 07:23:38 +00:00
2010-08-01 19:22:34 +00:00
/**
* Show the refit window for a vehicle
2009-03-14 18:16:29 +00:00
* @ param * v The vehicle to show the refit window for
2013-02-24 16:41:51 +00:00
* @ param order of the vehicle to assign refit to , or INVALID_VEH_ORDER_ID to refit the vehicle now
2009-09-19 09:51:14 +00:00
* @ param parent the parent window of the refit window
2011-11-04 00:38:59 +00:00
* @ param auto_refit Choose cargo for auto - refitting
2009-03-14 18:16:29 +00:00
*/
2011-11-04 00:38:59 +00:00
void ShowVehicleRefitWindow ( const Vehicle * v , VehicleOrderID order , Window * parent , bool auto_refit )
2006-09-27 07:23:38 +00:00
{
DeleteWindowById ( WC_VEHICLE_REFIT , v - > index ) ;
2011-11-04 00:38:59 +00:00
RefitWindow * w = new RefitWindow ( & _vehicle_refit_desc , v , order , auto_refit ) ;
2008-09-24 16:40:06 +00:00
w - > parent = parent ;
2006-09-27 07:23:38 +00:00
}
2007-04-04 04:08:47 +00:00
/** Display list of cargo types of the engine, for the purchase information window */
2009-03-22 11:06:25 +00:00
uint ShowRefitOptionsList ( int left , int right , int y , EngineID engine )
2006-10-23 21:39:15 +00:00
{
/* List of cargo types of this engine */
2018-05-21 21:08:39 +00:00
CargoTypes cmask = GetUnionOfArticulatedRefitMasks ( engine , false ) ;
2006-10-23 21:39:15 +00:00
/* List of cargo types available in this climate */
2018-05-21 21:08:39 +00:00
CargoTypes lmask = _cargo_mask ;
2006-10-23 21:39:15 +00:00
/* Draw nothing if the engine is not refittable */
2010-02-05 17:05:58 +00:00
if ( HasAtMostOneBit ( cmask ) ) return y ;
2006-10-23 21:39:15 +00:00
if ( cmask = = lmask ) {
/* Engine can be refitted to all types in this climate */
2012-03-10 19:18:04 +00:00
SetDParam ( 0 , STR_PURCHASE_INFO_ALL_TYPES ) ;
2006-10-23 21:39:15 +00:00
} else {
/* Check if we are able to refit to more cargo types and unable to. If
* so , invert the cargo types to list those that we can ' t refit to . */
2010-11-04 19:48:25 +00:00
if ( CountBits ( cmask ^ lmask ) < CountBits ( cmask ) & & CountBits ( cmask ^ lmask ) < = 7 ) {
2006-10-23 21:39:15 +00:00
cmask ^ = lmask ;
2012-03-10 19:18:04 +00:00
SetDParam ( 0 , STR_PURCHASE_INFO_ALL_BUT ) ;
} else {
SetDParam ( 0 , STR_JUST_CARGO_LIST ) ;
2006-10-23 21:39:15 +00:00
}
2012-03-10 19:18:04 +00:00
SetDParam ( 1 , cmask ) ;
2006-10-23 21:39:15 +00:00
}
2012-03-10 19:18:04 +00:00
return DrawStringMultiLine ( left , right , y , INT32_MAX , STR_PURCHASE_INFO_REFITTABLE_TO ) ;
2006-10-23 21:39:15 +00:00
}
2009-02-14 18:42:03 +00:00
/** Get the cargo subtype text from NewGRF for the vehicle details window. */
StringID GetCargoSubtypeText ( const Vehicle * v )
{
2009-09-14 12:22:57 +00:00
if ( HasBit ( EngInfo ( v - > engine_type ) - > callback_mask , CBM_VEHICLE_CARGO_SUFFIX ) ) {
2009-02-14 18:42:03 +00:00
uint16 cb = GetVehicleCallback ( CBID_VEHICLE_CARGO_SUFFIX , 0 , 0 , v - > engine_type , v ) ;
2011-11-08 17:24:43 +00:00
if ( cb ! = CALLBACK_FAILED ) {
if ( cb > 0x400 ) ErrorUnknownCallbackResult ( v - > GetGRFID ( ) , CBID_VEHICLE_CARGO_SUFFIX , cb ) ;
if ( cb > = 0x400 | | ( v - > GetGRF ( ) - > grf_version < 8 & & cb = = 0xFF ) ) cb = CALLBACK_FAILED ;
}
2009-02-14 18:42:03 +00:00
if ( cb ! = CALLBACK_FAILED ) {
2011-11-01 00:23:41 +00:00
return GetGRFStringID ( v - > GetGRFID ( ) , 0xD000 + cb ) ;
2009-02-14 18:42:03 +00:00
}
}
return STR_EMPTY ;
}
2004-09-06 18:15:13 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their number */
2019-04-11 19:26:02 +00:00
static bool VehicleNumberSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2019-04-11 19:26:02 +00:00
return a - > unitnumber < b - > unitnumber ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their name */
2019-04-11 19:26:02 +00:00
static bool VehicleNameSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 18:15:13 +00:00
{
2008-06-15 22:10:22 +00:00
static char last_name [ 2 ] [ 64 ] ;
2004-09-06 18:15:13 +00:00
2019-04-11 19:26:02 +00:00
if ( a ! = _last_vehicle [ 0 ] ) {
_last_vehicle [ 0 ] = a ;
SetDParam ( 0 , a - > index ) ;
2008-06-15 22:10:22 +00:00
GetString ( last_name [ 0 ] , STR_VEHICLE_NAME , lastof ( last_name [ 0 ] ) ) ;
2004-09-06 18:15:13 +00:00
}
2019-04-11 19:26:02 +00:00
if ( b ! = _last_vehicle [ 1 ] ) {
_last_vehicle [ 1 ] = b ;
SetDParam ( 0 , b - > index ) ;
2008-06-15 22:10:22 +00:00
GetString ( last_name [ 1 ] , STR_VEHICLE_NAME , lastof ( last_name [ 1 ] ) ) ;
}
2004-09-06 21:20:01 +00:00
2010-11-27 22:52:12 +00:00
int r = strnatcmp ( last_name [ 0 ] , last_name [ 1 ] ) ; // Sort by name (natural sorting).
2019-04-11 19:26:02 +00:00
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 18:15:13 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their age */
2019-04-11 19:26:02 +00:00
static bool VehicleAgeSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 18:15:13 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > age - b - > age ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by this year profit */
2019-04-11 19:26:02 +00:00
static bool VehicleProfitThisYearSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2019-04-11 19:26:02 +00:00
int r = ClampToI32 ( a - > GetDisplayProfitThisYear ( ) - b - > GetDisplayProfitThisYear ( ) ) ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by last year profit */
2019-04-11 19:26:02 +00:00
static bool VehicleProfitLastYearSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2019-04-11 19:26:02 +00:00
int r = ClampToI32 ( a - > GetDisplayProfitLastYear ( ) - b - > GetDisplayProfitLastYear ( ) ) ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their cargo */
2019-04-11 19:26:02 +00:00
static bool VehicleCargoSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2008-06-15 22:10:22 +00:00
const Vehicle * v ;
2009-06-27 18:26:50 +00:00
CargoArray diff ;
2004-09-06 21:20:01 +00:00
2013-01-08 22:46:42 +00:00
/* Append the cargo of the connected waggons */
2019-04-11 19:26:02 +00:00
for ( v = a ; v ! = nullptr ; v = v - > Next ( ) ) diff [ v - > cargo_type ] + = v - > cargo_cap ;
for ( v = b ; v ! = nullptr ; v = v - > Next ( ) ) diff [ v - > cargo_type ] - = v - > cargo_cap ;
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
int r = 0 ;
2007-03-21 13:19:01 +00:00
for ( CargoID i = 0 ; i < NUM_CARGO ; i + + ) {
2008-06-15 22:10:22 +00:00
r = diff [ i ] ;
2005-10-23 13:04:44 +00:00
if ( r ! = 0 ) break ;
2004-09-06 18:15:13 +00:00
}
2004-09-06 21:20:01 +00:00
2019-04-11 19:26:02 +00:00
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 21:20:01 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their reliability */
2019-04-11 19:26:02 +00:00
static bool VehicleReliabilitySorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > reliability - b - > reliability ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-06 18:15:13 +00:00
}
2004-09-06 21:20:01 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their max speed */
2019-04-11 19:26:02 +00:00
static bool VehicleMaxSpeedSorter ( const Vehicle * const & a , const Vehicle * const & b )
2004-09-06 21:20:01 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > vcache . cached_max_speed - b - > vcache . cached_max_speed ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2004-09-10 19:02:27 +00:00
}
2005-01-02 17:23:04 +00:00
2008-06-15 22:10:22 +00:00
/** Sort vehicles by model */
2019-04-11 19:26:02 +00:00
static bool VehicleModelSorter ( const Vehicle * const & a , const Vehicle * const & b )
2006-02-03 18:32:59 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > engine_type - b - > engine_type ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2006-02-03 18:32:59 +00:00
}
2013-01-08 22:46:42 +00:00
/** Sort vehicles by their value */
2019-04-11 19:26:02 +00:00
static bool VehicleValueSorter ( const Vehicle * const & a , const Vehicle * const & b )
2006-02-03 18:32:59 +00:00
{
const Vehicle * u ;
2008-06-15 22:10:22 +00:00
Money diff = 0 ;
2006-02-03 18:32:59 +00:00
2019-04-11 19:26:02 +00:00
for ( u = a ; u ! = nullptr ; u = u - > Next ( ) ) diff + = u - > value ;
for ( u = b ; u ! = nullptr ; u = u - > Next ( ) ) diff - = u - > value ;
2006-02-03 18:32:59 +00:00
2008-06-15 22:10:22 +00:00
int r = ClampToI32 ( diff ) ;
2019-04-11 19:26:02 +00:00
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2006-02-03 18:32:59 +00:00
}
2008-06-15 22:10:22 +00:00
/** Sort vehicles by their length */
2019-04-11 19:26:02 +00:00
static bool VehicleLengthSorter ( const Vehicle * const & a , const Vehicle * const & b )
2008-04-18 10:58:11 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > GetGroundVehicleCache ( ) - > cached_total_length - b - > GetGroundVehicleCache ( ) - > cached_total_length ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2008-04-18 10:58:11 +00:00
}
2008-09-17 02:30:24 +00:00
/** Sort vehicles by the time they can still live */
2019-04-11 19:26:02 +00:00
static bool VehicleTimeToLiveSorter ( const Vehicle * const & a , const Vehicle * const & b )
2008-09-17 02:30:24 +00:00
{
2019-04-11 19:26:02 +00:00
int r = ClampToI32 ( ( a - > max_age - a - > age ) - ( b - > max_age - b - > age ) ) ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2008-09-17 02:30:24 +00:00
}
2009-08-15 10:51:33 +00:00
/** Sort vehicles by the timetable delay */
2019-04-11 19:26:02 +00:00
static bool VehicleTimetableDelaySorter ( const Vehicle * const & a , const Vehicle * const & b )
2009-08-15 10:51:33 +00:00
{
2019-04-11 19:26:02 +00:00
int r = a - > lateness_counter - b - > lateness_counter ;
return ( r ! = 0 ) ? r < 0 : VehicleNumberSorter ( a , b ) ;
2009-08-15 10:51:33 +00:00
}
2007-03-07 11:47:46 +00:00
void InitializeGUI ( )
2005-01-31 11:03:23 +00:00
{
2019-01-11 08:09:37 +00:00
MemSetT ( & _grouping , 0 ) ;
2008-06-15 22:10:22 +00:00
MemSetT ( & _sorting , 0 ) ;
2005-01-31 11:03:23 +00:00
}
2005-10-24 19:40:48 +00:00
2008-08-06 18:57:37 +00:00
/**
* Assign a vehicle window a new vehicle
* @ param window_class WindowClass to search for
* @ param from_index the old vehicle ID
* @ param to_index the new vehicle ID
2005-11-14 19:48:04 +00:00
*/
2008-08-06 18:57:37 +00:00
static inline void ChangeVehicleWindow ( WindowClass window_class , VehicleID from_index , VehicleID to_index )
2005-10-24 19:40:48 +00:00
{
2008-08-06 18:57:37 +00:00
Window * w = FindWindowById ( window_class , from_index ) ;
2019-04-10 21:07:06 +00:00
if ( w ! = nullptr ) {
2011-02-05 23:10:31 +00:00
/* Update window_number */
2008-04-27 18:05:48 +00:00
w - > window_number = to_index ;
2019-04-10 21:07:06 +00:00
if ( w - > viewport ! = nullptr ) w - > viewport - > follow_vehicle = to_index ;
2011-02-05 23:10:31 +00:00
/* Update vehicle drag data */
if ( _thd . window_class = = window_class & & _thd . window_number = = ( WindowNumber ) from_index ) {
_thd . window_number = to_index ;
}
2011-03-13 21:33:02 +00:00
/* Notify the window. */
2012-12-20 19:44:02 +00:00
w - > InvalidateData ( VIWD_AUTOREPLACE , false ) ;
2005-10-24 19:40:48 +00:00
}
}
2006-08-29 17:41:13 +00:00
2008-08-06 18:57:37 +00:00
/**
* Report a change in vehicle IDs ( due to autoreplace ) to affected vehicle windows .
* @ param from_index the old vehicle ID
* @ param to_index the new vehicle ID
*/
void ChangeVehicleViewWindow ( VehicleID from_index , VehicleID to_index )
{
ChangeVehicleWindow ( WC_VEHICLE_VIEW , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_ORDERS , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_REFIT , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_DETAILS , from_index , to_index ) ;
ChangeVehicleWindow ( WC_VEHICLE_TIMETABLE , from_index , to_index ) ;
}
2009-03-22 21:16:57 +00:00
static const NWidgetPart _nested_vehicle_list [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_VL_CAPTION ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VL_SORT_ORDER ) , SetMinimalSize ( 81 , 12 ) , SetFill ( 0 , 1 ) , SetDataTip ( STR_BUTTON_SORT_BY , STR_TOOLTIP_SORT_ORDER ) ,
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_VL_SORT_BY_PULLDOWN ) , SetMinimalSize ( 167 , 12 ) , SetFill ( 0 , 1 ) , SetDataTip ( 0x0 , STR_TOOLTIP_SORT_CRITERIA ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2013-06-30 14:36:31 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_VL_LIST ) , SetMinimalSize ( 248 , 0 ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 1 ) , SetMatrixDataTip ( 1 , 0 , STR_NULL ) , SetScrollbar ( WID_VL_SCROLLBAR ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_VL_SCROLLBAR ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_VL_HIDE_BUTTONS ) ,
2009-03-22 21:16:57 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VL_AVAILABLE_VEHICLES ) , SetMinimalSize ( 106 , 12 ) , SetFill ( 0 , 1 ) ,
2010-07-30 12:26:58 +00:00
SetDataTip ( STR_BLACK_STRING , STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP ) ,
2012-09-23 13:28:42 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 0 , 12 ) , SetResize ( 1 , 0 ) , SetFill ( 1 , 1 ) , EndContainer ( ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_VL_MANAGE_VEHICLES_DROPDOWN ) , SetMinimalSize ( 118 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( STR_VEHICLE_LIST_MANAGE_LIST , STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VL_STOP_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( SPR_FLAG_VEH_STOPPED , STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VL_START_ALL ) , SetMinimalSize ( 12 , 12 ) , SetFill ( 0 , 1 ) ,
2009-08-05 17:59:21 +00:00
SetDataTip ( SPR_FLAG_VEH_RUNNING , STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
2009-10-25 15:08:16 +00:00
/* Widget to be shown for other companies hiding the previous 5 widgets. */
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
} ;
2009-11-26 11:34:12 +00:00
static void DrawSmallOrderList ( const Vehicle * v , int left , int right , int y , VehicleOrderID start = 0 )
2006-10-05 08:15:51 +00:00
{
2009-11-26 11:34:12 +00:00
const Order * order = v - > GetOrder ( start ) ;
2019-04-10 21:07:06 +00:00
if ( order = = nullptr ) return ;
2006-10-05 08:15:51 +00:00
2014-10-18 16:12:48 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2015-02-01 20:54:24 +00:00
int l_offset = rtl ? 0 : ScaleGUITrad ( 6 ) ;
int r_offset = rtl ? ScaleGUITrad ( 6 ) : 0 ;
2009-11-26 11:34:12 +00:00
int i = 0 ;
VehicleOrderID oid = start ;
2006-10-05 08:15:51 +00:00
2009-11-26 11:34:12 +00:00
do {
2011-01-31 20:44:15 +00:00
if ( oid = = v - > cur_real_order_index ) DrawString ( left , right , y , STR_TINY_RIGHT_ARROW , TC_BLACK ) ;
2006-10-05 08:15:51 +00:00
2008-04-05 23:36:54 +00:00
if ( order - > IsType ( OT_GOTO_STATION ) ) {
2008-04-06 07:48:51 +00:00
SetDParam ( 0 , order - > GetDestination ( ) ) ;
2014-10-18 16:12:48 +00:00
DrawString ( left + l_offset , right - r_offset , y , STR_TINY_BLACK_STATION ) ;
2006-10-05 08:15:51 +00:00
2009-11-16 21:39:47 +00:00
y + = FONT_HEIGHT_SMALL ;
2006-10-05 08:15:51 +00:00
if ( + + i = = 4 ) break ;
}
2009-11-26 11:34:12 +00:00
oid + + ;
order = order - > next ;
2019-04-10 21:07:06 +00:00
if ( order = = nullptr ) {
2009-11-26 11:34:12 +00:00
order = v - > orders . list - > GetFirstOrder ( ) ;
oid = 0 ;
}
} while ( oid ! = start ) ;
2006-10-05 08:15:51 +00:00
}
2009-07-12 16:00:11 +00:00
/**
* Draws an image of a vehicle chain
2009-11-16 22:25:01 +00:00
* @ param v Front vehicle
* @ param left The minimum horizontal position
* @ param right The maximum horizontal position
* @ param y Vertical position to draw at
2009-09-19 09:51:14 +00:00
* @ param selection Selected vehicle to draw a frame around
2009-11-16 22:25:01 +00:00
* @ param skip Number of pixels to skip at the front ( for scrolling )
2009-07-12 16:00:11 +00:00
*/
2011-11-01 16:51:47 +00:00
void DrawVehicleImage ( const Vehicle * v , int left , int right , int y , VehicleID selection , EngineImageType image_type , int skip )
2008-09-13 10:04:36 +00:00
{
switch ( v - > type ) {
2011-11-01 16:51:47 +00:00
case VEH_TRAIN : DrawTrainImage ( Train : : From ( v ) , left , right , y , selection , image_type , skip ) ; break ;
case VEH_ROAD : DrawRoadVehImage ( v , left , right , y , selection , image_type , skip ) ; break ;
case VEH_SHIP : DrawShipImage ( v , left , right , y , selection , image_type ) ; break ;
case VEH_AIRCRAFT : DrawAircraftImage ( v , left , right , y , selection , image_type ) ; break ;
2008-09-13 10:04:36 +00:00
default : NOT_REACHED ( ) ;
}
}
2009-11-16 21:28:12 +00:00
/**
* Get the height of a vehicle in the vehicle list GUIs .
* @ param type the vehicle type to look at
* @ param divisor the resulting height must be dividable by this
* @ return the height
*/
uint GetVehicleListHeight ( VehicleType type , uint divisor )
{
2009-11-16 21:39:47 +00:00
/* Name + vehicle + profit */
2015-02-01 20:54:24 +00:00
uint base = ScaleGUITrad ( GetVehicleHeight ( type ) ) + 2 * FONT_HEIGHT_SMALL ;
2009-11-16 21:39:47 +00:00
/* Drawing of the 4 small orders + profit*/
if ( type > = VEH_SHIP ) base = max ( base , 5U * FONT_HEIGHT_SMALL ) ;
2009-11-16 21:28:12 +00:00
if ( divisor = = 1 ) return base ;
/* Make sure the height is dividable by divisor */
uint rem = base % divisor ;
return base + ( rem = = 0 ? 0 : divisor - rem ) ;
}
2008-09-13 10:04:36 +00:00
/**
* Draw all the vehicle list items .
2009-10-25 13:33:56 +00:00
* @ param selected_vehicle The vehicle that is to be highlighted .
* @ param line_height Height of a single item line .
* @ param r Rectangle with edge positions of the matrix widget .
2008-09-13 10:04:36 +00:00
*/
2009-10-25 14:52:46 +00:00
void BaseVehicleListWindow : : DrawVehicleListItems ( VehicleID selected_vehicle , int line_height , const Rect & r ) const
2008-09-13 10:04:36 +00:00
{
2009-10-25 13:33:56 +00:00
int left = r . left + WD_MATRIX_LEFT ;
int right = r . right - WD_MATRIX_RIGHT ;
2009-11-17 11:36:36 +00:00
int width = right - left ;
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2009-11-16 21:28:12 +00:00
2014-10-04 16:40:23 +00:00
int text_offset = max < int > ( GetSpriteSize ( SPR_PROFIT_LOT ) . width , GetDigitWidth ( ) * this - > unitnumber_digits ) + WD_FRAMERECT_RIGHT ;
2009-11-17 09:09:20 +00:00
int text_left = left + ( rtl ? 0 : text_offset ) ;
int text_right = right - ( rtl ? text_offset : 0 ) ;
2009-11-16 21:28:12 +00:00
2010-09-09 14:40:39 +00:00
bool show_orderlist = this - > vli . vtype > = VEH_SHIP ;
2015-02-01 20:54:24 +00:00
int orderlist_left = left + ( rtl ? 0 : max ( ScaleGUITrad ( 100 ) + text_offset , width / 2 ) ) ;
int orderlist_right = right - ( rtl ? max ( ScaleGUITrad ( 100 ) + text_offset , width / 2 ) : 0 ) ;
2009-11-17 11:36:36 +00:00
int image_left = ( rtl & & show_orderlist ) ? orderlist_right : text_left ;
int image_right = ( ! rtl & & show_orderlist ) ? orderlist_left : text_right ;
2009-11-16 21:28:12 +00:00
2010-09-02 20:00:48 +00:00
int vehicle_button_x = rtl ? right - GetSpriteSize ( SPR_PROFIT_LOT ) . width : left ;
2009-11-16 21:28:12 +00:00
2009-10-25 13:33:56 +00:00
int y = r . top ;
2019-01-11 08:09:37 +00:00
uint max = min ( this - > vscroll - > GetPosition ( ) + this - > vscroll - > GetCapacity ( ) , this - > vehgroups . size ( ) ) ;
2010-08-12 08:37:01 +00:00
for ( uint i = this - > vscroll - > GetPosition ( ) ; i < max ; + + i ) {
2008-09-13 10:04:36 +00:00
2019-01-11 08:09:37 +00:00
const GUIVehicleGroup & vehgroup = this - > vehgroups [ i ] ;
2008-09-13 10:04:36 +00:00
2019-01-11 08:09:37 +00:00
SetDParam ( 0 , vehgroup . display_profit_this_year ) ;
SetDParam ( 1 , vehgroup . display_profit_last_year ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1 , STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR ) ;
2008-09-13 10:04:36 +00:00
2019-01-11 08:09:37 +00:00
DrawVehicleProfitButton ( vehgroup . age , vehgroup . display_profit_last_year , vehgroup . NumVehicles ( ) , vehicle_button_x , y + FONT_HEIGHT_NORMAL + 3 ) ;
const Vehicle * v = vehgroup . GetSingleVehicle ( ) ;
DrawVehicleImage ( v , image_left , image_right , y + FONT_HEIGHT_SMALL - 1 , selected_vehicle , EIT_IN_LIST , 0 ) ;
2020-05-17 21:31:59 +00:00
if ( ! v - > name . empty ( ) ) {
2008-09-13 10:04:36 +00:00
/* The vehicle got a name so we will print it */
SetDParam ( 0 , v - > index ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y , STR_TINY_BLACK_VEHICLE ) ;
2008-11-20 16:48:22 +00:00
} else if ( v - > group_id ! = DEFAULT_GROUP ) {
/* The vehicle has no name, but is member of a group, so print group name */
SetDParam ( 0 , v - > group_id ) ;
2009-11-16 21:28:12 +00:00
DrawString ( text_left , text_right , y , STR_TINY_GROUP , TC_BLACK ) ;
2008-09-13 10:04:36 +00:00
}
2011-01-31 20:44:15 +00:00
if ( show_orderlist ) DrawSmallOrderList ( v , orderlist_left , orderlist_right , y , v - > cur_real_order_index ) ;
2008-09-13 10:04:36 +00:00
2019-01-11 08:09:37 +00:00
StringID str ;
2012-07-07 15:39:46 +00:00
if ( v - > IsChainInDepot ( ) ) {
2009-07-23 19:31:50 +00:00
str = STR_BLUE_COMMA ;
2008-09-13 10:04:36 +00:00
} else {
2009-04-21 23:40:56 +00:00
str = ( v - > age > v - > max_age - DAYS_IN_LEAP_YEAR ) ? STR_RED_COMMA : STR_BLACK_COMMA ;
2008-09-13 10:04:36 +00:00
}
SetDParam ( 0 , v - > unitnumber ) ;
2009-08-15 11:47:11 +00:00
DrawString ( left , right , y + 2 , str ) ;
2008-09-13 10:04:36 +00:00
2009-10-25 13:33:56 +00:00
y + = line_height ;
2008-09-13 10:04:36 +00:00
}
}
2019-01-11 08:09:37 +00:00
void BaseVehicleListWindow : : UpdateSortingFromGrouping ( )
{
/* Set up sorting. Make the window-specific _sorting variable
* point to the correct global _sorting struct so we are freed
* from having conditionals during window operation */
switch ( this - > vli . vtype ) {
case VEH_TRAIN : this - > sorting = & _sorting [ this - > grouping ] . train ; break ;
case VEH_ROAD : this - > sorting = & _sorting [ this - > grouping ] . roadveh ; break ;
case VEH_SHIP : this - > sorting = & _sorting [ this - > grouping ] . ship ; break ;
case VEH_AIRCRAFT : this - > sorting = & _sorting [ this - > grouping ] . aircraft ; break ;
default : NOT_REACHED ( ) ;
}
this - > vehgroups . SetSortFuncs ( this - > vehicle_group_none_sorter_funcs ) ;
this - > vehgroups . SetListing ( * this - > sorting ) ;
this - > vehgroups . ForceRebuild ( ) ;
this - > vehgroups . NeedResort ( ) ;
}
void BaseVehicleListWindow : : UpdateVehicleGroupBy ( GroupBy group_by )
{
if ( this - > grouping ! = group_by ) {
/* Save the old sorting option, so that if we change the grouping option back later on,
* UpdateSortingFromGrouping ( ) will automatically restore the saved sorting option . */
* this - > sorting = this - > vehgroups . GetListing ( ) ;
this - > grouping = group_by ;
_grouping [ this - > vli . type ] [ this - > vli . vtype ] = group_by ;
this - > UpdateSortingFromGrouping ( ) ;
}
}
2008-05-11 15:00:11 +00:00
/**
* Window for the ( old ) vehicle listing .
*
* bitmask for w - > window_number
2008-09-30 20:39:50 +00:00
* 0 - 7 CompanyID ( owner )
2008-05-11 15:00:11 +00:00
* 8 - 10 window type ( use flags in vehicle_gui . h )
* 11 - 15 vehicle type ( using VEH_ , but can be compressed to fewer bytes if needed )
* 16 - 31 StationID or OrderID depending on window type ( bit 8 - 10 )
*/
2008-09-13 10:04:36 +00:00
struct VehicleListWindow : public BaseVehicleListWindow {
2009-10-25 15:08:16 +00:00
private :
/** Enumeration of planes of the button row at the bottom. */
enum ButtonPlanes {
BP_SHOW_BUTTONS , ///< Show the buttons.
BP_HIDE_BUTTONS , ///< Show the empty panel.
} ;
public :
2013-05-26 19:23:42 +00:00
VehicleListWindow ( WindowDesc * desc , WindowNumber window_number ) : BaseVehicleListWindow ( desc , window_number )
2008-05-11 15:00:11 +00:00
{
2013-05-26 19:23:42 +00:00
this - > CreateNestedTree ( ) ;
2010-08-12 08:37:01 +00:00
2011-12-16 16:58:55 +00:00
this - > vscroll = this - > GetScrollbar ( WID_VL_SCROLLBAR ) ;
2010-08-12 08:37:01 +00:00
2010-09-09 14:40:39 +00:00
this - > BuildVehicleList ( ) ;
2009-10-30 20:51:36 +00:00
this - > SortVehicleList ( ) ;
2008-05-11 15:00:11 +00:00
/* Set up the window widgets */
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VL_LIST ) - > tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this - > vli . vtype ;
2006-09-28 18:13:31 +00:00
2010-09-09 14:40:39 +00:00
if ( this - > vli . type = = VL_SHARED_ORDERS ) {
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VL_CAPTION ) - > widget_data = STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION ;
2009-07-20 11:12:59 +00:00
} else {
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VL_CAPTION ) - > widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this - > vli . vtype ;
2006-10-05 08:15:51 +00:00
}
2006-09-28 18:13:31 +00:00
2013-05-26 19:23:42 +00:00
this - > FinishInitNested ( window_number ) ;
2012-05-16 22:08:46 +00:00
if ( this - > vli . company ! = OWNER_NONE ) this - > owner = this - > vli . company ;
2008-05-11 15:00:11 +00:00
}
2006-08-29 17:41:13 +00:00
2008-05-11 15:00:11 +00:00
~ VehicleListWindow ( )
{
2019-01-11 08:09:37 +00:00
* this - > sorting = this - > vehgroups . GetListing ( ) ;
2006-09-28 18:13:31 +00:00
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2008-05-11 15:00:11 +00:00
{
2010-07-17 15:03:07 +00:00
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VL_LIST :
2010-09-09 14:40:39 +00:00
resize - > height = GetVehicleListHeight ( this - > vli . vtype , 1 ) ;
2010-07-17 15:03:07 +00:00
2010-09-09 14:40:39 +00:00
switch ( this - > vli . vtype ) {
2010-07-17 15:03:07 +00:00
case VEH_TRAIN :
case VEH_ROAD :
size - > height = 6 * resize - > height ;
break ;
case VEH_SHIP :
case VEH_AIRCRAFT :
size - > height = 4 * resize - > height ;
break ;
default : NOT_REACHED ( ) ;
}
2009-10-25 15:08:16 +00:00
break ;
2010-07-17 15:03:07 +00:00
2011-12-16 16:58:55 +00:00
case WID_VL_SORT_ORDER : {
2010-10-19 21:48:20 +00:00
Dimension d = GetStringBoundingBox ( this - > GetWidget < NWidgetCore > ( widget ) - > widget_data ) ;
2014-10-05 11:20:02 +00:00
d . width + = padding . width + Window : : SortButtonWidth ( ) * 2 ; // Doubled since the string is centred and it also looks better.
2010-10-19 21:48:20 +00:00
d . height + = padding . height ;
* size = maxdim ( * size , d ) ;
break ;
}
2011-12-16 16:58:55 +00:00
case WID_VL_MANAGE_VEHICLES_DROPDOWN : {
2010-09-09 14:40:39 +00:00
Dimension d = this - > GetActionDropdownSize ( this - > vli . type = = VL_STANDARD , false ) ;
2010-07-17 15:03:07 +00:00
d . height + = padding . height ;
d . width + = padding . width ;
* size = maxdim ( * size , d ) ;
2009-10-25 15:08:16 +00:00
break ;
2010-07-17 15:03:07 +00:00
}
2009-10-25 15:08:16 +00:00
}
}
2008-05-11 15:00:11 +00:00
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-10-25 15:08:16 +00:00
{
2010-07-30 12:26:58 +00:00
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VL_AVAILABLE_VEHICLES :
2010-09-09 14:40:39 +00:00
SetDParam ( 0 , STR_VEHICLE_LIST_AVAILABLE_TRAINS + this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
2006-09-28 18:13:31 +00:00
2011-12-16 16:58:55 +00:00
case WID_VL_CAPTION : {
2010-09-09 14:40:39 +00:00
switch ( this - > vli . type ) {
2010-09-08 21:37:13 +00:00
case VL_SHARED_ORDERS : // Shared Orders
2018-09-23 11:23:54 +00:00
if ( this - > vehicles . size ( ) = = 0 ) {
2010-07-30 12:26:58 +00:00
/* We can't open this window without vehicles using this order
2011-01-21 01:38:30 +00:00
* and we should close the window when deleting the order . */
2010-07-30 12:26:58 +00:00
NOT_REACHED ( ) ;
}
2019-01-11 08:09:37 +00:00
SetDParam ( 0 , this - > vehicles . size ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2006-09-28 18:13:31 +00:00
2010-09-08 21:37:13 +00:00
case VL_STANDARD : // Company Name
2010-07-30 12:26:58 +00:00
SetDParam ( 0 , STR_COMPANY_NAME ) ;
2010-09-09 14:40:39 +00:00
SetDParam ( 1 , this - > vli . index ) ;
2019-01-11 08:09:37 +00:00
SetDParam ( 3 , this - > vehicles . size ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2006-08-29 17:41:13 +00:00
2010-09-08 21:37:13 +00:00
case VL_STATION_LIST : // Station/Waypoint Name
2010-09-09 14:40:39 +00:00
SetDParam ( 0 , Station : : IsExpected ( BaseStation : : Get ( this - > vli . index ) ) ? STR_STATION_NAME : STR_WAYPOINT_NAME ) ;
SetDParam ( 1 , this - > vli . index ) ;
2019-01-11 08:09:37 +00:00
SetDParam ( 3 , this - > vehicles . size ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
2010-09-08 21:37:13 +00:00
case VL_DEPOT_LIST :
2010-07-30 12:26:58 +00:00
SetDParam ( 0 , STR_DEPOT_CAPTION ) ;
2010-09-09 14:40:39 +00:00
SetDParam ( 1 , this - > vli . vtype ) ;
SetDParam ( 2 , this - > vli . index ) ;
2019-01-11 08:09:37 +00:00
SetDParam ( 3 , this - > vehicles . size ( ) ) ;
2010-07-30 12:26:58 +00:00
break ;
default : NOT_REACHED ( ) ;
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-11 15:00:11 +00:00
}
2009-10-25 15:08:16 +00:00
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-25 15:08:16 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VL_SORT_ORDER :
2009-10-25 15:08:16 +00:00
/* draw arrow pointing up/down for ascending/descending sorting */
2019-01-11 08:09:37 +00:00
this - > DrawSortButtonState ( widget , this - > vehgroups . IsDescSortOrder ( ) ? SBS_DOWN : SBS_UP ) ;
2009-10-25 15:08:16 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VL_LIST :
2009-10-25 15:08:16 +00:00
this - > DrawVehicleListItems ( INVALID_VEHICLE , this - > resize . step_height , r ) ;
break ;
}
}
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2009-10-25 15:08:16 +00:00
{
2010-09-09 14:40:39 +00:00
this - > BuildVehicleList ( ) ;
2009-10-25 15:08:16 +00:00
this - > SortVehicleList ( ) ;
2018-09-23 11:23:54 +00:00
if ( this - > vehicles . size ( ) = = 0 & & this - > IsWidgetLowered ( WID_VL_MANAGE_VEHICLES_DROPDOWN ) ) {
2010-06-23 14:56:17 +00:00
HideDropDownMenu ( this ) ;
}
2006-09-04 15:13:49 +00:00
2009-04-13 17:19:43 +00:00
/* Hide the widgets that we will not use in this window
* Some windows contains actions only fit for the owner */
2009-10-25 15:08:16 +00:00
int plane_to_show = ( this - > owner = = _local_company ) ? BP_SHOW_BUTTONS : BP_HIDE_BUTTONS ;
2011-12-16 16:58:55 +00:00
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( WID_VL_HIDE_BUTTONS ) ;
2009-10-25 15:08:16 +00:00
if ( plane_to_show ! = nwi - > shown_plane ) {
nwi - > SetDisplayedPlane ( plane_to_show ) ;
nwi - > SetDirty ( this ) ;
}
2009-04-13 17:19:43 +00:00
if ( this - > owner = = _local_company ) {
2011-12-16 16:58:55 +00:00
this - > SetWidgetDisabledState ( WID_VL_AVAILABLE_VEHICLES , this - > vli . type ! = VL_STANDARD ) ;
2018-09-23 11:23:54 +00:00
this - > SetWidgetsDisabledState ( this - > vehicles . size ( ) = = 0 ,
2011-12-16 16:58:55 +00:00
WID_VL_MANAGE_VEHICLES_DROPDOWN ,
WID_VL_STOP_ALL ,
WID_VL_START_ALL ,
2009-04-13 17:19:43 +00:00
WIDGET_LIST_END ) ;
}
2009-03-22 21:56:40 +00:00
/* Set text of sort by dropdown widget. */
2019-01-11 08:09:37 +00:00
this - > GetWidget < NWidgetCore > ( WID_VL_SORT_BY_PULLDOWN ) - > widget_data = this - > vehicle_group_none_sorter_names [ this - > vehgroups . SortType ( ) ] ;
2009-03-22 21:56:40 +00:00
2008-05-17 12:48:06 +00:00
this - > DrawWidgets ( ) ;
2008-05-11 15:00:11 +00:00
}
2006-09-04 15:13:49 +00:00
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-11 15:00:11 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VL_SORT_ORDER : // Flip sorting method ascending/descending
2019-01-11 08:09:37 +00:00
this - > vehgroups . ToggleSortOrder ( ) ;
2008-05-11 15:00:11 +00:00
this - > SetDirty ( ) ;
break ;
2009-10-25 15:08:16 +00:00
2011-12-16 16:58:55 +00:00
case WID_VL_SORT_BY_PULLDOWN : // Select sorting criteria dropdown menu
2019-01-11 08:09:37 +00:00
ShowDropDownMenu ( this , this - > vehicle_group_none_sorter_names , this - > vehgroups . SortType ( ) , WID_VL_SORT_BY_PULLDOWN , 0 ,
2010-09-09 14:40:39 +00:00
( this - > vli . vtype = = VEH_TRAIN | | this - > vli . vtype = = VEH_ROAD ) ? 0 : ( 1 < < 10 ) ) ;
2008-05-11 15:00:11 +00:00
return ;
2009-10-25 15:08:16 +00:00
2011-12-16 16:58:55 +00:00
case WID_VL_LIST : { // Matrix to show vehicles
uint id_v = this - > vscroll - > GetScrolledRowFromWidget ( pt . y , this , WID_VL_LIST ) ;
2019-01-11 08:09:37 +00:00
if ( id_v > = this - > vehgroups . size ( ) ) return ; // click out of list bound
const GUIVehicleGroup & vehgroup = this - > vehgroups [ id_v ] ;
const Vehicle * v = vehgroup . GetSingleVehicle ( ) ;
2008-05-11 15:00:11 +00:00
2019-10-23 21:48:20 +00:00
if ( ! VehicleClicked ( v ) ) {
if ( _ctrl_pressed ) {
ShowCompanyGroupForVehicle ( v ) ;
} else {
ShowVehicleViewWindow ( v ) ;
}
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-11 15:00:11 +00:00
2011-12-16 16:58:55 +00:00
case WID_VL_AVAILABLE_VEHICLES :
2010-09-09 14:40:39 +00:00
ShowBuildVehicleWindow ( INVALID_TILE , this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VL_MANAGE_VEHICLES_DROPDOWN : {
2019-04-02 19:31:24 +00:00
ShowDropDownList ( this , this - > BuildActionDropdownList ( VehicleListIdentifier : : UnPack ( this - > window_number ) . type = = VL_STANDARD , false ) , 0 , WID_VL_MANAGE_VEHICLES_DROPDOWN ) ;
2008-05-11 15:00:11 +00:00
break ;
2006-08-29 17:41:13 +00:00
}
2011-12-16 16:58:55 +00:00
case WID_VL_STOP_ALL :
case WID_VL_START_ALL :
DoCommandP ( 0 , ( 1 < < 1 ) | ( widget = = WID_VL_START_ALL ? ( 1 < < 0 ) : 0 ) , this - > window_number , CMD_MASS_START_STOP ) ;
2008-05-11 15:00:11 +00:00
break ;
}
2006-08-29 17:41:13 +00:00
}
2008-05-11 15:00:11 +00:00
2019-03-04 07:49:37 +00:00
void OnDropdownSelect ( int widget , int index ) override
2008-05-11 15:00:11 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VL_SORT_BY_PULLDOWN :
2019-01-11 08:09:37 +00:00
this - > vehgroups . SetSortType ( index ) ;
2008-05-11 15:00:11 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VL_MANAGE_VEHICLES_DROPDOWN :
2018-09-23 11:23:54 +00:00
assert ( this - > vehicles . size ( ) ! = 0 ) ;
2008-05-11 15:00:11 +00:00
switch ( index ) {
2010-07-17 14:58:35 +00:00
case ADI_REPLACE : // Replace window
2012-07-10 17:35:10 +00:00
ShowReplaceGroupVehicleWindow ( ALL_GROUP , this - > vli . vtype ) ;
2008-05-11 15:00:11 +00:00
break ;
2010-07-17 14:58:35 +00:00
case ADI_SERVICE : // Send for servicing
case ADI_DEPOT : // Send to Depots
2010-09-09 14:40:39 +00:00
DoCommandP ( 0 , DEPOT_MASS_SEND | ( index = = ADI_SERVICE ? DEPOT_SERVICE : ( DepotCommand ) 0 ) , this - > window_number , GetCmdSendToDepot ( this - > vli . vtype ) ) ;
2008-05-11 15:00:11 +00:00
break ;
default : NOT_REACHED ( ) ;
}
break ;
default : NOT_REACHED ( ) ;
}
this - > SetDirty ( ) ;
}
2019-03-04 07:49:37 +00:00
void OnGameTick ( ) override
2008-05-11 15:00:11 +00:00
{
2019-01-11 08:09:37 +00:00
if ( this - > vehgroups . NeedResort ( ) ) {
2010-09-09 14:40:39 +00:00
StationID station = ( this - > vli . type = = VL_STATION_LIST ) ? this - > vli . index : INVALID_STATION ;
2008-05-11 15:00:11 +00:00
2010-09-09 14:40:39 +00:00
DEBUG ( misc , 3 , " Periodic resort %d list company %d at station %d " , this - > vli . vtype , this - > owner , station ) ;
2008-05-11 15:00:11 +00:00
this - > SetDirty ( ) ;
}
}
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2008-05-11 15:00:11 +00:00
{
2011-12-16 16:58:55 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_VL_LIST ) ;
2008-05-11 15:00:11 +00:00
}
2008-05-18 16:51:44 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
2019-03-04 07:49:37 +00:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2008-05-18 16:51:44 +00:00
{
2011-03-13 21:33:30 +00:00
if ( ! gui_scope & & HasBit ( data , 31 ) & & this - > vli . type = = VL_SHARED_ORDERS ) {
/* Needs to be done in command-scope, so everything stays valid */
2010-09-09 14:40:39 +00:00
this - > vli . index = GB ( data , 0 , 20 ) ;
this - > window_number = this - > vli . Pack ( ) ;
2019-01-11 08:09:37 +00:00
this - > vehgroups . ForceRebuild ( ) ;
2008-08-17 21:07:09 +00:00
return ;
}
2008-06-16 17:09:52 +00:00
if ( data = = 0 ) {
2011-03-13 21:34:21 +00:00
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
2019-01-11 08:09:37 +00:00
this - > vehgroups . ForceRebuild ( ) ;
2008-06-16 17:09:52 +00:00
} else {
2019-01-11 08:09:37 +00:00
this - > vehgroups . ForceResort ( ) ;
2008-06-16 17:09:52 +00:00
}
2008-05-18 16:51:44 +00:00
}
2008-05-11 15:00:11 +00:00
} ;
2006-09-28 23:05:03 +00:00
2013-06-30 14:38:45 +00:00
static WindowDesc _vehicle_list_other_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " list_vehicles " , 260 , 246 ,
2008-09-12 21:58:36 +00:00
WC_INVALID , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_list , lengthof ( _nested_vehicle_list )
2009-03-15 15:12:06 +00:00
) ;
2006-09-28 23:05:03 +00:00
2013-06-30 14:38:45 +00:00
static WindowDesc _vehicle_list_train_desc (
WDP_AUTO , " list_vehicles_train " , 325 , 246 ,
WC_TRAINS_LIST , WC_NONE ,
0 ,
_nested_vehicle_list , lengthof ( _nested_vehicle_list )
) ;
2013-11-11 18:58:15 +00:00
static void ShowVehicleListWindowLocal ( CompanyID company , VehicleListType vlt , VehicleType vehicle_type , uint32 unique_number )
2006-09-28 23:05:03 +00:00
{
2012-05-16 22:08:46 +00:00
if ( ! Company : : IsValidID ( company ) & & company ! = OWNER_NONE ) return ;
2006-10-31 21:15:56 +00:00
2013-06-30 14:38:45 +00:00
WindowNumber num = VehicleListIdentifier ( vlt , vehicle_type , company , unique_number ) . Pack ( ) ;
if ( vehicle_type = = VEH_TRAIN ) {
AllocateWindowDescFront < VehicleListWindow > ( & _vehicle_list_train_desc , num ) ;
} else {
_vehicle_list_other_desc . cls = GetWindowClassForVehicleType ( vehicle_type ) ;
AllocateWindowDescFront < VehicleListWindow > ( & _vehicle_list_other_desc , num ) ;
}
2006-09-28 23:05:03 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type )
2006-09-28 23:05:03 +00:00
{
2008-05-29 15:13:28 +00:00
/* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list
2008-09-30 20:39:50 +00:00
* if _settings_client . gui . advanced_vehicle_list = = 1 , display Advanced list only for local company
2007-09-09 10:34:32 +00:00
* if _ctrl_pressed , do the opposite action ( Advanced list x Normal list )
*/
2008-09-30 20:39:50 +00:00
if ( ( _settings_client . gui . advanced_vehicle_list > ( uint ) ( company ! = _local_company ) ) ! = _ctrl_pressed ) {
ShowCompanyGroup ( company , vehicle_type ) ;
2007-05-19 09:40:18 +00:00
} else {
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_STANDARD , vehicle_type , company ) ;
2007-05-19 09:40:18 +00:00
}
2006-09-28 23:05:03 +00:00
}
2007-01-21 00:01:47 +00:00
void ShowVehicleListWindow ( const Vehicle * v )
2006-09-28 23:05:03 +00:00
{
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( v - > owner , VL_SHARED_ORDERS , v - > type , v - > FirstShared ( ) - > index ) ;
2007-01-21 00:01:47 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type , StationID station )
2007-01-21 00:01:47 +00:00
{
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_STATION_LIST , vehicle_type , station ) ;
2006-09-30 13:39:34 +00:00
}
2008-09-30 20:39:50 +00:00
void ShowVehicleListWindow ( CompanyID company , VehicleType vehicle_type , TileIndex depot_tile )
2006-09-30 13:39:34 +00:00
{
uint16 depot_airport_index ;
2007-03-08 16:27:54 +00:00
if ( vehicle_type = = VEH_AIRCRAFT ) {
2006-09-30 13:39:34 +00:00
depot_airport_index = GetStationIndex ( depot_tile ) ;
} else {
2009-09-10 14:37:55 +00:00
depot_airport_index = GetDepotIndex ( depot_tile ) ;
2006-09-30 13:39:34 +00:00
}
2010-09-08 21:37:13 +00:00
ShowVehicleListWindowLocal ( company , VL_DEPOT_LIST , vehicle_type , depot_airport_index ) ;
2006-09-29 07:30:44 +00:00
}
2007-08-29 20:50:58 +00:00
2007-09-05 23:26:45 +00:00
/* Unified vehicle GUI - Vehicle Details Window */
2011-12-16 16:58:55 +00:00
assert_compile ( WID_VD_DETAILS_CARGO_CARRIED = = WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_CARGO ) ;
assert_compile ( WID_VD_DETAILS_TRAIN_VEHICLES = = WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_INFO ) ;
assert_compile ( WID_VD_DETAILS_CAPACITY_OF_EACH = = WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_CAPACITY ) ;
assert_compile ( WID_VD_DETAILS_TOTAL_CARGO = = WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_TOTALS ) ;
2009-05-31 14:04:19 +00:00
2009-10-25 21:42:04 +00:00
/** Vehicle details widgets (other than train). */
static const NWidgetPart _nested_nontrain_vehicle_details_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_VD_CAPTION ) , SetDataTip ( STR_VEHICLE_DETAILS_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_RENAME_VEHICLE ) , SetMinimalSize ( 40 , 0 ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetDataTip ( STR_VEHICLE_NAME_BUTTON , STR_NULL /* filled in later */ ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-10-25 21:42:04 +00:00
EndContainer ( ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VD_TOP_DETAILS ) , SetMinimalSize ( 405 , 42 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VD_MIDDLE_DETAILS ) , SetMinimalSize ( 405 , 45 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-11-23 16:18:01 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , WID_VD_DECREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_DECREASE , STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , WID_VD_INCREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_INCREASE , STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2013-02-14 17:11:42 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_VD_SERVICE_INTERVAL_DROPDOWN ) , SetFill ( 0 , 1 ) ,
SetDataTip ( STR_EMPTY , STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VD_SERVICING_INTERVAL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-10-25 21:42:04 +00:00
EndContainer ( ) ,
2007-09-05 23:26:45 +00:00
} ;
2009-10-25 21:42:04 +00:00
/** Train details widgets. */
static const NWidgetPart _nested_train_vehicle_details_widgets [ ] = {
2009-04-13 14:09:56 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_VD_CAPTION ) , SetDataTip ( STR_VEHICLE_DETAILS_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_RENAME_VEHICLE ) , SetMinimalSize ( 40 , 0 ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetDataTip ( STR_VEHICLE_NAME_BUTTON , STR_NULL /* filled in later */ ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VD_TOP_DETAILS ) , SetResize ( 1 , 0 ) , SetMinimalSize ( 405 , 42 ) , EndContainer ( ) ,
2009-04-13 14:09:56 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2013-06-30 14:36:31 +00:00
NWidget ( WWT_MATRIX , COLOUR_GREY , WID_VD_MATRIX ) , SetResize ( 1 , 1 ) , SetMinimalSize ( 393 , 45 ) , SetMatrixDataTip ( 1 , 0 , STR_NULL ) , SetFill ( 1 , 0 ) , SetScrollbar ( WID_VD_SCROLLBAR ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_VSCROLLBAR , COLOUR_GREY , WID_VD_SCROLLBAR ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
2009-11-23 16:18:01 +00:00
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , WID_VD_DECREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( AWV_DECREASE , STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHARROWBTN , COLOUR_GREY , WID_VD_INCREASE_SERVICING_INTERVAL ) , SetFill ( 0 , 1 ) ,
2017-08-20 08:28:05 +00:00
SetDataTip ( AWV_INCREASE , STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP ) ,
2013-02-14 17:11:42 +00:00
NWidget ( WWT_DROPDOWN , COLOUR_GREY , WID_VD_SERVICE_INTERVAL_DROPDOWN ) , SetFill ( 0 , 1 ) ,
SetDataTip ( STR_EMPTY , STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_VD_SERVICING_INTERVAL ) , SetFill ( 1 , 1 ) , SetResize ( 1 , 0 ) , EndContainer ( ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_DETAILS_CARGO_CARRIED ) , SetMinimalSize ( 96 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_CARGO , STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_DETAILS_TRAIN_VEHICLES ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_INFORMATION , STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_DETAILS_CAPACITY_OF_EACH ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_CAPACITIES , STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHTXTBTN , COLOUR_GREY , WID_VD_DETAILS_TOTAL_CARGO ) , SetMinimalSize ( 99 , 12 ) ,
2009-11-23 16:18:01 +00:00
SetDataTip ( STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO , STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP ) , SetFill ( 1 , 0 ) , SetResize ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-04-13 14:09:56 +00:00
EndContainer ( ) ,
} ;
2007-09-05 23:26:45 +00:00
2009-05-31 14:04:19 +00:00
extern int GetTrainDetailsWndVScroll ( VehicleID veh_id , TrainDetailsWindowTabs det_tab ) ;
2009-07-01 23:57:20 +00:00
extern void DrawTrainDetails ( const Train * v , int left , int right , int y , int vscroll_pos , uint16 vscroll_cap , TrainDetailsWindowTabs det_tab ) ;
2009-03-22 10:37:51 +00:00
extern void DrawRoadVehDetails ( const Vehicle * v , int left , int right , int y ) ;
extern void DrawShipDetails ( const Vehicle * v , int left , int right , int y ) ;
2009-07-13 16:37:27 +00:00
extern void DrawAircraftDetails ( const Aircraft * v , int left , int right , int y ) ;
2007-09-05 23:26:45 +00:00
2013-02-14 17:11:42 +00:00
static StringID _service_interval_dropdown [ ] = {
STR_VEHICLE_DETAILS_DEFAULT ,
STR_VEHICLE_DETAILS_DAYS ,
STR_VEHICLE_DETAILS_PERCENT ,
INVALID_STRING_ID ,
} ;
2009-10-25 21:42:04 +00:00
/** Class for managing the vehicle details window. */
2008-05-16 17:33:09 +00:00
struct VehicleDetailsWindow : Window {
2009-10-25 21:42:04 +00:00
TrainDetailsWindowTabs tab ; ///< For train vehicles: which tab is displayed.
2010-08-12 08:37:01 +00:00
Scrollbar * vscroll ;
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/** Initialize a newly created vehicle details window */
2013-05-26 19:23:42 +00:00
VehicleDetailsWindow ( WindowDesc * desc , WindowNumber window_number ) : Window ( desc )
2008-05-16 17:33:09 +00:00
{
2010-08-12 08:37:01 +00:00
const Vehicle * v = Vehicle : : Get ( window_number ) ;
2009-10-25 21:42:04 +00:00
2013-05-26 19:23:42 +00:00
this - > CreateNestedTree ( ) ;
2019-04-10 21:07:06 +00:00
this - > vscroll = ( v - > type = = VEH_TRAIN ? this - > GetScrollbar ( WID_VD_SCROLLBAR ) : nullptr ) ;
2013-05-26 19:23:42 +00:00
this - > FinishInitNested ( window_number ) ;
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VD_RENAME_VEHICLE ) - > tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v - > type ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
this - > owner = v - > owner ;
this - > tab = TDW_TAB_CARGO ;
}
2007-09-05 23:26:45 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
2019-03-04 07:49:37 +00:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2010-04-01 18:30:00 +00:00
{
2012-12-20 19:44:02 +00:00
if ( data = = VIWD_AUTOREPLACE ) {
2011-03-08 19:41:58 +00:00
/* Autoreplace replaced the vehicle.
2011-03-13 21:33:02 +00:00
* Nothing to do for this window . */
2011-03-08 19:41:58 +00:00
return ;
}
2011-03-13 21:33:02 +00:00
if ( ! gui_scope ) return ;
2010-04-01 18:30:00 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
if ( v - > type = = VEH_ROAD ) {
2011-12-16 16:58:55 +00:00
const NWidgetBase * nwid_info = this - > GetWidget < NWidgetBase > ( WID_VD_MIDDLE_DETAILS ) ;
2010-04-01 18:30:00 +00:00
uint aimed_height = this - > GetRoadVehDetailsHeight ( v ) ;
/* If the number of articulated parts changes, the size of the window must change too. */
if ( aimed_height ! = nwid_info - > current_y ) {
this - > ReInit ( ) ;
}
}
}
/**
* Gets the desired height for the road vehicle details panel .
* @ param v Road vehicle being shown .
* @ return Desired height in pixels .
*/
uint GetRoadVehDetailsHeight ( const Vehicle * v )
{
uint desired_height ;
2011-01-29 17:30:25 +00:00
if ( v - > HasArticulatedPart ( ) ) {
2010-04-01 18:30:00 +00:00
/* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
2015-02-01 20:54:24 +00:00
desired_height = WD_FRAMERECT_TOP + ScaleGUITrad ( 15 ) + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM ;
2010-04-01 18:30:00 +00:00
/* Add space for the cargo amount for each part. */
2019-04-10 21:07:06 +00:00
for ( const Vehicle * u = v ; u ! = nullptr ; u = u - > Next ( ) ) {
2010-04-01 18:30:00 +00:00
if ( u - > cargo_cap ! = 0 ) desired_height + = FONT_HEIGHT_NORMAL + 1 ;
}
} else {
desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM ;
}
return desired_height ;
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-10-25 21:42:04 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VD_TOP_DETAILS : {
2009-12-09 22:25:12 +00:00
Dimension dim = { 0 , 0 } ;
2009-10-25 21:42:04 +00:00
size - > height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM ;
2009-12-09 22:25:12 +00:00
2012-12-08 17:18:51 +00:00
for ( uint i = 0 ; i < 4 ; i + + ) SetDParamMaxValue ( i , INT16_MAX ) ;
2009-12-09 22:25:12 +00:00
static const StringID info_strings [ ] = {
STR_VEHICLE_INFO_MAX_SPEED ,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED ,
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE ,
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR ,
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
} ;
for ( uint i = 0 ; i < lengthof ( info_strings ) ; i + + ) {
dim = maxdim ( dim , GetStringBoundingBox ( info_strings [ i ] ) ) ;
}
SetDParam ( 0 , STR_VEHICLE_INFO_AGE ) ;
dim = maxdim ( dim , GetStringBoundingBox ( STR_VEHICLE_INFO_AGE_RUNNING_COST_YR ) ) ;
size - > width = dim . width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
case WID_VD_MIDDLE_DETAILS : {
2009-10-25 21:42:04 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
switch ( v - > type ) {
case VEH_ROAD :
2010-04-01 18:30:00 +00:00
size - > height = this - > GetRoadVehDetailsHeight ( v ) ;
2009-10-25 21:42:04 +00:00
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VEH_SHIP :
size - > height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM ;
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
case VEH_AIRCRAFT :
size - > height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM ;
break ;
2007-09-05 23:26:45 +00:00
2009-10-25 21:42:04 +00:00
default :
2011-12-16 16:58:55 +00:00
NOT_REACHED ( ) ; // Train uses WID_VD_MATRIX instead.
2009-10-25 21:42:04 +00:00
}
2008-05-16 17:33:09 +00:00
break ;
2009-10-25 21:42:04 +00:00
}
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
case WID_VD_MATRIX :
2015-02-01 20:54:24 +00:00
resize - > height = max ( ScaleGUITrad ( 14 ) , WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM ) ;
2009-10-25 21:42:04 +00:00
size - > height = 4 * resize - > height ;
2008-05-16 17:33:09 +00:00
break ;
2007-09-05 23:26:45 +00:00
2013-02-14 17:11:42 +00:00
case WID_VD_SERVICE_INTERVAL_DROPDOWN : {
StringID * strs = _service_interval_dropdown ;
while ( * strs ! = INVALID_STRING_ID ) {
* size = maxdim ( * size , GetStringBoundingBox ( * strs + + ) ) ;
}
size - > width + = padding . width ;
size - > height = FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM ;
break ;
}
2011-12-16 16:58:55 +00:00
case WID_VD_SERVICING_INTERVAL :
2012-12-08 17:18:51 +00:00
SetDParamMaxValue ( 0 , MAX_SERVINT_DAYS ) ; // Roughly the maximum interval
SetDParamMaxValue ( 1 , MAX_YEAR * DAYS_IN_YEAR ) ; // Roughly the maximum year
2009-11-23 16:18:01 +00:00
size - > width = max ( GetStringBoundingBox ( STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT ) . width , GetStringBoundingBox ( STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS ) . width ) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2009-10-25 21:42:04 +00:00
size - > height = WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM ;
break ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
}
2008-05-16 17:33:09 +00:00
/** Checks whether service interval is enabled for the vehicle. */
2009-05-26 21:59:49 +00:00
static bool IsVehicleServiceIntervalEnabled ( const VehicleType vehicle_type , CompanyID company_id )
2008-05-16 17:33:09 +00:00
{
2009-05-26 21:59:49 +00:00
const VehicleDefaultSettings * vds = & Company : : Get ( company_id ) - > settings . vehicle ;
2008-05-16 17:33:09 +00:00
switch ( vehicle_type ) {
default : NOT_REACHED ( ) ;
2009-05-26 21:59:49 +00:00
case VEH_TRAIN : return vds - > servint_trains ! = 0 ;
case VEH_ROAD : return vds - > servint_roadveh ! = 0 ;
case VEH_SHIP : return vds - > servint_ships ! = 0 ;
case VEH_AIRCRAFT : return vds - > servint_aircraft ! = 0 ;
2008-05-16 17:33:09 +00:00
}
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/**
2009-03-22 10:37:51 +00:00
* Draw the details for the given vehicle at the position of the Details windows
2008-05-16 17:33:09 +00:00
*
2009-03-22 10:37:51 +00:00
* @ param v current vehicle
* @ param left The left most coordinate to draw
* @ param right The right most coordinate to draw
* @ param y The y coordinate
2009-05-31 14:04:19 +00:00
* @ param vscroll_pos Position of scrollbar ( train only )
* @ param vscroll_cap Number of lines currently displayed ( train only )
* @ param det_tab Selected details tab ( train only )
2008-05-16 17:33:09 +00:00
*/
2009-05-31 14:04:19 +00:00
static void DrawVehicleDetails ( const Vehicle * v , int left , int right , int y , int vscroll_pos , uint vscroll_cap , TrainDetailsWindowTabs det_tab )
2008-05-16 17:33:09 +00:00
{
switch ( v - > type ) {
2009-07-01 23:57:20 +00:00
case VEH_TRAIN : DrawTrainDetails ( Train : : From ( v ) , left , right , y , vscroll_pos , vscroll_cap , det_tab ) ; break ;
2009-03-22 10:37:51 +00:00
case VEH_ROAD : DrawRoadVehDetails ( v , left , right , y ) ; break ;
case VEH_SHIP : DrawShipDetails ( v , left , right , y ) ; break ;
2009-07-13 16:37:27 +00:00
case VEH_AIRCRAFT : DrawAircraftDetails ( Aircraft : : From ( v ) , left , right , y ) ; break ;
2008-05-16 17:33:09 +00:00
default : NOT_REACHED ( ) ;
}
2007-09-05 23:26:45 +00:00
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-10-25 21:42:04 +00:00
{
2011-12-16 16:58:55 +00:00
if ( widget = = WID_VD_CAPTION ) SetDParam ( 0 , Vehicle : : Get ( this - > window_number ) - > index ) ;
2009-10-25 21:42:04 +00:00
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-25 21:42:04 +00:00
{
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2009-10-27 20:50:47 +00:00
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VD_TOP_DETAILS : {
2009-10-27 20:50:47 +00:00
int y = r . top + WD_FRAMERECT_TOP ;
/* Draw running cost */
SetDParam ( 1 , v - > age / DAYS_IN_LEAP_YEAR ) ;
SetDParam ( 0 , ( v - > age + DAYS_IN_YEAR < v - > max_age ) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED ) ;
SetDParam ( 2 , v - > max_age / DAYS_IN_LEAP_YEAR ) ;
SetDParam ( 3 , v - > GetDisplayRunningCost ( ) ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_AGE_RUNNING_COST_YR ) ;
y + = FONT_HEIGHT_NORMAL ;
/* Draw max speed */
2010-12-14 21:31:00 +00:00
StringID string ;
if ( v - > type = = VEH_TRAIN | |
( v - > type = = VEH_ROAD & & _settings_game . vehicle . roadveh_acceleration_model ! = AM_ORIGINAL ) ) {
const GroundVehicleCache * gcache = v - > GetGroundVehicleCache ( ) ;
SetDParam ( 2 , v - > GetDisplayMaxSpeed ( ) ) ;
SetDParam ( 1 , gcache - > cached_power ) ;
SetDParam ( 0 , gcache - > cached_weight ) ;
SetDParam ( 3 , gcache - > cached_max_te / 1000 ) ;
if ( v - > type = = VEH_TRAIN & & ( _settings_game . vehicle . train_acceleration_model = = AM_ORIGINAL | |
GetRailTypeInfo ( Train : : From ( v ) - > railtype ) - > acceleration_type = = 2 ) ) {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED ;
} else {
string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE ;
}
} else {
SetDParam ( 0 , v - > GetDisplayMaxSpeed ( ) ) ;
2017-03-18 20:43:43 +00:00
if ( v - > type = = VEH_AIRCRAFT ) {
SetDParam ( 1 , v - > GetEngine ( ) - > GetAircraftTypeText ( ) ) ;
if ( Aircraft : : From ( v ) - > GetRange ( ) > 0 ) {
SetDParam ( 2 , Aircraft : : From ( v ) - > GetRange ( ) ) ;
string = STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE ;
} else {
string = STR_VEHICLE_INFO_MAX_SPEED_TYPE ;
}
2011-12-13 00:43:35 +00:00
} else {
string = STR_VEHICLE_INFO_MAX_SPEED ;
}
2009-10-27 20:50:47 +00:00
}
2010-12-14 21:31:00 +00:00
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , string ) ;
2009-10-27 20:50:47 +00:00
y + = FONT_HEIGHT_NORMAL ;
/* Draw profit */
SetDParam ( 0 , v - > GetDisplayProfitThisYear ( ) ) ;
SetDParam ( 1 , v - > GetDisplayProfitLastYear ( ) ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR ) ;
y + = FONT_HEIGHT_NORMAL ;
/* Draw breakdown & reliability */
SetDParam ( 0 , ToPercent16 ( v - > reliability ) ) ;
SetDParam ( 1 , v - > breakdowns_since_last_service ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , y , STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS ) ;
break ;
}
2011-12-16 16:58:55 +00:00
case WID_VD_MATRIX :
2009-10-27 20:50:47 +00:00
/* For trains only. */
2010-08-12 08:37:01 +00:00
DrawVehicleDetails ( v , r . left + WD_MATRIX_LEFT , r . right - WD_MATRIX_RIGHT , r . top + WD_MATRIX_TOP , this - > vscroll - > GetPosition ( ) , this - > vscroll - > GetCapacity ( ) , this - > tab ) ;
2009-10-27 20:50:47 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VD_MIDDLE_DETAILS : {
2009-10-27 20:50:47 +00:00
/* For other vehicles, at the place of the matrix. */
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2016-10-16 14:56:05 +00:00
uint sprite_width = GetSingleVehicleWidth ( v , EIT_IN_DETAILS ) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT ;
2009-11-17 15:05:12 +00:00
uint text_left = r . left + ( rtl ? 0 : sprite_width ) ;
uint text_right = r . right - ( rtl ? sprite_width : 0 ) ;
2010-07-11 13:14:08 +00:00
/* Articulated road vehicles use a complete line. */
2011-01-29 17:30:25 +00:00
if ( v - > type = = VEH_ROAD & & v - > HasArticulatedPart ( ) ) {
2011-11-01 16:51:47 +00:00
DrawVehicleImage ( v , r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , 0 ) ;
2010-07-11 13:14:08 +00:00
} else {
uint sprite_left = rtl ? text_right : r . left ;
uint sprite_right = rtl ? r . right : text_left ;
2011-11-01 16:51:47 +00:00
DrawVehicleImage ( v , sprite_left + WD_FRAMERECT_LEFT , sprite_right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , INVALID_VEHICLE , EIT_IN_DETAILS , 0 ) ;
2010-07-11 13:14:08 +00:00
}
2010-08-12 13:26:44 +00:00
DrawVehicleDetails ( v , text_left + WD_FRAMERECT_LEFT , text_right - WD_FRAMERECT_RIGHT , r . top + WD_FRAMERECT_TOP , 0 , 0 , this - > tab ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2009-10-27 20:50:47 +00:00
2011-12-16 16:58:55 +00:00
case WID_VD_SERVICING_INTERVAL :
2009-10-27 20:50:47 +00:00
/* Draw service interval text */
2013-02-14 17:04:01 +00:00
SetDParam ( 0 , v - > GetServiceInterval ( ) ) ;
2009-10-27 20:50:47 +00:00
SetDParam ( 1 , v - > date_of_last_service ) ;
DrawString ( r . left + WD_FRAMERECT_LEFT , r . right - WD_FRAMERECT_RIGHT , r . top + ( r . bottom - r . top + 1 - FONT_HEIGHT_NORMAL ) / 2 ,
2013-02-14 17:06:49 +00:00
v - > ServiceIntervalIsPercent ( ) ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS ) ;
2009-10-27 20:50:47 +00:00
break ;
}
2009-10-25 21:42:04 +00:00
}
2008-05-16 17:33:09 +00:00
/** Repaint vehicle details window. */
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2008-05-16 17:33:09 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
this - > SetWidgetDisabledState ( WID_VD_RENAME_VEHICLE , v - > owner ! = _local_company ) ;
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
if ( v - > type = = VEH_TRAIN ) {
2011-12-16 16:58:55 +00:00
this - > DisableWidget ( this - > tab + WID_VD_DETAILS_CARGO_CARRIED ) ;
2010-08-12 08:37:01 +00:00
this - > vscroll - > SetCount ( GetTrainDetailsWndVScroll ( v - > index , this - > tab ) ) ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
2008-05-16 17:33:09 +00:00
/* Disable service-scroller when interval is set to disabled */
2009-05-26 21:59:49 +00:00
this - > SetWidgetsDisabledState ( ! IsVehicleServiceIntervalEnabled ( v - > type , v - > owner ) ,
2011-12-16 16:58:55 +00:00
WID_VD_INCREASE_SERVICING_INTERVAL ,
WID_VD_DECREASE_SERVICING_INTERVAL ,
2008-05-16 17:33:09 +00:00
WIDGET_LIST_END ) ;
2007-09-05 23:26:45 +00:00
2013-02-14 17:11:42 +00:00
StringID str = v - > ServiceIntervalIsCustom ( ) ?
( v - > ServiceIntervalIsPercent ( ) ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_DAYS ) :
STR_VEHICLE_DETAILS_DEFAULT ;
this - > GetWidget < NWidgetCore > ( WID_VD_SERVICE_INTERVAL_DROPDOWN ) - > widget_data = str ;
2013-02-14 17:06:49 +00:00
2008-05-17 12:48:06 +00:00
this - > DrawWidgets ( ) ;
2008-05-16 17:33:09 +00:00
}
2007-09-05 23:26:45 +00:00
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-16 17:33:09 +00:00
{
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VD_RENAME_VEHICLE : { // rename
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-16 17:33:09 +00:00
SetDParam ( 0 , v - > index ) ;
2009-10-25 21:42:04 +00:00
ShowQueryString ( STR_VEHICLE_NAME , STR_QUERY_RENAME_TRAIN_CAPTION + v - > type ,
2011-04-17 18:42:17 +00:00
MAX_LENGTH_VEHICLE_NAME_CHARS , this , CS_ALPHANUMERAL , QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
case WID_VD_INCREASE_SERVICING_INTERVAL : // increase int
case WID_VD_DECREASE_SERVICING_INTERVAL : { // decrease int
2008-05-16 17:33:09 +00:00
int mod = _ctrl_pressed ? 5 : 10 ;
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
mod = ( widget = = WID_VD_DECREASE_SERVICING_INTERVAL ) ? - mod : mod ;
2013-02-14 17:06:49 +00:00
mod = GetServiceIntervalClamped ( mod + v - > GetServiceInterval ( ) , v - > ServiceIntervalIsPercent ( ) ) ;
2013-02-14 17:04:01 +00:00
if ( mod = = v - > GetServiceInterval ( ) ) return ;
2007-09-05 23:26:45 +00:00
2013-02-14 17:06:49 +00:00
DoCommandP ( v - > tile , v - > index , mod | ( 1 < < 16 ) | ( v - > ServiceIntervalIsPercent ( ) < < 17 ) , CMD_CHANGE_SERVICE_INT | CMD_MSG ( STR_ERROR_CAN_T_CHANGE_SERVICING ) ) ;
break ;
}
2013-02-14 17:11:42 +00:00
case WID_VD_SERVICE_INTERVAL_DROPDOWN : {
2013-02-14 17:06:49 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2013-02-14 17:11:42 +00:00
ShowDropDownMenu ( this , _service_interval_dropdown , v - > ServiceIntervalIsCustom ( ) ? ( v - > ServiceIntervalIsPercent ( ) ? 2 : 1 ) : 0 , widget , 0 , 0 ) ;
2010-08-01 18:53:30 +00:00
break ;
}
2007-09-05 23:26:45 +00:00
2011-12-16 16:58:55 +00:00
case WID_VD_DETAILS_CARGO_CARRIED :
case WID_VD_DETAILS_TRAIN_VEHICLES :
case WID_VD_DETAILS_CAPACITY_OF_EACH :
case WID_VD_DETAILS_TOTAL_CARGO :
2008-05-16 17:33:09 +00:00
this - > SetWidgetsDisabledState ( false ,
2011-12-16 16:58:55 +00:00
WID_VD_DETAILS_CARGO_CARRIED ,
WID_VD_DETAILS_TRAIN_VEHICLES ,
WID_VD_DETAILS_CAPACITY_OF_EACH ,
WID_VD_DETAILS_TOTAL_CARGO ,
2008-05-16 17:33:09 +00:00
widget ,
WIDGET_LIST_END ) ;
2011-12-16 16:58:55 +00:00
this - > tab = ( TrainDetailsWindowTabs ) ( widget - WID_VD_DETAILS_CARGO_CARRIED ) ;
2008-05-16 17:33:09 +00:00
this - > SetDirty ( ) ;
break ;
}
}
2007-09-05 23:26:45 +00:00
2019-03-04 07:49:37 +00:00
void OnDropdownSelect ( int widget , int index ) override
2013-02-14 17:11:42 +00:00
{
switch ( widget ) {
case WID_VD_SERVICE_INTERVAL_DROPDOWN : {
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
bool iscustom = index ! = 0 ;
bool ispercent = iscustom ? ( index = = 2 ) : Company : : Get ( v - > owner ) - > settings . vehicle . servint_ispercent ;
uint16 interval = GetServiceIntervalClamped ( v - > GetServiceInterval ( ) , ispercent ) ;
DoCommandP ( v - > tile , v - > index , interval | ( iscustom < < 16 ) | ( ispercent < < 17 ) , CMD_CHANGE_SERVICE_INT | CMD_MSG ( STR_ERROR_CAN_T_CHANGE_SERVICING ) ) ;
break ;
}
}
}
2019-03-04 07:49:37 +00:00
void OnQueryTextFinished ( char * str ) override
2008-05-16 17:33:09 +00:00
{
2019-04-10 21:07:06 +00:00
if ( str = = nullptr ) return ;
2008-09-15 19:02:50 +00:00
2019-04-10 21:07:06 +00:00
DoCommandP ( 0 , this - > window_number , 0 , CMD_RENAME_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle : : Get ( this - > window_number ) - > type ) , nullptr , str ) ;
2007-09-05 23:26:45 +00:00
}
2008-05-16 17:33:09 +00:00
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2008-05-16 17:33:09 +00:00
{
2011-12-16 16:58:55 +00:00
NWidgetCore * nwi = this - > GetWidget < NWidgetCore > ( WID_VD_MATRIX ) ;
2019-04-10 21:07:06 +00:00
if ( nwi ! = nullptr ) {
2011-12-16 16:58:55 +00:00
this - > vscroll - > SetCapacityFromWidget ( this , WID_VD_MATRIX ) ;
2009-10-25 21:42:04 +00:00
}
2008-05-16 17:33:09 +00:00
}
} ;
2007-09-05 23:26:45 +00:00
/** Vehicle details window descriptor. */
2013-05-26 19:23:42 +00:00
static WindowDesc _train_vehicle_details_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " view_vehicle_details_train " , 405 , 178 ,
2009-10-25 21:42:04 +00:00
WC_VEHICLE_DETAILS , WC_VEHICLE_VIEW ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_train_vehicle_details_widgets , lengthof ( _nested_train_vehicle_details_widgets )
2009-10-25 21:42:04 +00:00
) ;
/** Vehicle details window descriptor for other vehicles than a train. */
2013-05-26 19:23:42 +00:00
static WindowDesc _nontrain_vehicle_details_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " view_vehicle_details " , 405 , 113 ,
2007-09-05 23:26:45 +00:00
WC_VEHICLE_DETAILS , WC_VEHICLE_VIEW ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_nontrain_vehicle_details_widgets , lengthof ( _nested_nontrain_vehicle_details_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-09-05 23:26:45 +00:00
/** Shows the vehicle details window of the given vehicle. */
static void ShowVehicleDetailsWindow ( const Vehicle * v )
{
2009-01-03 23:32:59 +00:00
DeleteWindowById ( WC_VEHICLE_ORDERS , v - > index , false ) ;
DeleteWindowById ( WC_VEHICLE_TIMETABLE , v - > index , false ) ;
2009-10-25 21:42:04 +00:00
AllocateWindowDescFront < VehicleDetailsWindow > ( ( v - > type = = VEH_TRAIN ) ? & _train_vehicle_details_desc : & _nontrain_vehicle_details_desc , v - > index ) ;
2007-09-05 23:26:45 +00:00
}
2007-08-29 20:50:58 +00:00
/* Unified vehicle GUI - Vehicle View Window */
/** Vehicle view widgets. */
2009-05-03 13:13:41 +00:00
static const NWidgetPart _nested_vehicle_view_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_CAPTION , COLOUR_GREY , WID_VV_CAPTION ) , SetDataTip ( STR_VEHICLE_VIEW_CAPTION , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2010-04-24 13:39:11 +00:00
NWidget ( WWT_DEBUGBOX , COLOUR_GREY ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
2013-05-26 19:30:07 +00:00
NWidget ( WWT_DEFSIZEBOX , COLOUR_GREY ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 21:13:36 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
NWidget ( WWT_INSET , COLOUR_GREY ) , SetPadding ( 2 , 2 , 2 , 2 ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_VIEWPORT , INVALID_COLOUR , WID_VV_VIEWPORT ) , SetMinimalSize ( 226 , 84 ) , SetResize ( 1 , 1 ) , SetPadding ( 1 , 1 , 1 , 1 ) ,
2009-10-24 13:58:18 +00:00
EndContainer ( ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
NWidget ( NWID_VERTICAL ) ,
2016-04-17 20:20:52 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_CENTER_MAIN_VIEW ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_CENTRE_VIEW_VEHICLE , 0x0 /* filled later */ ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_VV_SELECT_DEPOT_CLONE ) ,
2016-04-17 20:20:52 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_GOTO_DEPOT ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( 0x0 /* filled later */ , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_CLONE ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( 0x0 /* filled later */ , 0x0 /* filled later */ ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
2009-10-24 13:49:04 +00:00
/* For trains only, 'ignore signal' button. */
2016-04-17 20:20:52 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_FORCE_PROCEED ) , SetMinimalSize ( 18 , 18 ) ,
2009-10-24 13:49:04 +00:00
SetDataTip ( SPR_IGNORE_SIGNALS , STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP ) ,
2011-12-16 16:58:55 +00:00
NWidget ( NWID_SELECTION , INVALID_COLOUR , WID_VV_SELECT_REFIT_TURN ) ,
2016-04-17 20:20:52 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_REFIT ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_REFIT_VEHICLE , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_TURN_AROUND ) , SetMinimalSize ( 18 , 18 ) ,
2009-07-22 22:44:56 +00:00
SetDataTip ( SPR_FORCE_VEHICLE_TURN , STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
2016-04-17 20:20:52 +00:00
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_SHOW_ORDERS ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_SHOW_ORDERS , 0x0 /* filled later */ ) ,
NWidget ( WWT_PUSHIMGBTN , COLOUR_GREY , WID_VV_SHOW_DETAILS ) , SetMinimalSize ( 18 , 18 ) , SetDataTip ( SPR_SHOW_VEHICLE_DETAILS , 0x0 /* filled later */ ) ,
NWidget ( WWT_PANEL , COLOUR_GREY ) , SetMinimalSize ( 18 , 0 ) , SetResize ( 0 , 1 ) , EndContainer ( ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
EndContainer ( ) ,
NWidget ( NWID_HORIZONTAL ) ,
2011-12-16 16:58:55 +00:00
NWidget ( WWT_PUSHBTN , COLOUR_GREY , WID_VV_START_STOP ) , SetMinimalTextLines ( 1 , WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2 ) , SetResize ( 1 , 0 ) , SetFill ( 1 , 0 ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_RESIZEBOX , COLOUR_GREY ) ,
2009-05-03 13:13:41 +00:00
EndContainer ( ) ,
} ;
2007-08-29 20:50:58 +00:00
/** Vehicle view window descriptor for all vehicles but trains. */
2013-05-26 19:23:42 +00:00
static WindowDesc _vehicle_view_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " view_vehicle " , 250 , 116 ,
2007-08-29 20:50:58 +00:00
WC_VEHICLE_VIEW , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_view_widgets , lengthof ( _nested_vehicle_view_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-08-29 20:50:58 +00:00
2010-08-01 19:22:34 +00:00
/**
* Vehicle view window descriptor for trains . Only minimum_height and
2007-08-29 20:50:58 +00:00
* default_height are different for train view .
*/
2013-05-26 19:23:42 +00:00
static WindowDesc _train_view_desc (
2013-05-26 19:25:01 +00:00
WDP_AUTO , " view_vehicle_train " , 250 , 134 ,
2007-08-29 20:50:58 +00:00
WC_VEHICLE_VIEW , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2009-11-15 10:26:01 +00:00
_nested_vehicle_view_widgets , lengthof ( _nested_vehicle_view_widgets )
2009-03-15 15:12:06 +00:00
) ;
2007-08-29 20:50:58 +00:00
/* Just to make sure, nobody has changed the vehicle type constants, as we are
using them for array indexing in a number of places here . */
assert_compile ( VEH_TRAIN = = 0 ) ;
assert_compile ( VEH_ROAD = = 1 ) ;
assert_compile ( VEH_SHIP = = 2 ) ;
assert_compile ( VEH_AIRCRAFT = = 3 ) ;
/** Zoom levels for vehicle views indexed by vehicle type. */
static const ZoomLevel _vehicle_view_zoom_levels [ ] = {
ZOOM_LVL_TRAIN ,
ZOOM_LVL_ROADVEH ,
ZOOM_LVL_SHIP ,
ZOOM_LVL_AIRCRAFT ,
} ;
/* Constants for geometry of vehicle view viewport */
static const int VV_INITIAL_VIEWPORT_WIDTH = 226 ;
static const int VV_INITIAL_VIEWPORT_HEIGHT = 84 ;
static const int VV_INITIAL_VIEWPORT_HEIGHT_TRAIN = 102 ;
2008-05-19 09:39:05 +00:00
/** Command indices for the _vehicle_command_translation_table. */
enum VehicleCommandTranslation {
VCT_CMD_START_STOP = 0 ,
VCT_CMD_CLONE_VEH ,
VCT_CMD_TURN_AROUND ,
} ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
/** Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type. */
static const uint32 _vehicle_command_translation_table [ ] [ 4 ] = {
{ // VCT_CMD_START_STOP
2009-04-21 23:40:56 +00:00
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_TRAIN ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_SHIP ) ,
CMD_START_STOP_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_STOP_START_AIRCRAFT )
2008-05-19 09:39:05 +00:00
} ,
{ // VCT_CMD_CLONE_VEH
2009-09-07 08:59:43 +00:00
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_TRAIN ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_ROAD_VEHICLE ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_SHIP ) ,
CMD_CLONE_VEHICLE | CMD_MSG ( STR_ERROR_CAN_T_BUY_AIRCRAFT )
2008-05-19 09:39:05 +00:00
} ,
{ // VCT_CMD_TURN_AROUND
2009-07-08 22:11:55 +00:00
CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG ( STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN ) ,
2009-07-22 19:12:20 +00:00
CMD_TURN_ROADVEH | CMD_MSG ( STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN ) ,
2008-05-19 09:39:05 +00:00
0xffffffff , // invalid for ships
2018-04-30 16:52:32 +00:00
0xffffffff // invalid for aircraft
2008-05-19 09:39:05 +00:00
} ,
} ;
2007-08-29 20:50:58 +00:00
2010-04-24 20:55:51 +00:00
/**
2016-10-30 18:04:20 +00:00
* This is the Callback method after attempting to start / stop a vehicle
* @ param result the result of the start / stop command
2010-04-24 20:55:51 +00:00
* @ param tile unused
* @ param p1 vehicle ID
* @ param p2 unused
*/
2019-09-07 16:37:01 +00:00
void CcStartStopVehicle ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 , uint32 cmd )
2010-04-24 20:55:51 +00:00
{
if ( result . Failed ( ) ) return ;
const Vehicle * v = Vehicle : : GetIfValid ( p1 ) ;
2019-04-10 21:07:06 +00:00
if ( v = = nullptr | | ! v - > IsPrimaryVehicle ( ) | | v - > owner ! = _local_company ) return ;
2010-04-24 20:55:51 +00:00
StringID msg = ( v - > vehstatus & VS_STOPPED ) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED ;
Point pt = RemapCoords ( v - > x_pos , v - > y_pos , v - > z_pos ) ;
AddTextEffect ( msg , pt . x , pt . y , DAY_TICKS , TE_RISING ) ;
}
2010-04-24 14:29:30 +00:00
/**
* Executes # CMD_START_STOP_VEHICLE for given vehicle .
* @ param v Vehicle to start / stop
2010-04-24 20:55:51 +00:00
* @ param texteffect Should a texteffect be shown ?
2010-04-24 14:29:30 +00:00
*/
2010-04-24 20:55:51 +00:00
void StartStopVehicle ( const Vehicle * v , bool texteffect )
2010-04-24 14:29:30 +00:00
{
assert ( v - > IsPrimaryVehicle ( ) ) ;
2019-04-10 21:07:06 +00:00
DoCommandP ( v - > tile , v - > index , 0 , _vehicle_command_translation_table [ VCT_CMD_START_STOP ] [ v - > type ] , texteffect ? CcStartStopVehicle : nullptr ) ;
2010-04-24 14:29:30 +00:00
}
2008-05-19 09:39:05 +00:00
/** Checks whether the vehicle may be refitted at the moment.*/
static bool IsVehicleRefitable ( const Vehicle * v )
2007-08-29 20:50:58 +00:00
{
2008-12-16 22:02:12 +00:00
if ( ! v - > IsStoppedInDepot ( ) ) return false ;
do {
if ( IsEngineRefittable ( v - > engine_type ) ) return true ;
2019-04-10 21:07:06 +00:00
} while ( v - > IsGroundVehicle ( ) & & ( v = v - > Next ( ) ) ! = nullptr ) ;
2008-12-16 22:02:12 +00:00
return false ;
2008-05-19 09:39:05 +00:00
}
2009-10-24 15:19:06 +00:00
/** Window manager class for viewing a vehicle. */
2008-05-19 09:39:05 +00:00
struct VehicleViewWindow : Window {
2009-10-24 13:49:04 +00:00
private :
/** Display planes available in the vehicle view window. */
enum PlaneSelections {
2011-12-16 16:58:55 +00:00
SEL_DC_GOTO_DEPOT , ///< Display 'goto depot' button in #WID_VV_SELECT_DEPOT_CLONE stacked widget.
SEL_DC_CLONE , ///< Display 'clone vehicle' button in #WID_VV_SELECT_DEPOT_CLONE stacked widget.
2009-10-24 13:49:04 +00:00
2011-12-16 16:58:55 +00:00
SEL_RT_REFIT , ///< Display 'refit' button in #WID_VV_SELECT_REFIT_TURN stacked widget.
SEL_RT_TURN_AROUND , ///< Display 'turn around' button in #WID_VV_SELECT_REFIT_TURN stacked widget.
2009-10-24 13:49:04 +00:00
2011-12-16 16:58:55 +00:00
SEL_DC_BASEPLANE = SEL_DC_GOTO_DEPOT , ///< First plane of the #WID_VV_SELECT_DEPOT_CLONE stacked widget.
SEL_RT_BASEPLANE = SEL_RT_REFIT , ///< First plane of the #WID_VV_SELECT_REFIT_TURN stacked widget.
2009-10-24 13:49:04 +00:00
} ;
2020-06-23 19:50:41 +00:00
bool mouse_over_start_stop = false ;
2009-10-24 13:49:04 +00:00
2010-08-01 19:22:34 +00:00
/**
* Display a plane in the window .
2009-10-24 13:49:04 +00:00
* @ param plane Plane to show .
*/
void SelectPlane ( PlaneSelections plane )
2008-05-19 09:39:05 +00:00
{
2009-10-24 13:49:04 +00:00
switch ( plane ) {
case SEL_DC_GOTO_DEPOT :
case SEL_DC_CLONE :
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetStacked > ( WID_VV_SELECT_DEPOT_CLONE ) - > SetDisplayedPlane ( plane - SEL_DC_BASEPLANE ) ;
2009-10-24 13:49:04 +00:00
break ;
2008-05-19 09:39:05 +00:00
2009-10-24 13:49:04 +00:00
case SEL_RT_REFIT :
case SEL_RT_TURN_AROUND :
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetStacked > ( WID_VV_SELECT_REFIT_TURN ) - > SetDisplayedPlane ( plane - SEL_RT_BASEPLANE ) ;
2009-10-24 13:49:04 +00:00
break ;
2007-08-29 20:50:58 +00:00
2009-10-24 13:49:04 +00:00
default :
NOT_REACHED ( ) ;
}
}
public :
2013-05-26 19:23:42 +00:00
VehicleViewWindow ( WindowDesc * desc , WindowNumber window_number ) : Window ( desc )
2009-10-24 13:49:04 +00:00
{
2017-03-24 12:00:52 +00:00
this - > flags | = WF_DISABLE_VP_SCROLL ;
2013-05-26 19:23:42 +00:00
this - > CreateNestedTree ( ) ;
2009-10-24 15:19:06 +00:00
/* Sprites for the 'send to depot' button indexed by vehicle type. */
static const SpriteID vehicle_view_goto_depot_sprites [ ] = {
SPR_SEND_TRAIN_TODEPOT ,
SPR_SEND_ROADVEH_TODEPOT ,
SPR_SEND_SHIP_TODEPOT ,
SPR_SEND_AIRCRAFT_TODEPOT ,
} ;
2009-10-24 13:49:04 +00:00
const Vehicle * v = Vehicle : : Get ( window_number ) ;
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VV_GOTO_DEPOT ) - > widget_data = vehicle_view_goto_depot_sprites [ v - > type ] ;
2009-10-24 13:49:04 +00:00
2009-10-24 15:19:06 +00:00
/* Sprites for the 'clone vehicle' button indexed by vehicle type. */
static const SpriteID vehicle_view_clone_sprites [ ] = {
SPR_CLONE_TRAIN ,
SPR_CLONE_ROADVEH ,
SPR_CLONE_SHIP ,
SPR_CLONE_AIRCRAFT ,
} ;
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VV_CLONE ) - > widget_data = vehicle_view_clone_sprites [ v - > type ] ;
2009-07-22 20:17:07 +00:00
2008-05-19 09:39:05 +00:00
switch ( v - > type ) {
case VEH_TRAIN :
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VV_TURN_AROUND ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
case VEH_ROAD :
break ;
2007-08-29 20:50:58 +00:00
2008-05-19 09:39:05 +00:00
case VEH_SHIP :
case VEH_AIRCRAFT :
2009-10-24 13:49:04 +00:00
this - > SelectPlane ( SEL_RT_REFIT ) ;
2008-05-19 09:39:05 +00:00
break ;
2009-07-22 20:17:07 +00:00
default : NOT_REACHED ( ) ;
2008-05-19 09:39:05 +00:00
}
2013-05-26 19:23:42 +00:00
this - > FinishInitNested ( window_number ) ;
2009-10-24 13:49:04 +00:00
this - > owner = v - > owner ;
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetViewport > ( WID_VV_VIEWPORT ) - > InitializeViewport ( this , this - > window_number | ( 1 < < 31 ) , _vehicle_view_zoom_levels [ v - > type ] ) ;
2008-05-23 23:02:13 +00:00
2011-12-16 16:58:55 +00:00
this - > GetWidget < NWidgetCore > ( WID_VV_START_STOP ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_CENTER_MAIN_VIEW ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_REFIT ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_GOTO_DEPOT ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_SHOW_ORDERS ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_SHOW_DETAILS ) - > tool_tip = STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP + v - > type ;
this - > GetWidget < NWidgetCore > ( WID_VV_CLONE ) - > tool_tip = STR_VEHICLE_VIEW_CLONE_TRAIN_INFO + v - > type ;
2019-02-10 08:43:54 +00:00
this - > UpdateButtonStatus ( ) ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
~ VehicleViewWindow ( )
{
2009-01-02 20:59:04 +00:00
DeleteWindowById ( WC_VEHICLE_ORDERS , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_REFIT , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_DETAILS , this - > window_number , false ) ;
DeleteWindowById ( WC_VEHICLE_TIMETABLE , this - > window_number , false ) ;
2007-08-29 20:50:58 +00:00
}
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-10-24 13:49:04 +00:00
{
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
switch ( widget ) {
2013-10-01 20:35:06 +00:00
case WID_VV_START_STOP :
size - > height = max ( size - > height , max ( GetSpriteSize ( SPR_FLAG_VEH_STOPPED ) . height , GetSpriteSize ( SPR_FLAG_VEH_RUNNING ) . height ) + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM ) ;
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_FORCE_PROCEED :
2009-10-24 13:49:04 +00:00
if ( v - > type ! = VEH_TRAIN ) {
size - > height = 0 ;
size - > width = 0 ;
2010-08-01 18:53:30 +00:00
}
2010-08-01 23:49:03 +00:00
break ;
2009-10-24 13:58:18 +00:00
2011-12-16 16:58:55 +00:00
case WID_VV_VIEWPORT :
2009-10-24 13:58:18 +00:00
size - > width = VV_INITIAL_VIEWPORT_WIDTH ;
size - > height = ( v - > type = = VEH_TRAIN ) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT ;
break ;
2009-10-24 13:49:04 +00:00
}
}
2019-03-04 07:49:37 +00:00
void OnPaint ( ) override
2008-05-19 09:39:05 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-09-30 20:39:50 +00:00
bool is_localcompany = v - > owner = = _local_company ;
2008-05-19 09:39:05 +00:00
bool refitable_and_stopped_in_depot = IsVehicleRefitable ( v ) ;
2011-12-16 16:58:55 +00:00
this - > SetWidgetDisabledState ( WID_VV_GOTO_DEPOT , ! is_localcompany ) ;
this - > SetWidgetDisabledState ( WID_VV_REFIT , ! refitable_and_stopped_in_depot | | ! is_localcompany ) ;
this - > SetWidgetDisabledState ( WID_VV_CLONE , ! is_localcompany ) ;
2008-05-19 09:39:05 +00:00
if ( v - > type = = VEH_TRAIN ) {
2011-12-16 16:58:55 +00:00
this - > SetWidgetLoweredState ( WID_VV_FORCE_PROCEED , Train : : From ( v ) - > force_proceed = = TFP_SIGNAL ) ;
this - > SetWidgetDisabledState ( WID_VV_FORCE_PROCEED , ! is_localcompany ) ;
this - > SetWidgetDisabledState ( WID_VV_TURN_AROUND , ! is_localcompany ) ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
this - > DrawWidgets ( ) ;
2009-10-24 13:49:04 +00:00
}
2019-03-04 07:49:37 +00:00
void SetStringParameters ( int widget ) const override
2009-10-24 13:49:04 +00:00
{
2011-12-16 16:58:55 +00:00
if ( widget ! = WID_VV_CAPTION ) return ;
2009-10-24 13:49:04 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
SetDParam ( 0 , v - > index ) ;
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2009-10-24 13:49:04 +00:00
{
2011-12-16 16:58:55 +00:00
if ( widget ! = WID_VV_START_STOP ) return ;
2009-10-24 13:49:04 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
StringID str ;
2008-05-19 09:39:05 +00:00
if ( v - > vehstatus & VS_CRASHED ) {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_CRASHED ;
2008-05-19 09:39:05 +00:00
} else if ( v - > type ! = VEH_AIRCRAFT & & v - > breakdown_ctr = = 1 ) { // check for aircraft necessary?
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_BROKEN_DOWN ;
2020-06-23 19:50:41 +00:00
} else if ( v - > vehstatus & VS_STOPPED & & ( ! mouse_over_start_stop | | v - > IsStoppedInDepot ( ) ) ) {
2008-05-19 09:39:05 +00:00
if ( v - > type = = VEH_TRAIN ) {
if ( v - > cur_speed = = 0 ) {
2010-12-14 21:28:45 +00:00
if ( Train : : From ( v ) - > gcache . cached_power = = 0 ) {
2009-08-05 17:59:21 +00:00
str = STR_VEHICLE_STATUS_TRAIN_NO_POWER ;
2008-05-19 09:39:05 +00:00
} else {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_STOPPED ;
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
} else {
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > GetDisplaySpeed ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
} else { // no train
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_STOPPED ;
2007-08-29 20:50:58 +00:00
}
2009-07-21 17:14:05 +00:00
} else if ( v - > type = = VEH_TRAIN & & HasBit ( Train : : From ( v ) - > flags , VRF_TRAIN_STUCK ) & & ! v - > current_order . IsType ( OT_LOADING ) ) {
2009-08-05 17:59:21 +00:00
str = STR_VEHICLE_STATUS_TRAIN_STUCK ;
2011-12-13 00:43:35 +00:00
} else if ( v - > type = = VEH_AIRCRAFT & & HasBit ( Aircraft : : From ( v ) - > flags , VAF_DEST_TOO_FAR ) & & ! v - > current_order . IsType ( OT_LOADING ) ) {
str = STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR ;
2008-05-19 09:39:05 +00:00
} else { // vehicle is in a "normal" state, show current order
switch ( v - > current_order . GetType ( ) ) {
case OT_GOTO_STATION : {
2008-04-06 07:48:51 +00:00
SetDParam ( 0 , v - > current_order . GetDestination ( ) ) ;
2007-08-29 20:50:58 +00:00
SetDParam ( 1 , v - > GetDisplaySpeed ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL ;
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-19 09:39:05 +00:00
case OT_GOTO_DEPOT : {
2010-05-12 18:19:36 +00:00
SetDParam ( 0 , v - > type ) ;
SetDParam ( 1 , v - > current_order . GetDestination ( ) ) ;
SetDParam ( 2 , v - > GetDisplaySpeed ( ) ) ;
2011-02-08 22:36:16 +00:00
if ( v - > current_order . GetDepotActionType ( ) & ODATFB_NEAREST_DEPOT ) {
/* This case *only* happens when multiple nearest depot orders
2013-01-08 22:46:42 +00:00
* follow each other ( including an order list only one order : a
2011-02-08 22:36:16 +00:00
* nearest depot order ) and there are no reachable depots .
* It is primarily to guard for the case that there is no
* depot with index 0 , which would be used as fallback for
* evaluating the string in the status bar . */
str = STR_EMPTY ;
} else if ( v - > current_order . GetDepotActionType ( ) & ODATFB_HALT ) {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL ;
2008-05-19 09:39:05 +00:00
} else {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL ;
2008-05-19 09:39:05 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2008-05-19 09:39:05 +00:00
case OT_LOADING :
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_LOADING_UNLOADING ;
2008-05-19 09:39:05 +00:00
break ;
case OT_GOTO_WAYPOINT : {
2009-07-10 18:30:02 +00:00
assert ( v - > type = = VEH_TRAIN | | v - > type = = VEH_SHIP ) ;
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > current_order . GetDestination ( ) ) ;
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL ;
2007-08-29 20:50:58 +00:00
SetDParam ( 1 , v - > GetDisplaySpeed ( ) ) ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
case OT_LEAVESTATION :
if ( v - > type ! = VEH_AIRCRAFT ) {
2009-04-21 23:40:56 +00:00
str = STR_VEHICLE_STATUS_LEAVING ;
2008-05-19 09:39:05 +00:00
break ;
}
2017-08-13 18:38:42 +00:00
FALLTHROUGH ;
2008-05-19 09:39:05 +00:00
default :
2010-12-26 13:25:34 +00:00
if ( v - > GetNumManualOrders ( ) = = 0 ) {
2011-02-04 14:37:24 +00:00
str = STR_VEHICLE_STATUS_NO_ORDERS_VEL ;
2008-05-19 09:39:05 +00:00
SetDParam ( 0 , v - > GetDisplaySpeed ( ) ) ;
} else {
str = STR_EMPTY ;
}
break ;
2007-08-29 20:50:58 +00:00
}
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
2013-10-01 20:16:44 +00:00
/* Draw the flag plus orders. */
bool rtl = ( _current_text_dir = = TD_RTL ) ;
uint text_offset = max ( GetSpriteSize ( SPR_FLAG_VEH_STOPPED ) . width , GetSpriteSize ( SPR_FLAG_VEH_RUNNING ) . width ) + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT ;
int text_left = r . left + ( rtl ? ( uint ) WD_FRAMERECT_LEFT : text_offset ) ;
int text_right = r . right - ( rtl ? text_offset : ( uint ) WD_FRAMERECT_RIGHT ) ;
int image_left = ( rtl ? text_right + 1 : r . left ) + WD_IMGBTN_LEFT ;
int image = ( ( v - > vehstatus & VS_STOPPED ) ! = 0 ) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING ;
2013-10-01 20:22:38 +00:00
int lowered = this - > IsWidgetLowered ( WID_VV_START_STOP ) ? 1 : 0 ;
DrawSprite ( image , PAL_NONE , image_left + lowered , r . top + WD_IMGBTN_TOP + lowered ) ;
DrawString ( text_left + lowered , text_right + lowered , r . top + WD_FRAMERECT_TOP + lowered , str , TC_FROMSTRING , SA_HOR_CENTER ) ;
2008-05-19 09:39:05 +00:00
}
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-19 09:39:05 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-19 09:39:05 +00:00
switch ( widget ) {
2011-12-16 16:58:55 +00:00
case WID_VV_START_STOP : // start stop
2010-02-22 20:53:45 +00:00
if ( _ctrl_pressed ) {
/* Scroll to current order destination */
TileIndex tile = v - > current_order . GetLocation ( v ) ;
if ( tile ! = INVALID_TILE ) ScrollMainWindowToTile ( tile ) ;
} else {
/* Start/Stop */
2010-04-24 20:55:51 +00:00
StartStopVehicle ( v , false ) ;
2010-02-22 20:53:45 +00:00
}
2008-05-19 09:39:05 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_CENTER_MAIN_VIEW : { // center main view
2008-05-19 09:39:05 +00:00
const Window * mainwindow = FindWindowById ( WC_MAIN_WINDOW , 0 ) ;
/* code to allow the main window to 'follow' the vehicle if the ctrl key is pressed */
2011-11-24 12:38:48 +00:00
if ( _ctrl_pressed & & mainwindow - > viewport - > zoom < = ZOOM_LVL_OUT_4X ) {
2008-05-19 09:39:05 +00:00
mainwindow - > viewport - > follow_vehicle = v - > index ;
} else {
2009-03-15 15:25:18 +00:00
ScrollMainWindowTo ( v - > x_pos , v - > y_pos , v - > z_pos ) ;
2007-08-29 20:50:58 +00:00
}
2010-08-01 18:53:30 +00:00
break ;
}
2007-08-29 20:50:58 +00:00
2011-12-16 16:58:55 +00:00
case WID_VV_GOTO_DEPOT : // goto hangar
2010-09-08 21:37:13 +00:00
DoCommandP ( v - > tile , v - > index | ( _ctrl_pressed ? DEPOT_SERVICE : 0U ) , 0 , GetCmdSendToDepot ( v ) ) ;
2008-05-19 09:39:05 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_REFIT : // refit
2008-09-24 16:40:06 +00:00
ShowVehicleRefitWindow ( v , INVALID_VEH_ORDER_ID , this ) ;
2008-05-19 09:39:05 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_SHOW_ORDERS : // show orders
2008-05-19 09:39:05 +00:00
if ( _ctrl_pressed ) {
ShowTimetableWindow ( v ) ;
2007-08-29 20:50:58 +00:00
} else {
2008-05-19 09:39:05 +00:00
ShowOrdersWindow ( v ) ;
2007-08-29 20:50:58 +00:00
}
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_SHOW_DETAILS : // show details
2019-05-10 17:49:50 +00:00
if ( _ctrl_pressed ) {
ShowCompanyGroupForVehicle ( v ) ;
} else {
ShowVehicleDetailsWindow ( v ) ;
}
2008-05-19 09:39:05 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_CLONE : // clone vehicle
2012-12-09 16:54:02 +00:00
/* Suppress the vehicle GUI when share-cloning.
* There is no point to it except for starting the vehicle .
* For starting the vehicle the player has to open the depot GUI , which is
* most likely already open , but is also visible in the vehicle viewport . */
2008-12-28 14:37:19 +00:00
DoCommandP ( v - > tile , v - > index , _ctrl_pressed ? 1 : 0 ,
_vehicle_command_translation_table [ VCT_CMD_CLONE_VEH ] [ v - > type ] ,
2019-04-10 21:07:06 +00:00
_ctrl_pressed ? nullptr : CcCloneVehicle ) ;
2008-05-19 09:39:05 +00:00
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_TURN_AROUND : // turn around
2010-12-14 21:26:03 +00:00
assert ( v - > IsGroundVehicle ( ) ) ;
2008-12-28 14:37:19 +00:00
DoCommandP ( v - > tile , v - > index , 0 ,
2008-05-19 09:39:05 +00:00
_vehicle_command_translation_table [ VCT_CMD_TURN_AROUND ] [ v - > type ] ) ;
break ;
2011-12-16 16:58:55 +00:00
case WID_VV_FORCE_PROCEED : // force proceed
2008-05-19 09:39:05 +00:00
assert ( v - > type = = VEH_TRAIN ) ;
2009-04-21 23:40:56 +00:00
DoCommandP ( v - > tile , v - > index , 0 , CMD_FORCE_TRAIN_PROCEED | CMD_MSG ( STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL ) ) ;
2008-05-19 09:39:05 +00:00
break ;
2007-08-29 20:50:58 +00:00
}
}
2020-06-23 19:50:41 +00:00
void OnMouseOver ( Point pt , int widget ) override
{
bool start_stop = widget = = WID_VV_START_STOP ;
if ( start_stop ! = mouse_over_start_stop ) {
mouse_over_start_stop = start_stop ;
this - > SetWidgetDirty ( WID_VV_START_STOP ) ;
}
}
2019-03-04 07:49:37 +00:00
void OnResize ( ) override
2008-05-19 09:39:05 +00:00
{
2019-04-10 21:07:06 +00:00
if ( this - > viewport ! = nullptr ) {
2011-12-16 16:58:55 +00:00
NWidgetViewport * nvp = this - > GetWidget < NWidgetViewport > ( WID_VV_VIEWPORT ) ;
2009-10-24 13:58:18 +00:00
nvp - > UpdateViewportCoordinates ( this ) ;
}
2008-05-19 09:39:05 +00:00
}
2007-08-29 20:50:58 +00:00
2019-02-10 08:43:54 +00:00
void UpdateButtonStatus ( )
2008-05-19 09:39:05 +00:00
{
2009-05-16 23:34:14 +00:00
const Vehicle * v = Vehicle : : Get ( this - > window_number ) ;
2008-05-19 09:39:05 +00:00
bool veh_stopped = v - > IsStoppedInDepot ( ) ;
2011-12-16 16:58:55 +00:00
/* Widget WID_VV_GOTO_DEPOT must be hidden if the vehicle is already stopped in depot.
* Widget WID_VV_CLONE_VEH should then be shown , since cloning is allowed only while in depot and stopped .
2009-10-24 13:49:04 +00:00
*/
PlaneSelections plane = veh_stopped ? SEL_DC_CLONE : SEL_DC_GOTO_DEPOT ;
2011-12-16 16:58:55 +00:00
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( WID_VV_SELECT_DEPOT_CLONE ) ; // Selection widget 'send to depot' / 'clone'.
2009-10-24 13:49:04 +00:00
if ( nwi - > shown_plane + SEL_DC_BASEPLANE ! = plane ) {
this - > SelectPlane ( plane ) ;
2011-12-16 16:58:55 +00:00
this - > SetWidgetDirty ( WID_VV_SELECT_DEPOT_CLONE ) ;
2009-10-24 13:49:04 +00:00
}
2011-12-16 16:58:55 +00:00
/* The same system applies to widget WID_VV_REFIT_VEH and VVW_WIDGET_TURN_AROUND.*/
2010-12-14 21:26:03 +00:00
if ( v - > IsGroundVehicle ( ) ) {
2009-10-24 13:49:04 +00:00
PlaneSelections plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND ;
2011-12-16 16:58:55 +00:00
NWidgetStacked * nwi = this - > GetWidget < NWidgetStacked > ( WID_VV_SELECT_REFIT_TURN ) ;
2009-10-24 13:49:04 +00:00
if ( nwi - > shown_plane + SEL_RT_BASEPLANE ! = plane ) {
this - > SelectPlane ( plane ) ;
2011-12-16 16:58:55 +00:00
this - > SetWidgetDirty ( WID_VV_SELECT_REFIT_TURN ) ;
2008-05-19 09:39:05 +00:00
}
}
}
2010-04-24 13:39:11 +00:00
2011-03-13 21:31:29 +00:00
/**
* Some data on this window has become invalid .
* @ param data Information about the changed data .
* @ param gui_scope Whether the call is done from GUI scope . You may not do everything when not in GUI scope . See # InvalidateWindowData ( ) for details .
*/
2019-03-04 07:49:37 +00:00
void OnInvalidateData ( int data = 0 , bool gui_scope = true ) override
2011-03-08 19:41:58 +00:00
{
2012-12-20 19:44:02 +00:00
if ( data = = VIWD_AUTOREPLACE ) {
2011-03-08 19:41:58 +00:00
/* Autoreplace replaced the vehicle.
2011-03-13 21:33:02 +00:00
* Nothing to do for this window . */
2011-03-08 19:41:58 +00:00
return ;
}
2019-02-10 08:43:54 +00:00
this - > UpdateButtonStatus ( ) ;
2011-03-08 19:41:58 +00:00
}
2019-03-04 07:49:37 +00:00
bool IsNewGRFInspectable ( ) const override
2010-04-24 13:39:11 +00:00
{
return : : IsNewGRFInspectable ( GetGrfSpecFeature ( Vehicle : : Get ( this - > window_number ) - > type ) , this - > window_number ) ;
}
2019-03-04 07:49:37 +00:00
void ShowNewGRFInspectWindow ( ) const override
2010-04-24 13:39:11 +00:00
{
: : ShowNewGRFInspectWindow ( GetGrfSpecFeature ( Vehicle : : Get ( this - > window_number ) - > type ) , this - > window_number ) ;
}
2007-08-29 20:50:58 +00:00
} ;
2008-05-19 09:39:05 +00:00
/** Shows the vehicle view window of the given vehicle. */
void ShowVehicleViewWindow ( const Vehicle * v )
2007-08-29 20:50:58 +00:00
{
2008-05-19 09:39:05 +00:00
AllocateWindowDescFront < VehicleViewWindow > ( ( v - > type = = VEH_TRAIN ) ? & _train_view_desc : & _vehicle_view_desc , v - > index ) ;
2007-08-29 20:50:58 +00:00
}
2007-12-27 13:35:39 +00:00
2010-09-06 14:14:09 +00:00
/**
* Dispatch a " vehicle selected " event if any window waits for it .
* @ param v selected vehicle ;
* @ return did any window accept vehicle selection ?
*/
bool VehicleClicked ( const Vehicle * v )
{
2019-04-10 21:07:06 +00:00
assert ( v ! = nullptr ) ;
2010-09-06 14:14:09 +00:00
if ( ! ( _thd . place_mode & HT_VEHICLE ) ) return false ;
v = v - > First ( ) ;
if ( ! v - > IsPrimaryVehicle ( ) ) return false ;
2011-12-10 19:20:30 +00:00
return _thd . GetCallbackWnd ( ) - > OnVehicleSelect ( v ) ;
2010-09-06 14:14:09 +00:00
}
2008-05-17 13:01:30 +00:00
void StopGlobalFollowVehicle ( const Vehicle * v )
{
Window * w = FindWindowById ( WC_MAIN_WINDOW , 0 ) ;
2019-04-10 21:07:06 +00:00
if ( w ! = nullptr & & w - > viewport - > follow_vehicle = = v - > index ) {
2009-03-15 15:25:18 +00:00
ScrollMainWindowTo ( v - > x_pos , v - > y_pos , v - > z_pos , true ) ; // lock the main view on the vehicle's last position
2008-05-17 13:01:30 +00:00
w - > viewport - > follow_vehicle = INVALID_VEHICLE ;
}
}
2010-01-11 18:34:02 +00:00
/**
* This is the Callback method after the construction attempt of a primary vehicle
2010-01-11 18:46:09 +00:00
* @ param result indicates completion ( or not ) of the operation
2010-01-11 18:34:02 +00:00
* @ param tile unused
* @ param p1 unused
* @ param p2 unused
2019-09-07 16:37:01 +00:00
* @ param cmd unused
2010-01-11 18:34:02 +00:00
*/
2019-09-07 16:37:01 +00:00
void CcBuildPrimaryVehicle ( const CommandCost & result , TileIndex tile , uint32 p1 , uint32 p2 , uint32 cmd )
2010-01-11 18:34:02 +00:00
{
2010-01-11 18:46:09 +00:00
if ( result . Failed ( ) ) return ;
2010-01-11 18:34:02 +00:00
const Vehicle * v = Vehicle : : Get ( _new_vehicle_id ) ;
ShowVehicleViewWindow ( v ) ;
}
2010-12-21 13:54:57 +00:00
/**
2016-08-15 18:34:09 +00:00
* Get the width of a vehicle ( part ) in pixels .
2010-12-21 13:54:57 +00:00
* @ param v Vehicle to get the width for .
* @ return Width of the vehicle .
*/
2016-08-15 18:34:09 +00:00
int GetSingleVehicleWidth ( const Vehicle * v , EngineImageType image_type )
2010-12-21 13:54:57 +00:00
{
switch ( v - > type ) {
case VEH_TRAIN :
2016-08-15 18:34:09 +00:00
return Train : : From ( v ) - > GetDisplayImageWidth ( ) ;
2010-12-21 13:54:57 +00:00
case VEH_ROAD :
2016-08-15 18:34:09 +00:00
return RoadVehicle : : From ( v ) - > GetDisplayImageWidth ( ) ;
2010-12-21 13:54:57 +00:00
default :
bool rtl = _current_text_dir = = TD_RTL ;
2016-10-16 14:57:56 +00:00
VehicleSpriteSeq seq ;
v - > GetImage ( rtl ? DIR_E : DIR_W , image_type , & seq ) ;
2016-10-16 14:58:38 +00:00
Rect rec ;
seq . GetBounds ( & rec ) ;
return UnScaleGUI ( rec . right - rec . left + 1 ) ;
2010-12-21 13:54:57 +00:00
}
2016-08-15 18:34:09 +00:00
}
2010-12-21 13:54:57 +00:00
2016-08-15 18:34:09 +00:00
/**
* Get the width of a vehicle ( including all parts of the consist ) in pixels .
* @ param v Vehicle to get the width for .
* @ return Width of the vehicle .
*/
int GetVehicleWidth ( const Vehicle * v , EngineImageType image_type )
{
if ( v - > type = = VEH_TRAIN | | v - > type = = VEH_ROAD ) {
int vehicle_width = 0 ;
2019-04-10 21:07:06 +00:00
for ( const Vehicle * u = v ; u ! = nullptr ; u = u - > Next ( ) ) {
2016-08-15 18:34:09 +00:00
vehicle_width + = GetSingleVehicleWidth ( u , image_type ) ;
}
return vehicle_width ;
} else {
return GetSingleVehicleWidth ( v , image_type ) ;
}
2010-12-21 13:54:57 +00:00
}
2016-08-15 18:33:52 +00:00
/**
* Set the mouse cursor to look like a vehicle .
* @ param v Vehicle
* @ param image_type Type of vehicle image to use .
*/
void SetMouseCursorVehicle ( const Vehicle * v , EngineImageType image_type )
{
bool rtl = _current_text_dir = = TD_RTL ;
2016-08-15 18:34:31 +00:00
_cursor . sprite_count = 0 ;
int total_width = 0 ;
2019-04-10 21:07:06 +00:00
for ( ; v ! = nullptr ; v = v - > HasArticulatedPart ( ) ? v - > GetNextArticulatedPart ( ) : nullptr ) {
2016-08-15 18:34:31 +00:00
if ( total_width > = 2 * ( int ) VEHICLEINFO_FULL_VEHICLE_WIDTH ) break ;
2016-10-16 14:57:13 +00:00
PaletteID pal = ( v - > vehstatus & VS_CRASHED ) ? PALETTE_CRASH : GetVehiclePalette ( v ) ;
2016-10-16 14:57:56 +00:00
VehicleSpriteSeq seq ;
v - > GetImage ( rtl ? DIR_E : DIR_W , image_type , & seq ) ;
2016-10-16 14:57:13 +00:00
2016-10-16 14:59:44 +00:00
if ( _cursor . sprite_count + seq . count > lengthof ( _cursor . sprite_seq ) ) break ;
for ( uint i = 0 ; i < seq . count ; + + i ) {
PaletteID pal2 = ( v - > vehstatus & VS_CRASHED ) | | ! seq . seq [ i ] . pal ? pal : seq . seq [ i ] . pal ;
_cursor . sprite_seq [ _cursor . sprite_count ] . sprite = seq . seq [ i ] . sprite ;
_cursor . sprite_seq [ _cursor . sprite_count ] . pal = pal2 ;
_cursor . sprite_pos [ _cursor . sprite_count ] . x = rtl ? - total_width : total_width ;
_cursor . sprite_pos [ _cursor . sprite_count ] . y = 0 ;
_cursor . sprite_count + + ;
}
2016-08-15 18:34:31 +00:00
total_width + = GetSingleVehicleWidth ( v , image_type ) ;
}
int offs = ( ( int ) VEHICLEINFO_FULL_VEHICLE_WIDTH - total_width ) / 2 ;
if ( rtl ) offs = - offs ;
for ( uint i = 0 ; i < _cursor . sprite_count ; + + i ) {
_cursor . sprite_pos [ i ] . x + = offs ;
}
2016-08-15 18:33:52 +00:00
UpdateCursorSize ( ) ;
}