2017-07-13 10:26:03 +02:00
/*
* CBattleInterfaceClasses . 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
*
*/
2011-12-22 16:05:19 +03:00
# include "StdInc.h"
2022-12-09 13:38:46 +02:00
# include "BattleInterfaceClasses.h"
2011-12-22 16:05:19 +03:00
2022-12-09 13:38:46 +02:00
# include "BattleInterface.h"
# include "BattleActionsController.h"
# include "BattleSiegeController.h"
# include "BattleFieldController.h"
# include "BattleStacksController.h"
# include "BattleControlPanel.h"
2014-07-13 20:53:37 +03:00
# include "../CGameInfo.h"
# include "../CMessage.h"
# include "../CMusicHandler.h"
2011-12-22 16:05:19 +03:00
# include "../CPlayerInterface.h"
2014-07-13 20:53:37 +03:00
# include "../CVideoHandler.h"
2011-12-22 16:05:19 +03:00
# include "../Graphics.h"
2017-09-05 15:44:27 +02:00
# include "../gui/CAnimation.h"
2014-07-13 20:53:37 +03:00
# include "../gui/CCursorHandler.h"
2013-04-07 14:52:07 +03:00
# include "../gui/CGuiHandler.h"
2014-07-15 10:14:49 +03:00
# include "../widgets/Buttons.h"
2022-11-24 16:30:04 +02:00
# include "../widgets/Images.h"
2014-07-15 10:14:49 +03:00
# include "../widgets/TextControls.h"
2014-07-13 20:53:37 +03:00
# include "../windows/CCreatureWindow.h"
# include "../windows/CSpellWindow.h"
# include "../../CCallback.h"
2017-03-17 17:48:44 +02:00
# include "../../lib/CStack.h"
2014-07-13 20:53:37 +03:00
# include "../../lib/CConfigHandler.h"
# include "../../lib/CCreatureHandler.h"
2014-07-15 10:14:49 +03:00
# include "../../lib/CGameState.h"
2011-12-22 16:05:19 +03:00
# include "../../lib/CGeneralTextHandler.h"
2014-07-13 20:53:37 +03:00
# include "../../lib/CTownHandler.h"
2011-12-22 16:05:19 +03:00
# include "../../lib/NetPacks.h"
2014-06-25 17:11:07 +03:00
# include "../../lib/StartInfo.h"
2014-07-15 10:14:49 +03:00
# include "../../lib/CondSh.h"
2015-12-02 21:05:10 +02:00
# include "../../lib/mapObjects/CGTownInstance.h"
2011-12-22 16:05:19 +03:00
2022-12-09 13:26:17 +02:00
void BattleConsole : : showAll ( SDL_Surface * to )
2011-12-22 16:05:19 +03:00
{
2013-01-21 01:49:34 +03:00
Point textPos ( pos . x + pos . w / 2 , pos . y + 17 ) ;
2012-12-19 20:24:53 +03:00
2011-12-22 16:05:19 +03:00
if ( ingcAlter . size ( ) )
{
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLinesCenter ( to , CMessage : : breakText ( ingcAlter , pos . w , FONT_SMALL ) , Colors : : WHITE , textPos ) ;
2011-12-22 16:05:19 +03:00
}
else if ( texts . size ( ) )
{
if ( texts . size ( ) = = 1 )
{
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLinesCenter ( to , CMessage : : breakText ( texts [ 0 ] , pos . w , FONT_SMALL ) , Colors : : WHITE , textPos ) ;
2011-12-22 16:05:19 +03:00
}
else
{
2012-12-19 20:24:53 +03:00
graphics - > fonts [ FONT_SMALL ] - > renderTextLinesCenter ( to , CMessage : : breakText ( texts [ lastShown - 1 ] , pos . w , FONT_SMALL ) , Colors : : WHITE , textPos ) ;
textPos . y + = 16 ;
graphics - > fonts [ FONT_SMALL ] - > renderTextLinesCenter ( to , CMessage : : breakText ( texts [ lastShown ] , pos . w , FONT_SMALL ) , Colors : : WHITE , textPos ) ;
2011-12-22 16:05:19 +03:00
}
}
}
2022-12-09 13:26:17 +02:00
bool BattleConsole : : addText ( const std : : string & text )
2011-12-22 16:05:19 +03:00
{
2017-08-11 13:38:10 +02:00
logGlobal - > trace ( " CBattleConsole message: %s " , text ) ;
2011-12-22 16:05:19 +03:00
if ( text . size ( ) > 70 )
return false ; //text too long!
int firstInToken = 0 ;
for ( size_t i = 0 ; i < text . size ( ) ; + + i ) //tokenize
{
if ( text [ i ] = = 10 )
{
texts . push_back ( text . substr ( firstInToken , i - firstInToken ) ) ;
2020-10-01 10:38:06 +02:00
firstInToken = ( int ) i + 1 ;
2011-12-22 16:05:19 +03:00
}
}
texts . push_back ( text . substr ( firstInToken , text . size ( ) ) ) ;
2020-10-01 10:38:06 +02:00
lastShown = ( int ) texts . size ( ) - 1 ;
2011-12-22 16:05:19 +03:00
return true ;
}
2022-12-09 13:26:17 +02:00
void BattleConsole : : scrollUp ( ui32 by )
2022-11-18 17:54:10 +02:00
{
if ( lastShown > static_cast < int > ( by ) )
lastShown - = by ;
}
2011-12-22 16:05:19 +03:00
2022-12-09 13:26:17 +02:00
void BattleConsole : : scrollDown ( ui32 by )
2012-02-20 11:19:03 +03:00
{
2022-11-18 17:54:10 +02:00
if ( lastShown + by < texts . size ( ) )
lastShown + = by ;
2012-02-20 11:19:03 +03:00
}
2022-12-09 13:26:17 +02:00
BattleConsole : : BattleConsole ( const Rect & position ) : lastShown ( - 1 )
2011-12-22 16:05:19 +03:00
{
2022-11-29 17:18:30 +02:00
pos + = position . topLeft ( ) ;
pos . w = position . w ;
pos . h = position . h ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleConsole : : clearMatching ( const std : : string & Text )
2011-12-22 16:05:19 +03:00
{
2022-11-18 17:54:10 +02:00
if ( ingcAlter = = Text )
clear ( ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleConsole : : clear ( )
2011-12-22 16:05:19 +03:00
{
2022-11-18 17:54:10 +02:00
ingcAlter . clear ( ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleConsole : : write ( const std : : string & Text )
2011-12-22 16:05:19 +03:00
{
2022-11-18 17:54:10 +02:00
ingcAlter = Text ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleConsole : : lock ( bool shouldLock )
2022-11-18 17:54:10 +02:00
{
// no-op?
}
2012-09-27 20:16:41 +03:00
2022-12-09 13:26:17 +02:00
void BattleHero : : show ( SDL_Surface * to )
2011-12-22 16:05:19 +03:00
{
2018-03-30 13:02:04 +02:00
auto flagFrame = flagAnimation - > getImage ( flagAnim , 0 , true ) ;
2017-09-05 15:44:27 +02:00
if ( ! flagFrame )
return ;
2011-12-22 16:05:19 +03:00
//animation of flag
2012-08-29 17:55:31 +03:00
SDL_Rect temp_rect ;
2011-12-22 16:05:19 +03:00
if ( flip )
{
2012-08-29 17:55:31 +03:00
temp_rect = genRect (
2017-09-05 15:44:27 +02:00
flagFrame - > height ( ) ,
flagFrame - > width ( ) ,
2011-12-22 16:05:19 +03:00
pos . x + 61 ,
pos . y + 39 ) ;
2012-08-29 17:55:31 +03:00
2011-12-22 16:05:19 +03:00
}
else
{
2012-08-29 17:55:31 +03:00
temp_rect = genRect (
2017-09-05 15:44:27 +02:00
flagFrame - > height ( ) ,
flagFrame - > width ( ) ,
2011-12-22 16:05:19 +03:00
pos . x + 72 ,
pos . y + 39 ) ;
}
2017-09-05 15:44:27 +02:00
flagFrame - > draw ( screen , & temp_rect , nullptr ) ; //FIXME: why screen?
2012-08-29 17:55:31 +03:00
2011-12-22 16:05:19 +03:00
//animation of hero
2012-08-29 17:55:31 +03:00
SDL_Rect rect = pos ;
2018-03-30 13:02:04 +02:00
auto heroFrame = animation - > getImage ( currentFrame , phase , true ) ;
2017-09-05 15:44:27 +02:00
if ( ! heroFrame )
return ;
heroFrame - > draw ( to , & rect , nullptr ) ;
if ( + + animCount > = 4 )
2011-12-22 16:05:19 +03:00
{
2012-08-29 17:55:31 +03:00
animCount = 0 ;
2017-09-05 15:44:27 +02:00
if ( + + flagAnim > = flagAnimation - > size ( 0 ) )
2012-08-29 17:55:31 +03:00
flagAnim = 0 ;
2017-09-05 15:44:27 +02:00
if ( + + currentFrame > = lastFrame )
2012-08-29 17:55:31 +03:00
switchToNextPhase ( ) ;
2011-12-22 16:05:19 +03:00
}
}
2022-12-09 13:26:17 +02:00
void BattleHero : : setPhase ( int newPhase )
2011-12-22 16:05:19 +03:00
{
2012-08-29 17:55:31 +03:00
nextPhase = newPhase ;
switchToNextPhase ( ) ; //immediately switch to next phase and then restore idling phase
nextPhase = 0 ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleHero : : hover ( bool on )
2016-09-27 14:13:20 +02:00
{
//TODO: Make lines below work properly
if ( on )
CCS - > curh - > changeGraphic ( ECursor : : COMBAT , 5 ) ;
else
CCS - > curh - > changeGraphic ( ECursor : : COMBAT , 0 ) ;
}
2022-12-09 13:26:17 +02:00
void BattleHero : : clickLeft ( tribool down , bool previousState )
2011-12-22 16:05:19 +03:00
{
2022-11-20 22:56:42 +02:00
if ( myOwner - > actionsController - > spellcastingModeActive ( ) ) //we are casting a spell
2011-12-22 16:05:19 +03:00
return ;
2017-09-05 15:44:27 +02:00
if ( boost : : logic : : indeterminate ( down ) )
return ;
if ( ! myHero | | down | | ! myOwner - > myTurn )
return ;
2017-07-20 06:08:49 +02:00
if ( myOwner - > getCurrentPlayerInterface ( ) - > cb - > battleCanCastSpell ( myHero , spells : : Mode : : HERO ) = = ESpellCastProblem : : OK ) //check conditions
2011-12-22 16:05:19 +03:00
{
2022-11-17 23:57:51 +02:00
BattleHex hoveredHex = myOwner - > fieldController - > getHoveredHex ( ) ;
//do nothing when any hex is hovered - hero's animation overlaps battlefield
if ( hoveredHex ! = BattleHex : : INVALID )
return ;
2012-12-14 18:32:53 +03:00
CCS - > curh - > changeGraphic ( ECursor : : ADVENTURE , 0 ) ;
2011-12-22 16:05:19 +03:00
2018-07-25 00:36:48 +02:00
GH . pushIntT < CSpellWindow > ( myHero , myOwner - > getCurrentPlayerInterface ( ) ) ;
2011-12-22 16:05:19 +03:00
}
}
2022-12-09 13:26:17 +02:00
void BattleHero : : clickRight ( tribool down , bool previousState )
2016-09-27 14:13:20 +02:00
{
2017-09-05 15:44:27 +02:00
if ( boost : : logic : : indeterminate ( down ) )
return ;
2016-09-27 14:13:20 +02:00
Point windowPosition ;
windowPosition . x = ( ! flip ) ? myOwner - > pos . topLeft ( ) . x + 1 : myOwner - > pos . topRight ( ) . x - 79 ;
windowPosition . y = myOwner - > pos . y + 135 ;
InfoAboutHero targetHero ;
2017-06-03 07:25:10 +02:00
if ( down & & ( myOwner - > myTurn | | settings [ " session " ] [ " spectate " ] . Bool ( ) ) )
2016-09-27 14:13:20 +02:00
{
2017-06-03 03:28:03 +02:00
auto h = flip ? myOwner - > defendingHeroInstance : myOwner - > attackingHeroInstance ;
targetHero . initFromHero ( h , InfoAboutHero : : EInfoLevel : : INBATTLE ) ;
2022-12-09 13:26:17 +02:00
GH . pushIntT < HeroInfoWindow > ( targetHero , & windowPosition ) ;
2016-09-27 14:13:20 +02:00
}
}
2022-12-09 13:26:17 +02:00
void BattleHero : : switchToNextPhase ( )
2012-08-29 17:55:31 +03:00
{
2017-09-05 15:44:27 +02:00
if ( phase ! = nextPhase )
2012-08-29 17:55:31 +03:00
{
phase = nextPhase ;
2017-09-05 15:44:27 +02:00
firstFrame = 0 ;
2012-08-29 17:55:31 +03:00
2020-10-01 10:38:06 +02:00
lastFrame = static_cast < int > ( animation - > size ( phase ) ) ;
2012-08-29 17:55:31 +03:00
}
currentFrame = firstFrame ;
}
2022-12-09 13:26:17 +02:00
BattleHero : : BattleHero ( const std : : string & animationPath , bool flipG , PlayerColor player , const CGHeroInstance * hero , const BattleInterface * owner ) :
2012-08-29 17:55:31 +03:00
flip ( flipG ) ,
myHero ( hero ) ,
myOwner ( owner ) ,
phase ( 1 ) ,
nextPhase ( 0 ) ,
flagAnim ( 0 ) ,
animCount ( 0 )
2011-12-22 16:05:19 +03:00
{
2017-09-05 15:44:27 +02:00
animation = std : : make_shared < CAnimation > ( animationPath ) ;
animation - > preload ( ) ;
if ( flipG )
animation - > verticalFlip ( ) ;
2011-12-22 16:05:19 +03:00
if ( flip )
2017-09-05 15:44:27 +02:00
flagAnimation = std : : make_shared < CAnimation > ( " CMFLAGR " ) ;
2011-12-22 16:05:19 +03:00
else
2017-09-05 15:44:27 +02:00
flagAnimation = std : : make_shared < CAnimation > ( " CMFLAGL " ) ;
flagAnimation - > preload ( ) ;
flagAnimation - > playerColored ( player ) ;
2011-12-22 16:05:19 +03:00
2016-09-27 14:13:20 +02:00
addUsedEvents ( LCLICK | RCLICK | HOVER ) ;
2012-08-29 17:55:31 +03:00
switchToNextPhase ( ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
HeroInfoWindow : : HeroInfoWindow ( const InfoAboutHero & hero , Point * position )
2018-04-07 13:34:11 +02:00
: CWindowObject ( RCLICK_POPUP | SHADOW_DISABLED , " CHRPOP " )
{
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
if ( position ! = nullptr )
moveTo ( * position ) ;
background - > colorize ( hero . owner ) ; //maybe add this functionality to base class?
auto attack = hero . details - > primskills [ 0 ] ;
auto defense = hero . details - > primskills [ 1 ] ;
auto power = hero . details - > primskills [ 2 ] ;
auto knowledge = hero . details - > primskills [ 3 ] ;
auto morale = hero . details - > morale ;
auto luck = hero . details - > luck ;
auto currentSpellPoints = hero . details - > mana ;
auto maxSpellPoints = hero . details - > manaLimit ;
icons . push_back ( std : : make_shared < CAnimImage > ( " PortraitsLarge " , hero . portrait , 0 , 10 , 6 ) ) ;
//primary stats
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 9 , 75 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 380 ] + " : " ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 9 , 87 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 381 ] + " : " ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 9 , 99 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 382 ] + " : " ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 9 , 111 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 383 ] + " : " ) ) ;
2018-04-07 13:34:11 +02:00
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 69 , 87 , EFonts : : FONT_TINY , ETextAlignment : : BOTTOMRIGHT , Colors : : WHITE , std : : to_string ( attack ) ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 69 , 99 , EFonts : : FONT_TINY , ETextAlignment : : BOTTOMRIGHT , Colors : : WHITE , std : : to_string ( defense ) ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 69 , 111 , EFonts : : FONT_TINY , ETextAlignment : : BOTTOMRIGHT , Colors : : WHITE , std : : to_string ( power ) ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 69 , 123 , EFonts : : FONT_TINY , ETextAlignment : : BOTTOMRIGHT , Colors : : WHITE , std : : to_string ( knowledge ) ) ) ;
2018-04-07 13:34:11 +02:00
//morale+luck
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 9 , 131 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 384 ] + " : " ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 9 , 143 , EFonts : : FONT_TINY , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 385 ] + " : " ) ) ;
2018-04-07 13:34:11 +02:00
icons . push_back ( std : : make_shared < CAnimImage > ( " IMRL22 " , morale + 3 , 0 , 47 , 131 ) ) ;
icons . push_back ( std : : make_shared < CAnimImage > ( " ILCK22 " , luck + 3 , 0 , 47 , 143 ) ) ;
//spell points
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 39 , 174 , EFonts : : FONT_TINY , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 387 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 39 , 186 , EFonts : : FONT_TINY , ETextAlignment : : CENTER , Colors : : WHITE , std : : to_string ( currentSpellPoints ) + " / " + std : : to_string ( maxSpellPoints ) ) ) ;
2018-04-07 13:34:11 +02:00
}
2022-12-09 13:26:17 +02:00
BattleOptionsWindow : : BattleOptionsWindow ( BattleInterface * owner ) :
2022-11-27 02:26:02 +02:00
CWindowObject ( PLAYER_COLORED , " comopbck.bmp " )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
2011-12-22 16:05:19 +03:00
2018-04-07 13:34:11 +02:00
auto viewGrid = std : : make_shared < CToggleButton > ( Point ( 25 , 56 ) , " sysopchk.def " , CGI - > generaltexth - > zelp [ 427 ] , [ = ] ( bool on ) { owner - > setPrintCellBorders ( on ) ; } ) ;
2014-08-03 14:16:19 +03:00
viewGrid - > setSelected ( settings [ " battle " ] [ " cellBorders " ] . Bool ( ) ) ;
2018-04-07 13:34:11 +02:00
toggles . push_back ( viewGrid ) ;
auto movementShadow = std : : make_shared < CToggleButton > ( Point ( 25 , 89 ) , " sysopchk.def " , CGI - > generaltexth - > zelp [ 428 ] , [ = ] ( bool on ) { owner - > setPrintStackRange ( on ) ; } ) ;
2014-08-03 14:16:19 +03:00
movementShadow - > setSelected ( settings [ " battle " ] [ " stackRange " ] . Bool ( ) ) ;
2018-04-07 13:34:11 +02:00
toggles . push_back ( movementShadow ) ;
auto mouseShadow = std : : make_shared < CToggleButton > ( Point ( 25 , 122 ) , " sysopchk.def " , CGI - > generaltexth - > zelp [ 429 ] , [ = ] ( bool on ) { owner - > setPrintMouseShadow ( on ) ; } ) ;
2014-08-03 14:16:19 +03:00
mouseShadow - > setSelected ( settings [ " battle " ] [ " mouseShadow " ] . Bool ( ) ) ;
2018-04-07 13:34:11 +02:00
toggles . push_back ( mouseShadow ) ;
animSpeeds = std : : make_shared < CToggleGroup > ( [ = ] ( int value ) { owner - > setAnimSpeed ( value ) ; } ) ;
std : : shared_ptr < CToggleButton > toggle ;
toggle = std : : make_shared < CToggleButton > ( Point ( 28 , 225 ) , " sysopb9.def " , CGI - > generaltexth - > zelp [ 422 ] ) ;
animSpeeds - > addToggle ( 40 , toggle ) ;
toggle = std : : make_shared < CToggleButton > ( Point ( 92 , 225 ) , " sysob10.def " , CGI - > generaltexth - > zelp [ 423 ] ) ;
animSpeeds - > addToggle ( 63 , toggle ) ;
toggle = std : : make_shared < CToggleButton > ( Point ( 156 , 225 ) , " sysob11.def " , CGI - > generaltexth - > zelp [ 424 ] ) ;
animSpeeds - > addToggle ( 100 , toggle ) ;
2014-08-03 14:16:19 +03:00
animSpeeds - > setSelected ( owner - > getAnimSpeed ( ) ) ;
2018-04-07 13:34:11 +02:00
setToDefault = std : : make_shared < CButton > ( Point ( 246 , 359 ) , " codefaul.def " , CGI - > generaltexth - > zelp [ 393 ] , [ & ] ( ) { bDefaultf ( ) ; } ) ;
2014-08-03 14:16:19 +03:00
setToDefault - > setImageOrder ( 1 , 0 , 2 , 3 ) ;
2018-04-07 13:34:11 +02:00
exit = std : : make_shared < CButton > ( Point ( 357 , 359 ) , " soretrn.def " , CGI - > generaltexth - > zelp [ 392 ] , [ & ] ( ) { bExitf ( ) ; } , SDLK_RETURN ) ;
2014-08-03 14:16:19 +03:00
exit - > setImageOrder ( 1 , 0 , 2 , 3 ) ;
2011-12-22 16:05:19 +03:00
//creating labels
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 242 , 32 , FONT_BIG , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 392 ] ) ) ; //window title
labels . push_back ( std : : make_shared < CLabel > ( 122 , 214 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 393 ] ) ) ; //animation speed
labels . push_back ( std : : make_shared < CLabel > ( 122 , 293 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 394 ] ) ) ; //music volume
labels . push_back ( std : : make_shared < CLabel > ( 122 , 359 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 395 ] ) ) ; //effects' volume
labels . push_back ( std : : make_shared < CLabel > ( 353 , 66 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 396 ] ) ) ; //auto - combat options
labels . push_back ( std : : make_shared < CLabel > ( 353 , 265 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 397 ] ) ) ; //creature info
2011-12-22 16:05:19 +03:00
//auto - combat options
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 283 , 86 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 398 ] ) ) ; //creatures
labels . push_back ( std : : make_shared < CLabel > ( 283 , 116 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 399 ] ) ) ; //spells
labels . push_back ( std : : make_shared < CLabel > ( 283 , 146 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 400 ] ) ) ; //catapult
labels . push_back ( std : : make_shared < CLabel > ( 283 , 176 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 151 ] ) ) ; //ballista
labels . push_back ( std : : make_shared < CLabel > ( 283 , 206 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 401 ] ) ) ; //first aid tent
2011-12-22 16:05:19 +03:00
//creature info
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 283 , 285 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 402 ] ) ) ; //all stats
labels . push_back ( std : : make_shared < CLabel > ( 283 , 315 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 403 ] ) ) ; //spells only
2011-12-22 16:05:19 +03:00
//general options
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 61 , 57 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 404 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 61 , 90 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 405 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 61 , 123 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 406 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 61 , 156 , FONT_MEDIUM , ETextAlignment : : TOPLEFT , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 407 ] ) ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleOptionsWindow : : bDefaultf ( )
2011-12-22 16:05:19 +03:00
{
2014-08-03 14:16:19 +03:00
//TODO: implement
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleOptionsWindow : : bExitf ( )
2011-12-22 16:05:19 +03:00
{
2018-07-25 00:36:48 +02:00
close ( ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
BattleResultWindow : : BattleResultWindow ( const BattleResult & br , CPlayerInterface & _owner )
2018-04-07 13:34:11 +02:00
: owner ( _owner )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
pos = genRect ( 561 , 470 , ( screen - > w - 800 ) / 2 + 165 , ( screen - > h - 600 ) / 2 + 19 ) ;
background = std : : make_shared < CPicture > ( " CPRESULT " ) ;
background - > colorize ( owner . playerID ) ;
2012-05-13 18:04:21 +03:00
2018-04-07 13:34:11 +02:00
exit = std : : make_shared < CButton > ( Point ( 384 , 505 ) , " iok6432.def " , std : : make_pair ( " " , " " ) , [ & ] ( ) { bExitf ( ) ; } , SDLK_RETURN ) ;
2018-03-17 06:23:22 +02:00
exit - > setBorderColor ( Colors : : METALLIC_GOLD ) ;
2011-12-22 16:05:19 +03:00
2022-04-16 12:18:41 +02:00
if ( br . winner = = 0 ) //attacker won
2011-12-22 16:05:19 +03:00
{
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 59 , 124 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 410 ] ) ) ;
2011-12-22 16:05:19 +03:00
}
2022-04-16 12:18:41 +02:00
else
2011-12-22 16:05:19 +03:00
{
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 59 , 124 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 411 ] ) ) ;
2022-04-16 12:18:41 +02:00
}
if ( br . winner = = 1 )
{
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 412 , 124 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 410 ] ) ) ;
2011-12-22 16:05:19 +03:00
}
2022-04-16 12:18:41 +02:00
else
{
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 408 , 124 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 411 ] ) ) ;
2022-04-16 12:18:41 +02:00
}
2011-12-22 16:05:19 +03:00
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 232 , 302 , FONT_BIG , ETextAlignment : : CENTER , Colors : : YELLOW , CGI - > generaltexth - > allTexts [ 407 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 232 , 332 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 408 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 232 , 428 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 409 ] ) ) ;
2011-12-22 16:05:19 +03:00
2013-06-23 14:25:48 +03:00
std : : string sideNames [ 2 ] = { " N/A " , " N/A " } ;
2011-12-22 16:05:19 +03:00
2013-06-23 14:25:48 +03:00
for ( int i = 0 ; i < 2 ; i + + )
2011-12-22 16:05:19 +03:00
{
2013-06-23 14:25:48 +03:00
auto heroInfo = owner . cb - > battleGetHeroInfo ( i ) ;
const int xs [ ] = { 21 , 392 } ;
2016-10-16 08:27:22 +02:00
if ( heroInfo . portrait > = 0 ) //attacking hero
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
icons . push_back ( std : : make_shared < CAnimImage > ( " PortraitsLarge " , heroInfo . portrait , 0 , xs [ i ] , 38 ) ) ;
2013-06-23 14:25:48 +03:00
sideNames [ i ] = heroInfo . name ;
2011-12-22 16:05:19 +03:00
}
2013-06-23 14:25:48 +03:00
else
2011-12-22 16:05:19 +03:00
{
2013-06-23 14:25:48 +03:00
auto stacks = owner . cb - > battleGetAllStacks ( ) ;
2018-04-07 13:34:11 +02:00
vstd : : erase_if ( stacks , [ i ] ( const CStack * stack ) //erase stack of other side and not coming from garrison
{
return stack - > side ! = i | | ! stack - > base ;
} ) ;
auto best = vstd : : maxElementByFun ( stacks , [ ] ( const CStack * stack )
{
return stack - > type - > AIValue ;
} ) ;
2013-06-23 14:25:48 +03:00
if ( best ! = stacks . end ( ) ) //should be always but to be safe...
2011-12-22 16:05:19 +03:00
{
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
icons . push_back ( std : : make_shared < CAnimImage > ( " TWCRPORT " , ( * best ) - > type - > getIconIndex ( ) , 0 , xs [ i ] , 38 ) ) ;
sideNames [ i ] = ( * best ) - > type - > getPluralName ( ) ;
2011-12-22 16:05:19 +03:00
}
}
}
//printing attacker and defender's names
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 89 , 37 , FONT_SMALL , ETextAlignment : : TOPLEFT , Colors : : WHITE , sideNames [ 0 ] ) ) ;
labels . push_back ( std : : make_shared < CLabel > ( 381 , 53 , FONT_SMALL , ETextAlignment : : BOTTOMRIGHT , Colors : : WHITE , sideNames [ 1 ] ) ) ;
2012-05-13 18:04:21 +03:00
2013-06-23 14:25:48 +03:00
//printing casualties
2011-12-22 16:05:19 +03:00
for ( int step = 0 ; step < 2 ; + + step )
{
if ( br . casualties [ step ] . size ( ) = = 0 )
{
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 235 , 360 + 97 * step , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ 523 ] ) ) ;
2011-12-22 16:05:19 +03:00
}
else
{
2020-10-01 10:38:06 +02:00
int xPos = 235 - ( ( int ) br . casualties [ step ] . size ( ) * 32 + ( ( int ) br . casualties [ step ] . size ( ) - 1 ) * 10 ) / 2 ; //increment by 42 with each picture
2018-04-07 13:34:11 +02:00
int yPos = 344 + step * 97 ;
2013-06-29 16:05:48 +03:00
for ( auto & elem : br . casualties [ step ] )
2011-12-22 16:05:19 +03:00
{
Entities redesign and a few ERM features
* Made most Handlers derived from CHandlerBase and moved service API there.
* Declared existing Entity APIs.
* Added basic script context caching
* Started Lua script module
* Started Lua spell effect API
* Started script state persistence
* Started battle info callback binding
* CommitPackage removed
* Extracted spells::Caster to own header; Expanded Spell API.
* implemented !!MC:S, !!FU:E, !!FU:P, !!MA, !!VR:H, !!VR:C
* !!BU:C, !!BU:E, !!BU:G, !!BU:M implemented
* Allow use of "MC:S@varName@" to declare normal variable (technically v-variable with string key)
* Re-enabled VERM macros.
* !?GM0 added
* !?TM implemented
* Added !!MF:N
* Started !?OB, !!BM, !!HE, !!OW, !!UN
* Added basic support of w-variables
* Added support for ERM indirect variables
* Made !?FU regular trigger
* !!re (ERA loop receiver) implemented
* Fixed ERM receivers with zero args.
2018-03-17 16:58:30 +02:00
icons . push_back ( std : : make_shared < CAnimImage > ( " CPRSMALL " , CGI - > creatures ( ) - > getByIndex ( elem . first ) - > getIconIndex ( ) , 0 , xPos , yPos ) ) ;
2011-12-22 16:05:19 +03:00
std : : ostringstream amount ;
2013-06-29 16:05:48 +03:00
amount < < elem . second ;
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( xPos + 16 , yPos + 42 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , amount . str ( ) ) ) ;
2011-12-22 16:05:19 +03:00
xPos + = 42 ;
}
}
}
//printing result description
2013-06-23 14:25:48 +03:00
bool weAreAttacker = ! ( owner . cb - > battleGetMySide ( ) ) ;
2011-12-22 16:05:19 +03:00
if ( ( br . winner = = 0 & & weAreAttacker ) | | ( br . winner = = 1 & & ! weAreAttacker ) ) //we've won
{
2018-04-07 13:34:11 +02:00
int text = 304 ;
2011-12-22 16:05:19 +03:00
switch ( br . result )
{
2018-04-07 13:34:11 +02:00
case BattleResult : : NORMAL :
break ;
case BattleResult : : ESCAPE :
text = 303 ;
break ;
case BattleResult : : SURRENDER :
text = 302 ;
break ;
default :
logGlobal - > error ( " Invalid battle result code %d. Assumed normal. " , static_cast < int > ( br . result ) ) ;
break ;
2011-12-22 16:05:19 +03:00
}
2022-11-13 14:24:15 +02:00
CCS - > musich - > playMusic ( " Music/Win Battle " , false , true ) ;
2012-08-21 20:37:06 +03:00
CCS - > videoh - > open ( " WIN3.BIK " ) ;
2011-12-22 16:05:19 +03:00
std : : string str = CGI - > generaltexth - > allTexts [ text ] ;
2013-06-23 14:25:48 +03:00
const CGHeroInstance * ourHero = owner . cb - > battleGetMyHero ( ) ;
2011-12-22 16:05:19 +03:00
if ( ourHero )
{
str + = CGI - > generaltexth - > allTexts [ 305 ] ;
2018-04-07 13:34:11 +02:00
boost : : algorithm : : replace_first ( str , " %s " , ourHero - > name ) ;
boost : : algorithm : : replace_first ( str , " %d " , boost : : lexical_cast < std : : string > ( br . exp [ weAreAttacker ? 0 : 1 ] ) ) ;
2011-12-22 16:05:19 +03:00
}
2016-10-16 08:27:22 +02:00
2022-11-26 23:12:20 +02:00
description = std : : make_shared < CTextBox > ( str , Rect ( 69 , 203 , 330 , 68 ) , 0 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE ) ;
2011-12-22 16:05:19 +03:00
}
else // we lose
{
2018-04-07 13:34:11 +02:00
int text = 311 ;
std : : string musicName = " Music/LoseCombat " ;
std : : string videoName = " LBSTART.BIK " ;
2011-12-22 16:05:19 +03:00
switch ( br . result )
{
2013-02-23 00:03:56 +03:00
case BattleResult : : NORMAL :
2018-04-07 13:34:11 +02:00
break ;
case BattleResult : : ESCAPE :
musicName = " Music/Retreat Battle " ;
videoName = " RTSTART.BIK " ;
text = 310 ;
break ;
2013-02-23 00:03:56 +03:00
case BattleResult : : SURRENDER :
2018-04-07 13:34:11 +02:00
musicName = " Music/Surrender Battle " ;
videoName = " SURRENDER.BIK " ;
text = 309 ;
break ;
default :
logGlobal - > error ( " Invalid battle result code %d. Assumed normal. " , static_cast < int > ( br . result ) ) ;
break ;
2011-12-22 16:05:19 +03:00
}
2022-11-13 14:24:15 +02:00
CCS - > musich - > playMusic ( musicName , false , true ) ;
2018-04-07 13:34:11 +02:00
CCS - > videoh - > open ( videoName ) ;
2022-11-26 23:12:20 +02:00
labels . push_back ( std : : make_shared < CLabel > ( 235 , 235 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE , CGI - > generaltexth - > allTexts [ text ] ) ) ;
2011-12-22 16:05:19 +03:00
}
}
2022-12-09 13:26:17 +02:00
void BattleResultWindow : : activate ( )
2011-12-22 16:05:19 +03:00
{
2013-06-23 14:25:48 +03:00
owner . showingDialog - > set ( true ) ;
2012-05-26 13:02:55 +03:00
CIntObject : : activate ( ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleResultWindow : : show ( SDL_Surface * to )
2011-12-22 16:05:19 +03:00
{
2012-05-13 18:04:21 +03:00
CIntObject : : show ( to ) ;
2012-05-26 13:02:55 +03:00
CCS - > videoh - > update ( pos . x + 107 , pos . y + 70 , screen , true , false ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void BattleResultWindow : : bExitf ( )
2011-12-22 16:05:19 +03:00
{
2013-06-23 14:25:48 +03:00
CPlayerInterface & intTmp = owner ; //copy reference because "this" will be destructed soon
2018-07-25 00:36:48 +02:00
close ( ) ;
2022-12-09 13:26:17 +02:00
if ( dynamic_cast < BattleInterface * > ( GH . topInt ( ) . get ( ) ) )
2013-06-23 14:25:48 +03:00
GH . popInts ( 1 ) ; //pop battle interface if present
2016-10-16 08:27:22 +02:00
//Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle,
2013-06-23 14:25:48 +03:00
//so we can be sure that there is no dialogs left on GUI stack.
intTmp . showingDialog - > setn ( false ) ;
2011-12-22 16:05:19 +03:00
CCS - > videoh - > close ( ) ;
}
2022-12-09 13:26:17 +02:00
void ClickableHex : : hover ( bool on )
2011-12-22 16:05:19 +03:00
{
hovered = on ;
//Hoverable::hover(on);
if ( ! on & & setAlterText )
{
2022-11-18 17:54:10 +02:00
myInterface - > controlPanel - > console - > clear ( ) ;
2011-12-22 16:05:19 +03:00
setAlterText = false ;
}
}
2022-12-09 13:26:17 +02:00
ClickableHex : : ClickableHex ( ) : setAlterText ( false ) , myNumber ( - 1 ) , strictHovered ( false ) , myInterface ( nullptr )
2011-12-22 16:05:19 +03:00
{
2012-06-02 18:16:54 +03:00
addUsedEvents ( LCLICK | RCLICK | HOVER | MOVE ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void ClickableHex : : mouseMoved ( const SDL_MouseMotionEvent & sEvent )
2011-12-22 16:05:19 +03:00
{
2022-11-17 23:57:51 +02:00
strictHovered = myInterface - > fieldController - > isPixelInHex ( Point ( sEvent . x - pos . x , sEvent . y - pos . y ) ) ;
2011-12-22 16:05:19 +03:00
if ( hovered & & strictHovered ) //print attacked creature to console
{
2013-11-03 19:44:47 +03:00
const CStack * attackedStack = myInterface - > getCurrentPlayerInterface ( ) - > cb - > battleGetStackByPos ( myNumber ) ;
2022-11-18 17:54:10 +02:00
if ( attackedStack ! = nullptr & &
2013-11-03 19:44:47 +03:00
attackedStack - > owner ! = myInterface - > getCurrentPlayerInterface ( ) - > playerID & &
2011-12-22 16:05:19 +03:00
attackedStack - > alive ( ) )
{
2017-07-04 13:24:46 +02:00
MetaString text ;
text . addTxt ( MetaString : : GENERAL_TXT , 220 ) ;
attackedStack - > addNameReplacement ( text ) ;
2022-11-18 17:54:10 +02:00
myInterface - > controlPanel - > console - > write ( text . toString ( ) ) ;
2011-12-22 16:05:19 +03:00
setAlterText = true ;
}
}
else if ( setAlterText )
{
2022-11-18 17:54:10 +02:00
myInterface - > controlPanel - > console - > clear ( ) ;
2011-12-22 16:05:19 +03:00
setAlterText = false ;
}
}
2022-12-09 13:26:17 +02:00
void ClickableHex : : clickLeft ( tribool down , bool previousState )
2011-12-22 16:05:19 +03:00
{
if ( ! down & & hovered & & strictHovered ) //we've been really clicked!
{
myInterface - > hexLclicked ( myNumber ) ;
}
}
2022-12-09 13:26:17 +02:00
void ClickableHex : : clickRight ( tribool down , bool previousState )
2011-12-22 16:05:19 +03:00
{
2013-11-03 19:44:47 +03:00
const CStack * myst = myInterface - > getCurrentPlayerInterface ( ) - > cb - > battleGetStackByPos ( myNumber ) ; //stack info
2013-06-26 14:18:27 +03:00
if ( hovered & & strictHovered & & myst ! = nullptr )
2011-12-22 16:05:19 +03:00
{
if ( ! myst - > alive ( ) ) return ;
if ( down )
{
2018-07-25 00:36:48 +02:00
GH . pushIntT < CStackWindow > ( myst , true ) ;
2011-12-22 16:05:19 +03:00
}
}
}
2022-12-09 13:26:17 +02:00
StackQueue : : StackQueue ( bool Embedded , BattleInterface * _owner )
2017-07-20 06:08:49 +02:00
: embedded ( Embedded ) ,
owner ( _owner )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
2011-12-22 16:05:19 +03:00
if ( embedded )
{
pos . w = QUEUE_SIZE * 37 ;
2012-08-28 19:28:21 +03:00
pos . h = 46 ;
2011-12-22 16:05:19 +03:00
pos . x = screen - > w / 2 - pos . w / 2 ;
pos . y = ( screen - > h - 600 ) / 2 + 10 ;
2017-07-20 06:08:49 +02:00
icons = std : : make_shared < CAnimation > ( " CPRSMALL " ) ;
stateIcons = std : : make_shared < CAnimation > ( " VCMI/BATTLEQUEUE/STATESSMALL " ) ;
2011-12-22 16:05:19 +03:00
}
else
{
2012-08-28 19:28:21 +03:00
pos . w = 800 ;
pos . h = 85 ;
2017-07-20 06:08:49 +02:00
2018-04-07 13:34:11 +02:00
background = std : : make_shared < CFilledTexture > ( " DIBOXBCK " , Rect ( 0 , 0 , pos . w , pos . h ) ) ;
2017-07-20 06:08:49 +02:00
icons = std : : make_shared < CAnimation > ( " TWCRPORT " ) ;
stateIcons = std : : make_shared < CAnimation > ( " VCMI/BATTLEQUEUE/STATESSMALL " ) ;
//TODO: where use big icons?
//stateIcons = std::make_shared<CAnimation>("VCMI/BATTLEQUEUE/STATESBIG");
2011-12-22 16:05:19 +03:00
}
2017-07-20 06:08:49 +02:00
stateIcons - > preload ( ) ;
2011-12-22 16:05:19 +03:00
stackBoxes . resize ( QUEUE_SIZE ) ;
2012-08-28 19:28:21 +03:00
for ( int i = 0 ; i < stackBoxes . size ( ) ; i + + )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
stackBoxes [ i ] = std : : make_shared < StackBox > ( this ) ;
stackBoxes [ i ] - > moveBy ( Point ( 1 + ( embedded ? 36 : 80 ) * i , 0 ) ) ;
2011-12-22 16:05:19 +03:00
}
}
2022-12-09 13:26:17 +02:00
void StackQueue : : update ( )
2011-12-22 16:05:19 +03:00
{
2017-07-20 06:08:49 +02:00
std : : vector < battle : : Units > queueData ;
2011-12-22 16:05:19 +03:00
2017-07-20 06:08:49 +02:00
owner - > getCurrentPlayerInterface ( ) - > cb - > battleGetTurnOrder ( queueData , stackBoxes . size ( ) , 0 ) ;
2011-12-22 16:05:19 +03:00
2017-07-20 06:08:49 +02:00
size_t boxIndex = 0 ;
for ( size_t turn = 0 ; turn < queueData . size ( ) & & boxIndex < stackBoxes . size ( ) ; turn + + )
2011-12-22 16:05:19 +03:00
{
2017-07-20 06:08:49 +02:00
for ( size_t unitIndex = 0 ; unitIndex < queueData [ turn ] . size ( ) & & boxIndex < stackBoxes . size ( ) ; boxIndex + + , unitIndex + + )
2018-04-07 13:34:11 +02:00
stackBoxes [ boxIndex ] - > setUnit ( queueData [ turn ] [ unitIndex ] , turn ) ;
2011-12-22 16:05:19 +03:00
}
2017-07-20 06:08:49 +02:00
for ( ; boxIndex < stackBoxes . size ( ) ; boxIndex + + )
2018-04-07 13:34:11 +02:00
stackBoxes [ boxIndex ] - > setUnit ( nullptr ) ;
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
int32_t StackQueue : : getSiegeShooterIconID ( )
2022-11-29 14:59:50 +02:00
{
2022-12-02 00:06:57 +02:00
return owner - > siegeController - > getSiegedTown ( ) - > town - > faction - > index ;
2022-11-29 14:59:50 +02:00
}
2022-12-09 13:26:17 +02:00
StackQueue : : StackBox : : StackBox ( StackQueue * owner ) :
2022-11-29 14:59:50 +02:00
owner ( owner )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
OBJECT_CONSTRUCTION_CAPTURING ( 255 - DISPOSE ) ;
background = std : : make_shared < CPicture > ( owner - > embedded ? " StackQueueSmall " : " StackQueueLarge " ) ;
2017-07-20 06:08:49 +02:00
2018-04-07 13:34:11 +02:00
pos . w = background - > pos . w ;
pos . h = background - > pos . h ;
2012-08-28 19:28:21 +03:00
2017-07-20 06:08:49 +02:00
if ( owner - > embedded )
{
2018-04-07 13:34:11 +02:00
icon = std : : make_shared < CAnimImage > ( owner - > icons , 0 , 0 , 5 , 2 ) ;
2022-11-26 23:12:20 +02:00
amount = std : : make_shared < CLabel > ( pos . w / 2 , pos . h - 7 , FONT_SMALL , ETextAlignment : : CENTER , Colors : : WHITE ) ;
2017-07-20 06:08:49 +02:00
}
2011-12-22 16:05:19 +03:00
else
2017-07-20 06:08:49 +02:00
{
2018-04-07 13:34:11 +02:00
icon = std : : make_shared < CAnimImage > ( owner - > icons , 0 , 0 , 9 , 1 ) ;
2022-11-26 23:12:20 +02:00
amount = std : : make_shared < CLabel > ( pos . w / 2 , pos . h - 8 , FONT_MEDIUM , ETextAlignment : : CENTER , Colors : : WHITE ) ;
2011-12-22 16:05:19 +03:00
2017-07-20 06:08:49 +02:00
int icon_x = pos . w - 17 ;
int icon_y = pos . h - 18 ;
2018-04-07 13:34:11 +02:00
stateIcon = std : : make_shared < CAnimImage > ( owner - > stateIcons , 0 , 0 , icon_x , icon_y ) ;
2017-07-20 06:08:49 +02:00
stateIcon - > visible = false ;
}
2011-12-22 16:05:19 +03:00
}
2022-12-09 13:26:17 +02:00
void StackQueue : : StackBox : : setUnit ( const battle : : Unit * unit , size_t turn )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
if ( unit )
2011-12-22 16:05:19 +03:00
{
2018-04-07 13:34:11 +02:00
background - > colorize ( unit - > unitOwner ( ) ) ;
2017-07-20 06:08:49 +02:00
icon - > visible = true ;
2022-11-29 14:59:50 +02:00
// temporary code for mod compatibility:
// first, set icon that should definitely exist (arrow tower icon in base vcmi mod)
// second, try to switch to icon that should be provided by mod
// if mod is not up to date and does have arrow tower icon yet - second setFrame call will fail and retain previously set image
// for 1.2 release & later next line should be moved into 'else' block
icon - > setFrame ( unit - > creatureIconIndex ( ) , 0 ) ;
if ( unit - > unitType ( ) - > idNumber = = CreatureID : : ARROW_TOWERS )
icon - > setFrame ( owner - > getSiegeShooterIconID ( ) , 1 ) ;
2018-04-07 13:34:11 +02:00
amount - > setText ( makeNumberShort ( unit - > getCount ( ) ) ) ;
2017-07-20 06:08:49 +02:00
if ( stateIcon )
{
2020-10-01 10:38:06 +02:00
if ( unit - > defended ( ( int ) turn ) | | ( turn > 0 & & unit - > defended ( ( int ) turn - 1 ) ) )
2017-07-20 06:08:49 +02:00
{
stateIcon - > setFrame ( 0 , 0 ) ;
stateIcon - > visible = true ;
}
2020-10-01 10:38:06 +02:00
else if ( unit - > waited ( ( int ) turn ) )
2017-07-20 06:08:49 +02:00
{
stateIcon - > setFrame ( 1 , 0 ) ;
stateIcon - > visible = true ;
}
else
{
stateIcon - > visible = false ;
}
}
2011-12-22 16:05:19 +03:00
}
else
2017-07-20 06:08:49 +02:00
{
2018-04-07 13:34:11 +02:00
background - > colorize ( PlayerColor : : NEUTRAL ) ;
2017-07-20 06:08:49 +02:00
icon - > visible = false ;
icon - > setFrame ( 0 ) ;
amount - > setText ( " " ) ;
2011-12-22 16:05:19 +03:00
2017-07-20 06:08:49 +02:00
if ( stateIcon )
stateIcon - > visible = false ;
}
2012-05-13 18:04:21 +03:00
}