2009-01-15 17:01:08 +00:00
#include "CBattleInterface.h"
#include "CGameInfo.h"
#include "hch/CLodHandler.h"
#include "SDL_Extensions.h"
#include "CAdvmapInterface.h"
#include "AdventureMapButton.h"
#include "hch/CObjectHandler.h"
#include "hch/CHeroHandler.h"
#include "hch/CDefHandler.h"
2009-01-14 19:07:57 +00:00
#include "hch/CSpellHandler.h"
2009-01-15 17:01:08 +00:00
#include "CMessage.h"
#include "CCursorHandler.h"
#include "CCallback.h"
#include "CGameState.h"
#include "hch/CGeneralTextHandler.h"
#include "client/CCreatureAnimation.h"
#include "client/Graphics.h"
#include "client/CSpellWindow.h"
#include "client/CConfigHandler.h"
#include <queue>
#include <sstream>
#include "lib/CondSh.h"
#include "lib/NetPacks.h"
#include <boost/assign/list_of.hpp>
#ifndef __GNUC__
const double M_PI = 3.14159265358979323846 ;
#else
#define _USE_MATH_DEFINES
#include <cmath>
#endif
extern SDL_Surface * screen ;
extern TTF_Font * TNRB16 , * TNR , * GEOR13 , * GEORXX , * GEORM , * GEOR16 ;
extern SDL_Color zwykly ;
2009-03-28 18:46:20 +00:00
BattleSettings CBattleInterface :: settings ;
2009-01-15 17:01:08 +00:00
struct CMP_stack2
{
inline bool operator ()( const CStack & a , const CStack & b )
{
2009-04-04 19:26:41 +00:00
return ( a . Speed ()) > ( b . Speed ());
2009-01-15 17:01:08 +00:00
}
} cmpst2 ;
CBattleInterface :: CBattleInterface ( CCreatureSet * army1 , CCreatureSet * army2 , CGHeroInstance * hero1 , CGHeroInstance * hero2 , const SDL_Rect & myRect )
2009-03-28 18:46:20 +00:00
: attackingHeroInstance ( hero1 ), defendingHeroInstance ( hero2 ), animCount ( 0 ), activeStack ( - 1 ), givenCommand ( NULL ),
attackingInfo ( NULL ), myTurn ( false ), resWindow ( NULL ), showStackQueue ( false ),
spellDestSelectMode ( false ), spellToCast ( NULL ), previouslyHoveredHex ( - 1 ), moveStarted ( false ), mouseHoveredStack ( - 1 )
2009-01-15 17:01:08 +00:00
{
pos = myRect ;
strongInterest = true ;
givenCommand = new CondSh < BattleAction *> ( NULL );
//initializing armies
this -> army1 = army1 ;
this -> army2 = army2 ;
std :: map < int , CStack > stacks = LOCPLINT -> cb -> battleGetStacks ();
for ( std :: map < int , CStack >:: iterator b = stacks . begin (); b != stacks . end (); ++ b )
{
std :: pair < int , int > coords = CBattleHex :: getXYUnitAnim ( b -> second . position , b -> second . owner == attackingHeroInstance -> tempOwner , b -> second . creature );
creAnims [ b -> second . ID ] = ( new CCreatureAnimation ( b -> second . creature -> animDefName ));
creAnims [ b -> second . ID ] -> setType ( 2 );
creAnims [ b -> second . ID ] -> pos = genRect ( creAnims [ b -> second . ID ] -> fullHeight , creAnims [ b -> second . ID ] -> fullWidth , coords . first , coords . second );
creDir [ b -> second . ID ] = b -> second . owner == attackingHeroInstance -> tempOwner ;
}
//preparing menu background and terrain
std :: vector < std :: string > & backref = graphics -> battleBacks [ LOCPLINT -> cb -> battleGetBattlefieldType () ];
background = BitmapHandler :: loadBitmap ( backref [ rand () % backref . size ()] );
menu = BitmapHandler :: loadBitmap ( "CBAR.BMP" );
graphics -> blueToPlayersAdv ( menu , hero1 -> tempOwner );
//preparing graphics for displaying amounts of creatures
amountNormal = BitmapHandler :: loadBitmap ( "CMNUMWIN.BMP" );
CSDL_Ext :: alphaTransform ( amountNormal );
for ( int g = 0 ; g < amountNormal -> format -> palette -> ncolors ; ++ g )
{
if (( amountNormal -> format -> palette -> colors + g ) -> b != 132 &&
( amountNormal -> format -> palette -> colors + g ) -> g != 231 &&
( amountNormal -> format -> palette -> colors + g ) -> r != 255 ) //it's not yellow border
{
( amountNormal -> format -> palette -> colors + g ) -> r = ( float )(( amountNormal -> format -> palette -> colors + g ) -> r ) * 0.54f ;
( amountNormal -> format -> palette -> colors + g ) -> g = ( float )(( amountNormal -> format -> palette -> colors + g ) -> g ) * 0.19f ;
( amountNormal -> format -> palette -> colors + g ) -> b = ( float )(( amountNormal -> format -> palette -> colors + g ) -> b ) * 0.93f ;
}
}
amountPositive = BitmapHandler :: loadBitmap ( "CMNUMWIN.BMP" );
CSDL_Ext :: alphaTransform ( amountPositive );
for ( int g = 0 ; g < amountPositive -> format -> palette -> ncolors ; ++ g )
{
if (( amountPositive -> format -> palette -> colors + g ) -> b != 132 &&
( amountPositive -> format -> palette -> colors + g ) -> g != 231 &&
( amountPositive -> format -> palette -> colors + g ) -> r != 255 ) //it's not yellow border
{
( amountPositive -> format -> palette -> colors + g ) -> r = ( float )(( amountPositive -> format -> palette -> colors + g ) -> r ) * 0.18f ;
( amountPositive -> format -> palette -> colors + g ) -> g = ( float )(( amountPositive -> format -> palette -> colors + g ) -> g ) * 1.00f ;
( amountPositive -> format -> palette -> colors + g ) -> b = ( float )(( amountPositive -> format -> palette -> colors + g ) -> b ) * 0.18f ;
}
}
amountNegative = BitmapHandler :: loadBitmap ( "CMNUMWIN.BMP" );
CSDL_Ext :: alphaTransform ( amountNegative );
for ( int g = 0 ; g < amountNegative -> format -> palette -> ncolors ; ++ g )
{
if (( amountNegative -> format -> palette -> colors + g ) -> b != 132 &&
( amountNegative -> format -> palette -> colors + g ) -> g != 231 &&
( amountNegative -> format -> palette -> colors + g ) -> r != 255 ) //it's not yellow border
{
( amountNegative -> format -> palette -> colors + g ) -> r = ( float )(( amountNegative -> format -> palette -> colors + g ) -> r ) * 1.00f ;
( amountNegative -> format -> palette -> colors + g ) -> g = ( float )(( amountNegative -> format -> palette -> colors + g ) -> g ) * 0.18f ;
( amountNegative -> format -> palette -> colors + g ) -> b = ( float )(( amountNegative -> format -> palette -> colors + g ) -> b ) * 0.18f ;
}
}
amountEffNeutral = BitmapHandler :: loadBitmap ( "CMNUMWIN.BMP" );
CSDL_Ext :: alphaTransform ( amountNegative );
for ( int g = 0 ; g < amountNegative -> format -> palette -> ncolors ; ++ g )
{
if (( amountNegative -> format -> palette -> colors + g ) -> b != 132 &&
( amountNegative -> format -> palette -> colors + g ) -> g != 231 &&
( amountNegative -> format -> palette -> colors + g ) -> r != 255 ) //it's not yellow border
{
( amountNegative -> format -> palette -> colors + g ) -> r = ( float )(( amountNegative -> format -> palette -> colors + g ) -> r ) * 1.00f ;
( amountNegative -> format -> palette -> colors + g ) -> g = ( float )(( amountNegative -> format -> palette -> colors + g ) -> g ) * 1.00f ;
( amountNegative -> format -> palette -> colors + g ) -> b = ( float )(( amountNegative -> format -> palette -> colors + g ) -> b ) * 0.18f ;
}
}
////blitting menu background and terrain
blitAt ( background , pos . x , pos . y );
blitAt ( menu , pos . x , 556 + pos . y );
CSDL_Ext :: update ();
//preparing buttons and console
2009-01-29 18:07:31 +00:00
bOptions = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 381 ]. first , CGI -> generaltexth -> zelp [ 381 ]. second , boost :: bind ( & CBattleInterface :: bOptionsf , this ), 3 + pos . x , 561 + pos . y , "icm003.def" , SDLK_o );
bSurrender = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 379 ]. first , CGI -> generaltexth -> zelp [ 379 ]. second , boost :: bind ( & CBattleInterface :: bSurrenderf , this ), 54 + pos . x , 561 + pos . y , "icm001.def" , SDLK_s );
bFlee = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 380 ]. first , CGI -> generaltexth -> zelp [ 380 ]. second , boost :: bind ( & CBattleInterface :: bFleef , this ), 105 + pos . x , 561 + pos . y , "icm002.def" , SDLK_r );
bAutofight = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 382 ]. first , CGI -> generaltexth -> zelp [ 382 ]. second , boost :: bind ( & CBattleInterface :: bAutofightf , this ), 157 + pos . x , 561 + pos . y , "icm004.def" , SDLK_a );
bSpell = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 385 ]. first , CGI -> generaltexth -> zelp [ 385 ]. second , boost :: bind ( & CBattleInterface :: bSpellf , this ), 645 + pos . x , 561 + pos . y , "icm005.def" , SDLK_c );
bWait = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 386 ]. first , CGI -> generaltexth -> zelp [ 386 ]. second , boost :: bind ( & CBattleInterface :: bWaitf , this ), 696 + pos . x , 561 + pos . y , "icm006.def" , SDLK_w );
bDefence = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 387 ]. first , CGI -> generaltexth -> zelp [ 387 ]. second , boost :: bind ( & CBattleInterface :: bDefencef , this ), 747 + pos . x , 561 + pos . y , "icm007.def" , SDLK_d );
2009-01-15 17:01:08 +00:00
bDefence -> assignedKeys . insert ( SDLK_SPACE );
bConsoleUp = new AdventureMapButton ( std :: string (), std :: string (), boost :: bind ( & CBattleInterface :: bConsoleUpf , this ), 624 + pos . x , 561 + pos . y , "ComSlide.def" , SDLK_UP );
bConsoleDown = new AdventureMapButton ( std :: string (), std :: string (), boost :: bind ( & CBattleInterface :: bConsoleDownf , this ), 624 + pos . x , 580 + pos . y , "ComSlide.def" , SDLK_DOWN );
bConsoleDown -> bitmapOffset = 2 ;
console = new CBattleConsole ();
console -> pos . x = 211 + pos . x ;
console -> pos . y = 560 + pos . y ;
console -> pos . w = 406 ;
console -> pos . h = 38 ;
//loading hero animations
if ( hero1 ) // attacking hero
{
attackingHero = new CBattleHero ( graphics -> battleHeroes [ hero1 -> type -> heroType ], 0 , 0 , false , hero1 -> tempOwner , hero1 -> tempOwner == LOCPLINT -> playerID ? hero1 : NULL , this );
attackingHero -> pos = genRect ( attackingHero -> dh -> ourImages [ 0 ]. bitmap -> h , attackingHero -> dh -> ourImages [ 0 ]. bitmap -> w , - 40 + pos . x , pos . y );
}
else
{
attackingHero = NULL ;
}
if ( hero2 ) // defending hero
{
defendingHero = new CBattleHero ( graphics -> battleHeroes [ hero2 -> type -> heroType ], 0 , 0 , true , hero2 -> tempOwner , hero2 -> tempOwner == LOCPLINT -> playerID ? hero2 : NULL , this );
defendingHero -> pos = genRect ( defendingHero -> dh -> ourImages [ 0 ]. bitmap -> h , defendingHero -> dh -> ourImages [ 0 ]. bitmap -> w , 690 + pos . x , pos . y );
}
else
{
defendingHero = NULL ;
}
//preparing cells and hexes
cellBorder = BitmapHandler :: loadBitmap ( "CCELLGRD.BMP" );
CSDL_Ext :: alphaTransform ( cellBorder );
cellShade = BitmapHandler :: loadBitmap ( "CCELLSHD.BMP" );
CSDL_Ext :: alphaTransform ( cellShade );
for ( int h = 0 ; h < BFIELD_SIZE ; ++ h )
{
bfield [ h ]. myNumber = h ;
int x = 14 + (( h / BFIELD_WIDTH ) % 2 == 0 ? 22 : 0 ) + 44 * ( h % BFIELD_WIDTH );
int y = 86 + 42 * ( h / BFIELD_WIDTH );
bfield [ h ]. pos = genRect ( cellShade -> h , cellShade -> w , x + pos . x , y + pos . y );
bfield [ h ]. accesible = true ;
bfield [ h ]. myInterface = this ;
}
//locking occupied positions on batlefield
for ( std :: map < int , CStack >:: iterator it = stacks . begin (); it != stacks . end (); ++ it ) //stacks gained at top of this function
{
bfield [ it -> second . position ]. accesible = false ;
}
//loading projectiles for units
for ( std :: map < int , CStack >:: iterator g = stacks . begin (); g != stacks . end (); ++ g )
{
if ( g -> second . creature -> isShooting () && CGI -> creh -> idToProjectile [ g -> second . creature -> idNumber ] != std :: string ())
{
idToProjectile [ g -> second . creature -> idNumber ] = CDefHandler :: giveDef ( CGI -> creh -> idToProjectile [ g -> second . creature -> idNumber ]);
if ( idToProjectile [ g -> second . creature -> idNumber ] -> ourImages . size () > 2 ) //add symmetric images
{
for ( int k = idToProjectile [ g -> second . creature -> idNumber ] -> ourImages . size () - 2 ; k > 1 ; -- k )
{
Cimage ci ;
ci . bitmap = CSDL_Ext :: rotate01 ( idToProjectile [ g -> second . creature -> idNumber ] -> ourImages [ k ]. bitmap );
ci . groupNumber = 0 ;
ci . imName = std :: string ();
idToProjectile [ g -> second . creature -> idNumber ] -> ourImages . push_back ( ci );
}
}
for ( int s = 0 ; s < idToProjectile [ g -> second . creature -> idNumber ] -> ourImages . size (); ++ s ) //alpha transforming
{
CSDL_Ext :: alphaTransform ( idToProjectile [ g -> second . creature -> idNumber ] -> ourImages [ s ]. bitmap );
}
}
}
//preparing graphic with cell borders
cellBorders = CSDL_Ext :: newSurface ( background -> w , background -> h , cellBorder );
//copying palette
for ( int g = 0 ; g < cellBorder -> format -> palette -> ncolors ; ++ g ) //we assume that cellBorders->format->palette->ncolors == 256
{
cellBorders -> format -> palette -> colors [ g ] = cellBorder -> format -> palette -> colors [ g ];
}
//palette copied
for ( int i = 0 ; i < BFIELD_HEIGHT ; ++ i ) //rows
{
for ( int j = 0 ; j < BFIELD_WIDTH - 2 ; ++ j ) //columns
{
int x = 58 + ( i % 2 == 0 ? 22 : 0 ) + 44 * j ;
int y = 86 + 42 * i ;
for ( int cellX = 0 ; cellX < cellBorder -> w ; ++ cellX )
{
for ( int cellY = 0 ; cellY < cellBorder -> h ; ++ cellY )
{
if ( y + cellY < cellBorders -> h && x + cellX < cellBorders -> w )
* (( Uint8 * ) cellBorders -> pixels + ( y + cellY ) * cellBorders -> pitch + ( x + cellX )) |= * (( Uint8 * ) cellBorder -> pixels + cellY * cellBorder -> pitch + cellX );
}
}
}
}
backgroundWithHexes = CSDL_Ext :: newSurface ( background -> w , background -> h , screen );
2009-02-09 14:50:32 +00:00
//preparing obstacle defs
std :: vector < CObstacleInstance > obst = LOCPLINT -> cb -> battleGetAllObstacles ();
for ( int t = 0 ; t < obst . size (); ++ t )
{
idToObstacle [ obst [ t ]. ID ] = CDefHandler :: giveDef ( CGI -> heroh -> obstacles [ obst [ t ]. ID ]. defName );
for ( int n = 0 ; n < idToObstacle [ obst [ t ]. ID ] -> ourImages . size (); ++ n )
{
SDL_SetColorKey ( idToObstacle [ obst [ t ]. ID ] -> ourImages [ n ]. bitmap , SDL_SRCCOLORKEY , SDL_MapRGB ( idToObstacle [ obst [ t ]. ID ] -> ourImages [ n ]. bitmap -> format , 0 , 255 , 255 ));
}
}
2009-03-21 16:03:07 +00:00
//initializing spellToEffect
spellToEffect [ 17 ] = 1 ; //lightning bolt
spellToEffect [ 18 ] = 10 ; //implosion
spellToEffect [ 27 ] = 27 ; //shield
spellToEffect [ 28 ] = 2 ; //air shield
spellToEffect [ 41 ] = 36 ; //bless
spellToEffect [ 42 ] = 40 ; //curse
spellToEffect [ 43 ] = 4 ; //bloodlust
spellToEffect [ 45 ] = 56 ; //weakness
spellToEffect [ 46 ] = 54 ; //stone skin
spellToEffect [ 48 ] = 0 ; //prayer
spellToEffect [ 49 ] = 20 ; //mirth
spellToEffect [ 50 ] = 30 ; //sorrow
spellToEffect [ 51 ] = 18 ; //fortune
spellToEffect [ 52 ] = 48 ; //misfortune
spellToEffect [ 53 ] = 31 ; //haste
spellToEffect [ 54 ] = 19 ; //slow
spellToEffect [ 56 ] = 17 ; //frenzy
spellToEffect [ 61 ] = 42 ; //forgetfulness
2009-01-15 17:01:08 +00:00
}
CBattleInterface ::~ CBattleInterface ()
{
SDL_FreeSurface ( background );
SDL_FreeSurface ( menu );
SDL_FreeSurface ( amountNormal );
SDL_FreeSurface ( amountNegative );
SDL_FreeSurface ( amountPositive );
SDL_FreeSurface ( amountEffNeutral );
SDL_FreeSurface ( cellBorders );
SDL_FreeSurface ( backgroundWithHexes );
delete bOptions ;
delete bSurrender ;
delete bFlee ;
delete bAutofight ;
delete bSpell ;
delete bWait ;
delete bDefence ;
delete bConsoleUp ;
delete bConsoleDown ;
delete console ;
delete givenCommand ;
delete attackingHero ;
delete defendingHero ;
SDL_FreeSurface ( cellBorder );
SDL_FreeSurface ( cellShade );
for ( std :: map < int , CCreatureAnimation * >:: iterator g = creAnims . begin (); g != creAnims . end (); ++ g )
delete g -> second ;
for ( std :: map < int , CDefHandler * >:: iterator g = idToProjectile . begin (); g != idToProjectile . end (); ++ g )
delete g -> second ;
2009-02-09 14:50:32 +00:00
for ( std :: map < int , CDefHandler * >:: iterator g = idToObstacle . begin (); g != idToObstacle . end (); ++ g )
delete g -> second ;
2009-04-14 12:47:09 +00:00
LOCPLINT -> battleInt = NULL ;
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: setPrintCellBorders ( bool set )
{
2009-03-28 18:46:20 +00:00
settings . printCellBorders = set ;
2009-01-15 17:01:08 +00:00
redrawBackgroundWithHexes ( activeStack );
}
void CBattleInterface :: setPrintStackRange ( bool set )
{
2009-03-28 18:46:20 +00:00
settings . printStackRange = set ;
2009-01-15 17:01:08 +00:00
redrawBackgroundWithHexes ( activeStack );
}
void CBattleInterface :: setPrintMouseShadow ( bool set )
{
2009-03-28 18:46:20 +00:00
settings . printMouseShadow = set ;
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: activate ()
{
KeyInterested :: activate ();
MotionInterested :: activate ();
subInt = NULL ;
bOptions -> activate ();
bSurrender -> activate ();
bFlee -> activate ();
bAutofight -> activate ();
bSpell -> activate ();
bWait -> activate ();
bDefence -> activate ();
bConsoleUp -> activate ();
bConsoleDown -> activate ();
for ( int b = 0 ; b < BFIELD_SIZE ; ++ b )
{
bfield [ b ]. activate ();
}
if ( attackingHero )
attackingHero -> activate ();
if ( defendingHero )
defendingHero -> activate ();
2009-04-03 15:55:26 +00:00
LOCPLINT -> cingconsole -> activate ();
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: deactivate ()
{
KeyInterested :: deactivate ();
MotionInterested :: deactivate ();
bOptions -> deactivate ();
bSurrender -> deactivate ();
bFlee -> deactivate ();
bAutofight -> deactivate ();
bSpell -> deactivate ();
bWait -> deactivate ();
bDefence -> deactivate ();
bConsoleUp -> deactivate ();
bConsoleDown -> deactivate ();
for ( int b = 0 ; b < BFIELD_SIZE ; ++ b )
{
bfield [ b ]. deactivate ();
}
if ( attackingHero )
attackingHero -> deactivate ();
if ( defendingHero )
defendingHero -> deactivate ();
2009-04-03 15:55:26 +00:00
LOCPLINT -> cingconsole -> deactivate ();
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: show ( SDL_Surface * to )
{
std :: map < int , CStack > stacks = LOCPLINT -> cb -> battleGetStacks (); //used in a few places
++ animCount ;
if ( ! to ) //"evaluating" to
to = screen ;
SDL_Rect buf ;
SDL_GetClipRect ( to , & buf );
SDL_SetClipRect ( to , & pos );
//printing background and hexes
if ( activeStack != - 1 && creAnims [ activeStack ] -> getType () != 0 ) //show everything with range
{
blitAt ( backgroundWithHexes , pos . x , pos . y , to );
}
else
{
//showing background
blitAt ( background , pos . x , pos . y , to );
2009-03-28 18:46:20 +00:00
if ( settings . printCellBorders )
2009-01-15 17:01:08 +00:00
{
CSDL_Ext :: blit8bppAlphaTo24bpp ( cellBorders , NULL , to , & pos );
}
}
//printing hovered cell
2009-02-07 16:07:29 +00:00
for ( int b = 0 ; b < BFIELD_SIZE ; ++ b )
2009-01-15 17:01:08 +00:00
{
2009-02-07 16:07:29 +00:00
if ( bfield [ b ]. strictHovered && bfield [ b ]. hovered )
2009-01-15 17:01:08 +00:00
{
2009-02-07 16:07:29 +00:00
if ( previouslyHoveredHex == - 1 ) previouslyHoveredHex = b ; //something to start with
if ( currentlyHoveredHex == - 1 ) currentlyHoveredHex = b ; //something to start with
if ( currentlyHoveredHex != b ) //repair hover info
{
previouslyHoveredHex = currentlyHoveredHex ;
currentlyHoveredHex = b ;
}
//print shade
2009-03-28 18:46:20 +00:00
if ( settings . printMouseShadow )
2009-01-15 17:01:08 +00:00
{
int x = 14 + (( b / BFIELD_WIDTH ) % 2 == 0 ? 22 : 0 ) + 44 * ( b % BFIELD_WIDTH ) + pos . x ;
int y = 86 + 42 * ( b / BFIELD_WIDTH ) + pos . y ;
CSDL_Ext :: blit8bppAlphaTo24bpp ( cellShade , NULL , to , & genRect ( cellShade -> h , cellShade -> w , x , y ));
}
}
}
SDL_SetClipRect ( to , & buf ); //restoring previous clip_rect
//showing menu background and console
blitAt ( menu , pos . x , 556 + pos . y , to );
console -> show ( to );
//showing buttons
bOptions -> show ( to );
bSurrender -> show ( to );
bFlee -> show ( to );
bAutofight -> show ( to );
bSpell -> show ( to );
bWait -> show ( to );
bDefence -> show ( to );
bConsoleUp -> show ( to );
bConsoleDown -> show ( to );
SDL_GetClipRect ( to , & buf );
SDL_SetClipRect ( to , & pos );
2009-02-09 14:50:32 +00:00
//showing obstacles
std :: vector < CObstacleInstance > obstacles = LOCPLINT -> cb -> battleGetAllObstacles ();
for ( int b = 0 ; b < obstacles . size (); ++ b )
{
int x = (( obstacles [ b ]. pos / BFIELD_WIDTH ) % 2 == 0 ? 22 : 0 ) + 44 * ( obstacles [ b ]. pos % BFIELD_WIDTH );
int y = 86 + 42 * ( obstacles [ b ]. pos / BFIELD_WIDTH );
std :: vector < Cimage > & images = idToObstacle [ obstacles [ b ]. ID ] -> ourImages ;
2009-03-28 18:46:20 +00:00
blitAt ( images [(( animCount + 1 ) / ( 4 / settings . animSpeed )) % images . size ()]. bitmap , x , y , to );
2009-02-09 14:50:32 +00:00
}
2009-01-15 17:01:08 +00:00
//showing hero animations
if ( attackingHero )
attackingHero -> show ( to );
if ( defendingHero )
defendingHero -> show ( to );
////showing units //a lot of work...
std :: vector < int > stackAliveByHex [ BFIELD_SIZE ];
//double loop because dead stacks should be printed first
for ( std :: map < int , CStack >:: iterator j = stacks . begin (); j != stacks . end (); ++ j )
{
if ( j -> second . alive ())
stackAliveByHex [ j -> second . position ]. push_back ( j -> second . ID );
}
std :: vector < int > stackDeadByHex [ BFIELD_SIZE ];
for ( std :: map < int , CStack >:: iterator j = stacks . begin (); j != stacks . end (); ++ j )
{
if ( ! j -> second . alive ())
stackDeadByHex [ j -> second . position ]. push_back ( j -> second . ID );
}
attackingShowHelper (); // handle attack animation
for ( int b = 0 ; b < BFIELD_SIZE ; ++ b ) //showing dead stacks
{
for ( size_t v = 0 ; v < stackDeadByHex [ b ]. size (); ++ v )
{
2009-02-21 15:43:28 +00:00
creAnims [ stackDeadByHex [ b ][ v ]] -> nextFrame ( to , creAnims [ stackDeadByHex [ b ][ v ]] -> pos . x + pos . x , creAnims [ stackDeadByHex [ b ][ v ]] -> pos . y + pos . y , creDir [ stackDeadByHex [ b ][ v ]], animCount , false ); //increment always when moving, never if stack died
2009-01-15 17:01:08 +00:00
}
}
for ( int b = 0 ; b < BFIELD_SIZE ; ++ b ) //showing alive stacks
{
for ( size_t v = 0 ; v < stackAliveByHex [ b ]. size (); ++ v )
{
2009-03-28 00:38:48 +00:00
int curStackID = stackAliveByHex [ b ][ v ];
const CStack & curStack = stacks [ curStackID ];
int animType = creAnims [ curStackID ] -> getType ();
2009-03-28 18:46:20 +00:00
bool incrementFrame = ( animCount % ( 4 / settings . animSpeed ) == 0 ) && animType != 5 && animType != 20 && animType != 3 && animType != 2 ;
2009-03-28 00:38:48 +00:00
2009-02-21 15:43:28 +00:00
if ( animType == 2 )
{
2009-03-28 00:38:48 +00:00
if ( standingFrame . find ( curStackID ) != standingFrame . end ())
2009-02-21 15:43:28 +00:00
{
2009-03-28 18:46:20 +00:00
incrementFrame = ( animCount % ( 8 / settings . animSpeed ) == 0 );
2009-02-21 15:43:28 +00:00
if ( incrementFrame )
{
2009-03-28 00:38:48 +00:00
++ standingFrame [ curStackID ];
if ( standingFrame [ curStackID ] == creAnims [ curStackID ] -> framesInGroup ( 2 ))
2009-02-21 15:43:28 +00:00
{
2009-03-28 00:38:48 +00:00
standingFrame . erase ( standingFrame . find ( curStackID ));
2009-02-21 15:43:28 +00:00
}
}
}
else
{
if (( rand () % 50 ) == 0 )
{
2009-03-28 00:38:48 +00:00
standingFrame . insert ( std :: make_pair ( curStackID , 0 ));
2009-02-21 15:43:28 +00:00
}
}
}
2009-03-28 00:38:48 +00:00
creAnims [ curStackID ] -> nextFrame ( to , creAnims [ curStackID ] -> pos . x + pos . x , creAnims [ curStackID ] -> pos . y + pos . y , creDir [ curStackID ], animCount , incrementFrame , curStackID == activeStack , curStackID == mouseHoveredStack ); //increment always when moving, never if stack died
2009-01-15 17:01:08 +00:00
//printing amount
2009-03-28 00:38:48 +00:00
if ( curStack . amount > 0 //don't print if stack is not alive
2009-03-29 12:02:37 +00:00
&& ( ! LOCPLINT -> curAction
2009-03-28 00:38:48 +00:00
|| ( LOCPLINT -> curAction -> stackNumber != curStackID //don't print if stack is currently taking an action
&& ( LOCPLINT -> curAction -> actionType != 6 || curStack . position != LOCPLINT -> curAction -> additionalInfo ) //nor if it's an object of attack
&& ( LOCPLINT -> curAction -> destinationTile != curStack . position ) //nor if it's on destination tile for current action
2009-03-29 12:02:37 +00:00
)
2009-03-28 00:38:48 +00:00
)
2009-03-29 12:02:37 +00:00
&& ! vstd :: contains ( curStack . abilities , SIEGE_WEAPON ) //and not a war machine...
2009-03-28 00:38:48 +00:00
)
2009-01-15 17:01:08 +00:00
{
2009-03-28 00:38:48 +00:00
int xAdd = curStack . attackerOwned ? 220 : 202 ;
2009-01-15 17:01:08 +00:00
//blitting amoutn background box
SDL_Surface * amountBG = NULL ;
2009-03-28 00:38:48 +00:00
if ( curStack . effects . size () == 0 )
2009-01-15 17:01:08 +00:00
{
amountBG = amountNormal ;
}
else
{
int pos = 0 ; //determining total positiveness of effects
2009-03-28 00:38:48 +00:00
for ( int c = 0 ; c < curStack . effects . size (); ++ c )
2009-01-15 17:01:08 +00:00
{
2009-03-28 00:38:48 +00:00
pos += CGI -> spellh -> spells [ curStack . effects [ c ]. id ]. positiveness ;
2009-01-15 17:01:08 +00:00
}
if ( pos > 0 )
{
amountBG = amountPositive ;
}
else if ( pos < 0 )
{
amountBG = amountNegative ;
}
else
{
amountBG = amountEffNeutral ;
}
}
2009-03-28 00:38:48 +00:00
SDL_BlitSurface ( amountBG , NULL , to , & genRect ( amountNormal -> h , amountNormal -> w , creAnims [ curStackID ] -> pos . x + xAdd + pos . x , creAnims [ curStackID ] -> pos . y + 260 + pos . y ));
2009-01-15 17:01:08 +00:00
//blitting amount
std :: stringstream ss ;
2009-03-28 00:38:48 +00:00
ss << curStack . amount ;
2009-01-15 17:01:08 +00:00
CSDL_Ext :: printAtMiddleWB (
ss . str (),
2009-03-28 00:38:48 +00:00
creAnims [ curStackID ] -> pos . x + xAdd + 14 + pos . x ,
creAnims [ curStackID ] -> pos . y + 260 + 4 + pos . y ,
2009-01-15 17:01:08 +00:00
GEOR13 ,
20 ,
zwykly ,
to
);
}
}
}
//units shown
projectileShowHelper ( to ); //showing projectiles
//showing spell effects
if ( battleEffects . size ())
{
std :: vector < std :: list < SBattleEffect >:: iterator > toErase ;
for ( std :: list < SBattleEffect >:: iterator it = battleEffects . begin (); it != battleEffects . end (); ++ it )
{
SDL_Surface * bitmapToBlit = it -> anim -> ourImages [( it -> frame ) % it -> anim -> ourImages . size ()]. bitmap ;
SDL_BlitSurface ( bitmapToBlit , NULL , to , & genRect ( bitmapToBlit -> h , bitmapToBlit -> w , pos . x + it -> x , pos . y + it -> y ));
++ ( it -> frame );
if ( it -> frame == it -> maxFrame )
{
toErase . push_back ( it );
}
}
for ( size_t b = 0 ; b < toErase . size (); ++ b )
{
delete toErase [ b ] -> anim ;
battleEffects . erase ( toErase [ b ]);
}
}
//showing queue of stacks
if ( showStackQueue )
{
int xPos = screen -> w / 2 - ( stacks . size () * 37 ) / 2 ;
2009-02-07 16:07:29 +00:00
int yPos = ( screen -> h - 600 ) / 2 + 10 ;
2009-01-15 17:01:08 +00:00
std :: vector < CStack > stacksSorted ;
stacksSorted = LOCPLINT -> cb -> battleGetStackQueue ();
int startFrom = - 1 ;
for ( size_t n = 0 ; n < stacksSorted . size (); ++ n )
{
if ( stacksSorted [ n ]. ID == activeStack )
{
startFrom = n ;
break ;
}
}
if ( startFrom != - 1 )
{
for ( size_t b = startFrom ; b < stacksSorted . size () + startFrom ; ++ b )
{
SDL_BlitSurface ( graphics -> smallImgs [ - 2 ], NULL , to , & genRect ( 32 , 32 , xPos , yPos ));
//printing colored border
for ( int xFrom = xPos - 1 ; xFrom < xPos + 33 ; ++ xFrom )
{
for ( int yFrom = yPos - 1 ; yFrom < yPos + 33 ; ++ yFrom )
{
if ( xFrom == xPos - 1 || xFrom == xPos + 32 || yFrom == yPos - 1 || yFrom == yPos + 32 )
{
SDL_Color pc ;
if ( stacksSorted [ b % stacksSorted . size ()]. owner != 255 )
{
pc = graphics -> playerColors [ stacksSorted [ b % stacksSorted . size ()]. owner ];
}
else
{
pc = * graphics -> neutralColor ;
}
CSDL_Ext :: SDL_PutPixelWithoutRefresh ( to , xFrom , yFrom , pc . r , pc . g , pc . b );
}
}
}
//colored border printed
SDL_BlitSurface ( graphics -> smallImgs [ stacksSorted [ b % stacksSorted . size ()]. creature -> idNumber ], NULL , to , & genRect ( 32 , 32 , xPos , yPos ));
xPos += 37 ;
}
}
}
2009-01-30 14:36:26 +00:00
SDL_SetClipRect ( to , & buf ); //restoring previous clip_rect
2009-01-15 17:01:08 +00:00
//showing window with result of battle
if ( resWindow )
{
resWindow -> show ( to );
}
2009-04-03 15:55:26 +00:00
//showing in-gmae console
2009-04-14 12:47:09 +00:00
LOCPLINT -> cingconsole -> show ( to );
2009-01-15 17:01:08 +00:00
//printing border around interface
2009-01-14 19:07:57 +00:00
if ( screen -> w != 800 || screen -> h != 600 )
2009-01-15 17:01:08 +00:00
CMessage :: drawBorder ( LOCPLINT -> playerID , to , 828 , 628 , pos . x - 14 , pos . y - 15 );
}
void CBattleInterface :: keyPressed ( const SDL_KeyboardEvent & key )
{
if ( key . keysym . sym == SDLK_q )
{
showStackQueue = key . state == SDL_PRESSED ;
}
}
void CBattleInterface :: mouseMoved ( const SDL_MouseMotionEvent & sEvent )
{
if ( activeStack >= 0 && ! spellDestSelectMode )
{
2009-02-21 15:43:28 +00:00
mouseHoveredStack = - 1 ;
2009-01-15 17:01:08 +00:00
int myNumber = - 1 ; //number of hovered tile
for ( int g = 0 ; g < BFIELD_SIZE ; ++ g )
{
if ( bfield [ g ]. hovered && bfield [ g ]. strictHovered )
{
myNumber = g ;
break ;
}
}
if ( myNumber == - 1 )
{
CGI -> curh -> changeGraphic ( 1 , 6 );
2009-01-29 18:07:31 +00:00
if ( console -> whoSetAlter == 0 )
{
console -> alterTxt = "" ;
}
2009-01-15 17:01:08 +00:00
}
else
{
if ( std :: find ( shadedHexes . begin (), shadedHexes . end (), myNumber ) == shadedHexes . end ())
{
CStack * shere = LOCPLINT -> cb -> battleGetStackByPos ( myNumber );
2009-01-29 18:07:31 +00:00
CStack * sactive = LOCPLINT -> cb -> battleGetStackByID ( activeStack );
2009-01-15 17:01:08 +00:00
if ( shere )
{
if ( shere -> owner == LOCPLINT -> playerID ) //our stack
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 5 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
sprintf ( buf , CGI -> generaltexth -> allTexts [ 297 ]. c_str (), shere -> amount == 1 ? shere -> creature -> nameSing . c_str () : shere -> creature -> namePl . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
2009-02-21 15:43:28 +00:00
mouseHoveredStack = shere -> ID ;
if ( creAnims [ shere -> ID ] -> getType () == 2 && creAnims [ shere -> ID ] -> framesInGroup ( 1 ) > 0 )
{
creAnims [ shere -> ID ] -> playOnce ( 1 );
}
2009-01-29 18:07:31 +00:00
}
2009-01-15 17:01:08 +00:00
else if ( LOCPLINT -> cb -> battleCanShoot ( activeStack , myNumber )) //we can shoot enemy
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 3 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
sprintf ( buf , CGI -> generaltexth -> allTexts [ 296 ]. c_str (), shere -> amount == 1 ? shere -> creature -> nameSing . c_str () : shere -> creature -> namePl . c_str (), sactive -> shots , "?" );
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
else if ( isTileAttackable ( myNumber )) //available enemy (melee attackable)
{
int fromHex = previouslyHoveredHex ;
2009-01-16 17:58:41 +00:00
if ( fromHex !=- 1 && fromHex % BFIELD_WIDTH != 0 && fromHex % BFIELD_WIDTH != ( BFIELD_WIDTH - 1 ) && vstd :: contains ( shadedHexes , fromHex ))
2009-01-15 17:01:08 +00:00
{
switch ( BattleInfo :: mutualPosition ( fromHex , myNumber ))
{
case 0 :
CGI -> curh -> changeGraphic ( 1 , 12 );
break ;
case 1 :
CGI -> curh -> changeGraphic ( 1 , 7 );
break ;
case 2 :
CGI -> curh -> changeGraphic ( 1 , 8 );
break ;
case 3 :
CGI -> curh -> changeGraphic ( 1 , 9 );
break ;
case 4 :
CGI -> curh -> changeGraphic ( 1 , 10 );
break ;
case 5 :
CGI -> curh -> changeGraphic ( 1 , 11 );
break ;
}
}
}
else //unavailable enemy
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
console -> alterTxt = "" ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
}
else //empty unavailable tile
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
console -> alterTxt = "" ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
}
else //available tile
{
2009-01-29 18:07:31 +00:00
CStack * sactive = LOCPLINT -> cb -> battleGetStackByID ( activeStack );
2009-01-15 17:01:08 +00:00
if ( LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> creature -> isFlying ())
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 2 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
sprintf ( buf , CGI -> generaltexth -> allTexts [ 295 ]. c_str (), sactive -> amount == 1 ? sactive -> creature -> nameSing . c_str () : sactive -> creature -> namePl . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
else
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 1 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
sprintf ( buf , CGI -> generaltexth -> allTexts [ 294 ]. c_str (), sactive -> amount == 1 ? sactive -> creature -> nameSing . c_str () : sactive -> creature -> namePl . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
}
}
}
else if ( spellDestSelectMode )
{
int myNumber = - 1 ; //number of hovered tile
for ( int g = 0 ; g < BFIELD_SIZE ; ++ g )
{
if ( bfield [ g ]. hovered && bfield [ g ]. strictHovered )
{
myNumber = g ;
break ;
}
}
if ( myNumber == - 1 )
{
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
console -> alterTxt = CGI -> generaltexth -> allTexts [ 23 ];
console -> whoSetAlter = 0 ;
2009-01-15 17:01:08 +00:00
}
else
{
2009-01-29 18:07:31 +00:00
CStack * stackUnder = LOCPLINT -> cb -> battleGetStackByPos ( myNumber );
2009-01-15 17:01:08 +00:00
switch ( spellSelMode )
{
case 0 :
CGI -> curh -> changeGraphic ( 3 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
sprintf ( buf , CGI -> generaltexth -> allTexts [ 26 ]. c_str (), CGI -> spellh -> spells [ spellToCast -> additionalInfo ]. name . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
2009-01-15 17:01:08 +00:00
break ;
case 1 :
2009-01-29 18:07:31 +00:00
if ( stackUnder && LOCPLINT -> playerID == stackUnder -> owner )
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 3 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
std :: string creName = stackUnder -> amount > 1 ? stackUnder -> creature -> namePl : stackUnder -> creature -> nameSing ;
sprintf ( buf , CGI -> generaltexth -> allTexts [ 27 ]. c_str (), CGI -> spellh -> spells [ spellToCast -> additionalInfo ]. name . c_str (), creName . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
break ;
}
2009-01-15 17:01:08 +00:00
else
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
console -> alterTxt = CGI -> generaltexth -> allTexts [ 23 ];
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
break ;
case 2 :
2009-01-29 18:07:31 +00:00
if ( stackUnder && LOCPLINT -> playerID != stackUnder -> owner )
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 3 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
std :: string creName = stackUnder -> amount > 1 ? stackUnder -> creature -> namePl : stackUnder -> creature -> nameSing ;
sprintf ( buf , CGI -> generaltexth -> allTexts [ 27 ]. c_str (), CGI -> spellh -> spells [ spellToCast -> additionalInfo ]. name . c_str (), creName . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
else
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
console -> alterTxt = CGI -> generaltexth -> allTexts [ 23 ];
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
break ;
case 3 :
2009-01-29 18:07:31 +00:00
if ( stackUnder )
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 3 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
char buf [ 500 ];
std :: string creName = stackUnder -> amount > 1 ? stackUnder -> creature -> namePl : stackUnder -> creature -> nameSing ;
sprintf ( buf , CGI -> generaltexth -> allTexts [ 27 ]. c_str (), CGI -> spellh -> spells [ spellToCast -> additionalInfo ]. name . c_str (), creName . c_str ());
console -> alterTxt = buf ;
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
else
2009-01-29 18:07:31 +00:00
{
2009-01-15 17:01:08 +00:00
CGI -> curh -> changeGraphic ( 1 , 0 );
2009-01-29 18:07:31 +00:00
//setting console text
console -> alterTxt = CGI -> generaltexth -> allTexts [ 23 ];
console -> whoSetAlter = 0 ;
}
2009-01-15 17:01:08 +00:00
break ;
case 4 : //TODO: implement this case
break ;
}
}
}
}
bool CBattleInterface :: reverseCreature ( int number , int hex , bool wideTrick )
{
if ( creAnims [ number ] == NULL )
return false ; //there is no such creature
creAnims [ number ] -> setType ( 8 );
2009-03-07 16:05:53 +00:00
//int firstFrame = creAnims[number]->getFrame();
//for(int g=0; creAnims[number]->getFrame() != creAnims[number]->framesInGroup(8) + firstFrame - 1; ++g)
while ( ! creAnims [ number ] -> onLastFrameInGroup ())
2009-01-15 17:01:08 +00:00
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
creDir [ number ] = ! creDir [ number ];
CStack curs = * LOCPLINT -> cb -> battleGetStackByID ( number );
std :: pair < int , int > coords = CBattleHex :: getXYUnitAnim ( hex , creDir [ number ], curs . creature );
creAnims [ number ] -> pos . x = coords . first ;
//creAnims[number]->pos.y = coords.second;
if ( wideTrick && curs . creature -> isDoubleWide ())
{
if ( curs . attackerOwned )
{
if ( ! creDir [ number ])
creAnims [ number ] -> pos . x -= 44 ;
}
else
{
if ( creDir [ number ])
creAnims [ number ] -> pos . x += 44 ;
}
}
creAnims [ number ] -> setType ( 7 );
2009-03-07 16:05:53 +00:00
//firstFrame = creAnims[number]->getFrame();
//for(int g=0; creAnims[number]->getFrame() != creAnims[number]->framesInGroup(7) + firstFrame - 1; ++g)
while ( ! creAnims [ number ] -> onLastFrameInGroup ())
2009-01-15 17:01:08 +00:00
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
creAnims [ number ] -> setType ( 2 );
return true ;
}
2009-02-20 13:06:20 +00:00
void CBattleInterface :: handleStartMoving ( int number )
{
for ( int i = 0 ; i < creAnims [ number ] -> framesInGroup ( 20 ) * getAnimSpeedMultiplier () - 1 ; ++ i )
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-02-20 13:06:20 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
2009-03-28 18:46:20 +00:00
if (( animCount + 1 ) % ( 4 / settings . animSpeed ) == 0 )
2009-02-20 13:06:20 +00:00
creAnims [ number ] -> incrementFrame ();
}
}
2009-01-15 17:01:08 +00:00
void CBattleInterface :: bOptionsf ()
{
CGI -> curh -> changeGraphic ( 0 , 0 );
deactivate ();
SDL_Rect temp_rect = genRect ( 431 , 481 , 160 , 84 );
CBattleOptionsWindow * optionsWin = new CBattleOptionsWindow ( temp_rect , this );
optionsWin -> activate ();
LOCPLINT -> objsToBlit . push_back ( optionsWin );
}
void CBattleInterface :: bSurrenderf ()
{
}
void CBattleInterface :: bFleef ()
{
2009-04-14 12:47:09 +00:00
CFunctionList < void () > ony = boost :: bind ( & CBattleInterface :: reallyFlee , this );
LOCPLINT -> showYesNoDialog ( CGI -> generaltexth -> allTexts [ 28 ], std :: vector < SComponent *> (), ony , 0 , false );
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: reallyFlee ()
{
giveCommand ( 4 , 0 , 0 );
CGI -> curh -> changeGraphic ( 0 , 0 );
}
void CBattleInterface :: bAutofightf ()
{
}
void CBattleInterface :: bSpellf ()
{
CGI -> curh -> changeGraphic ( 0 , 0 );
deactivate ();
const CGHeroInstance * chi = NULL ;
if ( attackingHeroInstance -> tempOwner == LOCPLINT -> playerID )
chi = attackingHeroInstance ;
else
chi = defendingHeroInstance ;
CSpellWindow * spellWindow = new CSpellWindow ( genRect ( 595 , 620 , ( conf . cc . resx - 620 ) / 2 , ( conf . cc . resy - 595 ) / 2 ), chi );
spellWindow -> activate ();
LOCPLINT -> objsToBlit . push_back ( spellWindow );
}
void CBattleInterface :: bWaitf ()
{
giveCommand ( 8 , 0 , activeStack );
}
void CBattleInterface :: bDefencef ()
{
giveCommand ( 3 , 0 , activeStack );
}
void CBattleInterface :: bConsoleUpf ()
{
console -> scrollUp ();
}
void CBattleInterface :: bConsoleDownf ()
{
console -> scrollDown ();
}
void CBattleInterface :: newStack ( CStack stack )
{
creAnims [ stack . ID ] = new CCreatureAnimation ( stack . creature -> animDefName );
creAnims [ stack . ID ] -> setType ( 2 );
creDir [ stack . ID ] = stack . owner == attackingHeroInstance -> tempOwner ;
}
void CBattleInterface :: stackRemoved ( CStack stack )
{
delete creAnims [ stack . ID ];
creAnims . erase ( stack . ID );
}
void CBattleInterface :: stackActivated ( int number )
{
//givenCommand = NULL;
activeStack = number ;
myTurn = true ;
redrawBackgroundWithHexes ( number );
bWait -> block ( vstd :: contains ( LOCPLINT -> cb -> battleGetStackByID ( number ) -> state , WAITING )); //block waiting button if stack has been already waiting
2009-02-15 19:49:23 +00:00
//block cast spell button if hero doesn't have a spellbook
if ( attackingHeroInstance && attackingHeroInstance -> tempOwner == LOCPLINT -> cb -> battleGetStackByID ( number ) -> owner )
{
bSpell -> block ( ! attackingHeroInstance -> getArt ( 17 ));
}
else if ( defendingHeroInstance && defendingHeroInstance -> tempOwner == LOCPLINT -> cb -> battleGetStackByID ( number ) -> owner )
{
bSpell -> block ( ! defendingHeroInstance -> getArt ( 17 ));
}
2009-01-15 17:01:08 +00:00
}
2009-03-07 16:05:53 +00:00
void CBattleInterface :: stackMoved ( int number , int destHex , bool endMoving , int distance )
2009-01-15 17:01:08 +00:00
{
2009-02-20 13:06:20 +00:00
bool startMoving = creAnims [ number ] -> getType () == 20 ;
2009-01-15 17:01:08 +00:00
//a few useful variables
int curStackPos = LOCPLINT -> cb -> battleGetPos ( number );
int steps = creAnims [ number ] -> framesInGroup ( 0 ) * getAnimSpeedMultiplier () - 1 ;
int hexWbase = 44 , hexHbase = 42 ;
bool twoTiles = LOCPLINT -> cb -> battleGetCreature ( number ). isDoubleWide ();
2009-03-07 16:05:53 +00:00
CStack * movedStack = LOCPLINT -> cb -> battleGetStackByID ( number );
std :: pair < int , int > begPosition = CBattleHex :: getXYUnitAnim ( curStackPos , movedStack -> attackerOwned , movedStack -> creature );
std :: pair < int , int > endPosition = CBattleHex :: getXYUnitAnim ( destHex , movedStack -> attackerOwned , movedStack -> creature );
2009-01-15 17:01:08 +00:00
if ( startMoving ) //animation of starting move; some units don't have this animation (ie. halberdier)
{
2009-02-20 13:06:20 +00:00
handleStartMoving ( number );
2009-01-15 17:01:08 +00:00
}
2009-02-21 15:43:28 +00:00
if ( moveStarted )
{
CGI -> curh -> hide ();
creAnims [ number ] -> setType ( 0 );
moveStarted = false ;
}
2009-01-15 17:01:08 +00:00
int mutPos = BattleInfo :: mutualPosition ( curStackPos , destHex );
2009-03-07 16:05:53 +00:00
float stepX = 0.0 , stepY = 0.0 ; //how far stack is moved in one frame; calculated later
2009-01-15 17:01:08 +00:00
2009-03-07 16:05:53 +00:00
//reverse unit if necessary
if (( begPosition . first > endPosition . first ) && creDir [ number ] == true )
2009-01-15 17:01:08 +00:00
{
2009-03-07 16:05:53 +00:00
reverseCreature ( number , curStackPos , twoTiles );
}
else if (( begPosition . first < endPosition . first ) && creDir [ number ] == false )
{
reverseCreature ( number , curStackPos , twoTiles );
}
if ( creAnims [ number ] -> getType () != 0 )
{
creAnims [ number ] -> setType ( 0 );
}
//unit reversed
//step shift calculation
float posX = creAnims [ number ] -> pos . x , posY = creAnims [ number ] -> pos . y ; // for precise calculations ;]
if ( mutPos == - 1 && movedStack -> creature -> isFlying ())
{
steps *= distance ;
stepX = ( endPosition . first - ( float ) begPosition . first ) / steps ;
stepY = ( endPosition . second - ( float ) begPosition . second ) / steps ;
}
else
{
switch ( mutPos )
2009-01-15 17:01:08 +00:00
{
2009-03-07 16:05:53 +00:00
case 0 :
stepX = ( - 1.0 ) * (( float ) hexWbase ) / ( 2.0f * steps );
stepY = ( - 1.0 ) * (( float ) hexHbase ) / (( float ) steps );
2009-01-15 17:01:08 +00:00
break ;
2009-03-07 16:05:53 +00:00
case 1 :
stepX = (( float ) hexWbase ) / ( 2.0f * steps );
stepY = ( - 1.0 ) * (( float ) hexHbase ) / (( float ) steps );
break ;
case 2 :
stepX = (( float ) hexWbase ) / (( float ) steps );
stepY = 0.0 ;
break ;
case 3 :
stepX = (( float ) hexWbase ) / ( 2.0f * steps );
stepY = (( float ) hexHbase ) / (( float ) steps );
break ;
case 4 :
stepX = ( - 1.0 ) * (( float ) hexWbase ) / ( 2.0f * steps );
stepY = (( float ) hexHbase ) / (( float ) steps );
break ;
case 5 :
stepX = ( - 1.0 ) * (( float ) hexWbase ) / (( float ) steps );
stepY = 0.0 ;
2009-01-15 17:01:08 +00:00
break ;
}
}
2009-03-07 16:05:53 +00:00
//step shifts calculated
//switch(mutPos) //reverse unit if necessary
//{
//case 0: case 4: case 5:
// if(creDir[number] == true)
// reverseCreature(number, curStackPos, twoTiles);
// break;
//case 1: case 2: case 3:
// if(creDir[number] == false)
// reverseCreature(number, curStackPos, twoTiles);
// break;
//}
//moving instructions
for ( int i = 0 ; i < steps ; ++ i )
{
posX += stepX ;
creAnims [ number ] -> pos . x = posX ;
posY += stepY ;
creAnims [ number ] -> pos . y = posY ;
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-03-07 16:05:53 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
//unit moved
2009-01-15 17:01:08 +00:00
if ( endMoving ) //animation of ending move
{
if ( creAnims [ number ] -> framesInGroup ( 21 ) != 0 ) // some units don't have this animation (ie. halberdier)
{
creAnims [ number ] -> setType ( 21 );
2009-03-07 16:05:53 +00:00
//for(int i=0; i<creAnims[number]->framesInGroup(21)*getAnimSpeedMultiplier()-1; ++i)
while ( ! creAnims [ number ] -> onLastFrameInGroup ())
2009-01-15 17:01:08 +00:00
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
}
creAnims [ number ] -> setType ( 2 ); //resetting to default
CGI -> curh -> show ();
}
CStack curs = * LOCPLINT -> cb -> battleGetStackByID ( number );
if ( endMoving ) //resetting to default
{
if ( creDir [ number ] != ( curs . owner == attackingHeroInstance -> tempOwner ))
reverseCreature ( number , destHex , twoTiles );
}
std :: pair < int , int > coords = CBattleHex :: getXYUnitAnim ( destHex , creDir [ number ], curs . creature );
creAnims [ number ] -> pos . x = coords . first ;
2009-01-29 18:07:31 +00:00
if ( ! endMoving && twoTiles && ( curs . owner == attackingHeroInstance -> tempOwner ) && ( creDir [ number ] != ( curs . owner == attackingHeroInstance -> tempOwner ))) //big attacker creature is reversed
2009-01-15 17:01:08 +00:00
creAnims [ number ] -> pos . x -= 44 ;
2009-01-29 18:07:31 +00:00
else if ( ! endMoving && twoTiles && ( curs . owner != attackingHeroInstance -> tempOwner ) && ( creDir [ number ] != ( curs . owner == attackingHeroInstance -> tempOwner ))) //big defender creature is reversed
creAnims [ number ] -> pos . x += 44 ;
2009-01-15 17:01:08 +00:00
creAnims [ number ] -> pos . y = coords . second ;
}
void CBattleInterface :: stacksAreAttacked ( std :: vector < CBattleInterface :: SStackAttackedInfo > attackedInfos )
{
//restoring default state of battleWindow by calling show func
while ( true )
{
2009-04-14 12:47:09 +00:00
show ( screen );
2009-01-15 17:01:08 +00:00
CSDL_Ext :: update ();
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
//checking break conditions
bool break_loop = true ;
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
if ( creAnims [ attackedInfos [ g ]. ID ] -> getType () != 2 )
{
break_loop = false ;
}
if ( attackingInfo && attackingInfo -> IDby == attackedInfos [ g ]. IDby )
{
break_loop = false ;
}
}
if ( break_loop ) break ;
}
if ( attackedInfos . size () == 1 && attackedInfos [ 0 ]. byShooting ) //delay hit animation
{
CStack attacker = * LOCPLINT -> cb -> battleGetStackByID ( attackedInfos [ 0 ]. IDby );
while ( true )
{
bool found = false ;
for ( std :: list < SProjectileInfo >:: const_iterator it = projectiles . begin (); it != projectiles . end (); ++ it )
{
if ( it -> creID == attacker . creature -> idNumber )
{
found = true ;
break ;
}
}
if ( ! found )
break ;
else
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
}
}
//initializing
int maxLen = 0 ;
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
if ( attackedInfos [ g ]. killed )
{
creAnims [ attackedInfos [ g ]. ID ] -> setType ( 5 ); //death
}
else
{
creAnims [ attackedInfos [ g ]. ID ] -> setType ( 3 ); //getting hit
}
}
//main showing loop
bool continueLoop = true ;
while ( continueLoop )
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
2009-03-28 18:46:20 +00:00
if (( animCount + 1 ) % ( 4 / settings . animSpeed ) == 0 && ! creAnims [ attackedInfos [ g ]. ID ] -> onLastFrameInGroup ())
2009-01-15 17:01:08 +00:00
{
creAnims [ attackedInfos [ g ]. ID ] -> incrementFrame ();
}
2009-03-05 17:57:26 +00:00
if ( creAnims [ attackedInfos [ g ]. ID ] -> onLastFrameInGroup () && creAnims [ attackedInfos [ g ]. ID ] -> getType () == 3 )
2009-01-15 17:01:08 +00:00
creAnims [ attackedInfos [ g ]. ID ] -> setType ( 2 );
}
bool isAnotherOne = false ; //if true, there is a stack whose hit/death anim must be continued
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
2009-03-05 17:57:26 +00:00
if ( ! creAnims [ attackedInfos [ g ]. ID ] -> onLastFrameInGroup ())
2009-01-15 17:01:08 +00:00
{
isAnotherOne = true ;
break ;
}
}
if ( ! isAnotherOne )
continueLoop = false ;
}
//restoring animType
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
if ( creAnims [ attackedInfos [ g ]. ID ] -> getType () == 3 )
creAnims [ attackedInfos [ g ]. ID ] -> setType ( 2 );
}
//printing info to console
for ( size_t g = 0 ; g < attackedInfos . size (); ++ g )
{
if ( attackedInfos [ g ]. IDby !=- 1 )
printConsoleAttacked ( attackedInfos [ g ]. ID , attackedInfos [ g ]. dmg , attackedInfos [ g ]. amountKilled , attackedInfos [ g ]. IDby );
}
}
void CBattleInterface :: stackAttacking ( int ID , int dest )
{
2009-02-20 13:06:20 +00:00
if ( attackingInfo == NULL && creAnims [ ID ] -> getType () == 20 )
{
handleStartMoving ( ID );
creAnims [ ID ] -> setType ( 2 );
}
2009-01-15 17:01:08 +00:00
while ( attackingInfo != NULL || creAnims [ ID ] -> getType () != 2 )
{
2009-04-14 12:47:09 +00:00
show ( screen );
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
CStack aStack = * LOCPLINT -> cb -> battleGetStackByID ( ID ); //attacking stack
int reversedShift = 0 ; //shift of attacking stack's position due to reversing
if ( aStack . attackerOwned )
{
if ( aStack . creature -> isDoubleWide ())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
break ;
case 2 :
break ;
case 3 :
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
reverseCreature ( ID , aStack . position , true );
break ;
case - 1 :
if ( BattleInfo :: mutualPosition ( aStack . position + ( aStack . attackerOwned ? - 1 : 1 ), dest ) >= 0 ) //if reversing stack will make its position adjacent to dest
{
reverseCreature ( ID , aStack . position , true );
reversedShift = ( aStack . attackerOwned ? - 1 : 1 );
}
break ;
}
}
else //else for if(aStack.creature->isDoubleWide())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , dest )) //attack direction
{
case 0 :
reverseCreature ( ID , aStack . position , true );
break ;
case 1 :
break ;
case 2 :
break ;
case 3 :
break ;
case 4 :
reverseCreature ( ID , aStack . position , true );
break ;
case 5 :
reverseCreature ( ID , aStack . position , true );
break ;
}
}
}
else //if(aStack.attackerOwned)
{
if ( aStack . creature -> isDoubleWide ())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
break ;
case 2 :
reverseCreature ( ID , aStack . position , true );
break ;
case 3 :
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
//reverseCreature(ID, aStack.position, true);
break ;
case - 1 :
if ( BattleInfo :: mutualPosition ( aStack . position + ( aStack . attackerOwned ? - 1 : 1 ), dest ) >= 0 ) //if reversing stack will make its position adjacent to dest
{
reverseCreature ( ID , aStack . position , true );
reversedShift = ( aStack . attackerOwned ? - 1 : 1 );
}
break ;
}
}
else //else for if(aStack.creature->isDoubleWide())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
reverseCreature ( ID , aStack . position , true );
break ;
case 2 :
reverseCreature ( ID , aStack . position , true );
break ;
case 3 :
reverseCreature ( ID , aStack . position , true );
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
//reverseCreature(ID, aStack.position, true);
break ;
}
}
}
attackingInfo = new CAttHelper ;
attackingInfo -> dest = dest ;
attackingInfo -> frame = 0 ;
attackingInfo -> hitCount = 0 ;
attackingInfo -> ID = ID ;
attackingInfo -> IDby = LOCPLINT -> cb -> battleGetStackByPos ( dest ) -> ID ;
attackingInfo -> reversing = false ;
attackingInfo -> posShiftDueToDist = reversedShift ;
attackingInfo -> shooting = false ;
switch ( BattleInfo :: mutualPosition ( aStack . position + reversedShift , dest )) //attack direction
{
case 0 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 11 );
break ;
case 1 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 11 );
break ;
case 2 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 12 );
break ;
case 3 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 13 );
break ;
case 4 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 13 );
break ;
case 5 :
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( 12 );
break ;
default :
2009-02-21 15:43:28 +00:00
tlog1 << "Critical Error! Wrong dest in stackAttacking! dest: " << dest << " attacking stack pos: " << aStack . position << " reversed shift: " << reversedShift << std :: endl ;
2009-01-15 17:01:08 +00:00
}
}
void CBattleInterface :: newRound ( int number )
{
console -> addText ( CGI -> generaltexth -> allTexts [ 412 ]);
}
void CBattleInterface :: giveCommand ( ui8 action , ui16 tile , ui32 stack , si32 additional )
{
BattleAction * ba = new BattleAction (); //is deleted in CPlayerInterface::activeStack()
ba -> side = defendingHeroInstance ? ( LOCPLINT -> playerID == defendingHeroInstance -> tempOwner ) : false ;
ba -> actionType = action ;
ba -> destinationTile = tile ;
ba -> stackNumber = stack ;
ba -> additionalInfo = additional ;
givenCommand -> setn ( ba );
myTurn = false ;
activeStack = - 1 ;
}
bool CBattleInterface :: isTileAttackable ( const int & number ) const
{
for ( size_t b = 0 ; b < shadedHexes . size (); ++ b )
{
if ( BattleInfo :: mutualPosition ( shadedHexes [ b ], number ) != - 1 || shadedHexes [ b ] == number )
return true ;
}
return false ;
}
void CBattleInterface :: hexLclicked ( int whichOne )
{
if (( whichOne % BFIELD_WIDTH ) != 0 && ( whichOne % BFIELD_WIDTH ) != ( BFIELD_WIDTH - 1 )) //if player is trying to attack enemey unit or move creature stack
{
if ( ! myTurn )
return ; //we are not permit to do anything
if ( spellDestSelectMode )
{
//checking destination
bool allowCasting = true ;
switch ( spellSelMode )
{
case 1 :
if ( ! LOCPLINT -> cb -> battleGetStackByPos ( whichOne ) || LOCPLINT -> playerID != LOCPLINT -> cb -> battleGetStackByPos ( whichOne ) -> owner )
allowCasting = false ;
break ;
case 2 :
if ( ! LOCPLINT -> cb -> battleGetStackByPos ( whichOne ) || LOCPLINT -> playerID == LOCPLINT -> cb -> battleGetStackByPos ( whichOne ) -> owner )
allowCasting = false ;
break ;
case 3 :
if ( ! LOCPLINT -> cb -> battleGetStackByPos ( whichOne ))
allowCasting = false ;
break ;
case 4 : //TODO: implement this case
break ;
}
//destination checked
if ( allowCasting )
{
spellToCast -> destinationTile = whichOne ;
LOCPLINT -> cb -> battleMakeAction ( spellToCast );
delete spellToCast ;
spellToCast = NULL ;
spellDestSelectMode = false ;
CGI -> curh -> changeGraphic ( 1 , 6 );
}
}
else
{
CStack * dest = LOCPLINT -> cb -> battleGetStackByPos ( whichOne ); //creature at destination tile; -1 if there is no one
if ( ! dest || ! dest -> alive ()) //no creature at that tile
{
if ( std :: find ( shadedHexes . begin (), shadedHexes . end (), whichOne ) != shadedHexes . end ()) // and it's in our range
{
CGI -> curh -> changeGraphic ( 1 , 6 ); //cursor should be changed
2009-02-05 14:44:27 +00:00
if ( LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> creature -> isDoubleWide ())
{
std :: vector < int > acc = LOCPLINT -> cb -> battleGetAvailableHexes ( activeStack , false );
2009-02-14 13:49:30 +00:00
int shiftedDest = whichOne + ( LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> attackerOwned ? 1 : - 1 );
2009-02-05 14:44:27 +00:00
if ( vstd :: contains ( acc , whichOne ))
giveCommand ( 2 , whichOne , activeStack );
2009-02-14 13:49:30 +00:00
else if ( vstd :: contains ( acc , shiftedDest ))
giveCommand ( 2 , shiftedDest , activeStack );
2009-02-05 14:44:27 +00:00
}
else
{
giveCommand ( 2 , whichOne , activeStack );
}
2009-01-15 17:01:08 +00:00
}
}
else if ( dest -> owner != attackingHeroInstance -> tempOwner
&& LOCPLINT -> cb -> battleCanShoot ( activeStack , whichOne ) ) //shooting
{
CGI -> curh -> changeGraphic ( 1 , 6 ); //cursor should be changed
giveCommand ( 7 , whichOne , activeStack );
}
else if ( dest -> owner != attackingHeroInstance -> tempOwner ) //attacking
{
switch ( CGI -> curh -> number )
{
2009-04-07 17:51:50 +00:00
case 12 : //from bottom right
{
int destHex = whichOne + ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH + 1 );
if ( vstd :: contains ( shadedHexes , destHex ))
giveCommand ( 6 , destHex , activeStack , whichOne );
else if ( attackingHeroInstance -> tempOwner == LOCPLINT -> cb -> getMyColor ()) //if we are attacker
{
if ( vstd :: contains ( shadedHexes , destHex + 1 ))
giveCommand ( 6 , destHex + 1 , activeStack , whichOne );
}
else //if we are defneder
{
if ( vstd :: contains ( shadedHexes , destHex - 1 ))
giveCommand ( 6 , destHex - 1 , activeStack , whichOne );
}
break ;
}
case 7 : //from bottom left
{
int destHex = whichOne + ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH - 1 : BFIELD_WIDTH );
if ( vstd :: contains ( shadedHexes , destHex ))
giveCommand ( 6 , destHex , activeStack , whichOne );
else if ( attackingHeroInstance -> tempOwner == LOCPLINT -> cb -> getMyColor ()) //if we are attacker
{
if ( vstd :: contains ( shadedHexes , destHex + 1 ))
giveCommand ( 6 , destHex + 1 , activeStack , whichOne );
}
else //if we are defneder
{
if ( vstd :: contains ( shadedHexes , destHex - 1 ))
giveCommand ( 6 , destHex - 1 , activeStack , whichOne );
}
break ;
}
case 8 : //from left
2009-02-05 14:44:27 +00:00
if ( LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> creature -> isDoubleWide () && ! LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> attackerOwned )
{
std :: vector < int > acc = LOCPLINT -> cb -> battleGetAvailableHexes ( activeStack , false );
if ( vstd :: contains ( acc , whichOne ))
giveCommand ( 6 , whichOne - 1 , activeStack , whichOne );
else
giveCommand ( 6 , whichOne - 2 , activeStack , whichOne );
}
else
{
giveCommand ( 6 , whichOne - 1 , activeStack , whichOne );
}
2009-01-15 17:01:08 +00:00
break ;
2009-04-07 17:51:50 +00:00
case 9 : //from top left
{
int destHex = whichOne - ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH + 1 : BFIELD_WIDTH );
if ( vstd :: contains ( shadedHexes , destHex ))
giveCommand ( 6 , destHex , activeStack , whichOne );
else if ( attackingHeroInstance -> tempOwner == LOCPLINT -> cb -> getMyColor ()) //if we are attacker
{
if ( vstd :: contains ( shadedHexes , destHex + 1 ))
giveCommand ( 6 , destHex + 1 , activeStack , whichOne );
}
else //if we are defneder
{
if ( vstd :: contains ( shadedHexes , destHex - 1 ))
giveCommand ( 6 , destHex - 1 , activeStack , whichOne );
}
break ;
}
case 10 : //from top right
{
int destHex = whichOne - ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH - 1 );
if ( vstd :: contains ( shadedHexes , destHex ))
giveCommand ( 6 , destHex , activeStack , whichOne );
else if ( attackingHeroInstance -> tempOwner == LOCPLINT -> cb -> getMyColor ()) //if we are attacker
{
if ( vstd :: contains ( shadedHexes , destHex + 1 ))
giveCommand ( 6 , destHex + 1 , activeStack , whichOne );
}
else //if we are defneder
{
if ( vstd :: contains ( shadedHexes , destHex - 1 ))
giveCommand ( 6 , destHex - 1 , activeStack , whichOne );
}
break ;
}
case 11 : //from right
2009-02-05 14:44:27 +00:00
if ( LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> creature -> isDoubleWide () && LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> attackerOwned )
{
std :: vector < int > acc = LOCPLINT -> cb -> battleGetAvailableHexes ( activeStack , false );
if ( vstd :: contains ( acc , whichOne ))
giveCommand ( 6 , whichOne + 1 , activeStack , whichOne );
else
giveCommand ( 6 , whichOne + 2 , activeStack , whichOne );
}
else
{
giveCommand ( 6 , whichOne + 1 , activeStack , whichOne );
}
2009-01-15 17:01:08 +00:00
break ;
}
CGI -> curh -> changeGraphic ( 1 , 6 ); //cursor should be changed
}
}
}
}
void CBattleInterface :: stackIsShooting ( int ID , int dest )
{
if ( attackingInfo != NULL )
{
return ; //something went wrong
}
//projectile
float projectileAngle ; //in radians; if positive, projectiles goes up
float straightAngle = 0.2f ; //maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
int fromHex = LOCPLINT -> cb -> battleGetPos ( ID );
2009-01-16 17:58:41 +00:00
projectileAngle = atan2 ( float ( abs ( dest - fromHex ) / BFIELD_WIDTH ), float ( abs ( dest - fromHex ) % BFIELD_WIDTH ));
2009-01-15 17:01:08 +00:00
if ( fromHex < dest )
projectileAngle = - projectileAngle ;
SProjectileInfo spi ;
spi . creID = LOCPLINT -> cb -> battleGetStackByID ( ID ) -> creature -> idNumber ;
2009-01-16 17:58:41 +00:00
spi . reverse = ! LOCPLINT -> cb -> battleGetStackByID ( ID ) -> attackerOwned ;
2009-01-15 17:01:08 +00:00
spi . step = 0 ;
spi . frameNum = 0 ;
spi . spin = CGI -> creh -> idToProjectileSpin [ spi . creID ];
std :: pair < int , int > xycoord = CBattleHex :: getXYUnitAnim ( LOCPLINT -> cb -> battleGetPos ( ID ), true , & LOCPLINT -> cb -> battleGetCreature ( ID ));
std :: pair < int , int > destcoord = CBattleHex :: getXYUnitAnim ( dest , false , & LOCPLINT -> cb -> battleGetCreature ( ID ));
destcoord . first += 250 ; destcoord . second += 210 ; //TODO: find a better place to shoot
if ( projectileAngle > straightAngle ) //upper shot
{
spi . x = xycoord . first + 200 + LOCPLINT -> cb -> battleGetCreature ( ID ). upperRightMissleOffsetX ;
spi . y = xycoord . second + 100 - LOCPLINT -> cb -> battleGetCreature ( ID ). upperRightMissleOffsetY ;
}
else if ( projectileAngle < - straightAngle ) //lower shot
{
spi . x = xycoord . first + 200 + LOCPLINT -> cb -> battleGetCreature ( ID ). lowerRightMissleOffsetX ;
spi . y = xycoord . second + 150 - LOCPLINT -> cb -> battleGetCreature ( ID ). lowerRightMissleOffsetY ;
}
else //straight shot
{
spi . x = xycoord . first + 200 + LOCPLINT -> cb -> battleGetCreature ( ID ). rightMissleOffsetX ;
spi . y = xycoord . second + 125 - LOCPLINT -> cb -> battleGetCreature ( ID ). rightMissleOffsetY ;
}
spi . lastStep = sqrt (( float )(( destcoord . first - spi . x ) * ( destcoord . first - spi . x ) + ( destcoord . second - spi . y ) * ( destcoord . second - spi . y ))) / 40 ;
if ( spi . lastStep == 0 )
spi . lastStep = 1 ;
spi . dx = ( destcoord . first - spi . x ) / spi . lastStep ;
spi . dy = ( destcoord . second - spi . y ) / spi . lastStep ;
//set starting frame
if ( spi . spin )
{
spi . frameNum = 0 ;
}
else
{
spi . frameNum = (( M_PI / 2.0f - projectileAngle ) / ( 2.0f * M_PI ) + 1 / (( float )( 2 * ( idToProjectile [ spi . creID ] -> ourImages . size () - 1 )))) * ( idToProjectile [ spi . creID ] -> ourImages . size () - 1 );
}
//set delay
spi . animStartDelay = CGI -> creh -> creatures [ spi . creID ]. attackClimaxFrame ;
projectiles . push_back ( spi );
//attack aniamtion
attackingInfo = new CAttHelper ;
attackingInfo -> dest = dest ;
attackingInfo -> frame = 0 ;
attackingInfo -> hitCount = 0 ;
attackingInfo -> ID = ID ;
attackingInfo -> reversing = false ;
attackingInfo -> posShiftDueToDist = 0 ;
attackingInfo -> shooting = true ;
if ( projectileAngle > straightAngle ) //upper shot
attackingInfo -> shootingGroup = 14 ;
else if ( projectileAngle < - straightAngle ) //lower shot
attackingInfo -> shootingGroup = 16 ;
else //straight shot
attackingInfo -> shootingGroup = 15 ;
attackingInfo -> maxframe = creAnims [ ID ] -> framesInGroup ( attackingInfo -> shootingGroup );
}
void CBattleInterface :: battleFinished ( const BattleResult & br )
{
CGI -> curh -> changeGraphic ( 0 , 0 );
2009-02-07 16:07:29 +00:00
SDL_Rect temp_rect = genRect ( 561 , 470 , ( screen -> w - 800 ) / 2 + 165 , ( screen -> h - 600 ) / 2 + 19 );
2009-01-15 17:01:08 +00:00
resWindow = new CBattleReslutWindow ( br , temp_rect , this );
2009-04-14 12:47:09 +00:00
LOCPLINT -> pushInt ( resWindow );
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: spellCasted ( SpellCasted * sc )
{
2009-04-14 12:47:09 +00:00
if ( sc -> side == ! LOCPLINT -> cb -> battleGetStackByID ( activeStack ) -> attackerOwned )
bSpell -> block ( true );
2009-01-15 17:01:08 +00:00
std :: vector < std :: string > anims ; //for magic arrow and ice bolt
switch ( sc -> id )
{
case 15 : //magic arrow
{
//initialization of anims
anims . push_back ( "C20SPX0.DEF" ); anims . push_back ( "C20SPX1.DEF" ); anims . push_back ( "C20SPX2.DEF" ); anims . push_back ( "C20SPX3.DEF" ); anims . push_back ( "C20SPX4.DEF" );
}
case 16 : //ice bolt
{
if ( anims . size () == 0 ) //initialiaztion of anims
{
anims . push_back ( "C08SPW0.DEF" ); anims . push_back ( "C08SPW1.DEF" ); anims . push_back ( "C08SPW2.DEF" ); anims . push_back ( "C08SPW3.DEF" ); anims . push_back ( "C08SPW4.DEF" );
}
} //end of ice bolt only part
{ //common ice bolt and magic arrow part
//initial variables
std :: string animToDisplay ;
std :: pair < int , int > srccoord = sc -> side ? std :: make_pair ( 770 , 60 ) : std :: make_pair ( 30 , 60 );
std :: pair < int , int > destcoord = CBattleHex :: getXYUnitAnim ( sc -> tile , ! sc -> side , LOCPLINT -> cb -> battleGetStackByPos ( sc -> tile ) -> creature ); //position attacked by arrow
destcoord . first += 250 ; destcoord . second += 240 ;
//animation angle
float angle = atan2 ( float ( destcoord . first - srccoord . first ), float ( destcoord . second - srccoord . second ));
//choosing animation by angle
if ( angle > 1.50 )
animToDisplay = anims [ 0 ];
else if ( angle > 1.20 )
animToDisplay = anims [ 1 ];
else if ( angle > 0.90 )
animToDisplay = anims [ 2 ];
else if ( angle > 0.60 )
animToDisplay = anims [ 3 ];
else
animToDisplay = anims [ 4 ];
//displaying animation
int steps = sqrt (( float )(( destcoord . first - srccoord . first ) * ( destcoord . first - srccoord . first ) + ( destcoord . second - srccoord . second ) * ( destcoord . second - srccoord . second ))) / 40 ;
if ( steps <= 0 )
steps = 1 ;
CDefHandler * animDef = CDefHandler :: giveDef ( animToDisplay );
int dx = ( destcoord . first - srccoord . first - animDef -> ourImages [ 0 ]. bitmap -> w ) / steps , dy = ( destcoord . second - srccoord . second - animDef -> ourImages [ 0 ]. bitmap -> h ) / steps ;
SDL_Rect buf ;
SDL_GetClipRect ( screen , & buf );
SDL_SetClipRect ( screen , & pos ); //setting rect we can blit to
for ( int g = 0 ; g < steps ; ++ g )
{
2009-04-14 12:47:09 +00:00
show ( screen );
2009-01-15 17:01:08 +00:00
SDL_Rect & srcr = animDef -> ourImages [ g % animDef -> ourImages . size ()]. bitmap -> clip_rect ;
SDL_Rect dstr = genRect ( srcr . h , srcr . w , srccoord . first + g * dx , srccoord . second + g * dy );
SDL_BlitSurface ( animDef -> ourImages [ g % animDef -> ourImages . size ()]. bitmap , & srcr , screen , & dstr );
2009-04-14 12:47:09 +00:00
CSDL_Ext :: update ( screen );
2009-01-15 17:01:08 +00:00
SDL_framerateDelay ( LOCPLINT -> mainFPSmng );
}
SDL_SetClipRect ( screen , & buf ); //restoring previous clip rect
break ; //for 15 and 16 cases
}
2009-03-21 16:03:07 +00:00
}
}
void CBattleInterface :: battleStacksEffectsSet ( const SetStackEffect & sse )
{
for ( std :: set < ui32 >:: const_iterator ci = sse . stacks . begin (); ci != sse . stacks . end (); ++ ci )
{
displayEffect ( spellToEffect [ sse . effect . id ], LOCPLINT -> cb -> battleGetStackByID ( * ci ) -> position );
2009-01-15 17:01:08 +00:00
}
2009-04-04 19:26:41 +00:00
redrawBackgroundWithHexes ( activeStack );
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: castThisSpell ( int spellID )
{
BattleAction * ba = new BattleAction ;
ba -> actionType = 1 ;
ba -> additionalInfo = spellID ; //spell number
ba -> destinationTile = - 1 ;
ba -> stackNumber = ( attackingHeroInstance -> tempOwner == LOCPLINT -> playerID ) ? - 1 : - 2 ;
ba -> side = defendingHeroInstance ? ( LOCPLINT -> playerID == defendingHeroInstance -> tempOwner ) : false ;
spellToCast = ba ;
spellDestSelectMode = true ;
//choosing possible tragets
const CGHeroInstance * castingHero = ( attackingHeroInstance -> tempOwner == LOCPLINT -> playerID ) ? attackingHeroInstance : attackingHeroInstance ;
spellSelMode = 0 ;
2009-03-21 16:03:07 +00:00
if ( CGI -> spellh -> spells [ spellID ]. attributes . find ( "CREATURE_TARGET" ) != std :: string :: npos ) //spell to be cast on one specific creature
2009-01-15 17:01:08 +00:00
{
switch ( CGI -> spellh -> spells [ spellID ]. positiveness )
{
case - 1 :
spellSelMode = 2 ;
break ;
case 0 :
spellSelMode = 3 ;
break ;
case 1 :
spellSelMode = 1 ;
break ;
}
}
2009-03-21 16:03:07 +00:00
if ( CGI -> spellh -> spells [ spellID ]. attributes . find ( "CREATURE_TARGET_2" ) != std :: string :: npos ) //spell to be cast on a specific creature but massive on expert
2009-01-15 17:01:08 +00:00
{
if ( castingHero && castingHero -> getSpellSecLevel ( spellID ) < 3 )
{
switch ( CGI -> spellh -> spells [ spellID ]. positiveness )
{
case - 1 :
spellSelMode = 2 ;
break ;
case 0 :
spellSelMode = 3 ;
break ;
case 1 :
spellSelMode = 1 ;
break ;
}
}
else
{
spellSelMode = - 1 ;
}
}
2009-01-16 17:58:41 +00:00
if ( spellSelMode == - 1 ) //user does not have to select location
{
spellToCast -> destinationTile = - 1 ;
LOCPLINT -> cb -> battleMakeAction ( spellToCast );
delete spellToCast ;
spellToCast = NULL ;
spellDestSelectMode = false ;
CGI -> curh -> changeGraphic ( 1 , 6 );
}
else
{
CGI -> curh -> changeGraphic ( 3 , 0 );
}
2009-01-15 17:01:08 +00:00
}
void CBattleInterface :: displayEffect ( ui32 effect , int destTile )
{
if ( graphics -> battleACToDef [ effect ]. size () != 0 )
{
SBattleEffect be ;
be . anim = CDefHandler :: giveDef ( graphics -> battleACToDef [ effect ][ 0 ]);
be . frame = 0 ;
be . maxFrame = be . anim -> ourImages . size ();
be . x = 22 * ( (( destTile / BFIELD_WIDTH ) + 1 ) % 2 ) + 44 * ( destTile % BFIELD_WIDTH ) + 45 ;
be . y = 105 + 42 * ( destTile / BFIELD_WIDTH );
if ( effect != 1 && effect != 0 )
{
be . x -= be . anim -> ourImages [ 0 ]. bitmap -> w / 2 ;
be . y -= be . anim -> ourImages [ 0 ]. bitmap -> h / 2 ;
}
else if ( effect == 1 )
{
be . x -= be . anim -> ourImages [ 0 ]. bitmap -> w ;
be . y -= be . anim -> ourImages [ 0 ]. bitmap -> h ;
}
else if ( effect == 0 )
{
be . x -= be . anim -> ourImages [ 0 ]. bitmap -> w / 2 ;
be . y -= be . anim -> ourImages [ 0 ]. bitmap -> h ;
}
battleEffects . push_back ( be );
}
//battleEffects
}
void CBattleInterface :: setAnimSpeed ( int set )
{
2009-03-28 18:46:20 +00:00
settings . animSpeed = set ;
2009-01-15 17:01:08 +00:00
}
int CBattleInterface :: getAnimSpeed () const
{
2009-03-28 18:46:20 +00:00
return settings . animSpeed ;
2009-01-15 17:01:08 +00:00
}
float CBattleInterface :: getAnimSpeedMultiplier () const
{
2009-03-28 18:46:20 +00:00
switch ( settings . animSpeed )
2009-01-15 17:01:08 +00:00
{
case 1 :
return 3.5f ;
case 2 :
return 2.2f ;
case 4 :
return 1.0f ;
default :
return 0.0f ;
}
}
void CBattleInterface :: attackingShowHelper ()
{
if ( attackingInfo && ! attackingInfo -> reversing )
{
if ( attackingInfo -> frame == 0 )
{
CStack aStack = * LOCPLINT -> cb -> battleGetStackByID ( attackingInfo -> ID ); //attacking stack
if ( attackingInfo -> shooting )
{
creAnims [ attackingInfo -> ID ] -> setType ( attackingInfo -> shootingGroup );
}
else
{
if ( aStack . creature -> isDoubleWide ())
{
switch ( BattleInfo :: mutualPosition ( aStack . position + attackingInfo -> posShiftDueToDist , attackingInfo -> dest )) //attack direction
{
case 0 :
creAnims [ attackingInfo -> ID ] -> setType ( 11 );
break ;
case 1 :
creAnims [ attackingInfo -> ID ] -> setType ( 11 );
break ;
case 2 :
creAnims [ attackingInfo -> ID ] -> setType ( 12 );
break ;
case 3 :
creAnims [ attackingInfo -> ID ] -> setType ( 13 );
break ;
case 4 :
creAnims [ attackingInfo -> ID ] -> setType ( 13 );
break ;
case 5 :
creAnims [ attackingInfo -> ID ] -> setType ( 12 );
break ;
}
}
else //else for if(aStack.creature->isDoubleWide())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , attackingInfo -> dest )) //attack direction
{
case 0 :
creAnims [ attackingInfo -> ID ] -> setType ( 11 );
break ;
case 1 :
creAnims [ attackingInfo -> ID ] -> setType ( 11 );
break ;
case 2 :
creAnims [ attackingInfo -> ID ] -> setType ( 12 );
break ;
case 3 :
creAnims [ attackingInfo -> ID ] -> setType ( 13 );
break ;
case 4 :
creAnims [ attackingInfo -> ID ] -> setType ( 13 );
break ;
case 5 :
creAnims [ attackingInfo -> ID ] -> setType ( 12 );
break ;
}
}
}
}
else if ( attackingInfo -> frame == ( attackingInfo -> maxframe - 1 ))
{
attackingInfo -> reversing = true ;
CStack * aStackp = LOCPLINT -> cb -> battleGetStackByID ( attackingInfo -> ID ); //attacking stack
if ( aStackp == NULL )
return ;
CStack aStack = * aStackp ;
if ( aStack . attackerOwned )
{
if ( aStack . creature -> isDoubleWide ())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , attackingInfo -> dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
break ;
case 2 :
break ;
case 3 :
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case - 1 :
if ( attackingInfo -> posShiftDueToDist ) //if reversing stack will make its position adjacent to dest
{
reverseCreature ( attackingInfo -> ID , aStack . position , true );
}
break ;
}
}
else //else for if(aStack.creature->isDoubleWide())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , attackingInfo -> dest )) //attack direction
{
case 0 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 1 :
break ;
case 2 :
break ;
case 3 :
break ;
case 4 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 5 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
}
}
}
else //if(aStack.attackerOwned)
{
if ( aStack . creature -> isDoubleWide ())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , attackingInfo -> dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
break ;
case 2 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 3 :
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
//reverseCreature(ID, aStack.position, true);
break ;
case - 1 :
if ( attackingInfo -> posShiftDueToDist ) //if reversing stack will make its position adjacent to dest
{
reverseCreature ( attackingInfo -> ID , aStack . position , true );
}
break ;
}
}
else //else for if(aStack.creature->isDoubleWide())
{
switch ( BattleInfo :: mutualPosition ( aStack . position , attackingInfo -> dest )) //attack direction
{
case 0 :
//reverseCreature(ID, aStack.position, true);
break ;
case 1 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 2 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 3 :
reverseCreature ( attackingInfo -> ID , aStack . position , true );
break ;
case 4 :
//reverseCreature(ID, aStack.position, true);
break ;
case 5 :
//reverseCreature(ID, aStack.position, true);
break ;
}
}
}
attackingInfo -> reversing = false ;
creAnims [ attackingInfo -> ID ] -> setType ( 2 );
delete attackingInfo ;
attackingInfo = NULL ;
}
if ( attackingInfo )
{
attackingInfo -> hitCount ++ ;
2009-03-28 18:46:20 +00:00
if ( attackingInfo -> hitCount % ( 4 / settings . animSpeed ) == 0 )
2009-01-15 17:01:08 +00:00
attackingInfo -> frame ++ ;
}
}
}
void CBattleInterface :: redrawBackgroundWithHexes ( int activeStack )
{
2009-02-05 14:44:27 +00:00
shadedHexes = LOCPLINT -> cb -> battleGetAvailableHexes ( activeStack , true );
2009-01-15 17:01:08 +00:00
//preparating background graphic with hexes and shaded hexes
blitAt ( background , 0 , 0 , backgroundWithHexes );
2009-03-28 18:46:20 +00:00
if ( settings . printCellBorders )
2009-01-15 17:01:08 +00:00
CSDL_Ext :: blit8bppAlphaTo24bpp ( cellBorders , NULL , backgroundWithHexes , NULL );
2009-03-28 18:46:20 +00:00
if ( settings . printStackRange )
2009-01-15 17:01:08 +00:00
{
for ( size_t m = 0 ; m < shadedHexes . size (); ++ m ) //rows
{
2009-01-16 17:58:41 +00:00
int i = shadedHexes [ m ] / BFIELD_WIDTH ; //row
int j = shadedHexes [ m ] % BFIELD_WIDTH - 1 ; //column
2009-01-15 17:01:08 +00:00
int x = 58 + ( i % 2 == 0 ? 22 : 0 ) + 44 * j ;
int y = 86 + 42 * i ;
CSDL_Ext :: blit8bppAlphaTo24bpp ( cellShade , NULL , backgroundWithHexes , & genRect ( cellShade -> h , cellShade -> w , x , y ));
}
}
}
void CBattleInterface :: printConsoleAttacked ( int ID , int dmg , int killed , int IDby )
{
char tabh [ 200 ];
CStack attacker = * LOCPLINT -> cb -> battleGetStackByID ( IDby );
CStack defender = * LOCPLINT -> cb -> battleGetStackByID ( ID );
int end = sprintf ( tabh , CGI -> generaltexth -> allTexts [ attacker . amount > 1 ? 377 : 376 ]. c_str (),
( attacker . amount > 1 ? attacker . creature -> namePl . c_str () : attacker . creature -> nameSing . c_str ()),
dmg );
if ( killed > 0 )
{
if ( killed > 1 )
{
sprintf ( tabh + end , CGI -> generaltexth -> allTexts [ 379 ]. c_str (), killed , defender . creature -> namePl . c_str ());
}
else //killed == 1
{
sprintf ( tabh + end , CGI -> generaltexth -> allTexts [ 378 ]. c_str (), defender . creature -> nameSing . c_str ());
}
}
console -> addText ( std :: string ( tabh ));
}
void CBattleInterface :: projectileShowHelper ( SDL_Surface * to )
{
if ( to == NULL )
to = screen ;
std :: list < std :: list < SProjectileInfo >:: iterator > toBeDeleted ;
for ( std :: list < SProjectileInfo >:: iterator it = projectiles . begin (); it != projectiles . end (); ++ it )
{
if ( it -> animStartDelay > 0 )
{
-- ( it -> animStartDelay );
continue ;
}
SDL_Rect dst ;
dst . h = idToProjectile [ it -> creID ] -> ourImages [ it -> frameNum ]. bitmap -> h ;
dst . w = idToProjectile [ it -> creID ] -> ourImages [ it -> frameNum ]. bitmap -> w ;
dst . x = it -> x ;
dst . y = it -> y ;
2009-01-16 17:58:41 +00:00
if ( it -> reverse )
{
SDL_Surface * rev = CSDL_Ext :: rotate01 ( idToProjectile [ it -> creID ] -> ourImages [ it -> frameNum ]. bitmap );
CSDL_Ext :: blit8bppAlphaTo24bpp ( rev , NULL , to , & dst );
SDL_FreeSurface ( rev );
}
else
{
CSDL_Ext :: blit8bppAlphaTo24bpp ( idToProjectile [ it -> creID ] -> ourImages [ it -> frameNum ]. bitmap , NULL , to , & dst );
}
2009-01-15 17:01:08 +00:00
//actualizing projectile
++ it -> step ;
if ( it -> step == it -> lastStep )
{
toBeDeleted . insert ( toBeDeleted . end (), it );
}
else
{
it -> x += it -> dx ;
it -> y += it -> dy ;
if ( it -> spin )
{
++ ( it -> frameNum );
it -> frameNum %= idToProjectile [ it -> creID ] -> ourImages . size ();
}
}
}
for ( std :: list < std :: list < SProjectileInfo >:: iterator >:: iterator it = toBeDeleted . begin (); it != toBeDeleted . end (); ++ it )
{
projectiles . erase ( * it );
}
}
void CBattleHero :: show ( SDL_Surface * to )
{
//animation of flag
if ( flip )
{
CSDL_Ext :: blit8bppAlphaTo24bpp (
flag -> ourImages [ flagAnim ]. bitmap ,
NULL ,
screen ,
& genRect (
flag -> ourImages [ flagAnim ]. bitmap -> h ,
flag -> ourImages [ flagAnim ]. bitmap -> w ,
62 + pos . x ,
39 + pos . y
)
);
}
else
{
CSDL_Ext :: blit8bppAlphaTo24bpp (
flag -> ourImages [ flagAnim ]. bitmap ,
NULL ,
screen ,
& genRect (
flag -> ourImages [ flagAnim ]. bitmap -> h ,
flag -> ourImages [ flagAnim ]. bitmap -> w ,
71 + pos . x ,
39 + pos . y
)
);
}
++ flagAnimCount ;
if ( flagAnimCount % 4 == 0 )
{
++ flagAnim ;
flagAnim %= flag -> ourImages . size ();
}
//animation of hero
int tick =- 1 ;
for ( int i = 0 ; i < dh -> ourImages . size (); ++ i )
{
if ( dh -> ourImages [ i ]. groupNumber == phase )
++ tick ;
if ( tick == image )
{
SDL_Rect posb = pos ;
CSDL_Ext :: blit8bppAlphaTo24bpp ( dh -> ourImages [ i ]. bitmap , NULL , to , & posb );
2009-02-28 16:44:56 +00:00
if ( phase != 4 || nextPhase != - 1 || image < 4 )
2009-01-15 17:01:08 +00:00
{
2009-02-28 16:44:56 +00:00
if ( flagAnimCount % 2 == 0 )
{
++ image ;
}
2009-02-09 14:50:32 +00:00
if ( dh -> ourImages [( i + 1 ) % dh -> ourImages . size ()]. groupNumber != phase ) //back to appropriate frame
{
image = 0 ;
}
}
if ( phase == 4 && nextPhase != - 1 && image == 7 )
{
phase = nextPhase ;
2009-02-28 16:44:56 +00:00
nextPhase = - 1 ;
2009-01-15 17:01:08 +00:00
image = 0 ;
}
break ;
}
}
}
void CBattleHero :: activate ()
{
ClickableL :: activate ();
}
void CBattleHero :: deactivate ()
{
ClickableL :: deactivate ();
}
void CBattleHero :: setPhase ( int newPhase )
{
2009-02-09 14:50:32 +00:00
if ( phase != 4 )
{
phase = newPhase ;
image = 0 ;
}
else
{
nextPhase = newPhase ;
}
2009-01-15 17:01:08 +00:00
}
void CBattleHero :: clickLeft ( boost :: logic :: tribool down )
{
2009-02-28 16:44:56 +00:00
if ( ! down && myHero ) if ( myHero -> getArt ( 17 )) //if both conditions are satisfied; for certain reason myHero->getArt(17) has been checked once even though myHero was NULL
2009-01-15 17:01:08 +00:00
{
for ( int it = 0 ; it < BFIELD_SIZE ; ++ it ) //do nothing when any hex is hovered - hero's animation overlaps battlefield
{
if ( myOwner -> bfield [ it ]. hovered && myOwner -> bfield [ it ]. strictHovered )
return ;
}
CGI -> curh -> changeGraphic ( 0 , 0 );
CSpellWindow * spellWindow = new CSpellWindow ( genRect ( 595 , 620 , ( conf . cc . resx - 620 ) / 2 , ( conf . cc . resy - 595 ) / 2 ), myHero );
2009-04-14 12:47:09 +00:00
LOCPLINT -> pushInt ( spellWindow );
2009-01-15 17:01:08 +00:00
}
}
2009-02-09 14:50:32 +00:00
CBattleHero :: CBattleHero ( const std :: string & defName , int phaseG , int imageG , bool flipG , unsigned char player , const CGHeroInstance * hero , const CBattleInterface * owner ) : phase ( phaseG ), image ( imageG ), flip ( flipG ), flagAnim ( 0 ), myHero ( hero ), myOwner ( owner ), nextPhase ( - 1 )
2009-01-15 17:01:08 +00:00
{
dh = CDefHandler :: giveDef ( defName );
for ( int i = 0 ; i < dh -> ourImages . size (); ++ i ) //transforming images
{
if ( flip )
{
SDL_Surface * hlp = CSDL_Ext :: rotate01 ( dh -> ourImages [ i ]. bitmap );
SDL_FreeSurface ( dh -> ourImages [ i ]. bitmap );
dh -> ourImages [ i ]. bitmap = hlp ;
}
dh -> ourImages [ i ]. bitmap = CSDL_Ext :: alphaTransform ( dh -> ourImages [ i ]. bitmap );
}
dh -> alphaTransformed = true ;
if ( flip )
flag = CDefHandler :: giveDef ( "CMFLAGR.DEF" );
else
flag = CDefHandler :: giveDef ( "CMFLAGL.DEF" );
//coloring flag and adding transparency
for ( int i = 0 ; i < flag -> ourImages . size (); ++ i )
{
flag -> ourImages [ i ]. bitmap = CSDL_Ext :: alphaTransform ( flag -> ourImages [ i ]. bitmap );
graphics -> blueToPlayersAdv ( flag -> ourImages [ i ]. bitmap , player );
}
}
CBattleHero ::~ CBattleHero ()
{
delete dh ;
delete flag ;
}
std :: pair < int , int > CBattleHex :: getXYUnitAnim ( const int & hexNum , const bool & attacker , const CCreature * creature )
{
std :: pair < int , int > ret = std :: make_pair ( - 500 , - 500 ); //returned value
ret . second = - 139 + 42 * ( hexNum / BFIELD_WIDTH ); //counting y
//counting x
if ( attacker )
{
ret . first = - 160 + 22 * ( (( hexNum / BFIELD_WIDTH ) + 1 ) % 2 ) + 44 * ( hexNum % BFIELD_WIDTH );
}
else
{
ret . first = - 219 + 22 * ( (( hexNum / BFIELD_WIDTH ) + 1 ) % 2 ) + 44 * ( hexNum % BFIELD_WIDTH );
}
//shifting position for double - hex creatures
if ( creature && creature -> isDoubleWide ())
{
if ( attacker )
{
ret . first -= 42 ;
}
else
{
ret . first += 42 ;
}
}
//returning
return ret ;
}
void CBattleHex :: activate ()
{
Hoverable :: activate ();
MotionInterested :: activate ();
ClickableL :: activate ();
ClickableR :: activate ();
}
void CBattleHex :: deactivate ()
{
Hoverable :: deactivate ();
MotionInterested :: deactivate ();
ClickableL :: deactivate ();
ClickableR :: deactivate ();
}
void CBattleHex :: hover ( bool on )
{
hovered = on ;
Hoverable :: hover ( on );
if ( ! on && setAlterText )
{
myInterface -> console -> alterTxt = std :: string ();
setAlterText = false ;
}
}
CBattleHex :: CBattleHex () : myNumber ( - 1 ), accesible ( true ), hovered ( false ), strictHovered ( false ), myInterface ( NULL ), setAlterText ( false )
{
}
void CBattleHex :: mouseMoved ( const SDL_MouseMotionEvent & sEvent )
{
if ( myInterface -> cellShade )
{
if ( CSDL_Ext :: SDL_GetPixel ( myInterface -> cellShade , sEvent . x - pos . x , sEvent . y - pos . y ) == 0 ) //hovered pixel is outside hex
{
strictHovered = false ;
}
else //hovered pixel is inside hex
{
strictHovered = true ;
}
}
if ( hovered && strictHovered ) //print attacked creature to console
{
if ( myInterface -> console -> alterTxt . size () == 0 && LOCPLINT -> cb -> battleGetStack ( myNumber ) != - 1 &&
LOCPLINT -> cb -> battleGetStackByPos ( myNumber ) -> owner != LOCPLINT -> playerID &&
LOCPLINT -> cb -> battleGetStackByPos ( myNumber ) -> alive ())
{
char tabh [ 160 ];
CStack attackedStack = * LOCPLINT -> cb -> battleGetStackByPos ( myNumber );
const std :: string & attackedName = attackedStack . amount == 1 ? attackedStack . creature -> nameSing : attackedStack . creature -> namePl ;
sprintf ( tabh , CGI -> generaltexth -> allTexts [ 220 ]. c_str (), attackedName . c_str ());
myInterface -> console -> alterTxt = std :: string ( tabh );
setAlterText = true ;
}
}
else if ( setAlterText )
{
myInterface -> console -> alterTxt = std :: string ();
setAlterText = false ;
}
}
void CBattleHex :: clickLeft ( boost :: logic :: tribool down )
{
if ( ! down && hovered && strictHovered ) //we've been really clicked!
{
myInterface -> hexLclicked ( myNumber );
}
}
void CBattleHex :: clickRight ( boost :: logic :: tribool down )
{
int stID = LOCPLINT -> cb -> battleGetStack ( myNumber ); //id of stack being on this tile
if ( hovered && strictHovered && stID !=- 1 )
{
CStack myst = * LOCPLINT -> cb -> battleGetStackByID ( stID ); //stack info
if ( ! myst . alive ()) return ;
StackState * pom = NULL ;
if ( down )
{
pom = new StackState ();
const CGHeroInstance * h = myst . owner == myInterface -> attackingHeroInstance -> tempOwner ? myInterface -> attackingHeroInstance : myInterface -> defendingHeroInstance ;
if ( h )
{
pom -> attackBonus = h -> getPrimSkillLevel ( 0 );
pom -> defenseBonus = h -> getPrimSkillLevel ( 1 );
2009-02-06 11:50:48 +00:00
pom -> luck = myst . Luck ();
pom -> morale = myst . Morale ();
2009-04-04 19:26:41 +00:00
pom -> speedBonus = myst . Speed () - myst . creature -> speed ;
2009-01-15 17:01:08 +00:00
}
pom -> shotsLeft = myst . shots ;
for ( int vb = 0 ; vb < myst . effects . size (); ++ vb )
{
pom -> effects . insert ( myst . effects [ vb ]. id );
}
pom -> currentHealth = myst . firstHPleft ;
2009-04-14 12:47:09 +00:00
LOCPLINT -> pushInt ( new CCreInfoWindow ( myst . creature -> idNumber , 0 , myst . amount , pom , 0 , 0 , NULL ));
2009-01-15 17:01:08 +00:00
}
delete pom ;
}
}
2009-01-29 18:07:31 +00:00
CBattleConsole :: CBattleConsole () : lastShown ( - 1 ), alterTxt ( "" ), whoSetAlter ( 0 )
2009-01-15 17:01:08 +00:00
{
}
CBattleConsole ::~ CBattleConsole ()
{
texts . clear ();
}
void CBattleConsole :: show ( SDL_Surface * to )
{
2009-04-03 15:55:26 +00:00
if ( ingcAlter . size ())
{
CSDL_Ext :: printAtMiddleWB ( ingcAlter , pos . x + pos . w / 2 , pos . y + 10 , GEOR13 , 80 , zwykly , to );
}
else if ( alterTxt . size ())
2009-01-15 17:01:08 +00:00
{
CSDL_Ext :: printAtMiddleWB ( alterTxt , pos . x + pos . w / 2 , pos . y + 10 , GEOR13 , 80 , zwykly , to );
}
else if ( texts . size ())
{
if ( texts . size () == 1 )
{
CSDL_Ext :: printAtMiddleWB ( texts [ 0 ], pos . x + pos . w / 2 , pos . y + 10 , GEOR13 , 80 , zwykly , to );
}
else
{
CSDL_Ext :: printAtMiddleWB ( texts [ lastShown - 1 ], pos . x + pos . w / 2 , pos . y + 10 , GEOR13 , 80 , zwykly , to );
CSDL_Ext :: printAtMiddleWB ( texts [ lastShown ], pos . x + pos . w / 2 , pos . y + 26 , GEOR13 , 80 , zwykly , to );
}
}
}
bool CBattleConsole :: addText ( const std :: string & text )
{
if ( text . size () > 70 )
return false ; //text too long!
int firstInToken = 0 ;
for ( int i = 0 ; i < text . size (); ++ i ) //tokenize
{
if ( text [ i ] == 10 )
{
texts . push_back ( text . substr ( firstInToken , i - firstInToken ) );
firstInToken = i + 1 ;
}
}
texts . push_back ( text . substr ( firstInToken , text . size ()) );
lastShown = texts . size () - 1 ;
return true ;
}
void CBattleConsole :: eraseText ( unsigned int pos )
{
if ( pos < texts . size ())
{
texts . erase ( texts . begin () + pos );
if ( lastShown == texts . size ())
-- lastShown ;
}
}
void CBattleConsole :: changeTextAt ( const std :: string & text , unsigned int pos )
{
if ( pos >= texts . size ()) //no such pos
return ;
texts [ pos ] = text ;
}
void CBattleConsole :: scrollUp ( unsigned int by )
{
if ( lastShown > by )
lastShown -= by ;
}
void CBattleConsole :: scrollDown ( unsigned int by )
{
if ( lastShown + by < texts . size ())
lastShown += by ;
}
CBattleReslutWindow :: CBattleReslutWindow ( const BattleResult & br , const SDL_Rect & pos , const CBattleInterface * owner )
{
this -> pos = pos ;
background = BitmapHandler :: loadBitmap ( "CPRESULT.BMP" , true );
graphics -> blueToPlayersAdv ( background , LOCPLINT -> playerID );
SDL_Surface * pom = SDL_ConvertSurface ( background , screen -> format , screen -> flags );
SDL_FreeSurface ( background );
background = pom ;
2009-02-07 16:07:29 +00:00
exit = new AdventureMapButton ( std :: string (), std :: string (), boost :: bind ( & CBattleReslutWindow :: bExitf , this ), 384 + pos . x , 505 + pos . y , "iok6432.def" , SDLK_RETURN );
2009-01-15 17:01:08 +00:00
if ( br . winner == 0 ) //attacker won
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 410 ], 60 , 122 , GEOR13 , zwykly , background );
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 411 ], 410 , 122 , GEOR13 , zwykly , background );
}
else //if(br.winner==1)
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 411 ], 60 , 122 , GEOR13 , zwykly , background );
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 410 ], 410 , 122 , GEOR13 , zwykly , background );
}
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 407 ], 235 , 299 , GEOR16 , tytulowy , background );
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 408 ], 235 , 329 , GEOR16 , zwykly , background );
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 409 ], 235 , 426 , GEOR16 , zwykly , background );
std :: string attackerName , defenderName ;
if ( owner -> attackingHeroInstance ) //a hero attacked
{
SDL_BlitSurface ( graphics -> portraitLarge [ owner -> attackingHeroInstance -> portrait ], NULL , background , & genRect ( 64 , 58 , 21 , 38 ));
//setting attackerName
attackerName = owner -> attackingHeroInstance -> name ;
}
else //a monster attacked
{
int bestMonsterID = - 1 ;
int bestPower = 0 ;
for ( std :: map < si32 , std :: pair < ui32 , si32 > >:: const_iterator it = owner -> army1 -> slots . begin (); it != owner -> army1 -> slots . end (); ++ it )
{
if ( CGI -> creh -> creatures [ it -> first ]. AIValue > bestPower )
{
bestPower = CGI -> creh -> creatures [ it -> first ]. AIValue ;
bestMonsterID = it -> first ;
}
}
SDL_BlitSurface ( graphics -> bigImgs [ bestMonsterID ], NULL , background , & genRect ( 64 , 58 , 21 , 38 ));
//setting attackerName
attackerName = CGI -> creh -> creatures [ bestMonsterID ]. namePl ;
}
if ( owner -> defendingHeroInstance ) //a hero defended
{
SDL_BlitSurface ( graphics -> portraitLarge [ owner -> defendingHeroInstance -> portrait ], NULL , background , & genRect ( 64 , 58 , 391 , 38 ));
//setting defenderName
defenderName = owner -> defendingHeroInstance -> name ;
}
else //a monster defended
{
int bestMonsterID = - 1 ;
int bestPower = 0 ;
for ( std :: map < si32 , std :: pair < ui32 , si32 > >:: const_iterator it = owner -> army2 -> slots . begin (); it != owner -> army2 -> slots . end (); ++ it )
{
if ( CGI -> creh -> creatures [ it -> second . first ]. AIValue > bestPower )
{
bestPower = CGI -> creh -> creatures [ it -> second . first ]. AIValue ;
bestMonsterID = it -> second . first ;
}
}
SDL_BlitSurface ( graphics -> bigImgs [ bestMonsterID ], NULL , background , & genRect ( 64 , 58 , 391 , 38 ));
//setting defenderName
defenderName = CGI -> creh -> creatures [ bestMonsterID ]. namePl ;
}
//printing attacker and defender's names
CSDL_Ext :: printAtMiddle ( attackerName , 156 , 44 , GEOR16 , zwykly , background );
CSDL_Ext :: printAtMiddle ( defenderName , 314 , 44 , GEOR16 , zwykly , background );
//printing casualities
for ( int step = 0 ; step < 2 ; ++ step )
{
if ( br . casualties [ step ]. size () == 0 )
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 523 ], 235 , 360 + 97 * step , GEOR16 , zwykly , background );
}
else
{
int xPos = 235 - ( br . casualties [ step ]. size () * 32 + ( br . casualties [ step ]. size () - 1 ) * 10 ) / 2 ; //increment by 42 with each picture
int yPos = 344 + step * 97 ;
for ( std :: set < std :: pair < ui32 , si32 > >:: const_iterator it = br . casualties [ step ]. begin (); it != br . casualties [ step ]. end (); ++ it )
{
blitAt ( graphics -> smallImgs [ it -> first ], xPos , yPos , background );
std :: stringstream amount ;
amount << it -> second ;
CSDL_Ext :: printAtMiddle ( amount . str (), xPos + 16 , yPos + 42 , GEOR13 , zwykly , background );
xPos += 42 ;
}
}
}
//printing result description
bool weAreAttacker = ( LOCPLINT -> playerID == owner -> attackingHeroInstance -> tempOwner );
switch ( br . result )
{
case 0 : //normal victory
if (( br . winner == 0 && weAreAttacker ) || ( br . winner == 1 && ! weAreAttacker )) //we've won
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 304 ], 235 , 235 , GEOR13 , zwykly , background );
}
else
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 311 ], 235 , 235 , GEOR13 , zwykly , background );
}
break ;
case 1 : //flee
if (( br . winner == 0 && weAreAttacker ) || ( br . winner == 1 && ! weAreAttacker )) //we've won
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 303 ], 235 , 235 , GEOR13 , zwykly , background );
}
else
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 310 ], 235 , 235 , GEOR13 , zwykly , background );
}
break ;
case 2 : //surrender
if (( br . winner == 0 && weAreAttacker ) || ( br . winner == 1 && ! weAreAttacker )) //we've won
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 302 ], 235 , 235 , GEOR13 , zwykly , background );
}
else
{
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 309 ], 235 , 235 , GEOR13 , zwykly , background );
}
break ;
}
}
CBattleReslutWindow ::~ CBattleReslutWindow ()
{
SDL_FreeSurface ( background );
}
void CBattleReslutWindow :: activate ()
{
LOCPLINT -> showingDialog -> set ( true );
exit -> activate ();
}
void CBattleReslutWindow :: deactivate ()
{
exit -> deactivate ();
}
void CBattleReslutWindow :: show ( SDL_Surface * to )
{
//evaluating to
if ( ! to )
to = screen ;
SDL_BlitSurface ( background , NULL , to , & pos );
exit -> show ( to );
}
void CBattleReslutWindow :: bExitf ()
{
2009-04-14 12:47:09 +00:00
LOCPLINT -> popInts ( 2 ); //first - we; second - battle interface
LOCPLINT -> showingDialog -> setn ( false );
2009-01-15 17:01:08 +00:00
}
CBattleOptionsWindow :: CBattleOptionsWindow ( const SDL_Rect & position , CBattleInterface * owner ) : myInt ( owner )
{
pos = position ;
background = BitmapHandler :: loadBitmap ( "comopbck.bmp" , true );
graphics -> blueToPlayersAdv ( background , LOCPLINT -> playerID );
viewGrid = new CHighlightableButton ( boost :: bind ( & CBattleInterface :: setPrintCellBorders , owner , true ), boost :: bind ( & CBattleInterface :: setPrintCellBorders , owner , false ), boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 427 ]. first )( 3 , CGI -> generaltexth -> zelp [ 427 ]. first ), CGI -> generaltexth -> zelp [ 427 ]. second , false , "sysopchk.def" , NULL , 185 , 140 , false );
2009-03-28 18:46:20 +00:00
viewGrid -> select ( owner -> settings . printCellBorders );
2009-01-15 17:01:08 +00:00
movementShadow = new CHighlightableButton ( boost :: bind ( & CBattleInterface :: setPrintStackRange , owner , true ), boost :: bind ( & CBattleInterface :: setPrintStackRange , owner , false ), boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 428 ]. first )( 3 , CGI -> generaltexth -> zelp [ 428 ]. first ), CGI -> generaltexth -> zelp [ 428 ]. second , false , "sysopchk.def" , NULL , 185 , 173 , false );
2009-03-28 18:46:20 +00:00
movementShadow -> select ( owner -> settings . printStackRange );
2009-01-15 17:01:08 +00:00
mouseShadow = new CHighlightableButton ( boost :: bind ( & CBattleInterface :: setPrintMouseShadow , owner , true ), boost :: bind ( & CBattleInterface :: setPrintMouseShadow , owner , false ), boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 429 ]. first )( 3 , CGI -> generaltexth -> zelp [ 429 ]. first ), CGI -> generaltexth -> zelp [ 429 ]. second , false , "sysopchk.def" , NULL , 185 , 207 , false );
2009-03-28 18:46:20 +00:00
mouseShadow -> select ( owner -> settings . printMouseShadow );
2009-01-15 17:01:08 +00:00
animSpeeds = new CHighlightableButtonsGroup ( 0 );
animSpeeds -> addButton ( boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 422 ]. first ), CGI -> generaltexth -> zelp [ 422 ]. second , "sysopb9.def" , 188 , 309 , 1 );
animSpeeds -> addButton ( boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 423 ]. first ), CGI -> generaltexth -> zelp [ 423 ]. second , "sysob10.def" , 252 , 309 , 2 );
animSpeeds -> addButton ( boost :: assign :: map_list_of ( 0 , CGI -> generaltexth -> zelp [ 424 ]. first ), CGI -> generaltexth -> zelp [ 424 ]. second , "sysob11.def" , 315 , 309 , 4 );
animSpeeds -> select ( owner -> getAnimSpeed (), 1 );
animSpeeds -> onChange = boost :: bind ( & CBattleInterface :: setAnimSpeed , owner , _1 );
setToDefault = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 392 ]. first , CGI -> generaltexth -> zelp [ 392 ]. second , boost :: bind ( & CBattleOptionsWindow :: bDefaultf , this ), 405 , 443 , "codefaul.def" );
std :: swap ( setToDefault -> imgs [ 0 ][ 0 ], setToDefault -> imgs [ 0 ][ 1 ]);
exit = new AdventureMapButton ( CGI -> generaltexth -> zelp [ 393 ]. first , CGI -> generaltexth -> zelp [ 393 ]. second , boost :: bind ( & CBattleOptionsWindow :: bExitf , this ), 516 , 443 , "soretrn.def" , SDLK_RETURN );
std :: swap ( exit -> imgs [ 0 ][ 0 ], exit -> imgs [ 0 ][ 1 ]);
//printing texts to background
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 392 ], 240 , 32 , GEOR16 , tytulowy , background ); //window title
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 393 ], 122 , 211 , GEOR16 , tytulowy , background ); //animation speed
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 394 ], 122 , 292 , GEOR16 , tytulowy , background ); //music volume
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 395 ], 122 , 358 , GEOR16 , tytulowy , background ); //effects' volume
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 396 ], 353 , 64 , GEOR16 , tytulowy , background ); //auto - combat options
CSDL_Ext :: printAtMiddle ( CGI -> generaltexth -> allTexts [ 397 ], 353 , 264 , GEOR16 , tytulowy , background ); //creature info
//auto - combat options
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 398 ], 283 , 87 , GEOR16 , zwykly , background ); //creatures
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 399 ], 283 , 117 , GEOR16 , zwykly , background ); //spells
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 400 ], 283 , 147 , GEOR16 , zwykly , background ); //catapult
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 151 ], 283 , 177 , GEOR16 , zwykly , background ); //ballista
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 401 ], 283 , 207 , GEOR16 , zwykly , background ); //first aid tent
//creature info
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 402 ], 283 , 286 , GEOR16 , zwykly , background ); //all stats
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 403 ], 283 , 316 , GEOR16 , zwykly , background ); //spells only
//general options
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 404 ], 61 , 58 , GEOR16 , zwykly , background ); //hex grid
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 405 ], 61 , 91 , GEOR16 , zwykly , background ); //movement shadow
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 406 ], 61 , 124 , GEOR16 , zwykly , background ); //cursor shadow
CSDL_Ext :: printAt ( CGI -> generaltexth -> allTexts [ 577 ], 61 , 157 , GEOR16 , zwykly , background ); //spellbook animation
//texts printed
}
CBattleOptionsWindow ::~ CBattleOptionsWindow ()
{
SDL_FreeSurface ( background );
delete setToDefault ;
delete exit ;
delete viewGrid ;
delete movementShadow ;
delete animSpeeds ;
delete mouseShadow ;
}
void CBattleOptionsWindow :: activate ()
{
setToDefault -> activate ();
exit -> activate ();
viewGrid -> activate ();
movementShadow -> activate ();
animSpeeds -> activate ();
mouseShadow -> activate ();
}
void CBattleOptionsWindow :: deactivate ()
{
setToDefault -> deactivate ();
exit -> deactivate ();
viewGrid -> deactivate ();
movementShadow -> deactivate ();
animSpeeds -> deactivate ();
mouseShadow -> deactivate ();
}
void CBattleOptionsWindow :: show ( SDL_Surface * to )
{
if ( ! to ) //"evaluating" to
to = screen ;
SDL_BlitSurface ( background , NULL , to , & pos );
setToDefault -> show ( to );
exit -> show ( to );
viewGrid -> show ( to );
movementShadow -> show ( to );
animSpeeds -> show ( to );
mouseShadow -> show ( to );
}
void CBattleOptionsWindow :: bDefaultf ()
{
}
void CBattleOptionsWindow :: bExitf ()
{
2009-04-14 12:47:09 +00:00
LOCPLINT -> popIntTotally ( this );
2009-01-15 17:01:08 +00:00
}