2009-08-21 21:21:05 +01: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 16:11:33 +01:00
/** @file cheat_gui.cpp GUI related to cheating. */
2008-04-17 22:21:01 +01:00
# include "stdafx.h"
# include "command_func.h"
2009-01-31 20:16:06 +00:00
# include "cheat_type.h"
2008-09-30 21:51:04 +01:00
# include "company_base.h"
# include "company_func.h"
2009-01-04 15:32:25 +00:00
# include "saveload/saveload.h"
2021-11-19 00:04:22 +00:00
# include "vehicle_base.h"
2011-01-22 14:52:20 +00:00
# include "textbuf_gui.h"
2008-04-17 22:21:01 +01:00
# include "window_gui.h"
2010-12-04 21:51:02 +00:00
# include "string_func.h"
2008-04-17 22:21:01 +01:00
# include "strings_func.h"
# include "window_func.h"
# include "rail_gui.h"
2012-06-01 11:44:45 +01:00
# include "settings_gui.h"
2008-09-30 21:51:04 +01:00
# include "company_gui.h"
2013-10-15 18:32:31 +01:00
# include "linkgraph/linkgraphschedule.h"
2014-09-21 13:39:24 +01:00
# include "map_func.h"
# include "tile_map.h"
# include "newgrf.h"
# include "error.h"
2021-10-31 18:39:09 +00:00
# include "misc_cmd.h"
2022-10-15 16:55:47 +01:00
# include "core/geometry_func.hpp"
2023-04-13 12:56:00 +01:00
# include "timer/timer.h"
# include "timer/timer_game_calendar.h"
2008-04-17 22:21:01 +01:00
2011-12-15 22:22:55 +00:00
# include "widgets/cheat_widget.h"
2008-04-17 22:21:01 +01:00
# include "table/sprites.h"
2014-04-23 21:13:33 +01:00
# include "safeguards.h"
2008-04-17 22:21:01 +01:00
/**
* The ' amount ' to cheat with .
* This variable is semantically a constant value , but because the cheat
* code requires to be able to write to the variable it is not constified .
*/
2023-05-08 18:01:06 +01:00
static int32_t _money_cheat_amount = 10000000 ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:25:24 +00:00
/**
* Handle cheating of money .
* Note that the amount of money of a company must be changed through a command
* rather than by setting a variable . Since the cheat data structure expects a
* variable , the amount of given / taken money is used for this purpose .
2023-04-15 14:11:41 +01:00
* @ param new_value not used .
* @ param change_direction is - 1 or + 1 ( down / up )
2010-12-04 21:25:24 +00:00
* @ return Amount of money cheat .
*/
2023-05-08 18:01:06 +01:00
static int32_t ClickMoneyCheat ( int32_t new_value , int32_t change_direction )
2008-04-17 22:21:01 +01:00
{
2023-04-15 14:11:41 +01:00
Command < CMD_MONEY_CHEAT > : : Post ( Money ( _money_cheat_amount ) * change_direction ) ;
2008-04-17 22:21:01 +01:00
return _money_cheat_amount ;
}
/**
2010-12-04 21:25:24 +00:00
* Handle changing of company .
2023-04-15 14:11:41 +01:00
* @ param new_value company to set to
* @ param change_direction is - 1 or + 1 ( down / up )
2010-12-04 21:25:24 +00:00
* @ return The new company .
2008-04-17 22:21:01 +01:00
*/
2023-05-08 18:01:06 +01:00
static int32_t ClickChangeCompanyCheat ( int32_t new_value , int32_t change_direction )
2008-04-17 22:21:01 +01:00
{
2023-04-15 14:11:41 +01:00
while ( ( uint ) new_value < Company : : GetPoolSize ( ) ) {
if ( Company : : IsValidID ( ( CompanyID ) new_value ) ) {
SetLocalCompany ( ( CompanyID ) new_value ) ;
2008-09-30 21:39:50 +01:00
return _local_company ;
2008-04-17 22:21:01 +01:00
}
2023-04-15 14:11:41 +01:00
new_value + = change_direction ;
2008-04-17 22:21:01 +01:00
}
2008-09-30 21:39:50 +01:00
return _local_company ;
2008-04-17 22:21:01 +01:00
}
/**
2010-12-04 21:25:24 +00:00
* Allow ( or disallow ) changing production of all industries .
2023-04-15 14:11:41 +01:00
* @ param new_value new value
* @ param change_direction unused
2013-01-08 22:46:42 +00:00
* @ return New value allowing change of industry production .
2009-02-23 22:00:29 +00:00
*/
2023-05-08 18:01:06 +01:00
static int32_t ClickSetProdCheat ( int32_t new_value , int32_t change_direction )
2009-02-23 22:00:29 +00:00
{
2023-04-15 14:11:41 +01:00
_cheats . setup_prod . value = ( new_value ! = 0 ) ;
2010-10-04 20:35:40 +01:00
InvalidateWindowClassesData ( WC_INDUSTRY_VIEW ) ;
return _cheats . setup_prod . value ;
2009-02-23 22:00:29 +00:00
}
2008-04-17 22:21:01 +01:00
extern void EnginesMonthlyLoop ( ) ;
/**
2010-12-04 21:25:24 +00:00
* Handle changing of the current year .
2023-04-23 20:20:56 +01:00
* @ param new_value The chosen year to change to .
2023-04-15 14:11:41 +01:00
* @ param change_direction + 1 ( increase ) or - 1 ( decrease ) .
2010-12-04 21:25:24 +00:00
* @ return New year .
2008-04-17 22:21:01 +01:00
*/
2023-05-08 18:01:06 +01:00
static int32_t ClickChangeDateCheat ( int32_t new_value , int32_t change_direction )
2008-04-17 22:21:01 +01:00
{
2023-04-23 20:20:56 +01:00
/* Don't allow changing to an invalid year, or the current year. */
2023-08-11 12:52:59 +01:00
auto new_year = Clamp ( TimerGameCalendar : : Year ( new_value ) , MIN_YEAR , MAX_YEAR ) ;
2023-08-12 19:14:21 +01:00
if ( new_year = = TimerGameCalendar : : year ) return static_cast < int32_t > ( TimerGameCalendar : : year ) ;
2008-04-17 22:21:01 +01:00
2023-05-04 14:14:12 +01:00
TimerGameCalendar : : YearMonthDay ymd ;
TimerGameCalendar : : ConvertDateToYMD ( TimerGameCalendar : : date , & ymd ) ;
2023-08-11 12:52:59 +01:00
TimerGameCalendar : : Date new_date = TimerGameCalendar : : ConvertYMDToDate ( new_year , ymd . month , ymd . day ) ;
2023-04-23 20:20:56 +01:00
2023-04-24 18:33:03 +01:00
/* Shift cached dates before we change the date. */
2023-04-24 16:56:01 +01:00
for ( auto v : Vehicle : : Iterate ( ) ) v - > ShiftDates ( new_date - TimerGameCalendar : : date ) ;
LinkGraphSchedule : : instance . ShiftDates ( new_date - TimerGameCalendar : : date ) ;
2023-04-23 20:20:56 +01:00
2023-04-24 18:33:03 +01:00
/* Now it's safe to actually change the date. */
TimerGameCalendar : : SetDate ( new_date , TimerGameCalendar : : date_fract ) ;
2008-04-17 22:21:01 +01:00
EnginesMonthlyLoop ( ) ;
2009-09-13 20:15:59 +01:00
SetWindowDirty ( WC_STATUS_BAR , 0 ) ;
2009-07-05 17:50:56 +01:00
InvalidateWindowClassesData ( WC_BUILD_STATION , 0 ) ;
2022-11-06 15:01:27 +00:00
InvalidateWindowClassesData ( WC_BUS_STATION , 0 ) ;
InvalidateWindowClassesData ( WC_TRUCK_STATION , 0 ) ;
2011-03-05 09:55:09 +00:00
InvalidateWindowClassesData ( WC_BUILD_OBJECT , 0 ) ;
2008-04-17 22:21:01 +01:00
ResetSignalVariant ( ) ;
2023-08-12 19:14:21 +01:00
return static_cast < int32_t > ( TimerGameCalendar : : year ) ;
2008-04-17 22:21:01 +01:00
}
2014-09-21 13:39:24 +01:00
/**
* Allow ( or disallow ) a change of the maximum allowed heightlevel .
2023-04-15 14:11:41 +01:00
* @ param new_value new value
* @ param change_direction unused
2014-09-21 13:39:24 +01:00
* @ return New value ( or unchanged old value ) of the maximum
* allowed heightlevel value .
*/
2023-05-08 18:01:06 +01:00
static int32_t ClickChangeMaxHlCheat ( int32_t new_value , int32_t change_direction )
2015-02-14 21:55:30 +00:00
{
2023-04-15 14:11:41 +01:00
new_value = Clamp ( new_value , MIN_MAP_HEIGHT_LIMIT , MAX_MAP_HEIGHT_LIMIT ) ;
2014-09-21 13:39:24 +01:00
/* Check if at least one mountain on the map is higher than the new value.
* If yes , disallow the change . */
2023-01-21 09:43:03 +00:00
for ( TileIndex t = 0 ; t < Map : : Size ( ) ; t + + ) {
2023-05-08 18:01:06 +01:00
if ( ( int32_t ) TileHeight ( t ) > new_value ) {
2014-09-21 13:39:24 +01:00
ShowErrorMessage ( STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN , INVALID_STRING_ID , WL_ERROR ) ;
/* Return old, unchanged value */
2021-03-24 08:42:54 +00:00
return _settings_game . construction . map_height_limit ;
2014-09-21 13:39:24 +01:00
}
}
/* Execute the change and reload GRF Data */
2023-04-15 14:11:41 +01:00
_settings_game . construction . map_height_limit = new_value ;
2014-09-21 13:39:24 +01:00
ReloadNewGRFData ( ) ;
2014-09-27 12:17:54 +01:00
/* The smallmap uses an index from heightlevels to colours. Trigger rebuilding it. */
InvalidateWindowClassesData ( WC_SMALLMAP , 2 ) ;
2021-03-24 08:42:54 +00:00
return _settings_game . construction . map_height_limit ;
2014-09-21 13:39:24 +01:00
}
2010-12-04 21:38:42 +00:00
/** Available cheats. */
enum CheatNumbers {
CHT_MONEY , ///< Change amount of money.
CHT_CHANGE_COMPANY , ///< Switch company.
CHT_EXTRA_DYNAMITE , ///< Dynamite anything.
CHT_CROSSINGTUNNELS , ///< Allow tunnels to cross each other.
CHT_NO_JETCRASH , ///< Disable jet-airplane crashes.
CHT_SETUP_PROD , ///< Allow manually editing of industry production.
2014-09-21 13:39:24 +01:00
CHT_EDIT_MAX_HL , ///< Edit maximum allowed heightlevel
2010-12-04 21:38:42 +00:00
CHT_CHANGE_DATE , ///< Do time traveling.
CHT_NUM_CHEATS , ///< Number of cheats.
} ;
2010-12-04 21:25:24 +00:00
/**
* Signature of handler function when user clicks at a cheat .
2023-04-15 14:11:41 +01:00
* @ param new_value The new value .
* @ param change_direction Change direction ( + 1 , + 1 ) , \ c 0 for boolean settings .
2010-12-04 21:25:24 +00:00
*/
2023-05-08 18:01:06 +01:00
typedef int32_t CheckButtonClick ( int32_t new_value , int32_t change_direction ) ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:25:24 +00:00
/** Information of a cheat. */
2008-04-17 22:21:01 +01:00
struct CheatEntry {
VarType type ; ///< type of selector
StringID str ; ///< string with descriptive text
void * variable ; ///< pointer to the variable
bool * been_used ; ///< has this cheat been used before?
CheckButtonClick * proc ; ///< procedure
} ;
2010-12-04 21:25:24 +00:00
/**
* The available cheats .
2010-12-04 21:38:42 +00:00
* Order matches with the values of # CheatNumbers
2010-12-04 21:25:24 +00:00
*/
2008-04-17 22:21:01 +01:00
static const CheatEntry _cheats_ui [ ] = {
2021-03-24 08:42:54 +00:00
{ SLE_INT32 , STR_CHEAT_MONEY , & _money_cheat_amount , & _cheats . money . been_used , & ClickMoneyCheat } ,
{ SLE_UINT8 , STR_CHEAT_CHANGE_COMPANY , & _local_company , & _cheats . switch_company . been_used , & ClickChangeCompanyCheat } ,
{ SLE_BOOL , STR_CHEAT_EXTRA_DYNAMITE , & _cheats . magic_bulldozer . value , & _cheats . magic_bulldozer . been_used , nullptr } ,
{ SLE_BOOL , STR_CHEAT_CROSSINGTUNNELS , & _cheats . crossing_tunnels . value , & _cheats . crossing_tunnels . been_used , nullptr } ,
{ SLE_BOOL , STR_CHEAT_NO_JETCRASH , & _cheats . no_jetcrash . value , & _cheats . no_jetcrash . been_used , nullptr } ,
{ SLE_BOOL , STR_CHEAT_SETUP_PROD , & _cheats . setup_prod . value , & _cheats . setup_prod . been_used , & ClickSetProdCheat } ,
{ SLE_UINT8 , STR_CHEAT_EDIT_MAX_HL , & _settings_game . construction . map_height_limit , & _cheats . edit_max_hl . been_used , & ClickChangeMaxHlCheat } ,
2023-04-24 16:56:01 +01:00
{ SLE_INT32 , STR_CHEAT_CHANGE_DATE , & TimerGameCalendar : : year , & _cheats . change_date . been_used , & ClickChangeDateCheat } ,
2008-04-17 22:21:01 +01:00
} ;
2020-12-27 10:44:22 +00:00
static_assert ( CHT_NUM_CHEATS = = lengthof ( _cheats_ui ) ) ;
2010-12-04 21:38:42 +00:00
2010-12-04 21:25:24 +00:00
/** Widget definitions of the cheat GUI. */
2009-03-22 21:16:57 +00:00
static const NWidgetPart _nested_cheat_widgets [ ] = {
NWidget ( NWID_HORIZONTAL ) ,
2009-11-24 18:05:55 +00:00
NWidget ( WWT_CLOSEBOX , COLOUR_GREY ) ,
NWidget ( WWT_CAPTION , COLOUR_GREY ) , SetDataTip ( STR_CHEATS , STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS ) ,
2009-12-21 16:24:29 +00:00
NWidget ( WWT_SHADEBOX , COLOUR_GREY ) ,
NWidget ( WWT_STICKYBOX , COLOUR_GREY ) ,
2009-03-22 21:16:57 +00:00
EndContainer ( ) ,
2011-12-16 16:27:45 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY , WID_C_PANEL ) , SetDataTip ( 0x0 , STR_CHEATS_TOOLTIP ) , EndContainer ( ) ,
2021-01-09 14:14:59 +00:00
NWidget ( WWT_PANEL , COLOUR_GREY ) ,
2022-09-23 09:36:22 +01:00
NWidget ( WWT_LABEL , COLOUR_GREY , WID_C_NOTE ) , SetFill ( 1 , 1 ) , SetDataTip ( STR_CHEATS_NOTE , STR_NULL ) , SetPadding ( WidgetDimensions : : unscaled . frametext ) ,
2021-01-09 14:14:59 +00:00
EndContainer ( ) ,
2009-03-22 21:16:57 +00:00
} ;
2010-12-04 21:25:24 +00:00
/** GUI for the cheats. */
2008-05-15 21:51:52 +01:00
struct CheatWindow : Window {
int clicked ;
2014-09-21 13:39:24 +01:00
int clicked_widget ;
2014-10-04 20:52:23 +01:00
uint line_height ;
2022-10-15 16:55:47 +01:00
Dimension box ; ///< Dimension of box sprite
Dimension icon ; ///< Dimension of company icon sprite
2008-04-17 22:21:01 +01:00
2013-05-26 20:23:42 +01:00
CheatWindow ( WindowDesc * desc ) : Window ( desc )
2008-05-15 21:51:52 +01:00
{
2013-05-26 20:23:42 +01:00
this - > InitNested ( ) ;
2008-05-15 21:51:52 +01:00
}
2008-04-17 22:21:01 +01:00
2022-10-15 16:55:47 +01:00
void OnInit ( ) override
{
this - > box = maxdim ( GetSpriteSize ( SPR_BOX_EMPTY ) , GetSpriteSize ( SPR_BOX_CHECKED ) ) ;
this - > icon = GetSpriteSize ( SPR_COMPANY_ICON ) ;
}
2019-03-04 07:49:37 +00:00
void DrawWidget ( const Rect & r , int widget ) const override
2008-05-15 21:51:52 +01:00
{
2011-12-16 16:27:45 +00:00
if ( widget ! = WID_C_PANEL ) return ;
2009-11-15 09:23:40 +00:00
2022-09-23 09:36:22 +01:00
const Rect ir = r . Shrink ( WidgetDimensions : : scaled . framerect ) ;
2022-10-15 16:55:47 +01:00
int y = ir . top ;
2008-04-17 22:21:01 +01:00
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2022-09-23 09:36:22 +01:00
uint box_left = rtl ? ir . right - this - > box . width - WidgetDimensions : : scaled . hsep_wide : ir . left + WidgetDimensions : : scaled . hsep_wide ;
uint button_left = rtl ? ir . right - this - > box . width - WidgetDimensions : : scaled . hsep_wide * 2 - SETTING_BUTTON_WIDTH : ir . left + this - > box . width + WidgetDimensions : : scaled . hsep_wide * 2 ;
uint text_left = ir . left + ( rtl ? 0 : WidgetDimensions : : scaled . hsep_wide * 4 + this - > box . width + SETTING_BUTTON_WIDTH ) ;
uint text_right = ir . right - ( rtl ? WidgetDimensions : : scaled . hsep_wide * 4 + this - > box . width + SETTING_BUTTON_WIDTH : 0 ) ;
2014-10-04 20:52:23 +01:00
int text_y_offset = ( this - > line_height - FONT_HEIGHT_NORMAL ) / 2 ;
2022-10-15 16:55:47 +01:00
int box_y_offset = ( this - > line_height - this - > box . height ) / 2 ;
int button_y_offset = ( this - > line_height - SETTING_BUTTON_HEIGHT ) / 2 ;
int icon_y_offset = ( this - > line_height - this - > icon . height ) / 2 ;
2009-11-19 21:07:08 +00:00
2009-11-15 09:23:40 +00:00
for ( int i = 0 ; i ! = lengthof ( _cheats_ui ) ; i + + ) {
2008-05-15 21:51:52 +01:00
const CheatEntry * ce = & _cheats_ui [ i ] ;
2008-04-17 22:21:01 +01:00
2022-10-15 16:55:47 +01:00
DrawSprite ( ( * ce - > been_used ) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY , PAL_NONE , box_left , y + box_y_offset ) ;
2008-04-17 22:21:01 +01:00
2008-05-15 21:51:52 +01:00
switch ( ce - > type ) {
case SLE_BOOL : {
bool on = ( * ( bool * ) ce - > variable ) ;
2022-09-23 09:36:22 +01:00
DrawBoolButton ( button_left , y + button_y_offset , on , true ) ;
2009-02-08 12:25:13 +00:00
SetDParam ( 0 , on ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF ) ;
2010-08-01 19:53:30 +01:00
break ;
}
2008-05-15 21:51:52 +01:00
default : {
2023-05-08 18:01:06 +01:00
int32_t val = ( int32_t ) ReadValue ( ce - > variable , ce - > type ) ;
2008-05-15 21:51:52 +01:00
/* Draw [<][>] boxes for settings of an integer-type */
2022-10-15 16:55:47 +01:00
DrawArrowButtons ( button_left , y + button_y_offset , COLOUR_YELLOW , clicked - ( i * 2 ) , true , true ) ;
2008-05-15 21:51:52 +01:00
switch ( ce - > str ) {
/* Display date for change date cheat */
2023-04-24 16:56:01 +01:00
case STR_CHEAT_CHANGE_DATE : SetDParam ( 0 , TimerGameCalendar : : date ) ; break ;
2008-05-15 21:51:52 +01:00
2009-02-09 02:57:15 +00:00
/* Draw coloured flag for change company cheat */
2009-11-19 21:07:08 +00:00
case STR_CHEAT_CHANGE_COMPANY : {
2008-11-22 13:09:31 +00:00
SetDParam ( 0 , val + 1 ) ;
2023-05-11 22:36:11 +01:00
uint offset = WidgetDimensions : : scaled . hsep_indent + GetStringBoundingBox ( ce - > str ) . width ;
2022-09-23 09:36:22 +01:00
DrawCompanyIcon ( _local_company , rtl ? text_right - offset - WidgetDimensions : : scaled . hsep_indent : text_left + offset , y + icon_y_offset ) ;
2010-08-01 19:53:30 +01:00
break ;
}
2008-05-15 21:51:52 +01:00
default : SetDParam ( 0 , val ) ;
}
2010-08-01 19:53:30 +01:00
break ;
}
2008-05-15 21:51:52 +01:00
}
2008-04-17 22:21:01 +01:00
2014-10-04 20:52:23 +01:00
DrawString ( text_left , text_right , y + text_y_offset , ce - > str ) ;
2008-04-17 22:21:01 +01:00
2014-10-04 20:52:23 +01:00
y + = this - > line_height ;
2008-04-17 22:21:01 +01:00
}
2008-05-15 21:51:52 +01:00
}
2008-04-17 22:21:01 +01:00
2019-03-04 07:49:37 +00:00
void UpdateWidgetSize ( int widget , Dimension * size , const Dimension & padding , Dimension * fill , Dimension * resize ) override
2009-11-15 09:23:40 +00:00
{
2011-12-16 16:27:45 +00:00
if ( widget ! = WID_C_PANEL ) return ;
2009-11-15 09:23:40 +00:00
uint width = 0 ;
for ( int i = 0 ; i ! = lengthof ( _cheats_ui ) ; i + + ) {
const CheatEntry * ce = & _cheats_ui [ i ] ;
switch ( ce - > type ) {
case SLE_BOOL :
SetDParam ( 0 , STR_CONFIG_SETTING_ON ) ;
2021-01-08 10:16:18 +00:00
width = std : : max ( width , GetStringBoundingBox ( ce - > str ) . width ) ;
2009-11-15 09:23:40 +00:00
SetDParam ( 0 , STR_CONFIG_SETTING_OFF ) ;
2021-01-08 10:16:18 +00:00
width = std : : max ( width , GetStringBoundingBox ( ce - > str ) . width ) ;
2009-11-15 09:23:40 +00:00
break ;
default :
switch ( ce - > str ) {
/* Display date for change date cheat */
case STR_CHEAT_CHANGE_DATE :
2023-05-04 14:14:12 +01:00
SetDParam ( 0 , TimerGameCalendar : : ConvertYMDToDate ( MAX_YEAR , 11 , 31 ) ) ;
2021-01-08 10:16:18 +00:00
width = std : : max ( width , GetStringBoundingBox ( ce - > str ) . width ) ;
2009-11-15 09:23:40 +00:00
break ;
/* Draw coloured flag for change company cheat */
case STR_CHEAT_CHANGE_COMPANY :
2012-12-08 17:18:51 +00:00
SetDParamMaxValue ( 0 , MAX_COMPANIES ) ;
2022-09-23 09:36:22 +01:00
width = std : : max ( width , GetStringBoundingBox ( ce - > str ) . width + WidgetDimensions : : scaled . hsep_wide * 4 ) ;
2009-11-15 09:23:40 +00:00
break ;
default :
SetDParam ( 0 , INT64_MAX ) ;
2021-01-08 10:16:18 +00:00
width = std : : max ( width , GetStringBoundingBox ( ce - > str ) . width ) ;
2009-11-15 09:23:40 +00:00
break ;
}
break ;
}
}
2022-09-23 09:36:22 +01:00
this - > line_height = std : : max ( this - > box . height , this - > icon . height ) ;
2021-01-08 10:16:18 +00:00
this - > line_height = std : : max < uint > ( this - > line_height , SETTING_BUTTON_HEIGHT ) ;
2022-09-23 09:36:22 +01:00
this - > line_height = std : : max < uint > ( this - > line_height , FONT_HEIGHT_NORMAL ) + WidgetDimensions : : scaled . framerect . Vertical ( ) ;
2014-10-04 20:52:23 +01:00
2022-09-23 09:36:22 +01:00
size - > width = width + WidgetDimensions : : scaled . hsep_wide * 4 + this - > box . width + SETTING_BUTTON_WIDTH /* stuff on the left */ + WidgetDimensions : : scaled . hsep_wide * 2 /* extra spacing on right */ ;
size - > height = WidgetDimensions : : scaled . framerect . Vertical ( ) + this - > line_height * lengthof ( _cheats_ui ) ;
2009-11-15 09:23:40 +00:00
}
2019-03-04 07:49:37 +00:00
void OnClick ( Point pt , int widget , int click_count ) override
2008-05-15 21:51:52 +01:00
{
2022-09-23 09:36:22 +01:00
Rect r = this - > GetWidget < NWidgetBase > ( WID_C_PANEL ) - > GetCurrentRect ( ) . Shrink ( WidgetDimensions : : scaled . framerect ) ;
uint btn = ( pt . y - r . top ) / this - > line_height ;
uint x = pt . x - r . left ;
2010-11-13 09:56:25 +00:00
bool rtl = _current_text_dir = = TD_RTL ;
2022-09-23 09:36:22 +01:00
if ( rtl ) x = r . Width ( ) - 1 - x ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:51:02 +00:00
if ( btn > = lengthof ( _cheats_ui ) ) return ;
2008-04-17 22:21:01 +01:00
2008-05-15 21:51:52 +01:00
const CheatEntry * ce = & _cheats_ui [ btn ] ;
2023-05-08 18:01:06 +01:00
int value = ( int32_t ) ReadValue ( ce - > variable , ce - > type ) ;
2008-05-15 21:51:52 +01:00
int oldvalue = value ;
2008-04-17 22:21:01 +01:00
2022-09-23 09:36:22 +01:00
if ( btn = = CHT_CHANGE_DATE & & x > = WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH ) {
2010-12-04 21:51:02 +00:00
/* Click at the date text directly. */
2014-09-21 13:39:24 +01:00
clicked_widget = CHT_CHANGE_DATE ;
2010-12-04 21:51:02 +00:00
SetDParam ( 0 , value ) ;
2011-04-17 19:42:17 +01:00
ShowQueryString ( STR_JUST_INT , STR_CHEAT_CHANGE_DATE_QUERY_CAPT , 8 , this , CS_NUMERAL , QSF_ACCEPT_UNCHANGED ) ;
2010-12-04 21:51:02 +00:00
return ;
2022-09-23 09:36:22 +01:00
} else if ( btn = = CHT_EDIT_MAX_HL & & x > = WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH ) {
2014-09-21 13:39:24 +01:00
clicked_widget = CHT_EDIT_MAX_HL ;
SetDParam ( 0 , value ) ;
ShowQueryString ( STR_JUST_INT , STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT , 8 , this , CS_NUMERAL , QSF_ACCEPT_UNCHANGED ) ;
return ;
2010-12-04 21:51:02 +00:00
}
/* Not clicking a button? */
2022-09-23 09:36:22 +01:00
if ( ! IsInsideMM ( x , WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width , WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH ) ) return ;
2010-12-04 21:51:02 +00:00
2008-05-15 21:51:52 +01:00
* ce - > been_used = true ;
2008-04-17 22:21:01 +01:00
2008-05-15 21:51:52 +01:00
switch ( ce - > type ) {
case SLE_BOOL :
value ^ = 1 ;
2019-04-10 22:07:06 +01:00
if ( ce - > proc ! = nullptr ) ce - > proc ( value , 0 ) ;
2008-05-15 21:51:52 +01:00
break ;
2008-04-17 22:21:01 +01:00
2008-05-15 21:51:52 +01:00
default :
/* Take whatever the function returns */
2022-09-23 09:36:22 +01:00
value = ce - > proc ( value + ( ( x > = WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH / 2 ) ? 1 : - 1 ) , ( x > = WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH / 2 ) ? 1 : - 1 ) ;
2008-04-17 22:21:01 +01:00
2008-05-15 21:51:52 +01:00
/* The first cheat (money), doesn't return a different value. */
2022-09-23 09:36:22 +01:00
if ( value ! = oldvalue | | btn = = CHT_MONEY ) this - > clicked = btn * 2 + 1 + ( ( x > = WidgetDimensions : : scaled . hsep_wide * 2 + this - > box . width + SETTING_BUTTON_WIDTH / 2 ) ! = rtl ? 1 : 0 ) ;
2008-05-15 21:51:52 +01:00
break ;
}
2008-04-17 22:21:01 +01:00
2023-05-08 18:01:06 +01:00
if ( value ! = oldvalue ) WriteValue ( ce - > variable , ce - > type , ( int64_t ) value ) ;
2008-04-17 22:21:01 +01:00
2011-12-15 19:54:23 +00:00
this - > SetTimeout ( ) ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:25:24 +00:00
this - > SetDirty ( ) ;
2008-05-15 21:51:52 +01:00
}
2008-04-17 22:21:01 +01:00
2019-03-04 07:49:37 +00:00
void OnTimeout ( ) override
2008-05-15 21:51:52 +01:00
{
this - > clicked = 0 ;
this - > SetDirty ( ) ;
2008-04-17 22:21:01 +01:00
}
2010-12-04 21:51:02 +00:00
2019-03-04 07:49:37 +00:00
void OnQueryTextFinished ( char * str ) override
2010-12-04 21:51:02 +00:00
{
/* Was 'cancel' pressed or nothing entered? */
2019-04-10 22:07:06 +01:00
if ( str = = nullptr | | StrEmpty ( str ) ) return ;
2010-12-04 21:51:02 +00:00
2014-09-21 13:39:24 +01:00
const CheatEntry * ce = & _cheats_ui [ clicked_widget ] ;
2023-05-08 18:01:06 +01:00
int oldvalue = ( int32_t ) ReadValue ( ce - > variable , ce - > type ) ;
2010-12-04 21:51:02 +00:00
int value = atoi ( str ) ;
* ce - > been_used = true ;
value = ce - > proc ( value , value - oldvalue ) ;
2023-05-08 18:01:06 +01:00
if ( value ! = oldvalue ) WriteValue ( ce - > variable , ce - > type , ( int64_t ) value ) ;
2010-12-04 21:51:02 +00:00
this - > SetDirty ( ) ;
}
2023-04-13 12:56:00 +01:00
IntervalTimer < TimerGameCalendar > daily_interval = { { TimerGameCalendar : : MONTH , TimerGameCalendar : : Priority : : NONE } , [ this ] ( auto ) {
this - > SetDirty ( ) ;
} } ;
2008-05-15 21:51:52 +01:00
} ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:25:24 +00:00
/** Window description of the cheats GUI. */
2013-05-26 20:23:42 +01:00
static WindowDesc _cheats_desc (
2013-05-26 20:25:01 +01:00
WDP_AUTO , " cheats " , 0 , 0 ,
2008-04-17 22:21:01 +01:00
WC_CHEATS , WC_NONE ,
2012-11-11 16:10:43 +00:00
0 ,
2023-09-03 21:54:13 +01:00
std : : begin ( _nested_cheat_widgets ) , std : : end ( _nested_cheat_widgets )
2009-03-15 15:12:06 +00:00
) ;
2008-04-17 22:21:01 +01:00
2010-12-04 21:25:24 +00:00
/** Open cheat window. */
2008-04-17 22:21:01 +01:00
void ShowCheatWindow ( )
{
2021-05-17 14:46:38 +01:00
CloseWindowById ( WC_CHEATS , 0 ) ;
2008-05-15 21:51:52 +01:00
new CheatWindow ( & _cheats_desc ) ;
2008-04-17 22:21:01 +01:00
}