2011-12-14 00:23:17 +03:00
# include "StdInc.h"
2009-05-19 21:23:04 +03:00
# include "GUIClasses.h"
2013-04-07 14:52:07 +03:00
# include "gui/SDL_Extensions.h"
2009-05-19 21:23:04 +03:00
2009-05-20 13:08:56 +03:00
# include "CAdvmapInterface.h"
2013-07-06 19:10:20 +03:00
# include "CBitmapHandler.h"
# include "CDefHandler.h"
2013-04-07 14:52:07 +03:00
# include "battle/CBattleInterface.h"
# include "battle/CBattleInterfaceClasses.h"
2009-05-19 21:23:04 +03:00
# include "../CCallback.h"
2009-05-20 13:08:56 +03:00
# include "CCastleInterface.h"
2011-03-03 20:25:48 +02:00
# include "CCreatureWindow.h"
2013-04-07 14:52:07 +03:00
# include "gui/CCursorHandler.h"
2009-05-20 13:08:56 +03:00
# include "CGameInfo.h"
# include "CHeroWindow.h"
# include "CMessage.h"
2012-09-29 13:59:43 +03:00
# include "../lib/CConfigHandler.h"
2013-04-07 14:52:07 +03:00
# include "battle/CCreatureAnimation.h"
2011-02-06 19:26:27 +02:00
# include "CPlayerInterface.h"
2009-05-19 21:23:04 +03:00
# include "Graphics.h"
2010-11-15 17:15:00 +02:00
# include "CAnimation.h"
2010-12-20 23:22:53 +02:00
# include "../lib/CArtHandler.h"
# include "../lib/CBuildingHandler.h"
# include "../lib/CGeneralTextHandler.h"
# include "../lib/CHeroHandler.h"
2012-09-05 15:49:23 +03:00
# include "../lib/CModHandler.h"
2010-12-20 23:22:53 +02:00
# include "../lib/CObjectHandler.h"
# include "../lib/CSpellHandler.h"
# include "../lib/CTownHandler.h"
2009-05-19 21:23:04 +03:00
# include "../lib/CondSh.h"
2013-04-07 13:48:07 +03:00
# include "../lib/mapping/CMap.h"
2010-04-06 11:59:24 +03:00
# include "mapHandler.h"
2011-12-17 21:59:59 +03:00
# include "../lib/CStopWatch.h"
2014-01-16 23:24:06 +03:00
# include "../lib/NetPacksBase.h"
2009-06-18 18:05:00 +03:00
# include "CSpellWindow.h"
# include "CHeroWindow.h"
2010-12-20 23:22:53 +02:00
# include "CVideoHandler.h"
2011-12-14 00:23:17 +03:00
# include "../lib/StartInfo.h"
2009-09-07 05:29:44 +03:00
# include "CPreGame.h"
2010-05-02 21:20:26 +03:00
# include "../lib/HeroBonus.h"
2010-12-20 23:22:53 +02:00
# include "../lib/CCreatureHandler.h"
# include "CMusicHandler.h"
2010-12-26 16:34:11 +02:00
# include "../lib/BattleState.h"
2011-05-10 01:20:47 +03:00
# include "../lib/CGameState.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"
2009-05-19 21:23:04 +03:00
/*
* GUIClasses . 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
*
*/
using namespace boost : : assign ;
using namespace CSDL_Ext ;
2012-09-11 17:25:19 +03:00
extern std : : queue < SDL_Event > events ;
2009-05-19 21:23:04 +03:00
extern boost : : mutex eventsM ;
2010-02-16 18:35:24 +02:00
std : : list < CFocusable * > CFocusable : : focusables ;
CFocusable * CFocusable : : inputWithFocus ;
2010-02-15 13:37:47 +02:00
2009-06-24 15:14:48 +03:00
# undef min
# undef max
2012-06-13 16:04:06 +03:00
void CArmyTooltip : : init ( const InfoAboutArmy & army )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-11-11 15:23:31 +03:00
new CLabel ( 66 , 2 , FONT_SMALL , TOPLEFT , Colors : : WHITE , army . name ) ;
2012-06-13 16:04:06 +03:00
std : : vector < Point > slotsPos ;
slotsPos . push_back ( Point ( 36 , 73 ) ) ;
slotsPos . push_back ( Point ( 72 , 73 ) ) ;
slotsPos . push_back ( Point ( 108 , 73 ) ) ;
slotsPos . push_back ( Point ( 18 , 122 ) ) ;
slotsPos . push_back ( Point ( 54 , 122 ) ) ;
slotsPos . push_back ( Point ( 90 , 122 ) ) ;
slotsPos . push_back ( Point ( 126 , 122 ) ) ;
2013-06-29 16:05:48 +03:00
for ( auto & slot : army . army )
2012-06-13 16:04:06 +03:00
{
2013-02-16 17:03:47 +03:00
if ( slot . first . getNum ( ) > = GameConstants : : ARMY_SIZE )
2012-08-30 19:01:19 +03:00
{
2013-04-09 17:31:36 +03:00
logGlobal - > warnStream ( ) < < " Warning: " < < army . name < < " has stack in slot " < < slot . first ;
2012-08-30 19:01:19 +03:00
continue ;
}
2013-02-16 17:03:47 +03:00
new CAnimImage ( " CPRSMALL " , slot . second . type - > iconIndex , 0 , slotsPos [ slot . first . getNum ( ) ] . x , slotsPos [ slot . first . getNum ( ) ] . y ) ;
2012-06-13 16:04:06 +03:00
std : : string subtitle ;
if ( army . army . isDetailed )
subtitle = boost : : lexical_cast < std : : string > ( slot . second . count ) ;
else
{
//if =0 - we have no information about stack size at all
if ( slot . second . count )
2012-06-13 17:11:18 +03:00
subtitle = CGI - > generaltexth - > arraytxt [ 171 + 3 * ( slot . second . count ) ] ;
2012-06-13 16:04:06 +03:00
}
2013-02-16 17:03:47 +03:00
new CLabel ( slotsPos [ slot . first . getNum ( ) ] . x + 17 , slotsPos [ slot . first . getNum ( ) ] . y + 41 , FONT_TINY , CENTER , Colors : : WHITE , subtitle ) ;
2012-06-13 16:04:06 +03:00
}
}
CArmyTooltip : : CArmyTooltip ( Point pos , const InfoAboutArmy & army ) :
CIntObject ( 0 , pos )
{
init ( army ) ;
}
CArmyTooltip : : CArmyTooltip ( Point pos , const CArmedInstance * army ) :
CIntObject ( 0 , pos )
{
init ( InfoAboutArmy ( army , true ) ) ;
}
void CHeroTooltip : : init ( const InfoAboutHero & hero )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
new CAnimImage ( " PortraitsLarge " , hero . portrait , 0 , 3 , 2 ) ;
if ( hero . details )
{
for ( size_t i = 0 ; i < hero . details - > primskills . size ( ) ; i + + )
2012-11-11 15:23:31 +03:00
new CLabel ( 75 + 28 * i , 58 , FONT_SMALL , CENTER , Colors : : WHITE ,
2012-06-13 16:04:06 +03:00
boost : : lexical_cast < std : : string > ( hero . details - > primskills [ i ] ) ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 158 , 98 , FONT_TINY , CENTER , Colors : : WHITE ,
2012-06-13 16:04:06 +03:00
boost : : lexical_cast < std : : string > ( hero . details - > mana ) ) ;
new CAnimImage ( " IMRL22 " , hero . details - > morale + 3 , 0 , 5 , 74 ) ;
new CAnimImage ( " ILCK22 " , hero . details - > luck + 3 , 0 , 5 , 91 ) ;
}
}
CHeroTooltip : : CHeroTooltip ( Point pos , const InfoAboutHero & hero ) :
CArmyTooltip ( pos , hero )
{
init ( hero ) ;
}
CHeroTooltip : : CHeroTooltip ( Point pos , const CGHeroInstance * hero ) :
CArmyTooltip ( pos , InfoAboutHero ( hero , true ) )
{
init ( InfoAboutHero ( hero , true ) ) ;
}
void CTownTooltip : : init ( const InfoAboutTown & town )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
//order of icons in def: fort, citadel, castle, no fort
size_t fortIndex = town . fortLevel ? town . fortLevel - 1 : 3 ;
new CAnimImage ( " ITMCLS " , fortIndex , 0 , 105 , 31 ) ;
assert ( town . tType ) ;
2012-09-22 18:10:15 +03:00
size_t iconIndex = town . tType - > clientInfo . icons [ town . fortLevel > 0 ] [ town . built > = CGI - > modh - > settings . MAX_BUILDING_PER_TURN ] ;
2012-06-13 16:04:06 +03:00
2012-09-22 18:10:15 +03:00
new CAnimImage ( " itpt " , iconIndex , 0 , 3 , 2 ) ;
2012-06-13 16:04:06 +03:00
if ( town . details )
{
2013-06-23 22:35:54 +03:00
new CAnimImage ( " ITMTLS " , town . details - > hallLevel , 0 , 67 , 31 ) ;
2012-06-13 16:04:06 +03:00
if ( town . details - > goldIncome )
2012-11-11 15:23:31 +03:00
new CLabel ( 157 , 58 , FONT_TINY , CENTER , Colors : : WHITE ,
2012-06-13 16:04:06 +03:00
boost : : lexical_cast < std : : string > ( town . details - > goldIncome ) ) ;
if ( town . details - > garrisonedHero ) //garrisoned hero icon
new CPicture ( " TOWNQKGH " , 149 , 76 ) ;
if ( town . details - > customRes ) //silo is built
{
2013-04-21 15:49:26 +03:00
if ( town . tType - > primaryRes = = Res : : WOOD_AND_ORE ) // wood & ore
2012-06-13 16:04:06 +03:00
{
new CAnimImage ( " SMALRES " , Res : : WOOD , 0 , 7 , 75 ) ;
new CAnimImage ( " SMALRES " , Res : : ORE , 0 , 7 , 88 ) ;
}
else
new CAnimImage ( " SMALRES " , town . tType - > primaryRes , 0 , 7 , 81 ) ;
}
}
}
CTownTooltip : : CTownTooltip ( Point pos , const InfoAboutTown & town ) :
CArmyTooltip ( pos , town )
{
init ( town ) ;
}
CTownTooltip : : CTownTooltip ( Point pos , const CGTownInstance * town ) :
CArmyTooltip ( pos , InfoAboutTown ( town , true ) )
{
init ( InfoAboutTown ( town , true ) ) ;
}
2011-02-27 21:58:14 +02:00
2012-12-11 15:12:46 +03:00
void CGarrisonSlot : : setHighlight ( bool on )
{
if ( on )
2012-12-14 18:32:53 +03:00
selectionImage - > enable ( ) ; //show
2012-12-11 15:12:46 +03:00
else
2012-12-14 18:32:53 +03:00
selectionImage - > disable ( ) ; //hide
2012-12-11 15:12:46 +03:00
}
2009-05-19 21:23:04 +03:00
void CGarrisonSlot : : hover ( bool on )
{
2009-08-11 19:05:33 +03:00
////Hoverable::hover(on);
2009-05-19 21:23:04 +03:00
if ( on )
{
std : : string temp ;
if ( creature )
{
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) )
2009-05-19 21:23:04 +03:00
{
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) = = this )
2009-05-19 21:23:04 +03:00
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 4 ] ; //View %s
2009-05-19 21:23:04 +03:00
boost : : algorithm : : replace_first ( temp , " %s " , creature - > nameSing ) ;
}
2012-12-11 15:12:46 +03:00
else if ( owner - > getSelection ( ) - > creature = = creature )
2009-05-19 21:23:04 +03:00
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 2 ] ; //Combine %s armies
2009-05-19 21:23:04 +03:00
boost : : algorithm : : replace_first ( temp , " %s " , creature - > nameSing ) ;
}
2012-12-11 15:12:46 +03:00
else if ( owner - > getSelection ( ) - > creature )
2009-05-19 21:23:04 +03:00
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 7 ] ; //Exchange %s with %s
2012-12-11 15:12:46 +03:00
boost : : algorithm : : replace_first ( temp , " %s " , owner - > getSelection ( ) - > creature - > nameSing ) ;
2009-05-19 21:23:04 +03:00
boost : : algorithm : : replace_first ( temp , " %s " , creature - > nameSing ) ;
}
else
{
2013-04-09 17:31:36 +03:00
logGlobal - > warnStream ( ) < < " Warning - shouldn't be - highlighted void slot " < < owner - > getSelection ( ) ;
2013-06-26 14:18:27 +03:00
logGlobal - > warnStream ( ) < < " Highlighted set to nullptr " ;
2012-12-11 15:12:46 +03:00
owner - > selectSlot ( nullptr ) ;
2009-05-19 21:23:04 +03:00
}
}
else
{
if ( upg )
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 32 ] ; //Select %s (visiting)
}
2012-09-23 21:01:04 +03:00
else if ( owner - > armedObjs [ 0 ] & & owner - > armedObjs [ 0 ] - > ID = = Obj : : TOWN )
2009-07-16 01:46:00 +03:00
{
temp = CGI - > generaltexth - > tcommands [ 12 ] ; //Select %s (in garrison)
2009-05-19 21:23:04 +03:00
}
else
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > allTexts [ 481 ] ; //Select %s
2009-05-19 21:23:04 +03:00
}
boost : : algorithm : : replace_first ( temp , " %s " , creature - > nameSing ) ;
} ;
}
else
{
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) )
2009-05-19 21:23:04 +03:00
{
2012-12-11 15:12:46 +03:00
const CArmedInstance * highl = owner - > getSelection ( ) - > getObj ( ) ;
2009-05-19 21:23:04 +03:00
if ( highl - > needsLastStack ( ) //we are moving stack from hero's
2010-05-02 21:20:26 +03:00
& & highl - > stacksCount ( ) = = 1 //it's only stack
2012-12-11 15:12:46 +03:00
& & owner - > getSelection ( ) - > upg ! = upg //we're moving it to the other garrison
2009-05-19 21:23:04 +03:00
)
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 5 ] ; //Cannot move last army to garrison
2009-05-19 21:23:04 +03:00
}
else
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 6 ] ; //Move %s
2012-12-11 15:12:46 +03:00
boost : : algorithm : : replace_first ( temp , " %s " , owner - > getSelection ( ) - > creature - > nameSing ) ;
2009-05-19 21:23:04 +03:00
}
}
else
{
2009-07-16 01:46:00 +03:00
temp = CGI - > generaltexth - > tcommands [ 11 ] ; //Empty
2009-05-19 21:23:04 +03:00
}
}
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( temp ) ;
2009-05-19 21:23:04 +03:00
}
else
{
2010-02-15 08:54:57 +02:00
GH . statusbar - > clear ( ) ;
2009-05-19 21:23:04 +03:00
}
}
2012-12-11 15:12:46 +03:00
const CArmedInstance * CGarrisonSlot : : getObj ( ) const
2009-05-19 21:23:04 +03:00
{
2011-02-05 15:39:10 +02:00
return ( ! upg ) ? ( owner - > armedObjs [ 0 ] ) : ( owner - > armedObjs [ 1 ] ) ;
2009-05-19 21:23:04 +03:00
}
2012-12-11 15:12:46 +03:00
bool CGarrisonSlot : : our ( ) const
2010-08-12 18:54:25 +03:00
{
2011-02-05 15:39:10 +02:00
return upg ? ( owner - > owned [ 1 ] ) : ( owner - > owned [ 0 ] ) ;
2010-08-12 18:54:25 +03:00
}
2009-08-11 19:05:33 +03:00
void CGarrisonSlot : : clickRight ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
if ( down & & creature )
2011-03-03 20:25:48 +02:00
{
2013-01-31 00:28:31 +03:00
GH . pushInt ( createCreWindow ( myStack , CCreatureWindow : : ARMY ) ) ;
2011-03-03 20:25:48 +02:00
}
2009-05-19 21:23:04 +03:00
}
2009-08-11 19:05:33 +03:00
void CGarrisonSlot : : clickLeft ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
if ( down )
{
bool refr = false ;
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) )
2009-05-19 21:23:04 +03:00
{
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) = = this ) //view info
2009-05-19 21:23:04 +03:00
{
2011-05-03 06:14:18 +03:00
UpgradeInfo pom ;
LOCPLINT - > cb - > getUpgradeInfo ( getObj ( ) , ID , pom ) ;
2009-05-19 21:23:04 +03:00
2010-08-12 18:54:25 +03:00
bool canUpgrade = getObj ( ) - > tempOwner = = LOCPLINT - > playerID & & pom . oldID > = 0 ; //upgrade is possible
bool canDismiss = getObj ( ) - > tempOwner = = LOCPLINT - > playerID & & ( getObj ( ) - > stacksCount ( ) > 1 | | ! getObj ( ) - > needsLastStack ( ) ) ;
2013-06-26 14:18:27 +03:00
std : : function < void ( ) > upgr = nullptr ;
std : : function < void ( ) > dism = nullptr ;
2013-07-02 15:08:30 +03:00
if ( canUpgrade ) upgr = [ = ] { LOCPLINT - > cb - > upgradeCreature ( getObj ( ) , ID , pom . newID [ 0 ] ) ; } ;
if ( canDismiss ) dism = [ = ] { LOCPLINT - > cb - > dismissCreature ( getObj ( ) , ID ) ; } ;
2009-05-19 21:23:04 +03:00
2012-12-11 15:12:46 +03:00
owner - > selectSlot ( nullptr ) ;
owner - > setSplittingMode ( false ) ;
2009-09-09 09:04:42 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & elem : owner - > splitButtons )
elem - > block ( true ) ;
2009-09-09 09:04:42 +03:00
2011-01-21 12:37:19 +02:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
refr = true ;
2013-01-31 00:28:31 +03:00
CIntObject * creWindow = createCreWindow ( myStack , CCreatureWindow : : HERO , upgr , dism , & pom ) ;
2011-05-25 16:11:03 +03:00
GH . pushInt ( creWindow ) ;
2009-05-19 21:23:04 +03:00
}
2012-01-12 18:23:00 +03:00
else
2009-09-24 16:23:52 +03:00
{
2010-08-12 18:54:25 +03:00
// Only allow certain moves if troops aren't removable or not ours.
2012-12-11 15:12:46 +03:00
if ( ( owner - > getSelection ( ) - > our ( ) //our creature is selected
| | owner - > getSelection ( ) - > creature = = creature ) //or we are rebalancing army
2010-08-12 18:54:25 +03:00
& & ( owner - > removableUnits
2012-12-11 15:12:46 +03:00
| | ( upg = = 0 & & ( owner - > getSelection ( ) - > upg = = 1 & & ! creature ) )
| | ( upg = = 1 & & owner - > getSelection ( ) - > upg = = 1 ) ) )
2009-05-19 21:23:04 +03:00
{
2009-09-09 20:49:03 +03:00
//we want to split
2012-12-11 15:12:46 +03:00
if ( ( owner - > getSplittingMode ( ) | | LOCPLINT - > shiftPressed ( ) )
2009-09-09 20:49:03 +03:00
& & ( ! creature
2012-12-11 15:12:46 +03:00
| | ( creature = = owner - > getSelection ( ) - > creature ) ) )
2009-05-19 21:23:04 +03:00
{
2009-09-09 20:49:03 +03:00
owner - > p2 = ID ; //store the second stack pos
owner - > pb = upg ; //store the second stack owner (up or down army)
2012-12-11 15:12:46 +03:00
owner - > setSplittingMode ( false ) ;
2009-09-09 20:49:03 +03:00
2012-06-13 16:04:06 +03:00
int minLeft = 0 , minRight = 0 ;
2009-09-09 20:49:03 +03:00
2012-12-11 15:12:46 +03:00
if ( upg ! = owner - > getSelection ( ) - > upg ) //not splitting within same army
2009-09-09 20:49:03 +03:00
{
2012-12-11 15:12:46 +03:00
if ( owner - > getSelection ( ) - > getObj ( ) - > stacksCount ( ) = = 1 //we're splitting away the last stack
& & owner - > getSelection ( ) - > getObj ( ) - > needsLastStack ( ) )
2009-09-09 20:49:03 +03:00
{
2012-06-13 16:04:06 +03:00
minLeft = 1 ;
2009-09-09 20:49:03 +03:00
}
2010-05-02 21:20:26 +03:00
if ( getObj ( ) - > stacksCount ( ) = = 1 //destination army can't be emptied, unless we're rebalancing two stacks of same creature
2012-12-11 15:12:46 +03:00
& & owner - > getSelection ( ) - > creature = = creature
2009-09-09 20:49:03 +03:00
& & getObj ( ) - > needsLastStack ( ) )
{
2012-06-13 16:04:06 +03:00
minRight = 1 ;
2009-09-09 20:49:03 +03:00
}
}
2012-12-12 17:52:42 +03:00
int countLeft = owner - > getSelection ( ) - > myStack ? owner - > getSelection ( ) - > myStack - > count : 0 ;
int countRight = myStack ? myStack - > count : 0 ;
2013-07-02 18:23:32 +03:00
GH . pushInt ( new CSplitWindow ( owner - > getSelection ( ) - > creature , boost : : bind ( & CGarrisonInt : : splitStacks , owner , _1 , _2 ) ,
2012-12-12 17:52:42 +03:00
minLeft , minRight , countLeft , countRight ) ) ;
2009-09-09 20:49:03 +03:00
refr = true ;
2009-05-19 21:23:04 +03:00
}
2012-12-11 15:12:46 +03:00
else if ( creature ! = owner - > getSelection ( ) - > creature ) //swap
2009-05-19 21:23:04 +03:00
{
2009-09-09 20:49:03 +03:00
LOCPLINT - > cb - > swapCreatures (
2011-02-05 15:39:10 +02:00
( ! upg ) ? ( owner - > armedObjs [ 0 ] ) : ( owner - > armedObjs [ 1 ] ) ,
2012-12-11 15:12:46 +03:00
( ! owner - > getSelection ( ) - > upg ) ? ( owner - > armedObjs [ 0 ] ) : ( owner - > armedObjs [ 1 ] ) ,
ID , owner - > getSelection ( ) - > ID ) ;
2009-09-09 20:49:03 +03:00
}
else //merge
{
LOCPLINT - > cb - > mergeStacks (
2012-12-11 15:12:46 +03:00
( ! owner - > getSelection ( ) - > upg ) ? ( owner - > armedObjs [ 0 ] ) : ( owner - > armedObjs [ 1 ] ) ,
2011-02-05 15:39:10 +02:00
( ! upg ) ? ( owner - > armedObjs [ 0 ] ) : ( owner - > armedObjs [ 1 ] ) ,
2012-12-11 15:12:46 +03:00
owner - > getSelection ( ) - > ID , ID ) ;
2009-05-19 21:23:04 +03:00
}
}
2009-09-24 16:23:52 +03:00
else // Highlight
2012-01-12 18:23:00 +03:00
{
2009-09-09 20:49:03 +03:00
if ( creature )
2012-12-11 15:12:46 +03:00
owner - > selectSlot ( this ) ;
2011-01-21 12:37:19 +02:00
redraw ( ) ;
2009-09-09 20:49:03 +03:00
refr = true ;
}
2009-05-19 21:23:04 +03:00
}
}
2012-04-14 05:20:22 +03:00
else //highlight or drop artifact
2009-05-19 21:23:04 +03:00
{
2012-01-30 19:07:52 +03:00
bool artSelected = false ;
2012-04-14 05:20:22 +03:00
if ( CWindowWithArtifacts * chw = dynamic_cast < CWindowWithArtifacts * > ( GH . topInt ( ) ) ) //dirty solution
2009-09-09 09:04:42 +03:00
{
2012-04-14 05:20:22 +03:00
const CArtifactsOfHero : : SCommonPart * commonInfo = chw - > artSets . front ( ) - > commonInfo ;
if ( const CArtifactInstance * art = commonInfo - > src . art )
2012-01-30 19:07:52 +03:00
{
2012-04-14 05:20:22 +03:00
const CGHeroInstance * srcHero = commonInfo - > src . AOH - > getHero ( ) ;
artSelected = true ;
ArtifactLocation src ( srcHero , commonInfo - > src . slotID ) ;
ArtifactLocation dst ( myStack , ArtifactPosition : : CREATURE_SLOT ) ;
if ( art - > canBePutAt ( dst , true ) )
{ //equip clicked stack
if ( dst . getArt ( ) )
{
//creature can wear only one active artifact
//if we are placing a new one, the old one will be returned to the hero's backpack
LOCPLINT - > cb - > swapArtifacts ( dst , ArtifactLocation ( srcHero , dst . getArt ( ) - > firstBackpackSlot ( srcHero ) ) ) ;
2012-01-30 19:07:52 +03:00
}
2012-04-14 05:20:22 +03:00
LOCPLINT - > cb - > swapArtifacts ( src , dst ) ;
2012-01-30 19:07:52 +03:00
}
}
}
2012-04-14 05:20:22 +03:00
if ( ! artSelected & & creature )
2012-01-30 19:07:52 +03:00
{
2012-12-11 15:12:46 +03:00
owner - > selectSlot ( this ) ;
2012-01-30 19:07:52 +03:00
if ( creature )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : owner - > splitButtons )
elem - > block ( false ) ;
2012-01-30 19:07:52 +03:00
}
2009-09-09 09:04:42 +03:00
}
2011-01-21 12:37:19 +02:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
refr = true ;
}
if ( refr ) { hover ( false ) ; hover ( true ) ; } //to refresh statusbar
}
}
2012-06-02 18:16:54 +03:00
2012-12-11 15:12:46 +03:00
void CGarrisonSlot : : update ( )
{
2012-12-12 15:03:02 +03:00
if ( getObj ( ) ! = nullptr )
{
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
myStack = getObj ( ) - > getStackPtr ( ID ) ;
2013-06-26 14:18:27 +03:00
creature = myStack ? myStack - > type : nullptr ;
2012-12-12 15:03:02 +03:00
}
else
{
removeUsedEvents ( LCLICK | RCLICK | HOVER ) ;
myStack = nullptr ;
creature = nullptr ;
}
2012-12-11 15:12:46 +03:00
if ( creature )
{
2012-12-14 18:32:53 +03:00
creatureImage - > enable ( ) ;
2012-12-11 15:12:46 +03:00
creatureImage - > setFrame ( creature - > iconIndex ) ;
2012-12-14 18:32:53 +03:00
stackCount - > enable ( ) ;
2013-08-29 16:46:27 +03:00
stackCount - > setText ( boost : : lexical_cast < std : : string > ( myStack - > count ) ) ;
2012-12-11 15:12:46 +03:00
}
else
{
2012-12-14 18:32:53 +03:00
creatureImage - > disable ( ) ;
stackCount - > disable ( ) ;
2012-12-11 15:12:46 +03:00
}
}
2013-02-16 17:03:47 +03:00
CGarrisonSlot : : CGarrisonSlot ( CGarrisonInt * Owner , int x , int y , SlotID IID , int Upg , const CStackInstance * Creature ) :
2012-12-12 15:03:02 +03:00
ID ( IID ) ,
owner ( Owner ) ,
myStack ( Creature ) ,
creature ( Creature ? Creature - > type : nullptr ) ,
upg ( Upg )
2009-05-19 21:23:04 +03:00
{
2012-08-06 10:34:37 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-12-12 15:03:02 +03:00
if ( getObj ( ) )
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
2012-08-06 10:34:37 +03:00
pos . x + = x ;
pos . y + = y ;
2012-12-11 15:12:46 +03:00
std : : string imgName = owner - > smallIcons ? " cprsmall " : " TWCRPORT " ;
creatureImage = new CAnimImage ( imgName , creature ? creature - > iconIndex : 0 ) ;
if ( ! creature )
2012-12-14 18:32:53 +03:00
creatureImage - > disable ( ) ;
2012-12-11 15:12:46 +03:00
selectionImage = new CAnimImage ( imgName , 1 ) ;
2012-12-14 18:32:53 +03:00
selectionImage - > disable ( ) ;
2012-08-06 10:34:37 +03:00
2009-06-28 11:21:50 +03:00
if ( Owner - > smallIcons )
{
pos . w = 32 ;
pos . h = 32 ;
}
else
{
pos . w = 58 ;
pos . h = 64 ;
}
2009-05-19 21:23:04 +03:00
2012-12-11 15:12:46 +03:00
stackCount = new CLabel ( pos . w , pos . h , owner - > smallIcons ? FONT_TINY : FONT_MEDIUM , BOTTOMRIGHT , Colors : : WHITE ) ;
if ( ! creature )
2012-12-14 18:32:53 +03:00
stackCount - > disable ( ) ;
2012-12-11 15:12:46 +03:00
else
2013-08-29 16:46:27 +03:00
stackCount - > setText ( boost : : lexical_cast < std : : string > ( myStack - > count ) ) ;
2009-05-19 21:23:04 +03:00
}
2011-02-05 15:39:10 +02:00
2011-12-22 16:05:19 +03:00
void CGarrisonInt : : addSplitBtn ( CAdventureMapButton * button )
2009-05-19 21:23:04 +03:00
{
2012-06-02 18:16:54 +03:00
addChild ( button ) ;
2010-08-27 19:20:35 +03:00
button - > recActions = defActions ;
splitButtons . push_back ( button ) ;
2012-12-12 15:03:02 +03:00
button - > block ( getSelection ( ) = = nullptr ) ;
2009-05-19 21:23:04 +03:00
}
2010-08-27 19:20:35 +03:00
void CGarrisonInt : : createSet ( std : : vector < CGarrisonSlot * > & ret , const CCreatureSet * set , int posX , int posY , int distance , int Upg )
2009-05-19 21:23:04 +03:00
{
2010-08-27 19:20:35 +03:00
ret . resize ( 7 ) ;
2012-01-12 18:23:00 +03:00
2012-12-12 15:03:02 +03:00
if ( set )
2009-05-19 21:23:04 +03:00
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : set - > Slots ( ) )
2012-12-12 15:03:02 +03:00
{
2013-06-29 16:05:48 +03:00
ret [ elem . first . getNum ( ) ] = new CGarrisonSlot ( this , posX + ( elem . first . getNum ( ) * distance ) , posY , elem . first , Upg , elem . second ) ;
2012-12-12 15:03:02 +03:00
}
2009-05-19 21:23:04 +03:00
}
2010-08-27 19:20:35 +03:00
for ( int i = 0 ; i < ret . size ( ) ; i + + )
if ( ! ret [ i ] )
2013-06-26 14:18:27 +03:00
ret [ i ] = new CGarrisonSlot ( this , posX + ( i * distance ) , posY , SlotID ( i ) , Upg , nullptr ) ;
2010-08-27 19:20:35 +03:00
if ( twoRows )
for ( int i = 4 ; i < ret . size ( ) ; i + + )
2009-05-19 21:23:04 +03:00
{
2010-08-27 19:20:35 +03:00
ret [ i ] - > pos . x - = 126 ;
ret [ i ] - > pos . y + = 37 ;
} ;
2009-05-19 21:23:04 +03:00
}
2010-08-27 19:20:35 +03:00
2009-05-19 21:23:04 +03:00
void CGarrisonInt : : createSlots ( )
{
2010-08-27 19:20:35 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2011-11-27 16:14:20 +03:00
int width = smallIcons ? 32 : 58 ;
2009-06-28 11:21:50 +03:00
2012-12-12 15:03:02 +03:00
createSet ( slotsUp , armedObjs [ 0 ] , 0 , 0 , width + interx , 0 ) ;
createSet ( slotsDown , armedObjs [ 1 ] , garOffset . x , garOffset . y , width + interx , 1 ) ;
2009-05-19 21:23:04 +03:00
}
2010-08-27 19:20:35 +03:00
2009-05-19 21:23:04 +03:00
void CGarrisonInt : : recreateSlots ( )
{
2012-12-11 15:12:46 +03:00
selectSlot ( nullptr ) ;
2013-05-04 16:14:23 +03:00
setSplittingMode ( false ) ;
2009-09-09 09:04:42 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & elem : splitButtons )
elem - > block ( true ) ;
2009-09-09 09:04:42 +03:00
2012-12-11 15:12:46 +03:00
2013-06-29 16:05:48 +03:00
for ( CGarrisonSlot * slot : slotsUp )
2012-12-11 15:12:46 +03:00
slot - > update ( ) ;
2013-06-29 16:05:48 +03:00
for ( CGarrisonSlot * slot : slotsDown )
2012-12-11 15:12:46 +03:00
slot - > update ( ) ;
2009-05-19 21:23:04 +03:00
}
2010-08-27 19:20:35 +03:00
2009-05-19 21:23:04 +03:00
void CGarrisonInt : : splitClick ( )
{
2012-12-11 15:12:46 +03:00
if ( ! getSelection ( ) )
2009-05-19 21:23:04 +03:00
return ;
2012-12-11 15:12:46 +03:00
setSplittingMode ( ! getSplittingMode ( ) ) ;
2011-03-13 00:29:19 +02:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-06-13 16:04:06 +03:00
void CGarrisonInt : : splitStacks ( int , int amountRight )
2009-05-19 21:23:04 +03:00
{
2012-12-11 15:12:46 +03:00
LOCPLINT - > cb - > splitStack ( armedObjs [ getSelection ( ) - > upg ] , armedObjs [ pb ] , getSelection ( ) - > ID , p2 , amountRight ) ;
2009-05-19 21:23:04 +03:00
}
2011-02-05 15:39:10 +02:00
2012-01-12 18:23:00 +03:00
CGarrisonInt : : CGarrisonInt ( int x , int y , int inx , const Point & garsOffset ,
2012-12-11 15:12:46 +03:00
SDL_Surface * pomsur , const Point & SurOffset ,
const CArmedInstance * s1 , const CArmedInstance * s2 ,
bool _removableUnits , bool smallImgs , bool _twoRows ) :
highlighted ( nullptr ) ,
inSplittingMode ( false ) ,
interx ( inx ) ,
garOffset ( garsOffset ) ,
smallIcons ( smallImgs ) ,
removableUnits ( _removableUnits ) ,
twoRows ( _twoRows )
2009-05-19 21:23:04 +03:00
{
2011-02-05 15:39:10 +02:00
setArmy ( s1 , false ) ;
setArmy ( s2 , true ) ;
2010-08-27 19:20:35 +03:00
pos . x + = x ;
pos . y + = y ;
2009-05-19 21:23:04 +03:00
createSlots ( ) ;
}
2012-12-11 15:12:46 +03:00
const CGarrisonSlot * CGarrisonInt : : getSelection ( )
{
return highlighted ;
}
void CGarrisonInt : : selectSlot ( CGarrisonSlot * slot )
{
if ( slot ! = highlighted )
{
if ( highlighted )
highlighted - > setHighlight ( false ) ;
highlighted = slot ;
2013-06-29 16:05:48 +03:00
for ( auto button : splitButtons )
2012-12-12 15:03:02 +03:00
button - > block ( highlighted = = nullptr ) ;
2012-12-11 15:12:46 +03:00
if ( highlighted )
highlighted - > setHighlight ( true ) ;
}
}
void CGarrisonInt : : setSplittingMode ( bool on )
{
assert ( on = = false | | highlighted ! = nullptr ) ; //can't be in splitting mode without selection
if ( inSplittingMode | | on )
{
2013-06-29 16:05:48 +03:00
for ( CGarrisonSlot * slot : slotsUp )
2013-05-04 16:14:23 +03:00
slot - > setHighlight ( ( on & & ( slot - > creature = = nullptr | | slot - > creature = = getSelection ( ) - > creature ) ) ) ;
2012-12-11 15:12:46 +03:00
2013-06-29 16:05:48 +03:00
for ( CGarrisonSlot * slot : slotsDown )
2013-05-04 16:14:23 +03:00
slot - > setHighlight ( ( on & & ( slot - > creature = = nullptr | | slot - > creature = = getSelection ( ) - > creature ) ) ) ;
2012-12-11 15:12:46 +03:00
inSplittingMode = on ;
}
}
bool CGarrisonInt : : getSplittingMode ( )
{
return inSplittingMode ;
}
2011-02-05 15:39:10 +02:00
void CGarrisonInt : : setArmy ( const CArmedInstance * army , bool bottomGarrison )
{
2013-03-03 20:06:03 +03:00
owned [ bottomGarrison ] = army ? ( army - > tempOwner = = LOCPLINT - > playerID | | army - > tempOwner = = PlayerColor : : UNFLAGGABLE ) : false ;
2011-02-05 15:39:10 +02:00
armedObjs [ bottomGarrison ] = army ;
}
2013-03-03 20:06:03 +03:00
CInfoWindow : : CInfoWindow ( std : : string Text , PlayerColor player , const TCompsInfo & comps , const TButtonsInfo & Buttons , bool delComps )
2009-05-19 21:23:04 +03:00
{
2010-07-06 05:10:26 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2011-03-22 15:19:07 +02:00
type | = BLOCK_ADV_HOTKEYS ;
2013-05-27 13:53:28 +03:00
ID = QueryID ( - 1 ) ;
2013-06-29 16:05:48 +03:00
for ( auto & Button : Buttons )
2009-05-19 21:23:04 +03:00
{
2013-07-02 18:23:32 +03:00
CAdventureMapButton * button = new CAdventureMapButton ( " " , " " , boost : : bind ( & CInfoWindow : : close , this ) , 0 , 0 , Button . first ) ;
2012-11-20 20:53:45 +03:00
button - > borderColor = Colors : : METALLIC_GOLD ;
2011-04-26 16:30:29 +03:00
button - > borderEnabled = true ;
2013-06-29 16:05:48 +03:00
button - > callback . add ( Button . second ) ; //each button will close the window apart from call-defined actions
2011-04-26 16:30:29 +03:00
buttons . push_back ( button ) ;
2009-05-19 21:23:04 +03:00
}
2012-11-11 15:23:31 +03:00
text = new CTextBox ( Text , Rect ( 0 , 0 , 250 , 100 ) , 0 , FONT_MEDIUM , CENTER , Colors : : WHITE ) ;
2011-05-26 01:44:02 +03:00
if ( ! text - > slider )
{
2013-08-29 16:46:27 +03:00
text - > resize ( text - > label - > textSize ) ;
2011-05-26 01:44:02 +03:00
}
2010-07-06 05:10:26 +03:00
2011-03-12 23:55:31 +02:00
if ( buttons . size ( ) )
{
buttons . front ( ) - > assignedKeys . insert ( SDLK_RETURN ) ; //first button - reacts on enter
buttons . back ( ) - > assignedKeys . insert ( SDLK_ESCAPE ) ; //last button - reacts on escape
}
2009-05-19 21:23:04 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & comp : comps )
2009-05-19 21:23:04 +03:00
{
2013-06-29 16:05:48 +03:00
comp - > recActions = 0xff ;
addChild ( comp ) ;
comp - > recActions & = ~ ( SHOWALL | UPDATE ) ;
components . push_back ( comp ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-15 06:04:57 +03:00
setDelComps ( delComps ) ;
2010-07-26 18:37:58 +03:00
CMessage : : drawIWindow ( this , Text , player ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-06 05:10:26 +03:00
2012-01-12 18:23:00 +03:00
CInfoWindow : : CInfoWindow ( )
2009-05-19 21:23:04 +03:00
{
2013-05-27 13:53:28 +03:00
ID = QueryID ( - 1 ) ;
2010-07-15 06:04:57 +03:00
setDelComps ( false ) ;
2013-06-26 14:18:27 +03:00
text = nullptr ;
2011-02-23 13:21:40 +02:00
}
2011-02-20 11:24:53 +02:00
2009-05-19 21:23:04 +03:00
void CInfoWindow : : close ( )
{
2009-08-07 01:36:51 +03:00
GH . popIntTotally ( this ) ;
2009-11-24 22:29:50 +02:00
if ( LOCPLINT )
LOCPLINT - > showingDialog - > setn ( false ) ;
2009-05-19 21:23:04 +03:00
}
2011-02-20 11:24:53 +02:00
2009-05-19 21:23:04 +03:00
void CInfoWindow : : show ( SDL_Surface * to )
{
2010-07-06 05:10:26 +03:00
CIntObject : : show ( to ) ;
2009-05-19 21:23:04 +03:00
}
CInfoWindow : : ~ CInfoWindow ( )
{
2010-07-15 06:04:57 +03:00
if ( ! delComps )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : components )
removeChild ( elem ) ;
2010-07-15 06:04:57 +03:00
}
2009-05-19 21:23:04 +03:00
}
2009-08-17 11:50:31 +03:00
2011-12-22 16:05:19 +03:00
void CInfoWindow : : showAll ( SDL_Surface * to )
2009-08-17 11:50:31 +03:00
{
2010-07-06 05:10:26 +03:00
CSimpleWindow : : show ( to ) ;
CIntObject : : showAll ( to ) ;
2009-08-17 11:50:31 +03:00
}
2013-10-21 00:53:27 +03:00
void CInfoWindow : : showInfoDialog ( const std : : string & text , const std : : vector < CComponent * > * components , bool DelComps , PlayerColor player )
{
CInfoWindow * window = CInfoWindow : : create ( text , player , components , DelComps ) ;
GH . pushInt ( window ) ;
}
2013-03-03 20:06:03 +03:00
void CInfoWindow : : showYesNoDialog ( const std : : string & text , const std : : vector < CComponent * > * components , const CFunctionList < void ( ) > & onYes , const CFunctionList < void ( ) > & onNo , bool DelComps , PlayerColor player )
2009-11-13 21:04:36 +02:00
{
assert ( ! LOCPLINT | | LOCPLINT - > showingDialog - > get ( ) ) ;
std : : vector < std : : pair < std : : string , CFunctionList < void ( ) > > > pom ;
pom . push_back ( std : : pair < std : : string , CFunctionList < void ( ) > > ( " IOKAY.DEF " , 0 ) ) ;
2010-08-18 13:52:30 +03:00
pom . push_back ( std : : pair < std : : string , CFunctionList < void ( ) > > ( " ICANCEL.DEF " , 0 ) ) ;
2011-12-22 16:05:19 +03:00
CInfoWindow * temp = new CInfoWindow ( text , player , components ? * components : std : : vector < CComponent * > ( ) , pom , DelComps ) ;
2013-06-29 16:05:48 +03:00
for ( auto & elem : onYes . funcs )
temp - > buttons [ 0 ] - > callback + = elem ;
for ( auto & elem : onNo . funcs )
temp - > buttons [ 1 ] - > callback + = elem ;
2009-11-13 21:04:36 +02:00
GH . pushInt ( temp ) ;
}
2013-11-30 12:43:31 +03:00
void CInfoWindow : : showOkDialog ( const std : : string & text , const std : : vector < CComponent * > * components , const boost : : function < void ( ) > & onOk , bool delComps , PlayerColor player )
{
std : : vector < std : : pair < std : : string , CFunctionList < void ( ) > > > pom ;
pom . push_back ( std : : pair < std : : string , CFunctionList < void ( ) > > ( " IOKAY.DEF " , 0 ) ) ;
CInfoWindow * temp = new CInfoWindow ( text , player , * components , pom , delComps ) ;
temp - > buttons [ 0 ] - > callback + = onOk ;
GH . pushInt ( temp ) ;
}
2013-06-26 14:18:27 +03:00
CInfoWindow * CInfoWindow : : create ( const std : : string & text , PlayerColor playerID /*= 1*/ , const std : : vector < CComponent * > * components /*= nullptr*/ , bool DelComps )
2010-03-08 00:56:51 +02:00
{
std : : vector < std : : pair < std : : string , CFunctionList < void ( ) > > > pom ;
pom . push_back ( std : : pair < std : : string , CFunctionList < void ( ) > > ( " IOKAY.DEF " , 0 ) ) ;
2011-12-22 16:05:19 +03:00
CInfoWindow * ret = new CInfoWindow ( text , playerID , components ? * components : std : : vector < CComponent * > ( ) , pom , DelComps ) ;
2010-03-08 00:56:51 +02:00
return ret ;
}
2012-12-11 15:12:46 +03:00
std : : string CInfoWindow : : genText ( std : : string title , std : : string description )
{
return std : : string ( " { " ) + title + " } " + " \n \n " + description ;
}
2010-07-15 06:04:57 +03:00
void CInfoWindow : : setDelComps ( bool DelComps )
{
delComps = DelComps ;
2013-06-29 16:05:48 +03:00
for ( CComponent * comp : components )
2010-07-15 06:04:57 +03:00
{
if ( delComps )
comp - > recActions | = DISPOSE ;
else
comp - > recActions & = ~ DISPOSE ;
}
}
2009-05-19 21:23:04 +03:00
CInfoPopup : : CInfoPopup ( SDL_Surface * Bitmap , int x , int y , bool Free )
: free ( Free ) , bitmap ( Bitmap )
{
2010-03-21 00:17:19 +02:00
init ( x , y ) ;
}
2009-10-22 06:12:01 +03:00
2009-06-02 06:01:17 +03:00
2011-12-22 16:05:19 +03:00
CInfoPopup : : CInfoPopup ( SDL_Surface * Bitmap , const Point & p , EAlignment alignment , bool Free /*=false*/ )
2010-03-21 00:17:19 +02:00
: free ( Free ) , bitmap ( Bitmap )
{
switch ( alignment )
{
case BOTTOMRIGHT :
init ( p . x - Bitmap - > w , p . y - Bitmap - > h ) ;
break ;
case CENTER :
init ( p . x - Bitmap - > w / 2 , p . y - Bitmap - > h / 2 ) ;
break ;
case TOPLEFT :
init ( p . x , p . y ) ;
break ;
default :
assert ( 0 ) ; //not implemented
}
2009-05-19 21:23:04 +03:00
}
2009-05-22 02:50:45 +03:00
CInfoPopup : : CInfoPopup ( SDL_Surface * Bitmap , bool Free )
{
2010-12-19 16:39:56 +02:00
CCS - > curh - > hide ( ) ;
2009-10-22 06:12:01 +03:00
2009-05-22 02:50:45 +03:00
free = Free ;
bitmap = Bitmap ;
2009-08-22 16:59:15 +03:00
2009-08-23 21:23:21 +03:00
if ( bitmap )
{
pos . x = screen - > w / 2 - bitmap - > w / 2 ;
pos . y = screen - > h / 2 - bitmap - > h / 2 ;
pos . h = bitmap - > h ;
pos . w = bitmap - > w ;
}
2009-05-22 02:50:45 +03:00
}
2009-05-19 21:23:04 +03:00
void CInfoPopup : : close ( )
{
if ( free )
SDL_FreeSurface ( bitmap ) ;
2009-08-07 01:36:51 +03:00
GH . popIntTotally ( this ) ;
2009-05-19 21:23:04 +03:00
}
void CInfoPopup : : show ( SDL_Surface * to )
{
blitAt ( bitmap , pos . x , pos . y , to ) ;
}
2009-10-22 06:12:01 +03:00
CInfoPopup : : ~ CInfoPopup ( )
{
2010-12-19 16:39:56 +02:00
CCS - > curh - > show ( ) ;
2009-10-22 06:12:01 +03:00
}
2009-05-19 21:23:04 +03:00
2010-03-21 00:17:19 +02:00
void CInfoPopup : : init ( int x , int y )
{
2010-12-19 16:39:56 +02:00
CCS - > curh - > hide ( ) ;
2010-03-21 00:17:19 +02:00
pos . x = x ;
pos . y = y ;
pos . h = bitmap - > h ;
pos . w = bitmap - > w ;
// Put the window back on screen if necessary
2011-12-14 00:23:17 +03:00
vstd : : amax ( pos . x , 0 ) ;
vstd : : amax ( pos . y , 0 ) ;
2012-01-12 18:23:00 +03:00
vstd : : amin ( pos . x , screen - > w - bitmap - > w ) ;
vstd : : amin ( pos . y , screen - > h - bitmap - > h ) ;
2010-03-21 00:17:19 +02:00
}
2012-07-07 16:32:37 +03:00
CComponent : : CComponent ( Etype Type , int Subtype , int Val , ESize imageSize ) :
2012-07-03 00:51:48 +03:00
image ( nullptr ) ,
perDay ( false )
2009-05-19 21:23:04 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( RCLICK ) ;
2012-07-07 16:32:37 +03:00
init ( Type , Subtype , Val , imageSize ) ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
CComponent : : CComponent ( const Component & c ) :
2012-07-03 00:51:48 +03:00
image ( nullptr ) ,
perDay ( false )
2009-05-19 21:23:04 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( RCLICK ) ;
2012-05-13 18:04:21 +03:00
2012-07-03 00:51:48 +03:00
if ( c . id = = Component : : RESOURCE & & c . when = = - 1 )
perDay = true ;
2012-07-21 23:16:54 +03:00
init ( ( Etype ) c . id , c . subtype , c . val , large ) ;
2009-05-19 21:23:04 +03:00
}
2010-08-18 17:24:30 +03:00
2012-07-07 16:32:37 +03:00
void CComponent : : init ( Etype Type , int Subtype , int Val , ESize imageSize )
2010-08-18 17:24:30 +03:00
{
2012-07-03 00:51:48 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
compType = Type ;
2012-05-13 18:04:21 +03:00
subtype = Subtype ;
val = Val ;
2012-07-07 16:32:37 +03:00
size = imageSize ;
2012-05-13 18:04:21 +03:00
2012-07-21 23:16:54 +03:00
assert ( compType < typeInvalid ) ;
assert ( size < sizeInvalid ) ;
2012-07-07 16:32:37 +03:00
setSurface ( getFileName ( ) [ size ] , getIndex ( ) ) ;
2012-05-13 18:04:21 +03:00
pos . w = image - > pos . w ;
pos . h = image - > pos . h ;
2012-07-03 00:51:48 +03:00
2012-12-10 17:28:27 +03:00
EFonts font = FONT_SMALL ;
if ( imageSize < small )
font = FONT_TINY ; //other sizes?
2012-07-07 16:32:37 +03:00
pos . h + = 4 ; //distance between text and image
2012-12-10 17:28:27 +03:00
std : : vector < std : : string > textLines = CMessage : : breakText ( getSubtitle ( ) , std : : max < int > ( 80 , pos . w ) , font ) ;
2013-06-29 16:05:48 +03:00
for ( auto & line : textLines )
2012-07-03 00:51:48 +03:00
{
2012-12-19 20:24:53 +03:00
int height = graphics - > fonts [ font ] - > getLineHeight ( ) ;
2013-06-29 16:05:48 +03:00
auto label = new CLabel ( pos . w / 2 , pos . h + height / 2 , font , CENTER , Colors : : WHITE , line ) ;
2012-07-03 00:51:48 +03:00
2012-07-07 16:32:37 +03:00
pos . h + = height ;
if ( label - > pos . w > pos . w )
2012-07-03 00:51:48 +03:00
{
2012-07-07 16:32:37 +03:00
pos . x - = ( label - > pos . w - pos . w ) / 2 ;
pos . w = label - > pos . w ;
2012-07-03 00:51:48 +03:00
}
}
2010-08-18 17:24:30 +03:00
}
2012-07-07 16:32:37 +03:00
const std : : vector < std : : string > CComponent : : getFileName ( )
2012-05-13 18:04:21 +03:00
{
2012-07-07 16:32:37 +03:00
static const std : : string primSkillsArr [ ] = { " PSKIL32 " , " PSKIL32 " , " PSKIL42 " , " PSKILL " } ;
static const std : : string secSkillsArr [ ] = { " SECSK32 " , " SECSK32 " , " SECSKILL " , " SECSK82 " } ;
static const std : : string resourceArr [ ] = { " SMALRES " , " RESOURCE " , " RESOUR82 " , " RESOUR82 " } ;
static const std : : string creatureArr [ ] = { " CPRSMALL " , " CPRSMALL " , " TWCRPORT " , " TWCRPORT " } ;
static const std : : string artifactArr [ ] = { " Artifact " , " Artifact " , " Artifact " , " Artifact " } ;
static const std : : string spellsArr [ ] = { " SpellInt " , " SpellInt " , " SPELLSCR " , " SPELLSCR " } ;
static const std : : string moraleArr [ ] = { " IMRL22 " , " IMRL30 " , " IMRL42 " , " imrl82 " } ;
static const std : : string luckArr [ ] = { " ILCK22 " , " ILCK30 " , " ILCK42 " , " ilck82 " } ;
static const std : : string heroArr [ ] = { " PortraitsSmall " , " PortraitsSmall " , " PortraitsLarge " , " PortraitsLarge " } ;
static const std : : string flagArr [ ] = { " CREST58 " , " CREST58 " , " CREST58 " , " CREST58 " } ;
auto gen = [ ] ( const std : : string * arr )
{
return std : : vector < std : : string > ( arr , arr + 4 ) ;
} ;
2012-07-03 00:51:48 +03:00
switch ( compType )
2012-05-13 18:04:21 +03:00
{
2012-07-07 16:32:37 +03:00
case primskill : return gen ( primSkillsArr ) ;
case secskill : return gen ( secSkillsArr ) ;
case resource : return gen ( resourceArr ) ;
case creature : return gen ( creatureArr ) ;
case artifact : return gen ( artifactArr ) ;
case experience : return gen ( primSkillsArr ) ;
case spell : return gen ( spellsArr ) ;
case morale : return gen ( moraleArr ) ;
case luck : return gen ( luckArr ) ;
2013-04-21 15:49:26 +03:00
case building : return std : : vector < std : : string > ( 4 , CGI - > townh - > factions [ subtype ] - > town - > clientInfo . buildingsIcons ) ;
2012-07-07 16:32:37 +03:00
case hero : return gen ( heroArr ) ;
case flag : return gen ( flagArr ) ;
2012-05-13 18:04:21 +03:00
}
assert ( 0 ) ;
2012-07-07 16:32:37 +03:00
return std : : vector < std : : string > ( ) ;
2010-08-18 17:24:30 +03:00
}
2012-05-13 18:04:21 +03:00
size_t CComponent : : getIndex ( )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
switch ( compType )
2012-05-13 18:04:21 +03:00
{
case primskill : return subtype ;
case secskill : return subtype * 3 + 3 + val - 1 ;
case resource : return subtype ;
2012-09-22 18:10:15 +03:00
case creature : return CGI - > creh - > creatures [ subtype ] - > iconIndex ;
2012-12-14 18:32:53 +03:00
case artifact : return CGI - > arth - > artifacts [ subtype ] - > iconIndex ;
2012-05-13 18:04:21 +03:00
case experience : return 4 ;
case spell : return subtype ;
case morale : return val + 3 ;
case luck : return val + 3 ;
case building : return val ;
2013-09-21 21:29:26 +03:00
case hero : return subtype ;
2012-05-13 18:04:21 +03:00
case flag : return subtype ;
}
assert ( 0 ) ;
return 0 ;
2009-05-19 21:23:04 +03:00
}
2010-08-18 17:24:30 +03:00
2012-05-13 18:04:21 +03:00
std : : string CComponent : : getDescription ( )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
switch ( compType )
2009-05-19 21:23:04 +03:00
{
2012-05-13 18:04:21 +03:00
case primskill : return ( subtype < 4 ) ? CGI - > generaltexth - > arraytxt [ 2 + subtype ] //Primary skill
: CGI - > generaltexth - > allTexts [ 149 ] ; //mana
case secskill : return CGI - > generaltexth - > skillInfoTexts [ subtype ] [ val - 1 ] ;
case resource : return CGI - > generaltexth - > allTexts [ 242 ] ;
case creature : return " " ;
2012-09-22 18:10:15 +03:00
case artifact : return CGI - > arth - > artifacts [ subtype ] - > Description ( ) ;
2012-05-13 18:04:21 +03:00
case experience : return CGI - > generaltexth - > allTexts [ 241 ] ;
2014-03-17 16:11:10 +03:00
case spell : return CGI - > spellh - > objects [ subtype ] - > getLevelInfo ( val ) . description ;
2012-05-13 18:04:21 +03:00
case morale : return CGI - > generaltexth - > heroscrn [ 4 - ( val > 0 ) + ( val < 0 ) ] ;
case luck : return CGI - > generaltexth - > heroscrn [ 7 - ( val > 0 ) + ( val < 0 ) ] ;
2013-04-21 15:49:26 +03:00
case building : return CGI - > townh - > factions [ subtype ] - > town - > buildings [ BuildingID ( val ) ] - > Description ( ) ;
2013-09-21 21:29:26 +03:00
case hero : return " " ;
2012-05-13 18:04:21 +03:00
case flag : return " " ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
assert ( 0 ) ;
2012-07-03 00:51:48 +03:00
return " " ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
std : : string CComponent : : getSubtitle ( )
2012-07-03 00:51:48 +03:00
{
if ( ! perDay )
return getSubtitleInternal ( ) ;
std : : string ret = CGI - > generaltexth - > allTexts [ 3 ] ;
boost : : replace_first ( ret , " %d " , getSubtitleInternal ( ) ) ;
return ret ;
}
std : : string CComponent : : getSubtitleInternal ( )
2009-05-19 21:23:04 +03:00
{
2012-05-13 18:04:21 +03:00
//FIXME: some of these are horrible (e.g creature)
2012-07-03 00:51:48 +03:00
switch ( compType )
2012-05-13 18:04:21 +03:00
{
case primskill : return boost : : str ( boost : : format ( " %+d %s " ) % val % ( subtype < 4 ? CGI - > generaltexth - > primarySkillNames [ subtype ] : CGI - > generaltexth - > allTexts [ 387 ] ) ) ;
2012-07-07 16:32:37 +03:00
case secskill : return CGI - > generaltexth - > levels [ val - 1 ] + " \n " + CGI - > generaltexth - > skillName [ subtype ] ;
2012-05-13 18:04:21 +03:00
case resource : return boost : : lexical_cast < std : : string > ( val ) ;
case creature : return ( val ? boost : : lexical_cast < std : : string > ( val ) + " " : " " ) + CGI - > creh - > creatures [ subtype ] - > * ( val ! = 1 ? & CCreature : : namePl : & CCreature : : nameSing ) ;
case artifact : return CGI - > arth - > artifacts [ subtype ] - > Name ( ) ;
2013-07-23 18:03:01 +03:00
case experience :
{
if ( subtype = = 1 ) //+1 level - tree of knowledge
{
std : : string level = CGI - > generaltexth - > allTexts [ 442 ] ;
boost : : replace_first ( level , " 1 " , boost : : lexical_cast < std : : string > ( val ) ) ;
return level ;
}
else
return boost : : lexical_cast < std : : string > ( val ) ; //amount of experience OR level required for seer hut;
}
2014-03-07 16:21:09 +03:00
case spell : return CGI - > spellh - > objects [ subtype ] - > name ;
2012-05-13 18:04:21 +03:00
case morale : return " " ;
case luck : return " " ;
2013-04-21 15:49:26 +03:00
case building : return CGI - > townh - > factions [ subtype ] - > town - > buildings [ BuildingID ( val ) ] - > Name ( ) ;
2013-09-21 21:29:26 +03:00
case hero : return " " ;
2012-05-13 18:04:21 +03:00
case flag : return CGI - > generaltexth - > capColors [ subtype ] ;
}
assert ( 0 ) ;
return " " ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
void CComponent : : setSurface ( std : : string defName , int imgPos )
2009-05-19 21:23:04 +03:00
{
2012-05-13 18:04:21 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-02 18:16:54 +03:00
vstd : : clear_pointer ( image ) ;
2012-05-13 18:04:21 +03:00
image = new CAnimImage ( defName , imgPos ) ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
void CComponent : : clickRight ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
if ( ! getDescription ( ) . empty ( ) )
adventureInt - > handleRightClick ( getDescription ( ) , down ) ;
2009-05-19 21:23:04 +03:00
}
2009-08-11 19:05:33 +03:00
void CSelectableComponent : : clickLeft ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
if ( down )
{
if ( onSelect )
onSelect ( ) ;
}
}
2012-05-13 18:04:21 +03:00
2010-08-12 08:22:48 +03:00
void CSelectableComponent : : init ( )
2009-05-19 21:23:04 +03:00
{
selected = false ;
}
2012-05-13 18:04:21 +03:00
2013-06-26 14:18:27 +03:00
CSelectableComponent : : CSelectableComponent ( const Component & c , std : : function < void ( ) > OnSelect ) :
2012-05-13 18:04:21 +03:00
CComponent ( c ) , onSelect ( OnSelect )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
type | = REDRAW_PARENT ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | KEYBOARD ) ;
2010-08-12 08:22:48 +03:00
init ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
2013-06-26 14:18:27 +03:00
CSelectableComponent : : CSelectableComponent ( Etype Type , int Sub , int Val , ESize imageSize , std : : function < void ( ) > OnSelect ) :
2012-07-07 16:32:37 +03:00
CComponent ( Type , Sub , Val , imageSize ) , onSelect ( OnSelect )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
type | = REDRAW_PARENT ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | KEYBOARD ) ;
2010-08-12 08:22:48 +03:00
init ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
2009-05-19 21:23:04 +03:00
void CSelectableComponent : : select ( bool on )
{
if ( on ! = selected )
{
selected = on ;
2012-07-03 00:51:48 +03:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-07-03 00:51:48 +03:00
}
void CSelectableComponent : : showAll ( SDL_Surface * to )
{
CComponent : : showAll ( to ) ;
if ( selected )
2009-05-19 21:23:04 +03:00
{
2012-07-03 00:51:48 +03:00
CSDL_Ext : : drawBorder ( to , Rect : : around ( image - > pos ) , int3 ( 239 , 215 , 123 ) ) ;
2009-05-19 21:23:04 +03:00
}
}
2012-05-13 18:04:21 +03:00
2012-07-03 00:51:48 +03:00
void CComponentBox : : selectionChanged ( CSelectableComponent * newSelection )
2009-05-19 21:23:04 +03:00
{
2012-07-07 16:32:37 +03:00
if ( newSelection = = selected )
return ;
2012-07-03 00:51:48 +03:00
if ( selected )
selected - > select ( false ) ;
selected = newSelection ;
2012-07-07 16:32:37 +03:00
if ( onSelect )
onSelect ( selectedIndex ( ) ) ;
2012-07-03 00:51:48 +03:00
if ( selected )
selected - > select ( true ) ;
}
int CComponentBox : : selectedIndex ( )
{
if ( selected )
return std : : find ( components . begin ( ) , components . end ( ) , selected ) - components . begin ( ) ;
return - 1 ;
}
2012-07-07 16:32:37 +03:00
Point CComponentBox : : getOrTextPos ( CComponent * left , CComponent * right )
{
int leftSubtitle = ( left - > pos . w - left - > image - > pos . w ) / 2 ;
int rightSubtitle = ( right - > pos . w - right - > image - > pos . w ) / 2 ;
int fullDistance = getDistance ( left , right ) + leftSubtitle + rightSubtitle ;
return Point ( fullDistance / 2 - leftSubtitle , ( left - > image - > pos . h + right - > image - > pos . h ) / 4 ) ;
}
int CComponentBox : : getDistance ( CComponent * left , CComponent * right )
{
2012-12-10 17:28:27 +03:00
static const int betweenImagesMin = 20 ;
2012-07-07 16:32:37 +03:00
static const int betweenSubtitlesMin = 10 ;
int leftSubtitle = ( left - > pos . w - left - > image - > pos . w ) / 2 ;
int rightSubtitle = ( right - > pos . w - right - > image - > pos . w ) / 2 ;
int subtitlesOffset = leftSubtitle + rightSubtitle ;
return std : : max ( betweenSubtitlesMin , betweenImagesMin - subtitlesOffset ) ;
}
2012-07-03 00:51:48 +03:00
void CComponentBox : : placeComponents ( bool selectable )
{
2012-07-07 16:32:37 +03:00
static const int betweenRows = 22 ;
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-07-03 00:51:48 +03:00
if ( components . empty ( ) )
return ;
//prepare components
2013-06-29 16:05:48 +03:00
for ( auto & comp : components )
2012-07-03 00:51:48 +03:00
{
addChild ( comp ) ;
comp - > moveTo ( Point ( pos . x , pos . y ) ) ;
}
struct RowData
{
size_t comps ;
int width ;
int height ;
2012-07-03 09:28:11 +03:00
RowData ( size_t Comps , int Width , int Height ) :
comps ( Comps ) , width ( Width ) , height ( Height ) { } ;
2012-07-03 00:51:48 +03:00
} ;
std : : vector < RowData > rows ;
2012-07-03 09:28:11 +03:00
rows . push_back ( RowData ( 0 , 0 , 0 ) ) ;
2012-07-03 00:51:48 +03:00
//split components in rows
2012-07-07 16:32:37 +03:00
CComponent * prevComp = nullptr ;
2013-06-29 16:05:48 +03:00
for ( CComponent * comp : components )
2010-08-18 13:58:41 +03:00
{
2012-07-03 00:51:48 +03:00
//make sure that components are smaller than our width
2012-07-07 16:32:37 +03:00
//assert(pos.w == 0 || pos.w < comp->pos.w);
const int distance = prevComp ? getDistance ( prevComp , comp ) : 0 ;
2012-07-03 00:51:48 +03:00
//start next row
2012-12-20 16:57:29 +03:00
if ( ( pos . w ! = 0 & & rows . back ( ) . width + comp - > pos . w + distance > pos . w ) // row is full
| | rows . back ( ) . comps > = 4 ) // no more than 4 comps per row
2012-07-07 16:32:37 +03:00
{
prevComp = nullptr ;
2012-07-03 09:28:11 +03:00
rows . push_back ( RowData ( 0 , 0 , 0 ) ) ;
2012-07-07 16:32:37 +03:00
}
if ( prevComp )
rows . back ( ) . width + = distance ;
2012-07-03 00:51:48 +03:00
rows . back ( ) . comps + + ;
rows . back ( ) . width + = comp - > pos . w ;
2012-07-07 16:32:37 +03:00
2012-07-03 00:51:48 +03:00
vstd : : amax ( rows . back ( ) . height , comp - > pos . h ) ;
2012-07-07 16:32:37 +03:00
prevComp = comp ;
2010-08-18 13:58:41 +03:00
}
2012-01-12 18:23:00 +03:00
2012-07-03 00:51:48 +03:00
if ( pos . w = = 0 )
{
2013-06-29 16:05:48 +03:00
for ( auto & row : rows )
2012-07-07 16:32:37 +03:00
vstd : : amax ( pos . w , row . width ) ;
2012-07-03 00:51:48 +03:00
}
int height = ( rows . size ( ) - 1 ) * betweenRows ;
2013-06-29 16:05:48 +03:00
for ( auto & row : rows )
2012-07-03 00:51:48 +03:00
height + = row . height ;
2012-07-07 16:32:37 +03:00
//assert(pos.h == 0 || pos.h < height);
2012-07-03 00:51:48 +03:00
if ( pos . h = = 0 )
pos . h = height ;
auto iter = components . begin ( ) ;
int currentY = ( pos . h - height ) / 2 ;
//move components to their positions
2013-06-29 16:05:48 +03:00
for ( auto & rows_row : rows )
2012-07-03 00:51:48 +03:00
{
2012-12-20 16:57:29 +03:00
// amount of free space we may add on each side of every component
2013-06-29 16:05:48 +03:00
int freeSpace = ( pos . w - rows_row . width ) / ( rows_row . comps * 2 ) ;
2012-07-07 16:32:37 +03:00
prevComp = nullptr ;
2012-12-20 16:57:29 +03:00
int currentX = 0 ;
2013-06-29 16:05:48 +03:00
for ( size_t col = 0 ; col < rows_row . comps ; col + + )
2012-07-03 00:51:48 +03:00
{
2012-12-20 16:57:29 +03:00
currentX + = freeSpace ;
2012-07-07 16:32:37 +03:00
if ( prevComp )
{
if ( selectable )
{
2013-01-23 02:28:10 +03:00
Point orPos = Point ( currentX - freeSpace , currentY ) + getOrTextPos ( prevComp , * iter ) ;
2012-07-07 16:32:37 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( orPos . x , orPos . y , FONT_MEDIUM , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 4 ] ) ;
2012-07-07 16:32:37 +03:00
}
currentX + = getDistance ( prevComp , * iter ) ;
}
2012-07-03 00:51:48 +03:00
( * iter ) - > moveBy ( Point ( currentX , currentY ) ) ;
2012-07-07 16:32:37 +03:00
currentX + = ( * iter ) - > pos . w ;
2012-12-20 16:57:29 +03:00
currentX + = freeSpace ;
2012-07-07 16:32:37 +03:00
prevComp = * ( iter + + ) ;
2012-07-03 00:51:48 +03:00
}
2013-06-29 16:05:48 +03:00
currentY + = rows_row . height + betweenRows ;
2012-07-03 00:51:48 +03:00
}
}
CComponentBox : : CComponentBox ( CComponent * _components , Rect position ) :
components ( 1 , _components ) ,
selected ( nullptr )
{
2012-07-07 16:32:37 +03:00
type | = REDRAW_PARENT ;
pos = position + pos ;
2012-07-03 00:51:48 +03:00
placeComponents ( false ) ;
}
CComponentBox : : CComponentBox ( std : : vector < CComponent * > _components , Rect position ) :
components ( _components ) ,
selected ( nullptr )
{
2012-07-07 16:32:37 +03:00
type | = REDRAW_PARENT ;
pos = position + pos ;
2012-07-03 00:51:48 +03:00
placeComponents ( false ) ;
}
2013-06-26 14:18:27 +03:00
CComponentBox : : CComponentBox ( std : : vector < CSelectableComponent * > _components , Rect position , std : : function < void ( int newID ) > _onSelect ) :
2012-07-03 00:51:48 +03:00
components ( _components . begin ( ) , _components . end ( ) ) ,
2012-07-07 16:32:37 +03:00
selected ( nullptr ) ,
onSelect ( _onSelect )
2012-07-03 00:51:48 +03:00
{
2012-07-07 16:32:37 +03:00
type | = REDRAW_PARENT ;
pos = position + pos ;
2012-07-03 00:51:48 +03:00
placeComponents ( true ) ;
2012-07-07 16:32:37 +03:00
assert ( ! components . empty ( ) ) ;
int key = SDLK_1 ;
2013-06-29 16:05:48 +03:00
for ( auto & comp : _components )
2012-07-07 16:32:37 +03:00
{
2013-07-02 18:23:32 +03:00
comp - > onSelect = boost : : bind ( & CComponentBox : : selectionChanged , this , comp ) ;
2012-07-07 16:32:37 +03:00
comp - > assignedKeys . insert ( key + + ) ;
}
selectionChanged ( _components . front ( ) ) ;
2009-05-19 21:23:04 +03:00
}
void CSelWindow : : selectionChange ( unsigned to )
{
for ( unsigned i = 0 ; i < components . size ( ) ; i + + )
{
CSelectableComponent * pom = dynamic_cast < CSelectableComponent * > ( components [ i ] ) ;
if ( ! pom )
continue ;
pom - > select ( i = = to ) ;
}
2012-05-13 18:04:21 +03:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-05-13 18:04:21 +03:00
2013-05-27 13:53:28 +03:00
CSelWindow : : CSelWindow ( const std : : string & Text , PlayerColor player , int charperline , const std : : vector < CSelectableComponent * > & comps , const std : : vector < std : : pair < std : : string , CFunctionList < void ( ) > > > & Buttons , QueryID askID )
2009-05-19 21:23:04 +03:00
{
2010-07-26 18:37:58 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2009-05-19 21:23:04 +03:00
ID = askID ;
for ( int i = 0 ; i < Buttons . size ( ) ; i + + )
{
2011-12-22 16:05:19 +03:00
buttons . push_back ( new CAdventureMapButton ( " " , " " , Buttons [ i ] . second , 0 , 0 , Buttons [ i ] . first ) ) ;
2013-05-27 13:53:28 +03:00
if ( ! i & & askID . getNum ( ) > = 0 )
2013-07-02 18:23:32 +03:00
buttons . back ( ) - > callback + = boost : : bind ( & CSelWindow : : madeChoice , this ) ;
buttons [ i ] - > callback + = boost : : bind ( & CInfoWindow : : close , this ) ; //each button will close the window apart from call-defined actions
2009-05-19 21:23:04 +03:00
}
2012-11-11 15:23:31 +03:00
text = new CTextBox ( Text , Rect ( 0 , 0 , 250 , 100 ) , 0 , FONT_MEDIUM , CENTER , Colors : : WHITE ) ;
2010-07-26 18:37:58 +03:00
2009-05-19 21:23:04 +03:00
buttons . front ( ) - > assignedKeys . insert ( SDLK_RETURN ) ; //first button - reacts on enter
buttons . back ( ) - > assignedKeys . insert ( SDLK_ESCAPE ) ; //last button - reacts on escape
2013-05-27 13:53:28 +03:00
if ( buttons . size ( ) > 1 & & askID . getNum ( ) > = 0 ) //cancel button functionality
2013-07-02 18:23:32 +03:00
buttons . back ( ) - > callback + = boost : : bind ( & CCallback : : selectionMade , LOCPLINT - > cb . get ( ) , 0 , askID ) ;
2009-05-19 21:23:04 +03:00
for ( int i = 0 ; i < comps . size ( ) ; i + + )
{
2010-07-06 05:10:26 +03:00
comps [ i ] - > recActions = 255 ;
addChild ( comps [ i ] ) ;
2009-05-19 21:23:04 +03:00
components . push_back ( comps [ i ] ) ;
2013-07-02 18:23:32 +03:00
comps [ i ] - > onSelect = boost : : bind ( & CSelWindow : : selectionChange , this , i ) ;
2009-05-19 21:23:04 +03:00
if ( i < 9 )
comps [ i ] - > assignedKeys . insert ( SDLK_1 + i ) ;
}
2010-07-26 18:37:58 +03:00
CMessage : : drawIWindow ( this , Text , player ) ;
2009-05-19 21:23:04 +03:00
}
void CSelWindow : : madeChoice ( )
{
2013-05-27 13:53:28 +03:00
if ( ID . getNum ( ) < 0 )
2009-05-19 21:23:04 +03:00
return ;
int ret = - 1 ;
for ( int i = 0 ; i < components . size ( ) ; i + + )
{
if ( dynamic_cast < CSelectableComponent * > ( components [ i ] ) - > selected )
{
ret = i ;
}
}
LOCPLINT - > cb - > selectionMade ( ret + 1 , ID ) ;
}
2010-11-15 17:15:00 +02:00
CCreaturePic : : CCreaturePic ( int x , int y , const CCreature * cre , bool Big , bool Animated )
2009-05-19 21:23:04 +03:00
{
2010-11-15 17:15:00 +02:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
pos . x + = x ;
pos . y + = y ;
2012-01-12 18:23:00 +03:00
2012-09-29 18:10:56 +03:00
TFaction faction = cre - > faction ;
2013-04-21 15:49:26 +03:00
assert ( CGI - > townh - > factions . size ( ) > faction ) ;
2012-09-29 18:10:56 +03:00
2011-02-06 19:26:27 +02:00
if ( Big )
2013-04-21 15:49:26 +03:00
bg = new CPicture ( CGI - > townh - > factions [ faction ] - > creatureBg130 ) ;
2011-02-06 19:26:27 +02:00
else
2013-04-21 15:49:26 +03:00
bg = new CPicture ( CGI - > townh - > factions [ faction ] - > creatureBg120 ) ;
2011-02-06 19:26:27 +02:00
bg - > needRefresh = true ;
2011-12-22 16:05:19 +03:00
anim = new CCreatureAnim ( 0 , 0 , cre - > animDefName , Rect ( ) ) ;
2012-06-27 23:44:01 +03:00
anim - > clipRect ( cre - > isDoubleWide ( ) ? 170 : 150 , 155 , bg - > pos . w , bg - > pos . h ) ;
anim - > startPreview ( cre - > hasBonusOfType ( Bonus : : SIEGE_WEAPON ) ) ;
2012-06-22 14:40:16 +03:00
pos . w = bg - > pos . w ;
pos . h = bg - > pos . h ;
2009-05-19 21:23:04 +03:00
}
2010-11-15 17:15:00 +02:00
2012-06-22 14:40:16 +03:00
CRecruitmentWindow : : CCreatureCard : : CCreatureCard ( CRecruitmentWindow * window , const CCreature * crea , int totalAmount ) :
CIntObject ( LCLICK | RCLICK ) ,
parent ( window ) ,
selected ( false ) ,
creature ( crea ) ,
amount ( totalAmount )
2009-05-19 21:23:04 +03:00
{
2012-06-22 14:40:16 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
pic = new CCreaturePic ( 1 , 1 , creature , true , true ) ;
// 1 + 1 px for borders
pos . w = pic - > pos . w + 2 ;
pos . h = pic - > pos . h + 2 ;
}
void CRecruitmentWindow : : CCreatureCard : : select ( bool on )
{
selected = on ;
redraw ( ) ;
}
void CRecruitmentWindow : : CCreatureCard : : clickLeft ( tribool down , bool previousState )
{
if ( down )
parent - > select ( this ) ;
}
void CRecruitmentWindow : : CCreatureCard : : clickRight ( tribool down , bool previousState )
{
if ( down )
2013-01-31 00:28:31 +03:00
GH . pushInt ( createCreWindow ( creature - > idNumber , CCreatureWindow : : OTHER , 0 ) ) ;
2012-06-22 14:40:16 +03:00
}
void CRecruitmentWindow : : CCreatureCard : : showAll ( SDL_Surface * to )
{
CIntObject : : showAll ( to ) ;
if ( selected )
drawBorder ( to , pos , int3 ( 248 , 0 , 0 ) ) ;
else
drawBorder ( to , pos , int3 ( 232 , 212 , 120 ) ) ;
}
CRecruitmentWindow : : CCostBox : : CCostBox ( Rect position , std : : string title )
{
type | = REDRAW_PARENT ;
pos = position + pos ;
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-11-11 15:23:31 +03:00
new CLabel ( pos . w / 2 , 10 , FONT_SMALL , CENTER , Colors : : WHITE , title ) ;
2012-06-22 14:40:16 +03:00
}
void CRecruitmentWindow : : CCostBox : : set ( TResources res )
{
//just update values
2013-06-29 16:05:48 +03:00
for ( auto & item : resources )
2012-06-22 14:40:16 +03:00
{
2013-08-29 16:46:27 +03:00
item . second . first - > setText ( boost : : lexical_cast < std : : string > ( res [ item . first ] ) ) ;
2012-06-22 14:40:16 +03:00
}
}
void CRecruitmentWindow : : CCostBox : : createItems ( TResources res )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2013-06-29 16:05:48 +03:00
for ( auto & curr : resources )
2012-06-22 14:40:16 +03:00
{
delete curr . second . first ;
delete curr . second . second ;
}
resources . clear ( ) ;
TResources : : nziterator iter ( res ) ;
while ( iter . valid ( ) )
{
CAnimImage * image = new CAnimImage ( " RESOURCE " , iter - > resType ) ;
2012-11-11 15:23:31 +03:00
CLabel * text = new CLabel ( 15 , 43 , FONT_SMALL , CENTER , Colors : : WHITE , " 0 " ) ;
2012-06-22 14:40:16 +03:00
resources . insert ( std : : make_pair ( iter - > resType , std : : make_pair ( text , image ) ) ) ;
iter + + ;
}
if ( ! resources . empty ( ) )
{
int curx = pos . w / 2 - ( 16 * resources . size ( ) ) - ( 8 * ( resources . size ( ) - 1 ) ) ;
//reverse to display gold as first resource
2013-06-29 16:05:48 +03:00
for ( auto & res : boost : : adaptors : : reverse ( resources ) )
2012-06-22 14:40:16 +03:00
{
res . second . first - > moveBy ( Point ( curx , 22 ) ) ;
res . second . second - > moveBy ( Point ( curx , 22 ) ) ;
curx + = 48 ;
}
}
redraw ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-06-22 14:40:16 +03:00
void CRecruitmentWindow : : select ( CCreatureCard * card )
2009-05-19 21:23:04 +03:00
{
2012-06-22 14:40:16 +03:00
if ( card = = selected )
return ;
if ( selected )
selected - > select ( false ) ;
selected = card ;
if ( selected )
selected - > select ( true ) ;
if ( card )
{
si32 maxAmount = card - > creature - > maxAmount ( LOCPLINT - > cb - > getResourceAmount ( ) ) ;
vstd : : amin ( maxAmount , card - > amount ) ;
slider - > setAmount ( maxAmount ) ;
2012-09-30 13:35:17 +03:00
if ( slider - > value ! = maxAmount )
slider - > moveTo ( maxAmount ) ;
2012-06-22 14:40:16 +03:00
else // if slider already at 0 - emulate call to sliderMoved()
2012-09-30 13:35:17 +03:00
sliderMoved ( maxAmount ) ;
2012-06-22 14:40:16 +03:00
costPerTroopValue - > createItems ( card - > creature - > cost ) ;
totalCostValue - > createItems ( card - > creature - > cost ) ;
costPerTroopValue - > set ( card - > creature - > cost ) ;
2012-10-07 17:58:48 +03:00
totalCostValue - > set ( card - > creature - > cost * maxAmount ) ;
2012-06-22 14:40:16 +03:00
//Recruit %s
2013-08-29 16:46:27 +03:00
title - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > tcommands [ 21 ] ) % card - > creature - > namePl ) ) ;
2012-06-22 14:40:16 +03:00
maxButton - > block ( maxAmount = = 0 ) ;
slider - > block ( maxAmount = = 0 ) ;
}
}
void CRecruitmentWindow : : buy ( )
{
2013-02-11 02:24:57 +03:00
CreatureID crid = selected - > creature - > idNumber ;
2013-02-16 17:03:47 +03:00
SlotID dstslot = dst - > getSlotFor ( crid ) ;
2009-08-07 01:36:51 +03:00
2013-02-16 17:03:47 +03:00
if ( ! dstslot . validSlot ( ) & & ! vstd : : contains ( CGI - > arth - > bigArtifacts , CGI - > arth - > creatureToMachineID ( crid ) ) ) //no available slot
2009-08-07 01:36:51 +03:00
{
std : : string txt ;
2012-09-23 21:01:04 +03:00
if ( dst - > ID = = Obj : : HERO )
2009-08-07 01:36:51 +03:00
{
txt = CGI - > generaltexth - > allTexts [ 425 ] ; //The %s would join your hero, but there aren't enough provisions to support them.
2010-05-02 21:20:26 +03:00
boost : : algorithm : : replace_first ( txt , " %s " , slider - > value > 1 ? CGI - > creh - > creatures [ crid ] - > namePl : CGI - > creh - > creatures [ crid ] - > nameSing ) ;
2009-08-07 01:36:51 +03:00
}
else
{
txt = CGI - > generaltexth - > allTexts [ 17 ] ; //There is no room in the garrison for this army.
}
LOCPLINT - > showInfoDialog ( txt ) ;
return ;
}
2012-06-22 14:40:16 +03:00
onRecruit ( crid , slider - > value ) ;
2009-07-26 13:43:22 +03:00
if ( level > = 0 )
close ( ) ;
2009-05-19 21:23:04 +03:00
}
2011-12-22 16:05:19 +03:00
void CRecruitmentWindow : : showAll ( SDL_Surface * to )
2009-05-19 21:23:04 +03:00
{
2012-06-15 20:08:19 +03:00
CWindowObject : : showAll ( to ) ;
2012-06-22 14:40:16 +03:00
// recruit\total values
2012-06-16 13:41:14 +03:00
drawBorder ( to , pos . x + 172 , pos . y + 222 , 67 , 42 , int3 ( 239 , 215 , 123 ) ) ;
drawBorder ( to , pos . x + 246 , pos . y + 222 , 67 , 42 , int3 ( 239 , 215 , 123 ) ) ;
2012-06-22 14:40:16 +03:00
//cost boxes
2012-06-16 13:41:14 +03:00
drawBorder ( to , pos . x + 64 , pos . y + 222 , 99 , 76 , int3 ( 239 , 215 , 123 ) ) ;
drawBorder ( to , pos . x + 322 , pos . y + 222 , 99 , 76 , int3 ( 239 , 215 , 123 ) ) ;
2012-06-22 14:40:16 +03:00
//buttons borders
2012-06-16 13:41:14 +03:00
drawBorder ( to , pos . x + 133 , pos . y + 312 , 66 , 34 , int3 ( 173 , 142 , 66 ) ) ;
drawBorder ( to , pos . x + 211 , pos . y + 312 , 66 , 34 , int3 ( 173 , 142 , 66 ) ) ;
drawBorder ( to , pos . x + 289 , pos . y + 312 , 66 , 34 , int3 ( 173 , 142 , 66 ) ) ;
2009-05-19 21:23:04 +03:00
}
2013-06-26 14:18:27 +03:00
CRecruitmentWindow : : CRecruitmentWindow ( const CGDwelling * Dwelling , int Level , const CArmedInstance * Dst , const std : : function < void ( CreatureID , int ) > & Recruit , int y_offset ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " TPRCRT " ) ,
2012-06-22 14:40:16 +03:00
onRecruit ( Recruit ) ,
2012-06-15 20:08:19 +03:00
level ( Level ) ,
2012-06-22 14:40:16 +03:00
dst ( Dst ) ,
selected ( nullptr ) ,
dwelling ( Dwelling )
2009-05-19 21:23:04 +03:00
{
2012-06-22 14:40:16 +03:00
moveBy ( Point ( 0 , y_offset ) ) ;
2011-02-12 18:12:48 +02:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-22 14:40:16 +03:00
new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2011-02-12 18:12:48 +02:00
2013-06-29 16:05:48 +03:00
slider = new CSlider ( 176 , 279 , 135 , nullptr , 0 , 0 , 0 , true ) ;
2013-07-02 18:23:32 +03:00
slider - > moved = boost : : bind ( & CRecruitmentWindow : : sliderMoved , this , _1 ) ;
2009-07-26 13:43:22 +03:00
2013-07-02 18:23:32 +03:00
maxButton = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 553 ] , boost : : bind ( & CSlider : : moveToMax , slider ) , 134 , 313 , " IRCBTNS.DEF " , SDLK_m ) ;
buyButton = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 554 ] , boost : : bind ( & CRecruitmentWindow : : buy , this ) , 212 , 313 , " IBY6432.DEF " , SDLK_RETURN ) ;
cancelButton = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 555 ] , boost : : bind ( & CRecruitmentWindow : : close , this ) , 290 , 313 , " ICN6432.DEF " , SDLK_ESCAPE ) ;
2009-07-26 13:43:22 +03:00
2012-11-11 15:23:31 +03:00
title = new CLabel ( 243 , 32 , FONT_BIG , CENTER , Colors : : YELLOW ) ;
availableValue = new CLabel ( 205 , 253 , FONT_SMALL , CENTER , Colors : : WHITE ) ;
toRecruitValue = new CLabel ( 279 , 253 , FONT_SMALL , CENTER , Colors : : WHITE ) ;
2012-06-16 13:41:14 +03:00
2012-06-22 14:40:16 +03:00
costPerTroopValue = new CCostBox ( Rect ( 65 , 222 , 97 , 74 ) , CGI - > generaltexth - > allTexts [ 346 ] ) ;
totalCostValue = new CCostBox ( Rect ( 323 , 222 , 97 , 74 ) , CGI - > generaltexth - > allTexts [ 466 ] ) ;
2012-06-15 20:08:19 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 205 , 233 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 465 ] ) ; //available t
new CLabel ( 279 , 233 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 16 ] ) ; //recruit t
2009-05-19 21:23:04 +03:00
2012-06-22 14:40:16 +03:00
availableCreaturesChanged ( ) ;
2009-05-19 21:23:04 +03:00
}
2012-06-22 14:40:16 +03:00
void CRecruitmentWindow : : availableCreaturesChanged ( )
2009-07-26 13:43:22 +03:00
{
2012-06-22 14:40:16 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-27 23:44:01 +03:00
size_t selectedIndex = 0 ;
if ( ! cards . empty ( ) & & selected ) // find position of selected item
selectedIndex = std : : find ( cards . begin ( ) , cards . end ( ) , selected ) - cards . begin ( ) ;
2012-06-22 14:40:16 +03:00
//deselect card
select ( nullptr ) ;
//delete old cards
2013-06-29 16:05:48 +03:00
for ( auto & card : cards )
2012-06-22 14:40:16 +03:00
delete card ;
cards . clear ( ) ;
2011-02-12 18:12:48 +02:00
2009-07-26 13:43:22 +03:00
for ( int i = 0 ; i < dwelling - > creatures . size ( ) ; i + + )
{
2012-06-22 14:40:16 +03:00
//find appropriate level
2012-01-12 18:23:00 +03:00
if ( level > = 0 & & i ! = level )
2009-07-26 13:43:22 +03:00
continue ;
2012-06-22 14:40:16 +03:00
int amount = dwelling - > creatures [ i ] . first ;
2009-07-26 13:43:22 +03:00
2012-06-22 14:40:16 +03:00
//create new cards
2013-06-29 16:05:48 +03:00
for ( auto & creature : boost : : adaptors : : reverse ( dwelling - > creatures [ i ] . second ) )
2012-06-22 14:40:16 +03:00
cards . push_back ( new CCreatureCard ( this , CGI - > creh - > creatures [ creature ] , amount ) ) ;
}
2009-07-26 13:43:22 +03:00
2012-06-22 14:40:16 +03:00
assert ( ! cards . empty ( ) ) ;
2012-06-27 23:44:01 +03:00
const int creatureWidth = 102 ;
//normal distance between cards - 18px
int requiredSpace = 18 ;
//maximum distance we can use without reaching window borders
int availableSpace = pos . w - 50 - creatureWidth * cards . size ( ) ;
if ( cards . size ( ) > 1 ) // avoid division by zero
availableSpace / = cards . size ( ) - 1 ;
else
availableSpace = 0 ;
assert ( availableSpace > = 0 ) ;
const int spaceBetween = std : : min ( requiredSpace , availableSpace ) ;
const int totalCreatureWidth = spaceBetween + creatureWidth ;
2012-06-22 14:40:16 +03:00
//now we know total amount of cards and can move them to correct position
2012-06-27 23:44:01 +03:00
int curx = pos . w / 2 - ( creatureWidth * cards . size ( ) / 2 ) - ( spaceBetween * ( cards . size ( ) - 1 ) / 2 ) ;
2013-06-29 16:05:48 +03:00
for ( auto & card : cards )
2012-06-22 14:40:16 +03:00
{
card - > moveBy ( Point ( curx , 64 ) ) ;
2012-06-27 23:44:01 +03:00
curx + = totalCreatureWidth ;
2009-07-26 13:43:22 +03:00
}
2012-06-27 23:44:01 +03:00
//restore selection
select ( cards [ selectedIndex ] ) ;
2012-06-22 14:40:16 +03:00
2012-09-30 13:35:17 +03:00
if ( slider - > value = = slider - > amount )
slider - > moveTo ( slider - > amount ) ;
2012-06-22 14:40:16 +03:00
else // if slider already at 0 - emulate call to sliderMoved()
2012-09-30 13:35:17 +03:00
sliderMoved ( slider - > amount ) ;
2012-06-22 14:40:16 +03:00
}
void CRecruitmentWindow : : sliderMoved ( int to )
{
if ( ! selected )
return ;
buyButton - > block ( ! to ) ;
2013-08-29 16:46:27 +03:00
availableValue - > setText ( boost : : lexical_cast < std : : string > ( selected - > amount - to ) ) ;
toRecruitValue - > setText ( boost : : lexical_cast < std : : string > ( to ) ) ;
2012-06-22 14:40:16 +03:00
totalCostValue - > set ( selected - > creature - > cost * to ) ;
2009-07-26 13:43:22 +03:00
}
2013-06-26 14:18:27 +03:00
CSplitWindow : : CSplitWindow ( const CCreature * creature , std : : function < void ( int , int ) > callback_ ,
2012-06-13 16:04:06 +03:00
int leftMin_ , int rightMin_ , int leftAmount_ , int rightAmount_ ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " GPUCRDIV " ) ,
2012-06-13 16:04:06 +03:00
callback ( callback_ ) ,
leftAmount ( leftAmount_ ) ,
rightAmount ( rightAmount_ ) ,
leftMin ( leftMin_ ) ,
rightMin ( rightMin_ ) ,
slider ( nullptr )
2009-05-19 21:23:04 +03:00
{
2012-06-13 16:04:06 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-02-02 18:24:53 +02:00
2012-06-13 16:04:06 +03:00
int total = leftAmount + rightAmount ;
int leftMax = total - rightMin ;
int rightMax = total - leftMin ;
2009-05-19 21:23:04 +03:00
2013-07-02 18:23:32 +03:00
ok = new CAdventureMapButton ( " " , " " , boost : : bind ( & CSplitWindow : : apply , this ) , 20 , 263 , " IOK6432 " , SDLK_RETURN ) ;
cancel = new CAdventureMapButton ( " " , " " , boost : : bind ( & CSplitWindow : : close , this ) , 214 , 263 , " ICN6432 " , SDLK_ESCAPE ) ;
2009-05-19 21:23:04 +03:00
2012-06-13 16:04:06 +03:00
int sliderPositions = total - leftMin - rightMin ;
2009-05-19 21:23:04 +03:00
2013-07-02 18:23:32 +03:00
leftInput = new CTextInput ( Rect ( 20 , 218 , 100 , 36 ) , FONT_BIG , boost : : bind ( & CSplitWindow : : setAmountText , this , _1 , true ) ) ;
rightInput = new CTextInput ( Rect ( 176 , 218 , 100 , 36 ) , FONT_BIG , boost : : bind ( & CSplitWindow : : setAmountText , this , _1 , false ) ) ;
2009-05-19 21:23:04 +03:00
2012-06-13 16:04:06 +03:00
//add filters to allow only number input
2013-07-02 18:23:32 +03:00
leftInput - > filters . add ( boost : : bind ( & CTextInput : : numberFilter , _1 , _2 , leftMin , leftMax ) ) ;
rightInput - > filters . add ( boost : : bind ( & CTextInput : : numberFilter , _1 , _2 , rightMin , rightMax ) ) ;
2009-05-19 21:23:04 +03:00
2013-08-29 16:46:27 +03:00
leftInput - > setText ( boost : : lexical_cast < std : : string > ( leftAmount ) , false ) ;
rightInput - > setText ( boost : : lexical_cast < std : : string > ( rightAmount ) , false ) ;
2009-05-19 21:23:04 +03:00
2012-06-13 16:04:06 +03:00
animLeft = new CCreaturePic ( 20 , 54 , creature , true , false ) ;
animRight = new CCreaturePic ( 177 , 54 , creature , true , false ) ;
2009-05-19 21:23:04 +03:00
2013-07-02 18:23:32 +03:00
slider = new CSlider ( 21 , 194 , 257 , boost : : bind ( & CSplitWindow : : sliderMoved , this , _1 ) , 0 , sliderPositions , rightAmount - rightMin , true ) ;
2009-09-07 05:29:44 +03:00
2012-06-13 16:04:06 +03:00
std : : string title = CGI - > generaltexth - > allTexts [ 256 ] ;
boost : : algorithm : : replace_first ( title , " %s " , creature - > namePl ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 150 , 34 , FONT_BIG , CENTER , Colors : : YELLOW , title ) ;
2012-06-13 16:04:06 +03:00
}
2009-05-19 21:23:04 +03:00
2012-06-13 16:04:06 +03:00
void CSplitWindow : : setAmountText ( std : : string text , bool left )
{
try
2010-08-19 14:03:33 +03:00
{
2012-06-13 16:04:06 +03:00
setAmount ( boost : : lexical_cast < int > ( text ) , left ) ;
slider - > moveTo ( rightAmount - rightMin ) ;
2010-08-19 14:03:33 +03:00
}
2012-06-13 16:04:06 +03:00
catch ( boost : : bad_lexical_cast & )
2009-05-19 21:23:04 +03:00
{
}
}
2012-06-13 16:04:06 +03:00
void CSplitWindow : : setAmount ( int value , bool left )
2009-05-19 21:23:04 +03:00
{
2012-06-13 16:04:06 +03:00
int total = leftAmount + rightAmount ;
leftAmount = left ? value : total - value ;
rightAmount = left ? total - value : value ;
2013-08-29 16:46:27 +03:00
leftInput - > setText ( boost : : lexical_cast < std : : string > ( leftAmount ) ) ;
rightInput - > setText ( boost : : lexical_cast < std : : string > ( rightAmount ) ) ;
2012-06-13 16:04:06 +03:00
}
void CSplitWindow : : apply ( )
{
callback ( leftAmount , rightAmount ) ;
close ( ) ;
}
void CSplitWindow : : sliderMoved ( int to )
{
setAmount ( rightMin + to , false ) ;
2009-05-19 21:23:04 +03:00
}
2013-06-26 14:18:27 +03:00
CLevelWindow : : CLevelWindow ( const CGHeroInstance * hero , PrimarySkill : : PrimarySkill pskill , std : : vector < SecondarySkill > & skills , std : : function < void ( ui32 ) > callback ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " LVLUPBKG " ) ,
cb ( callback )
2009-05-19 21:23:04 +03:00
{
2012-06-15 20:08:19 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2009-05-19 21:23:04 +03:00
LOCPLINT - > showingDialog - > setn ( true ) ;
2012-06-15 20:08:19 +03:00
2012-06-16 13:41:14 +03:00
new CAnimImage ( " PortraitsLarge " , hero - > portrait , 0 , 170 , 66 ) ;
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( " " , " " , boost : : bind ( & CLevelWindow : : close , this ) , 297 , 413 , " IOKAY " , SDLK_RETURN ) ;
2012-06-15 20:08:19 +03:00
//%s has gained a level.
2012-11-11 15:23:31 +03:00
new CLabel ( 192 , 33 , FONT_MEDIUM , CENTER , Colors : : WHITE ,
2012-06-15 20:08:19 +03:00
boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 444 ] ) % hero - > name ) ) ;
2009-05-19 21:23:04 +03:00
2012-06-15 20:08:19 +03:00
//%s is now a level %d %s.
2012-11-11 15:23:31 +03:00
new CLabel ( 192 , 162 , FONT_MEDIUM , CENTER , Colors : : WHITE ,
2012-06-16 13:41:14 +03:00
boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 445 ] ) % hero - > name % hero - > level % hero - > type - > heroClass - > name ) ) ;
2009-05-19 21:23:04 +03:00
2012-06-16 13:41:14 +03:00
new CAnimImage ( " PSKIL42 " , pskill , 0 , 174 , 190 ) ;
2009-05-19 21:23:04 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 192 , 253 , FONT_MEDIUM , CENTER , Colors : : WHITE ,
2012-06-15 20:08:19 +03:00
CGI - > generaltexth - > primarySkillNames [ pskill ] + " +1 " ) ;
2010-02-02 18:24:53 +02:00
2012-07-07 16:32:37 +03:00
if ( ! skills . empty ( ) )
2009-05-19 21:23:04 +03:00
{
2012-07-07 16:32:37 +03:00
std : : vector < CSelectableComponent * > comps ;
2013-06-29 16:05:48 +03:00
for ( auto & skill : skills )
2009-05-19 21:23:04 +03:00
{
2012-07-07 16:32:37 +03:00
comps . push_back ( new CSelectableComponent (
CComponent : : secskill ,
2013-06-29 16:05:48 +03:00
skill ,
hero - > getSecSkillLevel ( SecondarySkill ( skill ) ) + 1 ,
2012-07-07 16:32:37 +03:00
CComponent : : medium ) ) ;
2009-05-19 21:23:04 +03:00
}
2013-01-23 02:28:10 +03:00
box = new CComponentBox ( comps , Rect ( 75 , 300 , pos . w - 150 , 100 ) ) ;
2009-05-19 21:23:04 +03:00
}
2012-07-07 16:32:37 +03:00
else
box = nullptr ;
2009-05-19 21:23:04 +03:00
}
2012-06-15 20:08:19 +03:00
2009-05-19 21:23:04 +03:00
CLevelWindow : : ~ CLevelWindow ( )
{
2012-07-07 16:32:37 +03:00
//FIXME: call callback if there was nothing to select?
if ( box & & box - > selectedIndex ( ) ! = - 1 )
cb ( box - > selectedIndex ( ) ) ;
2012-06-15 20:08:19 +03:00
LOCPLINT - > showingDialog - > setn ( false ) ;
2009-05-19 21:23:04 +03:00
}
void CMinorResDataBar : : show ( SDL_Surface * to )
2012-06-02 18:16:54 +03:00
{
}
void CMinorResDataBar : : showAll ( SDL_Surface * to )
2009-05-19 21:23:04 +03:00
{
blitAt ( bg , pos . x , pos . y , to ) ;
2013-02-09 15:56:35 +03:00
for ( Res : : ERes i = Res : : WOOD ; i < = Res : : GOLD ; vstd : : advance ( i , 1 ) )
2009-05-19 21:23:04 +03:00
{
2012-12-19 20:24:53 +03:00
std : : string text = boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getResourceAmount ( i ) ) ;
graphics - > fonts [ FONT_SMALL ] - > renderTextCenter ( to , text , Colors : : WHITE , Point ( pos . x + 50 + 76 * i , pos . y + pos . h / 2 ) ) ;
2009-05-19 21:23:04 +03:00
}
std : : vector < std : : string > temp ;
2012-12-19 20:24:53 +03:00
2013-02-02 11:29:57 +03:00
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : MONTH ) ) ) ;
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : WEEK ) ) ) ;
temp . push_back ( boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getDate ( Date : : DAY_OF_WEEK ) ) ) ;
2012-12-19 20:24:53 +03:00
std : : string datetext = CGI - > generaltexth - > allTexts [ 62 ] + " : %s, " + CGI - > generaltexth - > allTexts [ 63 ]
+ " : %s, " + CGI - > generaltexth - > allTexts [ 64 ] + " : %s " ;
graphics - > fonts [ FONT_SMALL ] - > renderTextCenter ( to , processStr ( datetext , temp ) , Colors : : WHITE , Point ( pos . x + 545 + ( pos . w - 545 ) / 2 , pos . y + pos . h / 2 ) ) ;
2009-05-19 21:23:04 +03:00
}
CMinorResDataBar : : CMinorResDataBar ( )
{
2013-05-04 16:14:23 +03:00
bg = BitmapHandler : : loadBitmap ( " KRESBAR.bmp " ) ;
2009-05-19 21:23:04 +03:00
SDL_SetColorKey ( bg , SDL_SRCCOLORKEY , SDL_MapRGB ( bg - > format , 0 , 255 , 255 ) ) ;
graphics - > blueToPlayersAdv ( bg , LOCPLINT - > playerID ) ;
pos . x = 7 ;
pos . y = 575 ;
pos . w = bg - > w ;
pos . h = bg - > h ;
}
CMinorResDataBar : : ~ CMinorResDataBar ( )
{
SDL_FreeSurface ( bg ) ;
}
2012-01-12 18:23:00 +03:00
CObjectListWindow : : CItem : : CItem ( CObjectListWindow * _parent , size_t _id , std : : string _text ) :
parent ( _parent ) ,
index ( _id )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
border = new CPicture ( " TPGATES " ) ;
pos = border - > pos ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK ) ;
2012-01-12 18:23:00 +03:00
type | = REDRAW_PARENT ;
2012-11-11 15:23:31 +03:00
text = new CLabel ( pos . w / 2 , pos . h / 2 , FONT_SMALL , CENTER , Colors : : WHITE , _text ) ;
2012-01-12 18:23:00 +03:00
select ( index = = parent - > selected ) ;
}
void CObjectListWindow : : CItem : : select ( bool on )
{
if ( on )
border - > recActions = 255 ;
else
border - > recActions = ~ ( UPDATE | SHOWALL ) ;
redraw ( ) ;
}
void CObjectListWindow : : CItem : : clickLeft ( tribool down , bool previousState )
{
if ( previousState & & ! down )
parent - > changeSelection ( index ) ;
}
2014-03-10 19:00:58 +03:00
CObjectListWindow : : CObjectListWindow ( const std : : vector < int > & _items , CIntObject * titlePic , std : : string _title , std : : string _descr ,
2013-06-26 14:18:27 +03:00
std : : function < void ( int ) > Callback ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " TPGATE " ) ,
2012-01-12 18:23:00 +03:00
onSelect ( Callback )
{
items . reserve ( _items . size ( ) ) ;
2013-06-29 16:05:48 +03:00
for ( int id : _items )
2012-01-12 18:23:00 +03:00
{
items . push_back ( std : : make_pair ( id , CGI - > mh - > map - > objects [ id ] - > hoverName ) ) ;
}
init ( titlePic , _title , _descr ) ;
}
2014-03-10 19:00:58 +03:00
CObjectListWindow : : CObjectListWindow ( const std : : vector < std : : string > & _items , CIntObject * titlePic , std : : string _title , std : : string _descr ,
2013-06-26 14:18:27 +03:00
std : : function < void ( int ) > Callback ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " TPGATE " ) ,
2012-01-12 18:23:00 +03:00
onSelect ( Callback )
{
items . reserve ( _items . size ( ) ) ;
for ( size_t i = 0 ; i < _items . size ( ) ; i + + )
items . push_back ( std : : make_pair ( int ( i ) , _items [ i ] ) ) ;
init ( titlePic , _title , _descr ) ;
}
2014-03-10 19:00:58 +03:00
void CObjectListWindow : : init ( CIntObject * titlePic , std : : string _title , std : : string _descr )
2010-06-26 13:01:26 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-01-12 18:23:00 +03:00
2012-11-11 15:23:31 +03:00
title = new CLabel ( 152 , 27 , FONT_BIG , CENTER , Colors : : YELLOW , _title ) ;
descr = new CLabel ( 145 , 133 , FONT_SMALL , CENTER , Colors : : WHITE , _descr ) ;
2012-01-12 18:23:00 +03:00
2013-07-02 18:23:32 +03:00
ok = new CAdventureMapButton ( " " , " " , boost : : bind ( & CObjectListWindow : : elementSelected , this ) , 15 , 402 , " IOKAY.DEF " , SDLK_RETURN ) ;
2012-01-12 18:23:00 +03:00
ok - > block ( true ) ;
2013-07-02 18:23:32 +03:00
exit = new CAdventureMapButton ( " " , " " , boost : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) , 228 , 402 , " ICANCEL.DEF " , SDLK_ESCAPE ) ;
2012-01-12 18:23:00 +03:00
if ( titlePic )
{
titleImage = titlePic ;
addChild ( titleImage ) ;
titleImage - > recActions = defActions ;
2012-06-15 20:08:19 +03:00
titleImage - > pos . x = pos . w / 2 + pos . x - titleImage - > pos . w / 2 ;
2012-01-12 18:23:00 +03:00
titleImage - > pos . y = 75 + pos . y - titleImage - > pos . h / 2 ;
}
2013-07-02 18:23:32 +03:00
list = new CListBox ( boost : : bind ( & CObjectListWindow : : genItem , this , _1 ) , CListBox : : DestroyFunc ( ) ,
2012-09-29 15:02:46 +03:00
Point ( 14 , 151 ) , Point ( 0 , 25 ) , 9 , items . size ( ) , 0 , 1 , Rect ( 262 , - 32 , 256 , 256 ) ) ;
2012-01-12 18:23:00 +03:00
list - > type | = REDRAW_PARENT ;
2010-06-26 13:01:26 +03:00
}
2012-01-12 18:23:00 +03:00
CIntObject * CObjectListWindow : : genItem ( size_t index )
2010-06-26 13:01:26 +03:00
{
2012-01-12 18:23:00 +03:00
if ( index < items . size ( ) )
return new CItem ( this , index , items [ index ] . second ) ;
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-06-26 13:01:26 +03:00
}
void CObjectListWindow : : elementSelected ( )
{
2013-06-26 14:18:27 +03:00
std : : function < void ( int ) > toCall = onSelect ; //save
2012-01-12 18:23:00 +03:00
int where = items [ selected ] . first ; //required variables
2010-06-30 22:27:35 +03:00
GH . popIntTotally ( this ) ; //then destroy window
toCall ( where ) ; //and send selected object
2010-06-26 13:01:26 +03:00
}
2012-01-12 18:23:00 +03:00
void CObjectListWindow : : changeSelection ( size_t which )
2010-06-26 13:01:26 +03:00
{
2012-01-12 18:23:00 +03:00
ok - > block ( false ) ;
if ( selected = = which )
return ;
2010-06-26 13:01:26 +03:00
2012-01-12 18:23:00 +03:00
std : : list < CIntObject * > elements = list - > getItems ( ) ;
2013-06-29 16:05:48 +03:00
for ( CIntObject * element : elements )
2010-06-26 13:01:26 +03:00
{
2012-01-12 18:23:00 +03:00
CItem * item ;
if ( ( item = dynamic_cast < CItem * > ( element ) ) )
2012-10-27 19:59:24 +03:00
{
2012-01-12 18:23:00 +03:00
if ( item - > index = = selected )
item - > select ( false ) ;
if ( item - > index = = which )
item - > select ( true ) ;
2012-10-27 19:59:24 +03:00
}
2010-06-26 13:01:26 +03:00
}
2012-01-12 18:23:00 +03:00
selected = which ;
2010-06-26 13:01:26 +03:00
}
void CObjectListWindow : : keyPressed ( const SDL_KeyboardEvent & key )
{
2012-01-12 18:23:00 +03:00
if ( key . state ! = SDL_PRESSED )
return ;
2010-06-26 13:01:26 +03:00
int sel = selected ;
switch ( key . keysym . sym )
{
2012-01-12 18:23:00 +03:00
break ; case SDLK_UP :
sel - = 1 ;
break ; case SDLK_DOWN :
sel + = 1 ;
break ; case SDLK_PAGEUP :
sel - = 9 ;
break ; case SDLK_PAGEDOWN :
sel + = 9 ;
break ; case SDLK_HOME :
2010-06-26 13:01:26 +03:00
sel = 0 ;
2012-01-12 18:23:00 +03:00
break ; case SDLK_END :
sel = items . size ( ) ;
2010-06-26 13:01:26 +03:00
2012-01-12 18:23:00 +03:00
break ; default :
return ;
2010-06-26 13:01:26 +03:00
}
2012-01-12 18:23:00 +03:00
vstd : : abetween ( sel , 0 , items . size ( ) - 1 ) ;
list - > scrollTo ( sel ) ;
changeSelection ( sel ) ;
2010-06-26 13:01:26 +03:00
}
2012-12-23 13:23:41 +03:00
CTradeWindow : : CTradeableItem : : CTradeableItem ( Point pos , EType Type , int ID , bool Left , int Serial ) :
CIntObject ( LCLICK | HOVER | RCLICK , pos ) ,
type ( EType ( - 1 ) ) , // set to invalid, will be corrected in setType
2012-12-20 16:57:29 +03:00
id ( ID ) ,
serial ( Serial ) ,
left ( Left )
2009-05-19 21:23:04 +03:00
{
2010-07-20 09:05:45 +03:00
downSelection = false ;
2013-06-26 14:18:27 +03:00
hlp = nullptr ;
2012-12-20 16:57:29 +03:00
image = nullptr ;
2012-12-23 13:23:41 +03:00
setType ( Type ) ;
2012-12-20 16:57:29 +03:00
}
void CTradeWindow : : CTradeableItem : : setType ( EType newType )
{
if ( type ! = newType )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
type = newType ;
delete image ;
if ( getIndex ( ) < 0 )
{
image = new CAnimImage ( getFilename ( ) , 0 ) ;
image - > disable ( ) ;
}
else
image = new CAnimImage ( getFilename ( ) , getIndex ( ) ) ;
}
}
void CTradeWindow : : CTradeableItem : : setID ( int newID )
{
if ( id ! = newID )
{
id = newID ;
if ( image )
{
int index = getIndex ( ) ;
if ( index < 0 )
image - > disable ( ) ;
else
{
image - > enable ( ) ;
image - > setFrame ( index ) ;
}
}
}
}
std : : string CTradeWindow : : CTradeableItem : : getFilename ( )
{
switch ( type )
{
case RESOURCE :
2012-12-23 13:23:41 +03:00
return " RESOURCE " ;
2012-12-20 16:57:29 +03:00
case PLAYER :
2012-12-23 13:23:41 +03:00
return " CREST58 " ;
2012-12-20 16:57:29 +03:00
case ARTIFACT_TYPE :
case ARTIFACT_PLACEHOLDER :
case ARTIFACT_INSTANCE :
2012-12-23 13:23:41 +03:00
return " artifact " ;
2012-12-20 16:57:29 +03:00
case CREATURE :
2013-01-23 02:28:10 +03:00
return " TWCRPORT " ;
2012-12-20 16:57:29 +03:00
default :
return " " ;
}
}
int CTradeWindow : : CTradeableItem : : getIndex ( )
{
2013-01-23 02:28:10 +03:00
if ( id < 0 )
return - 1 ;
2012-12-20 16:57:29 +03:00
switch ( type )
{
case RESOURCE :
case PLAYER :
return id ;
case ARTIFACT_TYPE :
case ARTIFACT_INSTANCE :
2013-01-23 02:28:10 +03:00
case ARTIFACT_PLACEHOLDER :
return VLC - > arth - > artifacts [ id ] - > iconIndex ;
2012-12-20 16:57:29 +03:00
case CREATURE :
2013-01-23 02:28:10 +03:00
return VLC - > creh - > creatures [ id ] - > iconIndex ;
2012-12-20 16:57:29 +03:00
default :
return - 1 ;
}
2009-05-19 21:23:04 +03:00
}
2010-07-20 09:05:45 +03:00
void CTradeWindow : : CTradeableItem : : showAll ( SDL_Surface * to )
2009-05-19 21:23:04 +03:00
{
2011-12-22 16:05:19 +03:00
Point posToBitmap ;
Point posToSubCenter ;
2010-05-08 01:10:32 +03:00
switch ( type )
{
case RESOURCE :
2011-12-22 16:05:19 +03:00
posToBitmap = Point ( 19 , 9 ) ;
posToSubCenter = Point ( 36 , 59 ) ;
2010-07-20 09:05:45 +03:00
break ;
case CREATURE_PLACEHOLDER :
case CREATURE :
2011-12-22 16:05:19 +03:00
posToSubCenter = Point ( 29 , 76 ) ;
2010-07-20 09:05:45 +03:00
if ( downSelection )
posToSubCenter . y + = 5 ;
break ;
case PLAYER :
2011-12-22 16:05:19 +03:00
posToSubCenter = Point ( 31 , 76 ) ;
2010-07-20 09:05:45 +03:00
break ;
2010-07-23 15:02:15 +03:00
case ARTIFACT_PLACEHOLDER :
2011-04-23 00:51:10 +03:00
case ARTIFACT_INSTANCE :
2011-12-22 16:05:19 +03:00
posToSubCenter = Point ( 19 , 55 ) ;
2010-07-31 04:38:12 +03:00
if ( downSelection )
posToSubCenter . y + = 8 ;
break ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2011-12-22 16:05:19 +03:00
posToSubCenter = Point ( 19 , 58 ) ;
2010-05-08 01:10:32 +03:00
break ;
}
2012-12-20 16:57:29 +03:00
if ( image )
{
2012-12-23 13:23:41 +03:00
image - > moveTo ( pos . topLeft ( ) + posToBitmap ) ;
2013-01-23 02:28:10 +03:00
CIntObject : : showAll ( to ) ;
2012-12-20 16:57:29 +03:00
}
2010-07-20 09:05:45 +03:00
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( subtitle , posToSubCenter , FONT_SMALL , Colors : : WHITE , to ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-20 09:05:45 +03:00
void CTradeWindow : : CTradeableItem : : clickLeft ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
2011-01-28 04:11:58 +02:00
CTradeWindow * mw = dynamic_cast < CTradeWindow * > ( parent ) ;
2009-05-19 21:23:04 +03:00
assert ( mw ) ;
if ( down )
{
2010-07-23 15:02:15 +03:00
if ( type = = ARTIFACT_PLACEHOLDER )
{
CAltarWindow * aw = static_cast < CAltarWindow * > ( mw ) ;
2011-01-28 04:11:58 +02:00
if ( const CArtifactInstance * movedArt = aw - > arts - > commonInfo - > src . art )
2010-07-23 15:02:15 +03:00
{
2011-01-15 04:17:56 +02:00
aw - > moveFromSlotToAltar ( aw - > arts - > commonInfo - > src . slotID , this , movedArt ) ;
2010-07-23 15:02:15 +03:00
}
2010-12-29 23:04:22 +02:00
else if ( const CArtifactInstance * art = getArtInstance ( ) )
2010-07-23 15:02:15 +03:00
{
2011-01-06 22:00:19 +02:00
aw - > arts - > commonInfo - > src . AOH = aw - > arts ;
2011-01-28 04:11:58 +02:00
aw - > arts - > commonInfo - > src . art = art ;
2011-01-15 04:17:56 +02:00
aw - > arts - > commonInfo - > src . slotID = aw - > hero - > getArtPos ( art ) ;
2011-01-28 04:11:58 +02:00
aw - > arts - > markPossibleSlots ( art ) ;
2010-07-23 15:02:15 +03:00
2011-01-15 04:17:56 +02:00
//aw->arts->commonInfo->dst.AOH = aw->arts;
2012-12-14 18:32:53 +03:00
CCS - > curh - > dragAndDropCursor ( new CAnimImage ( " artifact " , art - > artType - > iconIndex ) ) ;
2010-07-23 15:02:15 +03:00
2011-01-28 04:11:58 +02:00
aw - > arts - > artifactsOnAltar . erase ( art ) ;
2012-12-20 16:57:29 +03:00
setID ( - 1 ) ;
2010-07-23 15:02:15 +03:00
subtitle = " " ;
aw - > deal - > block ( ! aw - > arts - > artifactsOnAltar . size ( ) ) ;
}
aw - > calcTotalExp ( ) ;
return ;
}
2009-05-19 21:23:04 +03:00
if ( left )
{
if ( mw - > hLeft ! = this )
mw - > hLeft = this ;
else
return ;
}
else
{
2012-01-12 18:23:00 +03:00
if ( mw - > hRight ! = this )
2009-05-19 21:23:04 +03:00
mw - > hRight = this ;
else
return ;
}
mw - > selectionChanged ( left ) ;
}
}
2011-12-22 16:05:19 +03:00
void CTradeWindow : : CTradeableItem : : showAllAt ( const Point & dstPos , const std : : string & customSub , SDL_Surface * to )
2010-07-20 09:05:45 +03:00
{
2011-12-22 16:05:19 +03:00
Rect oldPos = pos ;
2010-07-20 09:05:45 +03:00
std : : string oldSub = subtitle ;
downSelection = true ;
2012-12-23 13:23:41 +03:00
moveTo ( dstPos ) ;
2010-07-20 09:05:45 +03:00
subtitle = customSub ;
showAll ( to ) ;
downSelection = false ;
2012-12-23 13:23:41 +03:00
moveTo ( oldPos . topLeft ( ) ) ;
2010-07-20 09:05:45 +03:00
subtitle = oldSub ;
}
void CTradeWindow : : CTradeableItem : : hover ( bool on )
{
if ( ! on )
{
GH . statusbar - > clear ( ) ;
return ;
}
switch ( type )
{
case CREATURE :
case CREATURE_PLACEHOLDER :
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 481 ] ) % CGI - > creh - > creatures [ id ] - > namePl ) ) ;
2010-07-20 09:05:45 +03:00
break ;
case ARTIFACT_PLACEHOLDER :
if ( id < 0 )
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( CGI - > generaltexth - > zelp [ 582 ] . first ) ;
2010-07-20 09:05:45 +03:00
else
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( CGI - > arth - > artifacts [ id ] - > Name ( ) ) ;
2010-07-20 09:05:45 +03:00
break ;
}
}
void CTradeWindow : : CTradeableItem : : clickRight ( tribool down , bool previousState )
{
2010-07-23 15:02:15 +03:00
if ( down )
2010-07-20 09:05:45 +03:00
{
2010-07-23 15:02:15 +03:00
switch ( type )
{
case CREATURE :
case CREATURE_PLACEHOLDER :
//GH.statusbar->print(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->creatures[id]->namePl));
break ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2010-07-23 15:02:15 +03:00
case ARTIFACT_PLACEHOLDER :
if ( id > = 0 )
adventureInt - > handleRightClick ( CGI - > arth - > artifacts [ id ] - > Description ( ) , down ) ;
break ;
}
2010-07-20 09:05:45 +03:00
}
}
2010-07-31 04:38:12 +03:00
std : : string CTradeWindow : : CTradeableItem : : getName ( int number /*= -1*/ ) const
{
switch ( type )
{
case PLAYER :
return CGI - > generaltexth - > capColors [ id ] ;
case RESOURCE :
return CGI - > generaltexth - > restypes [ id ] ;
case CREATURE :
if ( number = = 1 )
return CGI - > creh - > creatures [ id ] - > nameSing ;
else
return CGI - > creh - > creatures [ id ] - > namePl ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2011-04-23 00:51:10 +03:00
case ARTIFACT_INSTANCE :
2010-07-31 04:38:12 +03:00
return CGI - > arth - > artifacts [ id ] - > Name ( ) ;
}
2010-08-02 14:06:49 +03:00
assert ( 0 ) ;
return " " ;
2010-07-31 04:38:12 +03:00
}
2010-12-29 23:04:22 +02:00
const CArtifactInstance * CTradeWindow : : CTradeableItem : : getArtInstance ( ) const
{
switch ( type )
{
case ARTIFACT_PLACEHOLDER :
case ARTIFACT_INSTANCE :
return ( const CArtifactInstance * ) hlp ;
default :
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-12-29 23:04:22 +02:00
}
}
2011-04-23 00:51:10 +03:00
void CTradeWindow : : CTradeableItem : : setArtInstance ( const CArtifactInstance * art )
{
assert ( type = = ARTIFACT_PLACEHOLDER | | type = = ARTIFACT_INSTANCE ) ;
hlp = art ;
if ( art )
2012-12-20 16:57:29 +03:00
setID ( art - > artType - > id ) ;
2011-04-23 00:51:10 +03:00
else
2012-12-20 16:57:29 +03:00
setID ( - 1 ) ;
2011-04-23 00:51:10 +03:00
}
2010-12-29 23:04:22 +02:00
2012-06-15 20:08:19 +03:00
CTradeWindow : : CTradeWindow ( std : : string bgName , const IMarket * Market , const CGHeroInstance * Hero , EMarketMode : : EMarketMode Mode ) :
CWindowObject ( PLAYER_COLORED , bgName ) ,
market ( Market ) ,
hero ( Hero ) ,
2013-06-26 14:18:27 +03:00
arts ( nullptr ) ,
hLeft ( nullptr ) ,
hRight ( nullptr ) ,
2012-06-15 20:08:19 +03:00
readyToTrade ( false )
2010-07-20 09:05:45 +03:00
{
2011-01-28 04:11:58 +02:00
type | = BLOCK_ADV_HOTKEYS ;
2010-07-20 09:05:45 +03:00
mode = Mode ;
initTypes ( ) ;
}
void CTradeWindow : : initTypes ( )
{
switch ( mode )
{
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_RESOURCE :
2010-07-20 09:05:45 +03:00
itemsType [ 1 ] = RESOURCE ;
itemsType [ 0 ] = RESOURCE ;
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_PLAYER :
2010-07-20 09:05:45 +03:00
itemsType [ 1 ] = RESOURCE ;
itemsType [ 0 ] = PLAYER ;
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : CREATURE_RESOURCE :
2010-07-20 09:05:45 +03:00
itemsType [ 1 ] = CREATURE ;
itemsType [ 0 ] = RESOURCE ;
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_ARTIFACT :
2010-07-20 09:05:45 +03:00
itemsType [ 1 ] = RESOURCE ;
2010-12-29 23:04:22 +02:00
itemsType [ 0 ] = ARTIFACT_TYPE ;
2010-07-20 09:05:45 +03:00
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : ARTIFACT_RESOURCE :
2011-04-23 00:51:10 +03:00
itemsType [ 1 ] = ARTIFACT_INSTANCE ;
itemsType [ 0 ] = RESOURCE ;
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : CREATURE_EXP :
2010-07-20 09:05:45 +03:00
itemsType [ 1 ] = CREATURE ;
itemsType [ 0 ] = CREATURE_PLACEHOLDER ;
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : ARTIFACT_EXP :
2010-12-29 23:04:22 +02:00
itemsType [ 1 ] = ARTIFACT_TYPE ;
2010-07-20 09:05:45 +03:00
itemsType [ 0 ] = ARTIFACT_PLACEHOLDER ;
break ;
}
}
void CTradeWindow : : initItems ( bool Left )
2009-05-19 21:23:04 +03:00
{
2011-04-23 00:51:10 +03:00
if ( Left & & ( itemsType [ 1 ] = = ARTIFACT_TYPE | | itemsType [ 1 ] = = ARTIFACT_INSTANCE ) )
{
int xOffset = 0 , yOffset = 0 ;
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_RESOURCE )
2011-04-23 00:51:10 +03:00
{
xOffset = - 361 ;
yOffset = + 46 ;
2013-06-29 16:05:48 +03:00
auto hlp = new CTradeableItem ( Point ( 137 , 469 ) , itemsType [ Left ] , - 1 , 1 , 0 ) ;
2011-04-23 00:51:10 +03:00
hlp - > recActions & = ~ ( UPDATE | SHOWALL ) ;
items [ Left ] . push_back ( hlp ) ;
}
else //ARTIFACT_EXP
{
xOffset = - 363 ;
yOffset = - 12 ;
}
BLOCK_CAPTURING ;
2011-12-22 16:05:19 +03:00
arts = new CArtifactsOfHero ( Point ( pos . x + xOffset , pos . y + yOffset ) ) ;
2011-04-23 00:51:10 +03:00
arts - > commonInfo = new CArtifactsOfHero : : SCommonPart ;
arts - > commonInfo - > participants . insert ( arts ) ;
arts - > recActions = 255 ;
arts - > setHero ( hero ) ;
arts - > allowedAssembling = false ;
addChild ( arts ) ;
artSets . push_back ( arts ) ;
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_RESOURCE )
2013-07-02 18:23:32 +03:00
arts - > highlightModeCallback = boost : : bind ( & CTradeWindow : : artifactSelected , this , _1 ) ;
2011-04-23 00:51:10 +03:00
return ;
}
2010-07-20 09:05:45 +03:00
std : : vector < int > * ids = getItemsIds ( Left ) ;
2011-12-22 16:05:19 +03:00
std : : vector < Rect > pos ;
2010-07-20 09:05:45 +03:00
int amount = - 1 ;
getPositionsFor ( pos , Left , itemsType [ Left ] ) ;
if ( Left | | ! ids )
amount = 7 ;
2012-01-12 18:23:00 +03:00
else
2010-07-20 09:05:45 +03:00
amount = ids - > size ( ) ;
2010-05-08 01:10:32 +03:00
if ( ids )
2011-12-14 00:23:17 +03:00
vstd : : amin ( amount , ids - > size ( ) ) ;
2010-05-08 01:10:32 +03:00
2010-07-20 09:05:45 +03:00
for ( int j = 0 ; j < amount ; j + + )
2009-05-19 21:23:04 +03:00
{
2010-05-26 12:47:53 +03:00
int id = ( ids & & ids - > size ( ) > j ) ? ( * ids ) [ j ] : j ;
2011-12-14 00:23:17 +03:00
if ( id < 0 & & mode ! = EMarketMode : : ARTIFACT_EXP ) //when sacrificing artifacts we need to prepare empty slots
2010-05-26 12:47:53 +03:00
continue ;
2013-06-29 16:05:48 +03:00
auto hlp = new CTradeableItem ( pos [ j ] . topLeft ( ) , itemsType [ Left ] , id , Left , j ) ;
2012-12-23 13:23:41 +03:00
hlp - > pos = pos [ j ] + this - > pos . topLeft ( ) ;
2010-07-20 09:05:45 +03:00
items [ Left ] . push_back ( hlp ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-20 09:05:45 +03:00
initSubs ( Left ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-20 09:05:45 +03:00
std : : vector < int > * CTradeWindow : : getItemsIds ( bool Left )
2009-05-19 21:23:04 +03:00
{
2013-06-26 14:18:27 +03:00
std : : vector < int > * ids = nullptr ;
2010-06-27 19:03:01 +03:00
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_EXP )
2010-07-23 15:02:15 +03:00
return new std : : vector < int > ( 22 , - 1 ) ;
2010-07-20 09:05:45 +03:00
if ( Left )
{
switch ( itemsType [ 1 ] )
{
case CREATURE :
ids = new std : : vector < int > ;
for ( int i = 0 ; i < 7 ; i + + )
{
2013-02-16 17:03:47 +03:00
if ( const CCreature * c = hero - > getCreature ( SlotID ( i ) ) )
2010-07-20 09:05:45 +03:00
ids - > push_back ( c - > idNumber ) ;
else
ids - > push_back ( - 1 ) ;
}
break ;
}
}
else
{
switch ( itemsType [ 0 ] )
{
case PLAYER :
ids = new std : : vector < int > ;
2013-03-03 20:06:03 +03:00
for ( int i = 0 ; i < PlayerColor : : PLAYER_LIMIT_I ; i + + )
if ( PlayerColor ( i ) ! = LOCPLINT - > playerID & & LOCPLINT - > cb - > getPlayerStatus ( PlayerColor ( i ) ) = = EPlayerStatus : : INGAME )
2010-07-20 09:05:45 +03:00
ids - > push_back ( i ) ;
break ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2010-07-20 09:05:45 +03:00
ids = new std : : vector < int > ( market - > availableItemsIds ( mode ) ) ;
break ;
}
}
return ids ;
}
2011-12-22 16:05:19 +03:00
void CTradeWindow : : getPositionsFor ( std : : vector < Rect > & poss , bool Left , EType type ) const
2010-07-20 09:05:45 +03:00
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_EXP & & ! Left )
2010-07-20 09:05:45 +03:00
{
//22 boxes, 5 in row, last row: two boxes centered
int h , w , x , y , dx , dy ;
h = w = 44 ;
x = 317 ;
y = 53 ;
dx = 54 ;
dy = 70 ;
for ( int i = 0 ; i < 4 ; i + + )
for ( int j = 0 ; j < 5 ; j + + )
2011-12-22 16:05:19 +03:00
poss + = Rect ( x + dx * j , y + dy * i , w , h ) ;
2010-07-20 09:05:45 +03:00
2011-12-22 16:05:19 +03:00
poss + = Rect ( x + dx * 1.5 , y + dy * 4 , w , h ) ;
poss + = Rect ( x + dx * 2.5 , y + dy * 4 , w , h ) ;
2010-07-20 09:05:45 +03:00
}
else
{
//seven boxes:
// X X X
// X X X
2012-01-12 18:23:00 +03:00
// X
2010-07-20 09:05:45 +03:00
int h , w , x , y , dx , dy ;
int leftToRightOffset ;
getBaseForPositions ( type , dx , dy , x , y , h , w , ! Left , leftToRightOffset ) ;
poss + = genRect ( h , w , x , y ) , genRect ( h , w , x + dx , y ) , genRect ( h , w , x + 2 * dx , y ) ,
genRect ( h , w , x , y + dy ) , genRect ( h , w , x + dx , y + dy ) , genRect ( h , w , x + 2 * dx , y + dy ) ,
genRect ( h , w , x + dx , y + 2 * dy ) ;
if ( ! Left )
2010-11-15 17:15:00 +02:00
{
2013-06-29 16:05:48 +03:00
for ( Rect & r : poss )
2010-07-20 09:05:45 +03:00
r . x + = leftToRightOffset ;
2010-11-15 17:15:00 +02:00
}
2010-07-20 09:05:45 +03:00
}
}
void CTradeWindow : : initSubs ( bool Left )
{
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ Left ] )
2010-07-20 09:05:45 +03:00
{
if ( Left )
{
switch ( itemsType [ 1 ] )
{
case CREATURE :
2013-02-16 17:03:47 +03:00
t - > subtitle = boost : : lexical_cast < std : : string > ( hero - > getStackCount ( SlotID ( t - > serial ) ) ) ;
2010-07-20 09:05:45 +03:00
break ;
case RESOURCE :
2013-02-09 15:56:35 +03:00
t - > subtitle = boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > getResourceAmount ( static_cast < Res : : ERes > ( t - > serial ) ) ) ;
2010-07-20 09:05:45 +03:00
break ;
}
}
else //right side
{
if ( itemsType [ 0 ] = = PLAYER )
{
t - > subtitle = CGI - > generaltexth - > capColors [ t - > id ] ;
}
else if ( hLeft ) //artifact, creature
{
int h1 , h2 ; //hlp variables for getting offer
market - > getOffer ( hLeft - > id , t - > id , h1 , h2 , mode ) ;
2011-12-14 00:23:17 +03:00
if ( t - > id ! = hLeft - > id | | mode ! = EMarketMode : : RESOURCE_RESOURCE ) //don't allow exchanging same resources
2010-07-20 09:05:45 +03:00
{
std : : ostringstream oss ;
oss < < h2 ;
if ( h1 ! = 1 )
oss < < " / " < < h1 ;
t - > subtitle = oss . str ( ) ;
}
else
t - > subtitle = CGI - > generaltexth - > allTexts [ 164 ] ; // n/a
}
else
t - > subtitle = " " ;
}
}
}
void CTradeWindow : : showAll ( SDL_Surface * to )
{
2012-06-15 20:08:19 +03:00
CWindowObject : : showAll ( to ) ;
2010-07-20 09:05:45 +03:00
if ( hRight )
CSDL_Ext : : drawBorder ( to , hRight - > pos . x - 1 , hRight - > pos . y - 1 , hRight - > pos . w + 2 , hRight - > pos . h + 2 , int3 ( 255 , 231 , 148 ) ) ;
2011-04-23 00:51:10 +03:00
if ( hLeft & & hLeft - > type ! = ARTIFACT_INSTANCE )
2010-07-20 09:05:45 +03:00
CSDL_Ext : : drawBorder ( to , hLeft - > pos . x - 1 , hLeft - > pos . y - 1 , hLeft - > pos . w + 2 , hLeft - > pos . h + 2 , int3 ( 255 , 231 , 148 ) ) ;
if ( readyToTrade )
{
hLeft - > showAllAt ( pos . topLeft ( ) + selectionOffset ( true ) , selectionSubtitle ( true ) , to ) ;
hRight - > showAllAt ( pos . topLeft ( ) + selectionOffset ( false ) , selectionSubtitle ( false ) , to ) ;
}
}
void CTradeWindow : : removeItems ( const std : : set < CTradeableItem * > & toRemove )
{
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : toRemove )
2010-07-20 09:05:45 +03:00
removeItem ( t ) ;
}
void CTradeWindow : : removeItem ( CTradeableItem * t )
{
items [ t - > left ] - = t ;
2012-06-02 18:16:54 +03:00
delete t ;
2010-07-20 09:05:45 +03:00
if ( hRight = = t )
{
2013-06-26 14:18:27 +03:00
hRight = nullptr ;
2010-07-20 09:05:45 +03:00
selectionChanged ( false ) ;
}
}
void CTradeWindow : : getEmptySlots ( std : : set < CTradeableItem * > & toRemove )
{
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 1 ] )
2013-02-16 17:03:47 +03:00
if ( ! hero - > getStackCount ( SlotID ( t - > serial ) ) )
2010-07-20 09:05:45 +03:00
toRemove . insert ( t ) ;
}
2011-12-14 00:23:17 +03:00
void CTradeWindow : : setMode ( EMarketMode : : EMarketMode Mode )
2010-07-20 09:05:45 +03:00
{
2010-07-23 15:02:15 +03:00
const IMarket * m = market ;
const CGHeroInstance * h = hero ;
2013-06-26 14:18:27 +03:00
CTradeWindow * nwindow = nullptr ;
2010-07-23 15:02:15 +03:00
GH . popIntTotally ( this ) ;
2012-01-12 18:23:00 +03:00
2010-07-20 09:05:45 +03:00
switch ( Mode )
{
2011-12-14 00:23:17 +03:00
case EMarketMode : : CREATURE_EXP :
case EMarketMode : : ARTIFACT_EXP :
2010-07-23 15:02:15 +03:00
nwindow = new CAltarWindow ( m , h , Mode ) ;
2010-07-20 09:05:45 +03:00
break ;
default :
2010-07-23 15:02:15 +03:00
nwindow = new CMarketplaceWindow ( m , h , Mode ) ;
2010-07-20 09:05:45 +03:00
break ;
}
GH . pushInt ( nwindow ) ;
}
2010-05-08 01:10:32 +03:00
2011-04-23 00:51:10 +03:00
void CTradeWindow : : artifactSelected ( CArtPlace * slot )
{
2011-12-14 00:23:17 +03:00
assert ( mode = = EMarketMode : : ARTIFACT_RESOURCE ) ;
2011-04-23 00:51:10 +03:00
items [ 1 ] [ 0 ] - > setArtInstance ( slot - > ourArt ) ;
2012-04-14 05:20:22 +03:00
if ( slot - > ourArt )
2011-04-23 00:51:10 +03:00
hLeft = items [ 1 ] [ 0 ] ;
else
2013-06-26 14:18:27 +03:00
hLeft = nullptr ;
2011-04-23 00:51:10 +03:00
selectionChanged ( true ) ;
}
2012-06-15 20:08:19 +03:00
std : : string CMarketplaceWindow : : getBackgroundForMode ( EMarketMode : : EMarketMode mode )
2010-07-20 09:05:45 +03:00
{
2012-06-15 20:08:19 +03:00
switch ( mode )
2010-05-08 01:10:32 +03:00
{
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_RESOURCE :
2012-06-15 20:08:19 +03:00
return " TPMRKRES.bmp " ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_PLAYER :
2012-06-15 20:08:19 +03:00
return " TPMRKPTS.bmp " ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : CREATURE_RESOURCE :
2012-06-15 20:08:19 +03:00
return " TPMRKCRS.bmp " ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_ARTIFACT :
2012-06-15 20:08:19 +03:00
return " TPMRKABS.bmp " ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : ARTIFACT_RESOURCE :
2012-06-15 20:08:19 +03:00
return " TPMRKASS.bmp " ;
2010-05-08 01:10:32 +03:00
}
2012-06-15 20:08:19 +03:00
assert ( 0 ) ;
return " " ;
}
CMarketplaceWindow : : CMarketplaceWindow ( const IMarket * Market , const CGHeroInstance * Hero , EMarketMode : : EMarketMode Mode )
: CTradeWindow ( getBackgroundForMode ( Mode ) , Market , Hero , Mode )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-05-08 01:10:32 +03:00
2012-06-15 20:08:19 +03:00
madeTransaction = false ;
bool sliderNeeded = true ;
2010-05-08 01:10:32 +03:00
2012-06-16 13:41:14 +03:00
new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2010-07-26 18:37:58 +03:00
2012-06-15 20:08:19 +03:00
std : : string title ;
2012-01-12 18:23:00 +03:00
2012-09-23 21:01:04 +03:00
if ( market - > o - > ID = = Obj : : TOWN )
2012-06-15 20:08:19 +03:00
{
switch ( mode )
{
2012-09-05 15:49:23 +03:00
break ; case EMarketMode : : CREATURE_RESOURCE :
2013-04-21 15:49:26 +03:00
title = CGI - > townh - > factions [ ETownType : : STRONGHOLD ] - > town - > buildings [ BuildingID : : FREELANCERS_GUILD ] - > Name ( ) ;
2012-09-05 15:49:23 +03:00
break ; case EMarketMode : : RESOURCE_ARTIFACT :
2013-04-21 15:49:26 +03:00
title = CGI - > townh - > factions [ market - > o - > subID ] - > town - > buildings [ BuildingID : : ARTIFACT_MERCHANT ] - > Name ( ) ;
2013-01-23 02:28:10 +03:00
sliderNeeded = false ;
2012-09-05 15:49:23 +03:00
break ; case EMarketMode : : ARTIFACT_RESOURCE :
2013-04-21 15:49:26 +03:00
title = CGI - > townh - > factions [ market - > o - > subID ] - > town - > buildings [ BuildingID : : ARTIFACT_MERCHANT ] - > Name ( ) ;
2013-01-23 02:28:10 +03:00
sliderNeeded = false ;
2012-09-05 15:49:23 +03:00
break ; default :
title = CGI - > generaltexth - > allTexts [ 158 ] ;
2012-06-15 20:08:19 +03:00
}
2010-10-31 21:56:37 +02:00
}
2010-05-26 12:47:53 +03:00
else
{
2012-06-15 20:08:19 +03:00
switch ( market - > o - > ID )
{
2013-01-31 23:11:25 +03:00
break ; case Obj : : BLACK_MARKET : title = CGI - > generaltexth - > allTexts [ 349 ] ;
break ; case Obj : : TRADING_POST : title = CGI - > generaltexth - > allTexts [ 159 ] ;
break ; case Obj : : TRADING_POST_SNOW : title = CGI - > generaltexth - > allTexts [ 159 ] ;
2012-06-15 20:08:19 +03:00
break ; default : title = market - > o - > getHoverText ( ) ;
}
2010-05-26 12:47:53 +03:00
}
2010-05-08 01:10:32 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 300 , 27 , FONT_BIG , CENTER , Colors : : YELLOW , title ) ;
2012-06-15 20:08:19 +03:00
2010-07-20 09:05:45 +03:00
initItems ( false ) ;
initItems ( true ) ;
2012-01-12 18:23:00 +03:00
2013-07-02 18:23:32 +03:00
ok = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 600 ] , boost : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) , 516 , 520 , " IOK6432.DEF " , SDLK_RETURN ) ;
2009-07-27 20:55:56 +03:00
ok - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2013-07-02 18:23:32 +03:00
deal = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 595 ] , boost : : bind ( & CMarketplaceWindow : : makeDeal , this ) , 307 , 520 , " TPMRKB.DEF " ) ;
2010-06-27 19:03:01 +03:00
deal - > block ( true ) ;
if ( sliderNeeded )
{
2013-06-29 16:05:48 +03:00
slider = new CSlider ( 231 , 490 , 137 , nullptr , 0 , 0 ) ;
2013-07-02 18:23:32 +03:00
slider - > moved = boost : : bind ( & CMarketplaceWindow : : sliderMoved , this , _1 ) ;
max = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 596 ] , boost : : bind ( & CMarketplaceWindow : : setMax , this ) , 229 , 520 , " IRCBTNS.DEF " ) ;
2010-06-27 19:03:01 +03:00
max - > block ( true ) ;
}
else
{
2013-06-26 14:18:27 +03:00
slider = nullptr ;
max = nullptr ;
2011-12-22 16:05:19 +03:00
deal - > moveBy ( Point ( - 30 , 0 ) ) ;
2010-06-27 19:03:01 +03:00
}
2010-05-08 01:10:32 +03:00
2011-12-22 16:05:19 +03:00
Rect traderTextRect ;
2010-07-31 04:38:12 +03:00
2010-05-26 12:47:53 +03:00
//left side
2010-05-08 01:10:32 +03:00
switch ( Mode )
{
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_RESOURCE :
case EMarketMode : : RESOURCE_PLAYER :
case EMarketMode : : RESOURCE_ARTIFACT :
2012-11-11 15:23:31 +03:00
new CLabel ( 154 , 148 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 270 ] ) ;
2012-06-22 14:40:16 +03:00
break ;
2012-06-15 20:08:19 +03:00
2012-01-12 18:23:00 +03:00
case EMarketMode : : CREATURE_RESOURCE :
2012-06-15 20:08:19 +03:00
//%s's Creatures
2012-11-11 15:23:31 +03:00
new CLabel ( 152 , 102 , FONT_SMALL , CENTER , Colors : : WHITE ,
2012-06-15 20:08:19 +03:00
boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 272 ] ) % hero - > name ) ) ;
2010-05-26 12:47:53 +03:00
break ;
2012-01-12 18:23:00 +03:00
case EMarketMode : : ARTIFACT_RESOURCE :
2012-06-15 20:08:19 +03:00
//%s's Artifacts
2012-11-11 15:23:31 +03:00
new CLabel ( 152 , 102 , FONT_SMALL , CENTER , Colors : : WHITE ,
2012-06-15 20:08:19 +03:00
boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 272 ] ) % hero - > name ) ) ;
2011-04-23 00:51:10 +03:00
break ;
2010-05-26 12:47:53 +03:00
}
//right side
switch ( Mode )
{
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_RESOURCE :
case EMarketMode : : CREATURE_RESOURCE :
case EMarketMode : : RESOURCE_ARTIFACT :
case EMarketMode : : ARTIFACT_RESOURCE :
2012-11-11 15:23:31 +03:00
new CLabel ( 445 , 148 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 168 ] ) ;
2011-12-22 16:05:19 +03:00
traderTextRect = Rect ( 316 , 48 , 260 , 75 ) ;
2010-05-08 01:10:32 +03:00
break ;
2011-12-14 00:23:17 +03:00
case EMarketMode : : RESOURCE_PLAYER :
2012-11-11 15:23:31 +03:00
new CLabel ( 445 , 55 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 169 ] ) ;
2011-12-22 16:05:19 +03:00
traderTextRect = Rect ( 28 , 48 , 260 , 75 ) ;
2010-05-08 01:10:32 +03:00
break ;
}
2009-05-19 21:23:04 +03:00
2010-07-31 04:38:12 +03:00
traderText = new CTextBox ( " " , traderTextRect , 0 , FONT_SMALL , CENTER ) ;
2011-12-14 00:23:17 +03:00
int specialOffset = mode = = EMarketMode : : ARTIFACT_RESOURCE ? 35 : 0 ; //in selling artifacts mode we need to move res-res and art-res buttons down
if ( printButtonFor ( EMarketMode : : RESOURCE_PLAYER ) )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 612 ] , boost : : bind ( & CMarketplaceWindow : : setMode , this , EMarketMode : : RESOURCE_PLAYER ) , 18 , 520 , " TPMRKBU1.DEF " ) ;
2011-12-14 00:23:17 +03:00
if ( printButtonFor ( EMarketMode : : RESOURCE_RESOURCE ) )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 605 ] , boost : : bind ( & CMarketplaceWindow : : setMode , this , EMarketMode : : RESOURCE_RESOURCE ) , 516 , 450 + specialOffset , " TPMRKBU5.DEF " ) ;
2011-12-14 00:23:17 +03:00
if ( printButtonFor ( EMarketMode : : CREATURE_RESOURCE ) )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 599 ] , boost : : bind ( & CMarketplaceWindow : : setMode , this , EMarketMode : : CREATURE_RESOURCE ) , 516 , 485 , " TPMRKBU4.DEF " ) ; //was y=450, changed to not overlap res-res in some conditions
2011-12-14 00:23:17 +03:00
if ( printButtonFor ( EMarketMode : : RESOURCE_ARTIFACT ) )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 598 ] , boost : : bind ( & CMarketplaceWindow : : setMode , this , EMarketMode : : RESOURCE_ARTIFACT ) , 18 , 450 + specialOffset , " TPMRKBU2.DEF " ) ;
2012-01-12 18:23:00 +03:00
if ( printButtonFor ( EMarketMode : : ARTIFACT_RESOURCE ) )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 613 ] , boost : : bind ( & CMarketplaceWindow : : setMode , this , EMarketMode : : ARTIFACT_RESOURCE ) , 18 , 485 , " TPMRKBU3.DEF " ) ; //was y=450, changed to not overlap res-art in some conditions
2010-05-26 12:47:53 +03:00
2010-07-31 04:38:12 +03:00
updateTraderText ( ) ;
2009-05-19 21:23:04 +03:00
}
CMarketplaceWindow : : ~ CMarketplaceWindow ( )
{
2013-06-26 14:18:27 +03:00
hLeft = hRight = nullptr ;
2013-06-29 16:05:48 +03:00
for ( auto & elem : items [ 1 ] )
delete elem ;
for ( auto & elem : items [ 0 ] )
delete elem ;
2010-05-08 01:10:32 +03:00
2010-07-20 09:05:45 +03:00
items [ 1 ] . clear ( ) ;
items [ 0 ] . clear ( ) ;
2009-05-19 21:23:04 +03:00
}
2010-05-08 01:10:32 +03:00
2009-05-19 21:23:04 +03:00
void CMarketplaceWindow : : setMax ( )
{
2010-10-24 14:35:14 +03:00
slider - > moveToMax ( ) ;
2009-05-19 21:23:04 +03:00
}
void CMarketplaceWindow : : makeDeal ( )
{
2010-06-27 19:03:01 +03:00
int sliderValue = 0 ;
if ( slider )
sliderValue = slider - > value ;
2012-01-12 18:23:00 +03:00
else
2011-02-20 11:24:53 +02:00
sliderValue = ! deal - > isBlocked ( ) ; //should always be 1
2010-06-27 19:03:01 +03:00
if ( ! sliderValue )
2010-05-26 12:47:53 +03:00
return ;
int leftIdToSend = - 1 ;
2012-01-28 14:42:15 +03:00
switch ( mode )
{
case EMarketMode : : CREATURE_RESOURCE :
leftIdToSend = hLeft - > serial ;
break ;
case EMarketMode : : ARTIFACT_RESOURCE :
2013-02-14 02:55:42 +03:00
leftIdToSend = hLeft - > getArtInstance ( ) - > id . getNum ( ) ;
2012-01-28 14:42:15 +03:00
break ;
default :
leftIdToSend = hLeft - > id ;
break ;
}
2010-05-26 12:47:53 +03:00
2011-04-23 00:51:10 +03:00
if ( slider )
2010-06-27 19:03:01 +03:00
{
LOCPLINT - > cb - > trade ( market - > o , mode , leftIdToSend , hRight - > id , slider - > value * r1 , hero ) ;
slider - > moveTo ( 0 ) ;
}
else
{
LOCPLINT - > cb - > trade ( market - > o , mode , leftIdToSend , hRight - > id , r2 , hero ) ;
}
2010-07-31 04:38:12 +03:00
madeTransaction = true ;
2010-06-27 19:03:01 +03:00
2013-06-26 14:18:27 +03:00
hLeft = nullptr ;
hRight = nullptr ;
2009-05-19 21:23:04 +03:00
selectionChanged ( true ) ;
}
void CMarketplaceWindow : : sliderMoved ( int to )
{
2010-05-26 12:47:53 +03:00
redraw ( ) ;
2009-05-19 21:23:04 +03:00
}
void CMarketplaceWindow : : selectionChanged ( bool side )
{
2011-04-23 00:51:10 +03:00
readyToTrade = hLeft & & hRight ;
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : RESOURCE_RESOURCE )
2012-01-12 18:23:00 +03:00
readyToTrade = readyToTrade & & ( hLeft - > id ! = hRight - > id ) ; //for resource trade, two DIFFERENT resources must be selected
2010-05-26 12:47:53 +03:00
2012-01-12 18:23:00 +03:00
if ( mode = = EMarketMode : : ARTIFACT_RESOURCE & & ! hLeft )
2011-04-23 00:51:10 +03:00
arts - > unmarkSlots ( false ) ;
2012-01-12 18:23:00 +03:00
2010-05-26 12:47:53 +03:00
if ( readyToTrade )
2009-05-19 21:23:04 +03:00
{
2011-04-23 00:51:10 +03:00
int soldItemId = hLeft - > id ;
market - > getOffer ( soldItemId , hRight - > id , r1 , r2 , mode ) ;
2010-05-26 12:47:53 +03:00
2010-06-27 19:03:01 +03:00
if ( slider )
{
2011-04-23 00:51:10 +03:00
int newAmount = - 1 ;
if ( itemsType [ 1 ] = = RESOURCE )
2013-02-09 15:56:35 +03:00
newAmount = LOCPLINT - > cb - > getResourceAmount ( static_cast < Res : : ERes > ( soldItemId ) ) ;
2011-04-23 00:51:10 +03:00
else if ( itemsType [ 1 ] = = CREATURE )
2013-02-16 17:03:47 +03:00
newAmount = hero - > getStackCount ( SlotID ( hLeft - > serial ) ) - ( hero - > Slots ( ) . size ( ) = = 1 & & hero - > needsLastStack ( ) ) ;
2011-04-23 00:51:10 +03:00
else
assert ( 0 ) ;
2010-06-27 19:03:01 +03:00
slider - > setAmount ( newAmount / r1 ) ;
slider - > moveTo ( 0 ) ;
max - > block ( false ) ;
deal - > block ( false ) ;
}
2011-04-23 00:51:10 +03:00
else if ( itemsType [ 1 ] = = RESOURCE ) //buying -> check if we can afford transaction
2010-06-27 19:03:01 +03:00
{
2013-02-09 15:56:35 +03:00
deal - > block ( LOCPLINT - > cb - > getResourceAmount ( static_cast < Res : : ERes > ( soldItemId ) ) < r1 ) ;
2010-06-27 19:03:01 +03:00
}
2011-04-23 00:51:10 +03:00
else
deal - > block ( false ) ;
2009-05-19 21:23:04 +03:00
}
else
{
2010-06-27 19:03:01 +03:00
if ( slider )
{
max - > block ( true ) ;
slider - > setAmount ( 0 ) ;
slider - > moveTo ( 0 ) ;
}
2009-05-19 21:23:04 +03:00
deal - > block ( true ) ;
}
2010-06-27 19:03:01 +03:00
2010-07-20 09:05:45 +03:00
if ( side & & itemsType [ 0 ] ! = PLAYER ) //items[1] selection changed, recalculate offers
initSubs ( false ) ;
2010-07-31 04:38:12 +03:00
updateTraderText ( ) ;
2010-07-20 09:05:45 +03:00
redraw ( ) ;
}
2011-12-14 00:23:17 +03:00
bool CMarketplaceWindow : : printButtonFor ( EMarketMode : : EMarketMode M ) const
2010-07-20 09:05:45 +03:00
{
2011-12-14 00:23:17 +03:00
return market - > allowsTrade ( M ) & & M ! = mode & & ( hero | | ( M ! = EMarketMode : : CREATURE_RESOURCE & & M ! = EMarketMode : : RESOURCE_ARTIFACT & & M ! = EMarketMode : : ARTIFACT_RESOURCE ) ) ;
2010-07-20 09:05:45 +03:00
}
void CMarketplaceWindow : : garrisonChanged ( )
{
2011-12-14 00:23:17 +03:00
if ( mode ! = EMarketMode : : CREATURE_RESOURCE )
2010-07-20 09:05:45 +03:00
return ;
std : : set < CTradeableItem * > toRemove ;
getEmptySlots ( toRemove ) ;
removeItems ( toRemove ) ;
initSubs ( true ) ;
}
void CMarketplaceWindow : : artifactsChanged ( bool Left )
{
assert ( ! Left ) ;
2011-12-14 00:23:17 +03:00
if ( mode ! = EMarketMode : : RESOURCE_ARTIFACT )
2010-07-20 09:05:45 +03:00
return ;
std : : vector < int > available = market - > availableItemsIds ( mode ) ;
std : : set < CTradeableItem * > toRemove ;
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 0 ] )
2010-07-20 09:05:45 +03:00
if ( ! vstd : : contains ( available , t - > id ) )
toRemove . insert ( t ) ;
removeItems ( toRemove ) ;
2010-07-31 04:38:12 +03:00
redraw ( ) ;
2010-07-20 09:05:45 +03:00
}
std : : string CMarketplaceWindow : : selectionSubtitle ( bool Left ) const
{
if ( Left )
2009-05-19 21:23:04 +03:00
{
2011-04-23 00:51:10 +03:00
switch ( itemsType [ 1 ] )
{
case RESOURCE :
case CREATURE :
{
2012-01-12 18:23:00 +03:00
int val = slider
? slider - > value * r1
2011-04-23 00:51:10 +03:00
: ( ( ( deal - > isBlocked ( ) ) ) ? 0 : r1 ) ;
2010-07-20 09:05:45 +03:00
2011-04-23 00:51:10 +03:00
return boost : : lexical_cast < std : : string > ( val ) ;
}
case ARTIFACT_INSTANCE :
return ( ( deal - > isBlocked ( ) ) ? " 0 " : " 1 " ) ;
}
2010-07-20 09:05:45 +03:00
}
else
{
switch ( itemsType [ 0 ] )
2009-05-19 21:23:04 +03:00
{
2010-07-20 09:05:45 +03:00
case RESOURCE :
2011-04-23 00:51:10 +03:00
if ( slider )
return boost : : lexical_cast < std : : string > ( slider - > value * r2 ) ;
else
return boost : : lexical_cast < std : : string > ( r2 ) ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2011-02-20 11:24:53 +02:00
return ( ( deal - > isBlocked ( ) ) ? " 0 " : " 1 " ) ;
2010-07-20 09:05:45 +03:00
case PLAYER :
return ( hRight ? CGI - > generaltexth - > capColors [ hRight - > id ] : " " ) ;
}
}
return " ??? " ;
}
2010-05-18 10:01:54 +03:00
2011-12-22 16:05:19 +03:00
Point CMarketplaceWindow : : selectionOffset ( bool Left ) const
2010-07-20 09:05:45 +03:00
{
if ( Left )
{
switch ( itemsType [ 1 ] )
{
case RESOURCE :
2011-12-22 16:05:19 +03:00
return Point ( 122 , 446 ) ;
2010-07-20 09:05:45 +03:00
case CREATURE :
2011-12-22 16:05:19 +03:00
return Point ( 128 , 450 ) ;
2011-04-23 00:51:10 +03:00
case ARTIFACT_INSTANCE :
2011-12-22 16:05:19 +03:00
return Point ( 134 , 466 ) ;
2009-05-19 21:23:04 +03:00
}
}
2010-07-20 09:05:45 +03:00
else
{
switch ( itemsType [ 0 ] )
{
case RESOURCE :
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_RESOURCE )
2011-12-22 16:05:19 +03:00
return Point ( 410 , 469 ) ;
2011-04-23 00:51:10 +03:00
else
2011-12-22 16:05:19 +03:00
return Point ( 410 , 446 ) ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE :
2011-12-22 16:05:19 +03:00
return Point ( 425 , 447 ) ;
2010-07-20 09:05:45 +03:00
case PLAYER :
2011-12-22 16:05:19 +03:00
return Point ( 417 , 451 ) ;
2010-07-20 09:05:45 +03:00
}
}
assert ( 0 ) ;
2011-12-22 16:05:19 +03:00
return Point ( 0 , 0 ) ;
2009-05-19 21:23:04 +03:00
}
2010-07-20 09:05:45 +03:00
void CMarketplaceWindow : : resourceChanged ( int type , int val )
{
initSubs ( true ) ;
}
void CMarketplaceWindow : : getBaseForPositions ( EType type , int & dx , int & dy , int & x , int & y , int & h , int & w , bool Right , int & leftToRightOffset ) const
2010-05-08 01:10:32 +03:00
{
2010-05-26 12:47:53 +03:00
switch ( type )
2010-05-08 01:10:32 +03:00
{
2010-05-26 12:47:53 +03:00
case RESOURCE :
dx = 82 ;
dy = 79 ;
x = 39 ;
y = 180 ;
h = 66 ;
w = 74 ;
break ;
case PLAYER :
dx = 83 ;
dy = 118 ;
h = 64 ;
w = 58 ;
x = 44 ;
y = 83 ;
2010-05-08 01:10:32 +03:00
assert ( Right ) ;
2010-05-26 12:47:53 +03:00
break ;
case CREATURE : //45,123
x = 45 ;
y = 123 ;
w = 58 ;
h = 64 ;
dx = 83 ;
dy = 98 ;
assert ( ! Right ) ;
2010-07-20 09:05:45 +03:00
break ;
2010-12-29 23:04:22 +02:00
case ARTIFACT_TYPE : //45,123
2010-07-26 18:37:58 +03:00
x = 340 - 289 ;
y = 180 ;
2010-06-27 19:03:01 +03:00
w = 44 ;
h = 44 ;
dx = 83 ;
dy = 79 ;
2010-07-20 09:05:45 +03:00
break ;
2010-05-08 01:10:32 +03:00
}
2010-05-26 12:47:53 +03:00
2010-07-26 18:37:58 +03:00
leftToRightOffset = 289 ;
2010-07-20 09:05:45 +03:00
}
2010-07-31 04:38:12 +03:00
void CMarketplaceWindow : : updateTraderText ( )
{
if ( readyToTrade )
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : RESOURCE_PLAYER )
2010-07-31 04:38:12 +03:00
{
//I can give %s to the %s player.
2013-08-29 16:46:27 +03:00
traderText - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 165 ] ) % hLeft - > getName ( ) % hRight - > getName ( ) ) ) ;
2010-07-31 04:38:12 +03:00
}
2011-12-14 00:23:17 +03:00
else if ( mode = = EMarketMode : : RESOURCE_ARTIFACT )
2010-07-31 04:38:12 +03:00
{
//I can offer you the %s for %d %s of %s.
2013-08-29 16:46:27 +03:00
traderText - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 267 ] ) % hRight - > getName ( ) % r1 % CGI - > generaltexth - > allTexts [ 160 + ( r1 = = 1 ) ] % hLeft - > getName ( ) ) ) ;
2010-07-31 04:38:12 +03:00
}
2011-12-14 00:23:17 +03:00
else if ( mode = = EMarketMode : : RESOURCE_RESOURCE )
2010-07-31 04:38:12 +03:00
{
//I can offer you %d %s of %s for %d %s of %s.
2013-08-29 16:46:27 +03:00
traderText - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 157 ] ) % r2 % CGI - > generaltexth - > allTexts [ 160 + ( r2 = = 1 ) ] % hRight - > getName ( ) % r1 % CGI - > generaltexth - > allTexts [ 160 + ( r1 = = 1 ) ] % hLeft - > getName ( ) ) ) ;
2010-07-31 04:38:12 +03:00
}
2011-12-14 00:23:17 +03:00
else if ( mode = = EMarketMode : : CREATURE_RESOURCE )
2010-07-31 04:38:12 +03:00
{
//I can offer you %d %s of %s for %d %s.
2013-08-29 16:46:27 +03:00
traderText - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 269 ] ) % r2 % CGI - > generaltexth - > allTexts [ 160 + ( r2 = = 1 ) ] % hRight - > getName ( ) % r1 % hLeft - > getName ( r1 ) ) ) ;
2010-07-31 04:38:12 +03:00
}
2011-12-14 00:23:17 +03:00
else if ( mode = = EMarketMode : : ARTIFACT_RESOURCE )
2011-04-23 00:51:10 +03:00
{
//I can offer you %d %s of %s for your %s.
2013-08-29 16:46:27 +03:00
traderText - > setText ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 268 ] ) % r2 % CGI - > generaltexth - > allTexts [ 160 + ( r2 = = 1 ) ] % hRight - > getName ( ) % hLeft - > getName ( r1 ) ) ) ;
2011-04-23 00:51:10 +03:00
}
2010-07-31 04:38:12 +03:00
return ;
}
int gnrtxtnr = - 1 ;
if ( madeTransaction )
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : RESOURCE_PLAYER )
2010-07-31 04:38:12 +03:00
gnrtxtnr = 166 ; //Are there any other resources you'd like to give away?
else
gnrtxtnr = 162 ; //You have received quite a bargain. I expect to make no profit on the deal. Can I interest you in any of my other wares?
}
else
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : RESOURCE_PLAYER )
2010-07-31 04:38:12 +03:00
gnrtxtnr = 167 ; //If you'd like to give any of your resources to another player, click on the item you wish to give and to whom.
else
gnrtxtnr = 163 ; //Please inspect our fine wares. If you feel like offering a trade, click on the items you wish to trade with and for.
}
2013-08-29 16:46:27 +03:00
traderText - > setText ( CGI - > generaltexth - > allTexts [ gnrtxtnr ] ) ;
2010-07-31 04:38:12 +03:00
}
2013-06-26 14:18:27 +03:00
CAltarWindow : : CAltarWindow ( const IMarket * Market , const CGHeroInstance * Hero /*= nullptr*/ , EMarketMode : : EMarketMode Mode )
2012-06-15 20:08:19 +03:00
: CTradeWindow ( ( Mode = = EMarketMode : : CREATURE_EXP ? " ALTARMON.bmp " : " ALTRART2.bmp " ) , Market , Hero , Mode )
2010-07-20 09:05:45 +03:00
{
2012-09-29 18:10:56 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2011-12-14 00:23:17 +03:00
if ( Mode = = EMarketMode : : CREATURE_EXP )
2010-07-20 09:05:45 +03:00
{
2012-06-15 20:08:19 +03:00
//%s's Creatures
2012-11-11 15:23:31 +03:00
new CLabel ( 155 , 30 , FONT_SMALL , CENTER , Colors : : YELLOW ,
2012-06-15 20:08:19 +03:00
boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 272 ] ) % hero - > name ) ) ;
//Altar of Sacrifice
2012-11-11 15:23:31 +03:00
new CLabel ( 450 , 30 , FONT_SMALL , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 479 ] ) ;
2012-06-15 20:08:19 +03:00
//To sacrifice creatures, move them from your army on to the Altar and click Sacrifice
2012-11-11 15:23:31 +03:00
new CTextBox ( CGI - > generaltexth - > allTexts [ 480 ] , Rect ( 320 , 56 , 256 , 40 ) , 0 , FONT_SMALL , CENTER , Colors : : YELLOW ) ;
2010-07-20 09:05:45 +03:00
2013-06-29 16:05:48 +03:00
slider = new CSlider ( 231 , 481 , 137 , nullptr , 0 , 0 ) ;
2013-07-02 18:23:32 +03:00
slider - > moved = boost : : bind ( & CAltarWindow : : sliderMoved , this , _1 ) ;
max = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 578 ] , boost : : bind ( & CSlider : : moveToMax , slider ) , 147 , 520 , " IRCBTNS.DEF " ) ;
2010-07-20 09:05:45 +03:00
2011-12-14 00:23:17 +03:00
sacrificedUnits . resize ( GameConstants : : ARMY_SIZE , 0 ) ;
2013-07-02 18:23:32 +03:00
sacrificeAll = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 579 ] , boost : : bind ( & CAltarWindow : : SacrificeAll , this ) , 393 , 520 , " ALTARMY.DEF " ) ;
2013-06-26 14:18:27 +03:00
sacrificeBackpack = nullptr ;
2010-07-20 09:05:45 +03:00
initItems ( true ) ;
mimicCres ( ) ;
2012-12-23 13:23:41 +03:00
artIcon = nullptr ;
2010-07-20 09:05:45 +03:00
}
else
{
2012-06-15 20:08:19 +03:00
//Sacrifice artifacts for experience
2012-11-11 15:23:31 +03:00
new CLabel ( 450 , 34 , FONT_SMALL , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 477 ] ) ;
2012-06-15 20:08:19 +03:00
//%s's Creatures
2012-11-11 15:23:31 +03:00
new CLabel ( 302 , 423 , FONT_SMALL , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 478 ] ) ;
2010-07-20 09:05:45 +03:00
2013-07-02 18:23:32 +03:00
sacrificeAll = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 571 ] , boost : : bind ( & CAltarWindow : : SacrificeAll , this ) , 393 , 520 , " ALTFILL.DEF " ) ;
2012-06-15 20:08:19 +03:00
sacrificeAll - > block ( hero - > artifactsInBackpack . empty ( ) & & hero - > artifactsWorn . empty ( ) ) ;
2013-07-02 18:23:32 +03:00
sacrificeBackpack = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 570 ] , boost : : bind ( & CAltarWindow : : SacrificeBackpack , this ) , 147 , 520 , " ALTEMBK.DEF " ) ;
2012-06-15 20:08:19 +03:00
sacrificeBackpack - > block ( hero - > artifactsInBackpack . empty ( ) ) ;
2010-07-20 09:05:45 +03:00
2013-06-26 14:18:27 +03:00
slider = nullptr ;
max = nullptr ;
2012-01-12 18:23:00 +03:00
2011-04-23 00:51:10 +03:00
initItems ( true ) ;
2010-07-20 09:05:45 +03:00
initItems ( false ) ;
2012-12-23 13:23:41 +03:00
artIcon = new CAnimImage ( " ARTIFACT " , 0 , 0 , 281 , 442 ) ;
artIcon - > disable ( ) ;
2010-07-20 09:05:45 +03:00
}
2012-06-15 20:08:19 +03:00
//Experience needed to reach next level
2012-11-11 15:23:31 +03:00
new CTextBox ( CGI - > generaltexth - > allTexts [ 475 ] , Rect ( 15 , 415 , 125 , 50 ) , 0 , FONT_SMALL , CENTER , Colors : : YELLOW ) ;
2012-06-15 20:08:19 +03:00
//Total experience on the Altar
2012-11-11 15:23:31 +03:00
new CTextBox ( CGI - > generaltexth - > allTexts [ 476 ] , Rect ( 15 , 495 , 125 , 40 ) , 0 , FONT_SMALL , CENTER , Colors : : YELLOW ) ;
2010-07-20 09:05:45 +03:00
2012-06-16 13:41:14 +03:00
new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2013-07-02 18:23:32 +03:00
ok = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 568 ] , boost : : bind ( & CGuiHandler : : popIntTotally , & GH , this ) , 516 , 520 , " IOK6432.DEF " , SDLK_RETURN ) ;
2010-07-20 09:05:45 +03:00
ok - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2013-07-02 18:23:32 +03:00
deal = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 585 ] , boost : : bind ( & CAltarWindow : : makeDeal , this ) , 269 , 520 , " ALTSACR.DEF " ) ;
2010-07-20 09:05:45 +03:00
2011-12-14 00:23:17 +03:00
if ( Hero - > getAlignment ( ) ! = : : EAlignment : : EVIL & & Mode = = EMarketMode : : CREATURE_EXP )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 580 ] , boost : : bind ( & CTradeWindow : : setMode , this , EMarketMode : : ARTIFACT_EXP ) , 516 , 421 , " ALTART.DEF " ) ;
2011-12-14 00:23:17 +03:00
if ( Hero - > getAlignment ( ) ! = : : EAlignment : : GOOD & & Mode = = EMarketMode : : ARTIFACT_EXP )
2013-07-02 18:23:32 +03:00
new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 572 ] , boost : : bind ( & CTradeWindow : : setMode , this , EMarketMode : : CREATURE_EXP ) , 516 , 421 , " ALTSACC.DEF " ) ;
2010-07-20 09:05:45 +03:00
2011-12-14 00:23:17 +03:00
expPerUnit . resize ( GameConstants : : ARMY_SIZE , 0 ) ;
2010-07-20 09:05:45 +03:00
getExpValues ( ) ;
expToLevel = new CLabel ( 73 , 475 , FONT_SMALL , CENTER ) ;
expOnAltar = new CLabel ( 73 , 543 , FONT_SMALL , CENTER ) ;
setExpToLevel ( ) ;
calcTotalExp ( ) ;
blockTrade ( ) ;
2010-05-08 01:10:32 +03:00
}
2010-07-20 09:05:45 +03:00
CAltarWindow : : ~ CAltarWindow ( )
2010-05-08 01:10:32 +03:00
{
2010-07-20 09:05:45 +03:00
2010-05-08 01:10:32 +03:00
}
2010-07-20 09:05:45 +03:00
void CAltarWindow : : getBaseForPositions ( EType type , int & dx , int & dy , int & x , int & y , int & h , int & w , bool Right , int & leftToRightOffset ) const
2010-05-26 12:47:53 +03:00
{
2010-07-20 09:05:45 +03:00
leftToRightOffset = 289 ;
x = 45 ;
y = 110 ;
w = 58 ;
h = 64 ;
dx = 83 ;
dy = 98 ;
2010-05-26 12:47:53 +03:00
}
2010-07-20 09:05:45 +03:00
void CAltarWindow : : sliderMoved ( int to )
2010-05-26 12:47:53 +03:00
{
2010-07-20 09:05:45 +03:00
sacrificedUnits [ hLeft - > serial ] = to ;
updateRight ( hRight ) ;
deal - > block ( ! to ) ;
calcTotalExp ( ) ;
redraw ( ) ;
}
void CAltarWindow : : makeDeal ( )
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : CREATURE_EXP )
2010-07-20 09:05:45 +03:00
{
2010-07-23 15:02:15 +03:00
blockTrade ( ) ;
slider - > value = 0 ;
std : : vector < int > toSacrifice = sacrificedUnits ;
for ( int i = 0 ; i < toSacrifice . size ( ) ; i + + )
{
if ( toSacrifice [ i ] )
LOCPLINT - > cb - > trade ( market - > o , mode , i , 0 , toSacrifice [ i ] , hero ) ;
}
2010-07-20 09:05:45 +03:00
2013-06-29 16:05:48 +03:00
for ( int & val : sacrificedUnits )
2010-07-23 15:02:15 +03:00
val = 0 ;
2010-07-20 09:05:45 +03:00
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 0 ] )
2010-07-23 15:02:15 +03:00
{
2012-12-20 16:57:29 +03:00
t - > setType ( CREATURE_PLACEHOLDER ) ;
2010-07-23 15:02:15 +03:00
t - > subtitle = " " ;
}
}
else
2010-07-20 09:05:45 +03:00
{
2013-06-29 16:05:48 +03:00
for ( const CArtifactInstance * art : arts - > artifactsOnAltar ) //sacrifice each artifact on the list
2010-07-23 15:02:15 +03:00
{
2011-01-15 04:17:56 +02:00
LOCPLINT - > cb - > trade ( market - > o , mode , hero - > getArtPos ( art ) , - 1 , 1 , hero ) ;
2010-07-23 15:02:15 +03:00
}
arts - > artifactsOnAltar . clear ( ) ;
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 0 ] )
2010-07-23 15:02:15 +03:00
{
2012-12-20 16:57:29 +03:00
t - > setID ( - 1 ) ;
2010-07-23 15:02:15 +03:00
t - > subtitle = " " ;
}
arts - > commonInfo - > reset ( ) ;
2011-02-05 15:39:10 +02:00
//arts->scrollBackpack(0);
2010-07-23 15:02:15 +03:00
deal - > block ( true ) ;
2010-07-20 09:05:45 +03:00
}
calcTotalExp ( ) ;
}
void CAltarWindow : : SacrificeAll ( )
{
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : CREATURE_EXP )
2010-07-23 15:02:15 +03:00
{
bool movedAnything = false ;
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 1 ] )
2013-02-16 17:03:47 +03:00
sacrificedUnits [ t - > serial ] = hero - > getStackCount ( SlotID ( t - > serial ) ) ;
2010-07-20 09:05:45 +03:00
2010-07-23 15:02:15 +03:00
sacrificedUnits [ items [ 1 ] . front ( ) - > serial ] - - ;
2010-07-20 09:05:45 +03:00
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 0 ] )
2010-07-23 15:02:15 +03:00
{
updateRight ( t ) ;
if ( t - > type = = CREATURE )
movedAnything = true ;
}
2012-01-12 18:23:00 +03:00
2010-07-23 15:02:15 +03:00
deal - > block ( ! movedAnything ) ;
calcTotalExp ( ) ;
}
else
{
2013-02-07 02:24:43 +03:00
for ( auto i = hero - > artifactsWorn . cbegin ( ) ; i ! = hero - > artifactsWorn . cend ( ) ; i + + )
2010-07-23 15:02:15 +03:00
{
2013-02-07 02:24:43 +03:00
if ( i - > second . artifact - > artType - > id ! = ArtifactID : : ART_LOCK ) //ignore locks from assembled artifacts
2013-06-26 14:18:27 +03:00
moveFromSlotToAltar ( i - > first , nullptr , i - > second . artifact ) ;
2010-07-23 15:02:15 +03:00
}
2010-07-20 09:05:45 +03:00
2010-07-23 15:02:15 +03:00
SacrificeBackpack ( ) ;
}
2010-07-20 09:05:45 +03:00
redraw ( ) ;
}
void CAltarWindow : : selectionChanged ( bool side )
{
2011-12-14 00:23:17 +03:00
if ( mode ! = EMarketMode : : CREATURE_EXP )
2010-05-26 12:47:53 +03:00
return ;
2010-07-20 09:05:45 +03:00
CTradeableItem * & selected = side ? hLeft : hRight ;
CTradeableItem * & theOther = side ? hRight : hLeft ;
2010-05-26 12:47:53 +03:00
2013-06-26 14:18:27 +03:00
theOther = * std : : find_if ( items [ ! side ] . begin ( ) , items [ ! side ] . end ( ) , [ & ] ( const CTradeableItem * item )
{
return item - > serial = = selected - > serial ;
} ) ;
2010-07-23 15:02:15 +03:00
int stackCount = 0 ;
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : ARMY_SIZE ; i + + )
2013-02-16 17:03:47 +03:00
if ( hero - > getStackCount ( SlotID ( i ) ) > sacrificedUnits [ i ] )
2010-07-23 15:02:15 +03:00
stackCount + + ;
2013-02-16 17:03:47 +03:00
slider - > setAmount ( hero - > getStackCount ( SlotID ( hLeft - > serial ) ) - ( stackCount = = 1 ) ) ;
2010-07-20 09:05:45 +03:00
slider - > block ( ! slider - > amount ) ;
slider - > value = sacrificedUnits [ hLeft - > serial ] ;
max - > block ( ! slider - > amount ) ;
readyToTrade = true ;
redraw ( ) ;
}
void CAltarWindow : : mimicCres ( )
{
2011-12-22 16:05:19 +03:00
std : : vector < Rect > positions ;
2010-07-20 09:05:45 +03:00
getPositionsFor ( positions , false , CREATURE ) ;
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 1 ] )
2010-05-26 12:47:53 +03:00
{
2013-06-29 16:05:48 +03:00
auto hlp = new CTradeableItem ( positions [ t - > serial ] . topLeft ( ) , CREATURE_PLACEHOLDER , t - > id , false , t - > serial ) ;
2012-12-23 13:23:41 +03:00
hlp - > pos = positions [ t - > serial ] + this - > pos . topLeft ( ) ;
2010-07-20 09:05:45 +03:00
items [ 0 ] . push_back ( hlp ) ;
2010-05-26 12:47:53 +03:00
}
}
2011-12-22 16:05:19 +03:00
Point CAltarWindow : : selectionOffset ( bool Left ) const
2010-06-27 19:03:01 +03:00
{
2010-07-20 09:05:45 +03:00
if ( Left )
2011-12-22 16:05:19 +03:00
return Point ( 150 , 421 ) ;
2010-07-20 09:05:45 +03:00
else
2011-12-22 16:05:19 +03:00
return Point ( 396 , 421 ) ;
2010-07-20 09:05:45 +03:00
}
std : : string CAltarWindow : : selectionSubtitle ( bool Left ) const
{
if ( Left & & slider & & hLeft )
return boost : : lexical_cast < std : : string > ( slider - > value ) ;
else if ( ! Left & & hRight )
return hRight - > subtitle ;
else
return " " ;
}
void CAltarWindow : : artifactsChanged ( bool left )
{
}
void CAltarWindow : : garrisonChanged ( )
{
2011-12-14 00:23:17 +03:00
if ( mode ! = EMarketMode : : CREATURE_EXP )
2010-06-27 19:03:01 +03:00
return ;
2010-07-20 09:05:45 +03:00
std : : set < CTradeableItem * > empty ;
getEmptySlots ( empty ) ;
2010-06-27 19:03:01 +03:00
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : empty )
2010-06-27 19:03:01 +03:00
{
2013-06-26 14:18:27 +03:00
removeItem ( * std : : find_if ( items [ 0 ] . begin ( ) , items [ 0 ] . end ( ) , [ & ] ( const CTradeableItem * item )
{
return item - > serial = = t - > serial ;
} ) ) ;
2010-06-27 19:03:01 +03:00
}
2010-07-20 09:05:45 +03:00
initSubs ( true ) ;
getExpValues ( ) ;
}
void CAltarWindow : : getExpValues ( )
{
int dump ;
2013-06-29 16:05:48 +03:00
for ( CTradeableItem * t : items [ 1 ] )
2010-07-20 09:05:45 +03:00
if ( t - > id > = 0 )
2011-12-14 00:23:17 +03:00
market - > getOffer ( t - > id , 0 , dump , expPerUnit [ t - > serial ] , EMarketMode : : CREATURE_EXP ) ;
2010-07-20 09:05:45 +03:00
}
void CAltarWindow : : calcTotalExp ( )
{
int val = 0 ;
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : CREATURE_EXP )
2010-07-20 09:05:45 +03:00
{
2010-07-23 15:02:15 +03:00
for ( int i = 0 ; i < sacrificedUnits . size ( ) ; i + + )
{
val + = expPerUnit [ i ] * sacrificedUnits [ i ] ;
}
}
else
{
2013-06-29 16:05:48 +03:00
for ( const CArtifactInstance * art : arts - > artifactsOnAltar )
2010-07-23 15:02:15 +03:00
{
int dmp , valOfArt ;
2011-01-15 04:17:56 +02:00
market - > getOffer ( art - > artType - > id , 0 , dmp , valOfArt , mode ) ;
val + = valOfArt ; //WAS val += valOfArt * arts->artifactsOnAltar.count(*i);
2010-07-23 15:02:15 +03:00
}
2010-07-20 09:05:45 +03:00
}
2013-01-12 16:53:02 +03:00
val = hero - > calculateXp ( val ) ;
2013-08-29 16:46:27 +03:00
expOnAltar - > setText ( boost : : lexical_cast < std : : string > ( val ) ) ;
2010-07-20 09:05:45 +03:00
}
void CAltarWindow : : setExpToLevel ( )
{
2013-08-29 16:46:27 +03:00
expToLevel - > setText ( boost : : lexical_cast < std : : string > ( CGI - > heroh - > reqExp ( CGI - > heroh - > level ( hero - > exp ) + 1 ) - hero - > exp ) ) ;
2010-07-20 09:05:45 +03:00
}
void CAltarWindow : : blockTrade ( )
{
2013-06-26 14:18:27 +03:00
hLeft = hRight = nullptr ;
2010-07-20 09:05:45 +03:00
readyToTrade = false ;
if ( slider )
{
slider - > block ( true ) ;
max - > block ( true ) ;
}
deal - > block ( true ) ;
}
void CAltarWindow : : updateRight ( CTradeableItem * toUpdate )
{
int val = sacrificedUnits [ toUpdate - > serial ] ;
2012-12-20 16:57:29 +03:00
toUpdate - > setType ( val ? CREATURE : CREATURE_PLACEHOLDER ) ;
2010-07-20 09:05:45 +03:00
toUpdate - > subtitle = val ? boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 122 ] ) % boost : : lexical_cast < std : : string > ( val * expPerUnit [ toUpdate - > serial ] ) ) : " " ; //%s exp
}
2010-07-23 15:02:15 +03:00
int CAltarWindow : : firstFreeSlot ( )
{
int ret = - 1 ;
while ( items [ 0 ] [ + + ret ] - > id > = 0 & & ret + 1 < items [ 0 ] . size ( ) ) ;
return ret < items [ 0 ] . size ( ) ? ret : - 1 ;
}
2010-07-20 09:05:45 +03:00
void CAltarWindow : : SacrificeBackpack ( )
{
2011-01-15 04:17:56 +02:00
std : : multiset < const CArtifactInstance * > toOmmit = arts - > artifactsOnAltar ;
2010-07-20 09:05:45 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & elem : hero - > artifactsInBackpack )
2010-07-23 15:02:15 +03:00
{
2011-01-15 04:17:56 +02:00
2013-06-29 16:05:48 +03:00
if ( vstd : : contains ( toOmmit , elem . artifact ) )
2010-07-23 15:02:15 +03:00
{
2013-06-29 16:05:48 +03:00
toOmmit - = elem . artifact ;
2010-07-23 15:02:15 +03:00
continue ;
}
2013-06-29 16:05:48 +03:00
putOnAltar ( nullptr , elem . artifact ) ;
2010-07-23 15:02:15 +03:00
}
2011-01-15 04:17:56 +02:00
2010-07-23 15:02:15 +03:00
arts - > scrollBackpack ( 0 ) ;
calcTotalExp ( ) ;
}
void CAltarWindow : : artifactPicked ( )
{
redraw ( ) ;
}
void CAltarWindow : : showAll ( SDL_Surface * to )
{
CTradeWindow : : showAll ( to ) ;
2011-12-14 00:23:17 +03:00
if ( mode = = EMarketMode : : ARTIFACT_EXP & & arts & & arts - > commonInfo - > src . art )
2010-07-23 15:02:15 +03:00
{
2013-01-23 02:28:10 +03:00
artIcon - > setFrame ( arts - > commonInfo - > src . art - > artType - > iconIndex ) ;
2012-12-23 13:23:41 +03:00
artIcon - > showAll ( to ) ;
2010-07-23 15:02:15 +03:00
int dmp , val ;
2011-12-14 00:23:17 +03:00
market - > getOffer ( arts - > commonInfo - > src . art - > artType - > id , 0 , dmp , val , EMarketMode : : ARTIFACT_EXP ) ;
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( boost : : lexical_cast < std : : string > ( val ) , 304 , 498 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-07-23 15:02:15 +03:00
}
}
2011-01-15 04:17:56 +02:00
bool CAltarWindow : : putOnAltar ( CTradeableItem * altarSlot , const CArtifactInstance * art )
2010-07-23 15:02:15 +03:00
{
2011-01-15 04:17:56 +02:00
int artID = art - > artType - > id ;
2010-07-23 15:02:15 +03:00
if ( artID ! = 1 & & artID < 7 ) //special art
2011-01-15 04:17:56 +02:00
{
2013-04-09 17:31:36 +03:00
logGlobal - > warnStream ( ) < < " Cannot put special artifact on altar! " ;
2010-07-23 15:02:15 +03:00
return false ;
2011-01-15 04:17:56 +02:00
}
2010-07-23 15:02:15 +03:00
if ( ! altarSlot )
{
int slotIndex = firstFreeSlot ( ) ;
if ( slotIndex < 0 )
{
2013-04-09 17:31:36 +03:00
logGlobal - > warnStream ( ) < < " No free slots on altar! " ;
2010-07-23 15:02:15 +03:00
return false ;
}
altarSlot = items [ 0 ] [ slotIndex ] ;
}
int dmp , val ;
2011-12-14 00:23:17 +03:00
market - > getOffer ( artID , 0 , dmp , val , EMarketMode : : ARTIFACT_EXP ) ;
2010-07-23 15:02:15 +03:00
2011-01-15 04:17:56 +02:00
arts - > artifactsOnAltar . insert ( art ) ;
2011-04-23 00:51:10 +03:00
altarSlot - > setArtInstance ( art ) ;
2010-07-23 15:02:15 +03:00
altarSlot - > subtitle = boost : : lexical_cast < std : : string > ( val ) ;
deal - > block ( false ) ;
return true ;
}
2013-02-12 22:49:40 +03:00
void CAltarWindow : : moveFromSlotToAltar ( ArtifactPosition slotID , CTradeableItem * altarSlot , const CArtifactInstance * art )
2010-07-23 15:02:15 +03:00
{
2013-02-12 22:49:40 +03:00
auto freeBackpackSlot = ArtifactPosition ( hero - > artifactsInBackpack . size ( ) + GameConstants : : BACKPACK_START ) ;
2011-01-06 22:00:19 +02:00
if ( arts - > commonInfo - > src . art )
2010-07-23 15:02:15 +03:00
{
2011-01-28 04:11:58 +02:00
arts - > commonInfo - > dst . slotID = freeBackpackSlot ;
2011-01-06 22:00:19 +02:00
arts - > commonInfo - > dst . AOH = arts ;
2010-07-23 15:02:15 +03:00
}
2011-01-15 04:17:56 +02:00
if ( putOnAltar ( altarSlot , art ) )
2011-01-28 04:11:58 +02:00
{
2011-12-14 00:23:17 +03:00
if ( slotID < GameConstants : : BACKPACK_START )
2012-04-14 05:20:22 +03:00
LOCPLINT - > cb - > swapArtifacts ( ArtifactLocation ( hero , slotID ) , ArtifactLocation ( hero , freeBackpackSlot ) ) ;
2011-01-28 04:11:58 +02:00
else
{
arts - > commonInfo - > src . clear ( ) ;
arts - > commonInfo - > dst . clear ( ) ;
2013-06-26 14:18:27 +03:00
CCS - > curh - > dragAndDropCursor ( nullptr ) ;
2011-02-14 12:38:33 +02:00
arts - > unmarkSlots ( false ) ;
2011-01-28 04:11:58 +02:00
}
}
2010-06-27 19:03:01 +03:00
}
2012-01-12 18:23:00 +03:00
void CSystemOptionsWindow : : setMusicVolume ( int newVolume )
2009-05-19 21:23:04 +03:00
{
2012-01-12 18:23:00 +03:00
Settings volume = settings . write [ " general " ] [ " music " ] ;
volume - > Float ( ) = newVolume ;
}
2009-05-19 21:23:04 +03:00
2012-01-12 18:23:00 +03:00
void CSystemOptionsWindow : : setSoundVolume ( int newVolume )
{
Settings volume = settings . write [ " general " ] [ " sound " ] ;
volume - > Float ( ) = newVolume ;
}
void CSystemOptionsWindow : : setHeroMoveSpeed ( int newSpeed )
{
Settings speed = settings . write [ " adventure " ] [ " heroSpeed " ] ;
speed - > Float ( ) = newSpeed ;
}
void CSystemOptionsWindow : : setMapScrollingSpeed ( int newSpeed )
{
2012-01-19 17:33:22 +03:00
Settings speed = settings . write [ " adventure " ] [ " scrollSpeed " ] ;
2012-01-12 18:23:00 +03:00
speed - > Float ( ) = newSpeed ;
}
2012-06-15 20:08:19 +03:00
CSystemOptionsWindow : : CSystemOptionsWindow ( ) :
2012-09-30 13:35:17 +03:00
CWindowObject ( PLAYER_COLORED , " SysOpBck " ) ,
onFullscreenChanged ( settings . listen [ " video " ] [ " fullscreen " ] )
2012-01-12 18:23:00 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-11-11 15:23:31 +03:00
title = new CLabel ( 242 , 32 , FONT_BIG , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 568 ] ) ;
2012-01-12 18:23:00 +03:00
2013-10-27 16:05:01 +03:00
const JsonNode & texts = CGI - > generaltexth - > localizedTexts [ " systemOptions " ] ;
2012-01-12 18:23:00 +03:00
//left window section
2012-11-11 15:23:31 +03:00
leftGroup = new CLabelGroup ( FONT_MEDIUM , CENTER , Colors : : YELLOW ) ;
2012-01-12 18:23:00 +03:00
leftGroup - > add ( 122 , 64 , CGI - > generaltexth - > allTexts [ 569 ] ) ;
leftGroup - > add ( 122 , 130 , CGI - > generaltexth - > allTexts [ 570 ] ) ;
leftGroup - > add ( 122 , 196 , CGI - > generaltexth - > allTexts [ 571 ] ) ;
2013-10-27 16:05:01 +03:00
leftGroup - > add ( 122 , 262 , texts [ " resolutionButton " ] [ " label " ] . String ( ) ) ;
2012-01-12 18:23:00 +03:00
leftGroup - > add ( 122 , 347 , CGI - > generaltexth - > allTexts [ 394 ] ) ;
leftGroup - > add ( 122 , 412 , CGI - > generaltexth - > allTexts [ 395 ] ) ;
//right section
2012-11-11 15:23:31 +03:00
rightGroup = new CLabelGroup ( FONT_MEDIUM , TOPLEFT , Colors : : WHITE ) ;
2012-01-12 18:23:00 +03:00
rightGroup - > add ( 282 , 57 , CGI - > generaltexth - > allTexts [ 572 ] ) ;
rightGroup - > add ( 282 , 89 , CGI - > generaltexth - > allTexts [ 573 ] ) ;
rightGroup - > add ( 282 , 121 , CGI - > generaltexth - > allTexts [ 574 ] ) ;
2013-10-27 16:05:01 +03:00
rightGroup - > add ( 282 , 153 , CGI - > generaltexth - > allTexts [ 577 ] ) ;
rightGroup - > add ( 282 , 185 , texts [ " creatureWindowButton " ] [ " label " ] . String ( ) ) ;
rightGroup - > add ( 282 , 217 , texts [ " fullscreenButton " ] [ " label " ] . String ( ) ) ;
2009-05-19 21:23:04 +03:00
//setting up buttons
2012-04-09 05:53:50 +03:00
load = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 321 ] . first , CGI - > generaltexth - > zelp [ 321 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : bloadf , this ) , 246 , 298 , " SOLOAD.DEF " , SDLK_l ) ;
2012-04-09 05:53:50 +03:00
load - > swappedImages = true ;
load - > update ( ) ;
2009-12-11 06:52:51 +02:00
2012-01-12 18:23:00 +03:00
save = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 322 ] . first , CGI - > generaltexth - > zelp [ 322 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : bsavef , this ) , 357 , 298 , " SOSAVE.DEF " , SDLK_s ) ;
2011-02-20 11:24:53 +02:00
save - > swappedImages = true ;
save - > update ( ) ;
2009-12-11 06:52:51 +02:00
2012-07-19 21:52:44 +03:00
restart = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 323 ] . first , CGI - > generaltexth - > zelp [ 323 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : brestartf , this ) , 246 , 357 , " SORSTRT " , SDLK_r ) ;
2012-04-08 06:06:27 +03:00
restart - > swappedImages = true ;
restart - > update ( ) ;
2009-12-11 06:52:51 +02:00
2012-01-12 18:23:00 +03:00
mainMenu = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 320 ] . first , CGI - > generaltexth - > zelp [ 320 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : bmainmenuf , this ) , 357 , 357 , " SOMAIN.DEF " , SDLK_m ) ;
2011-02-20 11:24:53 +02:00
mainMenu - > swappedImages = true ;
mainMenu - > update ( ) ;
2009-12-11 06:52:51 +02:00
2012-01-12 18:23:00 +03:00
quitGame = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 324 ] . first , CGI - > generaltexth - > zelp [ 324 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : bquitf , this ) , 246 , 415 , " soquit.def " , SDLK_q ) ;
2011-02-20 11:24:53 +02:00
quitGame - > swappedImages = true ;
quitGame - > update ( ) ;
2012-01-12 18:23:00 +03:00
backToMap = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 325 ] . first , CGI - > generaltexth - > zelp [ 325 ] . second ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : breturnf , this ) , 357 , 415 , " soretrn.def " , SDLK_RETURN ) ;
2011-02-20 11:24:53 +02:00
backToMap - > swappedImages = true ;
backToMap - > update ( ) ;
2009-12-11 06:52:51 +02:00
backToMap - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2009-05-19 21:23:04 +03:00
heroMoveSpeed = new CHighlightableButtonsGroup ( 0 ) ;
2011-11-27 16:14:20 +03:00
heroMoveSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 349 ] . second ) , CGI - > generaltexth - > zelp [ 349 ] . second , " sysopb1.def " , 28 , 77 , 1 ) ;
heroMoveSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 350 ] . second ) , CGI - > generaltexth - > zelp [ 350 ] . second , " sysopb2.def " , 76 , 77 , 2 ) ;
heroMoveSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 351 ] . second ) , CGI - > generaltexth - > zelp [ 351 ] . second , " sysopb3.def " , 124 , 77 , 4 ) ;
heroMoveSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 352 ] . second ) , CGI - > generaltexth - > zelp [ 352 ] . second , " sysopb4.def " , 172 , 77 , 8 ) ;
2012-01-12 18:23:00 +03:00
heroMoveSpeed - > select ( settings [ " adventure " ] [ " heroSpeed " ] . Float ( ) , 1 ) ;
2013-07-02 18:23:32 +03:00
heroMoveSpeed - > onChange = boost : : bind ( & CSystemOptionsWindow : : setHeroMoveSpeed , this , _1 ) ;
2009-05-19 21:23:04 +03:00
mapScrollSpeed = new CHighlightableButtonsGroup ( 0 ) ;
2011-11-27 16:14:20 +03:00
mapScrollSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 357 ] . second ) , CGI - > generaltexth - > zelp [ 357 ] . second , " sysopb9.def " , 28 , 210 , 1 ) ;
mapScrollSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 358 ] . second ) , CGI - > generaltexth - > zelp [ 358 ] . second , " sysob10.def " , 92 , 210 , 2 ) ;
mapScrollSpeed - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 359 ] . second ) , CGI - > generaltexth - > zelp [ 359 ] . second , " sysob11.def " , 156 , 210 , 4 ) ;
2012-01-12 18:23:00 +03:00
mapScrollSpeed - > select ( settings [ " adventure " ] [ " scrollSpeed " ] . Float ( ) , 1 ) ;
2013-07-02 18:23:32 +03:00
mapScrollSpeed - > onChange = boost : : bind ( & CSystemOptionsWindow : : setMapScrollingSpeed , this , _1 ) ;
2009-05-19 21:23:04 +03:00
musicVolume = new CHighlightableButtonsGroup ( 0 , true ) ;
for ( int i = 0 ; i < 10 ; + + i )
2011-11-27 16:14:20 +03:00
musicVolume - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 326 + i ] . second ) , CGI - > generaltexth - > zelp [ 326 + i ] . second , " syslb.def " , 29 + 19 * i , 359 , i * 11 ) ;
2012-01-12 18:23:00 +03:00
2010-12-19 16:39:56 +02:00
musicVolume - > select ( CCS - > musich - > getVolume ( ) , 1 ) ;
2013-07-02 18:23:32 +03:00
musicVolume - > onChange = boost : : bind ( & CSystemOptionsWindow : : setMusicVolume , this , _1 ) ;
2009-05-19 21:23:04 +03:00
effectsVolume = new CHighlightableButtonsGroup ( 0 , true ) ;
for ( int i = 0 ; i < 10 ; + + i )
2011-11-27 16:14:20 +03:00
effectsVolume - > addButton ( boost : : assign : : map_list_of ( 0 , CGI - > generaltexth - > zelp [ 336 + i ] . second ) , CGI - > generaltexth - > zelp [ 336 + i ] . second , " syslb.def " , 29 + 19 * i , 425 , i * 11 ) ;
2012-01-12 18:23:00 +03:00
2010-12-19 16:39:56 +02:00
effectsVolume - > select ( CCS - > soundh - > getVolume ( ) , 1 ) ;
2013-07-02 18:23:32 +03:00
effectsVolume - > onChange = boost : : bind ( & CSystemOptionsWindow : : setSoundVolume , this , _1 ) ;
2012-01-12 18:23:00 +03:00
showReminder = new CHighlightableButton (
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : toggleReminder , this , true ) , boost : : bind ( & CSystemOptionsWindow : : toggleReminder , this , false ) ,
2013-06-26 14:18:27 +03:00
std : : map < int , std : : string > ( ) , CGI - > generaltexth - > zelp [ 361 ] . second , false , " sysopchk.def " , nullptr , 246 , 87 , false ) ;
2012-01-12 18:23:00 +03:00
2013-06-23 10:54:33 +03:00
quickCombat = new CHighlightableButton (
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : toggleQuickCombat , this , true ) , boost : : bind ( & CSystemOptionsWindow : : toggleQuickCombat , this , false ) ,
2013-06-26 14:18:27 +03:00
std : : map < int , std : : string > ( ) , CGI - > generaltexth - > zelp [ 362 ] . second , false , " sysopchk.def " , nullptr , 246 , 87 + 32 , false ) ;
2013-06-23 10:54:33 +03:00
2013-10-27 16:05:01 +03:00
spellbookAnim = new CHighlightableButton (
boost : : bind ( & CSystemOptionsWindow : : toggleSpellbookAnim , this , true ) , boost : : bind ( & CSystemOptionsWindow : : toggleSpellbookAnim , this , false ) ,
std : : map < int , std : : string > ( ) , CGI - > generaltexth - > zelp [ 364 ] . second , false , " sysopchk.def " , nullptr , 246 , 87 + 64 , false ) ;
2012-01-12 18:23:00 +03:00
newCreatureWin = new CHighlightableButton (
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : toggleCreatureWin , this , true ) , boost : : bind ( & CSystemOptionsWindow : : toggleCreatureWin , this , false ) ,
2013-10-27 16:05:01 +03:00
std : : map < int , std : : string > ( ) , texts [ " creatureWindowButton " ] [ " help " ] . String ( ) , false , " sysopchk.def " , nullptr , 246 , 183 , false ) ;
2012-01-12 18:23:00 +03:00
fullscreen = new CHighlightableButton (
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : toggleFullscreen , this , true ) , boost : : bind ( & CSystemOptionsWindow : : toggleFullscreen , this , false ) ,
2013-10-27 16:05:01 +03:00
std : : map < int , std : : string > ( ) , texts [ " fullscreenButton " ] [ " help " ] . String ( ) , false , " sysopchk.def " , nullptr , 246 , 215 , false ) ;
2012-01-12 18:23:00 +03:00
showReminder - > select ( settings [ " adventure " ] [ " heroReminder " ] . Bool ( ) ) ;
2013-06-23 10:54:33 +03:00
quickCombat - > select ( settings [ " adventure " ] [ " quickCombat " ] . Bool ( ) ) ;
2013-10-27 16:05:01 +03:00
spellbookAnim - > select ( settings [ " video " ] [ " spellbookAnimation " ] . Bool ( ) ) ;
2012-01-12 18:23:00 +03:00
newCreatureWin - > select ( settings [ " general " ] [ " classicCreatureWindow " ] . Bool ( ) ) ;
fullscreen - > select ( settings [ " video " ] [ " fullscreen " ] . Bool ( ) ) ;
2012-09-30 13:35:17 +03:00
onFullscreenChanged ( [ & ] ( const JsonNode & newState ) { fullscreen - > select ( newState . Bool ( ) ) ; } ) ;
2013-10-27 16:05:01 +03:00
gameResButton = new CAdventureMapButton ( " " , texts [ " resolutionButton " ] [ " help " ] . String ( ) ,
boost : : bind ( & CSystemOptionsWindow : : selectGameRes , this ) ,
28 , 275 , " SYSOB12 " , SDLK_g ) ;
2012-09-29 18:10:56 +03:00
std : : string resText ;
resText + = boost : : lexical_cast < std : : string > ( settings [ " video " ] [ " screenRes " ] [ " width " ] . Float ( ) ) ;
resText + = " x " ;
resText + = boost : : lexical_cast < std : : string > ( settings [ " video " ] [ " screenRes " ] [ " height " ] . Float ( ) ) ;
2012-11-11 15:23:31 +03:00
gameResLabel = new CLabel ( 170 , 292 , FONT_MEDIUM , CENTER , Colors : : YELLOW , resText ) ;
2012-09-29 18:10:56 +03:00
2009-05-19 21:23:04 +03:00
}
2012-05-18 20:35:46 +03:00
void CSystemOptionsWindow : : selectGameRes ( )
2009-05-19 21:23:04 +03:00
{
2012-01-12 18:23:00 +03:00
std : : vector < std : : string > items ;
2013-10-27 16:05:01 +03:00
const JsonNode & texts = CGI - > generaltexth - > localizedTexts [ " systemOptions " ] [ " resolutionMenu " ] ;
2012-01-12 18:23:00 +03:00
2013-06-29 16:05:48 +03:00
for ( config : : CConfigHandler : : GuiOptionsMap : : value_type & value : conf . guiOptions )
2012-01-12 18:23:00 +03:00
{
std : : string resX = boost : : lexical_cast < std : : string > ( value . first . first ) ;
std : : string resY = boost : : lexical_cast < std : : string > ( value . first . second ) ;
items . push_back ( resX + ' x ' + resY ) ;
}
2013-10-27 16:05:01 +03:00
GH . pushInt ( new CObjectListWindow ( items , nullptr , texts [ " label " ] . String ( ) , texts [ " help " ] . String ( ) ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CSystemOptionsWindow : : setGameRes , this , _1 ) ) ) ;
2012-01-12 18:23:00 +03:00
}
2012-05-18 20:35:46 +03:00
void CSystemOptionsWindow : : setGameRes ( int index )
2012-01-12 18:23:00 +03:00
{
2012-09-29 18:10:56 +03:00
auto iter = conf . guiOptions . begin ( ) ;
std : : advance ( iter , index ) ;
2012-01-12 18:23:00 +03:00
2012-06-22 14:40:16 +03:00
//do not set resolution to illegal one (0x0)
assert ( iter ! = conf . guiOptions . end ( ) & & iter - > first . first > 0 & & iter - > first . second > 0 ) ;
2012-05-18 20:35:46 +03:00
Settings gameRes = settings . write [ " video " ] [ " screenRes " ] ;
2012-01-12 18:23:00 +03:00
gameRes [ " width " ] . Float ( ) = iter - > first . first ;
gameRes [ " height " ] . Float ( ) = iter - > first . second ;
2012-09-29 18:10:56 +03:00
std : : string resText ;
resText + = boost : : lexical_cast < std : : string > ( iter - > first . first ) ;
resText + = " x " ;
resText + = boost : : lexical_cast < std : : string > ( iter - > first . second ) ;
2013-08-29 16:46:27 +03:00
gameResLabel - > setText ( resText ) ;
2009-05-19 21:23:04 +03:00
}
2012-01-12 18:23:00 +03:00
void CSystemOptionsWindow : : toggleReminder ( bool on )
{
Settings heroReminder = settings . write [ " adventure " ] [ " heroReminder " ] ;
heroReminder - > Bool ( ) = on ;
}
2013-06-23 10:54:33 +03:00
void CSystemOptionsWindow : : toggleQuickCombat ( bool on )
{
Settings quickCombat = settings . write [ " adventure " ] [ " quickCombat " ] ;
quickCombat - > Bool ( ) = on ;
}
2013-10-27 16:05:01 +03:00
void CSystemOptionsWindow : : toggleSpellbookAnim ( bool on )
{
Settings quickCombat = settings . write [ " video " ] [ " spellbookAnimation " ] ;
quickCombat - > Bool ( ) = on ;
}
2012-01-12 18:23:00 +03:00
void CSystemOptionsWindow : : toggleCreatureWin ( bool on )
{
Settings classicCreatureWindow = settings . write [ " general " ] [ " classicCreatureWindow " ] ;
classicCreatureWindow - > Bool ( ) = on ;
}
void CSystemOptionsWindow : : toggleFullscreen ( bool on )
{
Settings fullscreen = settings . write [ " video " ] [ " fullscreen " ] ;
fullscreen - > Bool ( ) = on ;
}
2009-05-19 21:23:04 +03:00
void CSystemOptionsWindow : : bquitf ( )
{
2012-09-11 17:25:19 +03:00
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 578 ] , [ this ] { closeAndPushEvent ( SDL_QUIT ) ; } , 0 ) ;
2009-05-19 21:23:04 +03:00
}
void CSystemOptionsWindow : : breturnf ( )
{
2009-08-07 01:36:51 +03:00
GH . popIntTotally ( this ) ;
2009-05-19 21:23:04 +03:00
}
2009-11-01 03:15:16 +02:00
void CSystemOptionsWindow : : bmainmenuf ( )
{
2012-09-11 17:25:19 +03:00
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 578 ] , [ this ] { closeAndPushEvent ( SDL_USEREVENT , RETURN_TO_MAIN_MENU ) ; } , 0 ) ;
2012-04-09 05:53:50 +03:00
}
void CSystemOptionsWindow : : bloadf ( )
{
GH . popIntTotally ( this ) ;
LOCPLINT - > proposeLoadingGame ( ) ;
2009-11-01 03:15:16 +02:00
}
2009-05-19 21:23:04 +03:00
void CSystemOptionsWindow : : bsavef ( )
{
2009-09-07 05:29:44 +03:00
GH . popIntTotally ( this ) ;
2010-05-27 00:59:58 +03:00
GH . pushInt ( new CSavingScreen ( CPlayerInterface : : howManyPeople > 1 ) ) ;
2009-05-19 21:23:04 +03:00
}
2012-04-08 06:06:27 +03:00
void CSystemOptionsWindow : : brestartf ( )
{
2012-09-11 17:25:19 +03:00
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 67 ] , [ this ] { closeAndPushEvent ( SDL_USEREVENT , RESTART_GAME ) ; } , 0 ) ;
}
void CSystemOptionsWindow : : closeAndPushEvent ( int eventType , int code /*= 0*/ )
{
GH . popIntTotally ( this ) ;
GH . pushSDLEvent ( eventType , code ) ;
2012-04-08 06:06:27 +03:00
}
2012-06-15 20:08:19 +03:00
CTavernWindow : : CTavernWindow ( const CGObjectInstance * TavernObj ) :
CWindowObject ( PLAYER_COLORED , " TPTAVERN " ) ,
tavernObj ( TavernObj )
2009-05-19 21:23:04 +03:00
{
2010-07-09 02:03:27 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
std : : vector < const CGHeroInstance * > h = LOCPLINT - > cb - > getAvailableHeroes ( TavernObj ) ;
2014-03-01 16:42:23 +03:00
if ( h . size ( ) < 2 )
h . resize ( 2 , nullptr ) ;
2010-07-09 02:03:27 +03:00
h1 = new HeroPortrait ( selected , 0 , 72 , 299 , h [ 0 ] ) ;
h2 = new HeroPortrait ( selected , 1 , 162 , 299 , h [ 1 ] ) ;
2013-03-14 23:44:00 +03:00
selected = 0 ;
if ( ! h [ 0 ] )
selected = 1 ;
if ( ! h [ 0 ] & & ! h [ 1 ] )
2009-05-19 21:23:04 +03:00
selected = - 1 ;
2009-05-30 19:17:44 +03:00
oldSelected = - 1 ;
2010-02-02 18:24:53 +02:00
2012-11-11 15:23:31 +03:00
new CLabel ( 200 , 35 , FONT_BIG , CENTER , Colors : : YELLOW , CGI - > generaltexth - > jktexts [ 37 ] ) ;
new CLabel ( 320 , 328 , FONT_SMALL , CENTER , Colors : : WHITE , " 2500 " ) ;
new CTextBox ( LOCPLINT - > cb - > getTavernGossip ( tavernObj ) , Rect ( 32 , 190 , 330 , 68 ) , 0 , FONT_SMALL , CENTER , Colors : : WHITE ) ;
2010-07-09 02:03:27 +03:00
2012-06-16 13:41:14 +03:00
new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2013-07-02 18:23:32 +03:00
cancel = new CAdventureMapButton ( CGI - > generaltexth - > tavernInfo [ 7 ] , " " , boost : : bind ( & CTavernWindow : : close , this ) , 310 , 428 , " ICANCEL.DEF " , SDLK_ESCAPE ) ;
recruit = new CAdventureMapButton ( " " , " " , boost : : bind ( & CTavernWindow : : recruitb , this ) , 272 , 355 , " TPTAV01.DEF " , SDLK_RETURN ) ;
thiefGuild = new CAdventureMapButton ( CGI - > generaltexth - > tavernInfo [ 5 ] , " " , boost : : bind ( & CTavernWindow : : thievesguildb , this ) , 22 , 428 , " TPTAV02.DEF " , SDLK_t ) ;
2009-05-19 21:23:04 +03:00
2013-02-09 15:56:35 +03:00
if ( LOCPLINT - > cb - > getResourceAmount ( Res : : GOLD ) < 2500 ) //not enough gold
2009-05-19 21:23:04 +03:00
{
recruit - > hoverTexts [ 0 ] = CGI - > generaltexth - > tavernInfo [ 0 ] ; //Cannot afford a Hero
2013-03-14 23:44:00 +03:00
recruit - > block ( true ) ;
2009-05-19 21:23:04 +03:00
}
2014-04-27 09:43:42 +03:00
else if ( LOCPLINT - > castleInt & & LOCPLINT - > cb - > howManyHeroes ( true ) > = VLC - > modh - > settings . MAX_HEROES_AVAILABLE_PER_PLAYER )
2009-05-19 21:23:04 +03:00
{
recruit - > hoverTexts [ 0 ] = CGI - > generaltexth - > tavernInfo [ 1 ] ; //Cannot recruit. You already have %d Heroes.
2014-04-27 09:43:42 +03:00
boost : : algorithm : : replace_first ( recruit - > hoverTexts [ 0 ] , " %d " , boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > howManyHeroes ( true ) ) ) ;
recruit - > block ( true ) ;
}
else if ( ( ! LOCPLINT - > castleInt ) & & LOCPLINT - > cb - > howManyHeroes ( false ) > = VLC - > modh - > settings . MAX_HEROES_ON_MAP_PER_PLAYER )
{
recruit - > hoverTexts [ 0 ] = CGI - > generaltexth - > tavernInfo [ 1 ] ; //Cannot recruit. You already have %d Heroes.
boost : : algorithm : : replace_first ( recruit - > hoverTexts [ 0 ] , " %d " , boost : : lexical_cast < std : : string > ( LOCPLINT - > cb - > howManyHeroes ( false ) ) ) ;
2013-03-14 23:44:00 +03:00
recruit - > block ( true ) ;
2009-05-19 21:23:04 +03:00
}
else if ( LOCPLINT - > castleInt & & LOCPLINT - > castleInt - > town - > visitingHero )
{
recruit - > hoverTexts [ 0 ] = CGI - > generaltexth - > tavernInfo [ 2 ] ; //Cannot recruit. You already have a Hero in this town.
2013-03-14 23:44:00 +03:00
recruit - > block ( true ) ;
2009-05-19 21:23:04 +03:00
}
else
{
2013-03-14 23:44:00 +03:00
if ( selected = = - 1 )
recruit - > block ( true ) ;
2009-05-19 21:23:04 +03:00
}
2014-04-29 12:06:55 +03:00
if ( LOCPLINT - > castleInt )
2014-04-25 00:06:14 +03:00
CCS - > videoh - > open ( LOCPLINT - > castleInt - > town - > town - > clientInfo . tavernVideo ) ;
else
CCS - > videoh - > open ( " TAVERN.BIK " ) ;
2009-05-19 21:23:04 +03:00
}
void CTavernWindow : : recruitb ( )
{
2010-07-09 02:03:27 +03:00
const CGHeroInstance * toBuy = ( selected ? h2 : h1 ) - > h ;
const CGObjectInstance * obj = tavernObj ;
2009-05-19 21:23:04 +03:00
close ( ) ;
2010-07-09 02:03:27 +03:00
LOCPLINT - > cb - > recruitHero ( obj , toBuy ) ;
2009-05-19 21:23:04 +03:00
}
2010-01-31 20:41:22 +02:00
void CTavernWindow : : thievesguildb ( )
{
2010-07-09 02:03:27 +03:00
GH . pushInt ( new CThievesGuildWindow ( tavernObj ) ) ;
2010-01-31 20:41:22 +02:00
}
2009-05-19 21:23:04 +03:00
CTavernWindow : : ~ CTavernWindow ( )
{
2010-12-19 16:39:56 +02:00
CCS - > videoh - > close ( ) ;
2009-05-19 21:23:04 +03:00
}
void CTavernWindow : : show ( SDL_Surface * to )
{
2012-06-15 20:08:19 +03:00
CWindowObject : : show ( to ) ;
2009-05-19 21:23:04 +03:00
2010-12-19 16:39:56 +02:00
CCS - > videoh - > update ( pos . x + 70 , pos . y + 56 , to , true , false ) ;
2009-05-19 21:23:04 +03:00
if ( selected > = 0 )
{
2010-07-09 02:03:27 +03:00
HeroPortrait * sel = selected ? h2 : h1 ;
2009-05-30 19:17:44 +03:00
2012-01-12 18:23:00 +03:00
if ( selected ! = oldSelected & & ! recruit - > isBlocked ( ) )
2009-06-10 23:48:55 +03:00
{
// Selected hero just changed. Update RECRUIT button hover text if recruitment is allowed.
2009-05-30 19:17:44 +03:00
oldSelected = selected ;
recruit - > hoverTexts [ 0 ] = CGI - > generaltexth - > tavernInfo [ 3 ] ; //Recruit %s the %s
boost : : algorithm : : replace_first ( recruit - > hoverTexts [ 0 ] , " %s " , sel - > h - > name ) ;
boost : : algorithm : : replace_first ( recruit - > hoverTexts [ 0 ] , " %s " , sel - > h - > type - > heroClass - > name ) ;
}
2009-05-30 18:58:28 +03:00
2014-02-27 00:20:36 +03:00
printAtMiddleWBLoc ( sel - > description , 146 , 395 , FONT_SMALL , 200 , Colors : : WHITE , to ) ;
2009-05-19 21:23:04 +03:00
CSDL_Ext : : drawBorder ( to , sel - > pos . x - 2 , sel - > pos . y - 2 , sel - > pos . w + 4 , sel - > pos . h + 4 , int3 ( 247 , 223 , 123 ) ) ;
}
}
2009-08-11 19:05:33 +03:00
void CTavernWindow : : HeroPortrait : : clickLeft ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
2010-07-09 02:03:27 +03:00
if ( previousState & & ! down & & h )
2011-12-14 00:23:17 +03:00
* _sel = _id ;
2009-05-19 21:23:04 +03:00
}
2009-11-28 21:55:40 +02:00
2009-08-11 19:05:33 +03:00
void CTavernWindow : : HeroPortrait : : clickRight ( tribool down , bool previousState )
2009-05-19 21:23:04 +03:00
{
2010-07-09 02:03:27 +03:00
if ( down & & h )
2009-05-19 21:23:04 +03:00
{
2011-01-06 22:00:19 +02:00
GH . pushInt ( new CRClickPopupInt ( new CHeroWindow ( h ) , true ) ) ;
2009-05-19 21:23:04 +03:00
}
}
2009-11-28 21:55:40 +02:00
2009-05-19 21:23:04 +03:00
CTavernWindow : : HeroPortrait : : HeroPortrait ( int & sel , int id , int x , int y , const CGHeroInstance * H )
2011-12-31 13:03:29 +03:00
: h ( H ) , _sel ( & sel ) , _id ( id )
2009-05-19 21:23:04 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
2012-06-17 01:40:28 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2009-05-19 21:23:04 +03:00
h = H ;
2012-06-15 20:08:19 +03:00
pos . x + = x ;
pos . y + = y ;
2009-05-19 21:23:04 +03:00
pos . w = 58 ;
pos . h = 64 ;
2010-07-09 02:03:27 +03:00
2009-05-19 21:23:04 +03:00
if ( H )
{
hoverName = CGI - > generaltexth - > tavernInfo [ 4 ] ;
boost : : algorithm : : replace_first ( hoverName , " %s " , H - > name ) ;
2009-07-16 02:58:47 +03:00
2011-01-18 20:56:14 +02:00
int artifs = h - > artifactsWorn . size ( ) + h - > artifactsInBackpack . size ( ) ;
2009-07-16 02:58:47 +03:00
for ( int i = 13 ; i < = 17 ; i + + ) //war machines and spellbook don't count
2013-02-12 22:49:40 +03:00
if ( vstd : : contains ( h - > artifactsWorn , ArtifactPosition ( i ) ) )
2009-07-16 02:58:47 +03:00
artifs - - ;
2014-02-27 00:20:36 +03:00
description = CGI - > generaltexth - > allTexts [ 215 ] ;
boost : : algorithm : : replace_first ( description , " %s " , h - > name ) ;
boost : : algorithm : : replace_first ( description , " %d " , boost : : lexical_cast < std : : string > ( h - > level ) ) ;
boost : : algorithm : : replace_first ( description , " %s " , h - > type - > heroClass - > name ) ;
boost : : algorithm : : replace_first ( description , " %d " , boost : : lexical_cast < std : : string > ( artifs ) ) ;
2012-01-12 18:23:00 +03:00
2012-12-16 16:47:53 +03:00
new CAnimImage ( " portraitsLarge " , h - > portrait ) ;
2012-06-17 01:40:28 +03:00
}
2009-05-19 21:23:04 +03:00
}
void CTavernWindow : : HeroPortrait : : hover ( bool on )
{
2009-08-11 19:05:33 +03:00
//Hoverable::hover(on);
2009-05-19 21:23:04 +03:00
if ( on )
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( hoverName ) ;
2009-05-19 21:23:04 +03:00
else
2010-02-15 08:54:57 +02:00
GH . statusbar - > clear ( ) ;
2009-05-19 21:23:04 +03:00
}
void CInGameConsole : : show ( SDL_Surface * to )
{
int number = 0 ;
std : : vector < std : : list < std : : pair < std : : string , int > > : : iterator > toDel ;
2012-07-19 21:52:44 +03:00
boost : : unique_lock < boost : : mutex > lock ( texts_mx ) ;
2013-06-29 16:05:48 +03:00
for ( auto it = texts . begin ( ) ; it ! = texts . end ( ) ; + + it , + + number )
2009-05-19 21:23:04 +03:00
{
2011-12-22 16:05:19 +03:00
Point leftBottomCorner ( 0 , screen - > h ) ;
2009-05-19 21:23:04 +03:00
if ( LOCPLINT - > battleInt )
{
leftBottomCorner = LOCPLINT - > battleInt - > pos . bottomLeft ( ) ;
}
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_MEDIUM ] - > renderTextLeft ( to , it - > first , Colors : : GREEN ,
Point ( leftBottomCorner . x + 50 , leftBottomCorner . y - texts . size ( ) * 20 - 80 + number * 20 ) ) ;
2009-05-19 21:23:04 +03:00
if ( SDL_GetTicks ( ) - it - > second > defaultTimeout )
{
toDel . push_back ( it ) ;
}
}
2013-06-29 16:05:48 +03:00
for ( auto & elem : toDel )
2009-05-19 21:23:04 +03:00
{
2013-06-29 16:05:48 +03:00
texts . erase ( elem ) ;
2009-05-19 21:23:04 +03:00
}
}
void CInGameConsole : : print ( const std : : string & txt )
{
2012-07-19 21:52:44 +03:00
boost : : unique_lock < boost : : mutex > lock ( texts_mx ) ;
2009-10-18 17:39:53 +03:00
int lineLen = conf . go ( ) - > ac . outputLineLength ;
2009-06-09 06:53:29 +03:00
2009-10-18 17:39:53 +03:00
if ( txt . size ( ) < lineLen )
2009-05-19 21:23:04 +03:00
{
2009-10-18 17:39:53 +03:00
texts . push_back ( std : : make_pair ( txt , SDL_GetTicks ( ) ) ) ;
if ( texts . size ( ) > maxDisplayedTexts )
{
texts . pop_front ( ) ;
}
}
else
{
2009-12-02 00:14:25 +02:00
assert ( lineLen ) ;
2009-10-18 17:39:53 +03:00
for ( int g = 0 ; g < txt . size ( ) / lineLen + 1 ; + + g )
{
std : : string part = txt . substr ( g * lineLen , lineLen ) ;
if ( part . size ( ) = = 0 )
break ;
texts . push_back ( std : : make_pair ( part , SDL_GetTicks ( ) ) ) ;
if ( texts . size ( ) > maxDisplayedTexts )
{
texts . pop_front ( ) ;
}
}
2009-05-19 21:23:04 +03:00
}
}
void CInGameConsole : : keyPressed ( const SDL_KeyboardEvent & key )
{
if ( key . type ! = SDL_KEYDOWN ) return ;
if ( ! captureAllKeys & & key . keysym . sym ! = SDLK_TAB ) return ; //because user is not entering any text
switch ( key . keysym . sym )
{
case SDLK_TAB :
2009-08-27 11:04:32 +03:00
case SDLK_ESCAPE :
2009-05-19 21:23:04 +03:00
{
if ( captureAllKeys )
{
captureAllKeys = false ;
endEnteringText ( false ) ;
}
2009-08-27 11:04:32 +03:00
else if ( SDLK_TAB )
2009-05-19 21:23:04 +03:00
{
captureAllKeys = true ;
startEnteringText ( ) ;
}
break ;
}
case SDLK_RETURN : //enter key
{
if ( enteredText . size ( ) > 0 & & captureAllKeys )
{
captureAllKeys = false ;
endEnteringText ( true ) ;
}
break ;
}
case SDLK_BACKSPACE :
{
if ( enteredText . size ( ) > 1 )
{
enteredText . resize ( enteredText . size ( ) - 1 ) ;
enteredText [ enteredText . size ( ) - 1 ] = ' _ ' ;
refreshEnteredText ( ) ;
}
break ;
}
case SDLK_UP : //up arrow
{
2009-08-07 12:45:21 +03:00
if ( previouslyEntered . size ( ) = = 0 )
break ;
2009-05-19 21:23:04 +03:00
if ( prevEntDisp = = - 1 )
{
prevEntDisp = previouslyEntered . size ( ) - 1 ;
enteredText = previouslyEntered [ prevEntDisp ] + " _ " ;
refreshEnteredText ( ) ;
}
else if ( prevEntDisp > 0 )
{
- - prevEntDisp ;
enteredText = previouslyEntered [ prevEntDisp ] + " _ " ;
refreshEnteredText ( ) ;
}
break ;
}
case SDLK_DOWN : //down arrow
{
if ( prevEntDisp ! = - 1 & & prevEntDisp + 1 < previouslyEntered . size ( ) )
{
+ + prevEntDisp ;
enteredText = previouslyEntered [ prevEntDisp ] + " _ " ;
refreshEnteredText ( ) ;
}
else if ( prevEntDisp + 1 = = previouslyEntered . size ( ) ) //useful feature
{
prevEntDisp = - 1 ;
enteredText = " _ " ;
refreshEnteredText ( ) ;
}
break ;
}
default :
{
2009-10-18 17:39:53 +03:00
if ( enteredText . size ( ) > 0 & & enteredText . size ( ) < conf . go ( ) - > ac . inputLineLength )
2009-05-19 21:23:04 +03:00
{
if ( key . keysym . unicode < 0x80 & & key . keysym . unicode > 0 )
{
enteredText [ enteredText . size ( ) - 1 ] = ( char ) key . keysym . unicode ;
enteredText + = " _ " ;
refreshEnteredText ( ) ;
}
}
break ;
}
}
}
void CInGameConsole : : startEnteringText ( )
{
enteredText = " _ " ;
2010-02-20 15:24:38 +02:00
if ( GH . topInt ( ) = = adventureInt )
2009-05-19 21:23:04 +03:00
{
2013-08-29 16:46:27 +03:00
GH . statusbar - > alignment = TOPLEFT ;
GH . statusbar - > setText ( enteredText ) ;
2012-12-22 23:05:08 +03:00
2013-08-29 16:46:27 +03:00
//Prevent changes to the text from mouse interaction with the adventure map
GH . statusbar - > lock ( true ) ;
2009-05-19 21:23:04 +03:00
}
else if ( LOCPLINT - > battleInt )
{
LOCPLINT - > battleInt - > console - > ingcAlter = enteredText ;
}
}
void CInGameConsole : : endEnteringText ( bool printEnteredText )
{
prevEntDisp = - 1 ;
if ( printEnteredText )
{
std : : string txt = enteredText . substr ( 0 , enteredText . size ( ) - 1 ) ;
LOCPLINT - > cb - > sendMessage ( txt ) ;
previouslyEntered . push_back ( txt ) ;
2012-04-08 05:14:20 +03:00
//print(txt);
2009-05-19 21:23:04 +03:00
}
enteredText = " " ;
2010-02-20 15:24:38 +02:00
if ( GH . topInt ( ) = = adventureInt )
2009-05-19 21:23:04 +03:00
{
2013-08-29 16:46:27 +03:00
GH . statusbar - > alignment = CENTER ;
GH . statusbar - > lock ( false ) ;
GH . statusbar - > clear ( ) ;
2009-05-19 21:23:04 +03:00
}
else if ( LOCPLINT - > battleInt )
{
LOCPLINT - > battleInt - > console - > ingcAlter = " " ;
}
}
void CInGameConsole : : refreshEnteredText ( )
{
2010-02-20 15:24:38 +02:00
if ( GH . topInt ( ) = = adventureInt )
2009-05-19 21:23:04 +03:00
{
2013-08-29 16:46:27 +03:00
GH . statusbar - > lock ( false ) ;
GH . statusbar - > clear ( ) ;
GH . statusbar - > setText ( enteredText ) ;
GH . statusbar - > lock ( true ) ;
2009-05-19 21:23:04 +03:00
}
else if ( LOCPLINT - > battleInt )
{
LOCPLINT - > battleInt - > console - > ingcAlter = enteredText ;
}
}
CInGameConsole : : CInGameConsole ( ) : prevEntDisp ( - 1 ) , defaultTimeout ( 10000 ) , maxDisplayedTexts ( 10 )
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( KEYBOARD ) ;
2009-05-19 21:23:04 +03:00
}
2012-06-02 18:16:54 +03:00
CGarrisonWindow : : CGarrisonWindow ( const CArmedInstance * up , const CGHeroInstance * down , bool removableUnits ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " GARRISON " )
2009-05-19 21:23:04 +03:00
{
2011-02-05 15:39:10 +02:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-02 18:16:54 +03:00
garr = new CGarrisonInt ( 92 , 127 , 4 , Point ( 0 , 96 ) , background - > bg , Point ( 93 , 127 ) , up , down , removableUnits ) ;
2011-02-05 15:39:10 +02:00
{
2013-07-02 18:23:32 +03:00
CAdventureMapButton * split = new CAdventureMapButton ( CGI - > generaltexth - > tcommands [ 3 ] , " " , boost : : bind ( & CGarrisonInt : : splitClick , garr ) , 88 , 314 , " IDV6432.DEF " ) ;
2011-02-05 15:39:10 +02:00
removeChild ( split ) ;
garr - > addSplitBtn ( split ) ;
}
2013-07-02 18:23:32 +03:00
quit = new CAdventureMapButton ( CGI - > generaltexth - > tcommands [ 8 ] , " " , boost : : bind ( & CGarrisonWindow : : close , this ) , 399 , 314 , " IOK6432.DEF " , SDLK_RETURN ) ;
2011-07-18 18:21:16 +03:00
std : : string titleText ;
if ( garr - > armedObjs [ 1 ] - > tempOwner = = garr - > armedObjs [ 0 ] - > tempOwner )
titleText = CGI - > generaltexth - > allTexts [ 709 ] ;
else
{
titleText = CGI - > generaltexth - > allTexts [ 35 ] ;
boost : : algorithm : : replace_first ( titleText , " %s " , garr - > armedObjs [ 0 ] - > Slots ( ) . begin ( ) - > second - > type - > namePl ) ;
}
2012-11-11 15:23:31 +03:00
new CLabel ( 275 , 30 , FONT_BIG , CENTER , Colors : : YELLOW , titleText ) ;
2009-05-19 21:23:04 +03:00
2013-03-03 20:06:03 +03:00
new CAnimImage ( " CREST58 " , garr - > armedObjs [ 0 ] - > getOwner ( ) . getNum ( ) , 0 , 28 , 124 ) ;
2012-06-17 01:40:28 +03:00
new CAnimImage ( " PortraitsLarge " , dynamic_cast < const CGHeroInstance * > ( garr - > armedObjs [ 1 ] ) - > portrait , 0 , 29 , 222 ) ;
2009-05-19 21:23:04 +03:00
}
2011-12-17 21:59:59 +03:00
IShowActivatable : : IShowActivatable ( )
2009-05-19 21:23:04 +03:00
{
type = 0 ;
}
2010-07-22 03:32:45 +03:00
CGarrisonHolder : : CGarrisonHolder ( )
2009-05-19 21:23:04 +03:00
{
}
2010-07-22 03:32:45 +03:00
void CWindowWithGarrison : : updateGarrisons ( )
{
garr - > recreateSlots ( ) ;
}
2009-05-19 21:23:04 +03:00
2011-12-22 16:05:19 +03:00
CArtPlace : : CArtPlace ( Point position , const CArtifactInstance * Art ) :
2012-12-14 18:32:53 +03:00
locked ( false ) , picked ( false ) , marked ( false ) , ourArt ( Art )
2011-04-23 13:27:44 +03:00
{
pos + = position ;
pos . w = pos . h = 44 ;
2012-12-14 18:32:53 +03:00
createImage ( ) ;
}
void CArtPlace : : createImage ( )
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
int graphic = 0 ;
if ( ourArt )
graphic = ourArt - > artType - > iconIndex ;
if ( locked )
2013-02-11 17:42:09 +03:00
graphic = ArtifactID : : ART_LOCK ;
2012-12-14 18:32:53 +03:00
image = new CAnimImage ( " artifact " , graphic ) ;
if ( ! ourArt )
image - > disable ( ) ;
2013-02-11 17:42:09 +03:00
selection = new CAnimImage ( " artifact " , ArtifactID : : ART_SELECTION ) ;
2012-12-14 18:32:53 +03:00
selection - > disable ( ) ;
}
void CArtPlace : : lockSlot ( bool on )
{
if ( locked = = on )
return ;
locked = on ;
if ( on )
2013-02-11 17:42:09 +03:00
image - > setFrame ( ArtifactID : : ART_LOCK ) ;
2012-12-14 18:32:53 +03:00
else
image - > setFrame ( ourArt - > artType - > iconIndex ) ;
}
void CArtPlace : : pickSlot ( bool on )
{
if ( picked = = on )
return ;
picked = on ;
if ( on )
image - > disable ( ) ;
else
image - > enable ( ) ;
}
void CArtPlace : : selectSlot ( bool on )
{
if ( marked = = on )
return ;
marked = on ;
if ( on )
selection - > enable ( ) ;
else
selection - > disable ( ) ;
2011-04-23 13:27:44 +03:00
}
2009-08-11 19:05:33 +03:00
void CArtPlace : : clickLeft ( tribool down , bool previousState )
2009-06-18 18:05:00 +03:00
{
//LRClickableAreaWTextComp::clickLeft(down);
2012-01-12 18:23:00 +03:00
bool inBackpack = slotID > = GameConstants : : BACKPACK_START ,
2011-12-14 00:23:17 +03:00
srcInBackpack = ourOwner - > commonInfo - > src . slotID > = GameConstants : : BACKPACK_START ,
2011-01-15 04:17:56 +02:00
srcInSameHero = ourOwner - > commonInfo - > src . AOH = = ourOwner ;
2012-01-12 18:23:00 +03:00
2011-04-23 00:51:10 +03:00
if ( ourOwner - > highlightModeCallback & & ourArt )
{
if ( down )
{
if ( ourArt - > artType - > id < 7 ) //War Machine or Spellbook
{
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > allTexts [ 21 ] ) ; //This item can't be traded.
}
else
{
ourOwner - > unmarkSlots ( false ) ;
2012-12-14 18:32:53 +03:00
selectSlot ( true ) ;
2011-04-23 00:51:10 +03:00
ourOwner - > highlightModeCallback ( this ) ;
}
}
return ;
}
2009-11-28 21:55:40 +02:00
// If clicked on spellbook, open it only if no artifact is held at the moment.
2011-01-06 22:00:19 +02:00
if ( ourArt & & ! down & & previousState & & ! ourOwner - > commonInfo - > src . AOH )
2009-06-18 18:05:00 +03:00
{
2010-12-29 23:04:22 +02:00
if ( ourArt - > artType - > id = = 0 )
2009-06-18 18:05:00 +03:00
{
2013-06-29 16:05:48 +03:00
auto spellWindow = new CSpellWindow ( genRect ( 595 , 620 , ( screen - > w - 620 ) / 2 , ( screen - > h - 595 ) / 2 ) , ourOwner - > curHero , LOCPLINT , LOCPLINT - > battleInt ) ;
2009-08-07 01:36:51 +03:00
GH . pushInt ( spellWindow ) ;
2009-06-18 18:05:00 +03:00
}
}
2010-07-20 21:34:32 +03:00
2009-12-02 01:19:43 +02:00
if ( ! down & & previousState )
2009-06-18 18:05:00 +03:00
{
2011-02-15 20:40:06 +02:00
if ( ourArt & & ourArt - > artType - > id = = 0 ) //spellbook
2009-06-18 18:05:00 +03:00
return ; //this is handled separately
2010-07-20 21:34:32 +03:00
2011-01-06 22:00:19 +02:00
if ( ! ourOwner - > commonInfo - > src . AOH ) //nothing has been clicked
2009-06-18 18:05:00 +03:00
{
2010-08-12 18:54:25 +03:00
if ( ourArt //to prevent selecting empty slots (bugfix to what GrayFace reported)
& & ourOwner - > curHero - > tempOwner = = LOCPLINT - > playerID ) //can't take art from another player
2009-06-18 18:05:00 +03:00
{
2011-01-15 04:17:56 +02:00
if ( ourArt - > artType - > id = = 3 ) //catapult cannot be highlighted
2009-09-11 08:45:40 +03:00
{
2011-12-22 16:05:19 +03:00
std : : vector < CComponent * > catapult ( 1 , new CComponent ( CComponent : : artifact , 3 , 0 ) ) ;
2009-09-11 08:45:40 +03:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > allTexts [ 312 ] , catapult ) ; //The Catapult must be equipped.
return ;
}
2009-11-28 21:55:40 +02:00
select ( ) ;
2009-06-18 18:05:00 +03:00
}
}
2011-01-06 22:00:19 +02:00
else if ( ourArt = = ourOwner - > commonInfo - > src . art ) //restore previously picked artifact
{
deselect ( ) ;
}
2011-01-15 04:17:56 +02:00
else //perform artifact transition
2009-06-18 18:05:00 +03:00
{
2011-01-15 04:17:56 +02:00
if ( inBackpack ) // Backpack destination.
2009-11-10 05:10:14 +02:00
{
2011-01-15 19:58:08 +02:00
if ( srcInBackpack & & slotID = = ourOwner - > commonInfo - > src . slotID + 1 ) //next slot (our is not visible, so visually same as "old" place) to the art -> make nothing, return artifact to slot
2009-09-11 08:45:40 +03:00
{
2011-01-15 04:17:56 +02:00
deselect ( ) ;
}
else
{
const CArtifact * const cur = ourOwner - > commonInfo - > src . art - > artType ;
2010-12-29 23:04:22 +02:00
2011-01-15 04:17:56 +02:00
switch ( cur - > id )
{
2013-02-07 02:24:43 +03:00
case ArtifactID : : CATAPULT :
2011-01-15 04:17:56 +02:00
//should not happen, catapult cannot be selected
2013-02-07 02:24:43 +03:00
assert ( cur - > id ! = ArtifactID : : CATAPULT ) ;
2011-01-15 04:17:56 +02:00
break ;
2013-02-12 22:49:40 +03:00
case ArtifactID : : BALLISTA : case ArtifactID : : AMMO_CART : case ArtifactID : : FIRST_AID_TENT : //war machines cannot go to backpack
2011-01-15 04:17:56 +02:00
LOCPLINT - > showInfoDialog ( boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 153 ] ) % cur - > Name ( ) ) ) ;
break ;
default :
setMeAsDest ( ) ;
2013-02-12 22:49:40 +03:00
vstd : : amin ( ourOwner - > commonInfo - > dst . slotID , ArtifactPosition (
2013-02-07 02:24:43 +03:00
ourOwner - > curHero - > artifactsInBackpack . size ( ) + GameConstants : : BACKPACK_START ) ) ;
2011-01-15 19:58:08 +02:00
if ( srcInBackpack & & srcInSameHero )
{
2011-12-14 00:23:17 +03:00
if ( ! ourArt //cannot move from backpack to AFTER backpack -> combined with vstd::amin above it will guarantee that dest is at most the last artifact
2011-01-15 19:58:08 +02:00
| | ourOwner - > commonInfo - > src . slotID < ourOwner - > commonInfo - > dst . slotID ) //rearranging arts in backpack after taking src artifact, the dest id will be shifted
2013-02-07 02:24:43 +03:00
vstd : : advance ( ourOwner - > commonInfo - > dst . slotID , - 1 ) ;
2011-01-15 19:58:08 +02:00
}
2011-01-15 04:17:56 +02:00
if ( srcInSameHero & & ourOwner - > commonInfo - > dst . slotID = = ourOwner - > commonInfo - > src . slotID ) //we came to src == dst
deselect ( ) ;
else
ourOwner - > realizeCurrentTransaction ( ) ;
break ;
}
2009-09-11 08:45:40 +03:00
}
2009-06-18 18:05:00 +03:00
}
//check if swap is possible
2011-01-06 22:00:19 +02:00
else if ( fitsHere ( ourOwner - > commonInfo - > src . art ) & &
2010-08-12 18:54:25 +03:00
( ! ourArt | | ourOwner - > curHero - > tempOwner = = LOCPLINT - > playerID ) )
2009-06-18 18:05:00 +03:00
{
2010-12-29 23:04:22 +02:00
setMeAsDest ( ) ;
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// // Special case when the dest artifact can't be fit into the src slot.
// //CGI->arth->unequipArtifact(ourOwner->curHero->artifWorn, slotID);
// const CArtifactsOfHero* srcAOH = ourOwner->commonInfo->src.AOH;
// ui16 srcSlotID = ourOwner->commonInfo->src.slotID;
2012-01-12 18:23:00 +03:00
// if (ourArt && srcSlotID < 19 && !ourArt->canBePutAt(ArtifactLocation(srcAOH->curHero, srcSlotID)))
2011-01-06 22:00:19 +02:00
// {
// // Put dest artifact into owner's backpack.
// ourOwner->commonInfo->src.AOH = ourOwner;
// ourOwner->commonInfo->src.slotID = ourOwner->curHero->artifacts.size() + 19;
// }
2010-02-08 23:17:22 +02:00
2010-12-29 23:04:22 +02:00
ourOwner - > realizeCurrentTransaction ( ) ;
2009-06-18 18:05:00 +03:00
}
}
}
}
2009-11-28 21:55:40 +02:00
2009-08-11 19:05:33 +03:00
void CArtPlace : : clickRight ( tribool down , bool previousState )
2009-06-18 18:05:00 +03:00
{
2011-07-02 18:12:35 +03:00
if ( down & & ourArt & & ! locked & & text . size ( ) & & ! picked ) //if there is no description or it's a lock, do nothing ;]
2010-07-20 21:34:32 +03:00
{
2012-04-14 05:20:22 +03:00
if ( slotID < GameConstants : : BACKPACK_START )
2010-07-20 21:34:32 +03:00
{
2010-07-23 15:02:15 +03:00
if ( ourOwner - > allowedAssembling )
{
2010-12-29 23:04:22 +02:00
std : : vector < const CArtifact * > assemblyPossibilities = ourArt - > assemblyPossibilities ( ourOwner - > curHero ) ;
2010-07-23 15:02:15 +03:00
// If the artifact can be assembled, display dialog.
2013-06-29 16:05:48 +03:00
for ( const CArtifact * combination : assemblyPossibilities )
2010-07-23 15:02:15 +03:00
{
2010-12-29 23:04:22 +02:00
LOCPLINT - > showArtifactAssemblyDialog (
ourArt - > artType - > id ,
combination - > id ,
true ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CCallback : : assembleArtifacts , LOCPLINT - > cb . get ( ) , ourOwner - > curHero , slotID , true , combination - > id ) ,
2010-12-29 23:04:22 +02:00
0 ) ;
2011-01-24 01:49:17 +02:00
if ( assemblyPossibilities . size ( ) > 2 )
2010-07-23 15:02:15 +03:00
{
2013-04-09 17:31:36 +03:00
logGlobal - > warnStream ( ) < < " More than one possibility of assembling... taking only first " ;
2010-12-29 23:04:22 +02:00
break ;
2010-02-27 03:05:39 +02:00
}
2011-07-02 18:12:35 +03:00
return ;
2010-02-27 03:05:39 +02:00
}
2010-02-16 16:39:56 +02:00
2010-07-23 15:02:15 +03:00
// Otherwise if the artifact can be diasassembled, display dialog.
2010-12-29 23:04:22 +02:00
if ( ourArt - > canBeDisassembled ( ) )
2010-07-23 15:02:15 +03:00
{
LOCPLINT - > showArtifactAssemblyDialog (
2010-12-29 23:04:22 +02:00
ourArt - > artType - > id ,
2010-07-23 15:02:15 +03:00
0 ,
false ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CCallback : : assembleArtifacts , LOCPLINT - > cb . get ( ) , ourOwner - > curHero , slotID , false , ArtifactID ( ) ) ,
2010-12-29 23:04:22 +02:00
0 ) ;
2011-07-02 18:12:35 +03:00
return ;
2010-07-23 15:02:15 +03:00
}
2010-02-16 16:39:56 +02:00
}
}
2010-02-27 03:05:39 +02:00
// Lastly just show the artifact description.
LRClickableAreaWTextComp : : clickRight ( down , previousState ) ;
2010-02-16 16:39:56 +02:00
}
2009-06-18 18:05:00 +03:00
}
2009-11-28 21:55:40 +02:00
/**
* Selects artifact slot so that the containing artifact looks like it ' s picked up .
*/
void CArtPlace : : select ( )
{
2011-01-22 05:43:20 +02:00
if ( locked )
2010-02-08 23:17:22 +02:00
return ;
2012-12-14 18:32:53 +03:00
selectSlot ( true ) ;
pickSlot ( true ) ;
2011-12-14 00:23:17 +03:00
if ( ourArt - > canBeDisassembled ( ) & & slotID < GameConstants : : BACKPACK_START ) //worn combined artifact -> locks have to disappear
2011-07-03 04:03:46 +03:00
{
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : BACKPACK_START ; i + + )
2011-07-03 04:03:46 +03:00
{
CArtPlace * ap = ourOwner - > getArtPlace ( i ) ;
2012-12-14 18:32:53 +03:00
ap - > pickSlot ( ourArt - > isPart ( ap - > ourArt ) ) ;
2011-07-03 04:03:46 +03:00
}
}
2011-01-28 04:11:58 +02:00
//int backpackCorrection = -(slotID - Arts::BACKPACK_START < ourOwner->backpackPos);
2010-02-28 04:44:37 +02:00
2012-12-14 18:32:53 +03:00
CCS - > curh - > dragAndDropCursor ( new CAnimImage ( " artifact " , ourArt - > artType - > iconIndex ) ) ;
2011-01-06 22:00:19 +02:00
ourOwner - > commonInfo - > src . setTo ( this , false ) ;
2010-07-20 21:34:32 +03:00
ourOwner - > markPossibleSlots ( ourArt ) ;
2011-01-15 04:17:56 +02:00
2011-12-14 00:23:17 +03:00
if ( slotID > = GameConstants : : BACKPACK_START )
2011-01-15 04:17:56 +02:00
ourOwner - > scrollBackpack ( 0 ) ; //will update slots
2010-07-23 15:02:15 +03:00
ourOwner - > updateParentWindow ( ) ;
ourOwner - > safeRedraw ( ) ;
2009-11-28 21:55:40 +02:00
}
/**
2010-02-28 04:44:37 +02:00
* Deselects the artifact slot . FIXME : Not used . Maybe it should ?
2009-11-28 21:55:40 +02:00
*/
void CArtPlace : : deselect ( )
{
2012-12-14 18:32:53 +03:00
pickSlot ( false ) ;
2011-07-03 04:03:46 +03:00
if ( ourArt & & ourArt - > canBeDisassembled ( ) ) //combined art returned to its slot -> restore locks
{
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : BACKPACK_START ; i + + )
2012-12-14 18:32:53 +03:00
ourOwner - > getArtPlace ( i ) - > pickSlot ( false ) ;
2011-07-03 04:03:46 +03:00
}
2013-06-26 14:18:27 +03:00
CCS - > curh - > dragAndDropCursor ( nullptr ) ;
2009-11-28 21:55:40 +02:00
ourOwner - > unmarkSlots ( ) ;
2011-01-06 22:00:19 +02:00
ourOwner - > commonInfo - > src . clear ( ) ;
2011-12-14 00:23:17 +03:00
if ( slotID > = GameConstants : : BACKPACK_START )
2011-01-15 04:17:56 +02:00
ourOwner - > scrollBackpack ( 0 ) ; //will update slots
2011-01-06 22:00:19 +02:00
ourOwner - > updateParentWindow ( ) ;
ourOwner - > safeRedraw ( ) ;
2009-11-28 21:55:40 +02:00
}
2011-12-22 16:05:19 +03:00
void CArtPlace : : showAll ( SDL_Surface * to )
2009-06-18 18:05:00 +03:00
{
2011-03-19 02:06:54 +02:00
if ( ourArt & & ! picked & & ourArt = = ourOwner - > curHero - > getArt ( slotID , false ) ) //last condition is needed for disassembling -> artifact may be gone, but we don't know yet TODO: real, nice solution
2011-01-22 05:43:20 +02:00
{
2012-12-14 18:32:53 +03:00
CIntObject : : showAll ( to ) ;
2011-01-22 05:43:20 +02:00
}
2009-12-02 01:19:43 +02:00
2009-11-28 21:55:40 +02:00
if ( marked & & active )
2009-06-18 18:05:00 +03:00
{
2009-11-28 21:55:40 +02:00
// Draw vertical bars.
2012-01-12 18:23:00 +03:00
for ( int i = 0 ; i < pos . h ; + + i )
2010-07-20 09:05:45 +03:00
{
2009-11-28 21:55:40 +02:00
CSDL_Ext : : SDL_PutPixelWithoutRefresh ( to , pos . x , pos . y + i , 240 , 220 , 120 ) ;
CSDL_Ext : : SDL_PutPixelWithoutRefresh ( to , pos . x + pos . w - 1 , pos . y + i , 240 , 220 , 120 ) ;
}
// Draw horizontal bars.
2012-01-12 18:23:00 +03:00
for ( int i = 0 ; i < pos . w ; + + i )
2010-07-20 09:05:45 +03:00
{
2009-11-28 21:55:40 +02:00
CSDL_Ext : : SDL_PutPixelWithoutRefresh ( to , pos . x + i , pos . y , 240 , 220 , 120 ) ;
CSDL_Ext : : SDL_PutPixelWithoutRefresh ( to , pos . x + i , pos . y + pos . h - 1 , 240 , 220 , 120 ) ;
2009-06-18 18:05:00 +03:00
}
}
}
2009-11-28 21:55:40 +02:00
2010-12-29 23:04:22 +02:00
bool CArtPlace : : fitsHere ( const CArtifactInstance * art ) const
2009-06-18 18:05:00 +03:00
{
2009-11-28 21:55:40 +02:00
// You can place 'no artifact' anywhere.
2009-06-18 18:05:00 +03:00
if ( ! art )
2009-11-28 21:55:40 +02:00
return true ;
2009-12-30 17:33:28 +02:00
// Anything can but War Machines can be placed in backpack.
2012-04-14 05:20:22 +03:00
if ( slotID > = GameConstants : : BACKPACK_START )
2013-02-07 20:34:50 +03:00
return ! CGI - > arth - > isBigArtifact ( art - > artType - > id ) ;
2009-09-11 08:45:40 +03:00
2011-01-06 22:00:19 +02:00
return art - > canBePutAt ( ArtifactLocation ( ourOwner - > curHero , slotID ) , true ) ;
2009-06-18 18:05:00 +03:00
}
2009-11-28 21:55:40 +02:00
2010-12-29 23:04:22 +02:00
void CArtPlace : : setMeAsDest ( bool backpackAsVoid /*= true*/ )
{
2011-01-06 22:00:19 +02:00
ourOwner - > commonInfo - > dst . setTo ( this , backpackAsVoid ) ;
2010-12-29 23:04:22 +02:00
}
2011-01-15 04:17:56 +02:00
void CArtPlace : : setArtifact ( const CArtifactInstance * art )
{
2011-03-12 23:55:31 +02:00
baseType = - 1 ; //by default we don't store any component
2011-01-15 04:17:56 +02:00
ourArt = art ;
if ( ! art )
{
2012-12-14 18:32:53 +03:00
image - > disable ( ) ;
2011-01-15 04:17:56 +02:00
text = std : : string ( ) ;
hoverText = CGI - > generaltexth - > allTexts [ 507 ] ;
}
else
{
2012-12-14 18:32:53 +03:00
image - > enable ( ) ;
2013-02-11 17:42:09 +03:00
image - > setFrame ( locked ? ArtifactID : : ART_LOCK : art - > artType - > iconIndex ) ;
2013-01-24 11:01:43 +03:00
std : : string artDesc = ourArt - > artType - > Description ( ) ;
if ( vstd : : contains ( artDesc , ' { ' ) )
text = artDesc ;
else
text = ' { ' + ourArt - > artType - > Name ( ) + " } \n \n " + artDesc ; //workaround for new artifacts with single name, turns it to H3-style
2011-03-12 23:55:31 +02:00
if ( art - > artType - > id = = 1 ) //spell scroll
{
// we expect scroll description to be like this: This scroll contains the [spell name] spell which is added into your spell book for as long as you carry the scroll.
// so we want to replace text in [...] with a spell name
// however other language versions don't have name placeholder at all, so we have to be careful
int spellID = art - > getGivenSpellID ( ) ;
2013-01-21 01:49:34 +03:00
size_t nameStart = text . find_first_of ( ' [ ' ) ;
size_t nameEnd = text . find_first_of ( ' ] ' , nameStart ) ;
2011-03-12 23:55:31 +02:00
if ( spellID > = 0 )
{
if ( nameStart ! = std : : string : : npos & & nameEnd ! = std : : string : : npos )
2014-03-07 16:21:09 +03:00
text = text . replace ( nameStart , nameEnd - nameStart + 1 , CGI - > spellh - > objects [ spellID ] - > name ) ;
2011-03-12 23:55:31 +02:00
//add spell component info (used to provide a pic in r-click popup)
2011-12-22 16:05:19 +03:00
baseType = CComponent : : spell ;
2011-03-12 23:55:31 +02:00
type = spellID ;
bonusValue = 0 ;
}
}
2013-04-25 17:03:35 +03:00
else
{
baseType = CComponent : : artifact ;
2014-01-30 14:08:37 +03:00
type = art - > artType - > id ;
2013-04-25 17:03:35 +03:00
bonusValue = 0 ;
}
2013-12-01 16:08:35 +03:00
if ( art - > artType - > constituents ) //display info about components of combined artifact
{
//TODO
}
else if ( art - > artType - > constituentOf . size ( ) ) //display info about set
{
std : : string artList ;
auto combinedArt = art - > artType - > constituentOf [ 0 ] ;
text + = " \n \n " ;
text + = " { " + combinedArt - > Name ( ) + " } " ;
int wornArtifacts = 0 ;
for ( auto a : * combinedArt - > constituents ) //TODO: can the artifact be a part of more than one set?
{
artList + = " \n " + a - > Name ( ) ;
if ( ourOwner - > curHero - > hasArt ( a - > id , true ) )
wornArtifacts + + ;
}
text + = " ( " + boost : : str ( boost : : format ( " %d " ) % wornArtifacts ) + " / " +
boost : : str ( boost : : format ( " %d " ) % combinedArt - > constituents - > size ( ) ) + " ) " + artList ;
//TODO: fancy colors and fonts for this text
}
2011-03-12 23:55:31 +02:00
2011-01-22 05:43:20 +02:00
if ( locked ) // Locks should appear as empty.
2011-01-15 04:17:56 +02:00
hoverText = CGI - > generaltexth - > allTexts [ 507 ] ;
else
hoverText = boost : : str ( boost : : format ( CGI - > generaltexth - > heroscrn [ 1 ] ) % ourArt - > artType - > Name ( ) ) ;
}
}
2009-08-11 19:05:33 +03:00
void LRClickableAreaWTextComp : : clickLeft ( tribool down , bool previousState )
2009-06-18 18:05:00 +03:00
{
2009-08-11 19:05:33 +03:00
if ( ( ! down ) & & previousState )
2009-06-18 18:05:00 +03:00
{
2011-12-22 16:05:19 +03:00
std : : vector < CComponent * > comp ( 1 , createComponent ( ) ) ;
2010-07-13 08:25:40 +03:00
LOCPLINT - > showInfoDialog ( text , comp ) ;
2009-06-18 18:05:00 +03:00
}
}
2011-12-22 16:05:19 +03:00
LRClickableAreaWTextComp : : LRClickableAreaWTextComp ( const Rect & Pos , int BaseType )
2010-12-17 00:32:53 +02:00
: LRClickableAreaWText ( Pos ) , baseType ( BaseType ) , bonusValue ( - 1 )
{
}
2011-12-22 16:05:19 +03:00
CComponent * LRClickableAreaWTextComp : : createComponent ( ) const
2011-03-12 23:55:31 +02:00
{
if ( baseType > = 0 )
2011-12-22 16:05:19 +03:00
return new CComponent ( CComponent : : Etype ( baseType ) , type , bonusValue ) ;
2011-03-12 23:55:31 +02:00
else
2013-06-26 14:18:27 +03:00
return nullptr ;
2011-03-12 23:55:31 +02:00
}
void LRClickableAreaWTextComp : : clickRight ( tribool down , bool previousState )
{
if ( down )
{
2011-12-22 16:05:19 +03:00
if ( CComponent * comp = createComponent ( ) )
2011-03-12 23:55:31 +02:00
{
CRClickPopup : : createAndPush ( text , CInfoWindow : : TCompsInfo ( 1 , comp ) ) ;
return ;
}
}
2011-09-24 04:15:36 +03:00
LRClickableAreaWText : : clickRight ( down , previousState ) ; //only if with-component variant not occurred
2011-03-12 23:55:31 +02:00
}
2010-07-22 03:32:45 +03:00
CHeroArea : : CHeroArea ( int x , int y , const CGHeroInstance * _hero ) : hero ( _hero )
{
2012-12-10 17:28:27 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
2010-07-22 03:32:45 +03:00
pos . x + = x ; pos . w = 58 ;
pos . y + = y ; pos . h = 64 ;
2012-12-10 17:28:27 +03:00
if ( hero )
new CAnimImage ( " PortraitsLarge " , hero - > portrait ) ;
2010-07-22 03:32:45 +03:00
}
void CHeroArea : : clickLeft ( tribool down , bool previousState )
2010-02-04 17:50:59 +02:00
{
if ( ( ! down ) & & previousState & & hero )
LOCPLINT - > openHeroWindow ( hero ) ;
}
2010-07-22 03:32:45 +03:00
void CHeroArea : : clickRight ( tribool down , bool previousState )
2010-02-04 17:50:59 +02:00
{
if ( ( ! down ) & & previousState & & hero )
LOCPLINT - > openHeroWindow ( hero ) ;
}
2010-07-22 03:32:45 +03:00
void CHeroArea : : hover ( bool on )
{
if ( on & & hero )
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( hero - > hoverName ) ;
2010-07-22 03:32:45 +03:00
else
GH . statusbar - > clear ( ) ;
}
2010-02-04 17:50:59 +02:00
void LRClickableAreaOpenTown : : clickLeft ( tribool down , bool previousState )
{
if ( ( ! down ) & & previousState & & town )
2010-02-28 12:01:36 +02:00
{
2010-02-04 17:50:59 +02:00
LOCPLINT - > openTownWindow ( town ) ;
2010-02-28 12:01:36 +02:00
if ( type = = 2 )
2013-02-11 22:11:34 +03:00
LOCPLINT - > castleInt - > builds - > buildingClicked ( BuildingID : : VILLAGE_HALL ) ;
2010-02-28 12:01:36 +02:00
else if ( type = = 3 & & town - > fortLevel ( ) )
2013-02-11 22:11:34 +03:00
LOCPLINT - > castleInt - > builds - > buildingClicked ( BuildingID : : FORT ) ;
2010-02-28 12:01:36 +02:00
}
2010-02-04 17:50:59 +02:00
}
void LRClickableAreaOpenTown : : clickRight ( tribool down , bool previousState )
{
if ( ( ! down ) & & previousState & & town )
2010-02-28 12:01:36 +02:00
LOCPLINT - > openTownWindow ( town ) ; //TODO: popup?
2010-02-04 17:50:59 +02:00
}
2010-12-17 00:32:53 +02:00
LRClickableAreaOpenTown : : LRClickableAreaOpenTown ( )
2011-12-22 16:05:19 +03:00
: LRClickableAreaWTextComp ( Rect ( 0 , 0 , 0 , 0 ) , - 1 )
2010-12-17 00:32:53 +02:00
{
}
2010-07-20 21:34:32 +03:00
void CArtifactsOfHero : : SCommonPart : : reset ( )
2009-06-18 18:05:00 +03:00
{
2011-01-06 22:00:19 +02:00
src . clear ( ) ;
dst . clear ( ) ;
2013-06-26 14:18:27 +03:00
CCS - > curh - > dragAndDropCursor ( nullptr ) ;
2009-06-18 18:05:00 +03:00
}
void CArtifactsOfHero : : setHero ( const CGHeroInstance * hero )
{
2011-01-06 22:00:19 +02:00
// // An update is made, rather than initialization.
2012-01-12 18:23:00 +03:00
// if (curHero && curHero->id == hero->id)
2011-01-06 22:00:19 +02:00
// {
// if(curHero != hero)
// {
// //delete curHero;
// curHero = hero; //was: creating a copy
// }
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// // Compensate backpack pos if an artifact was insertad before it.
// if (commonInfo->dst.slotID >= 19 && commonInfo->destAOH == this
// && commonInfo->dst.slotID - 19 < backpackPos)
// {
// backpackPos++;
// }
2012-01-12 18:23:00 +03:00
//
// if (updateState && commonInfo->srcAOH == this)
2011-01-06 22:00:19 +02:00
// {
// // A swap was made, make the replaced artifact the current selected.
2012-01-12 18:23:00 +03:00
// if (commonInfo->dst.slotID < 19 && commonInfo->destArtifact)
2011-01-06 22:00:19 +02:00
// {
// // // Temporarily remove artifact from hero.
// // if (commonInfo->srcSlotID < 19)
// // CGI->arth->unequipArtifact(curHero->artifWorn, commonInfo->srcSlotID);
// // else
// // curHero->artifacts.erase(curHero->artifacts.begin() + (commonInfo->srcSlotID - 19));
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// updateParentWindow(); //TODO: evil! but does the thing
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// // Source <- Dest
// commonInfo->srcArtifact = commonInfo->destArtifact;
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// // Reset destination parameters.
// commonInfo->dst.clear();
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// CCS->curh->dragAndDropCursor(graphics->artDefs->ourImages[commonInfo->srcArtifact->id].bitmap);
// markPossibleSlots(commonInfo->srcArtifact);
2012-01-12 18:23:00 +03:00
// }
2013-06-26 14:18:27 +03:00
// else if (commonInfo->destAOH != nullptr)
2011-01-06 22:00:19 +02:00
// {
// // Reset all parameters.
// commonInfo->reset();
// unmarkSlots();
// }
// }
2012-01-12 18:23:00 +03:00
// }
// else
2011-01-06 22:00:19 +02:00
// {
// commonInfo->reset();
// }
2012-01-12 18:23:00 +03:00
//
2011-01-06 22:00:19 +02:00
// if(hero != curHero)
// {
// // delete curHero;
// // curHero = new CGHeroInstance(*hero);
// curHero = hero; //was: creating a copy
// }
2009-06-18 18:05:00 +03:00
2011-01-06 22:00:19 +02:00
curHero = hero ;
2011-01-18 20:56:14 +02:00
if ( curHero - > artifactsInBackpack . size ( ) > 0 )
backpackPos % = curHero - > artifactsInBackpack . size ( ) ;
2009-11-28 21:55:40 +02:00
else
backpackPos = 0 ;
2009-06-18 18:05:00 +03:00
2009-12-02 01:19:43 +02:00
// Fill the slots for worn artifacts and backpack.
2011-04-23 13:27:44 +03:00
for ( int g = 0 ; g < artWorn . size ( ) ; g + + )
2013-02-12 22:49:40 +03:00
setSlotData ( artWorn [ g ] , ArtifactPosition ( g ) ) ;
2009-12-02 01:19:43 +02:00
scrollBackpack ( 0 ) ;
}
2009-11-28 21:55:40 +02:00
2009-06-18 18:05:00 +03:00
void CArtifactsOfHero : : dispose ( )
{
2011-12-14 00:23:17 +03:00
//vstd::clear_pointer(curHero);
2011-07-18 18:21:16 +03:00
//unmarkSlots(false);
2013-06-26 14:18:27 +03:00
CCS - > curh - > dragAndDropCursor ( nullptr ) ;
2009-06-18 18:05:00 +03:00
}
void CArtifactsOfHero : : scrollBackpack ( int dir )
{
2011-01-15 04:17:56 +02:00
int artsInBackpack = curHero - > artifactsInBackpack . size ( ) ;
2009-11-28 21:55:40 +02:00
backpackPos + = dir ;
2011-01-15 04:17:56 +02:00
if ( backpackPos < 0 ) // No guarantee of modulus behavior with negative operands -> we keep it positive
backpackPos + = artsInBackpack ;
2009-06-18 18:05:00 +03:00
2011-01-15 04:17:56 +02:00
if ( artsInBackpack )
backpackPos % = artsInBackpack ;
std : : multiset < const CArtifactInstance * > toOmit = artifactsOnAltar ;
if ( commonInfo - > src . art ) //if we picked an art from backapck, its slot has to be omitted
toOmit . insert ( commonInfo - > src . art ) ;
2012-01-12 18:23:00 +03:00
2011-01-15 04:17:56 +02:00
int omitedSoFar = 0 ;
2010-07-23 15:02:15 +03:00
2009-11-28 21:55:40 +02:00
//set new data
2010-07-23 15:02:15 +03:00
size_t s = 0 ;
2012-01-12 18:23:00 +03:00
for ( ; s < artsInBackpack ; + + s )
2010-07-20 21:34:32 +03:00
{
2010-07-23 15:02:15 +03:00
2011-01-15 04:17:56 +02:00
if ( s < artsInBackpack )
2010-07-23 15:02:15 +03:00
{
2013-02-12 22:49:40 +03:00
auto slotID = ArtifactPosition ( GameConstants : : BACKPACK_START + ( s + backpackPos ) % artsInBackpack ) ;
2010-12-29 23:04:22 +02:00
const CArtifactInstance * art = curHero - > getArt ( slotID ) ;
2010-07-23 15:02:15 +03:00
assert ( art ) ;
2011-01-15 04:17:56 +02:00
if ( ! vstd : : contains ( toOmit , art ) )
2012-01-12 18:23:00 +03:00
{
2011-04-30 21:16:58 +03:00
if ( s - omitedSoFar < backpack . size ( ) )
2011-01-15 04:17:56 +02:00
setSlotData ( backpack [ s - omitedSoFar ] , slotID ) ;
2010-07-23 15:02:15 +03:00
}
else
{
2011-01-15 04:17:56 +02:00
toOmit - = art ;
omitedSoFar + + ;
2010-07-23 15:02:15 +03:00
continue ;
}
}
2009-11-28 21:55:40 +02:00
}
2011-04-30 21:16:58 +03:00
for ( ; s - omitedSoFar < backpack . size ( ) ; s + + )
2013-02-12 22:49:40 +03:00
eraseSlotData ( backpack [ s - omitedSoFar ] , ArtifactPosition ( GameConstants : : BACKPACK_START + s ) ) ;
2010-07-23 15:02:15 +03:00
2011-04-23 00:51:10 +03:00
//in artifact merchant selling artifacts we may have highlight on one of backpack artifacts -> market needs update, cause artifact under highlight changed
if ( highlightModeCallback )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : backpack )
2011-04-23 00:51:10 +03:00
{
2013-06-29 16:05:48 +03:00
if ( elem - > marked )
2011-04-23 00:51:10 +03:00
{
2013-06-29 16:05:48 +03:00
highlightModeCallback ( elem ) ;
2011-04-23 00:51:10 +03:00
break ;
}
}
}
2010-07-23 15:02:15 +03:00
//blocking scrolling if there is not enough artifacts to scroll
2011-01-15 04:17:56 +02:00
bool scrollingPossible = artsInBackpack - omitedSoFar > backpack . size ( ) ;
leftArtRoll - > block ( ! scrollingPossible ) ;
rightArtRoll - > block ( ! scrollingPossible ) ;
2010-07-23 15:02:15 +03:00
safeRedraw ( ) ;
2009-11-28 21:55:40 +02:00
}
/**
* Marks possible slots where a given artifact can be placed , except backpack .
*
* @ param art Artifact checked against .
*/
2010-12-29 23:04:22 +02:00
void CArtifactsOfHero : : markPossibleSlots ( const CArtifactInstance * art )
2009-11-28 21:55:40 +02:00
{
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : commonInfo - > participants )
for ( CArtPlace * place : aoh - > artWorn )
2012-12-14 18:32:53 +03:00
place - > selectSlot ( art - > canBePutAt ( ArtifactLocation ( aoh - > curHero , place - > slotID ) , true ) ) ;
2012-02-16 20:10:58 +03:00
2010-07-23 15:02:15 +03:00
safeRedraw ( ) ;
2009-11-28 21:55:40 +02:00
}
/**
* Unamarks all slots .
*/
2010-10-31 21:56:37 +02:00
void CArtifactsOfHero : : unmarkSlots ( bool withRedraw /*= true*/ )
2009-11-28 21:55:40 +02:00
{
2011-01-15 04:17:56 +02:00
if ( commonInfo )
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : commonInfo - > participants )
2011-04-23 00:51:10 +03:00
aoh - > unmarkLocalSlots ( false ) ;
2011-01-15 04:17:56 +02:00
else
2011-04-23 00:51:10 +03:00
unmarkLocalSlots ( false ) ; \
if ( withRedraw )
safeRedraw ( ) ;
}
void CArtifactsOfHero : : unmarkLocalSlots ( bool withRedraw /*= true*/ )
{
2013-06-29 16:05:48 +03:00
for ( CArtPlace * place : artWorn )
2012-12-14 18:32:53 +03:00
place - > selectSlot ( false ) ;
2013-06-29 16:05:48 +03:00
for ( CArtPlace * place : backpack )
2012-12-14 18:32:53 +03:00
place - > selectSlot ( false ) ;
2010-07-23 15:02:15 +03:00
2010-10-31 21:56:37 +02:00
if ( withRedraw )
safeRedraw ( ) ;
2009-11-28 21:55:40 +02:00
}
/**
* Assigns an artifacts to an artifact place depending on it ' s new slot ID .
*/
2013-02-12 22:49:40 +03:00
void CArtifactsOfHero : : setSlotData ( CArtPlace * artPlace , ArtifactPosition slotID )
2009-11-28 21:55:40 +02:00
{
2011-12-14 00:23:17 +03:00
if ( ! artPlace & & slotID > = GameConstants : : BACKPACK_START ) //spurious call from artifactMoved in attempt to update hidden backpack slot
2010-07-20 21:34:32 +03:00
{
2011-01-15 04:17:56 +02:00
return ;
2009-06-18 18:05:00 +03:00
}
2011-01-15 04:17:56 +02:00
2012-12-14 18:32:53 +03:00
artPlace - > pickSlot ( false ) ;
2011-01-15 04:17:56 +02:00
artPlace - > slotID = slotID ;
2012-01-12 18:23:00 +03:00
2011-01-22 05:43:20 +02:00
if ( const ArtSlotInfo * asi = curHero - > getSlot ( slotID ) )
{
artPlace - > setArtifact ( asi - > artifact ) ;
2012-12-14 18:32:53 +03:00
artPlace - > lockSlot ( asi - > locked ) ;
2011-01-22 05:43:20 +02:00
}
else
2013-06-26 14:18:27 +03:00
artPlace - > setArtifact ( nullptr ) ;
2012-01-12 18:23:00 +03:00
}
2009-06-18 18:05:00 +03:00
2009-11-28 21:55:40 +02:00
/**
* Makes given artifact slot appear as empty with a certain slot ID .
*/
2013-02-12 22:49:40 +03:00
void CArtifactsOfHero : : eraseSlotData ( CArtPlace * artPlace , ArtifactPosition slotID )
2009-11-28 21:55:40 +02:00
{
2012-12-14 18:32:53 +03:00
artPlace - > pickSlot ( false ) ;
2009-11-28 21:55:40 +02:00
artPlace - > slotID = slotID ;
2013-06-26 14:18:27 +03:00
artPlace - > setArtifact ( nullptr ) ;
2009-11-28 21:55:40 +02:00
}
2011-04-23 13:27:44 +03:00
CArtifactsOfHero : : CArtifactsOfHero ( std : : vector < CArtPlace * > ArtWorn , std : : vector < CArtPlace * > Backpack ,
2011-12-22 16:05:19 +03:00
CAdventureMapButton * leftScroll , CAdventureMapButton * rightScroll , bool createCommonPart ) :
2011-04-23 13:27:44 +03:00
2013-06-26 14:18:27 +03:00
curHero ( nullptr ) ,
2011-04-23 13:27:44 +03:00
artWorn ( ArtWorn ) , backpack ( Backpack ) ,
2013-06-26 14:18:27 +03:00
backpackPos ( 0 ) , commonInfo ( nullptr ) , updateState ( false ) ,
2011-04-23 13:27:44 +03:00
leftArtRoll ( leftScroll ) , rightArtRoll ( rightScroll ) ,
2013-06-29 16:05:48 +03:00
allowedAssembling ( true ) , highlightModeCallback ( nullptr )
2011-04-23 13:27:44 +03:00
{
if ( createCommonPart )
{
commonInfo = new CArtifactsOfHero : : SCommonPart ;
commonInfo - > participants . insert ( this ) ;
}
2012-01-12 18:23:00 +03:00
2011-04-23 13:27:44 +03:00
// Init slots for worn artifacts.
for ( size_t g = 0 ; g < artWorn . size ( ) ; g + + )
{
artWorn [ g ] - > ourOwner = this ;
2013-02-12 22:49:40 +03:00
eraseSlotData ( artWorn [ g ] , ArtifactPosition ( g ) ) ;
2011-04-23 13:27:44 +03:00
}
// Init slots for the backpack.
for ( size_t s = 0 ; s < backpack . size ( ) ; + + s )
{
backpack [ s ] - > ourOwner = this ;
2013-02-12 22:49:40 +03:00
eraseSlotData ( backpack [ s ] , ArtifactPosition ( GameConstants : : BACKPACK_START + s ) ) ;
2011-04-23 13:27:44 +03:00
}
2011-04-30 21:16:58 +03:00
2013-07-02 18:23:32 +03:00
leftArtRoll - > callback + = boost : : bind ( & CArtifactsOfHero : : scrollBackpack , this , - 1 ) ;
rightArtRoll - > callback + = boost : : bind ( & CArtifactsOfHero : : scrollBackpack , this , + 1 ) ;
2011-04-23 13:27:44 +03:00
}
2011-12-22 16:05:19 +03:00
CArtifactsOfHero : : CArtifactsOfHero ( const Point & position , bool createCommonPart /*= false*/ )
2013-06-29 16:05:48 +03:00
: curHero ( nullptr ) , backpackPos ( 0 ) , commonInfo ( nullptr ) , updateState ( false ) , allowedAssembling ( true ) , highlightModeCallback ( nullptr )
2009-06-18 18:05:00 +03:00
{
2010-12-17 00:32:53 +02:00
if ( createCommonPart )
{
commonInfo = new CArtifactsOfHero : : SCommonPart ;
commonInfo - > participants . insert ( this ) ;
}
2010-07-20 21:34:32 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-07-20 09:05:45 +03:00
pos + = position ;
2009-06-18 18:05:00 +03:00
artWorn . resize ( 19 ) ;
2012-01-12 18:23:00 +03:00
2012-12-14 18:32:53 +03:00
std : : vector < Point > slotPos ;
slotPos + = Point ( 509 , 30 ) , Point ( 567 , 240 ) , Point ( 509 , 80 ) ,
Point ( 383 , 68 ) , Point ( 564 , 183 ) , Point ( 509 , 130 ) ,
Point ( 431 , 68 ) , Point ( 610 , 183 ) , Point ( 515 , 295 ) ,
Point ( 383 , 143 ) , Point ( 399 , 194 ) , Point ( 415 , 245 ) ,
Point ( 431 , 296 ) , Point ( 564 , 30 ) , Point ( 610 , 30 ) ,
Point ( 610 , 76 ) , Point ( 610 , 122 ) , Point ( 610 , 310 ) ,
Point ( 381 , 296 ) ;
2009-12-02 01:19:43 +02:00
// Create slots for worn artifacts.
2013-02-07 02:24:43 +03:00
for ( size_t g = 0 ; g < GameConstants : : BACKPACK_START ; g + + )
2011-04-23 13:27:44 +03:00
{
2012-12-14 18:32:53 +03:00
artWorn [ g ] = new CArtPlace ( slotPos [ g ] ) ;
2009-12-02 01:19:43 +02:00
artWorn [ g ] - > ourOwner = this ;
2013-02-12 22:49:40 +03:00
eraseSlotData ( artWorn [ g ] , ArtifactPosition ( g ) ) ;
2009-12-02 01:19:43 +02:00
}
// Create slots for the backpack.
for ( size_t s = 0 ; s < 5 ; + + s )
{
2013-06-29 16:05:48 +03:00
auto add = new CArtPlace ( Point ( 403 + 46 * s , 365 ) ) ;
2009-12-02 01:19:43 +02:00
add - > ourOwner = this ;
2013-02-12 22:49:40 +03:00
eraseSlotData ( add , ArtifactPosition ( GameConstants : : BACKPACK_START + s ) ) ;
2009-12-02 01:19:43 +02:00
backpack . push_back ( add ) ;
}
2013-07-02 18:23:32 +03:00
leftArtRoll = new CAdventureMapButton ( std : : string ( ) , std : : string ( ) , boost : : bind ( & CArtifactsOfHero : : scrollBackpack , this , - 1 ) , 379 , 364 , " hsbtns3.def " , SDLK_LEFT ) ;
rightArtRoll = new CAdventureMapButton ( std : : string ( ) , std : : string ( ) , boost : : bind ( & CArtifactsOfHero : : scrollBackpack , this , + 1 ) , 632 , 364 , " hsbtns5.def " , SDLK_RIGHT ) ;
2009-06-18 18:05:00 +03:00
}
CArtifactsOfHero : : ~ CArtifactsOfHero ( )
{
2009-06-19 15:10:36 +03:00
dispose ( ) ;
2009-06-18 18:05:00 +03:00
}
2010-07-21 22:50:15 +03:00
void CArtifactsOfHero : : updateParentWindow ( )
{
2012-01-12 18:23:00 +03:00
if ( CHeroWindow * chw = dynamic_cast < CHeroWindow * > ( GH . topInt ( ) ) )
2010-07-21 22:50:15 +03:00
{
if ( updateState )
chw - > curHero = curHero ;
else
2011-01-06 22:00:19 +02:00
chw - > update ( curHero , true ) ;
2012-01-12 18:23:00 +03:00
}
2010-07-21 22:50:15 +03:00
else if ( CExchangeWindow * cew = dynamic_cast < CExchangeWindow * > ( GH . topInt ( ) ) )
{
//use our copy of hero to draw window
if ( cew - > heroInst [ 0 ] - > id = = curHero - > id )
cew - > heroInst [ 0 ] = curHero ;
else
cew - > heroInst [ 1 ] = curHero ;
if ( ! updateState )
{
cew - > deactivate ( ) ;
2011-02-27 21:58:14 +02:00
// for(int g=0; g<ARRAY_COUNT(cew->heroInst); ++g)
// {
// if(cew->heroInst[g] == curHero)
// {
// cew->artifs[g]->setHero(curHero);
// }
// }
2010-07-21 22:50:15 +03:00
cew - > prepareBackground ( ) ;
2011-02-27 21:58:14 +02:00
cew - > redraw ( ) ;
2010-07-21 22:50:15 +03:00
cew - > activate ( ) ;
}
}
}
2010-07-23 15:02:15 +03:00
void CArtifactsOfHero : : safeRedraw ( )
{
2011-07-22 19:22:22 +03:00
if ( active )
{
if ( parent )
parent - > redraw ( ) ;
2012-01-12 18:23:00 +03:00
else
2011-07-22 19:22:22 +03:00
redraw ( ) ;
}
2010-07-23 15:02:15 +03:00
}
2010-12-29 23:04:22 +02:00
void CArtifactsOfHero : : realizeCurrentTransaction ( )
{
2012-04-14 05:20:22 +03:00
assert ( commonInfo - > src . AOH ) ;
assert ( commonInfo - > dst . AOH ) ;
LOCPLINT - > cb - > swapArtifacts ( ArtifactLocation ( commonInfo - > src . AOH - > curHero , commonInfo - > src . slotID ) ,
ArtifactLocation ( commonInfo - > dst . AOH - > curHero , commonInfo - > dst . slotID ) ) ;
2011-01-06 22:00:19 +02:00
}
void CArtifactsOfHero : : artifactMoved ( const ArtifactLocation & src , const ArtifactLocation & dst )
{
2012-04-14 05:20:22 +03:00
bool isCurHeroSrc = src . isHolder ( curHero ) ,
isCurHeroDst = dst . isHolder ( curHero ) ;
if ( isCurHeroSrc & & src . slot > = GameConstants : : BACKPACK_START )
2011-04-23 00:51:10 +03:00
updateSlot ( src . slot ) ;
2012-04-14 05:20:22 +03:00
if ( isCurHeroDst & & dst . slot > = GameConstants : : BACKPACK_START )
2011-04-23 00:51:10 +03:00
updateSlot ( dst . slot ) ;
2012-04-14 05:20:22 +03:00
if ( isCurHeroSrc | | isCurHeroDst ) //we need to update all slots, artifact might be combined and affect more slots
2011-02-27 21:58:14 +02:00
updateWornSlots ( false ) ;
2012-01-12 18:23:00 +03:00
2012-04-14 05:20:22 +03:00
if ( ! src . isHolder ( curHero ) & & ! isCurHeroDst )
2011-07-02 18:12:35 +03:00
return ;
2011-01-06 22:00:19 +02:00
if ( commonInfo - > src = = src ) //artifact was taken from us
{
2012-04-14 05:20:22 +03:00
assert ( commonInfo - > dst = = dst //expected movement from slot ot slot
| | dst . slot = = dst . getHolderArtSet ( ) - > artifactsInBackpack . size ( ) + GameConstants : : BACKPACK_START //artifact moved back to backpack (eg. to make place for art we are moving)
2012-05-19 21:27:23 +03:00
| | dst . getHolderArtSet ( ) - > bearerType ( ) ! = ArtBearer : : HERO ) ;
2011-01-06 22:00:19 +02:00
commonInfo - > reset ( ) ;
unmarkSlots ( ) ;
}
else if ( commonInfo - > dst = = src ) //the dest artifact was moved -> we are picking it
{
2011-12-14 00:23:17 +03:00
assert ( dst . slot > = GameConstants : : BACKPACK_START ) ;
2011-01-06 22:00:19 +02:00
commonInfo - > reset ( ) ;
2013-06-26 14:18:27 +03:00
CArtPlace * ap = nullptr ;
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : commonInfo - > participants )
2011-01-06 22:00:19 +02:00
{
2012-04-14 05:20:22 +03:00
if ( dst . isHolder ( aoh - > curHero ) )
2011-01-06 22:00:19 +02:00
{
commonInfo - > src . AOH = aoh ;
2011-02-20 11:24:53 +02:00
if ( ( ap = aoh - > getArtPlace ( dst . slot ) ) )
2011-01-06 22:00:19 +02:00
break ;
}
}
if ( ap )
{
ap - > select ( ) ;
}
else
{
2011-01-18 20:56:14 +02:00
commonInfo - > src . art = dst . getArt ( ) ;
commonInfo - > src . slotID = dst . slot ;
2011-01-06 22:00:19 +02:00
assert ( commonInfo - > src . AOH ) ;
2012-12-14 18:32:53 +03:00
CCS - > curh - > dragAndDropCursor ( new CAnimImage ( " artifact " , dst . getArt ( ) - > artType - > iconIndex ) ) ;
2011-01-06 22:00:19 +02:00
markPossibleSlots ( dst . getArt ( ) ) ;
}
}
2012-01-12 18:23:00 +03:00
else if ( src . slot > = GameConstants : : BACKPACK_START & &
2011-07-02 18:12:35 +03:00
src . slot < commonInfo - > src . slotID & &
2012-04-14 05:20:22 +03:00
src . isHolder ( commonInfo - > src . AOH - > curHero ) ) //artifact taken from before currently picked one
2011-01-18 20:56:14 +02:00
{
2011-03-20 00:27:05 +02:00
//int fixedSlot = src.hero->getArtPos(commonInfo->src.art);
2013-02-07 02:24:43 +03:00
vstd : : advance ( commonInfo - > src . slotID , - 1 ) ;
2011-01-18 20:56:14 +02:00
assert ( commonInfo - > src . valid ( ) ) ;
}
2011-01-06 22:00:19 +02:00
else
{
2011-07-03 04:03:46 +03:00
//when moving one artifact onto another it leads to two art movements: dst->backapck; src->dst
// however after first movement we pick the art from backpack and the second movement coming when
// we have a different artifact may look surprising... but it's valid.
2011-01-06 22:00:19 +02:00
}
2011-01-15 04:17:56 +02:00
2011-07-03 04:03:46 +03:00
updateParentWindow ( ) ;
2011-01-28 04:11:58 +02:00
int shift = 0 ;
// if(dst.slot >= Arts::BACKPACK_START && dst.slot - Arts::BACKPACK_START < backpackPos)
// shift++;
2012-01-12 18:23:00 +03:00
//
2011-12-14 00:23:17 +03:00
if ( src . slot < GameConstants : : BACKPACK_START & & dst . slot - GameConstants : : BACKPACK_START < backpackPos )
2011-01-28 04:11:58 +02:00
shift + + ;
2011-12-14 00:23:17 +03:00
if ( dst . slot < GameConstants : : BACKPACK_START & & src . slot - GameConstants : : BACKPACK_START < backpackPos )
2011-01-28 04:11:58 +02:00
shift - - ;
2012-04-14 05:20:22 +03:00
if ( ( isCurHeroSrc & & src . slot > = GameConstants : : BACKPACK_START )
| | ( isCurHeroDst & & dst . slot > = GameConstants : : BACKPACK_START ) )
2011-01-28 04:11:58 +02:00
scrollBackpack ( shift ) ; //update backpack slots
2011-01-06 22:00:19 +02:00
}
2011-04-23 00:51:10 +03:00
void CArtifactsOfHero : : artifactRemoved ( const ArtifactLocation & al )
{
2012-04-14 05:20:22 +03:00
if ( al . isHolder ( curHero ) )
2011-04-23 00:51:10 +03:00
{
2011-12-14 00:23:17 +03:00
if ( al . slot < GameConstants : : BACKPACK_START )
2011-04-23 00:51:10 +03:00
updateWornSlots ( 0 ) ;
else
scrollBackpack ( 0 ) ; //update backpack slots
}
}
2011-01-06 22:00:19 +02:00
CArtPlace * CArtifactsOfHero : : getArtPlace ( int slot )
{
2011-12-14 00:23:17 +03:00
if ( slot < GameConstants : : BACKPACK_START )
2011-01-06 22:00:19 +02:00
{
return artWorn [ slot ] ;
}
else
{
2013-06-29 16:05:48 +03:00
for ( CArtPlace * ap : backpack )
2011-01-06 22:00:19 +02:00
if ( ap - > slotID = = slot )
return ap ;
}
2013-06-26 14:18:27 +03:00
return nullptr ;
2010-12-29 23:04:22 +02:00
}
2011-01-24 01:49:17 +02:00
void CArtifactsOfHero : : artifactAssembled ( const ArtifactLocation & al )
{
2012-04-14 05:20:22 +03:00
if ( al . isHolder ( curHero ) )
2011-01-24 01:49:17 +02:00
updateWornSlots ( ) ;
}
void CArtifactsOfHero : : artifactDisassembled ( const ArtifactLocation & al )
{
2012-04-14 05:20:22 +03:00
if ( al . isHolder ( curHero ) )
2011-01-24 01:49:17 +02:00
updateWornSlots ( ) ;
}
2011-02-27 21:58:14 +02:00
void CArtifactsOfHero : : updateWornSlots ( bool redrawParent /*= true*/ )
2011-01-24 01:49:17 +02:00
{
2011-07-02 18:12:35 +03:00
for ( int i = 0 ; i < artWorn . size ( ) ; i + + )
2013-02-12 22:49:40 +03:00
updateSlot ( ArtifactPosition ( i ) ) ;
2011-04-23 00:51:10 +03:00
2011-01-24 01:49:17 +02:00
2011-02-27 21:58:14 +02:00
if ( redrawParent )
updateParentWindow ( ) ;
}
const CGHeroInstance * CArtifactsOfHero : : getHero ( ) const
{
return curHero ;
2011-01-24 01:49:17 +02:00
}
2013-02-12 22:49:40 +03:00
void CArtifactsOfHero : : updateSlot ( ArtifactPosition slotID )
2011-04-23 00:51:10 +03:00
{
setSlotData ( getArtPlace ( slotID ) , slotID ) ;
}
2009-06-19 15:10:36 +03:00
void CExchangeWindow : : questlog ( int whichHero )
{
2013-06-26 14:18:27 +03:00
CCS - > curh - > dragAndDropCursor ( nullptr ) ;
2009-06-16 14:18:14 +03:00
}
2009-06-28 16:49:39 +03:00
void CExchangeWindow : : prepareBackground ( )
2009-06-16 14:18:14 +03:00
{
2009-06-17 12:38:03 +03:00
//printing heroes' names and levels
2012-06-15 20:08:19 +03:00
auto genTitle = [ ] ( const CGHeroInstance * h )
{
return boost : : str ( boost : : format ( CGI - > generaltexth - > allTexts [ 138 ] )
% h - > name % h - > level % h - > type - > heroClass - > name ) ;
} ;
2012-11-11 15:23:31 +03:00
new CLabel ( 147 , 25 , FONT_SMALL , CENTER , Colors : : WHITE , genTitle ( heroInst [ 0 ] ) ) ;
new CLabel ( 653 , 25 , FONT_SMALL , CENTER , Colors : : WHITE , genTitle ( heroInst [ 1 ] ) ) ;
2009-06-17 12:38:03 +03:00
2009-06-19 15:10:36 +03:00
//printing primary skills
2009-06-17 12:38:03 +03:00
for ( int g = 0 ; g < 4 ; + + g )
2012-06-15 20:08:19 +03:00
new CAnimImage ( " PSKIL32 " , g , 0 , 385 , 19 + 36 * g ) ;
2009-06-17 19:46:16 +03:00
2009-06-19 15:10:36 +03:00
//heroes related thing
for ( int b = 0 ; b < ARRAY_COUNT ( heroInst ) ; b + + )
2009-06-17 19:46:16 +03:00
{
2011-02-27 21:58:14 +02:00
CHeroWithMaybePickedArtifact heroWArt = CHeroWithMaybePickedArtifact ( this , heroInst [ b ] ) ;
2009-06-17 19:46:16 +03:00
//printing primary skills' amounts
2013-02-06 13:16:44 +03:00
for ( int m = 0 ; m < GameConstants : : PRIMARY_SKILLS ; + + m )
2012-11-11 15:23:31 +03:00
new CLabel ( 352 + 93 * b , 35 + 36 * m , FONT_SMALL , CENTER , Colors : : WHITE ,
2013-02-06 13:16:44 +03:00
boost : : lexical_cast < std : : string > ( heroWArt . getPrimSkillLevel ( static_cast < PrimarySkill : : PrimarySkill > ( m ) ) ) ) ;
2009-06-17 19:46:16 +03:00
//printing secondary skills
2009-06-19 15:10:36 +03:00
for ( int m = 0 ; m < heroInst [ b ] - > secSkills . size ( ) ; + + m )
2009-06-17 19:46:16 +03:00
{
2012-06-15 20:08:19 +03:00
int id = heroInst [ b ] - > secSkills [ m ] . first ;
int level = heroInst [ b ] - > secSkills [ m ] . second ;
new CAnimImage ( " SECSK32 " , id * 3 + level + 2 , 0 , 32 + 36 * m + 454 * b , 88 ) ;
2009-06-17 19:46:16 +03:00
}
2009-06-19 15:10:36 +03:00
2009-06-28 16:49:39 +03:00
//hero's specialty
2012-12-16 16:47:53 +03:00
new CAnimImage ( " UN32 " , heroInst [ b ] - > type - > imageIndex , 0 , 67 + 490 * b , 45 ) ;
2009-06-28 16:49:39 +03:00
//experience
2012-06-15 20:08:19 +03:00
new CAnimImage ( " PSKIL32 " , 4 , 0 , 103 + 490 * b , 45 ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 119 + 490 * b , 71 , FONT_SMALL , CENTER , Colors : : WHITE , makeNumberShort ( heroInst [ b ] - > exp ) ) ;
2009-06-28 16:49:39 +03:00
//mana points
2012-06-15 20:08:19 +03:00
new CAnimImage ( " PSKIL32 " , 5 , 0 , 139 + 490 * b , 45 ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 155 + 490 * b , 71 , FONT_SMALL , CENTER , Colors : : WHITE , makeNumberShort ( heroInst [ b ] - > mana ) ) ;
2009-06-28 16:49:39 +03:00
}
//printing portraits
2012-06-15 20:08:19 +03:00
new CAnimImage ( " PortraitsLarge " , heroInst [ 0 ] - > portrait , 0 , 257 , 13 ) ;
new CAnimImage ( " PortraitsLarge " , heroInst [ 1 ] - > portrait , 0 , 485 , 13 ) ;
2009-06-28 16:49:39 +03:00
}
2013-05-27 13:53:28 +03:00
CExchangeWindow : : CExchangeWindow ( ObjectInstanceID hero1 , ObjectInstanceID hero2 , QueryID queryID ) :
2012-06-17 01:40:28 +03:00
CWindowObject ( PLAYER_COLORED | BORDERED , " TRADE2 " )
2009-06-28 16:49:39 +03:00
{
2011-11-27 16:14:20 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2011-05-03 06:14:18 +03:00
heroInst [ 0 ] = LOCPLINT - > cb - > getHero ( hero1 ) ;
heroInst [ 1 ] = LOCPLINT - > cb - > getHero ( hero2 ) ;
2009-06-28 16:49:39 +03:00
2009-07-27 20:55:56 +03:00
prepareBackground ( ) ;
2012-02-21 17:08:42 +03:00
artifs [ 0 ] = new CArtifactsOfHero ( Point ( - 334 , 150 ) ) ;
2009-07-26 18:37:27 +03:00
artifs [ 0 ] - > commonInfo = new CArtifactsOfHero : : SCommonPart ;
2009-11-28 21:55:40 +02:00
artifs [ 0 ] - > commonInfo - > participants . insert ( artifs [ 0 ] ) ;
artifs [ 0 ] - > setHero ( heroInst [ 0 ] ) ;
2012-02-21 17:08:42 +03:00
artifs [ 1 ] = new CArtifactsOfHero ( Point ( 96 , 150 ) ) ;
2009-07-26 18:37:27 +03:00
artifs [ 1 ] - > commonInfo = artifs [ 0 ] - > commonInfo ;
2009-11-28 21:55:40 +02:00
artifs [ 1 ] - > commonInfo - > participants . insert ( artifs [ 1 ] ) ;
2009-06-28 16:49:39 +03:00
artifs [ 1 ] - > setHero ( heroInst [ 1 ] ) ;
2011-01-15 04:17:56 +02:00
artSets . push_back ( artifs [ 0 ] ) ;
artSets . push_back ( artifs [ 1 ] ) ;
2009-06-28 16:49:39 +03:00
//primary skills
for ( int g = 0 ; g < 4 ; + + g )
{
//primary skill's clickable areas
primSkillAreas . push_back ( new LRClickableAreaWTextComp ( ) ) ;
2012-06-15 20:08:19 +03:00
primSkillAreas [ g ] - > pos = genRect ( 32 , 140 , pos . x + 329 , pos . y + 19 + 36 * g ) ;
2009-06-28 16:49:39 +03:00
primSkillAreas [ g ] - > text = CGI - > generaltexth - > arraytxt [ 2 + g ] ;
primSkillAreas [ g ] - > type = g ;
2010-07-13 08:25:40 +03:00
primSkillAreas [ g ] - > bonusValue = - 1 ;
2010-02-01 01:30:47 +02:00
primSkillAreas [ g ] - > baseType = 0 ;
2014-02-26 20:32:42 +03:00
primSkillAreas [ g ] - > hoverText = CGI - > generaltexth - > heroscrn [ 1 ] ;
boost : : replace_first ( primSkillAreas [ g ] - > hoverText , " %s " , CGI - > generaltexth - > primarySkillNames [ g ] ) ;
2009-06-28 16:49:39 +03:00
}
//heroes related thing
for ( int b = 0 ; b < ARRAY_COUNT ( heroInst ) ; b + + )
{
2009-06-19 15:10:36 +03:00
//secondary skill's clickable areas
for ( int g = 0 ; g < heroInst [ b ] - > secSkills . size ( ) ; + + g )
{
2009-11-13 18:02:25 +02:00
int skill = heroInst [ b ] - > secSkills [ g ] . first ,
level = heroInst [ b ] - > secSkills [ g ] . second ; // <1, 3>
2009-06-19 15:10:36 +03:00
secSkillAreas [ b ] . push_back ( new LRClickableAreaWTextComp ( ) ) ;
2012-06-15 20:08:19 +03:00
secSkillAreas [ b ] [ g ] - > pos = genRect ( 32 , 32 , pos . x + 32 + g * 36 + b * 454 , pos . y + 88 ) ;
2009-06-19 15:10:36 +03:00
secSkillAreas [ b ] [ g ] - > baseType = 1 ;
2009-11-13 18:02:25 +02:00
secSkillAreas [ b ] [ g ] - > type = skill ;
2010-07-13 08:25:40 +03:00
secSkillAreas [ b ] [ g ] - > bonusValue = level ;
2009-11-13 18:02:25 +02:00
secSkillAreas [ b ] [ g ] - > text = CGI - > generaltexth - > skillInfoTexts [ skill ] [ level - 1 ] ;
2009-06-19 15:10:36 +03:00
2014-02-26 20:32:42 +03:00
secSkillAreas [ b ] [ g ] - > hoverText = CGI - > generaltexth - > heroscrn [ 21 ] ;
boost : : algorithm : : replace_first ( secSkillAreas [ b ] [ g ] - > hoverText , " %s " , CGI - > generaltexth - > levels [ level - 1 ] ) ;
boost : : algorithm : : replace_first ( secSkillAreas [ b ] [ g ] - > hoverText , " %s " , CGI - > generaltexth - > skillName [ skill ] ) ;
2009-06-19 15:10:36 +03:00
}
2010-02-01 01:30:47 +02:00
2012-02-21 17:08:42 +03:00
portrait [ b ] = new CHeroArea ( 257 + 228 * b , 13 , heroInst [ b ] ) ;
2010-02-01 01:30:47 +02:00
2013-01-17 21:15:00 +03:00
specialty [ b ] = new LRClickableAreaWText ( ) ;
specialty [ b ] - > pos = genRect ( 32 , 32 , pos . x + 69 + 490 * b , pos . y + 45 ) ;
specialty [ b ] - > hoverText = CGI - > generaltexth - > heroscrn [ 27 ] ;
specialty [ b ] - > text = heroInst [ b ] - > type - > specDescr ;
2010-02-01 01:22:25 +02:00
experience [ b ] = new LRClickableAreaWText ( ) ;
2012-06-15 20:08:19 +03:00
experience [ b ] - > pos = genRect ( 32 , 32 , pos . x + 105 + 490 * b , pos . y + 45 ) ;
2010-02-01 01:30:47 +02:00
experience [ b ] - > hoverText = CGI - > generaltexth - > heroscrn [ 9 ] ;
2010-02-01 01:22:25 +02:00
experience [ b ] - > text = CGI - > generaltexth - > allTexts [ 2 ] . c_str ( ) ;
2014-02-26 20:32:42 +03:00
boost : : algorithm : : replace_first ( experience [ b ] - > text , " %d " , boost : : lexical_cast < std : : string > ( heroInst [ b ] - > level ) ) ;
boost : : algorithm : : replace_first ( experience [ b ] - > text , " %d " , boost : : lexical_cast < std : : string > ( CGI - > heroh - > reqExp ( heroInst [ b ] - > level + 1 ) ) ) ;
boost : : algorithm : : replace_first ( experience [ b ] - > text , " %d " , boost : : lexical_cast < std : : string > ( heroInst [ b ] - > exp ) ) ;
2010-02-01 01:30:47 +02:00
2010-02-01 01:22:25 +02:00
spellPoints [ b ] = new LRClickableAreaWText ( ) ;
2012-06-15 20:08:19 +03:00
spellPoints [ b ] - > pos = genRect ( 32 , 32 , pos . x + 141 + 490 * b , pos . y + 45 ) ;
2010-02-01 01:30:47 +02:00
spellPoints [ b ] - > hoverText = CGI - > generaltexth - > heroscrn [ 22 ] ;
2014-02-26 20:32:42 +03:00
spellPoints [ b ] - > text = CGI - > generaltexth - > allTexts [ 205 ] ;
boost : : algorithm : : replace_first ( spellPoints [ b ] - > text , " %s " , heroInst [ b ] - > name ) ;
boost : : algorithm : : replace_first ( spellPoints [ b ] - > text , " %d " , boost : : lexical_cast < std : : string > ( heroInst [ b ] - > mana ) ) ;
boost : : algorithm : : replace_first ( spellPoints [ b ] - > text , " %d " , boost : : lexical_cast < std : : string > ( heroInst [ b ] - > manaLimit ( ) ) ) ;
2009-06-19 15:10:36 +03:00
2009-06-26 18:41:19 +03:00
//setting morale
2012-02-21 17:08:42 +03:00
morale [ b ] = new MoraleLuckBox ( true , genRect ( 32 , 32 , 176 + 490 * b , 39 ) , true ) ;
2010-07-13 08:25:40 +03:00
morale [ b ] - > set ( heroInst [ b ] ) ;
2009-06-26 18:41:19 +03:00
//setting luck
2012-02-21 17:08:42 +03:00
luck [ b ] = new MoraleLuckBox ( false , genRect ( 32 , 32 , 212 + 490 * b , 39 ) , true ) ;
2010-07-13 08:25:40 +03:00
luck [ b ] - > set ( heroInst [ b ] ) ;
2009-06-17 19:46:16 +03:00
}
2009-06-17 12:38:03 +03:00
//buttons
2013-07-02 18:23:32 +03:00
quit = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 600 ] , boost : : bind ( & CExchangeWindow : : close , this ) , 732 , 567 , " IOKAY.DEF " , SDLK_RETURN ) ;
2013-05-27 13:53:28 +03:00
if ( queryID . getNum ( ) > 0 )
quit - > callback + = [ = ] { LOCPLINT - > cb - > selectionMade ( 0 , queryID ) ; } ;
2013-07-02 18:23:32 +03:00
questlogButton [ 0 ] = new CAdventureMapButton ( CGI - > generaltexth - > heroscrn [ 0 ] , " " , boost : : bind ( & CExchangeWindow : : questlog , this , 0 ) , 10 , 44 , " hsbtns4.def " ) ;
questlogButton [ 1 ] = new CAdventureMapButton ( CGI - > generaltexth - > heroscrn [ 0 ] , " " , boost : : bind ( & CExchangeWindow : : questlog , this , 1 ) , 740 , 44 , " hsbtns4.def " ) ;
2009-06-19 15:10:36 +03:00
2012-02-21 17:08:42 +03:00
Rect barRect ( 5 , 578 , 725 , 18 ) ;
ourBar = new CGStatusBar ( new CPicture ( * background , barRect , 5 , 578 , false ) ) ;
2009-06-19 15:10:36 +03:00
2009-06-28 11:21:50 +03:00
//garrison interface
2012-02-21 17:08:42 +03:00
garr = new CGarrisonInt ( 69 , 131 , 4 , Point ( 418 , 0 ) , * background , Point ( 69 , 131 ) , heroInst [ 0 ] , heroInst [ 1 ] , true , true ) ;
2013-07-02 18:23:32 +03:00
garr - > addSplitBtn ( new CAdventureMapButton ( CGI - > generaltexth - > tcommands [ 3 ] , " " , boost : : bind ( & CGarrisonInt : : splitClick , garr ) , 10 , 132 , " TSBTNS.DEF " ) ) ;
garr - > addSplitBtn ( new CAdventureMapButton ( CGI - > generaltexth - > tcommands [ 3 ] , " " , boost : : bind ( & CGarrisonInt : : splitClick , garr ) , 740 , 132 , " TSBTNS.DEF " ) ) ;
2009-06-16 14:18:14 +03:00
}
CExchangeWindow : : ~ CExchangeWindow ( ) //d-tor
{
2009-07-26 18:37:27 +03:00
delete artifs [ 0 ] - > commonInfo ;
2013-06-26 14:18:27 +03:00
artifs [ 0 ] - > commonInfo = nullptr ;
artifs [ 1 ] - > commonInfo = nullptr ;
2009-06-18 18:05:00 +03:00
}
2013-06-26 14:18:27 +03:00
CShipyardWindow : : CShipyardWindow ( const std : : vector < si32 > & cost , int state , int boatType , const std : : function < void ( ) > & onBuy ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " TPSHIP " )
2009-07-26 06:33:13 +03:00
{
2011-09-23 18:58:18 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2009-07-26 06:33:13 +03:00
2011-09-23 18:58:18 +03:00
bgWater = new CPicture ( " TPSHIPBK " , 100 , 69 ) ;
2009-07-26 06:33:13 +03:00
2011-09-23 18:58:18 +03:00
std : : string boatFilenames [ 3 ] = { " AB01_ " , " AB02_ " , " AB03_ " } ;
2009-07-26 06:33:13 +03:00
2011-12-22 16:05:19 +03:00
Point waterCenter = Point ( bgWater - > pos . x + bgWater - > pos . w / 2 , bgWater - > pos . y + bgWater - > pos . h / 2 ) ;
2011-09-23 18:58:18 +03:00
bgShip = new CAnimImage ( boatFilenames [ boatType ] , 0 , 7 , 120 , 96 , CShowableAnim : : USE_RLE ) ;
bgShip - > center ( waterCenter ) ;
2009-06-18 18:05:00 +03:00
2011-09-23 18:58:18 +03:00
// Create resource icons and costs.
std : : string goldValue = boost : : lexical_cast < std : : string > ( cost [ Res : : GOLD ] ) ;
std : : string woodValue = boost : : lexical_cast < std : : string > ( cost [ Res : : WOOD ] ) ;
2009-07-26 06:33:13 +03:00
2012-11-11 15:23:31 +03:00
goldCost = new CLabel ( 118 , 294 , FONT_SMALL , CENTER , Colors : : WHITE , goldValue ) ;
woodCost = new CLabel ( 212 , 294 , FONT_SMALL , CENTER , Colors : : WHITE , woodValue ) ;
2011-09-23 18:58:18 +03:00
goldPic = new CAnimImage ( " RESOURCE " , Res : : GOLD , 0 , 100 , 244 ) ;
woodPic = new CAnimImage ( " RESOURCE " , Res : : WOOD , 0 , 196 , 244 ) ;
2009-07-26 06:33:13 +03:00
2013-07-02 18:23:32 +03:00
quit = new CAdventureMapButton ( CGI - > generaltexth - > allTexts [ 599 ] , " " , boost : : bind ( & CShipyardWindow : : close , this ) , 224 , 312 , " ICANCEL " , SDLK_RETURN ) ;
build = new CAdventureMapButton ( CGI - > generaltexth - > allTexts [ 598 ] , " " , boost : : bind ( & CShipyardWindow : : close , this ) , 42 , 312 , " IBUY30 " , SDLK_RETURN ) ;
2011-09-23 18:58:18 +03:00
build - > callback + = onBuy ;
2009-08-17 20:19:09 +03:00
2013-02-09 15:56:35 +03:00
for ( Res : : ERes i = Res : : WOOD ; i < = Res : : GOLD ; vstd : : advance ( i , 1 ) )
2009-07-26 06:33:13 +03:00
{
if ( cost [ i ] > LOCPLINT - > cb - > getResourceAmount ( i ) )
{
2011-09-23 18:58:18 +03:00
build - > block ( true ) ;
2009-07-26 06:33:13 +03:00
break ;
}
}
2012-06-16 13:41:14 +03:00
statusBar = new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2009-07-26 06:33:13 +03:00
2012-11-11 15:23:31 +03:00
title = new CLabel ( 164 , 27 , FONT_BIG , CENTER , Colors : : YELLOW , CGI - > generaltexth - > jktexts [ 13 ] ) ;
costLabel = new CLabel ( 164 , 220 , FONT_MEDIUM , CENTER , Colors : : WHITE , CGI - > generaltexth - > jktexts [ 14 ] ) ;
2009-07-26 06:33:13 +03:00
}
2009-08-31 18:57:15 +03:00
2012-06-15 20:08:19 +03:00
CPuzzleWindow : : CPuzzleWindow ( const int3 & GrailPos , double discoveredRatio ) :
CWindowObject ( PLAYER_COLORED | BORDERED , " PUZZLE " ) ,
grailPos ( GrailPos ) ,
currentAlpha ( SDL_ALPHA_OPAQUE )
2009-08-31 18:57:15 +03:00
{
2012-06-15 20:08:19 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
CCS - > soundh - > playSound ( soundBase : : OBELISK ) ;
2013-07-02 18:23:32 +03:00
quitb = new CAdventureMapButton ( CGI - > generaltexth - > allTexts [ 599 ] , " " , boost : : bind ( & CPuzzleWindow : : close , this ) , 670 , 538 , " IOK6432.DEF " , SDLK_RETURN ) ;
2011-03-19 02:06:54 +02:00
quitb - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2012-11-20 20:53:45 +03:00
quitb - > borderColor = Colors : : METALLIC_GOLD ;
2011-04-30 22:52:35 +03:00
quitb - > borderEnabled = true ;
2011-03-19 02:06:54 +02:00
2012-06-15 20:08:19 +03:00
new CPicture ( " PUZZLOGO " , 607 , 3 ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 700 , 95 , FONT_BIG , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 463 ] ) ;
2013-05-04 16:14:23 +03:00
new CResDataBar ( " ARESBAR.bmp " , 3 , 575 , 32 , 2 , 85 , 85 ) ;
2010-02-18 16:09:16 +02:00
2010-08-03 14:36:52 +03:00
int faction = LOCPLINT - > cb - > getStartInfo ( ) - > playerInfos . find ( LOCPLINT - > playerID ) - > second . castle ;
2009-08-31 18:57:15 +03:00
2013-04-21 15:49:26 +03:00
auto & puzzleMap = CGI - > townh - > factions [ faction ] - > puzzleMap ;
2012-09-21 00:28:18 +03:00
2013-06-29 16:05:48 +03:00
for ( auto & elem : puzzleMap )
2009-08-31 18:57:15 +03:00
{
2013-06-29 16:05:48 +03:00
const SPuzzleInfo & info = elem ;
2009-08-31 18:57:15 +03:00
2013-06-29 16:05:48 +03:00
auto piece = new CPicture ( info . filename , info . x , info . y ) ;
2009-08-31 18:57:15 +03:00
2012-06-15 20:08:19 +03:00
//piece that will slowly disappear
2013-04-28 18:06:14 +03:00
if ( info . whenUncovered < = GameConstants : : PUZZLE_MAP_PIECES * discoveredRatio )
2012-06-15 20:08:19 +03:00
{
piecesToRemove . push_back ( piece ) ;
piece - > needRefresh = true ;
piece - > recActions = piece - > recActions & ~ SHOWALL ;
}
2009-08-31 18:57:15 +03:00
}
}
2012-06-15 20:08:19 +03:00
void CPuzzleWindow : : showAll ( SDL_Surface * to )
2009-08-31 18:57:15 +03:00
{
2012-06-15 20:08:19 +03:00
int3 moveInt = int3 ( 8 , 9 , 0 ) ;
Rect mapRect = genRect ( 544 , 591 , pos . x + 8 , pos . y + 7 ) ;
2009-08-31 18:57:15 +03:00
2012-06-15 20:08:19 +03:00
CGI - > mh - > terrainRect
( grailPos - moveInt , adventureInt - > anim ,
& LOCPLINT - > cb - > getVisibilityMap ( ) , true , adventureInt - > heroAnim ,
to , & mapRect , 0 , 0 , true , moveInt ) ;
2009-08-31 18:57:15 +03:00
2012-06-15 20:08:19 +03:00
CWindowObject : : showAll ( to ) ;
2009-08-31 18:57:15 +03:00
}
void CPuzzleWindow : : show ( SDL_Surface * to )
{
2012-06-15 20:08:19 +03:00
static int animSpeed = 2 ;
2009-08-31 18:57:15 +03:00
2012-06-15 20:08:19 +03:00
if ( currentAlpha < animSpeed )
2009-08-31 18:57:15 +03:00
{
2012-06-15 20:08:19 +03:00
//animation done
2013-06-29 16:05:48 +03:00
for ( auto & piece : piecesToRemove )
2012-06-15 20:08:19 +03:00
delete piece ;
piecesToRemove . clear ( ) ;
2009-08-31 18:57:15 +03:00
}
2012-06-15 20:08:19 +03:00
else
{
//update disappearing puzzles
2013-06-29 16:05:48 +03:00
for ( auto & piece : piecesToRemove )
2012-06-15 20:08:19 +03:00
piece - > setAlpha ( currentAlpha ) ;
currentAlpha - = animSpeed ;
}
CWindowObject : : show ( to ) ;
2009-08-31 18:57:15 +03:00
}
2009-09-21 12:00:33 +03:00
2010-07-03 15:00:53 +03:00
void CTransformerWindow : : CItem : : move ( )
{
if ( left )
2012-05-13 18:04:21 +03:00
moveBy ( Point ( 289 , 0 ) ) ;
2010-07-03 15:00:53 +03:00
else
2012-05-13 18:04:21 +03:00
moveBy ( Point ( - 289 , 0 ) ) ;
2010-07-03 15:00:53 +03:00
left = ! left ;
}
void CTransformerWindow : : CItem : : clickLeft ( tribool down , bool previousState )
{
if ( previousState & & ( ! down ) )
{
move ( ) ;
parent - > showAll ( screen2 ) ;
}
}
2012-06-17 01:40:28 +03:00
void CTransformerWindow : : CItem : : update ( )
{
2013-02-16 17:03:47 +03:00
icon - > setFrame ( parent - > army - > getCreature ( SlotID ( id ) ) - > idNumber + 2 ) ;
2012-06-17 01:40:28 +03:00
}
2012-09-26 16:13:39 +03:00
CTransformerWindow : : CItem : : CItem ( CTransformerWindow * parent , int size , int id ) :
id ( id ) , size ( size ) , parent ( parent )
2010-07-03 15:00:53 +03:00
{
2012-05-13 18:04:21 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK ) ;
2010-07-20 09:05:45 +03:00
left = true ;
2010-07-03 15:00:53 +03:00
pos . w = 58 ;
pos . h = 64 ;
2012-01-12 18:23:00 +03:00
2010-07-03 15:00:53 +03:00
pos . x + = 45 + ( id % 3 ) * 83 + id / 6 * 83 ;
pos . y + = 109 + ( id / 3 ) * 98 ;
2013-02-16 17:03:47 +03:00
icon = new CAnimImage ( " TWCRPORT " , parent - > army - > getCreature ( SlotID ( id ) ) - > idNumber + 2 ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 28 , 76 , FONT_SMALL , CENTER , Colors : : WHITE , boost : : lexical_cast < std : : string > ( size ) ) ; //stack size
2010-07-03 15:00:53 +03:00
}
void CTransformerWindow : : makeDeal ( )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : items )
if ( ! elem - > left )
LOCPLINT - > cb - > trade ( town , EMarketMode : : CREATURE_UNDEAD , elem - > id , 0 , 0 , hero ) ;
2010-07-03 15:00:53 +03:00
}
void CTransformerWindow : : addAll ( )
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : items )
if ( elem - > left )
elem - > move ( ) ;
2010-07-03 15:00:53 +03:00
showAll ( screen2 ) ;
}
2012-06-17 01:40:28 +03:00
void CTransformerWindow : : updateGarrisons ( )
{
2013-06-29 16:05:48 +03:00
for ( auto & item : items )
2012-06-17 01:40:28 +03:00
{
item - > update ( ) ;
}
}
2012-06-15 20:08:19 +03:00
CTransformerWindow : : CTransformerWindow ( const CGHeroInstance * _hero , const CGTownInstance * _town ) :
CWindowObject ( PLAYER_COLORED , " SKTRNBK " ) ,
hero ( _hero ) ,
town ( _town )
2010-07-03 15:00:53 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
if ( hero )
army = hero ;
else
army = town ;
2012-01-12 18:23:00 +03:00
2013-02-16 17:03:47 +03:00
for ( int i = 0 ; i < GameConstants : : ARMY_SIZE ; i + + )
if ( army - > getCreature ( SlotID ( i ) ) )
items . push_back ( new CItem ( this , army - > getStackCount ( SlotID ( i ) ) , i ) ) ;
2012-01-12 18:23:00 +03:00
2013-07-02 18:23:32 +03:00
all = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 590 ] , boost : : bind ( & CTransformerWindow : : addAll , this ) , 146 , 416 , " ALTARMY.DEF " , SDLK_a ) ;
convert = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 591 ] , boost : : bind ( & CTransformerWindow : : makeDeal , this ) , 269 , 416 , " ALTSACR.DEF " , SDLK_RETURN ) ;
cancel = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 592 ] , boost : : bind ( & CTransformerWindow : : close , this ) , 392 , 416 , " ICANCEL.DEF " , SDLK_ESCAPE ) ;
2012-06-16 13:41:14 +03:00
bar = new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2012-06-17 01:40:28 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 153 , 29 , FONT_SMALL , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 485 ] ) ; //holding area
new CLabel ( 153 + 295 , 29 , FONT_SMALL , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 486 ] ) ; //transformer
new CTextBox ( CGI - > generaltexth - > allTexts [ 487 ] , Rect ( 26 , 56 , 255 , 40 ) , 0 , FONT_MEDIUM , CENTER , Colors : : YELLOW ) ; //move creatures to create skeletons
new CTextBox ( CGI - > generaltexth - > allTexts [ 488 ] , Rect ( 320 , 56 , 255 , 40 ) , 0 , FONT_MEDIUM , CENTER , Colors : : YELLOW ) ; //creatures here will become skeletons
2012-06-17 01:40:28 +03:00
2010-07-03 15:00:53 +03:00
}
2010-07-20 17:08:13 +03:00
void CUniversityWindow : : CItem : : clickLeft ( tribool down , bool previousState )
{
if ( previousState & & ( ! down ) )
{
if ( state ( ) ! = 2 )
return ;
2013-06-29 16:05:48 +03:00
auto win = new CUnivConfirmWindow ( parent , ID , LOCPLINT - > cb - > getResourceAmount ( Res : : GOLD ) > = 2000 ) ;
2010-07-20 17:08:13 +03:00
GH . pushInt ( win ) ;
}
}
void CUniversityWindow : : CItem : : clickRight ( tribool down , bool previousState )
{
if ( down )
{
2012-12-11 15:12:46 +03:00
CRClickPopup : : createAndPush ( CGI - > generaltexth - > skillInfoTexts [ ID ] [ 0 ] ,
2013-03-14 23:44:00 +03:00
new CComponent ( CComponent : : secskill , ID , 1 ) ) ;
2010-07-20 17:08:13 +03:00
}
}
void CUniversityWindow : : CItem : : hover ( bool on )
{
if ( on )
2013-08-29 16:46:27 +03:00
GH . statusbar - > setText ( CGI - > generaltexth - > skillName [ ID ] ) ;
2010-07-20 17:08:13 +03:00
else
GH . statusbar - > clear ( ) ;
}
int CUniversityWindow : : CItem : : state ( )
{
2013-02-12 22:49:40 +03:00
if ( parent - > hero - > getSecSkillLevel ( SecondarySkill ( ID ) ) ) //hero know this skill
2010-07-20 17:08:13 +03:00
return 1 ;
2012-12-18 14:24:13 +03:00
if ( ! parent - > hero - > canLearnSkill ( ) ) //can't learn more skills
2010-07-20 17:08:13 +03:00
return 0 ;
2012-12-14 18:32:53 +03:00
if ( parent - > hero - > type - > heroClass - > secSkillProbability [ ID ] = = 0 ) //can't learn this skill (like necromancy for most of non-necros)
2010-07-22 03:32:45 +03:00
return 0 ;
2010-07-20 17:08:13 +03:00
return 2 ;
}
void CUniversityWindow : : CItem : : showAll ( SDL_Surface * to )
{
2010-08-06 16:14:10 +03:00
CPicture * bar ;
2010-07-20 17:08:13 +03:00
switch ( state ( ) )
{
case 0 : bar = parent - > red ;
break ;
case 1 : bar = parent - > yellow ;
break ;
case 2 : bar = parent - > green ;
break ;
2013-06-26 14:18:27 +03:00
default : bar = nullptr ;
2011-01-01 22:26:39 +02:00
break ;
2010-07-20 17:08:13 +03:00
}
2011-01-01 22:26:39 +02:00
assert ( bar ) ;
2012-01-12 18:23:00 +03:00
2010-08-06 16:14:10 +03:00
blitAtLoc ( bar - > bg , - 28 , - 22 , to ) ;
blitAtLoc ( bar - > bg , - 28 , 48 , to ) ;
2012-11-11 15:23:31 +03:00
printAtMiddleLoc ( CGI - > generaltexth - > skillName [ ID ] , 22 , - 13 , FONT_SMALL , Colors : : WHITE , to ) ; //Name
printAtMiddleLoc ( CGI - > generaltexth - > levels [ 0 ] , 22 , 57 , FONT_SMALL , Colors : : WHITE , to ) ; //Level(always basic)
2012-01-12 18:23:00 +03:00
2012-06-13 16:04:06 +03:00
CAnimImage : : showAll ( to ) ;
2010-07-20 17:08:13 +03:00
}
2010-08-27 19:20:35 +03:00
CUniversityWindow : : CItem : : CItem ( CUniversityWindow * _parent , int _ID , int X , int Y ) :
2012-06-13 16:04:06 +03:00
CAnimImage ( " SECSKILL " , _ID * 3 + 3 , 0 , X , Y ) ,
2012-05-13 18:04:21 +03:00
ID ( _ID ) ,
parent ( _parent )
2010-07-20 17:08:13 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
2010-07-20 17:08:13 +03:00
}
2012-06-15 20:08:19 +03:00
CUniversityWindow : : CUniversityWindow ( const CGHeroInstance * _hero , const IMarket * _market ) :
CWindowObject ( PLAYER_COLORED , " UNIVERS1 " ) ,
hero ( _hero ) ,
market ( _market )
2010-07-20 17:08:13 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-01-12 18:23:00 +03:00
2010-08-06 16:14:10 +03:00
green = new CPicture ( " UNIVGREN.PCX " ) ;
yellow = new CPicture ( " UNIVGOLD.PCX " ) ; //bars
red = new CPicture ( " UNIVRED.PCX " ) ;
green - > recActions =
yellow - > recActions =
red - > recActions = DISPOSE ;
2010-07-20 17:08:13 +03:00
2012-06-15 20:08:19 +03:00
CIntObject * titlePic = nullptr ;
2012-09-23 21:01:04 +03:00
if ( market - > o - > ID = = Obj : : TOWN )
2013-04-21 15:49:26 +03:00
titlePic = new CAnimImage ( CGI - > townh - > factions [ ETownType : : CONFLUX ] - > town - > clientInfo . buildingsIcons , BuildingID : : MAGIC_UNIVERSITY ) ;
2010-07-20 17:08:13 +03:00
else
2012-12-13 16:07:56 +03:00
titlePic = new CPicture ( " UNIVBLDG " ) ;
2010-07-20 17:08:13 +03:00
2012-12-13 16:07:56 +03:00
titlePic - > center ( Point ( 232 + pos . x , 76 + pos . y ) ) ;
2012-06-15 20:08:19 +03:00
//Clerk speech
2012-11-11 15:23:31 +03:00
new CTextBox ( CGI - > generaltexth - > allTexts [ 603 ] , Rect ( 24 , 129 , 413 , 70 ) , 0 , FONT_SMALL , CENTER , Colors : : WHITE ) ;
2012-06-15 20:08:19 +03:00
//University
2012-11-11 15:23:31 +03:00
new CLabel ( 231 , 26 , FONT_MEDIUM , CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 602 ] ) ;
2010-07-20 17:08:13 +03:00
2011-12-14 00:23:17 +03:00
std : : vector < int > list = market - > availableItemsIds ( EMarketMode : : RESOURCE_SKILL ) ;
2012-06-15 20:08:19 +03:00
assert ( list . size ( ) = = 4 ) ;
2010-07-20 17:08:13 +03:00
for ( int i = 0 ; i < list . size ( ) ; i + + ) //prepare clickable items
2012-06-15 20:08:19 +03:00
items . push_back ( new CItem ( this , list [ i ] , 54 + i * 104 , 234 ) ) ;
2012-01-12 18:23:00 +03:00
2011-12-22 16:05:19 +03:00
cancel = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 632 ] ,
2013-07-02 18:23:32 +03:00
boost : : bind ( & CUniversityWindow : : close , this ) , 200 , 313 , " IOKAY.DEF " , SDLK_RETURN ) ;
2012-01-12 18:23:00 +03:00
2012-06-16 13:41:14 +03:00
bar = new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2010-07-20 17:08:13 +03:00
}
2012-06-15 20:08:19 +03:00
CUnivConfirmWindow : : CUnivConfirmWindow ( CUniversityWindow * PARENT , int SKILL , bool available ) :
CWindowObject ( PLAYER_COLORED , " UNIVERS2.PCX " ) ,
parent ( PARENT )
2010-07-20 17:08:13 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
std : : string text = CGI - > generaltexth - > allTexts [ 608 ] ;
boost : : replace_first ( text , " %s " , CGI - > generaltexth - > levels [ 0 ] ) ;
boost : : replace_first ( text , " %s " , CGI - > generaltexth - > skillName [ SKILL ] ) ;
boost : : replace_first ( text , " %d " , " 2000 " ) ;
2012-11-11 15:23:31 +03:00
new CTextBox ( text , Rect ( 24 , 129 , 413 , 70 ) , 0 , FONT_SMALL , CENTER , Colors : : WHITE ) ; //Clerk speech
2012-06-15 20:08:19 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 230 , 37 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > skillName [ SKILL ] ) ; //Skill name
2012-06-15 20:08:19 +03:00
new CAnimImage ( " SECSKILL " , SKILL * 3 + 3 , 0 , 211 , 51 ) ; //skill
2012-11-11 15:23:31 +03:00
new CLabel ( 230 , 107 , FONT_SMALL , CENTER , Colors : : WHITE , CGI - > generaltexth - > levels [ 1 ] ) ; //Skill level
2010-07-20 17:08:13 +03:00
2012-06-15 20:08:19 +03:00
new CAnimImage ( " RESOURCE " , Res : : GOLD , 0 , 210 , 210 ) ; //gold
2012-11-11 15:23:31 +03:00
new CLabel ( 230 , 267 , FONT_SMALL , CENTER , Colors : : WHITE , " 2000 " ) ; //Cost
2010-07-20 17:08:13 +03:00
std : : string hoverText = CGI - > generaltexth - > allTexts [ 609 ] ;
boost : : replace_first ( hoverText , " %s " , CGI - > generaltexth - > levels [ 0 ] + " " + CGI - > generaltexth - > skillName [ SKILL ] ) ;
2012-01-12 18:23:00 +03:00
2010-07-20 17:08:13 +03:00
text = CGI - > generaltexth - > zelp [ 633 ] . second ;
boost : : replace_first ( text , " %s " , CGI - > generaltexth - > levels [ 0 ] ) ;
boost : : replace_first ( text , " %s " , CGI - > generaltexth - > skillName [ SKILL ] ) ;
boost : : replace_first ( text , " %d " , " 2000 " ) ;
2013-07-02 18:23:32 +03:00
confirm = new CAdventureMapButton ( hoverText , text , boost : : bind ( & CUnivConfirmWindow : : makeDeal , this , SKILL ) ,
2010-07-20 17:08:13 +03:00
148 , 299 , " IBY6432.DEF " , SDLK_RETURN ) ;
confirm - > block ( ! available ) ;
2012-01-12 18:23:00 +03:00
2013-07-02 18:23:32 +03:00
cancel = new CAdventureMapButton ( CGI - > generaltexth - > zelp [ 631 ] , boost : : bind ( & CUnivConfirmWindow : : close , this ) ,
2010-07-20 17:08:13 +03:00
252 , 299 , " ICANCEL.DEF " , SDLK_ESCAPE ) ;
2012-06-16 13:41:14 +03:00
bar = new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2010-07-20 17:08:13 +03:00
}
void CUnivConfirmWindow : : makeDeal ( int skill )
{
2011-12-14 00:23:17 +03:00
LOCPLINT - > cb - > trade ( parent - > market - > o , EMarketMode : : RESOURCE_SKILL , 6 , skill , 1 , parent - > hero ) ;
2012-06-15 20:08:19 +03:00
close ( ) ;
2010-07-20 17:08:13 +03:00
}
2010-07-22 03:32:45 +03:00
CHillFortWindow : : CHillFortWindow ( const CGHeroInstance * visitor , const CGObjectInstance * object ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( PLAYER_COLORED , " APHLFTBK " ) ,
fort ( object ) ,
hero ( visitor )
2010-07-22 03:32:45 +03:00
{
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
slotsCount = 7 ;
resources = CDefHandler : : giveDefEss ( " SMALRES.DEF " ) ;
2012-01-12 18:23:00 +03:00
2012-11-11 15:23:31 +03:00
new CLabel ( 325 , 32 , FONT_BIG , CENTER , Colors : : YELLOW , fort - > hoverName ) ; //Hill Fort
2010-07-22 03:32:45 +03:00
heroPic = new CHeroArea ( 30 , 60 , hero ) ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
currState . resize ( slotsCount + 1 ) ;
costs . resize ( slotsCount ) ;
2011-12-14 00:23:17 +03:00
totalSumm . resize ( GameConstants : : RESOURCE_QUANTITY ) ;
2011-02-20 11:24:53 +02:00
std : : vector < std : : string > files ;
files + = " APHLF1R.DEF " , " APHLF1Y.DEF " , " APHLF1G.DEF " ;
2010-07-22 03:32:45 +03:00
for ( int i = 0 ; i < slotsCount ; i + + )
{
2013-02-16 17:03:47 +03:00
currState [ i ] = getState ( SlotID ( i ) ) ;
2013-07-02 18:23:32 +03:00
upgrade [ i ] = new CAdventureMapButton ( getTextForSlot ( SlotID ( i ) ) , " " , boost : : bind ( & CHillFortWindow : : makeDeal , this , SlotID ( i ) ) ,
2011-02-20 11:24:53 +02:00
107 + i * 76 , 171 , " " , SDLK_1 + i , & files ) ;
2010-07-22 03:32:45 +03:00
upgrade [ i ] - > block ( currState [ i ] = = - 1 ) ;
}
2011-02-20 11:24:53 +02:00
files . clear ( ) ;
files + = " APHLF4R.DEF " , " APHLF4Y.DEF " , " APHLF4G.DEF " ;
2013-02-16 17:03:47 +03:00
currState [ slotsCount ] = getState ( SlotID ( slotsCount ) ) ;
2013-07-02 18:23:32 +03:00
upgradeAll = new CAdventureMapButton ( CGI - > generaltexth - > allTexts [ 432 ] , " " , boost : : bind ( & CHillFortWindow : : makeDeal , this , SlotID ( slotsCount ) ) ,
2011-02-20 11:24:53 +02:00
30 , 231 , " " , SDLK_0 , & files ) ;
2013-07-02 18:23:32 +03:00
quit = new CAdventureMapButton ( " " , " " , boost : : bind ( & CHillFortWindow : : close , this ) , 294 , 275 , " IOKAY.DEF " , SDLK_RETURN ) ;
2012-06-16 13:41:14 +03:00
bar = new CGStatusBar ( new CPicture ( * background , Rect ( 8 , pos . h - 26 , pos . w - 16 , 19 ) , 8 , pos . h - 26 ) ) ;
2010-08-27 19:20:35 +03:00
2013-06-26 14:18:27 +03:00
garr = new CGarrisonInt ( 108 , 60 , 18 , Point ( ) , background - > bg , Point ( 108 , 60 ) , hero , nullptr ) ;
2010-07-22 03:32:45 +03:00
updateGarrisons ( ) ;
}
void CHillFortWindow : : updateGarrisons ( )
{
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : RESOURCE_QUANTITY ; i + + )
2010-07-22 03:32:45 +03:00
totalSumm [ i ] = 0 ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
for ( int i = 0 ; i < slotsCount ; i + + )
{
costs [ i ] . clear ( ) ;
2013-02-16 17:03:47 +03:00
int newState = getState ( SlotID ( i ) ) ;
2010-07-22 03:32:45 +03:00
if ( newState ! = - 1 )
{
2011-05-03 06:14:18 +03:00
UpgradeInfo info ;
2013-02-16 17:03:47 +03:00
LOCPLINT - > cb - > getUpgradeInfo ( hero , SlotID ( i ) , info ) ;
2010-07-22 03:32:45 +03:00
if ( info . newID . size ( ) ) //we have upgrades here - update costs
2011-07-05 09:14:07 +03:00
{
2013-02-16 17:03:47 +03:00
costs [ i ] = info . cost [ 0 ] * hero - > getStackCount ( SlotID ( i ) ) ;
2011-07-05 09:14:07 +03:00
totalSumm + = costs [ i ] ;
}
2010-07-22 03:32:45 +03:00
}
2012-01-12 18:23:00 +03:00
2011-02-20 11:24:53 +02:00
currState [ i ] = newState ;
upgrade [ i ] - > setIndex ( newState ) ;
upgrade [ i ] - > block ( currState [ i ] = = - 1 ) ;
2013-02-16 17:03:47 +03:00
upgrade [ i ] - > hoverTexts [ 0 ] = getTextForSlot ( SlotID ( i ) ) ;
2010-07-22 03:32:45 +03:00
}
2012-01-12 18:23:00 +03:00
2013-02-16 17:03:47 +03:00
int newState = getState ( SlotID ( slotsCount ) ) ;
2011-02-20 11:24:53 +02:00
currState [ slotsCount ] = newState ;
upgradeAll - > setIndex ( newState ) ;
2010-07-22 03:32:45 +03:00
garr - > recreateSlots ( ) ;
}
2013-02-16 17:03:47 +03:00
void CHillFortWindow : : makeDeal ( SlotID slot )
2010-07-22 03:32:45 +03:00
{
2013-02-16 17:03:47 +03:00
assert ( slot . getNum ( ) > = 0 ) ;
int offset = ( slot . getNum ( ) = = slotsCount ) ? 2 : 0 ;
switch ( currState [ slot . getNum ( ) ] )
2010-07-22 03:32:45 +03:00
{
case 0 :
2012-01-12 18:23:00 +03:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > allTexts [ 314 + offset ] ,
2011-12-22 16:05:19 +03:00
std : : vector < CComponent * > ( ) , soundBase : : sound_todo ) ;
2010-07-22 03:32:45 +03:00
break ;
case 1 :
2012-01-12 18:23:00 +03:00
LOCPLINT - > showInfoDialog ( CGI - > generaltexth - > allTexts [ 313 + offset ] ,
2011-12-22 16:05:19 +03:00
std : : vector < CComponent * > ( ) , soundBase : : sound_todo ) ;
2010-07-22 03:32:45 +03:00
break ;
case 2 :
for ( int i = 0 ; i < slotsCount ; i + + )
2013-02-16 17:03:47 +03:00
if ( slot . getNum ( ) = = i | | ( slot . getNum ( ) = = slotsCount & & currState [ i ] = = 2 ) ) //this is activated slot or "upgrade all"
2010-07-22 03:32:45 +03:00
{
2011-05-03 06:14:18 +03:00
UpgradeInfo info ;
2013-02-16 17:03:47 +03:00
LOCPLINT - > cb - > getUpgradeInfo ( hero , SlotID ( i ) , info ) ;
LOCPLINT - > cb - > upgradeCreature ( hero , SlotID ( i ) , info . newID [ 0 ] ) ;
2010-07-22 03:32:45 +03:00
}
break ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
}
}
void CHillFortWindow : : showAll ( SDL_Surface * to )
{
2012-06-15 20:08:19 +03:00
CWindowObject : : showAll ( to ) ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
for ( int i = 0 ; i < slotsCount ; i + + )
{
if ( currState [ i ] = = 0 | | currState [ i ] = = 2 )
{
if ( costs [ i ] . size ( ) ) //we have several elements
{
int curY = 128 ; //reverse iterator is used to display gold as first element
2011-07-05 09:14:07 +03:00
for ( int j = costs [ i ] . size ( ) - 1 ; j > = 0 ; j - - )
2010-07-22 03:32:45 +03:00
{
2011-07-05 09:14:07 +03:00
int val = costs [ i ] [ j ] ;
if ( ! val ) continue ;
blitAtLoc ( resources - > ourImages [ j ] . bitmap , 104 + 76 * i , curY , to ) ;
2012-11-11 15:23:31 +03:00
printToLoc ( boost : : lexical_cast < std : : string > ( val ) , 168 + 76 * i , curY + 16 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-07-22 03:32:45 +03:00
curY + = 20 ;
}
}
else //free upgrade - print gold image and "Free" text
{
blitAtLoc ( resources - > ourImages [ 6 ] . bitmap , 104 + 76 * i , 128 , to ) ;
2012-11-11 15:23:31 +03:00
printToLoc ( CGI - > generaltexth - > allTexts [ 344 ] , 168 + 76 * i , 144 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-07-22 03:32:45 +03:00
}
}
}
2011-12-14 00:23:17 +03:00
for ( int i = 0 ; i < GameConstants : : RESOURCE_QUANTITY ; i + + )
2010-07-22 03:32:45 +03:00
{
if ( totalSumm [ i ] ) //this resource is used - display it
{
blitAtLoc ( resources - > ourImages [ i ] . bitmap , 104 + 76 * i , 237 , to ) ;
2012-11-11 15:23:31 +03:00
printToLoc ( boost : : lexical_cast < std : : string > ( totalSumm [ i ] ) , 166 + 76 * i , 253 , FONT_SMALL , Colors : : WHITE , to ) ;
2010-07-22 03:32:45 +03:00
}
}
}
2013-02-16 17:03:47 +03:00
std : : string CHillFortWindow : : getTextForSlot ( SlotID slot )
2010-07-27 02:20:21 +03:00
{
if ( ! hero - > getCreature ( slot ) ) //we dont have creature here
return " " ;
std : : string str = CGI - > generaltexth - > allTexts [ 318 ] ;
2010-11-27 03:46:19 +02:00
int amount = hero - > getStackCount ( slot ) ;
2010-07-27 02:20:21 +03:00
if ( amount = = 1 )
boost : : algorithm : : replace_first ( str , " %s " , hero - > getCreature ( slot ) - > nameSing ) ;
else
boost : : algorithm : : replace_first ( str , " %s " , hero - > getCreature ( slot ) - > namePl ) ;
2012-01-12 18:23:00 +03:00
2010-07-27 02:20:21 +03:00
return str ;
}
2013-02-16 17:03:47 +03:00
int CHillFortWindow : : getState ( SlotID slot )
2010-07-22 03:32:45 +03:00
{
2011-07-05 09:14:07 +03:00
TResources myRes = LOCPLINT - > cb - > getResourceAmount ( ) ;
2013-02-16 17:03:47 +03:00
if ( slot . getNum ( ) = = slotsCount ) //"Upgrade all" slot
2010-07-22 03:32:45 +03:00
{
bool allUpgraded = true ; //All creatures are upgraded?
for ( int i = 0 ; i < slotsCount ; i + + )
allUpgraded & = currState [ i ] = = 1 | | currState [ i ] = = - 1 ;
2012-01-12 18:23:00 +03:00
2010-07-22 03:32:45 +03:00
if ( allUpgraded )
return 1 ;
2011-07-05 09:14:07 +03:00
if ( ! totalSumm . canBeAfforded ( myRes ) )
return 0 ;
2010-07-22 03:32:45 +03:00
return 2 ;
}
if ( hero - > slotEmpty ( slot ) ) //no creature here
return - 1 ;
2012-01-12 18:23:00 +03:00
2011-05-03 06:14:18 +03:00
UpgradeInfo info ;
LOCPLINT - > cb - > getUpgradeInfo ( hero , slot , info ) ;
2010-07-22 03:32:45 +03:00
if ( ! info . newID . size ( ) ) //already upgraded
return 1 ;
2011-07-05 09:14:07 +03:00
if ( ! ( info . cost [ 0 ] * hero - > getStackCount ( slot ) ) . canBeAfforded ( myRes ) )
2010-07-22 03:32:45 +03:00
return 0 ;
2011-07-05 09:14:07 +03:00
2010-07-22 03:32:45 +03:00
return 2 ; //can upgrade
}
2012-06-15 20:08:19 +03:00
CThievesGuildWindow : : CThievesGuildWindow ( const CGObjectInstance * _owner ) :
CWindowObject ( PLAYER_COLORED | BORDERED , " TpRank " ) ,
owner ( _owner )
2010-01-31 20:41:22 +02:00
{
2010-02-07 17:06:14 +02:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2012-04-08 04:15:18 +03:00
type | = BLOCK_ADV_HOTKEYS ;
2010-02-07 17:06:14 +02:00
2010-02-01 19:51:33 +02:00
SThievesGuildInfo tgi ; //info to be displayed
LOCPLINT - > cb - > getThievesGuildInfo ( tgi , owner ) ;
2013-07-02 18:23:32 +03:00
exitb = new CAdventureMapButton ( CGI - > generaltexth - > allTexts [ 600 ] , " " , boost : : bind ( & CThievesGuildWindow : : close , this ) , 748 , 556 , " TPMAGE1 " , SDLK_RETURN ) ;
2012-11-11 00:56:19 +03:00
exitb - > assignedKeys . insert ( SDLK_ESCAPE ) ;
2012-06-17 01:40:28 +03:00
statusBar = new CGStatusBar ( 3 , 555 , " TStatBar.bmp " , 742 ) ;
2010-01-31 20:41:22 +02:00
2010-02-04 20:40:40 +02:00
resdatabar = new CMinorResDataBar ( ) ;
2010-07-26 01:47:59 +03:00
resdatabar - > pos . x + = pos . x ;
2010-02-04 20:40:40 +02:00
resdatabar - > pos . y + = pos . y ;
2012-06-15 20:08:19 +03:00
//data for information table:
// fields[row][column] = list of id's of players for this box
2013-03-03 20:06:03 +03:00
static std : : vector < std : : vector < PlayerColor > > SThievesGuildInfo : : * fields [ ] =
2012-06-15 20:08:19 +03:00
{ & SThievesGuildInfo : : numOfTowns , & SThievesGuildInfo : : numOfHeroes , & SThievesGuildInfo : : gold ,
& SThievesGuildInfo : : woodOre , & SThievesGuildInfo : : mercSulfCrystGems , & SThievesGuildInfo : : obelisks ,
& SThievesGuildInfo : : artifacts , & SThievesGuildInfo : : army , & SThievesGuildInfo : : income } ;
2010-01-31 20:41:22 +02:00
//printing texts & descriptions to background
for ( int g = 0 ; g < 12 ; + + g )
{
2012-06-15 20:08:19 +03:00
int posY [ ] = { 400 , 460 , 510 } ;
2010-01-31 20:41:22 +02:00
int y ;
2012-06-15 20:08:19 +03:00
if ( g < 9 )
2010-01-31 20:41:22 +02:00
y = 52 + 32 * g ;
2012-06-15 20:08:19 +03:00
else
y = posY [ g - 9 ] ;
2010-07-26 01:47:59 +03:00
std : : string text = CGI - > generaltexth - > jktexts [ 24 + g ] ;
boost : : algorithm : : trim_if ( text , boost : : algorithm : : is_any_of ( " \" " ) ) ;
2012-11-11 15:23:31 +03:00
new CLabel ( 135 , y , FONT_MEDIUM , CENTER , Colors : : YELLOW , text ) ;
2010-01-31 20:41:22 +02:00
}
2012-06-15 20:08:19 +03:00
for ( int g = 1 ; g < tgi . playerColors . size ( ) ; + + g )
new CAnimImage ( " PRSTRIPS " , g - 1 , 0 , 250 + 66 * g , 7 ) ;
2010-02-01 19:51:33 +02:00
for ( int g = 0 ; g < tgi . playerColors . size ( ) ; + + g )
2012-11-11 15:23:31 +03:00
new CLabel ( 283 + 66 * g , 24 , FONT_BIG , CENTER , Colors : : YELLOW , CGI - > generaltexth - > jktexts [ 16 + g ] ) ;
2010-02-04 20:40:40 +02:00
//printing flags
2011-12-14 00:23:17 +03:00
for ( int g = 0 ; g < ARRAY_COUNT ( fields ) ; + + g ) //by lines
2010-02-04 20:40:40 +02:00
{
for ( int b = 0 ; b < ( tgi . * fields [ g ] ) . size ( ) ; + + b ) //by places (1st, 2nd, ...)
{
2013-03-03 20:06:03 +03:00
std : : vector < PlayerColor > & players = ( tgi . * fields [ g ] ) [ b ] ; //get players with this place in this line
2012-06-15 20:08:19 +03:00
//position of box
int xpos = 259 + 66 * b ;
int ypos = 41 + 32 * g ;
2010-02-04 20:40:40 +02:00
2012-06-15 20:08:19 +03:00
size_t rowLength [ 2 ] ; //size of each row
rowLength [ 0 ] = std : : min < size_t > ( players . size ( ) , 4 ) ;
rowLength [ 1 ] = players . size ( ) - rowLength [ 0 ] ;
for ( size_t j = 0 ; j < 2 ; j + + )
2010-02-04 20:40:40 +02:00
{
2012-06-15 20:08:19 +03:00
// origin of this row | offset for 2nd row| shift right for short rows
2012-11-11 00:56:19 +03:00
//if we have 2 rows, start either from mid or beginning (depending on count), otherwise center the flags
int rowStartX = xpos + ( j ? 6 + ( rowLength [ j ] < 3 ? 12 : 0 ) : 24 - 6 * rowLength [ j ] ) ;
2012-06-15 20:08:19 +03:00
int rowStartY = ypos + ( j ? 4 : 0 ) ;
for ( size_t i = 0 ; i < rowLength [ j ] ; i + + )
{
2013-03-03 20:06:03 +03:00
new CAnimImage ( " itgflags " , players [ i + j * 4 ] . getNum ( ) , 0 , rowStartX + i * 12 , rowStartY ) ;
2012-06-15 20:08:19 +03:00
}
2010-02-04 20:40:40 +02:00
}
}
}
2012-06-15 20:08:19 +03:00
static const std : : string colorToBox [ ] = { " PRRED.BMP " , " PRBLUE.BMP " , " PRTAN.BMP " , " PRGREEN.BMP " , " PRORANGE.BMP " , " PRPURPLE.BMP " , " PRTEAL.BMP " , " PRROSE.bmp " } ;
2010-02-04 20:40:40 +02:00
2012-06-15 20:08:19 +03:00
//printing best hero
2010-02-04 20:40:40 +02:00
int counter = 0 ;
2013-06-29 16:05:48 +03:00
for ( auto & iter : tgi . colorToBestHero )
2010-02-04 20:40:40 +02:00
{
2012-06-15 20:08:19 +03:00
if ( iter . second . portrait > = 0 )
2010-02-07 19:56:06 +02:00
{
2013-03-03 20:06:03 +03:00
new CPicture ( colorToBox [ iter . first . getNum ( ) ] , 253 + 66 * counter , 334 ) ;
2012-06-15 20:08:19 +03:00
new CAnimImage ( " PortraitsSmall " , iter . second . portrait , 0 , 260 + 66 * counter , 360 ) ;
//TODO: r-click info:
// - r-click on hero
// - r-click on primary skill label
if ( iter . second . details )
2010-02-07 19:56:06 +02:00
{
2012-06-15 20:08:19 +03:00
new CTextBox ( CGI - > generaltexth - > allTexts [ 184 ] , Rect ( 260 + 66 * counter , 396 , 52 , 64 ) ,
2012-11-11 15:23:31 +03:00
0 , FONT_TINY , TOPLEFT , Colors : : WHITE ) ;
2012-06-15 20:08:19 +03:00
for ( int i = 0 ; i < iter . second . details - > primskills . size ( ) ; + + i )
{
2012-11-11 15:23:31 +03:00
new CLabel ( 310 + 66 * counter , 407 + 11 * i , FONT_TINY , BOTTOMRIGHT , Colors : : WHITE ,
2012-06-15 20:08:19 +03:00
boost : : lexical_cast < std : : string > ( iter . second . details - > primskills [ i ] ) ) ;
}
2010-02-07 19:56:06 +02:00
}
}
2012-06-15 20:08:19 +03:00
counter + + ;
2010-02-04 20:40:40 +02:00
}
2010-02-06 15:49:14 +02:00
//printing best creature
counter = 0 ;
2013-06-29 16:05:48 +03:00
for ( auto & it : tgi . bestCreature )
2010-02-06 15:49:14 +02:00
{
2012-06-15 20:08:19 +03:00
if ( it . second > = 0 )
new CAnimImage ( " TWCRPORT " , it . second + 2 , 0 , 255 + 66 * counter , 479 ) ;
2010-02-06 15:49:14 +02:00
counter + + ;
}
2010-02-07 19:56:06 +02:00
//printing personality
counter = 0 ;
2013-06-29 16:05:48 +03:00
for ( auto & it : tgi . personality )
2010-02-07 19:56:06 +02:00
{
2012-06-15 20:08:19 +03:00
std : : string text ;
2012-11-06 19:39:29 +03:00
if ( it . second = = EAiTactic : : NONE )
{
2012-06-15 20:08:19 +03:00
text = CGI - > generaltexth - > arraytxt [ 172 ] ;
2012-11-06 19:39:29 +03:00
}
else if ( it . second ! = EAiTactic : : RANDOM )
{
text = CGI - > generaltexth - > arraytxt [ 168 + it . second ] ;
}
2010-02-07 19:56:06 +02:00
2012-11-11 15:23:31 +03:00
new CLabel ( 283 + 66 * counter , 459 , FONT_SMALL , CENTER , Colors : : WHITE , text ) ;
2010-02-07 19:56:06 +02:00
counter + + ;
}
2010-01-31 20:41:22 +02:00
}
2011-02-27 21:58:14 +02:00
void MoraleLuckBox : : set ( const IBonusBearer * node )
2010-07-13 08:25:40 +03:00
{
2012-05-13 18:04:21 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
2010-07-13 08:25:40 +03:00
const int textId [ ] = { 62 , 88 } ; //eg %s \n\n\n {Current Luck Modifiers:}
2011-01-17 18:07:08 +02:00
const int noneTxtId = 108 ; //Russian version uses same text for neutral morale\luck
2010-07-13 08:25:40 +03:00
const int neutralDescr [ ] = { 60 , 86 } ; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat.
2011-12-22 16:05:19 +03:00
const int componentType [ ] = { CComponent : : luck , CComponent : : morale } ;
2010-07-13 08:25:40 +03:00
const int hoverTextBase [ ] = { 7 , 4 } ;
const Bonus : : BonusType bonusType [ ] = { Bonus : : LUCK , Bonus : : MORALE } ;
2011-02-27 21:58:14 +02:00
int ( IBonusBearer : : * getValue [ ] ) ( ) const = { & IBonusBearer : : LuckVal , & IBonusBearer : : MoraleVal } ;
2010-01-31 20:41:22 +02:00
2010-07-13 08:25:40 +03:00
int mrlt = - 9 ;
TModDescr mrl ;
2010-08-29 12:00:59 +03:00
if ( node )
2010-07-24 14:46:04 +03:00
{
2010-08-29 12:00:59 +03:00
node - > getModifiersWDescr ( mrl , bonusType [ morale ] ) ;
bonusValue = ( node - > * getValue [ morale ] ) ( ) ;
2010-07-24 14:46:04 +03:00
}
else
bonusValue = 0 ;
2010-07-13 08:25:40 +03:00
mrlt = ( bonusValue > 0 ) - ( bonusValue < 0 ) ; //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
hoverText = CGI - > generaltexth - > heroscrn [ hoverTextBase [ morale ] - mrlt ] ;
baseType = componentType [ morale ] ;
text = CGI - > generaltexth - > arraytxt [ textId [ morale ] ] ;
boost : : algorithm : : replace_first ( text , " %s " , CGI - > generaltexth - > arraytxt [ neutralDescr [ morale ] - mrlt ] ) ;
if ( ! mrl . size ( ) )
2011-01-17 18:07:08 +02:00
text + = CGI - > generaltexth - > arraytxt [ noneTxtId ] ;
2010-07-13 08:25:40 +03:00
else
2010-08-29 12:00:59 +03:00
{
2014-02-28 20:49:56 +03:00
//it's a creature window
2014-03-17 22:51:07 +03:00
if ( ( morale & & node - > hasBonusOfType ( Bonus : : UNDEAD ) ) | |
2014-02-28 20:49:56 +03:00
node - > hasBonusOfType ( Bonus : : BLOCK_MORALE ) | | node - > hasBonusOfType ( Bonus : : NON_LIVING ) )
2010-08-29 12:00:59 +03:00
{
text + = CGI - > generaltexth - > arraytxt [ 113 ] ; //unaffected by morale
}
else
{
2013-06-29 16:05:48 +03:00
for ( auto & elem : mrl )
2013-04-27 11:11:20 +03:00
{
2013-06-29 16:05:48 +03:00
if ( elem . first ) //no bonuses with value 0
text + = " \n " + elem . second ;
2013-04-27 11:11:20 +03:00
}
2010-08-29 12:00:59 +03:00
}
}
2012-07-19 21:52:44 +03:00
2012-05-13 18:04:21 +03:00
std : : string imageName ;
2011-04-30 21:16:58 +03:00
if ( small )
2012-05-13 18:04:21 +03:00
imageName = morale ? " IMRL30 " : " ILCK30 " ;
2011-04-30 21:16:58 +03:00
else
2012-05-13 18:04:21 +03:00
imageName = morale ? " IMRL42 " : " ILCK42 " ;
2012-06-02 18:16:54 +03:00
delete image ;
2012-05-13 18:04:21 +03:00
image = new CAnimImage ( imageName , bonusValue + 3 ) ;
image - > moveBy ( Point ( pos . w / 2 - image - > pos . w / 2 , pos . h / 2 - image - > pos . h / 2 ) ) ; //center icon
2010-07-13 08:25:40 +03:00
}
2010-01-31 20:41:22 +02:00
2012-05-13 18:04:21 +03:00
MoraleLuckBox : : MoraleLuckBox ( bool Morale , const Rect & r , bool Small ) :
2013-06-26 14:18:27 +03:00
image ( nullptr ) ,
2012-05-13 18:04:21 +03:00
morale ( Morale ) ,
small ( Small )
2010-07-13 08:25:40 +03:00
{
bonusValue = 0 ;
2010-12-17 00:32:53 +02:00
pos = r + pos ;
2010-07-13 08:25:40 +03:00
}
2010-01-31 20:41:22 +02:00
2011-04-30 21:16:58 +03:00
CArtifactHolder : : CArtifactHolder ( )
2011-01-06 22:00:19 +02:00
{
}
2011-04-30 21:16:58 +03:00
void CWindowWithArtifacts : : artifactRemoved ( const ArtifactLocation & artLoc )
{
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : artSets )
2011-04-30 21:16:58 +03:00
aoh - > artifactRemoved ( artLoc ) ;
}
void CWindowWithArtifacts : : artifactMoved ( const ArtifactLocation & artLoc , const ArtifactLocation & destLoc )
{
2013-06-26 14:18:27 +03:00
CArtifactsOfHero * destaoh = nullptr ;
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : artSets )
2013-01-10 21:53:49 +03:00
{
2011-04-30 21:16:58 +03:00
aoh - > artifactMoved ( artLoc , destLoc ) ;
2013-01-10 21:53:49 +03:00
aoh - > redraw ( ) ;
if ( destLoc . isHolder ( aoh - > getHero ( ) ) )
destaoh = aoh ;
}
//Make sure the status bar is updated so it does not display old text
2013-06-26 14:18:27 +03:00
if ( destaoh ! = nullptr & & destaoh - > getArtPlace ( destLoc . slot ) ! = nullptr )
2013-01-10 21:53:49 +03:00
{
destaoh - > getArtPlace ( destLoc . slot ) - > hover ( true ) ;
}
2011-04-30 21:16:58 +03:00
}
void CWindowWithArtifacts : : artifactDisassembled ( const ArtifactLocation & artLoc )
{
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : artSets )
2011-04-30 21:16:58 +03:00
aoh - > artifactDisassembled ( artLoc ) ;
}
void CWindowWithArtifacts : : artifactAssembled ( const ArtifactLocation & artLoc )
2011-01-06 22:00:19 +02:00
{
2013-06-29 16:05:48 +03:00
for ( CArtifactsOfHero * aoh : artSets )
2011-04-30 21:16:58 +03:00
aoh - > artifactAssembled ( artLoc ) ;
2011-01-06 22:00:19 +02:00
}
void CArtifactsOfHero : : SCommonPart : : Artpos : : clear ( )
{
2013-02-07 02:24:43 +03:00
slotID = ArtifactPosition : : PRE_FIRST ;
2013-06-26 14:18:27 +03:00
AOH = nullptr ;
art = nullptr ;
2011-01-06 22:00:19 +02:00
}
CArtifactsOfHero : : SCommonPart : : Artpos : : Artpos ( )
{
clear ( ) ;
}
void CArtifactsOfHero : : SCommonPart : : Artpos : : setTo ( const CArtPlace * place , bool dontTakeBackpack )
{
slotID = place - > slotID ;
AOH = place - > ourOwner ;
if ( slotID > = 19 & & dontTakeBackpack )
2013-06-26 14:18:27 +03:00
art = nullptr ;
2011-01-06 22:00:19 +02:00
else
art = place - > ourArt ;
}
bool CArtifactsOfHero : : SCommonPart : : Artpos : : operator = = ( const ArtifactLocation & al ) const
{
if ( ! AOH )
return false ;
2012-04-14 05:20:22 +03:00
bool ret = al . isHolder ( AOH - > curHero ) & & al . slot = = slotID ;
2011-01-06 22:00:19 +02:00
//assert(al.getArt() == art);
return ret ;
2011-01-18 20:56:14 +02:00
}
bool CArtifactsOfHero : : SCommonPart : : Artpos : : valid ( )
{
assert ( AOH & & art ) ;
return art = = AOH - > curHero - > getArt ( slotID ) ;
2011-02-27 21:58:14 +02:00
}
2011-05-25 16:11:03 +03:00
2011-12-22 16:05:19 +03:00
void CRClickPopup : : clickRight ( tribool down , bool previousState )
2011-05-25 16:11:03 +03:00
{
2011-12-22 16:05:19 +03:00
if ( down )
return ;
close ( ) ;
2011-05-25 16:11:03 +03:00
}
2011-12-22 16:05:19 +03:00
void CRClickPopup : : close ( )
{
GH . popIntTotally ( this ) ;
}
void CRClickPopup : : createAndPush ( const std : : string & txt , const CInfoWindow : : TCompsInfo & comps )
{
2013-03-03 20:06:03 +03:00
PlayerColor player = LOCPLINT ? LOCPLINT - > playerID : PlayerColor ( 1 ) ; //if no player, then use blue
2011-12-22 16:05:19 +03:00
CSimpleWindow * temp = new CInfoWindow ( txt , player , comps ) ;
temp - > center ( Point ( GH . current - > motion ) ) ; //center on mouse
temp - > fitToScreen ( 10 ) ;
2013-06-29 16:05:48 +03:00
auto rcpi = new CRClickPopupInt ( temp , true ) ;
2011-12-22 16:05:19 +03:00
GH . pushInt ( rcpi ) ;
}
2012-12-11 15:12:46 +03:00
void CRClickPopup : : createAndPush ( const std : : string & txt , CComponent * component )
{
CInfoWindow : : TCompsInfo intComps ;
intComps . push_back ( component ) ;
createAndPush ( txt , intComps ) ;
}
2012-06-13 16:04:06 +03:00
Point CInfoBoxPopup : : toScreen ( Point p )
{
vstd : : abetween ( p . x , adventureInt - > terrain . pos . x + 100 , adventureInt - > terrain . pos . x + adventureInt - > terrain . pos . w - 100 ) ;
vstd : : abetween ( p . y , adventureInt - > terrain . pos . y + 100 , adventureInt - > terrain . pos . y + adventureInt - > terrain . pos . h - 100 ) ;
return p ;
}
CInfoBoxPopup : : CInfoBoxPopup ( Point position , const CGTownInstance * town ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( RCLICK_POPUP | PLAYER_COLORED , " TOWNQVBK " , toScreen ( position ) )
2012-06-13 16:04:06 +03:00
{
InfoAboutTown iah ;
2012-07-19 21:52:44 +03:00
LOCPLINT - > cb - > getTownInfo ( town , iah ) ;
2012-06-13 16:04:06 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
new CTownTooltip ( Point ( 9 , 10 ) , iah ) ;
}
CInfoBoxPopup : : CInfoBoxPopup ( Point position , const CGHeroInstance * hero ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( RCLICK_POPUP | PLAYER_COLORED , " HEROQVBK " , toScreen ( position ) )
2012-06-13 16:04:06 +03:00
{
InfoAboutHero iah ;
2012-07-19 21:52:44 +03:00
LOCPLINT - > cb - > getHeroInfo ( hero , iah ) ;
2012-06-13 16:04:06 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
new CHeroTooltip ( Point ( 9 , 10 ) , iah ) ;
}
CInfoBoxPopup : : CInfoBoxPopup ( Point position , const CGGarrison * garr ) :
2012-06-15 20:08:19 +03:00
CWindowObject ( RCLICK_POPUP | PLAYER_COLORED , " TOWNQVBK " , toScreen ( position ) )
2012-06-13 16:04:06 +03:00
{
InfoAboutTown iah ;
2012-07-19 21:52:44 +03:00
LOCPLINT - > cb - > getTownInfo ( garr , iah ) ;
2012-06-13 16:04:06 +03:00
OBJ_CONSTRUCTION_CAPTURING_ALL ;
new CArmyTooltip ( Point ( 9 , 10 ) , iah ) ;
}
CIntObject * CRClickPopup : : createInfoWin ( Point position , const CGObjectInstance * specific ) //specific=0 => draws info about selected town/hero
{
if ( ! specific )
specific = adventureInt - > selection ;
assert ( specific ) ;
switch ( specific - > ID )
{
2012-09-23 21:01:04 +03:00
case Obj : : HERO :
2012-06-13 16:04:06 +03:00
return new CInfoBoxPopup ( position , dynamic_cast < const CGHeroInstance * > ( specific ) ) ;
2012-09-23 21:01:04 +03:00
case Obj : : TOWN :
2012-06-13 16:04:06 +03:00
return new CInfoBoxPopup ( position , dynamic_cast < const CGTownInstance * > ( specific ) ) ;
case Obj : : GARRISON :
case Obj : : GARRISON2 :
return new CInfoBoxPopup ( position , dynamic_cast < const CGGarrison * > ( specific ) ) ;
default :
2013-06-26 14:18:27 +03:00
return nullptr ;
2012-06-13 16:04:06 +03:00
}
}
2011-12-22 16:05:19 +03:00
void CRClickPopup : : createAndPush ( const CGObjectInstance * obj , const Point & p , EAlignment alignment /*= BOTTOMRIGHT*/ )
{
2012-06-13 16:04:06 +03:00
CIntObject * iWin = createInfoWin ( p , obj ) ; //try get custom infowindow for this obj
2011-12-22 16:05:19 +03:00
if ( iWin )
2012-06-13 16:04:06 +03:00
GH . pushInt ( iWin ) ;
2011-05-25 16:11:03 +03:00
else
2011-12-22 16:05:19 +03:00
CRClickPopup : : createAndPush ( obj - > getHoverText ( ) ) ;
}
CRClickPopup : : CRClickPopup ( )
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( RCLICK ) ;
2011-12-22 16:05:19 +03:00
}
CRClickPopup : : ~ CRClickPopup ( )
{
}
void CRClickPopupInt : : show ( SDL_Surface * to )
{
inner - > show ( to ) ;
}
CRClickPopupInt : : CRClickPopupInt ( IShowActivatable * our , bool deleteInt )
{
CCS - > curh - > hide ( ) ;
inner = our ;
delInner = deleteInt ;
}
CRClickPopupInt : : ~ CRClickPopupInt ( )
{
2012-01-12 18:23:00 +03:00
// //workaround for hero window issue - if it's our interface, call dispose to properly reset it's state
2011-12-22 16:05:19 +03:00
// //TODO? it might be better to rewrite hero window so it will bee newed/deleted on opening / closing (not effort-worthy now, but on some day...?)
// if(LOCPLINT && inner == adventureInt->heroWindow)
// adventureInt->heroWindow->dispose();
if ( delInner )
delete inner ;
CCS - > curh - > show ( ) ;
}
void CRClickPopupInt : : showAll ( SDL_Surface * to )
{
inner - > showAll ( to ) ;
2011-06-03 06:23:50 +03:00
}