2018-01-05 19:21:07 +02:00
/*
* CLobbyScreen . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# include "StdInc.h"
# include "CLobbyScreen.h"
2023-11-09 16:41:00 +02:00
2018-01-05 19:21:07 +02:00
# include "CBonusSelection.h"
2023-11-09 16:41:00 +02:00
# include "TurnOptionsTab.h"
2023-12-28 20:41:01 +02:00
# include "ExtraOptionsTab.h"
2018-01-05 19:21:07 +02:00
# include "OptionsTab.h"
2023-11-09 16:41:00 +02:00
# include "RandomMapTab.h"
# include "SelectionTab.h"
2018-01-05 19:21:07 +02:00
2023-11-09 16:41:00 +02:00
# include "../CServerHandler.h"
2018-01-05 19:21:07 +02:00
# include "../gui/CGuiHandler.h"
2023-04-27 19:21:06 +02:00
# include "../gui/Shortcut.h"
2018-01-05 19:21:07 +02:00
# include "../widgets/Buttons.h"
# include "../windows/InfoWindows.h"
2023-07-31 18:50:55 +02:00
# include "../render/Colors.h"
2018-01-05 19:21:07 +02:00
# include "../../CCallback.h"
2023-11-13 19:49:41 +02:00
# include "../../lib/CConfigHandler.h"
2018-01-05 19:21:07 +02:00
# include "../../lib/CGeneralTextHandler.h"
2023-06-25 21:28:24 +02:00
# include "../../lib/campaign/CampaignHandler.h"
2018-01-05 19:21:07 +02:00
# include "../../lib/mapping/CMapInfo.h"
2023-11-13 19:49:41 +02:00
# include "../../lib/networkPacks/PacksForLobby.h"
2018-01-05 19:21:07 +02:00
# include "../../lib/rmg/CMapGenOptions.h"
2023-11-13 19:49:41 +02:00
# include "../CGameInfo.h"
2018-01-05 19:21:07 +02:00
CLobbyScreen : : CLobbyScreen ( ESelectionScreen screenType )
: CSelectionBase ( screenType ) , bonusSel ( nullptr )
{
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE ;
tabSel = std : : make_shared < SelectionTab > ( screenType ) ;
curTab = tabSel ;
auto initLobby = [ & ] ( )
{
tabSel - > callOnSelect = std : : bind ( & IServerAPI : : setMapInfo , CSH , _1 , nullptr ) ;
2023-08-23 14:07:50 +02:00
buttonSelect = std : : make_shared < CButton > ( Point ( 411 , 80 ) , AnimationPath : : builtin ( " GSPBUTT.DEF " ) , CGI - > generaltexth - > zelp [ 45 ] , 0 , EShortcut : : LOBBY_SELECT_SCENARIO ) ;
2018-01-05 19:21:07 +02:00
buttonSelect - > addCallback ( [ & ] ( )
{
toggleTab ( tabSel ) ;
CSH - > setMapInfo ( tabSel - > getSelectedMapInfo ( ) ) ;
} ) ;
2023-08-23 14:07:50 +02:00
buttonOptions = std : : make_shared < CButton > ( Point ( 411 , 510 ) , AnimationPath : : builtin ( " GSPBUTT.DEF " ) , CGI - > generaltexth - > zelp [ 46 ] , std : : bind ( & CLobbyScreen : : toggleTab , this , tabOpt ) , EShortcut : : LOBBY_ADDITIONAL_OPTIONS ) ;
2023-11-13 19:49:41 +02:00
if ( settings [ " general " ] [ " enableUiEnhancements " ] . Bool ( ) )
2023-12-28 20:41:01 +02:00
{
buttonTurnOptions = std : : make_shared < CButton > ( Point ( 619 , 105 ) , AnimationPath : : builtin ( " GSPBUT2.DEF " ) , CGI - > generaltexth - > zelp [ 46 ] , std : : bind ( & CLobbyScreen : : toggleTab , this , tabTurnOptions ) , EShortcut : : NONE ) ;
buttonExtraOptions = std : : make_shared < CButton > ( Point ( 619 , 510 ) , AnimationPath : : builtin ( " GSPBUT2.DEF " ) , CGI - > generaltexth - > zelp [ 46 ] , std : : bind ( & CLobbyScreen : : toggleTab , this , tabExtraOptions ) , EShortcut : : NONE ) ;
}
2018-01-05 19:21:07 +02:00
} ;
2023-08-23 14:07:50 +02:00
buttonChat = std : : make_shared < CButton > ( Point ( 619 , 80 ) , AnimationPath : : builtin ( " GSPBUT2.DEF " ) , CGI - > generaltexth - > zelp [ 48 ] , std : : bind ( & CLobbyScreen : : toggleChat , this ) , EShortcut : : LOBBY_HIDE_CHAT ) ;
2023-07-31 18:50:55 +02:00
buttonChat - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 532 ] , FONT_SMALL , Colors : : WHITE ) ;
2018-01-05 19:21:07 +02:00
switch ( screenType )
{
case ESelectionScreen : : newGame :
{
tabOpt = std : : make_shared < OptionsTab > ( ) ;
2023-11-09 16:41:00 +02:00
tabTurnOptions = std : : make_shared < TurnOptionsTab > ( ) ;
2023-12-28 20:41:01 +02:00
tabExtraOptions = std : : make_shared < ExtraOptionsTab > ( ) ;
2018-01-05 19:21:07 +02:00
tabRand = std : : make_shared < RandomMapTab > ( ) ;
tabRand - > mapInfoChanged + = std : : bind ( & IServerAPI : : setMapInfo , CSH , _1 , _2 ) ;
2023-08-23 14:07:50 +02:00
buttonRMG = std : : make_shared < CButton > ( Point ( 411 , 105 ) , AnimationPath : : builtin ( " GSPBUTT.DEF " ) , CGI - > generaltexth - > zelp [ 47 ] , 0 , EShortcut : : LOBBY_RANDOM_MAP ) ;
2018-01-05 19:21:07 +02:00
buttonRMG - > addCallback ( [ & ] ( )
{
toggleTab ( tabRand ) ;
tabRand - > updateMapInfoByHost ( ) ; // TODO: This is only needed to force-update mapInfo in CSH when tab is opened
} ) ;
card - > iconDifficulty - > addCallback ( std : : bind ( & IServerAPI : : setDifficulty , CSH , _1 ) ) ;
2023-11-20 14:38:57 +02:00
buttonStart = std : : make_shared < CButton > ( Point ( 411 , 535 ) , AnimationPath : : builtin ( " SCNRBEG.DEF " ) , CGI - > generaltexth - > zelp [ 103 ] , std : : bind ( & CLobbyScreen : : startScenario , this , false ) , EShortcut : : LOBBY_BEGIN_GAME ) ;
2018-01-05 19:21:07 +02:00
initLobby ( ) ;
break ;
}
case ESelectionScreen : : loadGame :
{
tabOpt = std : : make_shared < OptionsTab > ( ) ;
2023-11-09 16:41:00 +02:00
tabTurnOptions = std : : make_shared < TurnOptionsTab > ( ) ;
2023-12-28 20:41:01 +02:00
tabExtraOptions = std : : make_shared < ExtraOptionsTab > ( ) ;
2023-11-20 14:38:57 +02:00
buttonStart = std : : make_shared < CButton > ( Point ( 411 , 535 ) , AnimationPath : : builtin ( " SCNRLOD.DEF " ) , CGI - > generaltexth - > zelp [ 103 ] , std : : bind ( & CLobbyScreen : : startScenario , this , false ) , EShortcut : : LOBBY_LOAD_GAME ) ;
2018-01-05 19:21:07 +02:00
initLobby ( ) ;
break ;
}
case ESelectionScreen : : campaignList :
tabSel - > callOnSelect = std : : bind ( & IServerAPI : : setMapInfo , CSH , _1 , nullptr ) ;
2023-08-23 14:07:50 +02:00
buttonStart = std : : make_shared < CButton > ( Point ( 411 , 535 ) , AnimationPath : : builtin ( " SCNRLOD.DEF " ) , CButton : : tooltip ( ) , std : : bind ( & CLobbyScreen : : startCampaign , this ) , EShortcut : : LOBBY_BEGIN_GAME ) ;
2018-01-05 19:21:07 +02:00
break ;
}
2023-09-11 18:39:32 +02:00
buttonStart - > block ( true ) ; // to be unblocked after map list is ready
2023-08-23 14:07:50 +02:00
buttonBack = std : : make_shared < CButton > ( Point ( 581 , 535 ) , AnimationPath : : builtin ( " SCNRBACK.DEF " ) , CGI - > generaltexth - > zelp [ 105 ] , [ & ] ( )
2018-07-25 00:36:48 +02:00
{
CSH - > sendClientDisconnecting ( ) ;
close ( ) ;
2023-04-27 19:21:06 +02:00
} , EShortcut : : GLOBAL_CANCEL ) ;
2018-01-05 19:21:07 +02:00
}
CLobbyScreen : : ~ CLobbyScreen ( )
{
// TODO: For now we always destroy whole lobby when leaving bonus selection screen
2024-02-04 19:56:04 +02:00
if ( CSH - > getState ( ) = = EClientState : : LOBBY_CAMPAIGN )
2018-01-05 19:21:07 +02:00
CSH - > sendClientDisconnecting ( ) ;
}
void CLobbyScreen : : toggleTab ( std : : shared_ptr < CIntObject > tab )
{
if ( tab = = curTab )
CSH - > sendGuiAction ( LobbyGuiAction : : NO_TAB ) ;
else if ( tab = = tabOpt )
CSH - > sendGuiAction ( LobbyGuiAction : : OPEN_OPTIONS ) ;
else if ( tab = = tabSel )
CSH - > sendGuiAction ( LobbyGuiAction : : OPEN_SCENARIO_LIST ) ;
else if ( tab = = tabRand )
CSH - > sendGuiAction ( LobbyGuiAction : : OPEN_RANDOM_MAP_OPTIONS ) ;
2023-12-20 23:52:39 +02:00
else if ( tab = = tabTurnOptions )
CSH - > sendGuiAction ( LobbyGuiAction : : OPEN_TURN_OPTIONS ) ;
2023-12-28 20:41:01 +02:00
else if ( tab = = tabExtraOptions )
CSH - > sendGuiAction ( LobbyGuiAction : : OPEN_EXTRA_OPTIONS ) ;
2018-01-05 19:21:07 +02:00
CSelectionBase : : toggleTab ( tab ) ;
}
void CLobbyScreen : : startCampaign ( )
{
2024-01-24 13:44:22 +02:00
if ( ! CSH - > mi )
return ;
try {
2023-06-25 20:16:03 +02:00
auto ourCampaign = CampaignHandler : : getCampaign ( CSH - > mi - > fileURI ) ;
2018-01-05 19:21:07 +02:00
CSH - > setCampaignState ( ourCampaign ) ;
}
2024-01-24 13:44:22 +02:00
catch ( const std : : runtime_error & e )
{
// handle possible exception on map loading. For example campaign that contains map in unsupported format
// for example, wog campaigns or hota campaigns without hota map support mod
MetaString message ;
message . appendTextID ( " vcmi.client.errors.invalidMap " ) ;
message . replaceRawString ( e . what ( ) ) ;
CInfoWindow : : showInfoDialog ( message . toString ( ) , { } ) ;
}
2018-01-05 19:21:07 +02:00
}
void CLobbyScreen : : startScenario ( bool allowOnlyAI )
{
2023-09-11 18:39:32 +02:00
if ( CSH - > validateGameStart ( allowOnlyAI ) )
2018-01-05 19:21:07 +02:00
{
CSH - > sendStartGame ( allowOnlyAI ) ;
buttonStart - > block ( true ) ;
}
}
void CLobbyScreen : : toggleMode ( bool host )
{
tabSel - > toggleMode ( ) ;
buttonStart - > block ( ! host ) ;
if ( screenType = = ESelectionScreen : : campaignList )
return ;
auto buttonColor = host ? Colors : : WHITE : Colors : : ORANGE ;
buttonSelect - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 500 ] , FONT_SMALL , buttonColor ) ;
buttonOptions - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 501 ] , FONT_SMALL , buttonColor ) ;
2023-11-13 19:49:41 +02:00
if ( buttonTurnOptions )
buttonTurnOptions - > addTextOverlay ( CGI - > generaltexth - > translate ( " vcmi.optionsTab.turnOptions.hover " ) , FONT_SMALL , buttonColor ) ;
2023-12-28 20:41:01 +02:00
if ( buttonExtraOptions )
buttonExtraOptions - > addTextOverlay ( CGI - > generaltexth - > translate ( " vcmi.optionsTab.extraOptions.hover " ) , FONT_SMALL , buttonColor ) ;
2018-01-05 19:21:07 +02:00
if ( buttonRMG )
{
buttonRMG - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 740 ] , FONT_SMALL , buttonColor ) ;
buttonRMG - > block ( ! host ) ;
}
buttonSelect - > block ( ! host ) ;
buttonOptions - > block ( ! host ) ;
2023-11-13 19:49:41 +02:00
if ( buttonTurnOptions )
buttonTurnOptions - > block ( ! host ) ;
2018-01-05 19:21:07 +02:00
2023-12-28 20:41:01 +02:00
if ( buttonExtraOptions )
buttonExtraOptions - > block ( ! host ) ;
2018-01-05 19:21:07 +02:00
if ( CSH - > mi )
2023-11-09 16:41:00 +02:00
{
2018-01-05 19:21:07 +02:00
tabOpt - > recreate ( ) ;
2023-11-09 16:41:00 +02:00
tabTurnOptions - > recreate ( ) ;
2023-12-28 20:41:01 +02:00
tabExtraOptions - > recreate ( ) ;
2023-11-09 16:41:00 +02:00
}
2018-01-05 19:21:07 +02:00
}
void CLobbyScreen : : toggleChat ( )
{
card - > toggleChat ( ) ;
if ( card - > showChat )
2023-07-31 18:50:55 +02:00
buttonChat - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 531 ] , FONT_SMALL , Colors : : WHITE ) ;
2018-01-05 19:21:07 +02:00
else
2023-07-31 18:50:55 +02:00
buttonChat - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 532 ] , FONT_SMALL , Colors : : WHITE ) ;
2018-01-05 19:21:07 +02:00
}
void CLobbyScreen : : updateAfterStateChange ( )
{
2023-11-09 16:41:00 +02:00
if ( CSH - > mi )
{
if ( tabOpt )
tabOpt - > recreate ( ) ;
if ( tabTurnOptions )
2023-12-28 20:41:01 +02:00
tabTurnOptions - > recreate ( ) ;
if ( tabExtraOptions )
tabExtraOptions - > recreate ( ) ;
2023-11-09 16:41:00 +02:00
}
2018-01-05 19:21:07 +02:00
2023-09-11 18:39:32 +02:00
buttonStart - > block ( CSH - > mi = = nullptr | | CSH - > isGuest ( ) ) ;
2018-01-05 19:21:07 +02:00
card - > changeSelection ( ) ;
2020-01-21 11:09:08 +02:00
if ( card - > iconDifficulty )
{
if ( screenType = = ESelectionScreen : : loadGame )
{
// When loading the game, only one button in the difficulty toggle group should be enabled, so here disable all other buttons first, then make selection
card - > iconDifficulty - > setSelectedOnly ( CSH - > si - > difficulty ) ;
}
else
{
card - > iconDifficulty - > setSelected ( CSH - > si - > difficulty ) ;
}
}
2023-04-24 16:17:12 +02:00
if ( curTab & & curTab = = tabRand & & CSH - > si - > mapGenOptions )
2018-01-05 19:21:07 +02:00
tabRand - > setMapGenOptions ( CSH - > si - > mapGenOptions ) ;
}
const StartInfo * CLobbyScreen : : getStartInfo ( )
{
return CSH - > si . get ( ) ;
}
const CMapInfo * CLobbyScreen : : getMapInfo ( )
{
return CSH - > mi . get ( ) ;
}