2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2008-08-02 18:08:03 +03:00
# include "CPreGame.h"
2011-12-14 00:23:17 +03:00
2013-07-28 17:49:50 +03:00
# include "../lib/filesystem/Filesystem.h"
2013-04-07 13:48:07 +03:00
# include "../lib/filesystem/CCompressedStream.h"
2012-08-01 15:02:54 +03:00
2011-12-17 21:59:59 +03:00
# include "../lib/CStopWatch.h"
2013-04-07 14:52:07 +03:00
# include "gui/SDL_Extensions.h"
2008-08-02 18:08:03 +03:00
# include "CGameInfo.h"
2013-04-07 14:52:07 +03:00
# include "gui/CCursorHandler.h"
2010-12-20 23:22:53 +02:00
# include "CDefHandler.h"
# include "../lib/CGeneralTextHandler.h"
# include "../lib/CTownHandler.h"
# include "../lib/CHeroHandler.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CCampaignHandler.h"
2010-12-20 23:22:53 +02:00
# include "../lib/CCreatureHandler.h"
2011-09-03 22:51:45 +03:00
# include "../lib/JsonNode.h"
2010-12-20 23:22:53 +02:00
# include "CMusicHandler.h"
# include "CVideoHandler.h"
2009-05-20 13:08:56 +03:00
# include "Graphics.h"
# include "../lib/Connection.h"
2009-10-10 08:47:59 +03:00
# include "../lib/VCMIDirs.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CMap.h"
2014-07-13 20:53:37 +03:00
# include "windows/GUIClasses.h"
2009-08-27 11:04:32 +03:00
# include "CPlayerInterface.h"
# include "../CCallback.h"
2010-02-08 16:38:06 +02:00
# include "CMessage.h"
2015-02-02 10:25:26 +02:00
# include "../lib/spells/CSpellHandler.h" /*for campaign bonuses*/
2010-12-20 23:22:53 +02:00
# include "../lib/CArtHandler.h" /*for campaign bonuses*/
# include "../lib/CBuildingHandler.h" /*for campaign bonuses*/
2010-08-17 17:58:13 +03:00
# include "CBitmapHandler.h"
2010-09-03 21:42:54 +03:00
# include "Client.h"
# include "../lib/NetPacks.h"
2014-02-24 22:57:33 +03:00
# include "../lib/registerTypes//RegisterTypes.h"
2011-12-14 00:23:17 +03:00
# include "../lib/CThreadHelper.h"
2012-09-29 13:59:43 +03:00
# include "../lib/CConfigHandler.h"
2011-12-14 00:23:17 +03:00
# include "../lib/GameConstants.h"
2013-04-07 14:52:07 +03:00
# include "gui/CGuiHandler.h"
2014-07-15 10:14:49 +03:00
# include "gui/CAnimation.h"
# include "widgets/CComponent.h"
# include "widgets/Buttons.h"
2014-07-13 20:53:37 +03:00
# include "widgets/MiscWidgets.h"
2014-07-15 10:14:49 +03:00
# include "widgets/ObjectLists.h"
# include "widgets/TextControls.h"
# include "windows/InfoWindows.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CMapService.h"
2014-04-10 20:11:09 +03:00
# include "../lib/CRandomGenerator.h"
2015-08-22 15:47:40 +02:00
# include "../lib/CondSh.h"
2010-08-02 17:29:30 +03:00
2009-04-15 17:03:31 +03:00
/*
* CPreGame . 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
*
*/
2009-08-17 13:47:08 +03:00
namespace fs = boost : : filesystem ;
2010-02-20 15:24:38 +02:00
2013-06-26 14:18:27 +03:00
void startGame ( StartInfo * options , CConnection * serv = nullptr ) ;
2013-12-17 15:12:25 +03:00
void endGame ( ) ;
2009-04-15 17:03:31 +03:00
2012-05-18 20:35:46 +03:00
CGPreGame * CGP = nullptr ;
2010-10-24 14:35:14 +03:00
ISelectionScreenInfo * SEL ;
2013-03-03 20:06:03 +03:00
static PlayerColor playerColor ; //if more than one player - applies to the first
2008-12-21 21:17:35 +02:00
2012-11-20 20:53:45 +03:00
/**
* Stores the current name of the savegame .
*
* TODO better solution for auto - selection when saving already saved games .
* - > CSelectionScreen should be divided into CLoadGameScreen , CSaveGameScreen , . . .
* The name of the savegame can then be stored non - statically in CGameState and
* passed separately to CSaveGameScreen .
*/
static std : : string saveGameName ;
2010-10-24 14:35:14 +03:00
struct EvilHlpStruct
{
CConnection * serv ;
StartInfo * sInfo ;
2011-11-27 16:14:20 +03:00
void reset ( bool strong = true )
2010-10-24 14:35:14 +03:00
{
if ( strong )
{
2011-12-14 00:23:17 +03:00
vstd : : clear_pointer ( serv ) ;
vstd : : clear_pointer ( sInfo ) ;
2010-10-24 14:35:14 +03:00
}
else
{
2013-06-26 14:18:27 +03:00
serv = nullptr ;
sInfo = nullptr ;
2010-10-24 14:35:14 +03:00
}
}
} startingInfo ;
2009-11-01 03:15:16 +02:00
static void do_quit ( )
{
SDL_Event event ;
event . quit . type = SDL_QUIT ;
SDL_PushEvent ( & event ) ;
}
2009-10-26 07:39:30 +02:00
2010-03-08 00:56:51 +02:00
static CMapInfo * mapInfoFromGame ( )
{
2013-06-29 16:05:48 +03:00
auto ret = new CMapInfo ( ) ;
2012-11-11 15:23:31 +03:00
ret - > mapHeader = std : : unique_ptr < CMapHeader > ( new CMapHeader ( * LOCPLINT - > cb - > getMapHeader ( ) ) ) ;
2010-03-08 00:56:51 +02:00
return ret ;
}
static void setPlayersFromGame ( )
{
playerColor = LOCPLINT - > playerID ;
}
2010-10-24 14:35:14 +03:00
static void swapPlayers ( PlayerSettings & a , PlayerSettings & b )
2010-03-08 00:56:51 +02:00
{
2012-12-02 15:21:44 +03:00
std : : swap ( a . playerID , b . playerID ) ;
2010-10-24 14:35:14 +03:00
std : : swap ( a . name , b . name ) ;
2012-12-02 15:21:44 +03:00
if ( a . playerID = = 1 )
2010-10-24 14:35:14 +03:00
playerColor = a . color ;
2012-12-02 15:21:44 +03:00
else if ( b . playerID = = 1 )
2010-10-24 14:35:14 +03:00
playerColor = b . color ;
2010-03-08 00:56:51 +02:00
}
2013-03-03 20:06:03 +03:00
void setPlayer ( PlayerSettings & pset , ui8 player , const std : : map < ui8 , std : : string > & playerNames )
2010-10-30 17:53:23 +03:00
{
if ( vstd : : contains ( playerNames , player ) )
pset . name = playerNames . find ( player ) - > second ;
else
pset . name = CGI - > generaltexth - > allTexts [ 468 ] ; //Computer
2012-12-02 15:21:44 +03:00
pset . playerID = player ;
2010-10-30 17:53:23 +03:00
if ( player = = playerNames . begin ( ) - > first )
playerColor = pset . color ;
}
2013-03-03 20:06:03 +03:00
void updateStartInfo ( std : : string filename , StartInfo & sInfo , const CMapHeader * mapHeader , const std : : map < ui8 , std : : string > & playerNames )
2010-10-30 17:53:23 +03:00
{
sInfo . playerInfos . clear ( ) ;
2012-11-20 20:53:45 +03:00
if ( ! mapHeader )
{
2010-10-30 17:53:23 +03:00
return ;
2012-11-20 20:53:45 +03:00
}
2010-10-30 17:53:23 +03:00
sInfo . mapname = filename ;
2013-03-03 20:06:03 +03:00
playerColor = PlayerColor : : NEUTRAL ;
2010-10-30 17:53:23 +03:00
2012-09-24 19:14:53 +03:00
auto namesIt = playerNames . cbegin ( ) ;
2010-10-30 17:53:23 +03:00
2012-11-20 20:53:45 +03:00
for ( int i = 0 ; i < mapHeader - > players . size ( ) ; i + + )
2010-10-30 17:53:23 +03:00
{
const PlayerInfo & pinfo = mapHeader - > players [ i ] ;
//neither computer nor human can play - no player
2012-09-26 16:13:39 +03:00
if ( ! ( pinfo . canHumanPlay | | pinfo . canComputerPlay ) )
2010-10-30 17:53:23 +03:00
continue ;
2013-03-03 20:06:03 +03:00
PlayerSettings & pset = sInfo . playerInfos [ PlayerColor ( i ) ] ;
pset . color = PlayerColor ( i ) ;
2012-09-24 19:14:53 +03:00
if ( pinfo . canHumanPlay & & namesIt ! = playerNames . cend ( ) )
2013-01-06 22:30:12 +03:00
{
2010-10-30 17:53:23 +03:00
setPlayer ( pset , namesIt + + - > first , playerNames ) ;
2013-01-06 22:30:12 +03:00
}
2010-10-30 17:53:23 +03:00
else
2013-01-06 22:30:12 +03:00
{
2010-10-30 17:53:23 +03:00
setPlayer ( pset , 0 , playerNames ) ;
2013-01-06 22:30:12 +03:00
if ( ! pinfo . canHumanPlay )
{
pset . compOnly = true ;
}
}
2010-10-30 17:53:23 +03:00
pset . castle = pinfo . defaultCastle ( ) ;
2011-03-19 16:35:29 +02:00
pset . hero = pinfo . defaultHero ( ) ;
2010-10-30 17:53:23 +03:00
2013-12-23 18:59:37 +03:00
if ( pset . hero ! = PlayerSettings : : RANDOM & & pinfo . hasCustomMainHero ( ) )
2010-10-30 17:53:23 +03:00
{
2013-12-23 18:59:37 +03:00
pset . hero = pinfo . mainCustomHeroId ;
pset . heroName = pinfo . mainCustomHeroName ;
pset . heroPortrait = pinfo . mainCustomHeroPortrait ;
2010-10-30 17:53:23 +03:00
}
2013-12-23 18:59:37 +03:00
2013-02-02 01:04:25 +03:00
pset . handicap = PlayerSettings : : NO_HANDICAP ;
2010-10-30 17:53:23 +03:00
}
}
2010-09-04 17:47:39 +03:00
template < typename T > class CApplyOnPG ;
2010-09-03 21:42:54 +03:00
class CBaseForPGApply
{
public :
2011-11-27 16:14:20 +03:00
virtual void applyOnPG ( CSelectionScreen * selScr , void * pack ) const = 0 ;
2010-09-03 21:42:54 +03:00
virtual ~ CBaseForPGApply ( ) { } ;
2013-06-26 14:18:27 +03:00
template < typename U > static CBaseForPGApply * getApplier ( const U * t = nullptr )
2010-09-03 21:42:54 +03:00
{
return new CApplyOnPG < U > ;
}
} ;
template < typename T > class CApplyOnPG : public CBaseForPGApply
{
public :
2015-10-12 15:47:10 +02:00
void applyOnPG ( CSelectionScreen * selScr , void * pack ) const override
2010-09-03 21:42:54 +03:00
{
T * ptr = static_cast < T * > ( pack ) ;
ptr - > apply ( selScr ) ;
}
} ;
2014-02-19 04:04:27 +03:00
template < > class CApplyOnPG < CPack > : public CBaseForPGApply
{
public :
2015-10-12 15:47:10 +02:00
void applyOnPG ( CSelectionScreen * selScr , void * pack ) const override
2014-02-19 04:04:27 +03:00
{
logGlobal - > errorStream ( ) < < " Cannot apply on PG plain CPack! " ;
assert ( 0 ) ;
}
} ;
2013-06-26 14:18:27 +03:00
static CApplier < CBaseForPGApply > * applier = nullptr ;
2010-09-03 21:42:54 +03:00
2011-11-27 16:14:20 +03:00
static CPicture * createPicture ( const JsonNode & config )
2009-02-06 13:15:39 +02:00
{
2011-11-27 16:14:20 +03:00
return new CPicture ( config [ " name " ] . String ( ) , config [ " x " ] . Float ( ) , config [ " y " ] . Float ( ) ) ;
}
2009-08-17 11:50:31 +03:00
2011-11-27 16:14:20 +03:00
CMenuScreen : : CMenuScreen ( const JsonNode & configNode ) :
config ( configNode )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-05-20 14:03:21 +03:00
background = new CPicture ( config [ " background " ] . String ( ) ) ;
if ( config [ " scalable " ] . Bool ( ) )
{
if ( background - > bg - > format - > palette )
background - > convertToScreenBPP ( ) ;
background - > scaleTo ( Point ( screen - > w , screen - > h ) ) ;
}
pos = background - > center ( ) ;
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " items " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
menuNameToEntry . push_back ( node [ " name " ] . String ( ) ) ;
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " images " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
images . push_back ( createPicture ( node ) ) ;
//Hardcoded entry
menuNameToEntry . push_back ( " credits " ) ;
2014-08-04 21:33:59 +03:00
tabs = new CTabbedInt ( std : : bind ( & CMenuScreen : : createTab , this , _1 ) , CTabbedInt : : DestroyFunc ( ) ) ;
2011-11-27 16:14:20 +03:00
tabs - > type | = REDRAW_PARENT ;
}
CIntObject * CMenuScreen : : createTab ( size_t index )
{
if ( config [ " items " ] . Vector ( ) . size ( ) = = index )
return new CreditsScreen ( ) ;
return new CMenuEntry ( this , config [ " items " ] . Vector ( ) [ index ] ) ;
}
2012-05-18 20:35:46 +03:00
void CMenuScreen : : showAll ( SDL_Surface * to )
{
CIntObject : : showAll ( to ) ;
if ( pos . h ! = to - > h | | pos . w ! = to - > w )
2013-03-03 20:06:03 +03:00
CMessage : : drawBorder ( PlayerColor ( 1 ) , to , pos . w + 28 , pos . h + 30 , pos . x - 14 , pos . y - 15 ) ;
2012-05-18 20:35:46 +03:00
}
2011-11-27 16:14:20 +03:00
void CMenuScreen : : show ( SDL_Surface * to )
{
if ( ! config [ " video " ] . isNull ( ) )
2012-05-18 20:35:46 +03:00
CCS - > videoh - > update ( config [ " video " ] [ " x " ] . Float ( ) + pos . x , config [ " video " ] [ " y " ] . Float ( ) + pos . y , to , true , false ) ;
2011-11-27 16:14:20 +03:00
CIntObject : : show ( to ) ;
}
void CMenuScreen : : activate ( )
{
2012-08-06 10:34:37 +03:00
CCS - > musich - > playMusic ( " Music/MainMenu " , true ) ;
2011-11-27 16:14:20 +03:00
if ( ! config [ " video " ] . isNull ( ) )
CCS - > videoh - > open ( config [ " video " ] [ " name " ] . String ( ) ) ;
CIntObject : : activate ( ) ;
}
void CMenuScreen : : deactivate ( )
{
if ( ! config [ " video " ] . isNull ( ) )
CCS - > videoh - > close ( ) ;
CIntObject : : deactivate ( ) ;
}
void CMenuScreen : : switchToTab ( size_t index )
{
tabs - > setActive ( index ) ;
}
2013-06-26 14:18:27 +03:00
//funciton for std::string -> std::function conversion for main menu
static std : : function < void ( ) > genCommand ( CMenuScreen * menu , std : : vector < std : : string > menuType , const std : : string & string )
2011-11-27 16:14:20 +03:00
{
2016-01-16 17:36:16 +02:00
static const std : : vector < std : : string > commandType =
2014-10-02 18:43:46 +03:00
{ " to " , " campaigns " , " start " , " load " , " exit " , " highscores " } ;
2011-11-27 16:14:20 +03:00
2016-01-16 17:36:16 +02:00
static const std : : vector < std : : string > gameType =
2014-10-02 18:43:46 +03:00
{ " single " , " multi " , " campaign " , " tutorial " } ;
2011-11-27 16:14:20 +03:00
std : : list < std : : string > commands ;
boost : : split ( commands , string , boost : : is_any_of ( " \t " ) ) ;
if ( ! commands . empty ( ) )
2009-02-06 13:15:39 +02:00
{
2011-11-27 16:14:20 +03:00
size_t index = std : : find ( commandType . begin ( ) , commandType . end ( ) , commands . front ( ) ) - commandType . begin ( ) ;
commands . pop_front ( ) ;
if ( index > 3 | | ! commands . empty ( ) )
2009-02-06 13:15:39 +02:00
{
2011-11-27 16:14:20 +03:00
switch ( index )
{
break ; case 0 : //to - switch to another tab, if such tab exists
{
size_t index2 = std : : find ( menuType . begin ( ) , menuType . end ( ) , commands . front ( ) ) - menuType . begin ( ) ;
if ( index2 ! = menuType . size ( ) )
2014-08-04 21:33:59 +03:00
return std : : bind ( & CMenuScreen : : switchToTab , menu , index2 ) ;
2011-11-27 16:14:20 +03:00
}
break ; case 1 : //open campaign selection window
{
2014-08-04 21:33:59 +03:00
return std : : bind ( & CGPreGame : : openCampaignScreen , CGP , commands . front ( ) ) ;
2011-11-27 16:14:20 +03:00
}
break ; case 2 : //start
{
switch ( std : : find ( gameType . begin ( ) , gameType . end ( ) , commands . front ( ) ) - gameType . begin ( ) )
{
2014-08-04 21:33:59 +03:00
case 0 : return std : : bind ( & CGPreGame : : openSel , CGP , CMenuScreen : : newGame , CMenuScreen : : SINGLE_PLAYER ) ;
2011-11-27 16:14:20 +03:00
case 1 : return & pushIntT < CMultiMode > ;
2014-08-04 21:33:59 +03:00
case 2 : return std : : bind ( & CGPreGame : : openSel , CGP , CMenuScreen : : campaignList , CMenuScreen : : SINGLE_PLAYER ) ;
2013-10-21 00:53:27 +03:00
//TODO: start tutorial
2014-08-04 21:33:59 +03:00
case 3 : return std : : bind ( CInfoWindow : : showInfoDialog , " Sorry, tutorial is not implemented yet \n " , ( const std : : vector < CComponent * > * ) nullptr , false , PlayerColor ( 1 ) ) ;
2011-11-27 16:14:20 +03:00
}
}
break ; case 3 : //load
{
switch ( std : : find ( gameType . begin ( ) , gameType . end ( ) , commands . front ( ) ) - gameType . begin ( ) )
{
2014-08-04 21:33:59 +03:00
case 0 : return std : : bind ( & CGPreGame : : openSel , CGP , CMenuScreen : : loadGame , CMenuScreen : : SINGLE_PLAYER ) ;
case 1 : return std : : bind ( & CGPreGame : : openSel , CGP , CMenuScreen : : loadGame , CMenuScreen : : MULTI_HOT_SEAT ) ;
2013-10-21 00:53:27 +03:00
//TODO: load campaign
2014-08-04 21:33:59 +03:00
case 2 : return std : : bind ( CInfoWindow : : showInfoDialog , " This function is not implemented yet. Campaign saves can be loaded from \" Single Player \" menu " , ( const std : : vector < CComponent * > * ) nullptr , false , PlayerColor ( 1 ) ) ;
2013-10-21 00:53:27 +03:00
//TODO: load tutorial
2014-08-04 21:33:59 +03:00
case 3 : return std : : bind ( CInfoWindow : : showInfoDialog , " Sorry, tutorial is not implemented yet \n " , ( const std : : vector < CComponent * > * ) nullptr , false , PlayerColor ( 1 ) ) ;
2011-11-27 16:14:20 +03:00
}
}
break ; case 4 : //exit
{
2014-08-04 21:33:59 +03:00
return std : : bind ( CInfoWindow : : showYesNoDialog , std : : ref ( CGI - > generaltexth - > allTexts [ 69 ] ) , ( const std : : vector < CComponent * > * ) nullptr , do_quit , 0 , false , PlayerColor ( 1 ) ) ;
2011-11-27 16:14:20 +03:00
}
break ; case 5 : //highscores
{
2013-10-21 00:53:27 +03:00
//TODO: high scores
2014-08-04 21:33:59 +03:00
return std : : bind ( CInfoWindow : : showInfoDialog , " Sorry, high scores menu is not implemented yet \n " , ( const std : : vector < CComponent * > * ) nullptr , false , PlayerColor ( 1 ) ) ;
2011-11-27 16:14:20 +03:00
}
}
2010-02-08 16:38:06 +02:00
}
2009-02-06 13:15:39 +02:00
}
2016-03-12 03:41:27 +02:00
logGlobal - > errorStream ( ) < < " Failed to parse command: " < < string ;
2013-06-26 14:18:27 +03:00
return std : : function < void ( ) > ( ) ;
2011-11-27 16:14:20 +03:00
}
2014-08-03 14:16:19 +03:00
CButton * CMenuEntry : : createButton ( CMenuScreen * parent , const JsonNode & button )
2011-11-27 16:14:20 +03:00
{
2013-06-26 14:18:27 +03:00
std : : function < void ( ) > command = genCommand ( parent , parent - > menuNameToEntry , button [ " command " ] . String ( ) ) ;
2009-08-17 11:50:31 +03:00
2011-11-27 16:14:20 +03:00
std : : pair < std : : string , std : : string > help ;
if ( ! button [ " help " ] . isNull ( ) & & button [ " help " ] . Float ( ) > 0 )
help = CGI - > generaltexth - > zelp [ button [ " help " ] . Float ( ) ] ;
2012-05-20 14:03:21 +03:00
int posx = button [ " x " ] . Float ( ) ;
if ( posx < 0 )
posx = pos . w + posx ;
int posy = button [ " y " ] . Float ( ) ;
if ( posy < 0 )
posy = pos . h + posy ;
2014-08-03 14:16:19 +03:00
return new CButton ( Point ( posx , posy ) , button [ " name " ] . String ( ) , help , command , button [ " hotkey " ] . Float ( ) ) ;
2009-02-06 13:15:39 +02:00
}
2011-11-27 16:14:20 +03:00
CMenuEntry : : CMenuEntry ( CMenuScreen * parent , const JsonNode & config )
2008-08-06 01:11:32 +03:00
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
type | = REDRAW_PARENT ;
2012-05-20 14:03:21 +03:00
pos = parent - > pos ;
2011-11-27 16:14:20 +03:00
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " images " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
images . push_back ( createPicture ( node ) ) ;
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " buttons " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
{
buttons . push_back ( createButton ( parent , node ) ) ;
buttons . back ( ) - > hoverable = true ;
buttons . back ( ) - > type | = REDRAW_PARENT ;
}
2009-08-17 11:50:31 +03:00
}
2013-08-29 19:41:14 +03:00
CreditsScreen : : CreditsScreen ( ) :
positionCounter ( 0 )
2008-08-06 01:11:32 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK ) ;
2011-11-27 16:14:20 +03:00
type | = REDRAW_PARENT ;
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-05-18 20:35:46 +03:00
pos . w = CGP - > menu - > pos . w ;
pos . h = CGP - > menu - > pos . h ;
2013-07-28 17:49:50 +03:00
auto textFile = CResourceHandler : : get ( ) - > load ( ResourceID ( " DATA/CREDITS.TXT " ) ) - > readAll ( ) ;
2012-08-01 15:02:54 +03:00
std : : string text ( ( char * ) textFile . first . get ( ) , textFile . second ) ;
2011-11-27 16:14:20 +03:00
size_t firstQuote = text . find ( ' \" ' ) + 1 ;
text = text . substr ( firstQuote , text . find ( ' \" ' , firstQuote ) - firstQuote ) ;
2013-08-29 19:41:14 +03:00
credits = new CMultiLineLabel ( Rect ( pos . w - 350 , 0 , 350 , 600 ) , FONT_CREDITS , CENTER , Colors : : WHITE , text ) ;
credits - > scrollTextTo ( - 600 ) ; // move all text below the screen
2012-05-18 20:35:46 +03:00
}
2011-12-22 16:05:19 +03:00
void CreditsScreen : : show ( SDL_Surface * to )
2009-01-25 18:19:34 +02:00
{
2013-08-29 19:41:14 +03:00
CIntObject : : show ( to ) ;
positionCounter + + ;
if ( positionCounter % 2 = = 0 )
credits - > scrollTextBy ( 1 ) ;
2011-11-27 16:14:20 +03:00
//end of credits, close this screen
2013-08-29 19:41:14 +03:00
if ( credits - > textSize . y + 600 < positionCounter / 2 )
2011-11-27 16:14:20 +03:00
clickRight ( false , false ) ;
}
void CreditsScreen : : clickLeft ( tribool down , bool previousState )
{
clickRight ( down , previousState ) ;
2009-01-25 18:19:34 +02:00
}
2009-08-17 11:50:31 +03:00
2011-11-27 16:14:20 +03:00
void CreditsScreen : : clickRight ( tribool down , bool previousState )
2008-08-02 18:08:03 +03:00
{
2011-11-27 16:14:20 +03:00
CTabbedInt * menu = dynamic_cast < CTabbedInt * > ( parent ) ;
assert ( menu ) ;
menu - > setActive ( 0 ) ;
2008-08-02 18:08:03 +03:00
}
2013-12-17 15:12:25 +03:00
CGPreGameConfig & CGPreGameConfig : : get ( )
{
static CGPreGameConfig config ;
return config ;
}
const JsonNode & CGPreGameConfig : : getConfig ( ) const
{
return config ;
}
2014-02-15 01:46:06 +03:00
const JsonNode & CGPreGameConfig : : getCampaigns ( ) const
{
return campaignSets ;
}
CGPreGameConfig : : CGPreGameConfig ( ) :
campaignSets ( JsonNode ( ResourceID ( " config/campaignSets.json " ) ) ) ,
config ( JsonNode ( ResourceID ( " config/mainmenu.json " ) ) )
2013-12-17 15:12:25 +03:00
{
}
CGPreGame : : CGPreGame ( )
2008-08-02 18:08:03 +03:00
{
2012-07-21 23:16:54 +03:00
pos . w = screen - > w ;
pos . h = screen - > h ;
2009-08-27 11:04:32 +03:00
GH . defActionsDef = 63 ;
2009-08-17 11:50:31 +03:00
CGP = this ;
2013-12-17 15:12:25 +03:00
menu = new CMenuScreen ( CGPreGameConfig : : get ( ) . getConfig ( ) [ " window " ] ) ;
2012-03-11 19:29:01 +03:00
loadGraphics ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
CGPreGame : : ~ CGPreGame ( )
2008-08-06 01:11:32 +03:00
{
2014-03-07 16:21:09 +03:00
boost : : unique_lock < boost : : recursive_mutex > lock ( * CPlayerInterface : : pim ) ;
2012-03-11 19:29:01 +03:00
disposeGraphics ( ) ;
2013-02-05 23:06:13 +03:00
if ( CGP = = this )
CGP = nullptr ;
2013-02-07 18:27:22 +03:00
if ( GH . curInt = = this )
GH . curInt = nullptr ;
2008-08-06 01:11:32 +03:00
}
2009-08-17 11:50:31 +03:00
2010-10-24 14:35:14 +03:00
void CGPreGame : : openSel ( CMenuScreen : : EState screenType , CMenuScreen : : EMultiMode multi /*= CMenuScreen::SINGLE_PLAYER*/ )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
GH . pushInt ( new CSelectionScreen ( screenType , multi ) ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void CGPreGame : : loadGraphics ( )
2008-08-02 18:08:03 +03:00
{
2012-07-21 23:16:54 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
new CFilledTexture ( " DIBOXBCK " , pos ) ;
2009-08-17 11:50:31 +03:00
victory = CDefHandler : : giveDef ( " SCNRVICT.DEF " ) ;
loss = CDefHandler : : giveDef ( " SCNRLOSS.DEF " ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void CGPreGame : : disposeGraphics ( )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
delete victory ;
delete loss ;
2008-08-02 18:08:03 +03:00
}
2009-12-28 06:08:24 +02:00
void CGPreGame : : update ( )
{
2013-02-06 00:19:08 +03:00
if ( CGP ! = this ) //don't update if you are not a main interface
return ;
2011-11-27 16:14:20 +03:00
if ( GH . listInt . empty ( ) )
2009-12-28 06:08:24 +02:00
{
2012-05-18 20:35:46 +03:00
GH . pushInt ( this ) ;
2011-11-27 16:14:20 +03:00
GH . pushInt ( menu ) ;
menu - > switchToTab ( 0 ) ;
2009-12-28 06:08:24 +02:00
}
2010-10-24 14:35:14 +03:00
if ( SEL )
SEL - > update ( ) ;
2011-04-13 22:52:56 +03:00
// Handles mouse and key input
GH . updateTime ( ) ;
GH . handleEvents ( ) ;
2011-04-17 21:02:13 +03:00
2014-02-01 17:32:09 +03:00
// check for null othervice crash on finishing a campaign
// /FIXME: find out why GH.listInt is empty to begin with
if ( GH . topInt ( ) ! = nullptr )
GH . topInt ( ) - > show ( screen ) ;
2009-12-28 06:08:24 +02:00
}
2011-11-27 16:14:20 +03:00
void CGPreGame : : openCampaignScreen ( std : : string name )
{
2014-02-15 01:46:06 +03:00
if ( vstd : : contains ( CGPreGameConfig : : get ( ) . getCampaigns ( ) . Struct ( ) , name ) )
2011-11-27 16:14:20 +03:00
{
2014-02-15 01:46:06 +03:00
GH . pushInt ( new CCampaignScreen ( CGPreGameConfig : : get ( ) . getCampaigns ( ) [ name ] ) ) ;
return ;
2011-11-27 16:14:20 +03:00
}
2014-02-15 01:46:06 +03:00
logGlobal - > errorStream ( ) < < " Unknown campaign set: " < < name ;
2011-11-27 16:14:20 +03:00
}
2012-05-18 20:35:46 +03:00
CGPreGame * CGPreGame : : create ( )
2012-03-11 19:29:01 +03:00
{
if ( ! CGP )
CGP = new CGPreGame ( ) ;
2016-01-16 17:36:16 +02:00
GH . terminate_cond . set ( false ) ;
2012-05-18 20:35:46 +03:00
return CGP ;
2012-03-11 19:29:01 +03:00
}
2012-05-26 20:59:00 +03:00
void CGPreGame : : removeFromGui ( )
{
//remove everything but main menu and background
GH . popInts ( GH . listInt . size ( ) - 2 ) ;
GH . popInt ( GH . topInt ( ) ) ; //remove main menu
GH . popInt ( GH . topInt ( ) ) ; //remove background
}
2013-06-26 14:18:27 +03:00
CSelectionScreen : : CSelectionScreen ( CMenuScreen : : EState Type , CMenuScreen : : EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/ , const std : : map < ui8 , std : : string > * Names /*= nullptr*/ , const std : : string & Address /*=""*/ , const std : : string & Port /*= ""*/ )
: ISelectionScreenInfo ( Names ) , serverHandlingThread ( nullptr ) , mx ( new boost : : recursive_mutex ) ,
serv ( nullptr ) , ongoingClosing ( false ) , myNameID ( 255 )
2010-08-20 16:34:39 +03:00
{
2012-05-18 20:35:46 +03:00
CGPreGame : : create ( ) ; //we depend on its graphics
2010-10-24 14:35:14 +03:00
screenType = Type ;
multiPlayer = MultiPlayer ;
2010-08-20 16:34:39 +03:00
2009-08-27 11:04:32 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-10-24 14:35:14 +03:00
2015-03-15 18:33:58 +02:00
bool network = ( isGuest ( ) | | isHost ( ) ) ;
2010-09-03 21:42:54 +03:00
2013-06-26 14:18:27 +03:00
CServerHandler * sh = nullptr ;
2015-03-15 18:33:58 +02:00
if ( isHost ( ) )
2010-09-03 21:42:54 +03:00
{
sh = new CServerHandler ;
sh - > startServer ( ) ;
}
2011-12-17 21:59:59 +03:00
IShowActivatable : : type = BLOCK_ADV_HOTKEYS ;
2009-08-27 11:04:32 +03:00
pos . w = 762 ;
pos . h = 584 ;
2010-02-13 18:26:47 +02:00
if ( Type = = CMenuScreen : : saveGame )
2009-08-27 11:04:32 +03:00
{
2012-05-18 20:35:46 +03:00
bordered = false ;
2009-08-27 11:04:32 +03:00
center ( pos ) ;
}
2010-02-15 14:12:21 +02:00
else if ( Type = = CMenuScreen : : campaignList )
{
2012-05-18 20:35:46 +03:00
bordered = false ;
2012-08-06 10:34:37 +03:00
bg = new CPicture ( " CamCust.bmp " , 0 , 0 ) ;
2012-05-18 20:35:46 +03:00
pos = bg - > center ( ) ;
2010-02-15 14:12:21 +02:00
}
2009-08-27 11:04:32 +03:00
else
{
2012-05-18 20:35:46 +03:00
bordered = true ;
2012-08-06 10:34:37 +03:00
//load random background
2013-12-17 15:12:25 +03:00
const JsonVector & bgNames = CGPreGameConfig : : get ( ) . getConfig ( ) [ " game-select " ] . Vector ( ) ;
2014-04-10 20:11:09 +03:00
bg = new CPicture ( RandomGeneratorUtil : : nextItem ( bgNames , CRandomGenerator : : getDefault ( ) ) - > String ( ) , 0 , 0 ) ;
2012-05-18 20:35:46 +03:00
pos = bg - > center ( ) ;
2009-08-27 11:04:32 +03:00
}
sInfo . difficulty = 1 ;
2013-06-26 14:18:27 +03:00
current = nullptr ;
2009-08-17 11:50:31 +03:00
2010-08-18 12:50:25 +03:00
sInfo . mode = ( Type = = CMenuScreen : : newGame ? StartInfo : : NEW_GAME : StartInfo : : LOAD_GAME ) ;
2009-08-17 11:50:31 +03:00
sInfo . turnTime = 0 ;
2013-06-26 14:18:27 +03:00
curTab = nullptr ;
2009-08-17 11:50:31 +03:00
2010-10-24 14:35:14 +03:00
card = new InfoCard ( network ) ; //right info card
if ( screenType = = CMenuScreen : : campaignList )
2010-02-13 18:26:47 +02:00
{
2013-06-26 14:18:27 +03:00
opt = nullptr ;
2011-11-27 16:14:20 +03:00
}
2010-02-13 18:26:47 +02:00
else
{
2010-10-24 14:35:14 +03:00
opt = new OptionsTab ( ) ; //scenario options tab
2010-02-13 18:26:47 +02:00
opt - > recActions = DISPOSE ;
2012-11-11 15:23:31 +03:00
2013-05-21 22:08:06 +03:00
randMapTab = new CRandomMapTab ( ) ;
2014-08-04 21:33:59 +03:00
randMapTab - > getMapInfoChanged ( ) + = std : : bind ( & CSelectionScreen : : changeSelection , this , _1 ) ;
2012-11-11 15:23:31 +03:00
randMapTab - > recActions = DISPOSE ;
2010-02-13 18:26:47 +02:00
}
2014-08-04 21:33:59 +03:00
sel = new SelectionTab ( screenType , std : : bind ( & CSelectionScreen : : changeSelection , this , _1 ) , multiPlayer ) ; //scenario selection tab
2009-08-17 11:50:31 +03:00
sel - > recActions = DISPOSE ;
2010-10-24 14:35:14 +03:00
switch ( screenType )
2008-08-02 18:08:03 +03:00
{
2010-02-13 18:26:47 +02:00
case CMenuScreen : : newGame :
2009-08-17 11:50:31 +03:00
{
2014-08-03 14:16:19 +03:00
SDL_Color orange = { 232 , 184 , 32 , 0 } ;
2015-03-15 18:33:58 +02:00
SDL_Color overlayColor = isGuest ( ) ? orange : Colors : : WHITE ;
2014-08-03 14:16:19 +03:00
2014-08-09 15:00:45 +03:00
card - > difficulty - > addCallback ( std : : bind ( & CSelectionScreen : : difficultyChange , this , _1 ) ) ;
2014-08-03 14:16:19 +03:00
card - > difficulty - > setSelected ( 1 ) ;
CButton * select = new CButton ( Point ( 411 , 80 ) , " GSPBUTT.DEF " , CGI - > generaltexth - > zelp [ 45 ] , 0 , SDLK_s ) ;
select - > addCallback ( [ & ] ( )
2012-11-20 20:53:45 +03:00
{
toggleTab ( sel ) ;
changeSelection ( sel - > getSelectedMapInfo ( ) ) ;
2014-08-03 14:16:19 +03:00
} ) ;
select - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 500 ] , FONT_SMALL , overlayColor ) ;
2009-08-17 11:50:31 +03:00
2014-08-09 15:14:31 +03:00
CButton * opts = new CButton ( Point ( 411 , 510 ) , " GSPBUTT.DEF " , CGI - > generaltexth - > zelp [ 46 ] , std : : bind ( & CSelectionScreen : : toggleTab , this , opt ) , SDLK_a ) ;
2014-08-03 14:16:19 +03:00
opts - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 501 ] , FONT_SMALL , overlayColor ) ;
2009-08-17 11:50:31 +03:00
2014-08-03 14:16:19 +03:00
CButton * randomBtn = new CButton ( Point ( 411 , 105 ) , " GSPBUTT.DEF " , CGI - > generaltexth - > zelp [ 47 ] , 0 , SDLK_r ) ;
randomBtn - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 740 ] , FONT_SMALL , overlayColor ) ;
randomBtn - > addCallback ( [ & ] ( )
2012-11-11 15:23:31 +03:00
{
2013-01-26 16:48:20 +03:00
toggleTab ( randMapTab ) ;
2013-05-21 22:08:06 +03:00
changeSelection ( randMapTab - > getMapInfo ( ) ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2009-08-17 11:50:31 +03:00
2014-08-09 15:14:31 +03:00
start = new CButton ( Point ( 411 , 535 ) , " SCNRBEG.DEF " , CGI - > generaltexth - > zelp [ 103 ] , std : : bind ( & CSelectionScreen : : startScenario , this ) , SDLK_b ) ;
2010-09-03 21:42:54 +03:00
2010-10-24 14:35:14 +03:00
if ( network )
2010-09-03 21:42:54 +03:00
{
2014-08-09 15:14:31 +03:00
CButton * hideChat = new CButton ( Point ( 619 , 83 ) , " GSPBUT2.DEF " , CGI - > generaltexth - > zelp [ 48 ] , std : : bind ( & InfoCard : : toggleChat , card ) , SDLK_h ) ;
2010-09-03 21:42:54 +03:00
hideChat - > addTextOverlay ( CGI - > generaltexth - > allTexts [ 531 ] , FONT_SMALL ) ;
2010-10-24 14:35:14 +03:00
2015-03-15 18:33:58 +02:00
if ( isGuest ( ) )
2010-10-24 14:35:14 +03:00
{
select - > block ( true ) ;
opts - > block ( true ) ;
2012-11-11 15:23:31 +03:00
randomBtn - > block ( true ) ;
2010-10-24 14:35:14 +03:00
start - > block ( true ) ;
}
2010-09-03 21:42:54 +03:00
}
2009-08-17 11:50:31 +03:00
}
break ;
2010-02-13 18:26:47 +02:00
case CMenuScreen : : loadGame :
2009-08-17 11:50:31 +03:00
sel - > recActions = 255 ;
2014-08-09 15:14:31 +03:00
start = new CButton ( Point ( 411 , 535 ) , " SCNRLOD.DEF " , CGI - > generaltexth - > zelp [ 103 ] , std : : bind ( & CSelectionScreen : : startScenario , this ) , SDLK_l ) ;
2009-08-27 11:04:32 +03:00
break ;
2010-02-13 18:26:47 +02:00
case CMenuScreen : : saveGame :
2009-08-27 11:04:32 +03:00
sel - > recActions = 255 ;
2014-08-09 15:14:31 +03:00
start = new CButton ( Point ( 411 , 535 ) , " SCNRSAV.DEF " , CGI - > generaltexth - > zelp [ 103 ] , std : : bind ( & CSelectionScreen : : startScenario , this ) , SDLK_s ) ;
2009-08-17 11:50:31 +03:00
break ;
2010-02-13 18:26:47 +02:00
case CMenuScreen : : campaignList :
sel - > recActions = 255 ;
2014-08-09 15:14:31 +03:00
start = new CButton ( Point ( 411 , 535 ) , " SCNRLOD.DEF " , CButton : : tooltip ( ) , std : : bind ( & CSelectionScreen : : startCampaign , this ) , SDLK_b ) ;
2010-02-13 18:26:47 +02:00
break ;
2008-08-02 18:08:03 +03:00
}
2011-11-27 16:14:20 +03:00
2009-08-27 11:04:32 +03:00
start - > assignedKeys . insert ( SDLK_RETURN ) ;
2014-08-09 15:14:31 +03:00
back = new CButton ( Point ( 581 , 535 ) , " SCNRBACK.DEF " , CGI - > generaltexth - > zelp [ 105 ] , std : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) , SDLK_ESCAPE ) ;
2010-09-03 21:42:54 +03:00
2010-10-24 14:35:14 +03:00
if ( network )
2010-09-03 21:42:54 +03:00
{
2015-03-15 18:33:58 +02:00
if ( isHost ( ) )
2010-10-24 14:35:14 +03:00
{
assert ( playerNames . size ( ) = = 1 & & vstd : : contains ( playerNames , 1 ) ) ; //TODO hot-seat/network combo
serv = sh - > connectToServer ( ) ;
* serv < < ( ui8 ) 4 ;
myNameID = 1 ;
}
else
2013-06-02 22:53:13 +03:00
serv = CServerHandler : : justConnectToServer ( Address , Port ) ;
2010-10-24 14:35:14 +03:00
2013-02-14 18:19:35 +03:00
serv - > enterPregameConnectionMode ( ) ;
2010-10-24 14:35:14 +03:00
* serv < < playerNames . begin ( ) - > second ;
2015-03-15 18:33:58 +02:00
if ( isGuest ( ) )
2010-10-24 14:35:14 +03:00
{
const CMapInfo * map ;
* serv > > myNameID > > map ;
serv - > connectionID = myNameID ;
changeSelection ( map ) ;
}
2015-03-15 18:33:58 +02:00
else if ( current )
2010-10-24 14:35:14 +03:00
{
2015-03-15 18:33:58 +02:00
SelectMap sm ( * current ) ;
* serv < < & sm ;
2010-10-24 14:35:14 +03:00
2015-03-15 18:33:58 +02:00
UpdateStartOptions uso ( sInfo ) ;
* serv < < & uso ;
2010-10-24 14:35:14 +03:00
}
applier = new CApplier < CBaseForPGApply > ;
2014-02-24 22:57:33 +03:00
registerTypesPregamePacks ( * applier ) ;
2010-10-24 14:35:14 +03:00
serverHandlingThread = new boost : : thread ( & CSelectionScreen : : handleConnection , this ) ;
2010-09-03 21:42:54 +03:00
}
delete sh ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
CSelectionScreen : : ~ CSelectionScreen ( )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
ongoingClosing = true ;
if ( serv )
{
assert ( serverHandlingThread ) ;
QuitMenuWithoutStarting qmws ;
* serv < < & qmws ;
// while(!serverHandlingThread->timed_join(boost::posix_time::milliseconds(50)))
// processPacks();
serverHandlingThread - > join ( ) ;
delete serverHandlingThread ;
}
2013-03-03 20:06:03 +03:00
playerColor = PlayerColor : : CANNOT_DETERMINE ;
2010-02-16 18:35:24 +02:00
playerNames . clear ( ) ;
2010-10-24 14:35:14 +03:00
assert ( ! serv ) ;
2011-12-14 00:23:17 +03:00
vstd : : clear_pointer ( applier ) ;
2010-10-24 14:35:14 +03:00
delete mx ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void CSelectionScreen : : toggleTab ( CIntObject * tab )
2008-08-02 18:08:03 +03:00
{
2015-03-15 18:33:58 +02:00
if ( isHost ( ) & & serv )
2010-10-24 14:35:14 +03:00
{
PregameGuiAction pga ;
if ( tab = = curTab )
pga . action = PregameGuiAction : : NO_TAB ;
else if ( tab = = opt )
pga . action = PregameGuiAction : : OPEN_OPTIONS ;
else if ( tab = = sel )
pga . action = PregameGuiAction : : OPEN_SCENARIO_LIST ;
2012-11-11 15:23:31 +03:00
else if ( tab = = randMapTab )
pga . action = PregameGuiAction : : OPEN_RANDOM_MAP_OPTIONS ;
2010-10-24 14:35:14 +03:00
* serv < < & pga ;
}
2009-08-17 11:50:31 +03:00
if ( curTab & & curTab - > active )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
curTab - > deactivate ( ) ;
curTab - > recActions = DISPOSE ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
if ( curTab ! = tab )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
tab - > recActions = 255 ;
tab - > activate ( ) ;
curTab = tab ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
else
{
2013-06-26 14:18:27 +03:00
curTab = nullptr ;
2009-08-17 11:50:31 +03:00
} ;
GH . totalRedraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2012-11-20 20:53:45 +03:00
void CSelectionScreen : : changeSelection ( const CMapInfo * to )
2008-08-02 18:08:03 +03:00
{
2013-05-21 22:08:06 +03:00
if ( current = = to ) return ;
2015-03-15 18:33:58 +02:00
if ( isGuest ( ) )
2011-12-14 00:23:17 +03:00
vstd : : clear_pointer ( current ) ;
2008-08-02 18:08:03 +03:00
2010-10-24 14:35:14 +03:00
current = to ;
2011-09-26 03:01:47 +03:00
if ( to & & ( screenType = = CMenuScreen : : loadGame | |
screenType = = CMenuScreen : : saveGame ) )
SEL - > sInfo . difficulty = to - > scenarioOpts - > difficulty ;
if ( screenType ! = CMenuScreen : : campaignList )
2010-02-16 18:35:24 +02:00
{
2013-06-26 14:18:27 +03:00
updateStartInfo ( to ? to - > fileURI : " " , sInfo , to ? to - > mapHeader . get ( ) : nullptr ) ;
2012-11-20 20:53:45 +03:00
if ( screenType = = CMenuScreen : : newGame )
{
2012-12-19 21:19:09 +03:00
if ( to & & to - > isRandomMap )
2012-11-20 20:53:45 +03:00
{
sInfo . mapGenOptions = std : : shared_ptr < CMapGenOptions > ( new CMapGenOptions ( randMapTab - > getMapGenOptions ( ) ) ) ;
}
else
{
2012-12-14 18:32:53 +03:00
sInfo . mapGenOptions . reset ( ) ;
2012-11-20 20:53:45 +03:00
}
}
2010-02-16 18:35:24 +02:00
}
2010-10-24 14:35:14 +03:00
card - > changeSelection ( to ) ;
if ( screenType ! = CMenuScreen : : campaignList )
2010-02-16 18:35:24 +02:00
{
2010-10-24 14:35:14 +03:00
opt - > recreate ( ) ;
2010-02-16 18:35:24 +02:00
}
2015-03-15 18:33:58 +02:00
if ( isHost ( ) & & serv )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
SelectMap sm ( * to ) ;
* serv < < & sm ;
2009-08-17 11:50:31 +03:00
2010-10-24 14:35:14 +03:00
UpdateStartOptions uso ( sInfo ) ;
* serv < < & uso ;
2009-08-17 11:50:31 +03:00
}
2008-08-02 18:08:03 +03:00
}
2008-11-16 03:06:15 +02:00
2010-02-15 14:12:21 +02:00
void CSelectionScreen : : startCampaign ( )
{
2011-11-27 21:55:11 +03:00
if ( SEL - > current )
2012-09-21 20:59:54 +03:00
GH . pushInt ( new CBonusSelection ( SEL - > current - > fileURI ) ) ;
2010-02-15 14:12:21 +02:00
}
2012-12-17 21:01:17 +03:00
void CSelectionScreen : : startScenario ( )
2008-08-06 01:11:32 +03:00
{
2010-10-24 14:35:14 +03:00
if ( screenType = = CMenuScreen : : newGame )
2010-03-08 00:56:51 +02:00
{
//there must be at least one human player before game can be started
2013-03-03 20:06:03 +03:00
std : : map < PlayerColor , PlayerSettings > : : const_iterator i ;
2012-09-24 19:14:53 +03:00
for ( i = SEL - > sInfo . playerInfos . cbegin ( ) ; i ! = SEL - > sInfo . playerInfos . cend ( ) ; i + + )
2012-12-02 15:21:44 +03:00
if ( i - > second . playerID ! = PlayerSettings : : PLAYER_AI )
2010-03-08 00:56:51 +02:00
break ;
2012-09-24 19:14:53 +03:00
if ( i = = SEL - > sInfo . playerInfos . cend ( ) )
2010-03-08 00:56:51 +02:00
{
GH . pushInt ( CInfoWindow : : create ( CGI - > generaltexth - > allTexts [ 530 ] ) ) ; //You must position yourself prior to starting the game.
return ;
}
}
2015-03-15 18:33:58 +02:00
if ( isHost ( ) )
2010-10-24 14:35:14 +03:00
{
start - > block ( true ) ;
StartWithCurrentSettings swcs ;
* serv < < & swcs ;
ongoingClosing = true ;
return ;
}
if ( screenType ! = CMenuScreen : : saveGame )
2009-08-27 11:04:32 +03:00
{
if ( ! current )
return ;
2013-05-21 22:08:06 +03:00
if ( sInfo . mapGenOptions )
{
2014-07-15 17:44:07 +03:00
//copy settings from interface to actual options. TODO: refactor, it used to have no effect at all -.-
sInfo . mapGenOptions = std : : shared_ptr < CMapGenOptions > ( new CMapGenOptions ( randMapTab - > getMapGenOptions ( ) ) ) ;
2013-05-21 22:08:06 +03:00
// Update player settings for RMG
2013-06-29 16:05:48 +03:00
for ( const auto & psetPair : sInfo . playerInfos )
2013-05-21 22:08:06 +03:00
{
const auto & pset = psetPair . second ;
sInfo . mapGenOptions - > setStartingTownForPlayer ( pset . color , pset . castle ) ;
if ( pset . playerID ! = PlayerSettings : : PLAYER_AI )
{
sInfo . mapGenOptions - > setPlayerTypeForStandardPlayer ( pset . color , EPlayerType : : HUMAN ) ;
}
}
if ( ! sInfo . mapGenOptions - > checkOptions ( ) )
{
GH . pushInt ( CInfoWindow : : create ( CGI - > generaltexth - > allTexts [ 751 ] ) ) ;
return ;
}
}
2012-11-20 20:53:45 +03:00
saveGameName . clear ( ) ;
if ( screenType = = CMenuScreen : : loadGame )
{
saveGameName = sInfo . mapname ;
}
2013-06-29 16:05:48 +03:00
auto si = new StartInfo ( sInfo ) ;
2012-05-26 20:59:00 +03:00
CGP - > removeFromGui ( ) ;
2014-08-04 21:33:59 +03:00
CGP - > showLoadingScreen ( std : : bind ( & startGame , si , ( CConnection * ) nullptr ) ) ;
2009-08-27 11:04:32 +03:00
}
else
{
if ( ! ( sel & & sel - > txt & & sel - > txt - > text . size ( ) ) )
return ;
2009-08-17 11:50:31 +03:00
2012-11-20 20:53:45 +03:00
saveGameName = " Saves/ " + sel - > txt - > text ;
2010-03-08 00:56:51 +02:00
CFunctionList < void ( ) > overWrite ;
2014-08-04 21:33:59 +03:00
overWrite + = std : : bind ( & CCallback : : save , LOCPLINT - > cb . get ( ) , saveGameName ) ;
overWrite + = std : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) ;
2010-03-08 00:56:51 +02:00
2014-03-08 19:05:23 +03:00
if ( CResourceHandler : : get ( " local " ) - > existsResource ( ResourceID ( saveGameName , EResType : : CLIENT_SAVEGAME ) ) )
2010-03-08 00:56:51 +02:00
{
std : : string hlp = CGI - > generaltexth - > allTexts [ 493 ] ; //%s exists. Overwrite?
boost : : algorithm : : replace_first ( hlp , " %s " , sel - > txt - > text ) ;
2012-04-09 05:53:50 +03:00
LOCPLINT - > showYesNoDialog ( hlp , overWrite , 0 , false ) ;
2010-03-08 00:56:51 +02:00
}
else
overWrite ( ) ;
2009-08-27 11:04:32 +03:00
}
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void CSelectionScreen : : difficultyChange ( int to )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
assert ( screenType = = CMenuScreen : : newGame ) ;
2009-08-17 11:50:31 +03:00
sInfo . difficulty = to ;
2010-10-24 14:35:14 +03:00
propagateOptions ( ) ;
2011-11-27 16:14:20 +03:00
redraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
2010-09-03 21:42:54 +03:00
void CSelectionScreen : : handleConnection ( )
{
2012-06-27 23:44:01 +03:00
setThreadName ( " CSelectionScreen::handleConnection " ) ;
2010-10-24 14:35:14 +03:00
try
2010-09-03 21:42:54 +03:00
{
2010-10-24 14:35:14 +03:00
assert ( serv ) ;
while ( serv )
{
2013-06-26 14:18:27 +03:00
CPackForSelectionScreen * pack = nullptr ;
2010-10-24 14:35:14 +03:00
* serv > > pack ;
2016-03-12 03:41:27 +02:00
logNetwork - > traceStream ( ) < < " Received a pack of type " < < typeid ( * pack ) . name ( ) ;
2010-10-24 14:35:14 +03:00
assert ( pack ) ;
if ( QuitMenuWithoutStarting * endingPack = dynamic_cast < QuitMenuWithoutStarting * > ( pack ) )
{
endingPack - > apply ( this ) ;
}
else if ( StartWithCurrentSettings * endingPack = dynamic_cast < StartWithCurrentSettings * > ( pack ) )
{
endingPack - > apply ( this ) ;
}
else
{
boost : : unique_lock < boost : : recursive_mutex > lll ( * mx ) ;
upcomingPacks . push_back ( pack ) ;
}
}
2015-02-14 21:42:47 +02:00
}
2010-10-24 14:35:14 +03:00
catch ( int i )
{
if ( i ! = 666 )
throw ;
2010-09-03 21:42:54 +03:00
}
2015-02-14 21:42:47 +02:00
catch ( . . . )
{
handleException ( ) ;
throw ;
}
2010-09-03 21:42:54 +03:00
}
2010-10-24 14:35:14 +03:00
void CSelectionScreen : : setSInfo ( const StartInfo & si )
2010-09-03 21:42:54 +03:00
{
2013-03-03 20:06:03 +03:00
std : : map < PlayerColor , PlayerSettings > : : const_iterator i ;
2012-09-24 19:14:53 +03:00
for ( i = si . playerInfos . cbegin ( ) ; i ! = si . playerInfos . cend ( ) ; i + + )
2010-10-24 14:35:14 +03:00
{
2012-12-02 15:21:44 +03:00
if ( i - > second . playerID = = myNameID )
2010-10-24 14:35:14 +03:00
{
playerColor = i - > first ;
break ;
}
}
2012-09-24 19:14:53 +03:00
if ( i = = si . playerInfos . cend ( ) ) //not found
2013-03-03 20:06:03 +03:00
playerColor = PlayerColor : : CANNOT_DETERMINE ;
2010-10-24 14:35:14 +03:00
sInfo = si ;
if ( current )
opt - > recreate ( ) ; //will force to recreate using current sInfo
2010-09-03 21:42:54 +03:00
2014-08-03 14:16:19 +03:00
card - > difficulty - > setSelected ( si . difficulty ) ;
2010-10-24 14:35:14 +03:00
2015-03-13 22:33:46 +02:00
if ( curTab = = randMapTab )
randMapTab - > setMapGenOptions ( si . mapGenOptions ) ;
2010-10-24 14:35:14 +03:00
GH . totalRedraw ( ) ;
}
void CSelectionScreen : : processPacks ( )
{
boost : : unique_lock < boost : : recursive_mutex > lll ( * mx ) ;
2013-11-03 15:51:25 +03:00
while ( ! upcomingPacks . empty ( ) )
2010-10-24 14:35:14 +03:00
{
CPackForSelectionScreen * pack = upcomingPacks . front ( ) ;
upcomingPacks . pop_front ( ) ;
CBaseForPGApply * apply = applier - > apps [ typeList . getTypeID ( pack ) ] ; //find the applier
apply - > applyOnPG ( this , pack ) ;
delete pack ;
}
}
void CSelectionScreen : : update ( )
{
if ( serverHandlingThread )
processPacks ( ) ;
}
void CSelectionScreen : : propagateOptions ( )
{
if ( isHost ( ) & & serv )
{
UpdateStartOptions ups ( sInfo ) ;
* serv < < & ups ;
}
}
void CSelectionScreen : : postRequest ( ui8 what , ui8 dir )
{
if ( ! isGuest ( ) | | ! serv )
return ;
RequestOptionsChange roc ( what , dir , myNameID ) ;
* serv < < & roc ;
}
void CSelectionScreen : : postChatMessage ( const std : : string & txt )
{
assert ( serv ) ;
ChatMessage cm ;
cm . message = txt ;
cm . playerName = sInfo . getPlayersSettings ( myNameID ) - > name ;
* serv < < & cm ;
}
void CSelectionScreen : : propagateNames ( )
{
PlayersNames pn ;
pn . playerNames = playerNames ;
* serv < < & pn ;
2010-09-03 21:42:54 +03:00
}
2012-05-18 20:35:46 +03:00
void CSelectionScreen : : showAll ( SDL_Surface * to )
{
CIntObject : : showAll ( to ) ;
if ( bordered & & ( pos . h ! = to - > h | | pos . w ! = to - > w ) )
2013-03-03 20:06:03 +03:00
CMessage : : drawBorder ( PlayerColor ( 1 ) , to , pos . w + 28 , pos . h + 30 , pos . x - 14 , pos . y - 15 ) ;
2012-05-18 20:35:46 +03:00
}
2009-08-17 11:50:31 +03:00
// A new size filter (Small, Medium, ...) has been selected. Populate
// selMaps with the relevant data.
2009-08-27 11:04:32 +03:00
void SelectionTab : : filter ( int size , bool selectFirst )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
curItems . clear ( ) ;
2010-02-13 18:26:47 +02:00
if ( tabType = = CMenuScreen : : campaignList )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : allItems )
curItems . push_back ( & elem ) ;
2010-02-13 18:26:47 +02:00
}
else
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : allItems )
if ( elem . mapHeader & & elem . mapHeader - > version & & ( ! size | | elem . mapHeader - > width = = size ) )
curItems . push_back ( & elem ) ;
2010-02-13 18:26:47 +02:00
}
2009-08-17 11:50:31 +03:00
if ( curItems . size ( ) )
{
slider - > block ( false ) ;
slider - > setAmount ( curItems . size ( ) ) ;
sort ( ) ;
2009-08-27 11:04:32 +03:00
if ( selectFirst )
{
slider - > moveTo ( 0 ) ;
onSelect ( curItems [ 0 ] ) ;
}
2009-09-11 14:11:01 +03:00
selectAbs ( 0 ) ;
2009-08-17 11:50:31 +03:00
}
else
{
slider - > block ( true ) ;
2013-06-26 14:18:27 +03:00
onSelect ( nullptr ) ;
2009-08-17 11:50:31 +03:00
}
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
2013-07-28 17:49:50 +03:00
std : : unordered_set < ResourceID > SelectionTab : : getFiles ( std : : string dirURI , int resType )
2008-08-02 18:08:03 +03:00
{
2012-08-01 15:02:54 +03:00
boost : : to_upper ( dirURI ) ;
2013-07-28 17:49:50 +03:00
std : : unordered_set < ResourceID > ret = CResourceHandler : : get ( ) - > getFilteredFiles ( [ & ] ( const ResourceID & ident )
2012-08-01 15:02:54 +03:00
{
return ident . getType ( ) = = resType
2012-11-11 15:23:31 +03:00
& & boost : : algorithm : : starts_with ( ident . getName ( ) , dirURI ) ;
2012-08-01 15:02:54 +03:00
} ) ;
return ret ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
2013-07-28 17:49:50 +03:00
void SelectionTab : : parseMaps ( const std : : unordered_set < ResourceID > & files )
2008-08-02 18:08:03 +03:00
{
2012-11-11 15:23:31 +03:00
allItems . clear ( ) ;
2013-06-29 16:05:48 +03:00
for ( auto & file : files )
2008-08-02 18:08:03 +03:00
{
2012-11-03 22:31:16 +03:00
try
{
CMapInfo mapInfo ;
2013-06-29 16:05:48 +03:00
mapInfo . mapInit ( file . getName ( ) ) ;
2013-05-04 22:20:32 +03:00
2016-02-09 19:20:03 +02:00
// ignore unsupported map versions (e.g. WoG maps without WoG)
// but accept VCMI maps
if ( ( mapInfo . mapHeader - > version > = EMapFormat : : VCMI ) | | ( mapInfo . mapHeader - > version < = CGI - > modh - > settings . data [ " textData " ] [ " mapVersion " ] . Float ( ) ) )
2013-06-29 16:05:48 +03:00
allItems . push_back ( std : : move ( mapInfo ) ) ;
2012-11-03 22:31:16 +03:00
}
catch ( std : : exception & e )
{
2016-03-12 03:41:27 +02:00
logGlobal - > errorStream ( ) < < " Map " < < file . getName ( ) < < " is invalid. Message: " < < e . what ( ) ;
2012-11-03 22:31:16 +03:00
}
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
}
2013-07-28 17:49:50 +03:00
void SelectionTab : : parseGames ( const std : : unordered_set < ResourceID > & files , bool multi )
2009-08-17 11:50:31 +03:00
{
2013-06-29 16:05:48 +03:00
for ( auto & file : files )
2008-08-02 18:08:03 +03:00
{
2012-06-08 03:12:31 +03:00
try
2008-08-02 18:08:03 +03:00
{
2014-02-02 17:31:56 +03:00
CLoadFile lf ( * CResourceHandler : : get ( ) - > getResourceName ( file ) , minSupportedVersion ) ;
2013-02-19 01:37:22 +03:00
lf . checkMagicBytes ( SAVEGAME_MAGIC ) ;
// ui8 sign[8];
// lf >> sign;
// if(std::memcmp(sign,"VCMISVG",7))
// {
// throw std::runtime_error("not a correct savefile!");
// }
2012-06-08 03:12:31 +03:00
2012-11-13 21:01:31 +03:00
// Create the map info object
CMapInfo mapInfo ;
2013-06-29 16:05:48 +03:00
mapInfo . mapHeader = make_unique < CMapHeader > ( ) ;
2012-11-13 21:01:31 +03:00
mapInfo . scenarioOpts = new StartInfo ;
lf > > * ( mapInfo . mapHeader . get ( ) ) > > mapInfo . scenarioOpts ;
2013-06-29 16:05:48 +03:00
mapInfo . fileURI = file . getName ( ) ;
2012-11-13 21:01:31 +03:00
mapInfo . countPlayers ( ) ;
2016-01-16 20:00:53 +02:00
std : : time_t time = boost : : filesystem : : last_write_time ( * CResourceHandler : : get ( ) - > getResourceName ( file ) ) ;
2012-11-13 21:01:31 +03:00
mapInfo . date = std : : asctime ( std : : localtime ( & time ) ) ;
2012-06-08 03:12:31 +03:00
2012-11-13 21:01:31 +03:00
// If multi mode then only multi games, otherwise single
if ( ( mapInfo . actualHumanPlayers > 1 ) ! = multi )
2012-06-08 03:12:31 +03:00
{
2012-11-13 21:01:31 +03:00
mapInfo . mapHeader . reset ( ) ;
2012-06-08 03:12:31 +03:00
}
2012-11-13 21:01:31 +03:00
2013-06-29 16:05:48 +03:00
allItems . push_back ( std : : move ( mapInfo ) ) ;
2012-06-08 03:12:31 +03:00
}
2013-01-06 22:30:12 +03:00
catch ( const std : : exception & e )
2010-02-24 15:03:36 +02:00
{
2016-03-12 03:41:27 +02:00
logGlobal - > errorStream ( ) < < " Error: Failed to process " < < file . getName ( ) < < " : " < < e . what ( ) ;
2010-02-24 15:03:36 +02:00
}
2008-08-02 18:08:03 +03:00
}
}
2009-02-06 13:15:39 +02:00
2013-07-28 17:49:50 +03:00
void SelectionTab : : parseCampaigns ( const std : : unordered_set < ResourceID > & files )
2010-02-13 18:26:47 +02:00
{
2013-07-28 17:49:50 +03:00
allItems . reserve ( files . size ( ) ) ;
for ( auto & file : files )
2010-02-13 18:26:47 +02:00
{
2013-07-28 17:49:50 +03:00
CMapInfo info ;
2010-02-18 16:09:16 +02:00
//allItems[i].date = std::asctime(std::localtime(&files[i].date));
2013-07-28 17:49:50 +03:00
info . fileURI = file . getName ( ) ;
info . campaignInit ( ) ;
allItems . push_back ( std : : move ( info ) ) ;
2010-02-13 18:26:47 +02:00
}
}
2013-06-26 14:18:27 +03:00
SelectionTab : : SelectionTab ( CMenuScreen : : EState Type , const std : : function < void ( CMapInfo * ) > & OnSelect , CMenuScreen : : EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/ )
: bg ( nullptr ) , onSelect ( OnSelect )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
OBJ_CONSTRUCTION ;
selectionPos = 0 ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | WHEEL | KEYBOARD | DOUBLECLICK ) ;
2013-06-26 14:18:27 +03:00
slider = nullptr ;
txt = nullptr ;
2010-02-13 18:26:47 +02:00
tabType = Type ;
2009-08-27 11:04:32 +03:00
2010-08-04 14:18:13 +03:00
if ( Type ! = CMenuScreen : : campaignList )
2010-02-15 15:28:33 +02:00
{
2012-05-18 20:35:46 +03:00
bg = new CPicture ( " SCSELBCK.bmp " , 0 , 6 ) ;
pos = bg - > pos ;
2010-02-15 15:28:33 +02:00
}
else
{
2012-05-18 20:35:46 +03:00
bg = nullptr ; //use background from parent
2015-03-13 17:06:19 +02:00
type | = REDRAW_PARENT ; // we use parent background so we need to make sure it's will be redrawn too
2012-05-18 20:35:46 +03:00
pos . w = parent - > pos . w ;
pos . h = parent - > pos . h ;
pos . x + = 3 ; pos . y + = 6 ;
2010-02-15 15:28:33 +02:00
}
2009-08-27 11:04:32 +03:00
2010-10-24 14:35:14 +03:00
if ( MultiPlayer = = CMenuScreen : : MULTI_NETWORK_GUEST )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
positions = 18 ;
2010-10-24 14:35:14 +03:00
}
else
{
switch ( tabType )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
case CMenuScreen : : newGame :
2012-08-01 15:02:54 +03:00
parseMaps ( getFiles ( " Maps/ " , EResType : : MAP ) ) ;
2009-08-17 11:50:31 +03:00
positions = 18 ;
2010-10-24 14:35:14 +03:00
break ;
case CMenuScreen : : loadGame :
case CMenuScreen : : saveGame :
2013-02-19 01:37:22 +03:00
parseGames ( getFiles ( " Saves/ " , EResType : : CLIENT_SAVEGAME ) , MultiPlayer ) ;
2010-10-24 14:35:14 +03:00
if ( tabType = = CMenuScreen : : loadGame )
2010-02-18 14:34:44 +02:00
{
2010-10-24 14:35:14 +03:00
positions = 18 ;
2010-02-18 14:34:44 +02:00
}
2010-10-24 14:35:14 +03:00
else
{
positions = 16 ;
2011-11-27 16:14:20 +03:00
}
2010-10-24 14:35:14 +03:00
if ( tabType = = CMenuScreen : : saveGame )
2012-06-13 16:04:06 +03:00
{
2011-12-22 16:05:19 +03:00
txt = new CTextInput ( Rect ( 32 , 539 , 350 , 20 ) , Point ( - 32 , - 25 ) , " GSSTRIP.bmp " , 0 ) ;
2014-11-12 22:45:48 +02:00
txt - > filters + = CTextInput : : filenameFilter ;
2012-06-13 16:04:06 +03:00
}
2010-10-24 14:35:14 +03:00
break ;
2012-08-01 15:02:54 +03:00
2010-10-24 14:35:14 +03:00
case CMenuScreen : : campaignList :
2012-08-01 15:02:54 +03:00
parseCampaigns ( getFiles ( " Maps/ " , EResType : : CAMPAIGN ) ) ;
2010-10-24 14:35:14 +03:00
positions = 18 ;
break ;
2009-02-08 19:19:42 +02:00
2010-10-24 14:35:14 +03:00
default :
assert ( 0 ) ;
break ;
}
2009-08-17 11:50:31 +03:00
}
2009-02-08 19:19:42 +02:00
2014-06-10 23:58:07 +03:00
generalSortingBy = ( tabType = = CMenuScreen : : loadGame | | tabType = = CMenuScreen : : saveGame ) ? _fileName : _name ;
2011-11-27 16:14:20 +03:00
2010-02-13 18:26:47 +02:00
if ( tabType ! = CMenuScreen : : campaignList )
2009-08-17 11:50:31 +03:00
{
2010-02-15 15:28:33 +02:00
//size filter buttons
2010-02-13 18:26:47 +02:00
{
int sizes [ ] = { 36 , 72 , 108 , 144 , 0 } ;
const char * names [ ] = { " SCSMBUT.DEF " , " SCMDBUT.DEF " , " SCLGBUT.DEF " , " SCXLBUT.DEF " , " SCALBUT.DEF " } ;
for ( int i = 0 ; i < 5 ; i + + )
2014-08-09 15:14:31 +03:00
new CButton ( Point ( 158 + 47 * i , 46 ) , names [ i ] , CGI - > generaltexth - > zelp [ 54 + i ] , std : : bind ( & SelectionTab : : filter , this , sizes [ i ] , true ) ) ;
2010-02-13 18:26:47 +02:00
}
2009-08-17 11:50:31 +03:00
2010-02-15 15:28:33 +02:00
//sort buttons buttons
2010-02-13 18:26:47 +02:00
{
int xpos [ ] = { 23 , 55 , 88 , 121 , 306 , 339 } ;
const char * names [ ] = { " SCBUTT1.DEF " , " SCBUTT2.DEF " , " SCBUTCP.DEF " , " SCBUTT3.DEF " , " SCBUTT4.DEF " , " SCBUTT5.DEF " } ;
for ( int i = 0 ; i < 6 ; i + + )
2014-06-10 23:58:07 +03:00
{
ESortBy criteria = ( ESortBy ) i ;
if ( criteria = = _name )
criteria = generalSortingBy ;
2014-08-09 15:14:31 +03:00
new CButton ( Point ( xpos [ i ] , 86 ) , names [ i ] , CGI - > generaltexth - > zelp [ 107 + i ] , std : : bind ( & SelectionTab : : sortBy , this , criteria ) ) ;
2014-06-10 23:58:07 +03:00
}
2010-02-13 18:26:47 +02:00
}
2009-02-11 19:03:30 +02:00
}
2010-02-15 15:28:33 +02:00
else
{
//sort by buttons
2014-08-09 15:14:31 +03:00
new CButton ( Point ( 23 , 86 ) , " CamCusM.DEF " , CButton : : tooltip ( ) , std : : bind ( & SelectionTab : : sortBy , this , _numOfMaps ) ) ; //by num of maps
new CButton ( Point ( 55 , 86 ) , " CamCusL.DEF " , CButton : : tooltip ( ) , std : : bind ( & SelectionTab : : sortBy , this , _name ) ) ; //by name
2010-02-15 15:28:33 +02:00
}
2009-08-17 11:50:31 +03:00
2014-08-09 15:14:31 +03:00
slider = new CSlider ( Point ( 372 , 86 ) , tabType ! = CMenuScreen : : saveGame ? 480 : 430 , std : : bind ( & SelectionTab : : sliderMove , this , _1 ) , positions , curItems . size ( ) , 0 , false , CSlider : : BLUE ) ;
2012-06-02 18:16:54 +03:00
slider - > addUsedEvents ( WHEEL ) ;
2016-02-09 19:20:03 +02:00
formatIcons = new CAnimation ( " SCSELC.DEF " ) ;
formatIcons - > load ( ) ;
2009-08-17 11:50:31 +03:00
sortingBy = _format ;
ascending = true ;
filter ( 0 ) ;
2009-08-27 11:04:32 +03:00
//select(0);
2010-02-13 18:26:47 +02:00
switch ( tabType )
2009-08-27 11:04:32 +03:00
{
2010-02-13 18:26:47 +02:00
case CMenuScreen : : newGame :
2012-08-01 15:02:54 +03:00
selectFName ( " Maps/Arrogance " ) ;
2009-08-27 11:04:32 +03:00
break ;
2010-02-13 18:26:47 +02:00
case CMenuScreen : : loadGame :
case CMenuScreen : : campaignList :
2009-08-27 11:04:32 +03:00
select ( 0 ) ;
break ;
2010-02-13 18:26:47 +02:00
case CMenuScreen : : saveGame : ;
2012-11-20 20:53:45 +03:00
if ( saveGameName . empty ( ) )
2009-08-27 11:04:32 +03:00
{
2013-08-29 16:46:27 +03:00
txt - > setText ( " NEWGAME " ) ;
2012-11-20 20:53:45 +03:00
}
else
{
selectFName ( saveGameName ) ;
2009-08-27 11:04:32 +03:00
}
}
2009-08-17 11:50:31 +03:00
}
SelectionTab : : ~ SelectionTab ( )
2008-08-02 18:08:03 +03:00
{
2016-02-09 19:20:03 +02:00
delete formatIcons ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void SelectionTab : : sortBy ( int criteria )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
if ( criteria = = sortingBy )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
ascending = ! ascending ;
2008-08-02 18:08:03 +03:00
}
else
{
2009-08-17 11:50:31 +03:00
sortingBy = ( ESortBy ) criteria ;
ascending = true ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
sort ( ) ;
2009-09-11 14:11:01 +03:00
selectAbs ( 0 ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void SelectionTab : : sort ( )
2008-08-02 18:08:03 +03:00
{
2014-06-10 23:58:07 +03:00
if ( sortingBy ! = generalSortingBy )
std : : stable_sort ( curItems . begin ( ) , curItems . end ( ) , mapSorter ( generalSortingBy ) ) ;
2010-02-13 18:26:47 +02:00
std : : stable_sort ( curItems . begin ( ) , curItems . end ( ) , mapSorter ( sortingBy ) ) ;
2009-06-10 23:48:55 +03:00
2009-08-17 11:50:31 +03:00
if ( ! ascending )
std : : reverse ( curItems . begin ( ) , curItems . end ( ) ) ;
2009-06-10 23:48:55 +03:00
2009-08-17 11:50:31 +03:00
redraw ( ) ;
}
2009-06-10 23:48:55 +03:00
2009-08-17 11:50:31 +03:00
void SelectionTab : : select ( int position )
{
2009-08-27 11:04:32 +03:00
if ( ! curItems . size ( ) ) return ;
2009-08-17 11:50:31 +03:00
// New selection. py is the index in curItems.
2014-08-03 17:31:56 +03:00
int py = position + slider - > getValue ( ) ;
2011-12-14 00:23:17 +03:00
vstd : : amax ( py , 0 ) ;
vstd : : amin ( py , curItems . size ( ) - 1 ) ;
2009-02-06 13:15:39 +02:00
2009-08-23 21:01:08 +03:00
selectionPos = py ;
if ( position < 0 )
2014-08-03 17:31:56 +03:00
slider - > moveBy ( position ) ;
2009-08-23 21:01:08 +03:00
else if ( position > = positions )
2014-08-03 17:31:56 +03:00
slider - > moveBy ( position - positions + 1 ) ;
2009-08-23 21:01:08 +03:00
2010-03-08 00:56:51 +02:00
if ( txt )
2012-08-01 15:02:54 +03:00
{
2016-01-16 17:36:16 +02:00
auto filename = * CResourceHandler : : get ( " local " ) - > getResourceName (
2013-02-19 01:37:22 +03:00
ResourceID ( curItems [ py ] - > fileURI , EResType : : CLIENT_SAVEGAME ) ) ;
2016-01-16 20:00:53 +02:00
txt - > setText ( filename . stem ( ) . string ( ) ) ;
2012-08-01 15:02:54 +03:00
}
2010-03-08 00:56:51 +02:00
2009-08-23 21:01:08 +03:00
onSelect ( curItems [ py ] ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
2009-08-27 11:04:32 +03:00
void SelectionTab : : selectAbs ( int position )
{
2014-08-03 17:31:56 +03:00
select ( position - slider - > getValue ( ) ) ;
2009-08-27 11:04:32 +03:00
}
2009-08-17 11:50:31 +03:00
int SelectionTab : : getPosition ( int x , int y )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
return - 1 ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void SelectionTab : : sliderMove ( int slidPos )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
if ( ! slider ) return ; //ignore spurious call when slider is being created
redraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-05-04 02:38:08 +03:00
2009-08-17 11:50:31 +03:00
2009-05-04 02:38:08 +03:00
// Display the tab with the scenario names
//
// elemIdx is the index of the maps or saved game to display on line 0
2009-08-17 11:50:31 +03:00
// slider->capacity contains the number of available screen lines
// slider->positionsAmnt is the number of elements after filtering
void SelectionTab : : printMaps ( SDL_Surface * to )
2008-08-02 18:08:03 +03:00
{
2009-05-04 02:38:08 +03:00
2014-08-03 17:31:56 +03:00
int elemIdx = slider - > getValue ( ) ;
2009-05-04 02:38:08 +03:00
2009-08-17 11:50:31 +03:00
// Display all elements if there's enough space
//if(slider->amount < slider->capacity)
// elemIdx = 0;
2009-05-04 02:38:08 +03:00
2010-02-13 18:26:47 +02:00
SDL_Color itemColor ;
2009-08-17 11:50:31 +03:00
for ( int line = 0 ; line < positions & & elemIdx < curItems . size ( ) ; elemIdx + + , line + + )
{
2010-10-24 14:35:14 +03:00
CMapInfo * currentItem = curItems [ elemIdx ] ;
2009-05-04 02:38:08 +03:00
2010-02-15 14:12:21 +02:00
if ( elemIdx = = selectionPos )
2012-11-11 15:23:31 +03:00
itemColor = Colors : : YELLOW ;
2011-11-27 16:14:20 +03:00
else
2012-11-11 15:23:31 +03:00
itemColor = Colors : : WHITE ;
2010-02-15 14:12:21 +02:00
2010-02-13 18:26:47 +02:00
if ( tabType ! = CMenuScreen : : campaignList )
{
//amount of players
std : : ostringstream ostr ( std : : ostringstream : : out ) ;
2012-08-01 15:02:54 +03:00
ostr < < currentItem - > playerAmnt < < " / " < < currentItem - > humanPlayers ;
2012-12-19 20:24:53 +03:00
printAtLoc ( ostr . str ( ) , 29 , 120 + line * 25 , FONT_SMALL , itemColor , to ) ;
2010-02-13 18:26:47 +02:00
//map size
std : : string temp2 = " C " ;
2010-10-24 14:35:14 +03:00
switch ( currentItem - > mapHeader - > width )
2010-02-13 18:26:47 +02:00
{
case 36 :
temp2 = " S " ;
break ;
case 72 :
temp2 = " M " ;
break ;
case 108 :
temp2 = " L " ;
break ;
case 144 :
temp2 = " XL " ;
break ;
}
2012-12-19 20:24:53 +03:00
printAtMiddleLoc ( temp2 , 70 , 128 + line * 25 , FONT_SMALL , itemColor , to ) ;
2009-05-04 02:38:08 +03:00
2016-02-09 19:20:03 +02:00
int frame = - 1 , group = 0 ;
2010-10-24 14:35:14 +03:00
switch ( currentItem - > mapHeader - > version )
2010-02-13 18:26:47 +02:00
{
2012-11-11 15:23:31 +03:00
case EMapFormat : : ROE :
2016-02-09 19:20:03 +02:00
frame = 0 ;
2010-02-13 18:26:47 +02:00
break ;
2012-11-11 15:23:31 +03:00
case EMapFormat : : AB :
2016-02-09 19:20:03 +02:00
frame = 1 ;
2010-02-13 18:26:47 +02:00
break ;
2012-11-11 15:23:31 +03:00
case EMapFormat : : SOD :
2016-02-09 19:20:03 +02:00
frame = 2 ;
2010-02-13 18:26:47 +02:00
break ;
2012-11-11 15:23:31 +03:00
case EMapFormat : : WOG :
2016-02-09 19:20:03 +02:00
frame = 3 ;
break ;
case EMapFormat : : VCMI :
frame = 0 ;
group = 1 ;
2010-02-13 18:26:47 +02:00
break ;
default :
// Unknown version. Be safe and ignore that map
2016-03-12 03:41:27 +02:00
logGlobal - > warnStream ( ) < < " Warning: " < < currentItem - > fileURI < < " has wrong version! " ;
2010-02-13 18:26:47 +02:00
continue ;
}
2016-02-09 19:20:03 +02:00
IImage * icon = formatIcons - > getImage ( frame , group ) ;
if ( icon )
icon - > draw ( to , pos . x + 88 , pos . y + 117 + line * 25 ) ;
2010-02-13 18:26:47 +02:00
//victory conditions
2013-12-29 14:27:38 +03:00
blitAtLoc ( CGP - > victory - > ourImages [ currentItem - > mapHeader - > victoryIconIndex ] . bitmap , 306 , 117 + line * 25 , to ) ;
2010-02-13 18:26:47 +02:00
//loss conditions
2013-12-29 14:27:38 +03:00
blitAtLoc ( CGP - > loss - > ourImages [ currentItem - > mapHeader - > defeatIconIndex ] . bitmap , 339 , 117 + line * 25 , to ) ;
2010-02-13 18:26:47 +02:00
}
2010-02-15 14:12:21 +02:00
else //if campaign
{
//number of maps in campaign
std : : ostringstream ostr ( std : : ostringstream : : out ) ;
2010-10-24 14:35:14 +03:00
ostr < < CGI - > generaltexth - > campaignRegionNames [ currentItem - > campaignHeader - > mapVersion ] . size ( ) ;
2012-12-19 20:24:53 +03:00
printAtLoc ( ostr . str ( ) , 29 , 120 + line * 25 , FONT_SMALL , itemColor , to ) ;
2010-02-15 14:12:21 +02:00
}
2009-05-04 02:38:08 +03:00
2010-02-13 18:26:47 +02:00
std : : string name ;
2010-10-24 14:35:14 +03:00
if ( tabType = = CMenuScreen : : newGame )
{
if ( ! currentItem - > mapHeader - > name . length ( ) )
currentItem - > mapHeader - > name = " Unnamed " ;
name = currentItem - > mapHeader - > name ;
}
else if ( tabType = = CMenuScreen : : campaignList )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
name = currentItem - > campaignHeader - > name ;
2008-08-02 18:08:03 +03:00
}
2010-02-13 18:26:47 +02:00
else
2008-08-02 18:08:03 +03:00
{
2016-01-16 17:36:16 +02:00
name = CResourceHandler : : get ( " local " ) - > getResourceName (
ResourceID ( currentItem - > fileURI , EResType : : CLIENT_SAVEGAME ) ) - > stem ( ) . string ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-01-11 00:08:18 +02:00
2010-02-13 18:26:47 +02:00
//print name
2012-12-19 20:24:53 +03:00
printAtMiddleLoc ( name , 213 , 128 + line * 25 , FONT_SMALL , itemColor , to ) ;
2008-08-02 18:08:03 +03:00
}
}
2009-05-04 02:38:08 +03:00
2011-12-22 16:05:19 +03:00
void SelectionTab : : showAll ( SDL_Surface * to )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
CIntObject : : showAll ( to ) ;
printMaps ( to ) ;
2009-10-23 04:48:03 +03:00
2010-02-13 18:26:47 +02:00
std : : string title ;
switch ( tabType ) {
case CMenuScreen : : newGame :
title = CGI - > generaltexth - > arraytxt [ 229 ] ;
break ;
case CMenuScreen : : loadGame :
title = CGI - > generaltexth - > arraytxt [ 230 ] ;
break ;
case CMenuScreen : : saveGame :
title = CGI - > generaltexth - > arraytxt [ 231 ] ;
break ;
case CMenuScreen : : campaignList :
2013-02-07 02:24:43 +03:00
title = CGI - > generaltexth - > allTexts [ 726 ] ;
2010-02-13 18:26:47 +02:00
break ;
2009-10-23 04:48:03 +03:00
}
2012-12-19 20:24:53 +03:00
printAtMiddleLoc ( title , 205 , 28 , FONT_MEDIUM , Colors : : YELLOW , to ) ; //Select a Scenario to Play
2010-02-15 14:12:21 +02:00
if ( tabType ! = CMenuScreen : : campaignList )
{
2012-12-19 20:24:53 +03:00
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 510 ] , 87 , 62 , FONT_SMALL , Colors : : YELLOW , to ) ; //Map sizes
2010-02-15 14:12:21 +02:00
}
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
void SelectionTab : : clickLeft ( tribool down , bool previousState )
2009-01-11 00:08:18 +02:00
{
2009-10-06 03:32:33 +03:00
if ( down )
{
int line = getLine ( ) ;
if ( line ! = - 1 )
select ( line ) ;
}
2009-01-11 00:08:18 +02:00
}
2009-08-23 21:01:08 +03:00
void SelectionTab : : keyPressed ( const SDL_KeyboardEvent & key )
{
if ( key . state ! = SDL_PRESSED ) return ;
int moveBy = 0 ;
switch ( key . keysym . sym )
{
case SDLK_UP :
moveBy = - 1 ;
break ;
case SDLK_DOWN :
moveBy = + 1 ;
break ;
case SDLK_PAGEUP :
moveBy = - positions + 1 ;
break ;
case SDLK_PAGEDOWN :
2011-11-27 16:14:20 +03:00
moveBy = + positions - 1 ;
2009-08-23 21:01:08 +03:00
break ;
case SDLK_HOME :
2014-08-03 17:31:56 +03:00
select ( - slider - > getValue ( ) ) ;
2009-08-23 21:01:08 +03:00
return ;
case SDLK_END :
2014-08-03 17:31:56 +03:00
select ( curItems . size ( ) - slider - > getValue ( ) ) ;
2009-08-23 21:01:08 +03:00
return ;
2009-08-27 11:04:32 +03:00
default :
return ;
2009-08-23 21:01:08 +03:00
}
2014-08-03 17:31:56 +03:00
select ( selectionPos - slider - > getValue ( ) + moveBy ) ;
2009-08-23 21:01:08 +03:00
}
void SelectionTab : : onDoubleClick ( )
{
2009-08-27 11:04:32 +03:00
if ( getLine ( ) ! = - 1 ) //double clicked scenarios list
{
2009-10-13 07:58:15 +03:00
//act as if start button was pressed
2014-08-03 14:16:19 +03:00
( static_cast < CSelectionScreen * > ( parent ) ) - > start - > clickLeft ( false , true ) ;
2009-08-27 11:04:32 +03:00
}
}
int SelectionTab : : getLine ( )
{
int line = - 1 ;
2011-12-22 16:05:19 +03:00
Point clickPos ( GH . current - > button . x , GH . current - > button . y ) ;
2009-09-26 00:11:13 +03:00
clickPos = clickPos - pos . topLeft ( ) ;
2009-08-27 11:04:32 +03:00
2014-11-23 07:51:48 +02:00
// Ignore clicks on save name area
int maxPosY ;
if ( tabType = = CMenuScreen : : saveGame )
maxPosY = 516 ;
else
maxPosY = 564 ;
if ( clickPos . y > 115 & & clickPos . y < maxPosY & & clickPos . x > 22 & & clickPos . x < 371 )
2009-08-27 11:04:32 +03:00
{
line = ( clickPos . y - 115 ) / 25 ; //which line
}
return line ;
}
2012-08-01 15:02:54 +03:00
void SelectionTab : : selectFName ( std : : string fname )
2009-08-27 11:04:32 +03:00
{
2012-08-01 15:02:54 +03:00
boost : : to_upper ( fname ) ;
2009-08-27 11:04:32 +03:00
for ( int i = curItems . size ( ) - 1 ; i > = 0 ; i - - )
{
2012-08-01 15:02:54 +03:00
if ( curItems [ i ] - > fileURI = = fname )
2009-08-27 11:04:32 +03:00
{
slider - > moveTo ( i ) ;
selectAbs ( i ) ;
return ;
}
}
selectAbs ( 0 ) ;
2009-08-23 21:01:08 +03:00
}
2012-11-20 20:53:45 +03:00
const CMapInfo * SelectionTab : : getSelectedMapInfo ( ) const
{
return curItems . empty ( ) ? nullptr : curItems [ selectionPos ] ;
}
2013-05-21 22:08:06 +03:00
CRandomMapTab : : CRandomMapTab ( )
2012-11-11 15:23:31 +03:00
{
OBJ_CONSTRUCTION ;
bg = new CPicture ( " RANMAPBK " , 0 , 6 ) ;
// Map Size
2014-08-03 14:16:19 +03:00
mapSizeBtnGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
mapSizeBtnGroup - > pos . y + = 81 ;
mapSizeBtnGroup - > pos . x + = 158 ;
2014-10-02 18:43:46 +03:00
const std : : vector < std : : string > mapSizeBtns = { " RANSIZS " , " RANSIZM " , " RANSIZL " , " RANSIZX " } ;
2012-11-11 15:23:31 +03:00
addButtonsToGroup ( mapSizeBtnGroup , mapSizeBtns , 0 , 3 , 47 , 198 ) ;
2014-08-03 14:16:19 +03:00
mapSizeBtnGroup - > setSelected ( 1 ) ;
mapSizeBtnGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2015-03-13 22:33:46 +02:00
auto mapSizeVal = getPossibleMapSizes ( ) ;
2012-11-20 20:53:45 +03:00
mapGenOptions . setWidth ( mapSizeVal [ btnId ] ) ;
mapGenOptions . setHeight ( mapSizeVal [ btnId ] ) ;
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Two levels
2014-08-03 14:16:19 +03:00
twoLevelsBtn = new CToggleButton ( Point ( 346 , 81 ) , " RANUNDR " , CGI - > generaltexth - > zelp [ 202 ] ) ;
2013-05-21 22:08:06 +03:00
//twoLevelsBtn->select(true); for now, deactivated
2015-03-13 22:33:46 +02:00
twoLevelsBtn - > addCallback ( [ & ] ( bool on )
{
mapGenOptions . setHasTwoLevels ( on ) ;
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
} ) ;
2012-11-11 15:23:31 +03:00
// Create number defs list
std : : vector < std : : string > numberDefs ;
for ( int i = 0 ; i < = 8 ; + + i )
{
numberDefs . push_back ( " RANNUM " + boost : : lexical_cast < std : : string > ( i ) ) ;
}
const int NUMBERS_WIDTH = 32 ;
const int BTNS_GROUP_LEFT_MARGIN = 67 ;
// Amount of players
2014-08-03 14:16:19 +03:00
playersCntGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
playersCntGroup - > pos . y + = 153 ;
playersCntGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( playersCntGroup , numberDefs , 1 , 8 , NUMBERS_WIDTH , 204 , 212 ) ;
2014-08-03 14:16:19 +03:00
playersCntGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2013-05-21 22:08:06 +03:00
mapGenOptions . setPlayerCount ( btnId ) ;
2012-11-11 15:23:31 +03:00
deactivateButtonsFrom ( teamsCntGroup , btnId ) ;
2015-05-27 11:30:46 +02:00
deactivateButtonsFrom ( compOnlyPlayersCntGroup , btnId ) ;
2012-11-11 15:23:31 +03:00
validatePlayersCnt ( btnId ) ;
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Amount of teams
2014-08-03 14:16:19 +03:00
teamsCntGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
teamsCntGroup - > pos . y + = 219 ;
teamsCntGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( teamsCntGroup , numberDefs , 0 , 7 , NUMBERS_WIDTH , 214 , 222 ) ;
2014-08-03 14:16:19 +03:00
teamsCntGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2013-05-21 22:08:06 +03:00
mapGenOptions . setTeamCount ( btnId ) ;
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Computer only players
2014-08-03 14:16:19 +03:00
compOnlyPlayersCntGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
compOnlyPlayersCntGroup - > pos . y + = 285 ;
compOnlyPlayersCntGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( compOnlyPlayersCntGroup , numberDefs , 0 , 7 , NUMBERS_WIDTH , 224 , 232 ) ;
2014-08-03 14:16:19 +03:00
compOnlyPlayersCntGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2013-05-21 22:08:06 +03:00
mapGenOptions . setCompOnlyPlayerCount ( btnId ) ;
2015-03-16 15:02:52 +02:00
deactivateButtonsFrom ( compOnlyTeamsCntGroup , ( btnId = = 0 ? 1 : btnId ) ) ;
2012-11-11 15:23:31 +03:00
validateCompOnlyPlayersCnt ( btnId ) ;
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Computer only teams
2014-08-03 14:16:19 +03:00
compOnlyTeamsCntGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
compOnlyTeamsCntGroup - > pos . y + = 351 ;
compOnlyTeamsCntGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( compOnlyTeamsCntGroup , numberDefs , 0 , 6 , NUMBERS_WIDTH , 234 , 241 ) ;
2015-03-16 15:02:52 +02:00
deactivateButtonsFrom ( compOnlyTeamsCntGroup , 1 ) ;
2014-08-03 14:16:19 +03:00
compOnlyTeamsCntGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2013-05-21 22:08:06 +03:00
mapGenOptions . setCompOnlyTeamCount ( btnId ) ;
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
const int WIDE_BTN_WIDTH = 85 ;
// Water content
2014-08-03 14:16:19 +03:00
waterContentGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
waterContentGroup - > pos . y + = 419 ;
waterContentGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2014-10-02 18:43:46 +03:00
const std : : vector < std : : string > waterContentBtns = { " RANNONE " , " RANNORM " , " RANISLD " } ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( waterContentGroup , waterContentBtns , 0 , 2 , WIDE_BTN_WIDTH , 243 , 246 ) ;
2014-08-03 14:16:19 +03:00
waterContentGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2012-11-20 20:53:45 +03:00
mapGenOptions . setWaterContent ( static_cast < EWaterContent : : EWaterContent > ( btnId ) ) ;
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Monster strength
2014-08-03 14:16:19 +03:00
monsterStrengthGroup = new CToggleGroup ( 0 ) ;
2013-01-06 22:30:12 +03:00
monsterStrengthGroup - > pos . y + = 485 ;
monsterStrengthGroup - > pos . x + = BTNS_GROUP_LEFT_MARGIN ;
2014-10-02 18:43:46 +03:00
const std : : vector < std : : string > monsterStrengthBtns = { " RANWEAK " , " RANNORM " , " RANSTRG " } ;
2012-11-11 15:23:31 +03:00
addButtonsWithRandToGroup ( monsterStrengthGroup , monsterStrengthBtns , 0 , 2 , WIDE_BTN_WIDTH , 248 , 251 ) ;
2014-08-03 14:16:19 +03:00
monsterStrengthGroup - > addCallback ( [ & ] ( int btnId )
2012-11-11 15:23:31 +03:00
{
2014-06-15 13:00:34 +03:00
if ( btnId < 0 )
mapGenOptions . setMonsterStrength ( EMonsterStrength : : RANDOM ) ;
else
mapGenOptions . setMonsterStrength ( static_cast < EMonsterStrength : : EMonsterStrength > ( btnId + EMonsterStrength : : GLOBAL_WEAK ) ) ; //value 2 to 4
2014-08-03 14:16:19 +03:00
} ) ;
2012-11-11 15:23:31 +03:00
// Show random maps btn
2014-08-03 14:16:19 +03:00
showRandMaps = new CButton ( Point ( 54 , 535 ) , " RANSHOW " , CGI - > generaltexth - > zelp [ 252 ] ) ;
2012-11-20 20:53:45 +03:00
// Initialize map info object
2015-03-13 22:33:46 +02:00
if ( ! SEL - > isGuest ( ) )
updateMapInfo ( ) ;
2012-11-11 15:23:31 +03:00
}
2014-08-03 14:16:19 +03:00
void CRandomMapTab : : addButtonsWithRandToGroup ( CToggleGroup * group , const std : : vector < std : : string > & defs , int nStart , int nEnd , int btnWidth , int helpStartIndex , int helpRandIndex ) const
2012-11-11 15:23:31 +03:00
{
addButtonsToGroup ( group , defs , nStart , nEnd , btnWidth , helpStartIndex ) ;
2012-11-20 20:53:45 +03:00
// Buttons are relative to button group, TODO better solution?
SObjectConstruction obj__i ( group ) ;
const std : : string RANDOM_DEF = " RANRAND " ;
2014-08-03 14:16:19 +03:00
group - > addToggle ( CMapGenOptions : : RANDOM_SIZE , new CToggleButton ( Point ( 256 , 0 ) , RANDOM_DEF , CGI - > generaltexth - > zelp [ helpRandIndex ] ) ) ;
group - > setSelected ( CMapGenOptions : : RANDOM_SIZE ) ;
2012-11-11 15:23:31 +03:00
}
2014-08-03 14:16:19 +03:00
void CRandomMapTab : : addButtonsToGroup ( CToggleGroup * group , const std : : vector < std : : string > & defs , int nStart , int nEnd , int btnWidth , int helpStartIndex ) const
2012-11-11 15:23:31 +03:00
{
// Buttons are relative to button group, TODO better solution?
SObjectConstruction obj__i ( group ) ;
2012-11-20 20:53:45 +03:00
int cnt = nEnd - nStart + 1 ;
2012-11-11 15:23:31 +03:00
for ( int i = 0 ; i < cnt ; + + i )
{
2014-08-03 14:16:19 +03:00
auto button = new CToggleButton ( Point ( i * btnWidth , 0 ) , defs [ i + nStart ] , CGI - > generaltexth - > zelp [ helpStartIndex + i ] ) ;
// For blocked state we should use pressed image actually
button - > setImageOrder ( 0 , 1 , 1 , 3 ) ;
group - > addToggle ( i + nStart , button ) ;
2012-11-11 15:23:31 +03:00
}
}
2014-08-03 14:16:19 +03:00
void CRandomMapTab : : deactivateButtonsFrom ( CToggleGroup * group , int startId )
2012-11-11 15:23:31 +03:00
{
2014-08-03 18:50:59 +03:00
logGlobal - > infoStream ( ) < < " Blocking buttons from " < < startId ;
2014-08-03 14:16:19 +03:00
for ( auto toggle : group - > buttons )
2012-11-11 15:23:31 +03:00
{
2014-08-03 14:16:19 +03:00
if ( auto button = dynamic_cast < CToggleButton * > ( toggle . second ) )
2012-11-11 15:23:31 +03:00
{
2014-08-03 14:16:19 +03:00
if ( startId = = CMapGenOptions : : RANDOM_SIZE | | toggle . first < startId )
2012-11-11 15:23:31 +03:00
{
2014-08-03 14:16:19 +03:00
button - > block ( false ) ;
}
else
{
button - > block ( true ) ;
2012-11-11 15:23:31 +03:00
}
}
}
}
2013-05-21 22:08:06 +03:00
void CRandomMapTab : : validatePlayersCnt ( int playersCnt )
2012-11-11 15:23:31 +03:00
{
2012-11-20 20:53:45 +03:00
if ( playersCnt = = CMapGenOptions : : RANDOM_SIZE )
2012-11-11 15:23:31 +03:00
{
return ;
}
2013-05-21 22:08:06 +03:00
if ( mapGenOptions . getTeamCount ( ) > = playersCnt )
2012-11-11 15:23:31 +03:00
{
2013-05-21 22:08:06 +03:00
mapGenOptions . setTeamCount ( playersCnt - 1 ) ;
2014-08-03 14:16:19 +03:00
teamsCntGroup - > setSelected ( mapGenOptions . getTeamCount ( ) ) ;
2012-11-11 15:23:31 +03:00
}
2015-05-27 11:30:46 +02:00
if ( mapGenOptions . getCompOnlyPlayerCount ( ) > = playersCnt )
2012-11-11 15:23:31 +03:00
{
2015-05-27 11:30:46 +02:00
mapGenOptions . setCompOnlyPlayerCount ( playersCnt - 1 ) ;
2014-08-03 14:16:19 +03:00
compOnlyPlayersCntGroup - > setSelected ( mapGenOptions . getCompOnlyPlayerCount ( ) ) ;
2012-11-11 15:23:31 +03:00
}
2013-05-21 22:08:06 +03:00
validateCompOnlyPlayersCnt ( mapGenOptions . getCompOnlyPlayerCount ( ) ) ;
2012-11-11 15:23:31 +03:00
}
2013-05-21 22:08:06 +03:00
void CRandomMapTab : : validateCompOnlyPlayersCnt ( int compOnlyPlayersCnt )
2012-11-11 15:23:31 +03:00
{
2012-11-20 20:53:45 +03:00
if ( compOnlyPlayersCnt = = CMapGenOptions : : RANDOM_SIZE )
2012-11-11 15:23:31 +03:00
{
return ;
}
2010-02-13 18:26:47 +02:00
2013-05-21 22:08:06 +03:00
if ( mapGenOptions . getCompOnlyTeamCount ( ) > = compOnlyPlayersCnt )
2012-11-11 15:23:31 +03:00
{
2015-03-16 15:02:52 +02:00
int compOnlyTeamCount = compOnlyPlayersCnt = = 0 ? 0 : compOnlyPlayersCnt - 1 ;
mapGenOptions . setCompOnlyTeamCount ( compOnlyTeamCount ) ;
compOnlyTeamsCntGroup - > setSelected ( compOnlyTeamCount ) ;
2012-11-11 15:23:31 +03:00
}
}
2015-03-13 22:33:46 +02:00
std : : vector < int > CRandomMapTab : : getPossibleMapSizes ( )
{
return { CMapHeader : : MAP_SIZE_SMALL , CMapHeader : : MAP_SIZE_MIDDLE , CMapHeader : : MAP_SIZE_LARGE , CMapHeader : : MAP_SIZE_XLARGE } ;
}
2013-05-21 22:08:06 +03:00
void CRandomMapTab : : showAll ( SDL_Surface * to )
2012-11-11 15:23:31 +03:00
{
CIntObject : : showAll ( to ) ;
// Headline
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 738 ] , 222 , 36 , FONT_BIG , Colors : : YELLOW , to ) ;
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 739 ] , 222 , 56 , FONT_SMALL , Colors : : WHITE , to ) ;
// Map size
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 752 ] , 104 , 97 , FONT_SMALL , Colors : : WHITE , to ) ;
// Players cnt
printAtLoc ( CGI - > generaltexth - > allTexts [ 753 ] , 68 , 133 , FONT_SMALL , Colors : : WHITE , to ) ;
// Teams cnt
printAtLoc ( CGI - > generaltexth - > allTexts [ 754 ] , 68 , 199 , FONT_SMALL , Colors : : WHITE , to ) ;
// Computer only players cnt
printAtLoc ( CGI - > generaltexth - > allTexts [ 755 ] , 68 , 265 , FONT_SMALL , Colors : : WHITE , to ) ;
// Computer only teams cnt
printAtLoc ( CGI - > generaltexth - > allTexts [ 756 ] , 68 , 331 , FONT_SMALL , Colors : : WHITE , to ) ;
// Water content
printAtLoc ( CGI - > generaltexth - > allTexts [ 757 ] , 68 , 398 , FONT_SMALL , Colors : : WHITE , to ) ;
// Monster strength
printAtLoc ( CGI - > generaltexth - > allTexts [ 758 ] , 68 , 465 , FONT_SMALL , Colors : : WHITE , to ) ;
}
2010-02-13 18:26:47 +02:00
2013-05-21 22:08:06 +03:00
void CRandomMapTab : : updateMapInfo ( )
2012-11-20 20:53:45 +03:00
{
2013-05-21 22:08:06 +03:00
// Generate header info
mapInfo = make_unique < CMapInfo > ( ) ;
mapInfo - > isRandomMap = true ;
2013-06-29 16:05:48 +03:00
mapInfo - > mapHeader = make_unique < CMapHeader > ( ) ;
mapInfo - > mapHeader - > version = EMapFormat : : SOD ;
mapInfo - > mapHeader - > name = CGI - > generaltexth - > allTexts [ 740 ] ;
mapInfo - > mapHeader - > description = CGI - > generaltexth - > allTexts [ 741 ] ;
mapInfo - > mapHeader - > difficulty = 1 ; // Normal
2013-05-21 22:08:06 +03:00
mapInfo - > mapHeader - > height = mapGenOptions . getHeight ( ) ;
mapInfo - > mapHeader - > width = mapGenOptions . getWidth ( ) ;
mapInfo - > mapHeader - > twoLevel = mapGenOptions . getHasTwoLevels ( ) ;
2012-11-20 20:53:45 +03:00
// Generate player information
2013-05-21 22:08:06 +03:00
mapInfo - > mapHeader - > players . clear ( ) ;
2015-11-25 06:25:44 +02:00
int playersToGen = PlayerColor : : PLAYER_LIMIT_I ;
if ( mapGenOptions . getPlayerCount ( ) ! = CMapGenOptions : : RANDOM_SIZE )
playersToGen = mapGenOptions . getPlayerCount ( ) ;
2013-05-21 22:08:06 +03:00
mapInfo - > mapHeader - > howManyTeams = playersToGen ;
2012-11-20 20:53:45 +03:00
for ( int i = 0 ; i < playersToGen ; + + i )
{
PlayerInfo player ;
2013-05-21 22:08:06 +03:00
player . isFactionRandom = true ;
2012-11-20 20:53:45 +03:00
player . canComputerPlay = true ;
2015-11-25 06:40:35 +02:00
if ( mapGenOptions . getCompOnlyPlayerCount ( ) ! = CMapGenOptions : : RANDOM_SIZE & &
i > = mapGenOptions . getHumanOnlyPlayerCount ( ) )
2012-11-20 20:53:45 +03:00
{
player . canHumanPlay = false ;
}
else
{
player . canHumanPlay = true ;
}
2013-03-03 20:06:03 +03:00
player . team = TeamID ( i ) ;
2013-01-20 17:43:58 +03:00
player . hasMainTown = true ;
player . generateHeroAtMainTown = true ;
2013-05-21 22:08:06 +03:00
mapInfo - > mapHeader - > players . push_back ( player ) ;
2012-11-20 20:53:45 +03:00
}
2013-05-21 22:08:06 +03:00
mapInfoChanged ( mapInfo . get ( ) ) ;
2012-11-20 20:53:45 +03:00
}
2013-05-21 22:08:06 +03:00
CFunctionList < void ( const CMapInfo * ) > & CRandomMapTab : : getMapInfoChanged ( )
2012-11-20 20:53:45 +03:00
{
return mapInfoChanged ;
}
2013-05-21 22:08:06 +03:00
const CMapInfo * CRandomMapTab : : getMapInfo ( ) const
2012-11-20 20:53:45 +03:00
{
2013-05-21 22:08:06 +03:00
return mapInfo . get ( ) ;
2012-11-20 20:53:45 +03:00
}
2013-05-21 22:08:06 +03:00
const CMapGenOptions & CRandomMapTab : : getMapGenOptions ( ) const
2012-11-20 20:53:45 +03:00
{
return mapGenOptions ;
}
2015-12-29 04:43:33 +02:00
void CRandomMapTab : : setMapGenOptions ( std : : shared_ptr < CMapGenOptions > opts )
2015-03-13 22:33:46 +02:00
{
mapSizeBtnGroup - > setSelected ( vstd : : find_pos ( getPossibleMapSizes ( ) , opts - > getWidth ( ) ) ) ;
twoLevelsBtn - > setSelected ( opts - > getHasTwoLevels ( ) ) ;
playersCntGroup - > setSelected ( opts - > getPlayerCount ( ) ) ;
teamsCntGroup - > setSelected ( opts - > getTeamCount ( ) ) ;
compOnlyPlayersCntGroup - > setSelected ( opts - > getCompOnlyPlayerCount ( ) ) ;
compOnlyTeamsCntGroup - > setSelected ( opts - > getCompOnlyTeamCount ( ) ) ;
waterContentGroup - > setSelected ( opts - > getWaterContent ( ) ) ;
monsterStrengthGroup - > setSelected ( opts - > getMonsterStrength ( ) ) ;
}
2011-12-22 16:05:19 +03:00
CChatBox : : CChatBox ( const Rect & rect )
2010-09-03 21:42:54 +03:00
{
2010-10-24 14:35:14 +03:00
OBJ_CONSTRUCTION ;
pos + = rect ;
2014-05-23 19:46:54 +03:00
addUsedEvents ( KEYBOARD | TEXTINPUT ) ;
2010-10-24 14:35:14 +03:00
captureAllKeys = true ;
2015-03-13 17:45:07 +02:00
type | = REDRAW_PARENT ;
2010-10-24 14:35:14 +03:00
2012-12-19 20:24:53 +03:00
const int height = graphics - > fonts [ FONT_SMALL ] - > getLineHeight ( ) ;
2011-12-22 16:05:19 +03:00
inputBox = new CTextInput ( Rect ( 0 , rect . h - height , rect . w , height ) ) ;
2012-06-02 18:16:54 +03:00
inputBox - > removeUsedEvents ( KEYBOARD ) ;
2011-12-22 16:05:19 +03:00
chatHistory = new CTextBox ( " " , Rect ( 0 , 0 , rect . w , rect . h - height ) , 1 ) ;
2010-10-24 14:35:14 +03:00
2013-08-29 16:46:27 +03:00
chatHistory - > label - > color = Colors : : GREEN ;
2010-10-24 14:35:14 +03:00
}
void CChatBox : : keyPressed ( const SDL_KeyboardEvent & key )
{
if ( key . keysym . sym = = SDLK_RETURN & & key . state = = SDL_PRESSED & & inputBox - > text . size ( ) )
{
SEL - > postChatMessage ( inputBox - > text ) ;
2013-08-29 16:46:27 +03:00
inputBox - > setText ( " " ) ;
2010-10-24 14:35:14 +03:00
}
else
inputBox - > keyPressed ( key ) ;
2010-09-03 21:42:54 +03:00
}
2010-10-24 14:35:14 +03:00
void CChatBox : : addNewMessage ( const std : : string & text )
{
2015-03-13 17:45:07 +02:00
CCS - > soundh - > playSound ( " CHAT " ) ;
2013-08-29 16:46:27 +03:00
chatHistory - > setText ( chatHistory - > label - > text + text + " \n " ) ;
2010-10-24 14:35:14 +03:00
if ( chatHistory - > slider )
chatHistory - > slider - > moveToMax ( ) ;
}
InfoCard : : InfoCard ( bool Network )
2013-06-26 14:18:27 +03:00
: bg ( nullptr ) , network ( Network ) , chatOn ( false ) , chat ( nullptr ) , playerListBg ( nullptr ) ,
difficulty ( nullptr ) , sizes ( nullptr ) , sFlags ( nullptr )
2009-02-08 08:42:15 +02:00
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2013-12-29 15:18:02 +03:00
CIntObject : : type | = REDRAW_PARENT ;
2009-08-27 11:04:32 +03:00
pos . x + = 393 ;
2012-05-18 20:35:46 +03:00
pos . y + = 6 ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( RCLICK ) ;
2013-06-26 14:18:27 +03:00
mapDescription = nullptr ;
2009-08-27 11:04:32 +03:00
2011-12-22 16:05:19 +03:00
Rect descriptionRect ( 26 , 149 , 320 , 115 ) ;
2010-07-06 05:10:26 +03:00
mapDescription = new CTextBox ( " " , descriptionRect , 1 ) ;
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : campaignList )
2009-01-12 22:05:56 +02:00
{
2010-07-06 05:10:26 +03:00
CSelectionScreen * ss = static_cast < CSelectionScreen * > ( parent ) ;
2012-06-02 18:16:54 +03:00
mapDescription - > addChild ( new CPicture ( * ss - > bg , descriptionRect + Point ( - 393 , 0 ) ) , true ) ; //move subpicture bg to our description control (by default it's our (Infocard) child)
2010-02-15 14:12:21 +02:00
}
else
{
2012-05-18 20:35:46 +03:00
bg = new CPicture ( " GSELPOP1.bmp " , 0 , 0 ) ;
2012-06-02 18:16:54 +03:00
parent - > addChild ( bg ) ;
2012-02-22 22:22:11 +03:00
auto it = vstd : : find ( parent - > children , this ) ; //our position among parent children
parent - > children . insert ( it , bg ) ; //put BG before us
2011-11-27 16:14:20 +03:00
parent - > children . pop_back ( ) ;
2010-02-15 14:12:21 +02:00
pos . w = bg - > pos . w ;
pos . h = bg - > pos . h ;
2010-02-13 18:26:47 +02:00
sizes = CDefHandler : : giveDef ( " SCNRMPSZ.DEF " ) ;
sFlags = CDefHandler : : giveDef ( " ITGFLAGS.DEF " ) ;
2014-08-03 14:16:19 +03:00
difficulty = new CToggleGroup ( 0 ) ;
2009-08-27 11:04:32 +03:00
{
2010-02-13 18:26:47 +02:00
static const char * difButns [ ] = { " GSPBUT3.DEF " , " GSPBUT4.DEF " , " GSPBUT5.DEF " , " GSPBUT6.DEF " , " GSPBUT7.DEF " } ;
for ( int i = 0 ; i < 5 ; i + + )
{
2014-08-03 14:16:19 +03:00
auto button = new CToggleButton ( Point ( 110 + i * 32 , 450 ) , difButns [ i ] , CGI - > generaltexth - > zelp [ 24 + i ] ) ;
difficulty - > addToggle ( i , button ) ;
if ( SEL - > screenType ! = CMenuScreen : : newGame )
button - > block ( true ) ;
2010-02-13 18:26:47 +02:00
}
2009-08-27 11:04:32 +03:00
}
2010-09-03 21:42:54 +03:00
if ( network )
{
2010-10-24 14:35:14 +03:00
playerListBg = new CPicture ( " CHATPLUG.bmp " , 16 , 276 ) ;
2015-03-13 17:45:07 +02:00
chat = new CChatBox ( Rect ( 26 , 132 , 340 , 132 ) ) ;
2010-10-24 14:35:14 +03:00
chatOn = true ;
mapDescription - > disable ( ) ;
2010-09-03 21:42:54 +03:00
}
2010-02-13 18:26:47 +02:00
}
2010-07-06 05:10:26 +03:00
2008-08-02 18:08:03 +03:00
}
2009-05-04 02:38:08 +03:00
2009-08-17 11:50:31 +03:00
InfoCard : : ~ InfoCard ( )
2009-05-29 04:50:33 +03:00
{
2009-08-17 11:50:31 +03:00
delete sizes ;
delete sFlags ;
2008-08-02 18:08:03 +03:00
}
2009-05-29 04:50:33 +03:00
2011-12-22 16:05:19 +03:00
void InfoCard : : showAll ( SDL_Surface * to )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
CIntObject : : showAll ( to ) ;
2009-05-04 02:38:08 +03:00
2009-08-17 11:50:31 +03:00
//blit texts
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType ! = CMenuScreen : : campaignList )
2010-02-13 18:26:47 +02:00
{
2012-11-11 15:23:31 +03:00
printAtLoc ( CGI - > generaltexth - > allTexts [ 390 ] + " : " , 24 , 400 , FONT_SMALL , Colors : : WHITE , to ) ; //Allies
printAtLoc ( CGI - > generaltexth - > allTexts [ 391 ] + " : " , 190 , 400 , FONT_SMALL , Colors : : WHITE , to ) ; //Enemies
printAtLoc ( CGI - > generaltexth - > allTexts [ 494 ] , 33 , 430 , FONT_SMALL , Colors : : YELLOW , to ) ; //"Map Diff:"
printAtLoc ( CGI - > generaltexth - > allTexts [ 492 ] + " : " , 133 , 430 , FONT_SMALL , Colors : : YELLOW , to ) ; //player difficulty
printAtLoc ( CGI - > generaltexth - > allTexts [ 218 ] + " : " , 290 , 430 , FONT_SMALL , Colors : : YELLOW , to ) ; //"Rating:"
printAtLoc ( CGI - > generaltexth - > allTexts [ 495 ] , 26 , 22 , FONT_SMALL , Colors : : YELLOW , to ) ; //Scenario Name:
2010-10-24 14:35:14 +03:00
if ( ! chatOn )
{
2012-11-11 15:23:31 +03:00
printAtLoc ( CGI - > generaltexth - > allTexts [ 496 ] , 26 , 132 , FONT_SMALL , Colors : : YELLOW , to ) ; //Scenario Description:
printAtLoc ( CGI - > generaltexth - > allTexts [ 497 ] , 26 , 283 , FONT_SMALL , Colors : : YELLOW , to ) ; //Victory Condition:
printAtLoc ( CGI - > generaltexth - > allTexts [ 498 ] , 26 , 339 , FONT_SMALL , Colors : : YELLOW , to ) ; //Loss Condition:
2010-10-24 14:35:14 +03:00
}
else //players list
{
2013-03-03 20:06:03 +03:00
std : : map < ui8 , std : : string > playerNames = SEL - > playerNames ;
2010-10-24 14:35:14 +03:00
int playerSoFar = 0 ;
2012-09-24 19:14:53 +03:00
for ( auto i = SEL - > sInfo . playerInfos . cbegin ( ) ; i ! = SEL - > sInfo . playerInfos . cend ( ) ; i + + )
2010-10-24 14:35:14 +03:00
{
2012-12-02 15:21:44 +03:00
if ( i - > second . playerID ! = PlayerSettings : : PLAYER_AI )
2010-10-24 14:35:14 +03:00
{
2012-12-19 20:24:53 +03:00
printAtLoc ( i - > second . name , 24 , 285 + playerSoFar + + * graphics - > fonts [ FONT_SMALL ] - > getLineHeight ( ) , FONT_SMALL , Colors : : WHITE , to ) ;
2012-12-02 15:21:44 +03:00
playerNames . erase ( i - > second . playerID ) ;
2010-10-24 14:35:14 +03:00
}
}
playerSoFar = 0 ;
2012-09-24 19:14:53 +03:00
for ( auto i = playerNames . cbegin ( ) ; i ! = playerNames . cend ( ) ; i + + )
2010-10-24 14:35:14 +03:00
{
2012-12-19 20:24:53 +03:00
printAtLoc ( i - > second , 193 , 285 + playerSoFar + + * graphics - > fonts [ FONT_SMALL ] - > getLineHeight ( ) , FONT_SMALL , Colors : : WHITE , to ) ;
2010-10-24 14:35:14 +03:00
}
}
2010-02-13 18:26:47 +02:00
}
2009-08-17 11:50:31 +03:00
2010-10-24 14:35:14 +03:00
if ( SEL - > current )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType ! = CMenuScreen : : campaignList )
2008-08-02 18:08:03 +03:00
{
2010-10-24 14:35:14 +03:00
int temp = - 1 ;
2008-08-02 18:08:03 +03:00
2010-10-24 14:35:14 +03:00
if ( ! chatOn )
{
2013-08-29 23:35:24 +03:00
CDefHandler * loss = CGP ? CGP - > loss : CDefHandler : : giveDef ( " SCNRLOSS.DEF " ) ;
CDefHandler * victory = CGP ? CGP - > victory : CDefHandler : : giveDef ( " SCNRVICT.DEF " ) ;
2013-12-29 14:27:38 +03:00
CMapHeader * header = SEL - > current - > mapHeader . get ( ) ;
2010-10-24 14:35:14 +03:00
//victory conditions
2013-12-29 14:27:38 +03:00
printAtLoc ( header - > victoryMessage , 60 , 307 , FONT_SMALL , Colors : : WHITE , to ) ;
blitAtLoc ( victory - > ourImages [ header - > victoryIconIndex ] . bitmap , 24 , 302 , to ) ; //victory cond descr
2010-10-24 14:35:14 +03:00
//loss conditoins
2013-12-29 14:27:38 +03:00
printAtLoc ( header - > defeatMessage , 60 , 366 , FONT_SMALL , Colors : : WHITE , to ) ;
blitAtLoc ( loss - > ourImages [ header - > defeatIconIndex ] . bitmap , 24 , 359 , to ) ; //loss cond
2013-08-29 23:35:24 +03:00
if ( ! CGP )
{
delete loss ;
delete victory ;
}
2010-10-24 14:35:14 +03:00
}
2008-08-02 18:08:03 +03:00
2010-02-13 18:26:47 +02:00
//difficulty
2010-10-24 14:35:14 +03:00
assert ( SEL - > current - > mapHeader - > difficulty < = 4 ) ;
std : : string & diff = CGI - > generaltexth - > arraytxt [ 142 + SEL - > current - > mapHeader - > difficulty ] ;
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( diff , 62 , 472 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-02-13 18:26:47 +02:00
//selecting size icon
2010-10-24 14:35:14 +03:00
switch ( SEL - > current - > mapHeader - > width )
2010-02-13 18:26:47 +02:00
{
case 36 :
temp = 0 ;
break ;
case 72 :
temp = 1 ;
break ;
case 108 :
temp = 2 ;
break ;
case 144 :
temp = 3 ;
break ;
default :
temp = 4 ;
break ;
}
blitAtLoc ( sizes - > ourImages [ temp ] . bitmap , 318 , 22 , to ) ;
2010-02-15 14:12:21 +02:00
2010-02-13 18:26:47 +02:00
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : loadGame )
2012-11-11 15:23:31 +03:00
printToLoc ( ( static_cast < const CMapInfo * > ( SEL - > current ) ) - > date , 308 , 34 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-02-13 18:26:47 +02:00
//print flags
2012-12-19 20:24:53 +03:00
int fx = 34 + graphics - > fonts [ FONT_SMALL ] - > getStringWidth ( CGI - > generaltexth - > allTexts [ 390 ] ) ;
int ex = 200 + graphics - > fonts [ FONT_SMALL ] - > getStringWidth ( CGI - > generaltexth - > allTexts [ 391 ] ) ;
2011-11-27 16:14:20 +03:00
2013-03-03 20:06:03 +03:00
TeamID myT ;
2010-10-24 14:35:14 +03:00
2013-03-03 20:06:03 +03:00
if ( playerColor < PlayerColor : : PLAYER_LIMIT )
myT = SEL - > current - > mapHeader - > players [ playerColor . getNum ( ) ] . team ;
2011-11-27 16:14:20 +03:00
else
2013-03-03 20:06:03 +03:00
myT = TeamID : : NO_TEAM ;
2010-10-24 14:35:14 +03:00
2012-09-24 19:14:53 +03:00
for ( auto i = SEL - > sInfo . playerInfos . cbegin ( ) ; i ! = SEL - > sInfo . playerInfos . cend ( ) ; i + + )
2010-02-13 18:26:47 +02:00
{
2013-03-03 20:06:03 +03:00
int * myx = ( ( i - > first = = playerColor | | SEL - > current - > mapHeader - > players [ i - > first . getNum ( ) ] . team = = myT ) ? & fx : & ex ) ;
blitAtLoc ( sFlags - > ourImages [ i - > first . getNum ( ) ] . bitmap , * myx , 399 , to ) ;
* myx + = sFlags - > ourImages [ i - > first . getNum ( ) ] . bitmap - > w ;
2010-02-13 18:26:47 +02:00
}
std : : string tob ;
2010-10-24 14:35:14 +03:00
switch ( SEL - > sInfo . difficulty )
2010-02-13 18:26:47 +02:00
{
case 0 :
tob = " 80% " ;
break ;
case 1 :
tob = " 100% " ;
break ;
case 2 :
tob = " 130% " ;
break ;
case 3 :
tob = " 160% " ;
break ;
case 4 :
tob = " 200% " ;
break ;
}
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( tob , 311 , 472 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-02-13 18:26:47 +02:00
}
2008-08-02 18:08:03 +03:00
2009-05-29 04:50:33 +03:00
//blit description
2010-07-06 05:10:26 +03:00
std : : string name ;
2010-02-13 18:26:47 +02:00
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : campaignList )
2010-02-13 18:26:47 +02:00
{
2010-10-24 14:35:14 +03:00
name = SEL - > current - > campaignHeader - > name ;
2011-11-27 16:14:20 +03:00
}
2010-02-13 18:26:47 +02:00
else
{
2010-10-24 14:35:14 +03:00
name = SEL - > current - > mapHeader - > name ;
2010-02-13 18:26:47 +02:00
}
2009-01-12 22:05:56 +02:00
2010-02-13 18:26:47 +02:00
//name
if ( name . length ( ) )
2012-12-19 20:24:53 +03:00
printAtLoc ( name , 26 , 39 , FONT_BIG , Colors : : YELLOW , to ) ;
2011-11-27 16:14:20 +03:00
else
2012-11-11 15:23:31 +03:00
printAtLoc ( " Unnamed " , 26 , 39 , FONT_BIG , Colors : : YELLOW , to ) ;
2008-08-02 18:08:03 +03:00
}
}
2009-05-04 02:38:08 +03:00
2009-08-17 11:50:31 +03:00
void InfoCard : : changeSelection ( const CMapInfo * to )
2008-08-02 18:08:03 +03:00
{
2010-07-06 05:10:26 +03:00
if ( to & & mapDescription )
{
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : campaignList )
2013-08-29 16:46:27 +03:00
mapDescription - > setText ( to - > campaignHeader - > description ) ;
2010-07-06 05:10:26 +03:00
else
2013-08-29 16:46:27 +03:00
mapDescription - > setText ( to - > mapHeader - > description ) ;
2010-07-06 05:10:26 +03:00
2014-11-24 14:56:33 +02:00
mapDescription - > label - > scrollTextTo ( 0 ) ;
if ( mapDescription - > slider )
mapDescription - > slider - > moveToMin ( ) ;
2011-09-26 03:01:47 +03:00
if ( SEL - > screenType ! = CMenuScreen : : newGame & & SEL - > screenType ! = CMenuScreen : : campaignList ) {
2014-08-03 14:16:19 +03:00
//difficulty->block(true);
difficulty - > setSelected ( SEL - > sInfo . difficulty ) ;
2011-09-26 03:01:47 +03:00
}
2010-07-06 05:10:26 +03:00
}
2013-12-29 15:18:02 +03:00
redraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-22 16:59:15 +03:00
void InfoCard : : clickRight ( tribool down , bool previousState )
{
2011-12-22 16:05:19 +03:00
static const Rect flagArea ( 19 , 397 , 335 , 23 ) ;
2010-10-24 14:35:14 +03:00
if ( down & & SEL - > current & & isItInLoc ( flagArea , GH . current - > motion . x , GH . current - > motion . y ) )
2009-08-22 16:59:15 +03:00
showTeamsPopup ( ) ;
}
void InfoCard : : showTeamsPopup ( )
{
2012-05-13 18:04:21 +03:00
SDL_Surface * bmp = CMessage : : drawDialogBox ( 256 , 90 + 50 * SEL - > current - > mapHeader - > howManyTeams ) ;
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_MEDIUM ] - > renderTextCenter ( bmp , CGI - > generaltexth - > allTexts [ 657 ] , Colors : : YELLOW , Point ( 128 , 30 ) ) ;
2009-08-22 16:59:15 +03:00
2010-10-24 14:35:14 +03:00
for ( int i = 0 ; i < SEL - > current - > mapHeader - > howManyTeams ; i + + )
2009-08-22 16:59:15 +03:00
{
std : : vector < ui8 > flags ;
std : : string hlp = CGI - > generaltexth - > allTexts [ 656 ] ; //Team %d
hlp . replace ( hlp . find ( " %d " ) , 2 , boost : : lexical_cast < std : : string > ( i + 1 ) ) ;
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextCenter ( bmp , hlp , Colors : : WHITE , Point ( 128 , 65 + 50 * i ) ) ;
2009-08-22 16:59:15 +03:00
2013-03-03 20:06:03 +03:00
for ( int j = 0 ; j < PlayerColor : : PLAYER_LIMIT_I ; j + + )
2010-10-24 14:35:14 +03:00
if ( ( SEL - > current - > mapHeader - > players [ j ] . canHumanPlay | | SEL - > current - > mapHeader - > players [ j ] . canComputerPlay )
2013-03-03 20:06:03 +03:00
& & SEL - > current - > mapHeader - > players [ j ] . team = = TeamID ( i ) )
2009-08-22 16:59:15 +03:00
flags . push_back ( j ) ;
int curx = 128 - 9 * flags . size ( ) ;
2013-06-29 16:05:48 +03:00
for ( auto & flag : flags )
2009-08-22 16:59:15 +03:00
{
2013-06-29 16:05:48 +03:00
blitAt ( sFlags - > ourImages [ flag ] . bitmap , curx , 75 + 50 * i , bmp ) ;
2009-08-22 16:59:15 +03:00
curx + = 18 ;
2011-11-27 16:14:20 +03:00
}
2009-08-22 16:59:15 +03:00
}
GH . pushInt ( new CInfoPopup ( bmp , true ) ) ;
}
2010-09-03 21:42:54 +03:00
void InfoCard : : toggleChat ( )
{
setChat ( ! chatOn ) ;
}
void InfoCard : : setChat ( bool activateChat )
{
if ( chatOn = = activateChat )
return ;
assert ( active ) ;
if ( activateChat )
{
2010-10-24 14:35:14 +03:00
mapDescription - > disable ( ) ;
chat - > enable ( ) ;
playerListBg - > enable ( ) ;
2010-09-03 21:42:54 +03:00
}
else
{
2010-10-24 14:35:14 +03:00
mapDescription - > enable ( ) ;
chat - > disable ( ) ;
playerListBg - > disable ( ) ;
2010-09-03 21:42:54 +03:00
}
chatOn = activateChat ;
2010-10-24 14:35:14 +03:00
GH . totalRedraw ( ) ;
2010-09-03 21:42:54 +03:00
}
2011-01-17 18:07:08 +02:00
OptionsTab : : OptionsTab ( ) :
2013-06-26 14:18:27 +03:00
turnDuration ( nullptr )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
OBJ_CONSTRUCTION ;
2012-05-18 20:35:46 +03:00
bg = new CPicture ( " ADVOPTBK " , 0 , 6 ) ;
2009-08-17 11:50:31 +03:00
pos = bg - > pos ;
2008-08-02 18:08:03 +03:00
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : newGame )
2014-08-09 15:14:31 +03:00
turnDuration = new CSlider ( Point ( 55 , 551 ) , 194 , std : : bind ( & OptionsTab : : setTurnLength , this , _1 ) , 1 , 11 , 11 , true , CSlider : : BLUE ) ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
OptionsTab : : ~ OptionsTab ( )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
2011-12-22 16:05:19 +03:00
void OptionsTab : : showAll ( SDL_Surface * to )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
CIntObject : : showAll ( to ) ;
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 515 ] , 222 , 30 , FONT_BIG , Colors : : YELLOW , to ) ;
2012-12-19 20:24:53 +03:00
printAtMiddleWBLoc ( CGI - > generaltexth - > allTexts [ 516 ] , 222 , 68 , FONT_SMALL , 300 , Colors : : WHITE , to ) ; //Select starting options, handicap, and name for each player in the game.
printAtMiddleWBLoc ( CGI - > generaltexth - > allTexts [ 517 ] , 107 , 110 , FONT_SMALL , 100 , Colors : : YELLOW , to ) ; //Player Name Handicap Type
printAtMiddleWBLoc ( CGI - > generaltexth - > allTexts [ 518 ] , 197 , 110 , FONT_SMALL , 70 , Colors : : YELLOW , to ) ; //Starting Town
printAtMiddleWBLoc ( CGI - > generaltexth - > allTexts [ 519 ] , 273 , 110 , FONT_SMALL , 70 , Colors : : YELLOW , to ) ; //Starting Hero
printAtMiddleWBLoc ( CGI - > generaltexth - > allTexts [ 520 ] , 349 , 110 , FONT_SMALL , 70 , Colors : : YELLOW , to ) ; //Starting Bonus
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( CGI - > generaltexth - > allTexts [ 521 ] , 222 , 538 , FONT_SMALL , Colors : : YELLOW , to ) ; // Player Turn Duration
2011-01-17 18:07:08 +02:00
if ( turnDuration )
2014-08-03 17:31:56 +03:00
printAtMiddleLoc ( CGI - > generaltexth - > turnDurations [ turnDuration - > getValue ( ) ] , 319 , 559 , FONT_SMALL , Colors : : WHITE , to ) ; //Turn duration value
2009-08-17 11:50:31 +03:00
}
2013-03-03 20:06:03 +03:00
void OptionsTab : : nextCastle ( PlayerColor player , int dir )
2009-08-17 11:50:31 +03:00
{
2010-10-24 14:35:14 +03:00
if ( SEL - > isGuest ( ) )
{
SEL - > postRequest ( RequestOptionsChange : : TOWN , dir ) ;
return ;
}
PlayerSettings & s = SEL - > sInfo . playerInfos [ player ] ;
2012-12-02 15:21:44 +03:00
si16 & cur = s . castle ;
2013-03-03 20:06:03 +03:00
auto & allowed = SEL - > current - > mapHeader - > players [ s . color . getNum ( ) ] . allowedFactions ;
2009-08-17 11:50:31 +03:00
2012-12-10 17:28:27 +03:00
if ( cur = = PlayerSettings : : NONE ) //no change
2010-08-04 14:18:13 +03:00
return ;
2012-12-10 17:28:27 +03:00
if ( cur = = PlayerSettings : : RANDOM ) //first/last available
2010-08-04 14:18:13 +03:00
{
2012-09-23 17:32:49 +03:00
if ( dir > 0 )
cur = * allowed . begin ( ) ; //id of first town
else
cur = * allowed . rbegin ( ) ; //id of last town
2010-08-04 14:18:13 +03:00
}
else // next/previous available
{
2012-09-23 17:32:49 +03:00
if ( ( cur = = * allowed . begin ( ) & & dir < 0 )
| | ( cur = = * allowed . rbegin ( ) & & dir > 0 ) )
cur = - 1 ;
else
2010-08-04 14:18:13 +03:00
{
2012-09-23 17:32:49 +03:00
assert ( dir > = - 1 & & dir < = 1 ) ; //othervice std::advance may go out of range
auto iter = allowed . find ( cur ) ;
std : : advance ( iter , dir ) ;
cur = * iter ;
2010-08-04 14:18:13 +03:00
}
}
2009-08-17 11:50:31 +03:00
2013-12-23 18:59:37 +03:00
if ( s . hero > = 0 & & ! SEL - > current - > mapHeader - > players [ s . color . getNum ( ) ] . hasCustomMainHero ( ) ) // remove hero unless it set to fixed one in map editor
2015-01-24 22:24:23 +02:00
{
2015-01-25 00:12:17 +02:00
usedHeroes . erase ( s . hero ) ; // restore previously selected hero back to available pool
2012-12-10 17:28:27 +03:00
s . hero = PlayerSettings : : RANDOM ;
2015-01-24 22:24:23 +02:00
}
2012-12-02 15:21:44 +03:00
if ( cur < 0 & & s . bonus = = PlayerSettings : : RESOURCE )
s . bonus = PlayerSettings : : RANDOM ;
2009-08-18 11:22:56 +03:00
entries [ player ] - > selectButtons ( ) ;
2010-10-24 14:35:14 +03:00
SEL - > propagateOptions ( ) ;
2012-12-10 17:28:27 +03:00
entries [ player ] - > update ( ) ;
2009-08-17 11:50:31 +03:00
redraw ( ) ;
}
2013-03-03 20:06:03 +03:00
void OptionsTab : : nextHero ( PlayerColor player , int dir )
2009-08-17 11:50:31 +03:00
{
2010-10-24 14:35:14 +03:00
if ( SEL - > isGuest ( ) )
{
SEL - > postRequest ( RequestOptionsChange : : HERO , dir ) ;
return ;
}
PlayerSettings & s = SEL - > sInfo . playerInfos [ player ] ;
2009-08-17 11:50:31 +03:00
int old = s . hero ;
2012-12-02 15:21:44 +03:00
if ( s . castle < 0 | | s . playerID = = PlayerSettings : : PLAYER_AI | | s . hero = = PlayerSettings : : NONE )
2009-08-17 11:50:31 +03:00
return ;
2008-08-02 18:08:03 +03:00
2012-12-10 17:28:27 +03:00
if ( s . hero = = PlayerSettings : : RANDOM ) // first/last available
2009-02-11 19:48:40 +02:00
{
2012-12-17 15:55:29 +03:00
int max = CGI - > heroh - > heroes . size ( ) ,
min = 0 ;
s . hero = nextAllowedHero ( player , min , max , 0 , dir ) ;
2009-02-11 19:48:40 +02:00
}
2009-08-17 11:50:31 +03:00
else
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
if ( dir > 0 )
2012-12-17 15:55:29 +03:00
s . hero = nextAllowedHero ( player , s . hero , CGI - > heroh - > heroes . size ( ) , 1 , dir ) ;
2009-08-17 11:50:31 +03:00
else
2015-01-25 00:12:17 +02:00
s . hero = nextAllowedHero ( player , - 1 , s . hero , 1 , dir ) ; // min needs to be -1 -- hero at index 0 would be skipped otherwise
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
if ( old ! = s . hero )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
usedHeroes . erase ( old ) ;
usedHeroes . insert ( s . hero ) ;
2012-12-10 17:28:27 +03:00
entries [ player ] - > update ( ) ;
2009-08-17 11:50:31 +03:00
redraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2010-10-24 14:35:14 +03:00
SEL - > propagateOptions ( ) ;
2009-08-17 11:50:31 +03:00
}
2013-03-03 20:06:03 +03:00
int OptionsTab : : nextAllowedHero ( PlayerColor player , int min , int max , int incl , int dir )
2009-08-17 11:50:31 +03:00
{
if ( dir > 0 )
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
for ( int i = min + incl ; i < = max - incl ; i + + )
2012-12-17 15:55:29 +03:00
if ( canUseThisHero ( player , i ) )
2009-08-17 11:50:31 +03:00
return i ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
else
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
for ( int i = max - incl ; i > = min + incl ; i - - )
2012-12-17 15:55:29 +03:00
if ( canUseThisHero ( player , i ) )
2009-08-17 11:50:31 +03:00
return i ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
return - 1 ;
2008-08-02 18:08:03 +03:00
}
2009-05-01 19:14:29 +03:00
2013-03-03 20:06:03 +03:00
bool OptionsTab : : canUseThisHero ( PlayerColor player , int ID )
2009-08-17 11:50:31 +03:00
{
2012-10-06 11:47:13 +03:00
return CGI - > heroh - > heroes . size ( ) > ID
2012-12-17 15:55:29 +03:00
& & SEL - > sInfo . playerInfos [ player ] . castle = = CGI - > heroh - > heroes [ ID ] - > heroClass - > faction
& & ! vstd : : contains ( usedHeroes , ID )
& & SEL - > current - > mapHeader - > allowedHeroes [ ID ] ;
2009-08-17 11:50:31 +03:00
}
2009-02-11 19:03:30 +02:00
2013-03-03 20:06:03 +03:00
void OptionsTab : : nextBonus ( PlayerColor player , int dir )
2009-08-17 11:50:31 +03:00
{
2010-10-24 14:35:14 +03:00
if ( SEL - > isGuest ( ) )
{
SEL - > postRequest ( RequestOptionsChange : : BONUS , dir ) ;
return ;
}
PlayerSettings & s = SEL - > sInfo . playerInfos [ player ] ;
2013-02-02 01:04:25 +03:00
PlayerSettings : : Ebonus & ret = s . bonus = static_cast < PlayerSettings : : Ebonus > ( static_cast < int > ( s . bonus ) + dir ) ;
2009-06-24 09:56:36 +03:00
2012-12-10 17:28:27 +03:00
if ( s . hero = = PlayerSettings : : NONE & &
2013-03-03 20:06:03 +03:00
! SEL - > current - > mapHeader - > players [ s . color . getNum ( ) ] . heroesNames . size ( ) & &
2012-12-10 17:28:27 +03:00
ret = = PlayerSettings : : ARTIFACT ) //no hero - can't be artifact
2009-08-17 11:50:31 +03:00
{
if ( dir < 0 )
2012-12-02 15:21:44 +03:00
ret = PlayerSettings : : RANDOM ;
else ret = PlayerSettings : : GOLD ;
2008-08-02 18:08:03 +03:00
}
2009-06-28 02:33:59 +03:00
2012-12-02 15:21:44 +03:00
if ( ret > PlayerSettings : : RESOURCE )
ret = PlayerSettings : : RANDOM ;
if ( ret < PlayerSettings : : RANDOM )
ret = PlayerSettings : : RESOURCE ;
2009-06-24 09:56:36 +03:00
2012-12-10 17:28:27 +03:00
if ( s . castle = = PlayerSettings : : RANDOM & & ret = = PlayerSettings : : RESOURCE ) //random castle - can't be resource
2008-08-02 18:08:03 +03:00
{
2009-08-17 11:50:31 +03:00
if ( dir < 0 )
2012-12-02 15:21:44 +03:00
ret = PlayerSettings : : GOLD ;
else ret = PlayerSettings : : RANDOM ;
2008-08-02 18:08:03 +03:00
}
2009-05-29 04:54:45 +03:00
2010-10-24 14:35:14 +03:00
SEL - > propagateOptions ( ) ;
2012-12-10 17:28:27 +03:00
entries [ player ] - > update ( ) ;
2009-08-17 11:50:31 +03:00
redraw ( ) ;
2008-08-02 18:08:03 +03:00
}
2009-05-29 04:54:45 +03:00
2010-10-24 14:35:14 +03:00
void OptionsTab : : recreate ( )
2008-08-02 18:08:03 +03:00
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : entries )
2008-08-02 18:08:03 +03:00
{
2013-06-29 16:05:48 +03:00
delete elem . second ;
2008-08-02 18:08:03 +03:00
}
2009-08-17 11:50:31 +03:00
entries . clear ( ) ;
usedHeroes . clear ( ) ;
2010-03-06 00:51:09 +02:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-09-24 19:14:53 +03:00
for ( auto it = SEL - > sInfo . playerInfos . begin ( ) ; it ! = SEL - > sInfo . playerInfos . end ( ) ; + + it )
2008-08-02 18:08:03 +03:00
{
2010-08-03 14:36:52 +03:00
entries . insert ( std : : make_pair ( it - > first , new PlayerOptionsEntry ( this , it - > second ) ) ) ;
2013-03-03 20:06:03 +03:00
const std : : vector < SHeroName > & heroes = SEL - > current - > mapHeader - > players [ it - > first . getNum ( ) ] . heroesNames ;
2013-06-29 16:05:48 +03:00
for ( auto & heroe : heroes )
usedHeroes . insert ( heroe . heroId ) ;
2008-08-02 18:08:03 +03:00
}
2010-10-24 14:35:14 +03:00
2008-08-02 18:08:03 +03:00
}
2008-11-16 03:06:15 +02:00
2009-08-17 11:50:31 +03:00
void OptionsTab : : setTurnLength ( int npos )
2008-11-16 03:06:15 +02:00
{
2009-08-17 11:50:31 +03:00
static const int times [ ] = { 1 , 2 , 4 , 6 , 8 , 10 , 15 , 20 , 25 , 30 , 0 } ;
2011-12-14 00:23:17 +03:00
vstd : : amin ( npos , ARRAY_COUNT ( times ) - 1 ) ;
2009-08-17 11:50:31 +03:00
2010-10-24 14:35:14 +03:00
SEL - > sInfo . turnTime = times [ npos ] ;
2009-08-17 11:50:31 +03:00
redraw ( ) ;
2008-11-16 03:06:15 +02:00
}
2013-03-03 20:06:03 +03:00
void OptionsTab : : flagPressed ( PlayerColor color )
2008-11-16 03:06:15 +02:00
{
2010-10-24 14:35:14 +03:00
PlayerSettings & clicked = SEL - > sInfo . playerInfos [ color ] ;
2013-06-26 14:18:27 +03:00
PlayerSettings * old = nullptr ;
2010-02-16 18:35:24 +02:00
2010-10-24 14:35:14 +03:00
if ( SEL - > playerNames . size ( ) = = 1 ) //single player -> just swap
2010-02-16 18:35:24 +02:00
{
2010-10-24 14:35:14 +03:00
if ( color = = playerColor ) //that color is already selected, no action needed
2010-02-16 18:35:24 +02:00
return ;
2010-10-24 14:35:14 +03:00
old = & SEL - > sInfo . playerInfos [ playerColor ] ;
swapPlayers ( * old , clicked ) ;
2010-02-16 18:35:24 +02:00
}
else
{
//identify clicked player
2012-12-02 15:21:44 +03:00
int clickedNameID = clicked . playerID ; //human is a number of player, zero means AI
2010-02-16 18:35:24 +02:00
2010-10-24 14:35:14 +03:00
if ( clickedNameID > 0 & & playerToRestore . id = = clickedNameID ) //player to restore is about to being replaced -> put him back to the old place
2010-02-16 18:35:24 +02:00
{
2010-10-24 14:35:14 +03:00
PlayerSettings & restPos = SEL - > sInfo . playerInfos [ playerToRestore . color ] ;
SEL - > setPlayer ( restPos , playerToRestore . id ) ;
playerToRestore . reset ( ) ;
2010-02-16 18:35:24 +02:00
}
2011-05-04 05:38:58 +03:00
int newPlayer ; //which player will take clicked position
2010-10-24 14:35:14 +03:00
2010-08-04 14:18:13 +03:00
//who will be put here?
2010-10-24 14:35:14 +03:00
if ( ! clickedNameID ) //AI player clicked -> if possible replace computer with unallocated player
2010-02-16 18:35:24 +02:00
{
2010-10-24 14:35:14 +03:00
newPlayer = SEL - > getIdOfFirstUnallocatedPlayer ( ) ;
if ( ! newPlayer ) //no "free" player -> get just first one
newPlayer = SEL - > playerNames . begin ( ) - > first ;
2010-02-16 18:35:24 +02:00
}
2010-10-24 14:35:14 +03:00
else //human clicked -> take next
{
2012-09-24 19:14:53 +03:00
auto i = SEL - > playerNames . find ( clickedNameID ) ; //clicked one
2010-10-24 14:35:14 +03:00
i + + ; //player AFTER clicked one
2009-08-18 11:22:56 +03:00
2010-10-24 14:35:14 +03:00
if ( i ! = SEL - > playerNames . end ( ) )
newPlayer = i - > first ;
else
newPlayer = 0 ; //AI if we scrolled through all players
}
SEL - > setPlayer ( clicked , newPlayer ) ; //put player
2009-08-18 11:22:56 +03:00
2010-02-16 18:35:24 +02:00
//if that player was somewhere else, we need to replace him with computer
2010-10-24 14:35:14 +03:00
if ( newPlayer ) //not AI
2010-02-16 18:35:24 +02:00
{
2012-09-24 19:14:53 +03:00
for ( auto i = SEL - > sInfo . playerInfos . begin ( ) ; i ! = SEL - > sInfo . playerInfos . end ( ) ; i + + )
2010-02-16 18:35:24 +02:00
{
2012-12-02 15:21:44 +03:00
int curNameID = i - > second . playerID ;
2010-10-24 14:35:14 +03:00
if ( i - > first ! = color & & curNameID = = newPlayer )
2010-02-16 18:35:24 +02:00
{
2012-12-02 15:21:44 +03:00
assert ( i - > second . playerID ) ;
2010-10-24 14:35:14 +03:00
playerToRestore . color = i - > first ;
playerToRestore . id = newPlayer ;
SEL - > setPlayer ( i - > second , 0 ) ; //set computer
2010-08-03 14:36:52 +03:00
old = & i - > second ;
2010-02-16 18:35:24 +02:00
break ;
}
}
}
}
2009-08-18 11:22:56 +03:00
2010-08-03 14:36:52 +03:00
entries [ clicked . color ] - > selectButtons ( ) ;
2010-02-16 18:35:24 +02:00
if ( old )
{
2010-08-03 14:36:52 +03:00
entries [ old - > color ] - > selectButtons ( ) ;
2012-03-26 14:38:51 +03:00
if ( old - > hero > = 0 )
usedHeroes . erase ( old - > hero ) ;
2010-10-24 14:35:14 +03:00
old - > hero = entries [ old - > color ] - > pi . defaultHero ( ) ;
2015-01-25 00:12:17 +02:00
entries [ old - > color ] - > update ( ) ; // update previous frame images in case entries were auto-updated
2010-02-16 18:35:24 +02:00
}
2010-10-24 14:35:14 +03:00
SEL - > propagateOptions ( ) ;
2009-08-17 11:50:31 +03:00
GH . totalRedraw ( ) ;
2008-11-16 03:06:15 +02:00
}
2009-08-17 11:50:31 +03:00
OptionsTab : : PlayerOptionsEntry : : PlayerOptionsEntry ( OptionsTab * owner , PlayerSettings & S )
2013-03-03 20:06:03 +03:00
: pi ( SEL - > current - > mapHeader - > players [ S . color . getNum ( ) ] ) , s ( S )
2008-11-16 03:06:15 +02:00
{
2009-08-17 11:50:31 +03:00
OBJ_CONSTRUCTION ;
defActions | = SHARE_POS ;
2010-10-24 14:35:14 +03:00
2010-08-03 14:36:52 +03:00
int serial = 0 ;
2013-03-03 20:06:03 +03:00
for ( int g = 0 ; g < s . color . getNum ( ) ; + + g )
2010-08-03 14:36:52 +03:00
{
2010-10-24 14:35:14 +03:00
PlayerInfo & itred = SEL - > current - > mapHeader - > players [ g ] ;
if ( itred . canComputerPlay | | itred . canHumanPlay )
2010-08-03 14:36:52 +03:00
serial + + ;
}
2012-06-02 18:16:54 +03:00
pos . x + = 54 ;
pos . y + = 122 + serial * 50 ;
2008-11-16 03:06:15 +02:00
2011-11-27 16:14:20 +03:00
static const char * flags [ ] = { " AOFLGBR.DEF " , " AOFLGBB.DEF " , " AOFLGBY.DEF " , " AOFLGBG.DEF " ,
2009-08-17 11:50:31 +03:00
" AOFLGBO.DEF " , " AOFLGBP.DEF " , " AOFLGBT.DEF " , " AOFLGBS.DEF " } ;
2011-11-27 16:14:20 +03:00
static const char * bgs [ ] = { " ADOPRPNL.bmp " , " ADOPBPNL.bmp " , " ADOPYPNL.bmp " , " ADOPGPNL.bmp " ,
2009-08-17 11:50:31 +03:00
" ADOPOPNL.bmp " , " ADOPPPNL.bmp " , " ADOPTPNL.bmp " , " ADOPSPNL.bmp " } ;
2008-11-16 03:06:15 +02:00
2013-03-03 20:06:03 +03:00
bg = new CPicture ( BitmapHandler : : loadBitmap ( bgs [ s . color . getNum ( ) ] ) , 0 , 0 , true ) ;
2010-10-24 14:35:14 +03:00
if ( SEL - > screenType = = CMenuScreen : : newGame )
2009-08-27 11:04:32 +03:00
{
2014-08-09 15:14:31 +03:00
btns [ 0 ] = new CButton ( Point ( 107 , 5 ) , " ADOPLFA.DEF " , CGI - > generaltexth - > zelp [ 132 ] , std : : bind ( & OptionsTab : : nextCastle , owner , s . color , - 1 ) ) ;
btns [ 1 ] = new CButton ( Point ( 168 , 5 ) , " ADOPRTA.DEF " , CGI - > generaltexth - > zelp [ 133 ] , std : : bind ( & OptionsTab : : nextCastle , owner , s . color , + 1 ) ) ;
btns [ 2 ] = new CButton ( Point ( 183 , 5 ) , " ADOPLFA.DEF " , CGI - > generaltexth - > zelp [ 148 ] , std : : bind ( & OptionsTab : : nextHero , owner , s . color , - 1 ) ) ;
btns [ 3 ] = new CButton ( Point ( 244 , 5 ) , " ADOPRTA.DEF " , CGI - > generaltexth - > zelp [ 149 ] , std : : bind ( & OptionsTab : : nextHero , owner , s . color , + 1 ) ) ;
btns [ 4 ] = new CButton ( Point ( 259 , 5 ) , " ADOPLFA.DEF " , CGI - > generaltexth - > zelp [ 164 ] , std : : bind ( & OptionsTab : : nextBonus , owner , s . color , - 1 ) ) ;
btns [ 5 ] = new CButton ( Point ( 320 , 5 ) , " ADOPRTA.DEF " , CGI - > generaltexth - > zelp [ 165 ] , std : : bind ( & OptionsTab : : nextBonus , owner , s . color , + 1 ) ) ;
2009-08-27 11:04:32 +03:00
}
2009-09-07 05:29:44 +03:00
else
2013-06-29 16:05:48 +03:00
for ( auto & elem : btns )
elem = nullptr ;
2009-05-10 01:19:41 +03:00
2011-08-25 18:24:37 +03:00
selectButtons ( ) ;
2009-08-18 11:22:56 +03:00
2010-10-24 14:35:14 +03:00
assert ( SEL - > current & & SEL - > current - > mapHeader ) ;
2013-03-03 20:06:03 +03:00
const PlayerInfo & p = SEL - > current - > mapHeader - > players [ s . color . getNum ( ) ] ;
2010-03-08 00:56:51 +02:00
assert ( p . canComputerPlay | | p . canHumanPlay ) ; //someone must be able to control this player
if ( p . canHumanPlay & & p . canComputerPlay )
whoCanPlay = HUMAN_OR_CPU ;
else if ( p . canComputerPlay )
whoCanPlay = CPU ;
else
whoCanPlay = HUMAN ;
2009-08-18 11:22:56 +03:00
2011-11-27 16:14:20 +03:00
if ( SEL - > screenType ! = CMenuScreen : : scenarioInfo
2015-03-15 18:24:03 +02:00
& & SEL - > current - > mapHeader - > players [ s . color . getNum ( ) ] . canHumanPlay )
2009-08-17 11:50:31 +03:00
{
2014-08-09 15:14:31 +03:00
flag = new CButton ( Point ( - 43 , 2 ) , flags [ s . color . getNum ( ) ] , CGI - > generaltexth - > zelp [ 180 ] , std : : bind ( & OptionsTab : : flagPressed , owner , s . color ) ) ;
2009-08-17 11:50:31 +03:00
flag - > hoverable = true ;
2015-03-15 18:24:03 +02:00
flag - > block ( SEL - > isGuest ( ) ) ;
2009-08-17 11:50:31 +03:00
}
else
2013-06-26 14:18:27 +03:00
flag = nullptr ;
2009-08-17 11:50:31 +03:00
2012-12-10 17:28:27 +03:00
town = new SelectedBox ( Point ( 119 , 2 ) , s , TOWN ) ;
hero = new SelectedBox ( Point ( 195 , 2 ) , s , HERO ) ;
bonus = new SelectedBox ( Point ( 271 , 2 ) , s , BONUS ) ;
2008-11-16 03:06:15 +02:00
}
2011-12-22 16:05:19 +03:00
void OptionsTab : : PlayerOptionsEntry : : showAll ( SDL_Surface * to )
2008-11-16 03:06:15 +02:00
{
2009-08-17 11:50:31 +03:00
CIntObject : : showAll ( to ) ;
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( s . name , 55 , 10 , FONT_SMALL , Colors : : WHITE , to ) ;
2012-12-19 20:24:53 +03:00
printAtMiddleWBLoc ( CGI - > generaltexth - > arraytxt [ 206 + whoCanPlay ] , 28 , 39 , FONT_TINY , 50 , Colors : : WHITE , to ) ;
2008-11-16 03:06:15 +02:00
}
2012-12-10 17:28:27 +03:00
void OptionsTab : : PlayerOptionsEntry : : update ( )
{
town - > update ( ) ;
hero - > update ( ) ;
bonus - > update ( ) ;
}
2011-08-25 18:24:37 +03:00
void OptionsTab : : PlayerOptionsEntry : : selectButtons ( )
2009-08-18 11:22:56 +03:00
{
2009-09-07 05:29:44 +03:00
if ( ! btns [ 0 ] )
2009-08-27 11:04:32 +03:00
return ;
2011-08-25 18:24:37 +03:00
if ( ( pi . defaultCastle ( ) ! = - 1 ) //fixed tow
2010-11-15 17:15:00 +02:00
| | ( SEL - > isGuest ( ) & & s . color ! = playerColor ) ) //or not our player
2009-08-18 11:22:56 +03:00
{
btns [ 0 ] - > disable ( ) ;
btns [ 1 ] - > disable ( ) ;
}
2010-10-24 14:35:14 +03:00
else
{
2012-06-02 18:16:54 +03:00
btns [ 0 ] - > enable ( ) ;
btns [ 1 ] - > enable ( ) ;
2010-10-24 14:35:14 +03:00
}
2012-12-02 15:21:44 +03:00
if ( ( pi . defaultHero ( ) ! = - 1 | | ! s . playerID | | s . castle < 0 ) //fixed hero
2010-11-15 17:15:00 +02:00
| | ( SEL - > isGuest ( ) & & s . color ! = playerColor ) ) //or not our player
2009-08-18 11:22:56 +03:00
{
btns [ 2 ] - > disable ( ) ;
btns [ 3 ] - > disable ( ) ;
}
else
{
2012-06-02 18:16:54 +03:00
btns [ 2 ] - > enable ( ) ;
btns [ 3 ] - > enable ( ) ;
2009-08-18 11:22:56 +03:00
}
2010-10-24 14:35:14 +03:00
if ( SEL - > isGuest ( ) & & s . color ! = playerColor ) //or not our player
{
btns [ 4 ] - > disable ( ) ;
btns [ 5 ] - > disable ( ) ;
}
else
{
2012-06-02 18:16:54 +03:00
btns [ 4 ] - > enable ( ) ;
btns [ 5 ] - > enable ( ) ;
2010-10-24 14:35:14 +03:00
}
2009-08-18 11:22:56 +03:00
}
2012-12-10 17:28:27 +03:00
size_t OptionsTab : : CPlayerSettingsHelper : : getImageIndex ( )
2012-10-05 16:11:26 +03:00
{
enum EBonusSelection //frames of bonuses file
{
WOOD_ORE = 0 , CRYSTAL = 1 , GEM = 2 ,
MERCURY = 3 , SULFUR = 5 , GOLD = 8 ,
ARTIFACT = 9 , RANDOM = 10 ,
2012-12-10 17:28:27 +03:00
WOOD = 0 , ORE = 0 , MITHRIL = 10 , // resources unavailable in bonuses file
TOWN_RANDOM = 38 , TOWN_NONE = 39 , // Special frames in ITPA
2013-04-22 22:51:22 +03:00
HERO_RANDOM = 163 , HERO_NONE = 164 // Special frames in PortraitsSmall
2012-10-05 16:11:26 +03:00
} ;
2012-12-10 17:28:27 +03:00
switch ( type )
2012-10-05 16:11:26 +03:00
{
2012-12-10 17:28:27 +03:00
case TOWN :
switch ( settings . castle )
2012-10-05 16:11:26 +03:00
{
2012-12-10 17:28:27 +03:00
case PlayerSettings : : NONE : return TOWN_NONE ;
case PlayerSettings : : RANDOM : return TOWN_RANDOM ;
2013-04-21 15:49:26 +03:00
default : return CGI - > townh - > factions [ settings . castle ] - > town - > clientInfo . icons [ true ] [ false ] + 2 ;
2012-10-05 16:11:26 +03:00
}
2009-08-22 16:59:15 +03:00
case HERO :
2012-12-10 17:28:27 +03:00
switch ( settings . hero )
2009-08-17 11:50:31 +03:00
{
2012-12-10 17:28:27 +03:00
case PlayerSettings : : NONE : return HERO_NONE ;
case PlayerSettings : : RANDOM : return HERO_RANDOM ;
default :
{
if ( settings . heroPortrait > = 0 )
return settings . heroPortrait ;
2012-12-16 16:47:53 +03:00
return CGI - > heroh - > heroes [ settings . hero ] - > imageIndex ;
2012-12-10 17:28:27 +03:00
}
2009-08-17 11:50:31 +03:00
}
2012-12-10 17:28:27 +03:00
case BONUS :
2009-08-17 11:50:31 +03:00
{
2012-12-10 17:28:27 +03:00
switch ( settings . bonus )
{
case PlayerSettings : : RANDOM : return RANDOM ;
case PlayerSettings : : ARTIFACT : return ARTIFACT ;
case PlayerSettings : : GOLD : return GOLD ;
case PlayerSettings : : RESOURCE :
{
2013-04-21 15:49:26 +03:00
switch ( CGI - > townh - > factions [ settings . castle ] - > town - > primaryRes )
2012-12-10 17:28:27 +03:00
{
2013-04-21 15:49:26 +03:00
case Res : : WOOD_AND_ORE : return WOOD_ORE ;
2012-12-10 17:28:27 +03:00
case Res : : WOOD : return WOOD ;
case Res : : MERCURY : return MERCURY ;
case Res : : ORE : return ORE ;
case Res : : SULFUR : return SULFUR ;
case Res : : CRYSTAL : return CRYSTAL ;
case Res : : GEMS : return GEM ;
case Res : : GOLD : return GOLD ;
case Res : : MITHRIL : return MITHRIL ;
}
}
}
2009-08-22 16:59:15 +03:00
}
2012-12-10 17:28:27 +03:00
}
return 0 ;
}
std : : string OptionsTab : : CPlayerSettingsHelper : : getImageName ( )
{
switch ( type )
{
case OptionsTab : : TOWN : return " ITPA " ;
case OptionsTab : : HERO : return " PortraitsSmall " ;
case OptionsTab : : BONUS : return " SCNRSTAR " ;
}
return " " ;
}
std : : string OptionsTab : : CPlayerSettingsHelper : : getTitle ( )
{
switch ( type )
{
case OptionsTab : : TOWN : return ( settings . castle < 0 ) ? CGI - > generaltexth - > allTexts [ 103 ] : CGI - > generaltexth - > allTexts [ 80 ] ;
case OptionsTab : : HERO : return ( settings . hero < 0 ) ? CGI - > generaltexth - > allTexts [ 101 ] : CGI - > generaltexth - > allTexts [ 77 ] ;
case OptionsTab : : BONUS :
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
switch ( settings . bonus )
{
case PlayerSettings : : RANDOM : return CGI - > generaltexth - > allTexts [ 86 ] ; //{Random Bonus}
case PlayerSettings : : ARTIFACT : return CGI - > generaltexth - > allTexts [ 83 ] ; //{Artifact Bonus}
case PlayerSettings : : GOLD : return CGI - > generaltexth - > allTexts [ 84 ] ; //{Gold Bonus}
case PlayerSettings : : RESOURCE : return CGI - > generaltexth - > allTexts [ 85 ] ; //{Resource Bonus}
}
2009-08-17 11:50:31 +03:00
}
}
2012-12-10 17:28:27 +03:00
return " " ;
2009-08-22 16:59:15 +03:00
}
2009-08-18 11:22:56 +03:00
2012-12-10 17:28:27 +03:00
std : : string OptionsTab : : CPlayerSettingsHelper : : getName ( )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
switch ( type )
2009-08-22 16:59:15 +03:00
{
case TOWN :
{
2012-12-10 17:28:27 +03:00
switch ( settings . castle )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
case PlayerSettings : : NONE : return CGI - > generaltexth - > allTexts [ 523 ] ;
case PlayerSettings : : RANDOM : return CGI - > generaltexth - > allTexts [ 522 ] ;
2013-04-21 15:49:26 +03:00
default : return CGI - > townh - > factions [ settings . castle ] - > name ;
2009-08-22 16:59:15 +03:00
}
}
2012-12-10 17:28:27 +03:00
case HERO :
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
switch ( settings . hero )
{
case PlayerSettings : : NONE : return CGI - > generaltexth - > allTexts [ 523 ] ;
case PlayerSettings : : RANDOM : return CGI - > generaltexth - > allTexts [ 522 ] ;
default :
{
if ( ! settings . heroName . empty ( ) )
return settings . heroName ;
return CGI - > heroh - > heroes [ settings . hero ] - > name ;
}
}
2009-08-22 16:59:15 +03:00
}
case BONUS :
{
2012-12-10 17:28:27 +03:00
switch ( settings . bonus )
{
case PlayerSettings : : RANDOM : return CGI - > generaltexth - > allTexts [ 522 ] ;
default : return CGI - > generaltexth - > arraytxt [ 214 + settings . bonus ] ;
}
2009-08-22 16:59:15 +03:00
}
}
2012-12-10 17:28:27 +03:00
return " " ;
2008-11-16 03:06:15 +02:00
}
2012-12-10 17:28:27 +03:00
std : : string OptionsTab : : CPlayerSettingsHelper : : getSubtitle ( )
2008-11-16 03:06:15 +02:00
{
2012-12-10 17:28:27 +03:00
switch ( type )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
case TOWN : return getName ( ) ;
2011-11-27 16:14:20 +03:00
case HERO :
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
if ( settings . hero > = 0 )
return getName ( ) + " - " + CGI - > heroh - > heroes [ settings . hero ] - > heroClass - > name ;
return getName ( ) ;
2009-08-22 16:59:15 +03:00
}
2012-12-10 17:28:27 +03:00
2011-11-27 16:14:20 +03:00
case BONUS :
2012-12-10 17:28:27 +03:00
{
switch ( settings . bonus )
{
case PlayerSettings : : GOLD : return CGI - > generaltexth - > allTexts [ 87 ] ; //500-1000
case PlayerSettings : : RESOURCE :
{
2013-04-21 15:49:26 +03:00
switch ( CGI - > townh - > factions [ settings . castle ] - > town - > primaryRes )
2012-12-10 17:28:27 +03:00
{
case Res : : MERCURY : return CGI - > generaltexth - > allTexts [ 694 ] ;
case Res : : SULFUR : return CGI - > generaltexth - > allTexts [ 695 ] ;
case Res : : CRYSTAL : return CGI - > generaltexth - > allTexts [ 692 ] ;
case Res : : GEMS : return CGI - > generaltexth - > allTexts [ 693 ] ;
2013-04-21 15:49:26 +03:00
case Res : : WOOD_AND_ORE : return CGI - > generaltexth - > allTexts [ 89 ] ; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
2012-12-10 17:28:27 +03:00
}
}
}
}
2009-08-22 16:59:15 +03:00
}
2012-12-10 17:28:27 +03:00
return " " ;
}
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
std : : string OptionsTab : : CPlayerSettingsHelper : : getDescription ( )
{
switch ( type )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
case TOWN : return CGI - > generaltexth - > allTexts [ 104 ] ;
case HERO : return CGI - > generaltexth - > allTexts [ 102 ] ;
case BONUS :
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
switch ( settings . bonus )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
case PlayerSettings : : RANDOM : return CGI - > generaltexth - > allTexts [ 94 ] ; //Gold, wood and ore, or an artifact is randomly chosen as your starting bonus
case PlayerSettings : : ARTIFACT : return CGI - > generaltexth - > allTexts [ 90 ] ; //An artifact is randomly chosen and equipped to your starting hero
case PlayerSettings : : GOLD : return CGI - > generaltexth - > allTexts [ 92 ] ; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool
case PlayerSettings : : RESOURCE :
2009-08-22 16:59:15 +03:00
{
2013-04-21 15:49:26 +03:00
switch ( CGI - > townh - > factions [ settings . castle ] - > town - > primaryRes )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
case Res : : MERCURY : return CGI - > generaltexth - > allTexts [ 690 ] ;
case Res : : SULFUR : return CGI - > generaltexth - > allTexts [ 691 ] ;
case Res : : CRYSTAL : return CGI - > generaltexth - > allTexts [ 688 ] ;
case Res : : GEMS : return CGI - > generaltexth - > allTexts [ 689 ] ;
2013-04-21 15:49:26 +03:00
case Res : : WOOD_AND_ORE : return CGI - > generaltexth - > allTexts [ 93 ] ; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
2009-08-22 16:59:15 +03:00
}
}
}
}
}
2012-12-10 17:28:27 +03:00
return " " ;
}
OptionsTab : : CPregameTooltipBox : : CPregameTooltipBox ( CPlayerSettingsHelper & helper ) :
CWindowObject ( BORDERED | RCLICK_POPUP ) ,
CPlayerSettingsHelper ( helper )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-12-14 18:32:53 +03:00
int value = PlayerSettings : : NONE ;
2012-12-10 17:28:27 +03:00
switch ( CPlayerSettingsHelper : : type )
2009-08-22 16:59:15 +03:00
{
2012-12-10 17:28:27 +03:00
break ; case TOWN :
value = settings . castle ;
break ; case HERO :
value = settings . hero ;
break ; case BONUS :
value = settings . bonus ;
2009-08-22 16:59:15 +03:00
}
2012-12-10 17:28:27 +03:00
if ( value = = PlayerSettings : : RANDOM )
genBonusWindow ( ) ;
else if ( CPlayerSettingsHelper : : type = = BONUS )
genBonusWindow ( ) ;
else if ( CPlayerSettingsHelper : : type = = HERO )
genHeroWindow ( ) ;
else if ( CPlayerSettingsHelper : : type = = TOWN )
genTownWindow ( ) ;
2011-11-27 16:14:20 +03:00
2012-12-10 17:28:27 +03:00
center ( ) ;
}
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
void OptionsTab : : CPregameTooltipBox : : genHeader ( )
{
new CFilledTexture ( " DIBOXBCK " , pos ) ;
updateShadow ( ) ;
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
new CLabel ( pos . w / 2 + 8 , 21 , FONT_MEDIUM , CENTER , Colors : : YELLOW , getTitle ( ) ) ;
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
new CLabel ( pos . w / 2 , 88 , FONT_SMALL , CENTER , Colors : : WHITE , getSubtitle ( ) ) ;
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
new CAnimImage ( getImageName ( ) , getImageIndex ( ) , 0 , pos . w / 2 - 24 , 45 ) ;
}
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
void OptionsTab : : CPregameTooltipBox : : genTownWindow ( )
{
pos = Rect ( 0 , 0 , 228 , 290 ) ;
genHeader ( ) ;
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
new CLabel ( pos . w / 2 + 8 , 122 , FONT_MEDIUM , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 79 ] ) ;
2009-08-22 16:59:15 +03:00
2012-12-10 17:28:27 +03:00
std : : vector < CComponent * > components ;
2013-04-21 15:49:26 +03:00
const CTown * town = CGI - > townh - > factions [ settings . castle ] - > town ;
2009-08-22 16:59:15 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & elem : town - > creatures )
2014-01-11 21:12:09 +03:00
{
if ( ! elem . empty ( ) )
components . push_back ( new CComponent ( CComponent : : creature , elem . front ( ) , 0 , CComponent : : tiny ) ) ;
}
2009-08-22 16:59:15 +03:00
2012-12-20 16:57:29 +03:00
new CComponentBox ( components , Rect ( 10 , 140 , pos . w - 20 , 140 ) ) ;
2012-12-10 17:28:27 +03:00
}
void OptionsTab : : CPregameTooltipBox : : genHeroWindow ( )
{
pos = Rect ( 0 , 0 , 292 , 226 ) ;
genHeader ( ) ;
2013-01-17 21:15:00 +03:00
// specialty
2012-12-16 16:47:53 +03:00
new CAnimImage ( " UN44 " , CGI - > heroh - > heroes [ settings . hero ] - > imageIndex , 0 , pos . w / 2 - 22 , 134 ) ;
2012-12-10 17:28:27 +03:00
new CLabel ( pos . w / 2 + 4 , 117 , FONT_MEDIUM , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 78 ] ) ;
2012-12-16 16:47:53 +03:00
new CLabel ( pos . w / 2 , 188 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > heroh - > heroes [ settings . hero ] - > specName ) ;
2012-12-10 17:28:27 +03:00
}
void OptionsTab : : CPregameTooltipBox : : genBonusWindow ( )
{
pos = Rect ( 0 , 0 , 228 , 162 ) ;
genHeader ( ) ;
2012-12-20 16:57:29 +03:00
new CTextBox ( getDescription ( ) , Rect ( 10 , 100 , pos . w - 20 , 70 ) , 0 , FONT_SMALL , CENTER , Colors : : WHITE ) ;
2012-12-10 17:28:27 +03:00
}
OptionsTab : : SelectedBox : : SelectedBox ( Point position , PlayerSettings & settings , SelType type )
: CIntObject ( RCLICK , position ) ,
CPlayerSettingsHelper ( settings , type )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
image = new CAnimImage ( getImageName ( ) , getImageIndex ( ) ) ;
subtitle = new CLabel ( 23 , 39 , FONT_TINY , CENTER , Colors : : WHITE , getName ( ) ) ;
pos = image - > pos ;
}
void OptionsTab : : SelectedBox : : update ( )
{
image - > setFrame ( getImageIndex ( ) ) ;
2013-08-29 16:46:27 +03:00
subtitle - > setText ( getName ( ) ) ;
2012-12-10 17:28:27 +03:00
}
void OptionsTab : : SelectedBox : : clickRight ( tribool down , bool previousState )
{
if ( down )
{
// cases when we do not need to display a message
if ( settings . castle = = - 2 & & CPlayerSettingsHelper : : type = = TOWN )
return ;
2013-12-23 18:59:37 +03:00
if ( settings . hero = = - 2 & & ! SEL - > current - > mapHeader - > players [ settings . color . getNum ( ) ] . hasCustomMainHero ( ) & & CPlayerSettingsHelper : : type = = HERO )
2012-12-10 17:28:27 +03:00
return ;
GH . pushInt ( new CPregameTooltipBox ( * this ) ) ;
}
2009-08-27 11:04:32 +03:00
}
2010-03-08 00:56:51 +02:00
CScenarioInfo : : CScenarioInfo ( const CMapHeader * mapHeader , const StartInfo * startInfo )
2009-08-27 11:04:32 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-09-24 19:14:53 +03:00
for ( auto it = startInfo - > playerInfos . cbegin ( ) ; it ! = startInfo - > playerInfos . cend ( ) ; + + it )
2009-10-06 04:14:00 +03:00
{
2012-12-02 15:21:44 +03:00
if ( it - > second . playerID )
2009-10-06 04:14:00 +03:00
{
2010-08-03 14:36:52 +03:00
playerColor = it - > first ;
2009-10-06 04:14:00 +03:00
}
}
2009-08-27 11:04:32 +03:00
pos . w = 762 ;
pos . h = 584 ;
center ( pos ) ;
2010-03-08 00:56:51 +02:00
assert ( LOCPLINT ) ;
2010-10-24 14:35:14 +03:00
sInfo = * LOCPLINT - > cb - > getStartInfo ( ) ;
assert ( ! SEL - > current ) ;
current = mapInfoFromGame ( ) ;
2010-03-08 00:56:51 +02:00
setPlayersFromGame ( ) ;
2009-08-27 11:04:32 +03:00
2010-10-24 14:35:14 +03:00
screenType = CMenuScreen : : scenarioInfo ;
card = new InfoCard ( ) ;
opt = new OptionsTab ( ) ;
opt - > recreate ( ) ;
2012-02-22 22:22:11 +03:00
card - > changeSelection ( current ) ;
2009-08-27 11:04:32 +03:00
2014-08-03 14:16:19 +03:00
card - > difficulty - > setSelected ( startInfo - > difficulty ) ;
2014-08-09 15:14:31 +03:00
back = new CButton ( Point ( 584 , 535 ) , " SCNRBACK.DEF " , CGI - > generaltexth - > zelp [ 105 ] , std : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) , SDLK_ESCAPE ) ;
2009-08-27 11:04:32 +03:00
}
CScenarioInfo : : ~ CScenarioInfo ( )
{
2010-10-24 14:35:14 +03:00
delete current ;
2009-08-27 11:04:32 +03:00
}
2010-02-13 18:26:47 +02:00
bool mapSorter : : operator ( ) ( const CMapInfo * aaa , const CMapInfo * bbb )
2010-02-08 16:38:06 +02:00
{
2012-11-11 15:23:31 +03:00
const CMapHeader * a = aaa - > mapHeader . get ( ) ,
* b = bbb - > mapHeader . get ( ) ;
2010-02-13 18:26:47 +02:00
if ( a & & b ) //if we are sorting scenarios
2010-02-08 16:38:06 +02:00
{
2010-02-13 18:26:47 +02:00
switch ( sortBy )
2010-02-08 16:38:06 +02:00
{
2010-02-13 18:26:47 +02:00
case _format : //by map format (RoE, WoG, etc)
return ( a - > version < b - > version ) ;
break ;
case _loscon : //by loss conditions
2013-12-29 14:27:38 +03:00
return ( a - > defeatMessage < b - > defeatMessage ) ;
2010-02-13 18:26:47 +02:00
break ;
case _playerAm : //by player amount
int playerAmntB , humenPlayersB , playerAmntA , humenPlayersA ;
playerAmntB = humenPlayersB = playerAmntA = humenPlayersA = 0 ;
for ( int i = 0 ; i < 8 ; i + + )
{
if ( a - > players [ i ] . canHumanPlay ) { playerAmntA + + ; humenPlayersA + + ; }
else if ( a - > players [ i ] . canComputerPlay ) { playerAmntA + + ; }
if ( b - > players [ i ] . canHumanPlay ) { playerAmntB + + ; humenPlayersB + + ; }
else if ( b - > players [ i ] . canComputerPlay ) { playerAmntB + + ; }
}
if ( playerAmntB ! = playerAmntA )
return ( playerAmntA < playerAmntB ) ;
else
return ( humenPlayersA < humenPlayersB ) ;
break ;
case _size : //by size of map
return ( a - > width < b - > width ) ;
break ;
case _viccon : //by victory conditions
2013-12-29 14:27:38 +03:00
return ( a - > victoryMessage < b - > victoryMessage ) ;
2010-02-13 18:26:47 +02:00
break ;
case _name : //by name
2012-02-29 04:31:48 +03:00
return boost : : ilexicographical_compare ( a - > name , b - > name ) ;
2014-06-10 23:58:07 +03:00
case _fileName : //by filename
return boost : : ilexicographical_compare ( aaa - > fileURI , bbb - > fileURI ) ;
2010-02-13 18:26:47 +02:00
default :
2012-02-29 04:31:48 +03:00
return boost : : ilexicographical_compare ( a - > name , b - > name ) ;
2010-02-08 16:38:06 +02:00
}
2010-02-13 18:26:47 +02:00
}
else //if we are sorting campaigns
{
2010-02-15 15:28:33 +02:00
switch ( sortBy )
{
case _numOfMaps : //by number of maps in campaign
2011-11-27 16:14:20 +03:00
return CGI - > generaltexth - > campaignRegionNames [ aaa - > campaignHeader - > mapVersion ] . size ( ) <
2010-02-15 15:28:33 +02:00
CGI - > generaltexth - > campaignRegionNames [ bbb - > campaignHeader - > mapVersion ] . size ( ) ;
break ;
case _name : //by name
2012-02-29 04:31:48 +03:00
return boost : : ilexicographical_compare ( aaa - > campaignHeader - > name , bbb - > campaignHeader - > name ) ;
2010-02-15 15:28:33 +02:00
default :
2012-02-29 04:31:48 +03:00
return boost : : ilexicographical_compare ( aaa - > campaignHeader - > name , bbb - > campaignHeader - > name ) ;
2010-02-15 15:28:33 +02:00
}
2010-02-08 16:38:06 +02:00
}
2010-02-15 08:54:57 +02:00
}
CMultiMode : : CMultiMode ( )
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-02-15 08:54:57 +02:00
bg = new CPicture ( " MUPOPUP.bmp " ) ;
bg - > convertToScreenBPP ( ) ; //so we could draw without problems
blitAt ( CPicture ( " MUMAP.bmp " ) , 16 , 77 , * bg ) ; //blit img
pos = bg - > center ( ) ; //center, window has size of bg graphic
2011-12-22 16:05:19 +03:00
bar = new CGStatusBar ( new CPicture ( Rect ( 7 , 465 , 440 , 18 ) , 0 ) ) ; //226, 472
txt = new CTextInput ( Rect ( 19 , 436 , 334 , 16 ) , * bg ) ;
2013-08-29 16:46:27 +03:00
txt - > setText ( settings [ " general " ] [ " playerName " ] . String ( ) ) ; //Player
2010-02-15 08:54:57 +02:00
2014-08-09 15:14:31 +03:00
btns [ 0 ] = new CButton ( Point ( 373 , 78 ) , " MUBHOT.DEF " , CGI - > generaltexth - > zelp [ 266 ] , std : : bind ( & CMultiMode : : openHotseat , this ) ) ;
btns [ 1 ] = new CButton ( Point ( 373 , 78 + 57 * 1 ) , " MUBHOST.DEF " , CButton : : tooltip ( " Host TCP/IP game " , " " ) , std : : bind ( & CMultiMode : : hostTCP , this ) ) ;
btns [ 2 ] = new CButton ( Point ( 373 , 78 + 57 * 2 ) , " MUBJOIN.DEF " , CButton : : tooltip ( " Join TCP/IP game " , " " ) , std : : bind ( & CMultiMode : : joinTCP , this ) ) ;
2014-08-03 14:16:19 +03:00
btns [ 6 ] = new CButton ( Point ( 373 , 424 ) , " MUBCANC.DEF " , CGI - > generaltexth - > zelp [ 288 ] , [ & ] { GH . popIntTotally ( this ) ; } , SDLK_ESCAPE ) ;
2010-02-15 08:54:57 +02:00
}
void CMultiMode : : openHotseat ( )
{
GH . pushInt ( new CHotSeatPlayers ( txt - > text ) ) ;
}
2010-09-03 21:42:54 +03:00
void CMultiMode : : hostTCP ( )
{
2012-01-12 18:23:00 +03:00
Settings name = settings . write [ " general " ] [ " playerName " ] ;
name - > String ( ) = txt - > text ;
2010-09-03 21:42:54 +03:00
GH . popIntTotally ( this ) ;
2010-10-24 14:35:14 +03:00
GH . pushInt ( new CSelectionScreen ( CMenuScreen : : newGame , CMenuScreen : : MULTI_NETWORK_HOST ) ) ;
2010-09-03 21:42:54 +03:00
}
void CMultiMode : : joinTCP ( )
{
2012-01-12 18:23:00 +03:00
Settings name = settings . write [ " general " ] [ " playerName " ] ;
name - > String ( ) = txt - > text ;
2014-03-07 16:21:09 +03:00
GH . pushInt ( new CSimpleJoinScreen ) ;
2010-09-03 21:42:54 +03:00
}
2010-02-15 08:54:57 +02:00
CHotSeatPlayers : : CHotSeatPlayers ( const std : : string & firstPlayer )
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-02-15 08:54:57 +02:00
bg = new CPicture ( " MUHOTSEA.bmp " ) ;
pos = bg - > center ( ) ; //center, window has size of bg graphic
2011-11-27 21:55:11 +03:00
std : : string text = CGI - > generaltexth - > allTexts [ 446 ] ;
boost : : replace_all ( text , " \t " , " \n " ) ;
2011-12-22 16:05:19 +03:00
Rect boxRect ( 25 , 20 , 315 , 50 ) ;
2012-11-11 15:23:31 +03:00
title = new CTextBox ( text , boxRect , 0 , FONT_BIG , CENTER , Colors : : WHITE ) ; //HOTSEAT Please enter names
2011-11-27 21:55:11 +03:00
2010-02-15 08:54:57 +02:00
for ( int i = 0 ; i < ARRAY_COUNT ( txt ) ; i + + )
2011-11-27 21:55:11 +03:00
{
2011-12-22 16:05:19 +03:00
txt [ i ] = new CTextInput ( Rect ( 60 , 85 + i * 30 , 280 , 16 ) , * bg ) ;
2014-08-04 21:33:59 +03:00
txt [ i ] - > cb + = std : : bind ( & CHotSeatPlayers : : onChange , this , _1 ) ;
2011-11-27 21:55:11 +03:00
}
2010-02-15 13:37:47 +02:00
2014-08-09 15:14:31 +03:00
ok = new CButton ( Point ( 95 , 338 ) , " MUBCHCK.DEF " , CGI - > generaltexth - > zelp [ 560 ] , std : : bind ( & CHotSeatPlayers : : enterSelectionScreen , this ) , SDLK_RETURN ) ;
cancel = new CButton ( Point ( 205 , 338 ) , " MUBCANC.DEF " , CGI - > generaltexth - > zelp [ 561 ] , std : : bind ( & CGuiHandler : : popIntTotally , std : : ref ( GH ) , this ) , SDLK_ESCAPE ) ;
2011-12-22 16:05:19 +03:00
bar = new CGStatusBar ( new CPicture ( Rect ( 7 , 381 , 348 , 18 ) , 0 ) ) ; //226, 472
2011-11-27 21:55:11 +03:00
2013-08-29 16:46:27 +03:00
txt [ 0 ] - > setText ( firstPlayer , true ) ;
2011-11-27 21:55:11 +03:00
txt [ 0 ] - > giveFocus ( ) ;
}
void CHotSeatPlayers : : onChange ( std : : string newText )
{
size_t namesCount = 0 ;
2013-06-29 16:05:48 +03:00
for ( auto & elem : txt )
if ( ! elem - > text . empty ( ) )
2011-11-27 21:55:11 +03:00
namesCount + + ;
ok - > block ( namesCount < 2 ) ;
2010-02-15 13:37:47 +02:00
}
void CHotSeatPlayers : : enterSelectionScreen ( )
{
2013-03-03 20:06:03 +03:00
std : : map < ui8 , std : : string > names ;
2010-10-24 14:35:14 +03:00
for ( int i = 0 , j = 1 ; i < ARRAY_COUNT ( txt ) ; i + + )
2010-02-15 13:37:47 +02:00
if ( txt [ i ] - > text . length ( ) )
2010-10-24 14:35:14 +03:00
names [ j + + ] = txt [ i ] - > text ;
2012-01-12 18:23:00 +03:00
Settings name = settings . write [ " general " ] [ " playerName " ] ;
name - > String ( ) = names . begin ( ) - > second ;
2010-02-15 13:37:47 +02:00
2010-09-03 21:42:54 +03:00
GH . popInts ( 2 ) ; //pop MP mode window and this
2010-10-24 14:35:14 +03:00
GH . pushInt ( new CSelectionScreen ( CMenuScreen : : newGame , CMenuScreen : : MULTI_HOT_SEAT , & names ) ) ;
2010-02-15 14:12:21 +02:00
}
2012-09-21 20:59:54 +03:00
void CBonusSelection : : init ( )
2010-02-15 14:12:21 +02:00
{
2012-09-21 20:59:54 +03:00
highlightedRegion = nullptr ;
ourHeader = nullptr ;
diffLb = nullptr ;
diffRb = nullptr ;
bonuses = nullptr ;
2013-12-16 21:39:56 +03:00
selectedMap = 0 ;
// Initialize start info
startInfo . mapname = ourCampaign - > camp - > header . filename ;
startInfo . mode = StartInfo : : CAMPAIGN ;
startInfo . campState = ourCampaign ;
startInfo . turnTime = 0 ;
2012-09-21 20:59:54 +03:00
2010-08-20 16:34:39 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-02-15 14:12:21 +02:00
static const std : : string bgNames [ ] = { " E1_BG.BMP " , " G2_BG.BMP " , " E2_BG.BMP " , " G1_BG.BMP " , " G3_BG.BMP " , " N1_BG.BMP " ,
" S1_BG.BMP " , " BR_BG.BMP " , " IS_BG.BMP " , " KR_BG.BMP " , " NI_BG.BMP " , " TA_BG.BMP " , " AR_BG.BMP " , " HS_BG.BMP " ,
" BB_BG.BMP " , " NB_BG.BMP " , " EL_BG.BMP " , " RN_BG.BMP " , " UA_BG.BMP " , " SP_BG.BMP " } ;
2011-11-27 16:14:20 +03:00
2010-02-16 19:28:56 +02:00
loadPositionsOfGraphics ( ) ;
2010-08-04 14:18:13 +03:00
background = BitmapHandler : : loadBitmap ( bgNames [ ourCampaign - > camp - > header . mapVersion ] ) ;
2012-05-18 20:35:46 +03:00
pos . h = background - > h ;
pos . w = background - > w ;
center ( ) ;
2010-02-15 14:12:21 +02:00
SDL_Surface * panel = BitmapHandler : : loadBitmap ( " CAMPBRF.BMP " ) ;
blitAt ( panel , 456 , 6 , background ) ;
2014-08-09 15:14:31 +03:00
startB = new CButton ( Point ( 475 , 536 ) , " CBBEGIB.DEF " , CButton : : tooltip ( ) , std : : bind ( & CBonusSelection : : startMap , this ) , SDLK_RETURN ) ;
restartB = new CButton ( Point ( 475 , 536 ) , " CBRESTB.DEF " , CButton : : tooltip ( ) , std : : bind ( & CBonusSelection : : restartMap , this ) , SDLK_RETURN ) ;
backB = new CButton ( Point ( 624 , 536 ) , " CBCANCB.DEF " , CButton : : tooltip ( ) , std : : bind ( & CBonusSelection : : goBack , this ) , SDLK_ESCAPE ) ;
2010-02-15 14:12:21 +02:00
//campaign name
2010-08-04 14:18:13 +03:00
if ( ourCampaign - > camp - > header . name . length ( ) )
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_BIG ] - > renderTextLeft ( background , ourCampaign - > camp - > header . name , Colors : : YELLOW , Point ( 481 , 28 ) ) ;
2011-11-27 16:14:20 +03:00
else
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_BIG ] - > renderTextLeft ( background , CGI - > generaltexth - > allTexts [ 508 ] , Colors : : YELLOW , Point ( 481 , 28 ) ) ;
2010-02-15 14:12:21 +02:00
//map size icon
2010-02-18 14:34:44 +02:00
sizes = CDefHandler : : giveDef ( " SCNRMPSZ.DEF " ) ;
2010-02-15 14:12:21 +02:00
//campaign description
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLeft ( background , CGI - > generaltexth - > allTexts [ 38 ] , Colors : : YELLOW , Point ( 481 , 63 ) ) ;
2011-11-27 16:14:20 +03:00
2013-12-16 21:39:56 +03:00
campaignDescription = new CTextBox ( ourCampaign - > camp - > header . description , Rect ( 480 , 86 , 286 , 117 ) , 1 ) ;
//campaignDescription->showAll(background);
2010-07-29 20:00:34 +03:00
//map description
2013-12-16 21:39:56 +03:00
mapDescription = new CTextBox ( " " , Rect ( 480 , 280 , 286 , 117 ) , 1 ) ;
2010-07-29 20:00:34 +03:00
//bonus choosing
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_MEDIUM ] - > renderTextLeft ( background , CGI - > generaltexth - > allTexts [ 71 ] , Colors : : WHITE , Point ( 511 , 432 ) ) ;
2014-10-10 13:36:35 +03:00
bonuses = new CToggleGroup ( std : : bind ( & CBonusSelection : : selectBonus , this , _1 ) ) ;
2010-02-15 14:12:21 +02:00
2010-02-18 14:34:44 +02:00
//set left part of window
2013-12-17 20:14:55 +03:00
bool isCurrentMapConquerable = ourCampaign - > currentMap & & ourCampaign - > camp - > conquerable ( * ourCampaign - > currentMap ) ;
for ( int g = 0 ; g < ourCampaign - > camp - > scenarios . size ( ) ; + + g )
2010-02-18 14:34:44 +02:00
{
2010-08-04 14:18:13 +03:00
if ( ourCampaign - > camp - > conquerable ( g ) )
2010-02-18 14:34:44 +02:00
{
regions . push_back ( new CRegion ( this , true , true , g ) ) ;
2010-08-04 14:18:13 +03:00
regions [ regions . size ( ) - 1 ] - > rclickText = ourCampaign - > camp - > scenarios [ g ] . regionText ;
2013-12-17 20:14:55 +03:00
if ( highlightedRegion = = nullptr )
2010-02-18 14:34:44 +02:00
{
2013-12-17 20:14:55 +03:00
if ( ! isCurrentMapConquerable | | ( isCurrentMapConquerable & & g = = * ourCampaign - > currentMap ) )
{
highlightedRegion = regions . back ( ) ;
selectMap ( g , true ) ;
}
2010-02-18 14:34:44 +02:00
}
}
2010-08-04 14:18:13 +03:00
else if ( ourCampaign - > camp - > scenarios [ g ] . conquered ) //display as striped
2010-02-18 14:34:44 +02:00
{
regions . push_back ( new CRegion ( this , false , false , g ) ) ;
2010-08-04 14:18:13 +03:00
regions [ regions . size ( ) - 1 ] - > rclickText = ourCampaign - > camp - > scenarios [ g ] . regionText ;
2010-02-18 14:34:44 +02:00
}
}
2010-02-15 14:12:21 +02:00
//allies / enemies
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLeft ( background , CGI - > generaltexth - > allTexts [ 390 ] + " : " , Colors : : WHITE , Point ( 486 , 407 ) ) ;
graphics - > fonts [ FONT_SMALL ] - > renderTextLeft ( background , CGI - > generaltexth - > allTexts [ 391 ] + " : " , Colors : : WHITE , Point ( 619 , 407 ) ) ;
2010-02-15 14:12:21 +02:00
SDL_FreeSurface ( panel ) ;
2010-02-16 19:28:56 +02:00
//difficulty
2011-04-26 16:30:29 +03:00
std : : vector < std : : string > difficulty ;
boost : : split ( difficulty , CGI - > generaltexth - > allTexts [ 492 ] , boost : : is_any_of ( " " ) ) ;
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_MEDIUM ] - > renderTextLeft ( background , difficulty . back ( ) , Colors : : WHITE , Point ( 689 , 432 ) ) ;
2011-11-27 16:14:20 +03:00
2011-04-26 16:30:29 +03:00
//difficulty pics
for ( int b = 0 ; b < ARRAY_COUNT ( diffPics ) ; + + b )
{
CDefEssential * cde = CDefHandler : : giveDefEss ( " GSPBUT " + boost : : lexical_cast < std : : string > ( b + 3 ) + " .DEF " ) ;
SDL_Surface * surfToDuplicate = cde - > ourImages [ 0 ] . bitmap ;
diffPics [ b ] = SDL_ConvertSurface ( surfToDuplicate , surfToDuplicate - > format ,
surfToDuplicate - > flags ) ;
2010-08-01 17:40:34 +03:00
2011-04-26 16:30:29 +03:00
delete cde ;
2010-08-01 17:40:34 +03:00
}
2011-11-27 16:14:20 +03:00
2010-08-01 17:40:34 +03:00
//difficulty selection buttons
2010-08-04 14:18:13 +03:00
if ( ourCampaign - > camp - > header . difficultyChoosenByPlayer )
2010-08-01 17:40:34 +03:00
{
2014-08-09 15:14:31 +03:00
diffLb = new CButton ( Point ( 694 , 508 ) , " SCNRBLF.DEF " , CButton : : tooltip ( ) , std : : bind ( & CBonusSelection : : decreaseDifficulty , this ) ) ;
diffRb = new CButton ( Point ( 738 , 508 ) , " SCNRBRT.DEF " , CButton : : tooltip ( ) , std : : bind ( & CBonusSelection : : increaseDifficulty , this ) ) ;
2010-08-01 17:40:34 +03:00
}
2010-07-31 16:55:05 +03:00
//load miniflags
sFlags = CDefHandler : : giveDef ( " ITGFLAGS.DEF " ) ;
2012-09-21 20:59:54 +03:00
}
2011-11-27 16:14:20 +03:00
2015-12-29 04:43:33 +02:00
CBonusSelection : : CBonusSelection ( std : : shared_ptr < CCampaignState > _ourCampaign ) : ourCampaign ( _ourCampaign )
2012-09-21 20:59:54 +03:00
{
init ( ) ;
}
2013-12-16 21:39:56 +03:00
CBonusSelection : : CBonusSelection ( const std : : string & campaignFName )
2012-09-21 20:59:54 +03:00
{
2015-12-29 04:43:33 +02:00
ourCampaign = std : : make_shared < CCampaignState > ( CCampaignHandler : : getCampaign ( campaignFName ) ) ;
2012-09-21 20:59:54 +03:00
init ( ) ;
2010-02-15 14:12:21 +02:00
}
CBonusSelection : : ~ CBonusSelection ( )
{
SDL_FreeSurface ( background ) ;
2010-02-18 14:34:44 +02:00
delete sizes ;
delete ourHeader ;
2010-07-31 16:55:05 +03:00
delete sFlags ;
2013-06-29 16:05:48 +03:00
for ( auto & elem : diffPics )
2010-08-01 17:40:34 +03:00
{
2013-06-29 16:05:48 +03:00
SDL_FreeSurface ( elem ) ;
2010-08-01 17:40:34 +03:00
}
2010-02-15 14:12:21 +02:00
}
void CBonusSelection : : goBack ( )
{
GH . popIntTotally ( this ) ;
}
2011-12-22 16:05:19 +03:00
void CBonusSelection : : showAll ( SDL_Surface * to )
2010-02-15 14:12:21 +02:00
{
blitAt ( background , pos . x , pos . y , to ) ;
2011-02-20 11:24:53 +02:00
CIntObject : : showAll ( to ) ;
2010-07-30 14:29:42 +03:00
show ( to ) ;
2012-05-18 20:35:46 +03:00
if ( pos . h ! = to - > h | | pos . w ! = to - > w )
2013-03-03 20:06:03 +03:00
CMessage : : drawBorder ( PlayerColor ( 1 ) , to , pos . w + 28 , pos . h + 30 , pos . x - 14 , pos . y - 15 ) ;
2010-02-15 15:28:33 +02:00
}
2010-02-16 19:28:56 +02:00
void CBonusSelection : : loadPositionsOfGraphics ( )
{
2012-08-02 14:03:26 +03:00
const JsonNode config ( ResourceID ( " config/campaign_regions.json " ) ) ;
2011-09-03 22:51:45 +03:00
int idx = 0 ;
2010-02-16 19:28:56 +02:00
2013-06-29 16:05:48 +03:00
for ( const JsonNode & campaign : config [ " campaign_regions " ] . Vector ( ) )
2010-02-16 19:28:56 +02:00
{
SCampPositions sc ;
2011-09-03 22:51:45 +03:00
sc . campPrefix = campaign [ " prefix " ] . String ( ) ;
sc . colorSuffixLength = campaign [ " color_suffix_length " ] . Float ( ) ;
2013-06-29 16:05:48 +03:00
for ( const JsonNode & desc : campaign [ " desc " ] . Vector ( ) )
2010-02-16 19:28:56 +02:00
{
SCampPositions : : SRegionDesc rd ;
2011-09-03 22:51:45 +03:00
rd . infix = desc [ " infix " ] . String ( ) ;
rd . xpos = desc [ " x " ] . Float ( ) ;
rd . ypos = desc [ " y " ] . Float ( ) ;
sc . regions . push_back ( rd ) ;
2010-02-16 19:28:56 +02:00
}
campDescriptions . push_back ( sc ) ;
2011-09-03 22:51:45 +03:00
idx + + ;
2010-02-16 19:28:56 +02:00
}
2011-09-03 22:51:45 +03:00
assert ( idx = = CGI - > generaltexth - > campaignMapNames . size ( ) ) ;
2010-02-16 19:28:56 +02:00
}
2013-12-16 21:39:56 +03:00
void CBonusSelection : : selectMap ( int mapNr , bool initialSelect )
2010-02-18 14:34:44 +02:00
{
2013-12-16 21:39:56 +03:00
if ( initialSelect | | selectedMap ! = mapNr )
2013-02-05 22:33:09 +03:00
{
2013-12-16 21:39:56 +03:00
// initialize restart / start button
if ( ! ourCampaign - > currentMap | | * ourCampaign - > currentMap ! = mapNr )
{
// draw start button
restartB - > disable ( ) ;
startB - > enable ( ) ;
2014-01-13 20:44:21 +03:00
if ( ! ourCampaign - > mapsConquered . empty ( ) )
backB - > block ( true ) ;
else
backB - > block ( false ) ;
2013-12-16 21:39:56 +03:00
}
else
{
// draw restart button
startB - > disable ( ) ;
restartB - > enable ( ) ;
2014-01-13 20:44:21 +03:00
backB - > block ( false ) ;
2013-12-16 21:39:56 +03:00
}
startInfo . difficulty = ourCampaign - > camp - > scenarios [ mapNr ] . difficulty ;
selectedMap = mapNr ;
selectedBonus = boost : : none ;
2010-02-18 14:34:44 +02:00
2013-12-31 02:09:58 +03:00
std : : string scenarioName = ourCampaign - > camp - > header . filename . substr ( 0 , ourCampaign - > camp - > header . filename . find ( ' . ' ) ) ;
boost : : to_lower ( scenarioName ) ;
scenarioName + = ' : ' + boost : : lexical_cast < std : : string > ( selectedMap ) ;
2013-02-05 22:33:09 +03:00
//get header
delete ourHeader ;
2013-12-16 21:39:56 +03:00
std : : string & headerStr = ourCampaign - > camp - > mapPieces . find ( mapNr ) - > second ;
2013-02-05 22:33:09 +03:00
auto buffer = reinterpret_cast < const ui8 * > ( headerStr . data ( ) ) ;
2013-12-31 02:09:58 +03:00
ourHeader = CMapService : : loadMapHeader ( buffer , headerStr . size ( ) , scenarioName ) . release ( ) ;
2011-11-27 16:14:20 +03:00
2013-03-03 20:06:03 +03:00
std : : map < ui8 , std : : string > names ;
2013-02-05 22:33:09 +03:00
names [ 1 ] = settings [ " general " ] [ " playerName " ] . String ( ) ;
2013-12-16 21:39:56 +03:00
updateStartInfo ( ourCampaign - > camp - > header . filename , startInfo , ourHeader , names ) ;
2010-08-04 14:18:13 +03:00
2013-12-16 21:39:56 +03:00
mapDescription - > setText ( ourHeader - > description ) ;
2010-07-29 20:00:34 +03:00
2013-02-05 22:33:09 +03:00
updateBonusSelection ( ) ;
2013-12-16 21:39:56 +03:00
GH . totalRedraw ( ) ;
2013-02-05 22:33:09 +03:00
}
2010-02-18 14:34:44 +02:00
}
2011-12-22 16:05:19 +03:00
void CBonusSelection : : show ( SDL_Surface * to )
2010-02-18 14:34:44 +02:00
{
2011-02-20 11:24:53 +02:00
//blitAt(background, pos.x, pos.y, to);
2010-02-18 14:34:44 +02:00
//map name
2010-07-29 20:00:34 +03:00
std : : string mapName = ourHeader - > name ;
2010-02-18 14:34:44 +02:00
if ( mapName . length ( ) )
2012-11-11 15:23:31 +03:00
printAtLoc ( mapName , 481 , 219 , FONT_BIG , Colors : : YELLOW , to ) ;
2011-11-27 16:14:20 +03:00
else
2012-11-11 15:23:31 +03:00
printAtLoc ( " Unnamed " , 481 , 219 , FONT_BIG , Colors : : YELLOW , to ) ;
2010-02-18 14:34:44 +02:00
//map description
2012-11-11 15:23:31 +03:00
printAtLoc ( CGI - > generaltexth - > allTexts [ 496 ] , 481 , 253 , FONT_SMALL , Colors : : YELLOW , to ) ;
2010-02-18 14:34:44 +02:00
2013-12-16 21:39:56 +03:00
mapDescription - > showAll ( to ) ; //showAll because CTextBox has no show()
2010-02-18 14:34:44 +02:00
//map size icon
int temp ;
switch ( ourHeader - > width )
{
case 36 :
temp = 0 ;
break ;
case 72 :
temp = 1 ;
break ;
case 108 :
temp = 2 ;
break ;
case 144 :
temp = 3 ;
break ;
default :
temp = 4 ;
break ;
}
blitAtLoc ( sizes - > ourImages [ temp ] . bitmap , 735 , 26 , to ) ;
2010-07-31 16:55:05 +03:00
//flags
2012-12-19 20:24:53 +03:00
int fx = 496 + graphics - > fonts [ FONT_SMALL ] - > getStringWidth ( CGI - > generaltexth - > allTexts [ 390 ] ) ;
int ex = 629 + graphics - > fonts [ FONT_SMALL ] - > getStringWidth ( CGI - > generaltexth - > allTexts [ 391 ] ) ;
2013-03-03 20:06:03 +03:00
TeamID myT ;
myT = ourHeader - > players [ playerColor . getNum ( ) ] . team ;
2013-12-16 21:39:56 +03:00
for ( auto i = startInfo . playerInfos . cbegin ( ) ; i ! = startInfo . playerInfos . cend ( ) ; i + + )
2010-07-31 16:55:05 +03:00
{
2013-03-03 20:06:03 +03:00
int * myx = ( ( i - > first = = playerColor | | ourHeader - > players [ i - > first . getNum ( ) ] . team = = myT ) ? & fx : & ex ) ;
2013-08-30 16:19:08 +03:00
blitAtLoc ( sFlags - > ourImages [ i - > first . getNum ( ) ] . bitmap , * myx , 405 , to ) ;
2013-03-03 20:06:03 +03:00
* myx + = sFlags - > ourImages [ i - > first . getNum ( ) ] . bitmap - > w ;
2010-07-31 16:55:05 +03:00
}
2010-08-01 17:40:34 +03:00
//difficulty
2013-12-16 21:39:56 +03:00
blitAtLoc ( diffPics [ startInfo . difficulty ] , 709 , 455 , to ) ;
2010-08-01 17:40:34 +03:00
2010-02-18 14:34:44 +02:00
CIntObject : : show ( to ) ;
}
2010-02-23 17:39:31 +02:00
void CBonusSelection : : updateBonusSelection ( )
{
2012-05-18 20:35:46 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-02-23 17:39:31 +02:00
//graphics:
//spell - SPELLBON.DEF
//monster - TWCRPORT.DEF
2010-07-31 16:55:05 +03:00
//building - BO*.BMP graphics
2010-02-23 17:39:31 +02:00
//artifact - ARTIFBON.DEF
//spell scroll - SPELLBON.DEF
//prim skill - PSKILBON.DEF
//sec skill - SSKILBON.DEF
//resource - BORES.DEF
2011-03-20 00:27:05 +02:00
//player - CREST58.DEF
//hero - PORTRAITSLARGE (HPL###.BMPs)
2013-12-16 21:39:56 +03:00
const CCampaignScenario & scenario = ourCampaign - > camp - > scenarios [ selectedMap ] ;
2010-07-29 20:00:34 +03:00
const std : : vector < CScenarioTravel : : STravelBonus > & bonDescs = scenario . travelOptions . bonusesToChoose ;
2010-02-23 17:39:31 +02:00
2012-09-26 21:10:29 +03:00
updateStartButtonState ( - 1 ) ;
2014-08-03 14:16:19 +03:00
delete bonuses ;
2014-10-10 13:36:35 +03:00
bonuses = new CToggleGroup ( std : : bind ( & CBonusSelection : : selectBonus , this , _1 ) ) ;
2011-03-20 00:27:05 +02:00
2013-12-16 21:39:56 +03:00
static const char * bonusPics [ ] = { " SPELLBON.DEF " , " TWCRPORT.DEF " , " " , " ARTIFBON.DEF " , " SPELLBON.DEF " ,
" PSKILBON.DEF " , " SSKILBON.DEF " , " BORES.DEF " , " PORTRAITSLARGE " , " PORTRAITSLARGE " } ;
2010-02-23 17:39:31 +02:00
2013-12-16 21:39:56 +03:00
for ( int i = 0 ; i < bonDescs . size ( ) ; i + + )
{
std : : string picName = bonusPics [ bonDescs [ i ] . type ] ;
size_t picNumber = bonDescs [ i ] . info2 ;
2010-07-29 20:00:34 +03:00
2013-12-16 21:39:56 +03:00
std : : string desc ;
switch ( bonDescs [ i ] . type )
{
case CScenarioTravel : : STravelBonus : : SPELL :
desc = CGI - > generaltexth - > allTexts [ 715 ] ;
2014-03-07 16:21:09 +03:00
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > spellh - > objects [ bonDescs [ i ] . info2 ] - > name ) ;
2013-12-16 21:39:56 +03:00
break ;
case CScenarioTravel : : STravelBonus : : MONSTER :
picNumber = bonDescs [ i ] . info2 + 2 ;
desc = CGI - > generaltexth - > allTexts [ 717 ] ;
boost : : algorithm : : replace_first ( desc , " %d " , boost : : lexical_cast < std : : string > ( bonDescs [ i ] . info3 ) ) ;
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > creh - > creatures [ bonDescs [ i ] . info2 ] - > namePl ) ;
break ;
case CScenarioTravel : : STravelBonus : : BUILDING :
2010-07-29 20:00:34 +03:00
{
2013-12-16 21:39:56 +03:00
int faction = - 1 ;
for ( auto & elem : startInfo . playerInfos )
2010-07-30 17:26:37 +03:00
{
2013-12-16 21:39:56 +03:00
if ( elem . second . playerID )
2010-08-02 17:29:30 +03:00
{
2013-12-16 21:39:56 +03:00
faction = elem . second . castle ;
break ;
2010-08-02 17:29:30 +03:00
}
2011-03-20 00:27:05 +02:00
2010-07-30 17:26:37 +03:00
}
2013-12-16 21:39:56 +03:00
assert ( faction ! = - 1 ) ;
BuildingID buildID = CBuildingHandler : : campToERMU ( bonDescs [ i ] . info1 , faction , std : : set < BuildingID > ( ) ) ;
picName = graphics - > ERMUtoPicture [ faction ] [ buildID ] ;
picNumber = - 1 ;
if ( vstd : : contains ( CGI - > townh - > factions [ faction ] - > town - > buildings , buildID ) )
desc = CGI - > townh - > factions [ faction ] - > town - > buildings . find ( buildID ) - > second - > Name ( ) ;
}
break ;
case CScenarioTravel : : STravelBonus : : ARTIFACT :
desc = CGI - > generaltexth - > allTexts [ 715 ] ;
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > arth - > artifacts [ bonDescs [ i ] . info2 ] - > Name ( ) ) ;
break ;
case CScenarioTravel : : STravelBonus : : SPELL_SCROLL :
desc = CGI - > generaltexth - > allTexts [ 716 ] ;
2014-03-07 16:21:09 +03:00
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > spellh - > objects [ bonDescs [ i ] . info2 ] - > name ) ;
2013-12-16 21:39:56 +03:00
break ;
case CScenarioTravel : : STravelBonus : : PRIMARY_SKILL :
{
int leadingSkill = - 1 ;
std : : vector < std : : pair < int , int > > toPrint ; //primary skills to be listed <num, val>
const ui8 * ptr = reinterpret_cast < const ui8 * > ( & bonDescs [ i ] . info2 ) ;
for ( int g = 0 ; g < GameConstants : : PRIMARY_SKILLS ; + + g )
2010-07-29 20:00:34 +03:00
{
2013-12-16 21:39:56 +03:00
if ( leadingSkill = = - 1 | | ptr [ g ] > ptr [ leadingSkill ] )
2010-07-29 20:00:34 +03:00
{
2013-12-16 21:39:56 +03:00
leadingSkill = g ;
2010-07-29 20:00:34 +03:00
}
2013-12-16 21:39:56 +03:00
if ( ptr [ g ] ! = 0 )
2010-07-29 20:00:34 +03:00
{
2013-12-16 21:39:56 +03:00
toPrint . push_back ( std : : make_pair ( g , ptr [ g ] ) ) ;
2010-07-29 20:00:34 +03:00
}
}
2013-12-16 21:39:56 +03:00
picNumber = leadingSkill ;
desc = CGI - > generaltexth - > allTexts [ 715 ] ;
2010-07-29 20:00:34 +03:00
2013-12-16 21:39:56 +03:00
std : : string substitute ; //text to be printed instead of %s
for ( int v = 0 ; v < toPrint . size ( ) ; + + v )
2010-07-30 14:29:42 +03:00
{
2013-12-16 21:39:56 +03:00
substitute + = boost : : lexical_cast < std : : string > ( toPrint [ v ] . second ) ;
substitute + = " " + CGI - > generaltexth - > primarySkillNames [ toPrint [ v ] . first ] ;
if ( v ! = toPrint . size ( ) - 1 )
2010-07-30 14:29:42 +03:00
{
2013-12-16 21:39:56 +03:00
substitute + = " , " ;
2010-07-30 14:29:42 +03:00
}
2013-02-09 22:19:14 +03:00
}
2010-08-28 17:52:20 +03:00
2013-12-16 21:39:56 +03:00
boost : : algorithm : : replace_first ( desc , " %s " , substitute ) ;
2010-07-29 20:00:34 +03:00
break ;
2013-12-16 21:39:56 +03:00
}
case CScenarioTravel : : STravelBonus : : SECONDARY_SKILL :
desc = CGI - > generaltexth - > allTexts [ 718 ] ;
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > generaltexth - > levels [ bonDescs [ i ] . info3 - 1 ] ) ; //skill level
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > generaltexth - > skillName [ bonDescs [ i ] . info2 ] ) ; //skill name
picNumber = bonDescs [ i ] . info2 * 3 + bonDescs [ i ] . info3 - 1 ;
2012-11-03 22:31:16 +03:00
2013-12-16 21:39:56 +03:00
break ;
case CScenarioTravel : : STravelBonus : : RESOURCE :
{
int serialResID = 0 ;
switch ( bonDescs [ i ] . info1 )
{
case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 :
serialResID = bonDescs [ i ] . info1 ;
break ;
case 0xFD : //wood + ore
serialResID = 7 ;
break ;
case 0xFE : //rare resources
serialResID = 8 ;
break ;
}
picNumber = serialResID ;
2010-08-28 17:52:20 +03:00
2013-12-16 21:39:56 +03:00
desc = CGI - > generaltexth - > allTexts [ 717 ] ;
boost : : algorithm : : replace_first ( desc , " %d " , boost : : lexical_cast < std : : string > ( bonDescs [ i ] . info2 ) ) ;
std : : string replacement ;
if ( serialResID < = 6 )
2010-08-28 17:52:20 +03:00
{
2013-12-16 21:39:56 +03:00
replacement = CGI - > generaltexth - > restypes [ serialResID ] ;
2010-08-28 17:52:20 +03:00
}
else
{
2013-12-16 21:39:56 +03:00
replacement = CGI - > generaltexth - > allTexts [ 714 + serialResID ] ;
2010-08-28 17:52:20 +03:00
}
2013-12-16 21:39:56 +03:00
boost : : algorithm : : replace_first ( desc , " %s " , replacement ) ;
}
break ;
2013-12-20 16:07:58 +03:00
case CScenarioTravel : : STravelBonus : : HEROES_FROM_PREVIOUS_SCENARIO :
2013-12-16 21:39:56 +03:00
{
auto superhero = ourCampaign - > camp - > scenarios [ bonDescs [ i ] . info2 ] . strongestHero ( PlayerColor ( bonDescs [ i ] . info1 ) ) ;
2014-03-23 15:59:03 +03:00
if ( ! superhero ) logGlobal - > warnStream ( ) < < " No superhero! How could it be transferred? " ;
2013-12-16 21:39:56 +03:00
picNumber = superhero ? superhero - > portrait : 0 ;
desc = CGI - > generaltexth - > allTexts [ 719 ] ;
boost : : algorithm : : replace_first ( desc , " %s " , ourCampaign - > camp - > scenarios [ bonDescs [ i ] . info2 ] . scenarioName ) ; //scenario
2010-07-29 20:00:34 +03:00
}
2013-12-16 21:39:56 +03:00
break ;
case CScenarioTravel : : STravelBonus : : HERO :
2010-07-29 20:00:34 +03:00
2013-12-16 21:39:56 +03:00
desc = CGI - > generaltexth - > allTexts [ 718 ] ;
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > generaltexth - > capColors [ bonDescs [ i ] . info1 ] ) ; //hero's color
2011-02-20 11:24:53 +02:00
2013-12-16 21:39:56 +03:00
if ( bonDescs [ i ] . info2 = = 0xFFFF )
{
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > generaltexth - > allTexts [ 101 ] ) ; //hero's name
picNumber = - 1 ;
picName = " CBONN1A3.BMP " ;
}
else
{
boost : : algorithm : : replace_first ( desc , " %s " , CGI - > heroh - > heroes [ bonDescs [ i ] . info2 ] - > name ) ; //hero's name
}
break ;
2010-02-23 17:39:31 +02:00
}
2013-12-16 21:39:56 +03:00
2014-08-03 14:16:19 +03:00
CToggleButton * bonusButton = new CToggleButton ( Point ( 475 + i * 68 , 455 ) , " " , CButton : : tooltip ( desc , desc ) ) ;
2013-12-16 21:39:56 +03:00
if ( picNumber ! = - 1 )
picName + = " : " + boost : : lexical_cast < std : : string > ( picNumber ) ;
auto anim = new CAnimation ( ) ;
anim - > setCustom ( picName , 0 ) ;
bonusButton - > setImage ( anim ) ;
const SDL_Color brightYellow = { 242 , 226 , 110 , 0 } ;
bonusButton - > borderColor = brightYellow ;
2014-08-03 14:16:19 +03:00
bonuses - > addToggle ( i , bonusButton ) ;
2013-12-16 21:39:56 +03:00
}
// set bonus if already chosen
if ( vstd : : contains ( ourCampaign - > chosenCampaignBonuses , selectedMap ) )
{
2014-08-03 14:16:19 +03:00
bonuses - > setSelected ( ourCampaign - > chosenCampaignBonuses [ selectedMap ] ) ;
2013-12-16 21:39:56 +03:00
}
2010-02-23 17:39:31 +02:00
}
2013-12-16 21:39:56 +03:00
void CBonusSelection : : updateCampaignState ( )
2010-05-08 21:56:38 +03:00
{
2013-12-16 21:39:56 +03:00
ourCampaign - > currentMap = selectedMap ;
2014-02-09 00:05:24 +03:00
if ( selectedBonus )
ourCampaign - > chosenCampaignBonuses [ selectedMap ] = * selectedBonus ;
2013-12-16 21:39:56 +03:00
}
2012-11-03 22:31:16 +03:00
2013-12-16 21:39:56 +03:00
void CBonusSelection : : startMap ( )
{
auto si = new StartInfo ( startInfo ) ;
2013-12-17 15:12:25 +03:00
auto showPrologVideo = [ = ] ( )
2013-02-21 00:01:18 +03:00
{
2013-12-17 15:12:25 +03:00
auto exitCb = [ = ] ( )
{
logGlobal - > infoStream ( ) < < " Starting scenario " < < selectedMap ;
2014-08-04 21:33:59 +03:00
CGP - > showLoadingScreen ( std : : bind ( & startGame , si , ( CConnection * ) nullptr ) ) ;
2013-12-17 15:12:25 +03:00
} ;
const CCampaignScenario & scenario = ourCampaign - > camp - > scenarios [ selectedMap ] ;
if ( scenario . prolog . hasPrologEpilog )
{
GH . pushInt ( new CPrologEpilogVideo ( scenario . prolog , exitCb ) ) ;
}
else
{
exitCb ( ) ;
}
2013-02-21 00:01:18 +03:00
} ;
2013-12-17 15:12:25 +03:00
if ( LOCPLINT ) // we're currently ingame, so ask for starting new map and end game
2010-08-28 17:52:20 +03:00
{
2013-12-17 15:12:25 +03:00
GH . popInt ( this ) ;
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 67 ] , [ = ]
{
updateCampaignState ( ) ;
endGame ( ) ;
GH . curInt = CGPreGame : : create ( ) ;
showPrologVideo ( ) ;
} , 0 ) ;
2010-08-28 17:52:20 +03:00
}
2012-12-17 21:01:17 +03:00
else
2013-02-21 00:01:18 +03:00
{
2013-12-17 15:12:25 +03:00
updateCampaignState ( ) ;
showPrologVideo ( ) ;
2013-02-21 00:01:18 +03:00
}
2010-05-08 21:56:38 +03:00
}
2013-12-16 21:39:56 +03:00
void CBonusSelection : : restartMap ( )
{
2013-12-17 15:12:25 +03:00
GH . popInt ( this ) ;
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 67 ] , [ = ]
2013-12-16 21:39:56 +03:00
{
2013-12-17 15:12:25 +03:00
updateCampaignState ( ) ;
auto si = new StartInfo ( startInfo ) ;
2013-12-16 21:39:56 +03:00
SDL_Event event ;
event . type = SDL_USEREVENT ;
event . user . code = PREPARE_RESTART_CAMPAIGN ;
event . user . data1 = si ;
SDL_PushEvent ( & event ) ;
} , 0 ) ;
}
void CBonusSelection : : selectBonus ( int id )
2010-07-31 16:55:05 +03:00
{
2011-04-26 16:30:29 +03:00
// Total redraw is needed because the border around the bonus images
// have to be undrawn/drawn.
2013-12-16 21:39:56 +03:00
if ( ! selectedBonus | | * selectedBonus ! = id )
2011-04-26 16:30:29 +03:00
{
2013-12-16 21:39:56 +03:00
selectedBonus = id ;
2011-04-26 16:30:29 +03:00
GH . totalRedraw ( ) ;
2012-09-26 21:10:29 +03:00
updateStartButtonState ( id ) ;
2011-04-26 16:30:29 +03:00
}
2011-11-27 16:14:20 +03:00
2013-12-16 21:39:56 +03:00
const CCampaignScenario & scenario = ourCampaign - > camp - > scenarios [ selectedMap ] ;
2010-09-04 17:49:15 +03:00
const std : : vector < CScenarioTravel : : STravelBonus > & bonDescs = scenario . travelOptions . bonusesToChoose ;
2012-09-23 14:26:26 +03:00
if ( bonDescs [ id ] . type = = CScenarioTravel : : STravelBonus : : HERO )
2010-09-04 17:49:15 +03:00
{
2013-03-03 20:06:03 +03:00
std : : map < ui8 , std : : string > names ;
2012-09-23 14:26:26 +03:00
names [ 1 ] = settings [ " general " ] [ " playerName " ] . String ( ) ;
2013-12-16 21:39:56 +03:00
for ( auto & elem : startInfo . playerInfos )
2012-09-23 14:26:26 +03:00
{
2013-06-29 16:05:48 +03:00
if ( elem . first = = PlayerColor ( bonDescs [ id ] . info1 ) )
: : setPlayer ( elem . second , 1 , names ) ;
2012-09-23 14:26:26 +03:00
else
2013-06-29 16:05:48 +03:00
: : setPlayer ( elem . second , 0 , names ) ;
2012-09-23 14:26:26 +03:00
}
2010-09-04 17:49:15 +03:00
}
2010-07-31 16:55:05 +03:00
}
2013-12-16 21:39:56 +03:00
void CBonusSelection : : increaseDifficulty ( )
2010-08-01 17:40:34 +03:00
{
2013-12-16 21:39:56 +03:00
startInfo . difficulty = std : : min ( startInfo . difficulty + 1 , 4 ) ;
2010-08-01 17:40:34 +03:00
}
2013-12-16 21:39:56 +03:00
void CBonusSelection : : decreaseDifficulty ( )
{
startInfo . difficulty = std : : max ( startInfo . difficulty - 1 , 0 ) ;
}
void CBonusSelection : : updateStartButtonState ( int selected /*= -1*/ )
2012-09-26 21:10:29 +03:00
{
if ( selected = = - 1 )
2013-12-16 21:39:56 +03:00
{
2014-08-03 14:16:19 +03:00
startB - > block ( ourCampaign - > camp - > scenarios [ selectedMap ] . travelOptions . bonusesToChoose . size ( ) ) ;
2013-12-16 21:39:56 +03:00
}
2014-08-03 14:16:19 +03:00
else if ( startB - > isBlocked ( ) )
2013-12-16 21:39:56 +03:00
{
2014-08-03 14:16:19 +03:00
startB - > block ( false ) ;
2013-12-16 21:39:56 +03:00
}
2012-09-26 21:10:29 +03:00
}
2010-02-16 19:28:56 +02:00
CBonusSelection : : CRegion : : CRegion ( CBonusSelection * _owner , bool _accessible , bool _selectable , int _myNumber )
: owner ( _owner ) , accessible ( _accessible ) , selectable ( _selectable ) , myNumber ( _myNumber )
{
OBJ_CONSTRUCTION ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK ) ;
2010-02-18 14:34:44 +02:00
2010-02-16 19:28:56 +02:00
static const std : : string colors [ 2 ] [ 8 ] = {
{ " R " , " B " , " N " , " G " , " O " , " V " , " T " , " P " } ,
{ " Re " , " Bl " , " Br " , " Gr " , " Or " , " Vi " , " Te " , " Pi " } } ;
2010-08-04 14:18:13 +03:00
const SCampPositions & campDsc = owner - > campDescriptions [ owner - > ourCampaign - > camp - > header . mapVersion ] ;
2010-02-16 19:28:56 +02:00
const SCampPositions : : SRegionDesc & desc = campDsc . regions [ myNumber ] ;
2012-05-18 20:35:46 +03:00
pos . x + = desc . xpos ;
pos . y + = desc . ypos ;
2010-02-16 19:28:56 +02:00
//loading of graphics
std : : string prefix = campDsc . campPrefix + desc . infix + " _ " ;
2010-08-04 14:18:13 +03:00
std : : string suffix = colors [ campDsc . colorSuffixLength - 1 ] [ owner - > ourCampaign - > camp - > scenarios [ myNumber ] . regionColor ] ;
2010-02-16 19:28:56 +02:00
static const std : : string infix [ ] = { " En " , " Se " , " Co " } ;
for ( int g = 0 ; g < ARRAY_COUNT ( infix ) ; g + + )
{
graphics [ g ] = BitmapHandler : : loadBitmap ( prefix + infix [ g ] + suffix + " .BMP " ) ;
}
2010-02-18 14:34:44 +02:00
pos . w = graphics [ 0 ] - > w ;
pos . h = graphics [ 0 ] - > h ;
2010-02-16 19:28:56 +02:00
}
CBonusSelection : : CRegion : : ~ CRegion ( )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : graphics )
2010-02-16 19:28:56 +02:00
{
2013-06-29 16:05:48 +03:00
SDL_FreeSurface ( elem ) ;
2010-02-16 19:28:56 +02:00
}
}
void CBonusSelection : : CRegion : : clickLeft ( tribool down , bool previousState )
{
//select if selectable & clicked inside our graphic
2010-02-21 17:03:30 +02:00
if ( indeterminate ( down ) )
{
return ;
}
2010-02-18 14:34:44 +02:00
if ( ! down & & selectable & & ! CSDL_Ext : : isTransparent ( graphics [ 0 ] , GH . current - > motion . x - pos . x , GH . current - > motion . y - pos . y ) )
2010-02-16 19:28:56 +02:00
{
2013-02-05 22:33:09 +03:00
owner - > selectMap ( myNumber , false ) ;
2010-02-18 14:34:44 +02:00
owner - > highlightedRegion = this ;
2011-03-20 00:27:05 +02:00
parent - > showAll ( screen ) ;
2010-02-16 19:28:56 +02:00
}
}
void CBonusSelection : : CRegion : : clickRight ( tribool down , bool previousState )
{
//show r-click text
2010-02-18 14:34:44 +02:00
if ( down & & ! CSDL_Ext : : isTransparent ( graphics [ 0 ] , GH . current - > motion . x - pos . x , GH . current - > motion . y - pos . y ) & &
rclickText . size ( ) )
{
2010-03-21 00:17:19 +02:00
CRClickPopup : : createAndPush ( rclickText ) ;
2010-02-18 14:34:44 +02:00
}
2010-02-16 19:28:56 +02:00
}
2011-12-22 16:05:19 +03:00
void CBonusSelection : : CRegion : : show ( SDL_Surface * to )
2010-02-16 19:28:56 +02:00
{
2010-11-15 17:15:00 +02:00
//const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber];
2010-02-16 19:28:56 +02:00
if ( ! accessible )
{
//show as striped
2012-05-18 20:35:46 +03:00
blitAtLoc ( graphics [ 2 ] , 0 , 0 , to ) ;
2010-02-16 19:28:56 +02:00
}
else if ( this = = owner - > highlightedRegion )
{
//show as selected
2012-05-18 20:35:46 +03:00
blitAtLoc ( graphics [ 1 ] , 0 , 0 , to ) ;
2010-02-16 19:28:56 +02:00
}
else
{
//show as not selected selected
2012-05-18 20:35:46 +03:00
blitAtLoc ( graphics [ 0 ] , 0 , 0 , to ) ;
2010-02-16 19:28:56 +02:00
}
}
2010-03-08 00:56:51 +02:00
2010-05-27 00:59:58 +03:00
CSavingScreen : : CSavingScreen ( bool hotseat )
2010-10-24 14:35:14 +03:00
: CSelectionScreen ( CMenuScreen : : saveGame , hotseat ? CMenuScreen : : MULTI_HOT_SEAT : CMenuScreen : : SINGLE_PLAYER )
2010-03-08 00:56:51 +02:00
{
ourGame = mapInfoFromGame ( ) ;
sInfo = * LOCPLINT - > cb - > getStartInfo ( ) ;
setPlayersFromGame ( ) ;
}
CSavingScreen : : ~ CSavingScreen ( )
{
}
2010-07-20 13:46:38 +03:00
2013-06-26 14:18:27 +03:00
ISelectionScreenInfo : : ISelectionScreenInfo ( const std : : map < ui8 , std : : string > * Names /*= nullptr*/ )
2010-10-24 14:35:14 +03:00
{
multiPlayer = CMenuScreen : : SINGLE_PLAYER ;
assert ( ! SEL ) ;
SEL = this ;
2013-06-26 14:18:27 +03:00
current = nullptr ;
2010-10-24 14:35:14 +03:00
2013-11-03 15:51:25 +03:00
if ( Names & & ! Names - > empty ( ) ) //if have custom set of player names - use it
2010-10-24 14:35:14 +03:00
playerNames = * Names ;
else
2012-01-12 18:23:00 +03:00
playerNames [ 1 ] = settings [ " general " ] [ " playerName " ] . String ( ) ; //by default we have only one player and his name is "Player" (or whatever the last used name was)
2010-10-24 14:35:14 +03:00
}
ISelectionScreenInfo : : ~ ISelectionScreenInfo ( )
{
assert ( SEL = = this ) ;
2013-06-26 14:18:27 +03:00
SEL = nullptr ;
2010-10-24 14:35:14 +03:00
}
void ISelectionScreenInfo : : updateStartInfo ( std : : string filename , StartInfo & sInfo , const CMapHeader * mapHeader )
{
2010-10-30 17:53:23 +03:00
: : updateStartInfo ( filename , sInfo , mapHeader , playerNames ) ;
2010-10-24 14:35:14 +03:00
}
2013-03-03 20:06:03 +03:00
void ISelectionScreenInfo : : setPlayer ( PlayerSettings & pset , ui8 player )
2010-10-24 14:35:14 +03:00
{
2010-10-30 17:53:23 +03:00
: : setPlayer ( pset , player , playerNames ) ;
2010-10-24 14:35:14 +03:00
}
2013-03-03 20:06:03 +03:00
ui8 ISelectionScreenInfo : : getIdOfFirstUnallocatedPlayer ( )
2010-10-24 14:35:14 +03:00
{
2012-09-24 19:14:53 +03:00
for ( auto i = playerNames . cbegin ( ) ; i ! = playerNames . cend ( ) ; i + + )
2010-10-24 14:35:14 +03:00
if ( ! sInfo . getPlayersSettings ( i - > first ) ) //
return i - > first ;
return 0 ;
}
bool ISelectionScreenInfo : : isGuest ( ) const
{
return multiPlayer = = CMenuScreen : : MULTI_NETWORK_GUEST ;
}
bool ISelectionScreenInfo : : isHost ( ) const
{
return multiPlayer = = CMenuScreen : : MULTI_NETWORK_HOST ;
}
2010-09-03 21:42:54 +03:00
void ChatMessage : : apply ( CSelectionScreen * selScreen )
{
2010-10-24 14:35:14 +03:00
selScreen - > card - > chat - > addNewMessage ( playerName + " : " + message ) ;
GH . totalRedraw ( ) ;
}
void QuitMenuWithoutStarting : : apply ( CSelectionScreen * selScreen )
{
if ( ! selScreen - > ongoingClosing )
{
* selScreen - > serv < < this ; //resend to confirm
GH . popIntTotally ( selScreen ) ; //will wait with deleting us before this thread ends
}
2010-09-03 21:42:54 +03:00
2011-12-14 00:23:17 +03:00
vstd : : clear_pointer ( selScreen - > serv ) ;
2010-09-03 21:42:54 +03:00
}
2010-10-24 14:35:14 +03:00
void PlayerJoined : : apply ( CSelectionScreen * selScreen )
{
//assert(SEL->playerNames.size() == connectionID); //temporary, TODO when player exits
SEL - > playerNames [ connectionID ] = playerName ;
2011-11-27 16:14:20 +03:00
2010-10-24 14:35:14 +03:00
//put new player in first slot with AI
2013-06-29 16:05:48 +03:00
for ( auto & elem : SEL - > sInfo . playerInfos )
2010-10-24 14:35:14 +03:00
{
2015-03-13 14:05:12 +02:00
if ( ! elem . second . playerID & & ! elem . second . compOnly )
2010-10-24 14:35:14 +03:00
{
2013-06-29 16:05:48 +03:00
selScreen - > setPlayer ( elem . second , connectionID ) ;
selScreen - > opt - > entries [ elem . second . color ] - > selectButtons ( ) ;
2010-10-24 14:35:14 +03:00
break ;
}
}
selScreen - > propagateNames ( ) ;
selScreen - > propagateOptions ( ) ;
2015-03-13 22:33:46 +02:00
selScreen - > toggleTab ( selScreen - > curTab ) ;
2010-10-24 14:35:14 +03:00
GH . totalRedraw ( ) ;
}
void SelectMap : : apply ( CSelectionScreen * selScreen )
{
2015-03-15 18:33:58 +02:00
if ( selScreen - > isGuest ( ) )
2010-10-24 14:35:14 +03:00
{
free = false ;
selScreen - > changeSelection ( mapInfo ) ;
}
}
void UpdateStartOptions : : apply ( CSelectionScreen * selScreen )
{
if ( ! selScreen - > isGuest ( ) )
return ;
selScreen - > setSInfo ( * options ) ;
}
void PregameGuiAction : : apply ( CSelectionScreen * selScreen )
{
if ( ! selScreen - > isGuest ( ) )
return ;
switch ( action )
{
case NO_TAB :
selScreen - > toggleTab ( selScreen - > curTab ) ;
break ;
case OPEN_OPTIONS :
selScreen - > toggleTab ( selScreen - > opt ) ;
break ;
case OPEN_SCENARIO_LIST :
selScreen - > toggleTab ( selScreen - > sel ) ;
break ;
2012-11-11 15:23:31 +03:00
case OPEN_RANDOM_MAP_OPTIONS :
selScreen - > toggleTab ( selScreen - > randMapTab ) ;
break ;
2010-10-24 14:35:14 +03:00
}
}
void RequestOptionsChange : : apply ( CSelectionScreen * selScreen )
{
if ( ! selScreen - > isHost ( ) )
return ;
2013-03-03 20:06:03 +03:00
PlayerColor color = selScreen - > sInfo . getPlayersSettings ( playerID ) - > color ;
2010-10-24 14:35:14 +03:00
switch ( what )
{
case TOWN :
selScreen - > opt - > nextCastle ( color , direction ) ;
break ;
case HERO :
selScreen - > opt - > nextHero ( color , direction ) ;
break ;
case BONUS :
selScreen - > opt - > nextBonus ( color , direction ) ;
break ;
}
}
void PlayerLeft : : apply ( CSelectionScreen * selScreen )
{
if ( selScreen - > isGuest ( ) )
return ;
SEL - > playerNames . erase ( playerID ) ;
if ( PlayerSettings * s = selScreen - > sInfo . getPlayersSettings ( playerID ) ) //it's possible that player was unallocated
{
selScreen - > setPlayer ( * s , 0 ) ;
selScreen - > opt - > entries [ s - > color ] - > selectButtons ( ) ;
}
2011-11-27 16:14:20 +03:00
2010-10-24 14:35:14 +03:00
selScreen - > propagateNames ( ) ;
selScreen - > propagateOptions ( ) ;
GH . totalRedraw ( ) ;
}
void PlayersNames : : apply ( CSelectionScreen * selScreen )
{
if ( selScreen - > isGuest ( ) )
selScreen - > playerNames = playerNames ;
}
void StartWithCurrentSettings : : apply ( CSelectionScreen * selScreen )
{
startingInfo . reset ( ) ;
startingInfo . serv = selScreen - > serv ;
startingInfo . sInfo = new StartInfo ( selScreen - > sInfo ) ;
if ( ! selScreen - > ongoingClosing )
{
* selScreen - > serv < < this ; //resend to confirm
}
2013-06-26 14:18:27 +03:00
selScreen - > serv = nullptr ; //hide it so it won't be deleted
2011-12-14 00:23:17 +03:00
vstd : : clear_pointer ( selScreen - > serverHandlingThread ) ; //detach us
2012-11-20 20:53:45 +03:00
saveGameName . clear ( ) ;
2010-10-24 14:35:14 +03:00
2014-08-04 21:33:59 +03:00
CGP - > showLoadingScreen ( std : : bind ( & startGame , startingInfo . sInfo , startingInfo . serv ) ) ;
2010-10-24 14:35:14 +03:00
throw 666 ; //EVIL, EVIL, EVIL workaround to kill thread (does "goto catch" outside listening loop)
2010-10-31 00:53:41 +03:00
}
2011-03-15 16:35:36 +02:00
2011-11-27 16:14:20 +03:00
CCampaignScreen : : CCampaignButton : : CCampaignButton ( const JsonNode & config )
2011-03-15 16:35:36 +02:00
{
2011-11-27 16:14:20 +03:00
pos . x + = config [ " x " ] . Float ( ) ;
pos . y + = config [ " y " ] . Float ( ) ;
pos . w = 200 ;
pos . h = 116 ;
2012-11-03 22:31:16 +03:00
2011-11-27 16:14:20 +03:00
campFile = config [ " file " ] . String ( ) ;
video = config [ " video " ] . String ( ) ;
2011-03-21 21:32:48 +02:00
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2011-03-15 16:35:36 +02:00
2011-11-27 16:14:20 +03:00
status = config [ " open " ] . Bool ( ) ? CCampaignScreen : : ENABLED : CCampaignScreen : : DISABLED ;
2011-03-15 16:35:36 +02:00
2012-08-01 15:02:54 +03:00
CCampaignHeader header = CCampaignHandler : : getHeader ( campFile ) ;
2011-11-27 16:14:20 +03:00
hoverText = header . name ;
2011-03-15 16:35:36 +02:00
2011-11-27 16:14:20 +03:00
if ( status ! = CCampaignScreen : : DISABLED )
2011-03-21 21:32:48 +02:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | HOVER ) ;
2011-11-27 16:14:20 +03:00
image = new CPicture ( config [ " image " ] . String ( ) ) ;
2011-03-21 21:32:48 +02:00
2012-11-11 15:23:31 +03:00
hoverLabel = new CLabel ( pos . w / 2 , pos . h + 20 , FONT_MEDIUM , CENTER , Colors : : YELLOW , " " ) ;
2012-06-02 18:16:54 +03:00
parent - > addChild ( hoverLabel ) ;
2011-04-26 16:30:29 +03:00
}
2011-11-27 16:14:20 +03:00
if ( status = = CCampaignScreen : : COMPLETED )
checkMark = new CPicture ( " CAMPCHK " ) ;
2011-03-15 16:35:36 +02:00
}
2011-11-27 16:14:20 +03:00
void CCampaignScreen : : CCampaignButton : : clickLeft ( tribool down , bool previousState )
2011-03-15 16:35:36 +02:00
{
2011-11-27 16:14:20 +03:00
if ( down )
2011-03-19 16:27:51 +02:00
{
2011-11-27 16:14:20 +03:00
// Close running video and open the selected campaign
CCS - > videoh - > close ( ) ;
2012-09-21 20:59:54 +03:00
GH . pushInt ( new CBonusSelection ( campFile ) ) ;
2011-03-19 16:27:51 +02:00
}
2011-03-15 16:35:36 +02:00
}
void CCampaignScreen : : CCampaignButton : : hover ( bool on )
2011-11-27 16:14:20 +03:00
{
2011-03-15 16:35:36 +02:00
if ( on )
2013-08-29 16:46:27 +03:00
hoverLabel - > setText ( hoverText ) ; // Shows the name of the campaign when you get into the bounds of the button
2011-03-15 16:35:36 +02:00
else
2013-08-29 16:46:27 +03:00
hoverLabel - > setText ( " " ) ;
2011-03-15 16:35:36 +02:00
}
2011-12-22 16:05:19 +03:00
void CCampaignScreen : : CCampaignButton : : show ( SDL_Surface * to )
2011-03-15 16:35:36 +02:00
{
2011-11-27 16:14:20 +03:00
if ( status = = CCampaignScreen : : DISABLED )
2011-03-15 16:35:36 +02:00
return ;
2011-11-27 16:14:20 +03:00
CIntObject : : show ( to ) ;
2011-03-15 16:35:36 +02:00
// Play the campaign button video when the mouse cursor is placed over the button
2011-11-27 16:14:20 +03:00
if ( hovered )
2011-03-15 16:35:36 +02:00
{
if ( CCS - > videoh - > fname ! = video )
CCS - > videoh - > open ( video ) ;
2011-11-27 16:14:20 +03:00
2011-03-15 16:35:36 +02:00
CCS - > videoh - > update ( pos . x , pos . y , to , true , false ) ; // plays sequentially frame by frame, starts at the beginning when the video is over
}
else if ( CCS - > videoh - > fname = = video ) // When you got out of the bounds of the button then close the video
{
CCS - > videoh - > close ( ) ;
2011-11-27 16:14:20 +03:00
redraw ( ) ;
2011-03-15 16:35:36 +02:00
}
2011-11-27 16:14:20 +03:00
}
2011-04-17 21:02:13 +03:00
2014-08-03 14:16:19 +03:00
CButton * CCampaignScreen : : createExitButton ( const JsonNode & button )
2011-11-27 16:14:20 +03:00
{
std : : pair < std : : string , std : : string > help ;
if ( ! button [ " help " ] . isNull ( ) & & button [ " help " ] . Float ( ) > 0 )
help = CGI - > generaltexth - > zelp [ button [ " help " ] . Float ( ) ] ;
2011-03-15 16:35:36 +02:00
2014-08-09 15:14:31 +03:00
std : : function < void ( ) > close = std : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) ;
2014-08-03 14:16:19 +03:00
return new CButton ( Point ( button [ " x " ] . Float ( ) , button [ " y " ] . Float ( ) ) , button [ " name " ] . String ( ) , help , close , button [ " hotkey " ] . Float ( ) ) ;
2011-03-15 16:35:36 +02:00
}
2011-11-27 16:14:20 +03:00
CCampaignScreen : : CCampaignScreen ( const JsonNode & config )
2011-03-15 16:35:36 +02:00
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " images " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
images . push_back ( createPicture ( node ) ) ;
2012-05-18 20:35:46 +03:00
if ( ! images . empty ( ) )
{
images [ 0 ] - > center ( ) ; // move background to center
moveTo ( images [ 0 ] - > pos . topLeft ( ) ) ; // move everything else to center
images [ 0 ] - > moveTo ( pos . topLeft ( ) ) ; // restore moved twice background
pos = images [ 0 ] - > pos ; // fix height\width of this window
}
2011-11-27 16:14:20 +03:00
if ( ! config [ " exitbutton " ] . isNull ( ) )
2011-03-15 16:35:36 +02:00
{
2011-11-27 16:14:20 +03:00
back = createExitButton ( config [ " exitbutton " ] ) ;
back - > hoverable = true ;
2011-03-15 16:35:36 +02:00
}
2012-11-03 22:31:16 +03:00
2013-06-29 16:05:48 +03:00
for ( const JsonNode & node : config [ " items " ] . Vector ( ) )
2011-11-27 16:14:20 +03:00
campButtons . push_back ( new CCampaignButton ( node ) ) ;
2011-04-17 21:02:13 +03:00
}
2012-05-18 20:35:46 +03:00
void CCampaignScreen : : showAll ( SDL_Surface * to )
{
CIntObject : : showAll ( to ) ;
if ( pos . h ! = to - > h | | pos . w ! = to - > w )
2013-03-03 20:06:03 +03:00
CMessage : : drawBorder ( PlayerColor ( 1 ) , to , pos . w + 28 , pos . h + 30 , pos . x - 14 , pos . y - 15 ) ;
2012-05-18 20:35:46 +03:00
}
2012-09-26 21:10:29 +03:00
2013-06-26 14:18:27 +03:00
void CGPreGame : : showLoadingScreen ( std : : function < void ( ) > loader )
2012-12-17 21:01:17 +03:00
{
2012-12-19 21:19:09 +03:00
if ( GH . listInt . size ( ) & & GH . listInt . front ( ) = = CGP ) //pregame active
2012-12-17 21:01:17 +03:00
CGP - > removeFromGui ( ) ;
GH . pushInt ( new CLoadingScreen ( loader ) ) ;
}
std : : string CLoadingScreen : : getBackground ( )
{
2013-12-17 15:12:25 +03:00
const auto & conf = CGPreGameConfig : : get ( ) . getConfig ( ) [ " loading " ] . Vector ( ) ;
2012-12-17 21:01:17 +03:00
2013-12-17 15:12:25 +03:00
if ( conf . empty ( ) )
{
2012-12-17 21:01:17 +03:00
return " loadbar " ;
2013-12-17 15:12:25 +03:00
}
else
{
2014-04-10 20:11:09 +03:00
return RandomGeneratorUtil : : nextItem ( conf , CRandomGenerator : : getDefault ( ) ) - > String ( ) ;
2013-12-17 15:12:25 +03:00
}
2012-12-17 21:01:17 +03:00
}
2013-06-26 14:18:27 +03:00
CLoadingScreen : : CLoadingScreen ( std : : function < void ( ) > loader ) :
2012-12-17 21:01:17 +03:00
CWindowObject ( BORDERED , getBackground ( ) ) ,
loadingThread ( loader )
2012-12-19 20:24:53 +03:00
{
CCS - > musich - > stopMusic ( 5000 ) ;
}
2012-12-17 21:01:17 +03:00
2012-12-18 13:32:11 +03:00
CLoadingScreen : : ~ CLoadingScreen ( )
{
loadingThread . join ( ) ;
}
2012-12-17 21:01:17 +03:00
void CLoadingScreen : : showAll ( SDL_Surface * to )
{
Rect rect ( 0 , 0 , to - > w , to - > h ) ;
SDL_FillRect ( to , & rect , 0 ) ;
CWindowObject : : showAll ( to ) ;
}
2013-02-19 23:39:09 +03:00
2013-08-29 19:41:14 +03:00
CPrologEpilogVideo : : CPrologEpilogVideo ( CCampaignScenario : : SScenarioPrologEpilog _spe , std : : function < void ( ) > callback ) :
CWindowObject ( BORDERED ) ,
spe ( _spe ) ,
positionCounter ( 0 ) ,
voiceSoundHandle ( - 1 ) ,
exitCb ( callback )
2013-02-19 23:39:09 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2013-02-21 00:01:18 +03:00
addUsedEvents ( LCLICK ) ;
2013-08-29 19:41:14 +03:00
pos = center ( Rect ( 0 , 0 , 800 , 600 ) ) ;
updateShadow ( ) ;
2013-02-19 23:39:09 +03:00
CCS - > videoh - > open ( CCampaignHandler : : prologVideoName ( spe . prologVideo ) ) ;
2013-08-29 19:41:14 +03:00
CCS - > musich - > playMusic ( " Music/ " + CCampaignHandler : : prologMusicName ( spe . prologMusic ) , true ) ;
voiceSoundHandle = CCS - > soundh - > playSound ( CCampaignHandler : : prologVoiceName ( spe . prologVideo ) ) ;
2013-02-19 23:39:09 +03:00
2013-08-29 19:41:14 +03:00
text = new CMultiLineLabel ( Rect ( 100 , 500 , 600 , 100 ) , EFonts : : FONT_BIG , CENTER , Colors : : METALLIC_GOLD , spe . prologText ) ;
text - > scrollTextTo ( - 100 ) ;
2013-02-19 23:39:09 +03:00
}
void CPrologEpilogVideo : : show ( SDL_Surface * to )
{
2014-07-05 00:46:55 +03:00
CSDL_Ext : : fillRectBlack ( to , & pos ) ;
2013-08-29 19:41:14 +03:00
//BUG: some videos are 800x600 in size while some are 800x400
//VCMI should center them in the middle of the screen. Possible but needs modification
2014-03-23 15:59:03 +03:00
//of video player API which I'd like to avoid until we'll get rid of Windows-specific player
2014-03-01 21:50:50 +03:00
CCS - > videoh - > update ( pos . x , pos . y , to , true , false ) ;
2013-02-23 00:03:56 +03:00
//move text every 5 calls/frames; seems to be good enough
2013-08-29 19:41:14 +03:00
+ + positionCounter ;
if ( positionCounter % 5 = = 0 )
2013-02-23 00:03:56 +03:00
{
2013-08-29 19:41:14 +03:00
text - > scrollTextBy ( 1 ) ;
2013-02-23 00:03:56 +03:00
}
2013-08-29 19:41:14 +03:00
else
text - > showAll ( to ) ; // blit text over video, if needed
if ( text - > textSize . y + 100 < positionCounter / 5 )
clickLeft ( false , false ) ;
2013-02-19 23:39:09 +03:00
}
void CPrologEpilogVideo : : clickLeft ( tribool down , bool previousState )
{
GH . popInt ( this ) ;
2013-08-29 19:41:14 +03:00
CCS - > soundh - > stopSound ( voiceSoundHandle ) ;
2013-02-21 00:01:18 +03:00
exitCb ( ) ;
2013-02-19 23:39:09 +03:00
}
2013-06-02 22:53:13 +03:00
CSimpleJoinScreen : : CSimpleJoinScreen ( )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
bg = new CPicture ( " MUDIALOG.bmp " ) ; // address background
pos = bg - > center ( ) ; //center, window has size of bg graphic (x,y = 396,278 w=232 h=212)
Rect boxRect ( 20 , 20 , 205 , 50 ) ;
title = new CTextBox ( " Enter address: " , boxRect , 0 , FONT_BIG , CENTER , Colors : : WHITE ) ;
address = new CTextInput ( Rect ( 25 , 68 , 175 , 16 ) , * bg ) ;
2014-08-04 21:33:59 +03:00
address - > cb + = std : : bind ( & CSimpleJoinScreen : : onChange , this , _1 ) ;
2013-06-02 22:53:13 +03:00
port = new CTextInput ( Rect ( 25 , 115 , 175 , 16 ) , * bg ) ;
2014-08-04 21:33:59 +03:00
port - > cb + = std : : bind ( & CSimpleJoinScreen : : onChange , this , _1 ) ;
2014-11-12 22:45:48 +02:00
port - > filters + = std : : bind ( & CTextInput : : numberFilter , _1 , _2 , 0 , 65535 ) ;
2013-06-02 22:53:13 +03:00
2014-08-09 15:14:31 +03:00
ok = new CButton ( Point ( 26 , 142 ) , " MUBCHCK.DEF " , CGI - > generaltexth - > zelp [ 560 ] , std : : bind ( & CSimpleJoinScreen : : enterSelectionScreen , this ) , SDLK_RETURN ) ;
cancel = new CButton ( Point ( 142 , 142 ) , " MUBCANC.DEF " , CGI - > generaltexth - > zelp [ 561 ] , std : : bind ( & CGuiHandler : : popIntTotally , std : : ref ( GH ) , this ) , SDLK_ESCAPE ) ;
2013-06-02 22:53:13 +03:00
bar = new CGStatusBar ( new CPicture ( Rect ( 7 , 186 , 218 , 18 ) , 0 ) ) ;
2013-08-29 16:46:27 +03:00
port - > setText ( boost : : lexical_cast < std : : string > ( settings [ " server " ] [ " port " ] . Float ( ) ) , true ) ;
address - > setText ( settings [ " server " ] [ " server " ] . String ( ) , true ) ;
2013-06-02 22:53:13 +03:00
address - > giveFocus ( ) ;
}
void CSimpleJoinScreen : : enterSelectionScreen ( )
{
std : : string textAddress = address - > text ;
std : : string textPort = port - > text ;
GH . popIntTotally ( this ) ;
2013-06-26 14:18:27 +03:00
GH . pushInt ( new CSelectionScreen ( CMenuScreen : : newGame , CMenuScreen : : MULTI_NETWORK_GUEST , nullptr , textAddress , textPort ) ) ;
2013-06-02 22:53:13 +03:00
}
void CSimpleJoinScreen : : onChange ( const std : : string & newText )
{
ok - > block ( address - > text . empty ( ) | | port - > text . empty ( ) ) ;
}