2009-01-15 19:01:08 +02:00
# include "CBattleInterface.h"
# include "CGameInfo.h"
2009-05-20 13:08:56 +03:00
# include "../hch/CLodHandler.h"
2009-01-15 19:01:08 +02:00
# include "SDL_Extensions.h"
# include "CAdvmapInterface.h"
# include "AdventureMapButton.h"
2009-05-20 13:08:56 +03:00
# include "../hch/CObjectHandler.h"
# include "../hch/CHeroHandler.h"
# include "../hch/CDefHandler.h"
# include "../hch/CSpellHandler.h"
2009-01-15 19:01:08 +02:00
# include "CMessage.h"
# include "CCursorHandler.h"
2009-05-20 13:08:56 +03:00
# include "../CCallback.h"
# include "../lib/CGameState.h"
# include "../hch/CGeneralTextHandler.h"
# include "CCreatureAnimation.h"
# include "Graphics.h"
# include "CSpellWindow.h"
# include "CConfigHandler.h"
2009-01-15 19:01:08 +02:00
# include <queue>
# include <sstream>
2009-05-20 13:08:56 +03:00
# include "../lib/CondSh.h"
# include "../lib/NetPacks.h"
2009-05-20 12:02:50 +03:00
# include "CPlayerInterface.h"
2009-06-28 19:02:39 +03:00
# include "../hch/CVideoHandler.h"
2009-08-24 15:55:05 +03:00
# include "../hch/CTownHandler.h"
2009-01-15 19:01:08 +02:00
# include <boost/assign/list_of.hpp>
# ifndef __GNUC__
const double M_PI = 3.14159265358979323846 ;
# else
# define _USE_MATH_DEFINES
# include <cmath>
# endif
2009-04-15 17:03:31 +03:00
/*
* CBattleInterface . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
2009-01-15 19:01:08 +02:00
extern SDL_Surface * screen ;
extern TTF_Font * TNRB16 , * TNR , * GEOR13 , * GEORXX , * GEORM , * GEOR16 ;
extern SDL_Color zwykly ;
2009-03-28 20:46:20 +02:00
BattleSettings CBattleInterface : : settings ;
2009-09-16 13:36:50 +03:00
CondSh < bool > CBattleInterface : : animsAreDisplayed ;
2009-03-28 20:46:20 +02:00
2009-01-15 19:01:08 +02:00
struct CMP_stack2
{
inline bool operator ( ) ( const CStack & a , const CStack & b )
{
2009-04-04 22:26:41 +03:00
return ( a . Speed ( ) ) > ( b . Speed ( ) ) ;
2009-01-15 19:01:08 +02:00
}
} cmpst2 ;
2009-08-01 14:55:40 +03:00
static void transformPalette ( SDL_Surface * surf , float rCor , float gCor , float bCor )
{
SDL_Color * colorsToChange = surf - > format - > palette - > colors ;
for ( int g = 0 ; g < surf - > format - > palette - > ncolors ; + + g )
{
if ( ( colorsToChange + g ) - > b ! = 132 & &
( colorsToChange + g ) - > g ! = 231 & &
( colorsToChange + g ) - > r ! = 255 ) //it's not yellow border
{
( colorsToChange + g ) - > r = ( float ) ( ( colorsToChange + g ) - > r ) * rCor ;
( colorsToChange + g ) - > g = ( float ) ( ( colorsToChange + g ) - > g ) * gCor ;
( colorsToChange + g ) - > b = ( float ) ( ( colorsToChange + g ) - > b ) * bCor ;
}
}
}
2009-09-10 14:28:34 +03:00
////////////////////////Battle helpers
//general anim
void CBattleAnimation : : endAnim ( )
{
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : iterator it = owner - > pendingAnims . begin ( ) ; it ! = owner - > pendingAnims . end ( ) ; + + it )
{
if ( it - > first = = this )
{
it - > first = NULL ;
}
}
2009-09-14 15:00:23 +03:00
2009-09-10 14:28:34 +03:00
}
2009-09-11 15:46:26 +03:00
bool CBattleAnimation : : isEarliest ( bool perStackConcurrency )
2009-09-10 14:28:34 +03:00
{
int lowestMoveID = owner - > animIDhelper + 5 ;
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : iterator it = owner - > pendingAnims . begin ( ) ; it ! = owner - > pendingAnims . end ( ) ; + + it )
{
2009-09-11 15:46:26 +03:00
CBattleStackAnimation * stAnim = dynamic_cast < CBattleStackAnimation * > ( it - > first ) ;
CBattleStackAnimation * thAnim = dynamic_cast < CBattleStackAnimation * > ( this ) ;
if ( perStackConcurrency & & stAnim & & thAnim & & stAnim - > stackID ! = thAnim - > stackID )
continue ;
2009-09-14 15:00:23 +03:00
CReverseAnim * revAnim = dynamic_cast < CReverseAnim * > ( stAnim ) ;
if ( revAnim & & stAnim - > stackID = = thAnim - > stackID & & revAnim - > priority )
2009-09-11 15:46:26 +03:00
return false ;
2009-09-10 14:28:34 +03:00
if ( it - > first )
amin ( lowestMoveID , it - > first - > ID ) ;
}
return ID = = lowestMoveID ;
}
CBattleAnimation : : CBattleAnimation ( CBattleInterface * _owner )
: owner ( _owner ) , ID ( _owner - > animIDhelper + + )
{ }
//stack's aniamtion
CBattleStackAnimation : : CBattleStackAnimation ( CBattleInterface * _owner , int stack )
: CBattleAnimation ( _owner ) , stackID ( stack )
{
}
2009-09-16 13:09:08 +03:00
bool CBattleStackAnimation : : isToReverseHlp ( int hexFrom , int hexTo , bool curDir )
{
int fromMod = hexFrom % BFIELD_WIDTH ;
int fromDiv = hexFrom / BFIELD_WIDTH ;
int toMod = hexTo % BFIELD_WIDTH ;
if ( curDir & & fromMod < toMod )
return false ;
else if ( curDir & & fromMod > toMod )
return true ;
else if ( curDir & & fromMod = = toMod )
{
return fromDiv % 2 = = 0 ;
}
else if ( ! curDir & & fromMod < toMod )
return true ;
else if ( ! curDir & & fromMod > toMod )
return false ;
else if ( ! curDir & & fromMod = = toMod )
{
return fromDiv % 2 = = 1 ;
}
tlog1 < < " Catastrope in CBattleStackAnimation::isToReverse! " < < std : : endl ;
return false ; //should never happen
}
bool CBattleStackAnimation : : isToReverse ( int hexFrom , int hexTo , bool curDir , bool toDoubleWide , bool toDir )
{
if ( toDoubleWide )
{
return isToReverseHlp ( hexFrom , hexTo , curDir ) & &
( toDir ? isToReverseHlp ( hexFrom , hexTo - 1 , curDir ) : isToReverseHlp ( hexFrom , hexTo + 1 , curDir ) ) ;
}
else
{
return isToReverseHlp ( hexFrom , hexTo , curDir ) ;
}
}
2009-09-10 14:28:34 +03:00
//revering animation
bool CReverseAnim : : init ( )
{
2009-09-11 15:46:26 +03:00
if ( owner - > creAnims [ stackID ] = = NULL | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
2009-09-10 14:28:34 +03:00
{
endAnim ( ) ;
return false ; //there is no such creature
}
2009-09-14 15:00:23 +03:00
if ( ! priority & & ! isEarliest ( false ) )
return false ;
2009-09-10 14:28:34 +03:00
owner - > creAnims [ stackID ] - > setType ( 8 ) ;
return true ;
}
void CReverseAnim : : nextFrame ( )
{
if ( partOfAnim = = 1 ) //first part of animation
{
if ( owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
{
partOfAnim = 2 ;
}
}
else if ( partOfAnim = = 2 )
{
if ( ! secondPartSetup )
{
owner - > creDir [ stackID ] = ! owner - > creDir [ stackID ] ;
2009-09-11 15:46:26 +03:00
const CStack * curs = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
2009-09-10 14:28:34 +03:00
std : : pair < int , int > coords = CBattleHex : : getXYUnitAnim ( hex , owner - > creDir [ stackID ] , curs , owner ) ;
owner - > creAnims [ stackID ] - > pos . x = coords . first ;
//creAnims[stackID]->pos.y = coords.second;
if ( curs - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) )
{
if ( curs - > attackerOwned )
{
if ( ! owner - > creDir [ stackID ] )
owner - > creAnims [ stackID ] - > pos . x - = 44 ;
}
else
{
if ( owner - > creDir [ stackID ] )
owner - > creAnims [ stackID ] - > pos . x + = 44 ;
}
}
owner - > creAnims [ stackID ] - > setType ( 7 ) ;
secondPartSetup = true ;
}
if ( owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
{
endAnim ( ) ;
}
}
}
void CReverseAnim : : endAnim ( )
{
CBattleAnimation : : endAnim ( ) ;
if ( LOCPLINT - > cb - > battleGetStackByID ( stackID ) ) //don't do that if stack is dead
owner - > creAnims [ stackID ] - > setType ( 2 ) ;
delete this ;
}
2009-09-14 15:00:23 +03:00
CReverseAnim : : CReverseAnim ( CBattleInterface * _owner , int stack , int dest , bool _priority )
: CBattleStackAnimation ( _owner , stack ) , partOfAnim ( 1 ) , hex ( dest ) , secondPartSetup ( false ) , priority ( _priority )
2009-09-10 14:28:34 +03:00
{
}
//defence anim
bool CDefenceAnim : : init ( )
{
//checking initial conditions
//if(owner->creAnims[stackID]->getType() != 2)
//{
// return false;
//}
int lowestMoveID = owner - > animIDhelper + 5 ;
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : iterator it = owner - > pendingAnims . begin ( ) ; it ! = owner - > pendingAnims . end ( ) ; + + it )
{
if ( dynamic_cast < CDefenceAnim * > ( it - > first ) )
continue ;
2009-09-16 13:09:08 +03:00
CBattleAttack * attAnim = dynamic_cast < CBattleAttack * > ( it - > first ) ;
if ( attAnim & & attAnim - > stackID ! = stackID )
2009-09-14 15:00:23 +03:00
continue ;
2009-09-10 14:28:34 +03:00
2009-09-15 15:20:11 +03:00
const CStack * attacker = LOCPLINT - > cb - > battleGetStackByID ( IDby , false ) ;
int attackerAnimType = owner - > creAnims [ IDby ] - > getType ( ) ;
if ( attackerAnimType = = 11 & & attackerAnimType = = 12 & & attackerAnimType = = 13 & & owner - > creAnims [ IDby ] - > getFrame ( ) < attacker - > creature - > attackClimaxFrame )
return false ;
CReverseAnim * animAsRev = dynamic_cast < CReverseAnim * > ( it - > first ) ;
if ( animAsRev & & animAsRev - > priority )
2009-09-11 15:46:26 +03:00
return false ;
2009-09-10 14:28:34 +03:00
if ( it - > first )
amin ( lowestMoveID , it - > first - > ID ) ;
}
if ( ID > lowestMoveID )
return false ;
2009-09-11 15:46:26 +03:00
const CStack * attacker = LOCPLINT - > cb - > battleGetStackByID ( IDby , false ) ;
const CStack * attacked = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
2009-09-10 14:28:34 +03:00
2009-09-11 15:46:26 +03:00
//reverse unit if necessary
2009-09-16 13:09:08 +03:00
if ( isToReverse ( attacked - > position , attacker - > position , owner - > creDir [ stackID ] , attacker - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) , owner - > creDir [ IDby ] ) )
2009-09-11 15:46:26 +03:00
{
2009-09-16 13:36:50 +03:00
owner - > addNewAnim ( new CReverseAnim ( owner , stackID , attacked - > position , true ) ) ;
2009-09-11 15:46:26 +03:00
return false ;
}
//unit reversed
if ( byShooting ) //delay hit animation
{
2009-09-10 14:28:34 +03:00
for ( std : : list < SProjectileInfo > : : const_iterator it = owner - > projectiles . begin ( ) ; it ! = owner - > projectiles . end ( ) ; + + it )
{
if ( it - > creID = = attacker - > creature - > idNumber )
{
return false ;
}
}
}
//initializing
int maxLen = 0 ;
if ( killed )
{
CGI - > soundh - > playSound ( attacked - > creature - > sounds . killed ) ;
owner - > creAnims [ stackID ] - > setType ( 5 ) ; //death
}
else
{
// TODO: this block doesn't seems correct if the unit is defending.
CGI - > soundh - > playSound ( attacked - > creature - > sounds . wince ) ;
owner - > creAnims [ stackID ] - > setType ( 3 ) ; //getting hit
}
return true ; //initialized successfuly
}
void CDefenceAnim : : nextFrame ( )
{
2009-09-16 13:09:08 +03:00
if ( ! killed & & owner - > creAnims [ stackID ] - > getType ( ) ! = 3 )
{
owner - > creAnims [ stackID ] - > setType ( 3 ) ;
}
2009-09-15 15:20:11 +03:00
if ( ! owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
2009-09-10 14:28:34 +03:00
{
2009-09-11 15:46:26 +03:00
if ( owner - > creAnims [ stackID ] - > getType ( ) = = 5 & & ( owner - > animCount + 1 ) % ( 4 / CBattleInterface : : settings . animSpeed ) = = 0
& & ! owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
2009-09-10 14:28:34 +03:00
{
owner - > creAnims [ stackID ] - > incrementFrame ( ) ;
}
}
else
{
endAnim ( ) ;
}
}
void CDefenceAnim : : endAnim ( )
{
//restoring animType
if ( owner - > creAnims [ stackID ] - > getType ( ) = = 3 )
owner - > creAnims [ stackID ] - > setType ( 2 ) ;
//printing info to console
if ( IDby ! = - 1 )
owner - > printConsoleAttacked ( stackID , dmg , amountKilled , IDby ) ;
2009-09-11 15:46:26 +03:00
const CStack * attacker = LOCPLINT - > cb - > battleGetStackByID ( IDby , false ) ;
const CStack * attacked = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
2009-09-10 14:28:34 +03:00
CBattleAnimation : : endAnim ( ) ;
delete this ;
}
CDefenceAnim : : CDefenceAnim ( SStackAttackedInfo _attackedInfo , CBattleInterface * _owner )
2009-09-15 15:20:11 +03:00
: CBattleStackAnimation ( _owner , _attackedInfo . ID ) , dmg ( _attackedInfo . dmg ) ,
2009-09-10 14:28:34 +03:00
amountKilled ( _attackedInfo . amountKilled ) , IDby ( _attackedInfo . IDby ) , byShooting ( _attackedInfo . byShooting ) ,
killed ( _attackedInfo . killed )
{
}
////move anim
bool CBattleStackMoved : : init ( )
{
2009-09-11 15:46:26 +03:00
if ( ! isEarliest ( false ) )
2009-09-10 14:28:34 +03:00
return false ;
//a few useful variables
steps = owner - > creAnims [ stackID ] - > framesInGroup ( 0 ) * owner - > getAnimSpeedMultiplier ( ) - 1 ;
whichStep = 0 ;
int hexWbase = 44 , hexHbase = 42 ;
2009-09-11 15:46:26 +03:00
const CStack * movedStack = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
if ( ! movedStack | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
2009-09-10 14:28:34 +03:00
{
endAnim ( ) ;
return false ;
}
bool twoTiles = movedStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) ;
std : : pair < int , int > begPosition = CBattleHex : : getXYUnitAnim ( curStackPos , movedStack - > attackerOwned , movedStack , owner ) ;
std : : pair < int , int > endPosition = CBattleHex : : getXYUnitAnim ( destHex , movedStack - > attackerOwned , movedStack , owner ) ;
int mutPos = BattleInfo : : mutualPosition ( curStackPos , destHex ) ;
//reverse unit if necessary
if ( ( begPosition . first > endPosition . first ) & & owner - > creDir [ stackID ] = = true )
{
2009-09-16 13:36:50 +03:00
owner - > addNewAnim ( new CReverseAnim ( owner , stackID , curStackPos , true ) ) ;
2009-09-10 14:28:34 +03:00
return false ;
}
else if ( ( begPosition . first < endPosition . first ) & & owner - > creDir [ stackID ] = = false )
{
2009-09-16 13:36:50 +03:00
owner - > addNewAnim ( new CReverseAnim ( owner , stackID , curStackPos , true ) ) ;
2009-09-10 14:28:34 +03:00
return false ;
}
2009-09-11 15:46:26 +03:00
2009-09-10 14:28:34 +03:00
if ( owner - > creAnims [ stackID ] - > getType ( ) ! = 0 )
{
owner - > creAnims [ stackID ] - > setType ( 0 ) ;
}
//unit reversed
2009-09-11 15:46:26 +03:00
owner - > moveSh = CGI - > soundh - > playSound ( movedStack - > creature - > sounds . move , - 1 ) ;
2009-09-10 14:28:34 +03:00
//step shift calculation
posX = owner - > creAnims [ stackID ] - > pos . x , posY = owner - > creAnims [ stackID ] - > pos . y ; // for precise calculations ;]
if ( mutPos = = - 1 & & movedStack - > hasFeatureOfType ( StackFeature : : FLYING ) )
{
steps * = distance ;
stepX = ( endPosition . first - ( float ) begPosition . first ) / steps ;
stepY = ( endPosition . second - ( float ) begPosition . second ) / steps ;
}
else
{
switch ( mutPos )
{
case 0 :
stepX = ( - 1.0 ) * ( ( float ) hexWbase ) / ( 2.0f * steps ) ;
stepY = ( - 1.0 ) * ( ( float ) hexHbase ) / ( ( float ) steps ) ;
break ;
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 ;
break ;
}
}
//step shifts calculated
return true ;
}
void CBattleStackMoved : : nextFrame ( )
{
//moving instructions
posX + = stepX ;
owner - > creAnims [ stackID ] - > pos . x = posX ;
posY + = stepY ;
owner - > creAnims [ stackID ] - > pos . y = posY ;
+ + whichStep ;
if ( whichStep = = steps )
{
endAnim ( ) ;
}
}
void CBattleStackMoved : : endAnim ( )
{
const CStack * movedStack = LOCPLINT - > cb - > battleGetStackByID ( stackID ) ;
CBattleAnimation : : endAnim ( ) ;
if ( movedStack )
{
bool twoTiles = movedStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) ;
if ( endMoving )
{
2009-09-16 13:36:50 +03:00
owner - > addNewAnim ( new CBattleMoveEnd ( owner , stackID , destHex ) ) ;
2009-09-10 14:28:34 +03:00
}
std : : pair < int , int > coords = CBattleHex : : getXYUnitAnim ( destHex , owner - > creDir [ stackID ] , movedStack , owner ) ;
owner - > creAnims [ stackID ] - > pos . x = coords . first ;
if ( ! endMoving & & twoTiles & & bool ( movedStack - > attackerOwned ) & & ( owner - > creDir [ stackID ] ! = bool ( movedStack - > attackerOwned ) ) ) //big attacker creature is reversed
owner - > creAnims [ stackID ] - > pos . x - = 44 ;
else if ( ! endMoving & & twoTiles & & ( ! bool ( movedStack - > attackerOwned ) ) & & ( owner - > creDir [ stackID ] ! = bool ( movedStack - > attackerOwned ) ) ) //big defender creature is reversed
owner - > creAnims [ stackID ] - > pos . x + = 44 ;
owner - > creAnims [ stackID ] - > pos . y = coords . second ;
}
delete this ;
}
CBattleStackMoved : : CBattleStackMoved ( CBattleInterface * _owner , int _number , int _destHex , bool _endMoving , int _distance )
: CBattleStackAnimation ( _owner , _number ) , destHex ( _destHex ) , endMoving ( _endMoving ) , distance ( _distance ) , stepX ( 0.0f ) , stepY ( 0.0f )
{
curStackPos = LOCPLINT - > cb - > battleGetPos ( stackID ) ;
}
//move started
bool CBattleMoveStart : : init ( )
{
2009-09-11 15:46:26 +03:00
if ( ! isEarliest ( false ) )
2009-09-10 14:28:34 +03:00
return false ;
2009-09-11 15:46:26 +03:00
const CStack * movedStack = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
2009-09-10 14:28:34 +03:00
2009-09-11 15:46:26 +03:00
if ( ! movedStack | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
2009-09-10 14:28:34 +03:00
{
CBattleMoveStart : : endAnim ( ) ;
return false ;
}
if ( movedStack - > creature - > sounds . startMoving )
CGI - > soundh - > playSound ( movedStack - > creature - > sounds . startMoving ) ;
return true ;
}
void CBattleMoveStart : : nextFrame ( )
{
if ( owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
{
endAnim ( ) ;
}
else
{
if ( ( owner - > animCount + 1 ) % ( 4 / CBattleInterface : : settings . animSpeed ) = = 0 )
owner - > creAnims [ stackID ] - > incrementFrame ( ) ;
}
}
void CBattleMoveStart : : endAnim ( )
{
CBattleAnimation : : endAnim ( ) ;
delete this ;
}
CBattleMoveStart : : CBattleMoveStart ( CBattleInterface * _owner , int stack )
: CBattleStackAnimation ( _owner , stack )
{
}
//move finished
bool CBattleMoveEnd : : init ( )
{
2009-09-11 15:46:26 +03:00
if ( ! isEarliest ( true ) )
2009-09-10 14:28:34 +03:00
return false ;
2009-09-11 15:46:26 +03:00
const CStack * movedStack = LOCPLINT - > cb - > battleGetStackByID ( stackID , false ) ;
if ( ! movedStack | | owner - > creAnims [ stackID ] - > framesInGroup ( 21 ) = = 0 | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
2009-09-10 14:28:34 +03:00
{
endAnim ( ) ;
return false ;
}
if ( movedStack - > creature - > sounds . endMoving )
{
CGI - > soundh - > playSound ( movedStack - > creature - > sounds . endMoving ) ;
}
owner - > creAnims [ stackID ] - > setType ( 21 ) ;
return true ;
}
void CBattleMoveEnd : : nextFrame ( )
{
if ( owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
{
endAnim ( ) ;
}
}
void CBattleMoveEnd : : endAnim ( )
{
CBattleAnimation : : endAnim ( ) ;
2009-09-15 15:20:11 +03:00
if ( owner - > creAnims [ stackID ] - > getType ( ) ! = 5 )
2009-09-10 14:28:34 +03:00
owner - > creAnims [ stackID ] - > setType ( 2 ) ; //resetting to default
CGI - > curh - > show ( ) ;
CGI - > soundh - > stopSound ( owner - > moveSh ) ;
delete this ;
}
CBattleMoveEnd : : CBattleMoveEnd ( CBattleInterface * _owner , int stack , int destTile )
: CBattleStackAnimation ( _owner , stack ) , destinationTile ( destTile )
{
}
//general attack anim
void CBattleAttack : : nextFrame ( )
{
if ( owner - > creAnims [ stackID ] - > getType ( ) ! = group )
owner - > creAnims [ stackID ] - > setType ( group ) ;
2009-09-11 15:46:26 +03:00
if ( owner - > creAnims [ stackID ] - > getFrame ( ) = = 0 )
2009-09-10 14:28:34 +03:00
{
if ( shooting )
{
// TODO: I see that we enter this function twice with
// attackingInfo->frame==0, so all the inits are done
// twice. The following is just a workaround until
// that is fixed. Once done, we can get rid of
// sh
if ( sh = = - 1 )
2009-09-16 13:59:56 +03:00
sh = CGI - > soundh - > playSound ( attackingStack - > creature - > sounds . shoot ) ;
2009-09-10 14:28:34 +03:00
owner - > creAnims [ stackID ] - > setType ( group ) ;
}
else
{
// TODO: see comment above
if ( sh = = - 1 )
2009-09-16 13:59:56 +03:00
sh = CGI - > soundh - > playSound ( attackingStack - > creature - > sounds . attack ) ;
2009-09-10 14:28:34 +03:00
static std : : map < int , int > dirToType = boost : : assign : : map_list_of ( 0 , 11 ) ( 1 , 11 ) ( 2 , 12 ) ( 3 , 13 ) ( 4 , 13 ) ( 5 , 12 ) ;
int type ; //dependent on attack direction
2009-09-16 13:59:56 +03:00
if ( attackingStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
type = dirToType [ BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn + posShiftDueToDist , dest ) ] ; //attack direction
2009-09-10 14:28:34 +03:00
}
else //else for if(aStack->hasFeatureOfType(StackFeature::DOUBLE_WIDE))
{
2009-09-16 13:59:56 +03:00
type = BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn , dest ) ;
2009-09-10 14:28:34 +03:00
}
owner - > creAnims [ stackID ] - > setType ( type ) ;
}
}
2009-09-11 15:46:26 +03:00
else if ( owner - > creAnims [ stackID ] - > onLastFrameInGroup ( ) )
2009-09-10 14:28:34 +03:00
{
owner - > creAnims [ stackID ] - > setType ( 2 ) ;
endAnim ( ) ;
return ; //execution of endAnim deletes this !!!
}
}
bool CBattleAttack : : checkInitialConditions ( )
{
2009-09-11 15:46:26 +03:00
return isEarliest ( false ) ;
2009-09-10 14:28:34 +03:00
}
2009-09-16 13:09:08 +03:00
CBattleAttack : : CBattleAttack ( CBattleInterface * _owner , int _stackID , int _dest )
: CBattleStackAnimation ( _owner , _stackID ) , sh ( - 1 ) , dest ( _dest )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:09:08 +03:00
attackedStack = LOCPLINT - > cb - > battleGetStackByPos ( _dest , false ) ;
2009-09-16 13:59:56 +03:00
attackingStack = LOCPLINT - > cb - > battleGetStackByID ( _stackID , false ) ;
attackingStackPosBeforeReturn = attackingStack - > position ;
2009-09-10 14:28:34 +03:00
}
////melee attack
bool CMeleeAttack : : init ( )
{
if ( ! CBattleAttack : : checkInitialConditions ( ) )
return false ;
//if(owner->creAnims[stackID]->getType()!=2)
//{
// return false;
//}
2009-09-16 13:59:56 +03:00
if ( ! attackingStack | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
2009-09-10 14:28:34 +03:00
{
endAnim ( ) ;
return false ;
}
int reversedShift = 0 ; //shift of attacking stack's position due to reversing
2009-09-16 13:59:56 +03:00
if ( attackingStack - > attackerOwned )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
if ( attackingStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) & & BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn , dest ) = = - 1 )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
if ( BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn + ( attackingStack - > attackerOwned ? - 1 : 1 ) , dest ) > = 0 ) //if reversing stack will make its position adjacent to dest
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
reversedShift = ( attackingStack - > attackerOwned ? - 1 : 1 ) ;
2009-09-10 14:28:34 +03:00
}
}
}
else //if(astack->attackerOwned)
{
2009-09-16 13:59:56 +03:00
if ( attackingStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) & & BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn , dest ) = = - 1 )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
if ( BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn + ( attackingStack - > attackerOwned ? - 1 : 1 ) , dest ) > = 0 ) //if reversing stack will make its position adjacent to dest
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
reversedShift = ( attackingStack - > attackerOwned ? - 1 : 1 ) ;
2009-09-10 14:28:34 +03:00
}
}
}
2009-09-16 13:09:08 +03:00
//reversing stack if necessary
2009-09-16 13:59:56 +03:00
if ( isToReverse ( attackingStackPosBeforeReturn , dest , owner - > creDir [ stackID ] , attackedStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) , owner - > creDir [ attackedStack - > ID ] ) )
2009-09-10 14:28:34 +03:00
{
2009-09-16 13:59:56 +03:00
owner - > addNewAnim ( new CReverseAnim ( owner , stackID , attackingStackPosBeforeReturn , true ) ) ;
2009-09-16 13:09:08 +03:00
return false ;
2009-09-10 14:28:34 +03:00
}
//reversed
2009-09-16 13:36:50 +03:00
IDby = attackedStack - > ID ;
2009-09-10 14:28:34 +03:00
shooting = false ;
posShiftDueToDist = reversedShift ;
static const int mutPosToGroup [ ] = { 11 , 11 , 12 , 13 , 13 , 12 } ;
2009-09-16 13:59:56 +03:00
int mutPos = BattleInfo : : mutualPosition ( attackingStackPosBeforeReturn + reversedShift , dest ) ;
2009-09-10 14:28:34 +03:00
switch ( mutPos ) //attack direction
{
case 0 : case 1 : case 2 : case 3 : case 4 : case 5 :
group = mutPosToGroup [ mutPos ] ;
break ;
default :
2009-09-16 13:59:56 +03:00
tlog1 < < " Critical Error! Wrong dest in stackAttacking! dest: " < < dest < < " attacking stack pos: " < < attackingStackPosBeforeReturn < < " reversed shift: " < < reversedShift < < std : : endl ;
2009-09-10 14:28:34 +03:00
}
return true ;
}
void CMeleeAttack : : nextFrame ( )
{
/*for(std::list<std::pair<CBattleAnimation *, bool> >::const_iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
{
CBattleMoveStart * anim = dynamic_cast < CBattleMoveStart * > ( it - > first ) ;
CReverseAnim * anim2 = dynamic_cast < CReverseAnim * > ( it - > first ) ;
if ( ( anim & & anim - > stackID = = stackID ) | | ( anim2 & & anim2 - > stackID = = stackID ) )
return ;
} */
CBattleAttack : : nextFrame ( ) ;
}
void CMeleeAttack : : endAnim ( )
{
CBattleAnimation : : endAnim ( ) ;
delete this ;
}
CMeleeAttack : : CMeleeAttack ( CBattleInterface * _owner , int attacker , int _dest )
2009-09-16 13:09:08 +03:00
: CBattleAttack ( _owner , attacker , _dest )
2009-09-10 14:28:34 +03:00
{
}
//shooting anim
bool CShootingAnim : : init ( )
{
if ( ! CBattleAttack : : checkInitialConditions ( ) )
return false ;
2009-09-16 13:59:56 +03:00
const CStack * shooter = attackingStack ;
2009-09-11 15:46:26 +03:00
if ( ! shooter | | owner - > creAnims [ stackID ] - > getType ( ) = = 5 )
{
endAnim ( ) ;
return false ;
}
2009-09-10 14:28:34 +03:00
//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)
2009-09-16 13:09:08 +03:00
int fromHex = shooter - > position ;
2009-09-10 14:28:34 +03:00
projectileAngle = atan2 ( float ( abs ( dest - fromHex ) / BFIELD_WIDTH ) , float ( abs ( dest - fromHex ) % BFIELD_WIDTH ) ) ;
if ( fromHex < dest )
projectileAngle = - projectileAngle ;
SProjectileInfo spi ;
2009-09-11 15:46:26 +03:00
spi . creID = shooter - > creature - > idNumber ;
spi . reverse = ! shooter - > attackerOwned ;
2009-09-10 14:28:34 +03:00
spi . step = 0 ;
spi . frameNum = 0 ;
spi . spin = CGI - > creh - > idToProjectileSpin [ spi . creID ] ;
std : : pair < int , int > xycoord = CBattleHex : : getXYUnitAnim ( shooter - > position , true , shooter , owner ) ;
2009-09-16 13:09:08 +03:00
std : : pair < int , int > destcoord = CBattleHex : : getXYUnitAnim ( dest , false , attackedStack , owner ) ;
2009-09-10 14:28:34 +03:00
destcoord . first + = 250 ; destcoord . second + = 210 ; //TODO: find a better place to shoot
if ( projectileAngle > straightAngle ) //upper shot
{
spi . x = xycoord . first + 200 + shooter - > creature - > upperRightMissleOffsetX ;
spi . y = xycoord . second + 100 - shooter - > creature - > upperRightMissleOffsetY ;
}
else if ( projectileAngle < - straightAngle ) //lower shot
{
spi . x = xycoord . first + 200 + shooter - > creature - > lowerRightMissleOffsetX ;
spi . y = xycoord . second + 150 - shooter - > creature - > lowerRightMissleOffsetY ;
}
else //straight shot
{
spi . x = xycoord . first + 200 + shooter - > creature - > rightMissleOffsetX ;
spi . y = xycoord . second + 125 - shooter - > creature - > 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 * ( owner - > idToProjectile [ spi . creID ] - > ourImages . size ( ) - 1 ) ) ) ) * ( owner - > idToProjectile [ spi . creID ] - > ourImages . size ( ) - 1 ) ;
}
//set delay
spi . animStartDelay = CGI - > creh - > creatures [ spi . creID ] . attackClimaxFrame ;
owner - > projectiles . push_back ( spi ) ;
//attack aniamtion
2009-09-16 13:09:08 +03:00
IDby = attackedStack - > ID ;
2009-09-10 14:28:34 +03:00
posShiftDueToDist = 0 ;
shooting = true ;
if ( projectileAngle > straightAngle ) //upper shot
group = 14 ;
else if ( projectileAngle < - straightAngle ) //lower shot
group = 16 ;
else //straight shot
group = 15 ;
return true ;
}
void CShootingAnim : : nextFrame ( )
{
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : const_iterator it = owner - > pendingAnims . begin ( ) ; it ! = owner - > pendingAnims . end ( ) ; + + it )
{
CBattleMoveStart * anim = dynamic_cast < CBattleMoveStart * > ( it - > first ) ;
CReverseAnim * anim2 = dynamic_cast < CReverseAnim * > ( it - > first ) ;
2009-09-14 15:00:23 +03:00
if ( ( anim & & anim - > stackID = = stackID ) | | ( anim2 & & anim2 - > stackID = = stackID & & anim2 - > priority ) )
2009-09-10 14:28:34 +03:00
return ;
}
CBattleAttack : : nextFrame ( ) ;
}
void CShootingAnim : : endAnim ( )
{
CBattleAnimation : : endAnim ( ) ;
delete this ;
}
CShootingAnim : : CShootingAnim ( CBattleInterface * _owner , int attacker , int _dest )
2009-09-16 13:09:08 +03:00
: CBattleAttack ( _owner , attacker , _dest )
2009-09-10 14:28:34 +03:00
{
}
////////////////////////
2009-08-01 14:55:40 +03:00
2009-09-16 13:36:50 +03:00
void CBattleInterface : : addNewAnim ( CBattleAnimation * anim )
{
pendingAnims . push_back ( std : : make_pair ( anim , false ) ) ;
animsAreDisplayed . setn ( true ) ;
}
2009-01-15 19:01:08 +02:00
CBattleInterface : : CBattleInterface ( CCreatureSet * army1 , CCreatureSet * army2 , CGHeroInstance * hero1 , CGHeroInstance * hero2 , const SDL_Rect & myRect )
2009-09-15 15:20:11 +03:00
: attackingHeroInstance ( hero1 ) , defendingHeroInstance ( hero2 ) , animCount ( 0 ) , activeStack ( - 1 ) , stackToActivate ( - 1 ) ,
2009-08-20 07:34:38 +03:00
mouseHoveredStack ( - 1 ) , previouslyHoveredHex ( - 1 ) , currentlyHoveredHex ( - 1 ) , spellDestSelectMode ( false ) ,
2009-09-10 14:28:34 +03:00
spellToCast ( NULL ) , givenCommand ( NULL ) , myTurn ( false ) , resWindow ( NULL ) , animIDhelper ( 0 ) ,
2009-09-15 15:20:11 +03:00
showStackQueue ( false ) , moveStarted ( false ) , moveSh ( - 1 ) , siegeH ( NULL ) , bresult ( NULL )
2009-01-15 19:01:08 +02:00
{
2009-09-16 13:36:50 +03:00
animsAreDisplayed . setn ( false ) ;
2009-01-15 19:01:08 +02:00
pos = myRect ;
strongInterest = true ;
givenCommand = new CondSh < BattleAction * > ( NULL ) ;
2009-09-04 17:11:42 +03:00
//preparing siege info
const CGTownInstance * town = LOCPLINT - > cb - > battleGetDefendedTown ( ) ;
if ( town )
{
siegeH = new SiegeHelper ( town , this ) ;
}
2009-01-15 19:01:08 +02:00
//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 )
{
2009-08-07 12:45:21 +03:00
newStack ( b - > second . ID ) ;
2009-01-15 19:01:08 +02:00
}
2009-08-24 15:55:05 +03:00
2009-01-15 19:01:08 +02:00
//preparing menu background and terrain
2009-08-24 15:55:05 +03:00
if ( siegeH )
{
2009-08-26 17:09:55 +03:00
background = BitmapHandler : : loadBitmap ( siegeH - > getSiegeName ( 0 ) ) ;
2009-09-02 17:10:19 +03:00
ui8 siegeLevel = LOCPLINT - > cb - > battleGetSiegeLevel ( ) ;
if ( siegeLevel > = 2 ) //citadel or castle
{
//print moat/mlip
SDL_Surface * moat = BitmapHandler : : loadBitmap ( siegeH - > getSiegeName ( 13 ) ) ,
* mlip = BitmapHandler : : loadBitmap ( siegeH - > getSiegeName ( 14 ) ) ;
2009-09-07 15:30:10 +03:00
std : : pair < int , int > moatPos = CGI - > heroh - > wallPositions [ siegeH - > town - > town - > typeID ] [ 10 ] ,
mlipPos = CGI - > heroh - > wallPositions [ siegeH - > town - > town - > typeID ] [ 11 ] ;
2009-09-05 17:10:26 +03:00
if ( moat ) //eg. tower has no moat
2009-09-07 15:30:10 +03:00
blitAt ( moat , moatPos . first , moatPos . second , background ) ;
2009-09-05 17:10:26 +03:00
if ( mlip ) //eg. tower has no mlip
2009-09-07 15:30:10 +03:00
blitAt ( mlip , mlipPos . first , mlipPos . second , background ) ;
2009-09-02 17:10:19 +03:00
SDL_FreeSurface ( moat ) ;
SDL_FreeSurface ( mlip ) ;
}
2009-08-24 15:55:05 +03:00
}
else
{
std : : vector < std : : string > & backref = graphics - > battleBacks [ LOCPLINT - > cb - > battleGetBattlefieldType ( ) ] ;
background = BitmapHandler : : loadBitmap ( backref [ rand ( ) % backref . size ( ) ] ) ;
}
2009-09-07 05:29:44 +03:00
//preparing menu background
2009-01-15 19:01:08 +02:00
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 ) ;
2009-08-01 14:55:40 +03:00
transformPalette ( amountNormal , 0.59f , 0.19f , 0.93f ) ;
2009-01-15 19:01:08 +02:00
amountPositive = BitmapHandler : : loadBitmap ( " CMNUMWIN.BMP " ) ;
CSDL_Ext : : alphaTransform ( amountPositive ) ;
2009-08-01 14:55:40 +03:00
transformPalette ( amountPositive , 0.18f , 1.00f , 0.18f ) ;
2009-01-15 19:01:08 +02:00
amountNegative = BitmapHandler : : loadBitmap ( " CMNUMWIN.BMP " ) ;
CSDL_Ext : : alphaTransform ( amountNegative ) ;
2009-08-01 14:55:40 +03:00
transformPalette ( amountNegative , 1.00f , 0.18f , 0.18f ) ;
2009-01-15 19:01:08 +02:00
amountEffNeutral = BitmapHandler : : loadBitmap ( " CMNUMWIN.BMP " ) ;
2009-08-01 14:55:40 +03:00
CSDL_Ext : : alphaTransform ( amountEffNeutral ) ;
transformPalette ( amountEffNeutral , 1.00f , 1.00f , 0.18f ) ;
2009-01-15 19:01:08 +02:00
////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 20:07:31 +02: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 19:01:08 +02: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
{
2009-09-04 17:11:42 +03:00
if ( it - > second . position > = 0 ) //turrets have position < 0
bfield [ it - > second . position ] . accesible = false ;
2009-01-15 19:01:08 +02:00
}
//loading projectiles for units
for ( std : : map < int , CStack > : : iterator g = stacks . begin ( ) ; g ! = stacks . end ( ) ; + + g )
{
2009-09-05 17:10:26 +03:00
int creID = ( g - > second . creature - > idNumber = = 149 ) ? CGI - > creh - > factionToTurretCreature [ siegeH - > town - > town - > typeID ] : g - > second . creature - > idNumber ; //id of creature whose shots should be loaded
if ( g - > second . creature - > isShooting ( ) & & CGI - > creh - > idToProjectile [ creID ] ! = std : : string ( ) )
{
idToProjectile [ g - > second . creature - > idNumber ] = CDefHandler : : giveDef ( CGI - > creh - > idToProjectile [ creID ] ) ;
2009-01-15 19:01:08 +02:00
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 16:50:32 +02: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-01-15 19:01:08 +02: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 16:50:32 +02:00
for ( std : : map < int , CDefHandler * > : : iterator g = idToObstacle . begin ( ) ; g ! = idToObstacle . end ( ) ; + + g )
delete g - > second ;
2009-04-14 15:47:09 +03:00
2009-08-24 15:55:05 +03:00
delete siegeH ;
2009-04-14 15:47:09 +03:00
LOCPLINT - > battleInt = NULL ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : setPrintCellBorders ( bool set )
{
2009-03-28 20:46:20 +02:00
settings . printCellBorders = set ;
2009-01-15 19:01:08 +02:00
redrawBackgroundWithHexes ( activeStack ) ;
2009-08-07 01:36:51 +03:00
GH . totalRedraw ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : setPrintStackRange ( bool set )
{
2009-03-28 20:46:20 +02:00
settings . printStackRange = set ;
2009-01-15 19:01:08 +02:00
redrawBackgroundWithHexes ( activeStack ) ;
2009-08-07 01:36:51 +03:00
GH . totalRedraw ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : setPrintMouseShadow ( bool set )
{
2009-03-28 20:46:20 +02:00
settings . printMouseShadow = set ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : activate ( )
{
2009-08-11 19:05:33 +03:00
activateKeys ( ) ;
activateMouseMove ( ) ;
activateRClick ( ) ;
2009-01-15 19:01:08 +02:00
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 18:55:26 +03:00
LOCPLINT - > cingconsole - > activate ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : deactivate ( )
{
2009-08-11 19:05:33 +03:00
deactivateKeys ( ) ;
deactivateMouseMove ( ) ;
deactivateRClick ( ) ;
2009-01-15 19:01:08 +02:00
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 18:55:26 +03:00
LOCPLINT - > cingconsole - > deactivate ( ) ;
2009-01-15 19:01:08 +02: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 20:46:20 +02:00
if ( settings . printCellBorders )
2009-01-15 19:01:08 +02:00
{
CSDL_Ext : : blit8bppAlphaTo24bpp ( cellBorders , NULL , to , & pos ) ;
}
}
//printing hovered cell
2009-02-07 18:07:29 +02:00
for ( int b = 0 ; b < BFIELD_SIZE ; + + b )
2009-01-15 19:01:08 +02:00
{
2009-02-07 18:07:29 +02:00
if ( bfield [ b ] . strictHovered & & bfield [ b ] . hovered )
2009-01-15 19:01:08 +02:00
{
2009-02-07 18:07:29 +02: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-04-15 17:03:31 +03:00
if ( spellToCast ) //when casting spell
{
//calculating spell schoold level
const CSpell & spToCast = CGI - > spellh - > spells [ spellToCast - > additionalInfo ] ;
ui8 schoolLevel = 0 ;
if ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
{
if ( attackingHeroInstance )
schoolLevel = attackingHeroInstance - > getSpellSchoolLevel ( & spToCast ) ;
}
else
{
if ( defendingHeroInstance )
schoolLevel = defendingHeroInstance - > getSpellSchoolLevel ( & spToCast ) ;
}
//obtaining range and printing it
std : : set < ui16 > shaded = spToCast . rangeInHexes ( b , schoolLevel ) ;
for ( std : : set < ui16 > : : iterator it = shaded . begin ( ) ; it ! = shaded . end ( ) ; + + it ) //for spells with range greater then one hex
{
if ( settings . printMouseShadow & & ( * it % BFIELD_WIDTH ! = 0 ) & & ( * it % BFIELD_WIDTH ! = 16 ) )
{
int x = 14 + ( ( * it / BFIELD_WIDTH ) % 2 = = 0 ? 22 : 0 ) + 44 * ( * it % BFIELD_WIDTH ) + pos . x ;
int y = 86 + 42 * ( * it / BFIELD_WIDTH ) + pos . y ;
CSDL_Ext : : blit8bppAlphaTo24bpp ( cellShade , NULL , to , & genRect ( cellShade - > h , cellShade - > w , x , y ) ) ;
}
}
}
else if ( settings . printMouseShadow ) //when not casting spell
2009-01-15 19:01:08 +02: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 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 ) ;
2009-04-16 17:01:27 +03:00
//prevents blitting outside this window
2009-01-15 19:01:08 +02:00
SDL_GetClipRect ( to , & buf ) ;
SDL_SetClipRect ( to , & pos ) ;
2009-02-09 16:50:32 +02:00
//showing obstacles
std : : vector < CObstacleInstance > obstacles = LOCPLINT - > cb - > battleGetAllObstacles ( ) ;
for ( int b = 0 ; b < obstacles . size ( ) ; + + b )
{
2009-08-30 15:58:38 +03:00
std : : pair < si16 , si16 > shift = CGI - > heroh - > obstacles [ obstacles [ b ] . ID ] . posShift ;
int x = ( ( obstacles [ b ] . pos / BFIELD_WIDTH ) % 2 = = 0 ? 22 : 0 ) + 44 * ( obstacles [ b ] . pos % BFIELD_WIDTH ) + pos . x + shift . first ;
int y = 86 + 42 * ( obstacles [ b ] . pos / BFIELD_WIDTH ) + pos . y + shift . second ;
2009-04-16 17:01:27 +03:00
std : : vector < Cimage > & images = idToObstacle [ obstacles [ b ] . ID ] - > ourImages ; //reference to animation of obstacle
2009-03-28 20:46:20 +02:00
blitAt ( images [ ( ( animCount + 1 ) / ( 4 / settings . animSpeed ) ) % images . size ( ) ] . bitmap , x , y , to ) ;
2009-02-09 16:50:32 +02:00
}
2009-01-15 19:01:08 +02: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 )
{
2009-09-11 15:46:26 +03:00
if ( creAnims [ j - > second . ID ] - > getType ( ) ! = 5 & & j - > second . position > = 0 ) //don't show turrets here
2009-01-15 19:01:08 +02:00
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 )
{
2009-09-11 15:46:26 +03:00
if ( creAnims [ j - > second . ID ] - > getType ( ) = = 5 )
2009-01-15 19:01:08 +02:00
stackDeadByHex [ j - > second . position ] . push_back ( j - > second . ID ) ;
}
2009-09-10 14:28:34 +03:00
//handle animations
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : iterator it = pendingAnims . begin ( ) ; it ! = pendingAnims . end ( ) ; + + it )
{
if ( ! it - > first ) //this animation should be deleted
continue ;
if ( ! it - > second )
{
it - > second = it - > first - > init ( ) ;
}
if ( it - > second & & it - > first )
it - > first - > nextFrame ( ) ;
}
//delete anims
2009-09-14 15:00:23 +03:00
int preSize = pendingAnims . size ( ) ;
2009-09-10 14:28:34 +03:00
for ( std : : list < std : : pair < CBattleAnimation * , bool > > : : iterator it = pendingAnims . begin ( ) ; it ! = pendingAnims . end ( ) ; + + it )
{
if ( it - > first = = NULL )
{
pendingAnims . erase ( it ) ;
it = pendingAnims . begin ( ) ;
break ;
}
}
2009-01-15 19:01:08 +02:00
2009-09-14 15:00:23 +03:00
if ( preSize > 0 & & pendingAnims . size ( ) = = 0 )
{
//restoring good directions of stacks
for ( std : : map < int , CStack > : : const_iterator it = stacks . begin ( ) ; it ! = stacks . end ( ) ; + + it )
{
2009-09-15 15:20:11 +03:00
if ( creDir [ it - > second . ID ] ! = bool ( it - > second . attackerOwned ) & & it - > second . alive ( ) )
2009-09-14 15:00:23 +03:00
{
2009-09-16 13:36:50 +03:00
addNewAnim ( new CReverseAnim ( this , it - > second . ID , it - > second . position , false ) ) ;
2009-09-14 15:00:23 +03:00
}
}
2009-09-15 15:20:11 +03:00
//activation of next stack
if ( pendingAnims . size ( ) = = 0 & & stackToActivate ! = - 1 )
{
activateStack ( ) ;
}
if ( pendingAnims . size ( ) = = 0 & & bresult ! = NULL )
{
displayBattleFinished ( ) ;
}
2009-09-16 13:36:50 +03:00
//anims ended
animsAreDisplayed . setn ( false ) ;
2009-09-14 15:00:23 +03:00
}
2009-01-15 19:01:08 +02:00
for ( int b = 0 ; b < BFIELD_SIZE ; + + b ) //showing dead stacks
{
for ( size_t v = 0 ; v < stackDeadByHex [ b ] . size ( ) ; + + v )
{
2009-02-21 17:43:28 +02: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 19:01:08 +02: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 02:38:48 +02:00
int curStackID = stackAliveByHex [ b ] [ v ] ;
2009-08-06 17:02:21 +03:00
2009-08-26 17:09:55 +03:00
showAliveStack ( stackAliveByHex [ b ] [ v ] , stacks , to ) ;
2009-01-15 19:01:08 +02:00
}
2009-08-26 17:09:55 +03:00
2009-09-04 17:11:42 +03:00
showPieceOfWall ( to , b , stacks ) ;
2009-01-15 19:01:08 +02:00
}
//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 )
{
2009-09-07 05:29:44 +03:00
const int QUEUE_SIZE = 10 ;
2009-01-15 19:01:08 +02:00
int xPos = screen - > w / 2 - ( stacks . size ( ) * 37 ) / 2 ;
2009-02-07 18:07:29 +02:00
int yPos = ( screen - > h - 600 ) / 2 + 10 ;
2009-01-15 19:01:08 +02:00
2009-09-07 05:29:44 +03:00
std : : vector < const CStack * > stacksSorted ;
// const CStack *curStack = LOCPLINT->cb->battleGetStackByID(activeStack);
// if(curStack)
// stacksSorted.push_back(curStack);
LOCPLINT - > cb - > getStackQueue ( stacksSorted , QUEUE_SIZE ) ;
for ( size_t b = 0 ; b < stacksSorted . size ( ) ; + + b )
2009-01-15 19:01:08 +02:00
{
2009-09-07 05:29:44 +03:00
const CStack * s = stacksSorted [ 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 )
2009-01-15 19:01:08 +02:00
{
2009-09-07 05:29:44 +03:00
for ( int yFrom = yPos - 1 ; yFrom < yPos + 33 ; + + yFrom )
2009-01-15 19:01:08 +02:00
{
2009-09-07 05:29:44 +03:00
if ( xFrom = = xPos - 1 | | xFrom = = xPos + 32 | | yFrom = = yPos - 1 | | yFrom = = yPos + 32 )
2009-01-15 19:01:08 +02:00
{
2009-09-07 05:29:44 +03:00
SDL_Color pc ;
if ( s - > owner ! = 255 )
2009-01-15 19:01:08 +02:00
{
2009-09-07 05:29:44 +03:00
pc = graphics - > playerColors [ s - > owner ] ;
}
else
{
pc = * graphics - > neutralColor ;
2009-01-15 19:01:08 +02:00
}
2009-09-07 05:29:44 +03:00
CSDL_Ext : : SDL_PutPixelWithoutRefresh ( to , xFrom , yFrom , pc . r , pc . g , pc . b ) ;
2009-01-15 19:01:08 +02:00
}
}
}
2009-09-07 05:29:44 +03:00
//colored border printed
SDL_BlitSurface ( graphics - > smallImgs [ s - > creature - > idNumber ] , NULL , to , & genRect ( 32 , 32 , xPos , yPos ) ) ;
xPos + = 37 ;
2009-01-15 19:01:08 +02:00
}
}
2009-01-30 16:36:26 +02:00
SDL_SetClipRect ( to , & buf ) ; //restoring previous clip_rect
2009-09-04 17:11:42 +03:00
//showing menu background and console
blitAt ( menu , pos . x , 556 + pos . y , to ) ;
console - > show ( to ) ;
2009-01-15 19:01:08 +02:00
//showing window with result of battle
if ( resWindow )
{
resWindow - > show ( to ) ;
}
2009-09-04 17:11:42 +03:00
//showing in-game console
2009-04-14 15:47:09 +03:00
LOCPLINT - > cingconsole - > show ( to ) ;
2009-01-15 19:01:08 +02:00
//printing border around interface
2009-01-14 21:07:57 +02:00
if ( screen - > w ! = 800 | | screen - > h ! = 600 )
2009-01-15 19:01:08 +02: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 ;
}
2009-04-16 17:01:27 +03:00
else if ( key . keysym . sym = = SDLK_ESCAPE & & spellDestSelectMode )
{
endCastingSpell ( ) ;
}
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : mouseMoved ( const SDL_MouseMotionEvent & sEvent )
{
if ( activeStack > = 0 & & ! spellDestSelectMode )
{
2009-02-21 17:43:28 +02:00
mouseHoveredStack = - 1 ;
2009-01-15 19:01:08 +02: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 20:07:31 +02:00
if ( console - > whoSetAlter = = 0 )
{
console - > alterTxt = " " ;
}
2009-01-15 19:01:08 +02:00
}
else
{
if ( std : : find ( shadedHexes . begin ( ) , shadedHexes . end ( ) , myNumber ) = = shadedHexes . end ( ) )
{
2009-08-04 20:05:49 +03:00
const CStack * shere = LOCPLINT - > cb - > battleGetStackByPos ( myNumber ) ;
const CStack * sactive = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) ;
2009-01-15 19:01:08 +02:00
if ( shere )
{
if ( shere - > owner = = LOCPLINT - > playerID ) //our stack
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 5 ) ;
2009-01-29 20:07:31 +02: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 17:43:28 +02:00
mouseHoveredStack = shere - > ID ;
if ( creAnims [ shere - > ID ] - > getType ( ) = = 2 & & creAnims [ shere - > ID ] - > framesInGroup ( 1 ) > 0 )
{
creAnims [ shere - > ID ] - > playOnce ( 1 ) ;
}
2009-01-29 20:07:31 +02:00
}
2009-01-15 19:01:08 +02:00
else if ( LOCPLINT - > cb - > battleCanShoot ( activeStack , myNumber ) ) //we can shoot enemy
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 3 ) ;
2009-01-29 20:07:31 +02:00
//setting console text
char buf [ 500 ] ;
2009-08-29 20:09:07 +03:00
//calculating esimated dmg
std : : pair < ui32 , ui32 > estimatedDmg = LOCPLINT - > cb - > battleEstimateDamage ( sactive - > ID , shere - > ID ) ;
std : : ostringstream estDmg ;
estDmg < < estimatedDmg . first < < " - " < < estimatedDmg . second ;
//printing
sprintf ( buf , CGI - > generaltexth - > allTexts [ 296 ] . c_str ( ) , shere - > amount = = 1 ? shere - > creature - > nameSing . c_str ( ) : shere - > creature - > namePl . c_str ( ) , sactive - > shots , estDmg . str ( ) . c_str ( ) ) ;
2009-01-29 20:07:31 +02:00
console - > alterTxt = buf ;
console - > whoSetAlter = 0 ;
}
2009-01-15 19:01:08 +02:00
else if ( isTileAttackable ( myNumber ) ) //available enemy (melee attackable)
{
2009-08-13 04:55:00 +03:00
CCursorHandler * cursor = CGI - > curh ;
const CBattleHex & hoveredHex = bfield [ myNumber ] ;
const double subdividingAngle = 2.0 * M_PI / 6.0 ; // Divide a hex into six sectors.
const double hexMidX = hoveredHex . pos . x + hoveredHex . pos . w / 2 ;
const double hexMidY = hoveredHex . pos . y + hoveredHex . pos . h / 2 ;
const double cursorHexAngle = M_PI - atan2 ( hexMidY - cursor - > ypos , cursor - > xpos - hexMidX ) + subdividingAngle / 2 ;
2009-08-19 18:47:00 +03:00
const double sector = fmod ( cursorHexAngle / subdividingAngle , 6.0 ) ;
2009-08-13 04:55:00 +03:00
const int zigzagCorrection = ! ( ( myNumber / BFIELD_WIDTH ) % 2 ) ; // Off-by-one correction needed to deal with the odd battlefield rows.
2009-08-19 18:47:00 +03:00
std : : vector < int > sectorCursor ; // From left to bottom left.
sectorCursor . push_back ( 8 ) ;
sectorCursor . push_back ( 9 ) ;
sectorCursor . push_back ( 10 ) ;
sectorCursor . push_back ( 11 ) ;
sectorCursor . push_back ( 12 ) ;
sectorCursor . push_back ( 7 ) ;
const bool doubleWide = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) ;
bool aboveAttackable = true , belowAttackable = true ;
2009-08-13 04:55:00 +03:00
// Exclude directions which cannot be attacked from.
// Check to the left.
if ( myNumber % BFIELD_WIDTH < = 1 | | ! vstd : : contains ( shadedHexes , myNumber - 1 ) ) {
sectorCursor [ 0 ] = - 1 ;
}
2009-08-19 18:47:00 +03:00
// Check top left, top right as well as above for 2-hex creatures.
2009-08-13 04:55:00 +03:00
if ( myNumber / BFIELD_WIDTH = = 0 ) {
sectorCursor [ 1 ] = - 1 ;
sectorCursor [ 2 ] = - 1 ;
2009-08-19 18:47:00 +03:00
aboveAttackable = false ;
} else {
if ( doubleWide ) {
bool attackRow [ 4 ] = { true , true , true , true } ;
if ( myNumber % BFIELD_WIDTH < = 1 | | ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH - 2 + zigzagCorrection ) )
attackRow [ 0 ] = false ;
if ( ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH - 1 + zigzagCorrection ) )
attackRow [ 1 ] = false ;
if ( ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH + zigzagCorrection ) )
attackRow [ 2 ] = false ;
if ( myNumber % BFIELD_WIDTH > = BFIELD_WIDTH - 2 | | ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH + 1 + zigzagCorrection ) )
attackRow [ 3 ] = false ;
if ( ! ( attackRow [ 0 ] & & attackRow [ 1 ] ) )
sectorCursor [ 1 ] = - 1 ;
if ( ! ( attackRow [ 1 ] & & attackRow [ 2 ] ) )
aboveAttackable = false ;
if ( ! ( attackRow [ 2 ] & & attackRow [ 3 ] ) )
sectorCursor [ 2 ] = - 1 ;
} else {
if ( ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH - 1 + zigzagCorrection ) )
sectorCursor [ 1 ] = - 1 ;
if ( ! vstd : : contains ( shadedHexes , myNumber - BFIELD_WIDTH + zigzagCorrection ) )
sectorCursor [ 2 ] = - 1 ;
}
2009-01-15 19:01:08 +02:00
}
2009-08-13 04:55:00 +03:00
// Check to the right.
if ( myNumber % BFIELD_WIDTH > = BFIELD_WIDTH - 2 | | ! vstd : : contains ( shadedHexes , myNumber + 1 ) ) {
sectorCursor [ 3 ] = - 1 ;
}
2009-08-19 18:47:00 +03:00
// Check bottom right, bottom left as well as below for 2-hex creatures.
2009-08-13 04:55:00 +03:00
if ( myNumber / BFIELD_WIDTH = = BFIELD_HEIGHT - 1 ) {
sectorCursor [ 4 ] = - 1 ;
sectorCursor [ 5 ] = - 1 ;
2009-08-19 18:47:00 +03:00
belowAttackable = false ;
} else {
if ( doubleWide ) {
bool attackRow [ 4 ] = { true , true , true , true } ;
if ( myNumber % BFIELD_WIDTH < = 1 | | ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH - 2 + zigzagCorrection ) )
attackRow [ 0 ] = false ;
if ( ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH - 1 + zigzagCorrection ) )
attackRow [ 1 ] = false ;
if ( ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH + zigzagCorrection ) )
attackRow [ 2 ] = false ;
if ( myNumber % BFIELD_WIDTH > = BFIELD_WIDTH - 2 | | ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH + 1 + zigzagCorrection ) )
attackRow [ 3 ] = false ;
if ( ! ( attackRow [ 0 ] & & attackRow [ 1 ] ) )
sectorCursor [ 5 ] = - 1 ;
if ( ! ( attackRow [ 1 ] & & attackRow [ 2 ] ) )
belowAttackable = false ;
if ( ! ( attackRow [ 2 ] & & attackRow [ 3 ] ) )
sectorCursor [ 4 ] = - 1 ;
} else {
if ( ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH + zigzagCorrection ) )
sectorCursor [ 4 ] = - 1 ;
if ( ! vstd : : contains ( shadedHexes , myNumber + BFIELD_WIDTH - 1 + zigzagCorrection ) )
sectorCursor [ 5 ] = - 1 ;
}
}
// Determine index from sector.
int cursorIndex ;
if ( doubleWide ) {
sectorCursor . insert ( sectorCursor . begin ( ) + 5 , belowAttackable ? 13 : - 1 ) ;
sectorCursor . insert ( sectorCursor . begin ( ) + 2 , aboveAttackable ? 14 : - 1 ) ;
if ( sector < 1.5 )
cursorIndex = sector ;
else if ( sector > = 1.5 & & sector < 2.5 )
cursorIndex = 2 ;
else if ( sector > = 2.5 & & sector < 4.5 )
cursorIndex = ( int ) sector + 1 ;
else if ( sector > = 4.5 & & sector < 5.5 )
cursorIndex = 6 ;
else
cursorIndex = ( int ) sector + 2 ;
2009-08-13 04:55:00 +03:00
} else {
2009-08-19 18:47:00 +03:00
cursorIndex = sector ;
2009-08-13 04:55:00 +03:00
}
// Find the closest direction attackable, starting with the right one.
// FIXME: Is this really how the original H3 client does it?
int i = 0 ;
2009-08-19 18:47:00 +03:00
while ( sectorCursor [ ( cursorIndex + i ) % sectorCursor . size ( ) ] = = - 1 )
2009-08-13 04:55:00 +03:00
i = i < = 0 ? 1 - i : - i ; // 0, 1, -1, 2, -2, 3, -3 etc..
2009-08-19 18:47:00 +03:00
cursor - > changeGraphic ( 1 , sectorCursor [ ( cursorIndex + i ) % sectorCursor . size ( ) ] ) ;
2009-08-29 20:09:07 +03:00
//setting console info
char buf [ 500 ] ;
//calculating esimated dmg
std : : pair < ui32 , ui32 > estimatedDmg = LOCPLINT - > cb - > battleEstimateDamage ( sactive - > ID , shere - > ID ) ;
std : : ostringstream estDmg ;
estDmg < < estimatedDmg . first < < " - " < < estimatedDmg . second ;
//printing
sprintf ( buf , CGI - > generaltexth - > allTexts [ 36 ] . c_str ( ) , shere - > amount = = 1 ? shere - > creature - > nameSing . c_str ( ) : shere - > creature - > namePl . c_str ( ) , estDmg . str ( ) . c_str ( ) ) ;
console - > alterTxt = buf ;
console - > whoSetAlter = 0 ;
2009-01-15 19:01:08 +02:00
}
else //unavailable enemy
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 0 ) ;
2009-01-29 20:07:31 +02:00
console - > alterTxt = " " ;
console - > whoSetAlter = 0 ;
}
2009-01-15 19:01:08 +02:00
}
2009-09-01 16:54:13 +03:00
else if ( sactive - > hasFeatureOfType ( StackFeature : : CATAPULT ) & & isCatapultAttackable ( myNumber ) ) //catapulting
{
CGI - > curh - > changeGraphic ( 1 , 16 ) ;
console - > alterTxt = " " ;
console - > whoSetAlter = 0 ;
}
2009-01-15 19:01:08 +02:00
else //empty unavailable tile
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 0 ) ;
2009-01-29 20:07:31 +02:00
console - > alterTxt = " " ;
console - > whoSetAlter = 0 ;
}
2009-01-15 19:01:08 +02:00
}
else //available tile
{
2009-09-10 14:28:34 +03:00
//setting console text and cursor
2009-08-04 20:05:49 +03:00
const CStack * sactive = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) ;
2009-09-10 14:28:34 +03:00
char buf [ 500 ] ;
2009-08-05 15:46:08 +03:00
if ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : FLYING ) )
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 2 ) ;
2009-01-29 20:07:31 +02:00
sprintf ( buf , CGI - > generaltexth - > allTexts [ 295 ] . c_str ( ) , sactive - > amount = = 1 ? sactive - > creature - > nameSing . c_str ( ) : sactive - > creature - > namePl . c_str ( ) ) ;
}
2009-01-15 19:01:08 +02:00
else
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 1 ) ;
2009-01-29 20:07:31 +02:00
sprintf ( buf , CGI - > generaltexth - > allTexts [ 294 ] . c_str ( ) , sactive - > amount = = 1 ? sactive - > creature - > nameSing . c_str ( ) : sactive - > creature - > namePl . c_str ( ) ) ;
}
2009-09-10 14:28:34 +03:00
console - > alterTxt = buf ;
console - > whoSetAlter = 0 ;
2009-01-15 19:01:08 +02: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 20:07:31 +02:00
//setting console text
console - > alterTxt = CGI - > generaltexth - > allTexts [ 23 ] ;
console - > whoSetAlter = 0 ;
2009-01-15 19:01:08 +02:00
}
else
{
2009-08-05 15:46:08 +03:00
//get dead stack if we cast resurrection or animate dead
const CStack * stackUnder = LOCPLINT - > cb - > battleGetStackByPos ( myNumber , spellToCast - > additionalInfo ! = 38 & & spellToCast - > additionalInfo ! = 39 ) ;
2009-08-19 13:59:42 +03:00
if ( stackUnder & & spellToCast - > additionalInfo = = 39 & & ! stackUnder - > hasFeatureOfType ( StackFeature : : UNDEAD ) ) //animate dead can be cast only on undead creatures
2009-08-05 15:46:08 +03:00
stackUnder = NULL ;
2009-08-01 14:55:40 +03:00
bool whichCase ; //for cases 1, 2 and 3
switch ( spellSelMode )
{
case 1 :
whichCase = stackUnder & & LOCPLINT - > playerID = = stackUnder - > owner ;
break ;
case 2 :
whichCase = stackUnder & & LOCPLINT - > playerID ! = stackUnder - > owner ;
break ;
case 3 :
whichCase = stackUnder ;
break ;
}
2009-01-15 19:01:08 +02:00
switch ( spellSelMode )
{
case 0 :
CGI - > curh - > changeGraphic ( 3 , 0 ) ;
2009-01-29 20:07:31 +02: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 19:01:08 +02:00
break ;
2009-08-01 14:55:40 +03:00
case 1 : case 2 : case 3 :
if ( whichCase )
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 3 , 0 ) ;
2009-01-29 20:07:31 +02: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 19:01:08 +02:00
else
2009-01-29 20:07:31 +02:00
{
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 0 ) ;
2009-01-29 20:07:31 +02:00
//setting console text
console - > alterTxt = CGI - > generaltexth - > allTexts [ 23 ] ;
console - > whoSetAlter = 0 ;
}
2009-01-15 19:01:08 +02:00
break ;
case 4 : //TODO: implement this case
2009-08-19 13:59:42 +03:00
if ( blockedByObstacle ( myNumber ) )
{
CGI - > curh - > changeGraphic ( 3 , 0 ) ;
}
else
{
CGI - > curh - > changeGraphic ( 1 , 0 ) ;
}
2009-01-15 19:01:08 +02:00
break ;
}
}
}
}
2009-08-11 19:05:33 +03:00
void CBattleInterface : : clickRight ( tribool down , bool previousState )
2009-04-16 17:01:27 +03:00
{
if ( ! down & & spellDestSelectMode )
{
endCastingSpell ( ) ;
}
}
2009-01-15 19:01:08 +02:00
void CBattleInterface : : bOptionsf ( )
{
CGI - > curh - > changeGraphic ( 0 , 0 ) ;
SDL_Rect temp_rect = genRect ( 431 , 481 , 160 , 84 ) ;
CBattleOptionsWindow * optionsWin = new CBattleOptionsWindow ( temp_rect , this ) ;
2009-08-07 01:36:51 +03:00
GH . pushInt ( optionsWin ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : bSurrenderf ( )
{
}
void CBattleInterface : : bFleef ( )
{
2009-08-16 16:44:17 +03:00
if ( LOCPLINT - > cb - > battleCanFlee ( ) )
{
CFunctionList < void ( ) > ony = boost : : bind ( & CBattleInterface : : reallyFlee , this ) ;
LOCPLINT - > showYesNoDialog ( CGI - > generaltexth - > allTexts [ 28 ] , std : : vector < SComponent * > ( ) , ony , 0 , false ) ;
}
else
{
std : : vector < SComponent * > comps ;
std : : string heroName ;
//calculating fleeing hero's name
if ( attackingHeroInstance )
if ( attackingHeroInstance - > tempOwner = = LOCPLINT - > cb - > getMyColor ( ) )
heroName = attackingHeroInstance - > name ;
if ( defendingHeroInstance )
if ( defendingHeroInstance - > tempOwner = = LOCPLINT - > cb - > getMyColor ( ) )
heroName = defendingHeroInstance - > name ;
//calculating text
char buffer [ 1000 ] ;
sprintf ( buffer , CGI - > generaltexth - > allTexts [ 340 ] . c_str ( ) , heroName . c_str ( ) ) ;
//printing message
LOCPLINT - > showInfoDialog ( std : : string ( buffer ) , comps ) ;
}
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : reallyFlee ( )
{
giveCommand ( 4 , 0 , 0 ) ;
CGI - > curh - > changeGraphic ( 0 , 0 ) ;
}
void CBattleInterface : : bAutofightf ( )
{
}
void CBattleInterface : : bSpellf ( )
{
CGI - > curh - > changeGraphic ( 0 , 0 ) ;
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 ) ;
2009-08-07 01:36:51 +03:00
GH . pushInt ( spellWindow ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : bWaitf ( )
{
2009-05-12 20:30:32 +03:00
if ( activeStack ! = - 1 )
giveCommand ( 8 , 0 , activeStack ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : bDefencef ( )
{
2009-05-12 20:30:32 +03:00
if ( activeStack ! = - 1 )
giveCommand ( 3 , 0 , activeStack ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : bConsoleUpf ( )
{
console - > scrollUp ( ) ;
2009-09-10 14:28:34 +03:00
}
2009-01-15 19:01:08 +02:00
2009-09-10 14:28:34 +03:00
void CBattleInterface : : bConsoleDownf ( )
{
console - > scrollDown ( ) ;
2009-01-15 19:01:08 +02:00
}
2009-09-10 14:28:34 +03:00
void CBattleInterface : : newStack ( int stackID )
2009-01-15 19:01:08 +02:00
{
2009-09-10 14:28:34 +03:00
const CStack * newStack = LOCPLINT - > cb - > battleGetStackByID ( stackID ) ;
std : : pair < int , int > coords = CBattleHex : : getXYUnitAnim ( newStack - > position , newStack - > owner = = attackingHeroInstance - > tempOwner , newStack , this ) ; ;
if ( newStack - > position < 0 ) //turret
2009-02-20 15:06:20 +02:00
{
2009-09-10 14:28:34 +03:00
const CCreature & turretCreature = CGI - > creh - > creatures [ CGI - > creh - > factionToTurretCreature [ siegeH - > town - > town - > typeID ] ] ;
creAnims [ stackID ] = new CCreatureAnimation ( turretCreature . animDefName ) ;
2009-02-20 15:06:20 +02:00
}
2009-09-10 14:28:34 +03:00
else
2009-01-15 19:01:08 +02:00
{
2009-09-10 14:28:34 +03:00
creAnims [ stackID ] = new CCreatureAnimation ( newStack - > creature - > animDefName ) ;
2009-01-15 19:01:08 +02:00
}
2009-09-10 14:28:34 +03:00
creAnims [ stackID ] - > setType ( 2 ) ;
creAnims [ stackID ] - > pos = genRect ( creAnims [ newStack - > ID ] - > fullHeight , creAnims [ newStack - > ID ] - > fullWidth , coords . first , coords . second ) ;
creDir [ stackID ] = newStack - > attackerOwned ;
}
void CBattleInterface : : stackRemoved ( int stackID )
{
delete creAnims [ stackID ] ;
creAnims . erase ( stackID ) ;
creDir . erase ( stackID ) ;
}
void CBattleInterface : : stackActivated ( int number )
{
//givenCommand = NULL;
2009-09-15 15:20:11 +03:00
stackToActivate = number ;
if ( pendingAnims . size ( ) = = 0 )
activateStack ( ) ;
2009-09-10 14:28:34 +03:00
}
2009-01-15 19:01:08 +02:00
2009-09-10 14:28:34 +03:00
void CBattleInterface : : stackMoved ( int number , int destHex , bool endMoving , int distance )
{
2009-09-16 13:36:50 +03:00
addNewAnim ( new CBattleStackMoved ( this , number , destHex , endMoving , distance ) ) ;
2009-09-10 14:28:34 +03:00
}
2009-01-15 19:01:08 +02:00
2009-09-10 14:28:34 +03:00
void CBattleInterface : : stacksAreAttacked ( std : : vector < SStackAttackedInfo > attackedInfos )
{
for ( int h = 0 ; h < attackedInfos . size ( ) ; + + h )
2009-01-15 19:01:08 +02:00
{
2009-09-16 13:36:50 +03:00
addNewAnim ( new CDefenceAnim ( attackedInfos [ h ] , this ) ) ;
2009-01-15 19:01:08 +02:00
}
}
2009-09-10 14:28:34 +03:00
void CBattleInterface : : stackAttacking ( int ID , int dest )
{
2009-09-16 13:36:50 +03:00
addNewAnim ( new CMeleeAttack ( this , ID , dest ) ) ;
2009-09-10 14:28:34 +03:00
}
2009-01-15 19:01:08 +02:00
void CBattleInterface : : newRound ( int number )
{
console - > addText ( CGI - > generaltexth - > allTexts [ 412 ] ) ;
2009-04-16 17:01:27 +03:00
//unlock spellbook
bSpell - > block ( ! LOCPLINT - > cb - > battleCanCastSpell ( ) ) ;
2009-08-22 17:39:44 +03:00
//handle regeneration
std : : map < int , CStack > stacks = LOCPLINT - > cb - > battleGetStacks ( ) ;
for ( std : : map < int , CStack > : : const_iterator it = stacks . begin ( ) ; it ! = stacks . end ( ) ; + + it )
{
if ( it - > second . hasFeatureOfType ( StackFeature : : HP_REGENERATION ) )
displayEffect ( 74 , it - > second . position ) ;
if ( it - > second . hasFeatureOfType ( StackFeature : : FULL_HP_REGENERATION , 0 ) )
displayEffect ( 4 , it - > second . position ) ;
if ( it - > second . hasFeatureOfType ( StackFeature : : FULL_HP_REGENERATION , 1 ) )
displayEffect ( 74 , it - > second . position ) ;
}
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : giveCommand ( ui8 action , ui16 tile , ui32 stack , si32 additional )
{
2009-09-07 16:34:02 +03:00
if ( ! LOCPLINT - > cb - > battleGetStackByID ( stack ) )
{
return ;
}
2009-01-15 19:01:08 +02:00
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 ;
}
2009-08-19 13:59:42 +03:00
bool CBattleInterface : : blockedByObstacle ( int hex ) const
{
std : : vector < CObstacleInstance > obstacles = LOCPLINT - > cb - > battleGetAllObstacles ( ) ;
std : : set < int > coveredHexes ;
for ( int b = 0 ; b < obstacles . size ( ) ; + + b )
{
std : : vector < int > blocked = CGI - > heroh - > obstacles [ obstacles [ b ] . ID ] . getBlocked ( obstacles [ b ] . pos ) ;
for ( int w = 0 ; w < blocked . size ( ) ; + + w )
coveredHexes . insert ( blocked [ w ] ) ;
}
return vstd : : contains ( coveredHexes , hex ) ;
}
2009-09-01 16:54:13 +03:00
bool CBattleInterface : : isCatapultAttackable ( int hex ) const
{
if ( ! siegeH )
return false ;
int wallUnder = LOCPLINT - > cb - > battleGetWallUnderHex ( hex ) ;
if ( wallUnder = = - 1 )
return false ;
return LOCPLINT - > cb - > battleGetWallState ( wallUnder ) < 3 ;
}
2009-01-15 19:01:08 +02:00
void CBattleInterface : : hexLclicked ( int whichOne )
{
2009-09-05 17:10:26 +03:00
const CStack * actSt = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) ;
if ( ( ( whichOne % BFIELD_WIDTH ) ! = 0 & & ( whichOne % BFIELD_WIDTH ) ! = ( BFIELD_WIDTH - 1 ) ) //if player is trying to attack enemey unit or move creature stack
| | ( actSt - > hasFeatureOfType ( StackFeature : : CATAPULT ) & & ! spellDestSelectMode )
)
2009-01-15 19:01:08 +02:00
{
if ( ! myTurn )
return ; //we are not permit to do anything
if ( spellDestSelectMode )
{
//checking destination
bool allowCasting = true ;
2009-08-05 15:46:08 +03:00
bool onlyAlive = spellToCast - > additionalInfo ! = 38 & & spellToCast - > additionalInfo ! = 39 ; //when casting resurrection or animate dead we should be allow to select dead stack
2009-01-15 19:01:08 +02:00
switch ( spellSelMode )
{
case 1 :
2009-08-05 15:46:08 +03:00
if ( ! LOCPLINT - > cb - > battleGetStackByPos ( whichOne , onlyAlive ) | | LOCPLINT - > playerID ! = LOCPLINT - > cb - > battleGetStackByPos ( whichOne , onlyAlive ) - > owner )
2009-01-15 19:01:08 +02:00
allowCasting = false ;
break ;
case 2 :
2009-08-05 15:46:08 +03:00
if ( ! LOCPLINT - > cb - > battleGetStackByPos ( whichOne , onlyAlive ) | | LOCPLINT - > playerID = = LOCPLINT - > cb - > battleGetStackByPos ( whichOne , onlyAlive ) - > owner )
2009-01-15 19:01:08 +02:00
allowCasting = false ;
break ;
case 3 :
2009-08-05 15:46:08 +03:00
if ( ! LOCPLINT - > cb - > battleGetStackByPos ( whichOne , onlyAlive ) )
2009-01-15 19:01:08 +02:00
allowCasting = false ;
break ;
2009-08-19 13:59:42 +03:00
case 4 :
if ( ! blockedByObstacle ( whichOne ) )
allowCasting = false ;
2009-01-15 19:01:08 +02:00
break ;
}
//destination checked
if ( allowCasting )
{
spellToCast - > destinationTile = whichOne ;
LOCPLINT - > cb - > battleMakeAction ( spellToCast ) ;
2009-04-16 17:01:27 +03:00
endCastingSpell ( ) ;
2009-01-15 19:01:08 +02:00
}
}
2009-08-18 14:49:34 +03:00
else //we don't cast any spell
2009-01-15 19:01:08 +02:00
{
2009-08-04 20:05:49 +03:00
const CStack * dest = LOCPLINT - > cb - > battleGetStackByPos ( whichOne ) ; //creature at destination tile; -1 if there is no one
2009-01-15 19:01:08 +02:00
if ( ! dest | | ! dest - > alive ( ) ) //no creature at that tile
{
2009-09-01 16:54:13 +03:00
const CStack * sactive = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) ;
2009-01-15 19:01:08 +02:00
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-08-05 15:46:08 +03:00
if ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) )
2009-02-05 16:44:27 +02:00
{
std : : vector < int > acc = LOCPLINT - > cb - > battleGetAvailableHexes ( activeStack , false ) ;
2009-02-14 15:49:30 +02:00
int shiftedDest = whichOne + ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned ? 1 : - 1 ) ;
2009-02-05 16:44:27 +02:00
if ( vstd : : contains ( acc , whichOne ) )
giveCommand ( 2 , whichOne , activeStack ) ;
2009-02-14 15:49:30 +02:00
else if ( vstd : : contains ( acc , shiftedDest ) )
giveCommand ( 2 , shiftedDest , activeStack ) ;
2009-02-05 16:44:27 +02:00
}
else
{
giveCommand ( 2 , whichOne , activeStack ) ;
}
2009-01-15 19:01:08 +02:00
}
2009-09-01 16:54:13 +03:00
else if ( sactive - > hasFeatureOfType ( StackFeature : : CATAPULT ) & & isCatapultAttackable ( whichOne ) ) //attacking (catapult)
{
giveCommand ( 9 , whichOne , activeStack ) ;
}
2009-01-15 19:01:08 +02: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
{
2009-08-18 14:49:34 +03:00
const CStack * actStack = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) ;
int attackFromHex = - 1 ; //hex from which we will attack chosen stack
2009-01-15 19:01:08 +02:00
switch ( CGI - > curh - > number )
{
2009-04-07 20:51:50 +03:00
case 12 : //from bottom right
{
2009-08-19 18:47:00 +03:00
bool doubleWide = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) ;
int destHex = whichOne + ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH + 1 ) + doubleWide ;
2009-04-07 20:51:50 +03:00
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex ;
else if ( actStack - > attackerOwned ) //if we are attacker
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex + 1 ;
2009-04-07 20:51:50 +03:00
}
2009-08-19 18:47:00 +03:00
else //if we are defender
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex - 1 ;
2009-04-07 20:51:50 +03:00
}
break ;
}
case 7 : //from bottom left
{
int destHex = whichOne + ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH - 1 : BFIELD_WIDTH ) ;
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex ;
else if ( actStack - > attackerOwned ) //if we are attacker
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex + 1 ;
2009-04-07 20:51:50 +03:00
}
2009-08-19 18:47:00 +03:00
else //if we are defender
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex - 1 ;
2009-04-07 20:51:50 +03:00
}
break ;
}
case 8 : //from left
2009-02-05 16:44:27 +02:00
{
2009-09-10 14:28:34 +03:00
if ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) & & ! LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
{
std : : vector < int > acc = LOCPLINT - > cb - > battleGetAvailableHexes ( activeStack , false ) ;
if ( vstd : : contains ( acc , whichOne ) )
attackFromHex = whichOne - 1 ;
else
attackFromHex = whichOne - 2 ;
}
2009-02-05 16:44:27 +02:00
else
2009-09-10 14:28:34 +03:00
{
attackFromHex = whichOne - 1 ;
}
break ;
2009-02-05 16:44:27 +02:00
}
2009-04-07 20:51:50 +03:00
case 9 : //from top left
{
int destHex = whichOne - ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH + 1 : BFIELD_WIDTH ) ;
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex ;
else if ( actStack - > attackerOwned ) //if we are attacker
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex + 1 ;
2009-04-07 20:51:50 +03:00
}
2009-08-19 18:47:00 +03:00
else //if we are defender
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex - 1 ;
2009-04-07 20:51:50 +03:00
}
break ;
}
case 10 : //from top right
{
2009-08-19 18:47:00 +03:00
bool doubleWide = LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) ;
int destHex = whichOne - ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH - 1 ) + doubleWide ;
2009-04-07 20:51:50 +03:00
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex ;
else if ( actStack - > attackerOwned ) //if we are attacker
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex + 1 ;
2009-04-07 20:51:50 +03:00
}
2009-08-19 18:47:00 +03:00
else //if we are defender
2009-04-07 20:51:50 +03:00
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-08-18 14:49:34 +03:00
attackFromHex = destHex - 1 ;
2009-04-07 20:51:50 +03:00
}
break ;
}
case 11 : //from right
2009-02-05 16:44:27 +02:00
{
2009-09-10 14:28:34 +03:00
if ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) & & LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
{
std : : vector < int > acc = LOCPLINT - > cb - > battleGetAvailableHexes ( activeStack , false ) ;
if ( vstd : : contains ( acc , whichOne ) )
attackFromHex = whichOne + 1 ;
else
attackFromHex = whichOne + 2 ;
}
2009-02-05 16:44:27 +02:00
else
2009-09-10 14:28:34 +03:00
{
attackFromHex = whichOne + 1 ;
}
break ;
2009-02-05 16:44:27 +02:00
}
2009-08-19 18:47:00 +03:00
case 13 : //from bottom
{
int destHex = whichOne + ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH + 1 ) ;
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex ;
2009-08-19 18:47:00 +03:00
else if ( attackingHeroInstance - > tempOwner = = LOCPLINT - > cb - > getMyColor ( ) ) //if we are attacker
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex + 1 ;
2009-08-19 18:47:00 +03:00
}
else //if we are defender
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex - 1 ;
2009-08-19 18:47:00 +03:00
}
break ;
}
case 14 : //from top
{
int destHex = whichOne - ( ( whichOne / BFIELD_WIDTH ) % 2 ? BFIELD_WIDTH : BFIELD_WIDTH - 1 ) ;
if ( vstd : : contains ( shadedHexes , destHex ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex ;
2009-08-19 18:47:00 +03:00
else if ( attackingHeroInstance - > tempOwner = = LOCPLINT - > cb - > getMyColor ( ) ) //if we are attacker
{
if ( vstd : : contains ( shadedHexes , destHex + 1 ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex + 1 ;
2009-08-19 18:47:00 +03:00
}
else //if we are defender
{
if ( vstd : : contains ( shadedHexes , destHex - 1 ) )
2009-09-10 14:28:34 +03:00
attackFromHex = destHex - 1 ;
2009-08-19 18:47:00 +03:00
}
break ;
}
2009-01-15 19:01:08 +02:00
}
2009-08-18 14:49:34 +03:00
giveCommand ( 6 , attackFromHex , activeStack , whichOne ) ;
2009-01-15 19:01:08 +02:00
CGI - > curh - > changeGraphic ( 1 , 6 ) ; //cursor should be changed
}
}
}
}
void CBattleInterface : : stackIsShooting ( int ID , int dest )
{
2009-09-16 13:36:50 +03:00
addNewAnim ( new CShootingAnim ( this , ID , dest ) ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleInterface : : battleFinished ( const BattleResult & br )
2009-09-15 15:20:11 +03:00
{
bresult = & br ;
2009-09-16 13:36:50 +03:00
//animsAreDisplayed.waitUntil(false);
2009-09-15 15:20:11 +03:00
displayBattleFinished ( ) ;
}
void CBattleInterface : : displayBattleFinished ( )
2009-01-15 19:01:08 +02:00
{
CGI - > curh - > changeGraphic ( 0 , 0 ) ;
2009-02-07 18:07:29 +02:00
SDL_Rect temp_rect = genRect ( 561 , 470 , ( screen - > w - 800 ) / 2 + 165 , ( screen - > h - 600 ) / 2 + 19 ) ;
2009-05-22 07:14:59 +03:00
CGI - > musich - > stopMusic ( ) ;
2009-09-15 15:20:11 +03:00
resWindow = new CBattleResultWindow ( * bresult , temp_rect , this ) ;
2009-08-07 01:36:51 +03:00
GH . pushInt ( resWindow ) ;
2009-01-15 19:01:08 +02:00
}
2009-05-12 06:35:51 +03:00
void CBattleInterface : : spellCast ( SpellCast * sc )
2009-01-15 19:01:08 +02:00
{
2009-05-14 07:49:04 +03:00
CSpell & spell = CGI - > spellh - > spells [ sc - > id ] ;
2009-04-14 15:47:09 +03:00
if ( sc - > side = = ! LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
bSpell - > block ( true ) ;
2009-01-15 19:01:08 +02:00
std : : vector < std : : string > anims ; //for magic arrow and ice bolt
2009-05-14 07:49:04 +03:00
if ( spell . soundID ! = soundBase : : invalid )
2009-05-22 07:14:59 +03:00
CGI - > soundh - > playSound ( spell . soundID ) ;
2009-05-14 07:49:04 +03:00
2009-01-15 19:01:08 +02:00
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
{
2009-05-12 06:35:51 +03:00
if ( anims . size ( ) = = 0 ) //initialization of anims
2009-01-15 19:01:08 +02:00
{
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 ) ;
2009-09-06 12:13:16 +03:00
std : : pair < int , int > destcoord = CBattleHex : : getXYUnitAnim ( sc - > tile , ! sc - > side , LOCPLINT - > cb - > battleGetStackByPos ( sc - > tile ) , this ) ; //position attacked by arrow
2009-01-15 19:01:08 +02:00
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 15:47:09 +03:00
show ( screen ) ;
2009-01-15 19:01:08 +02: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 15:47:09 +03:00
CSDL_Ext : : update ( screen ) ;
2009-01-15 19:01:08 +02:00
SDL_framerateDelay ( LOCPLINT - > mainFPSmng ) ;
}
SDL_SetClipRect ( screen , & buf ) ; //restoring previous clip rect
break ; //for 15 and 16 cases
}
2009-04-22 13:03:13 +03:00
case 17 : //lightning bolt
displayEffect ( 1 , sc - > tile ) ;
2009-05-14 07:49:04 +03:00
displayEffect ( spell . mainEffectAnim , sc - > tile ) ;
2009-08-04 20:05:49 +03:00
break ;
2009-04-21 20:32:43 +03:00
case 35 : //dispel
2009-08-04 20:05:49 +03:00
case 37 : //cure
2009-08-05 15:46:08 +03:00
case 38 : //resurrection
case 39 : //animate dead
2009-08-04 20:05:49 +03:00
for ( std : : set < ui32 > : : const_iterator it = sc - > affectedCres . begin ( ) ; it ! = sc - > affectedCres . end ( ) ; + + it )
{
2009-08-05 15:46:08 +03:00
displayEffect ( spell . mainEffectAnim , LOCPLINT - > cb - > battleGetStackByID ( * it , false ) - > position ) ;
2009-08-04 20:05:49 +03:00
}
break ;
2009-04-21 20:32:43 +03:00
} //switch(sc->id)
2009-07-26 15:15:38 +03:00
//support for resistance
for ( int j = 0 ; j < sc - > resisted . size ( ) ; + + j )
{
int tile = LOCPLINT - > cb - > battleGetStackByID ( sc - > resisted [ j ] ) - > position ;
displayEffect ( 78 , tile ) ;
}
2009-03-21 18:03:07 +02:00
}
void CBattleInterface : : battleStacksEffectsSet ( const SetStackEffect & sse )
{
for ( std : : set < ui32 > : : const_iterator ci = sse . stacks . begin ( ) ; ci ! = sse . stacks . end ( ) ; + + ci )
{
2009-04-22 13:03:13 +03:00
displayEffect ( CGI - > spellh - > spells [ sse . effect . id ] . mainEffectAnim , LOCPLINT - > cb - > battleGetStackByID ( * ci ) - > position ) ;
2009-01-15 19:01:08 +02:00
}
2009-04-04 22:26:41 +03:00
redrawBackgroundWithHexes ( activeStack ) ;
2009-01-15 19:01:08 +02: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 18:03:07 +02:00
if ( CGI - > spellh - > spells [ spellID ] . attributes . find ( " CREATURE_TARGET " ) ! = std : : string : : npos ) //spell to be cast on one specific creature
2009-01-15 19:01:08 +02:00
{
switch ( CGI - > spellh - > spells [ spellID ] . positiveness )
{
case - 1 :
spellSelMode = 2 ;
break ;
case 0 :
spellSelMode = 3 ;
break ;
case 1 :
spellSelMode = 1 ;
break ;
}
}
2009-08-04 20:05:49 +03:00
if ( CGI - > spellh - > spells [ spellID ] . attributes . find ( " CREATURE_TARGET_1 " ) ! = std : : string : : npos | |
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 19:01:08 +02: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-08-19 13:59:42 +03:00
if ( CGI - > spellh - > spells [ spellID ] . attributes . find ( " OBSTACLE_TARGET " ) ! = std : : string : : npos ) //spell to be cast on an obstacle
{
spellSelMode = 4 ;
}
2009-01-16 19:58:41 +02: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 19:01:08 +02:00
}
void CBattleInterface : : displayEffect ( ui32 effect , int destTile )
{
2009-04-17 17:01:22 +03:00
if ( effect = = 12 ) //armageddon
2009-01-15 19:01:08 +02:00
{
2009-04-17 17:01:22 +03:00
if ( graphics - > battleACToDef [ effect ] . size ( ) ! = 0 )
2009-01-15 19:01:08 +02:00
{
2009-04-17 17:01:22 +03:00
CDefHandler * anim = CDefHandler : : giveDef ( graphics - > battleACToDef [ effect ] [ 0 ] ) ;
for ( int i = 0 ; i * anim - > width < pos . w ; + + i )
{
for ( int j = 0 ; j * anim - > height < pos . h ; + + j )
{
SBattleEffect be ;
be . anim = CDefHandler : : giveDef ( graphics - > battleACToDef [ effect ] [ 0 ] ) ;
be . frame = 0 ;
be . maxFrame = be . anim - > ourImages . size ( ) ;
be . x = i * anim - > width ;
be . y = j * anim - > height ;
battleEffects . push_back ( be ) ;
}
}
2009-01-15 19:01:08 +02:00
}
2009-04-17 17:01:22 +03:00
}
2009-08-30 01:00:46 +03:00
else // Effects targeted at a specific creature/hex.
2009-04-17 17:01:22 +03:00
{
if ( graphics - > battleACToDef [ effect ] . size ( ) ! = 0 )
2009-01-15 19:01:08 +02:00
{
2009-08-30 01:00:46 +03:00
const CStack * destStack = LOCPLINT - > cb - > battleGetStackByPos ( destTile , false ) ;
Rect & tilePos = bfield [ destTile ] . pos ;
2009-04-17 17:01:22 +03:00
SBattleEffect be ;
be . anim = CDefHandler : : giveDef ( graphics - > battleACToDef [ effect ] [ 0 ] ) ;
be . frame = 0 ;
be . maxFrame = be . anim - > ourImages . size ( ) ;
2009-08-30 01:00:46 +03:00
switch ( effect ) {
case 0 : // Prayer and Lightning Bolt.
case 1 :
// Position effect with it's bottom center touching the bottom center of affected tile(s).
be . x = tilePos . x + tilePos . w / 2 - be . anim - > width / 2 ;
be . y = tilePos . y + tilePos . h - be . anim - > height ;
break ;
default :
// Position effect with it's center touching the top center of affected tile(s).
be . x = tilePos . x + tilePos . w / 2 - be . anim - > width / 2 ;
be . y = tilePos . y - be . anim - > height / 2 ;
break ;
2009-04-17 17:01:22 +03:00
}
2009-01-15 19:01:08 +02:00
2009-08-30 01:00:46 +03:00
// Correction for 2-hex creatures.
if ( destStack ! = NULL & & destStack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) )
be . x + = ( destStack - > attackerOwned ? - 1 : 1 ) * tilePos . w / 2 ;
2009-04-17 17:01:22 +03:00
battleEffects . push_back ( be ) ;
}
2009-01-15 19:01:08 +02:00
}
//battleEffects
}
void CBattleInterface : : setAnimSpeed ( int set )
{
2009-03-28 20:46:20 +02:00
settings . animSpeed = set ;
2009-01-15 19:01:08 +02:00
}
int CBattleInterface : : getAnimSpeed ( ) const
{
2009-03-28 20:46:20 +02:00
return settings . animSpeed ;
2009-01-15 19:01:08 +02:00
}
2009-09-15 15:20:11 +03:00
void CBattleInterface : : activateStack ( )
{
activeStack = stackToActivate ;
stackToActivate = - 1 ;
myTurn = true ;
redrawBackgroundWithHexes ( activeStack ) ;
bWait - > block ( vstd : : contains ( LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > state , WAITING ) ) ; //block waiting button if stack has been already waiting
//block cast spell button if hero doesn't have a spellbook
if ( attackingHeroInstance & & LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
{
if ( ! attackingHeroInstance - > getArt ( 17 ) ) //don't unlock if already locked
bSpell - > block ( ! attackingHeroInstance - > getArt ( 17 ) ) ;
}
else if ( defendingHeroInstance & & ! LOCPLINT - > cb - > battleGetStackByID ( activeStack ) - > attackerOwned )
{
if ( ! defendingHeroInstance - > getArt ( 17 ) ) //don't unlock if already locked
bSpell - > block ( ! defendingHeroInstance - > getArt ( 17 ) ) ;
}
}
2009-01-15 19:01:08 +02:00
float CBattleInterface : : getAnimSpeedMultiplier ( ) const
{
2009-03-28 20:46:20 +02:00
switch ( settings . animSpeed )
2009-01-15 19:01:08 +02:00
{
case 1 :
return 3.5f ;
case 2 :
return 2.2f ;
case 4 :
return 1.0f ;
default :
return 0.0f ;
}
}
2009-04-16 17:01:27 +03:00
void CBattleInterface : : endCastingSpell ( )
{
assert ( spellDestSelectMode ) ;
delete spellToCast ;
spellToCast = NULL ;
spellDestSelectMode = false ;
CGI - > curh - > changeGraphic ( 1 , 6 ) ;
}
2009-08-26 17:09:55 +03:00
void CBattleInterface : : showAliveStack ( int ID , const std : : map < int , CStack > & stacks , SDL_Surface * to )
{
if ( creAnims . find ( ID ) = = creAnims . end ( ) ) //eg. for summoned but not yet handled stacks
return ;
const CStack & curStack = stacks . find ( ID ) - > second ;
int animType = creAnims [ ID ] - > getType ( ) ;
int affectingSpeed = settings . animSpeed ;
if ( animType = = 1 | | animType = = 2 ) //standing stacks should not stand faster :)
affectingSpeed = 2 ;
2009-09-14 15:00:23 +03:00
if ( animType = = 3 | | animType = = 7 | | animType = = 8 | | animType = = 9 | | animType = = 10 | | animType = = 11 | | animType = = 12 | | animType = = 13 ) //defend & attack should be slower
2009-09-11 16:18:20 +03:00
affectingSpeed = 1 ;
2009-09-11 15:46:26 +03:00
bool incrementFrame = ( animCount % ( 4 / affectingSpeed ) = = 0 ) & & animType ! = 5 & & animType ! = 20 & & animType ! = 2 ;
2009-08-26 17:09:55 +03:00
if ( animType = = 2 )
{
if ( standingFrame . find ( ID ) ! = standingFrame . end ( ) )
{
incrementFrame = ( animCount % ( 8 / affectingSpeed ) = = 0 ) ;
if ( incrementFrame )
{
+ + standingFrame [ ID ] ;
if ( standingFrame [ ID ] = = creAnims [ ID ] - > framesInGroup ( 2 ) )
{
standingFrame . erase ( standingFrame . find ( ID ) ) ;
}
}
}
else
{
if ( ( rand ( ) % 50 ) = = 0 )
{
standingFrame . insert ( std : : make_pair ( ID , 0 ) ) ;
}
}
}
creAnims [ ID ] - > nextFrame ( to , creAnims [ ID ] - > pos . x + pos . x , creAnims [ ID ] - > pos . y + pos . y , creDir [ ID ] , animCount , incrementFrame , ID = = activeStack , ID = = mouseHoveredStack ) ; //increment always when moving, never if stack died
//printing amount
if ( curStack . amount > 0 //don't print if stack is not alive
& & ( ! LOCPLINT - > curAction
| | ( LOCPLINT - > curAction - > stackNumber ! = ID //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
)
)
& & ! curStack . hasFeatureOfType ( StackFeature : : SIEGE_WEAPON ) //and not a war machine...
)
{
int xAdd = curStack . attackerOwned ? 220 : 202 ;
//blitting amoutn background box
SDL_Surface * amountBG = NULL ;
if ( curStack . effects . size ( ) = = 0 )
{
amountBG = amountNormal ;
}
else
{
int pos = 0 ; //determining total positiveness of effects
for ( int c = 0 ; c < curStack . effects . size ( ) ; + + c )
{
pos + = CGI - > spellh - > spells [ curStack . effects [ c ] . id ] . positiveness ;
}
if ( pos > 0 )
{
amountBG = amountPositive ;
}
else if ( pos < 0 )
{
amountBG = amountNegative ;
}
else
{
amountBG = amountEffNeutral ;
}
}
SDL_BlitSurface ( amountBG , NULL , to , & genRect ( amountNormal - > h , amountNormal - > w , creAnims [ ID ] - > pos . x + xAdd + pos . x , creAnims [ ID ] - > pos . y + 260 + pos . y ) ) ;
//blitting amount
2009-09-07 05:29:44 +03:00
CSDL_Ext : : printAtMiddle (
2009-08-26 17:09:55 +03:00
makeNumberShort ( curStack . amount ) ,
2009-09-07 05:29:44 +03:00
creAnims [ ID ] - > pos . x + xAdd + 15 + pos . x ,
creAnims [ ID ] - > pos . y + 260 + 5 + pos . y ,
FONT_TINY ,
2009-08-26 17:09:55 +03:00
zwykly ,
to
) ;
}
}
2009-09-04 17:11:42 +03:00
void CBattleInterface : : showPieceOfWall ( SDL_Surface * to , int hex , const std : : map < int , CStack > & stacks )
2009-08-26 17:09:55 +03:00
{
if ( ! siegeH )
return ;
2009-09-04 17:11:42 +03:00
static const std : : map < int , int > hexToPart = boost : : assign : : map_list_of ( 12 , 8 ) ( 16 , 1 ) ( 29 , 7 ) ( 50 , 2 ) ( 62 , 12 ) ( 78 , 6 ) ( 112 , 10 ) ( 147 , 5 ) ( 165 , 11 ) ( 182 , 3 ) ( 186 , 0 ) ;
//additionally print bottom wall
if ( hex = = 182 )
{
siegeH - > printPartOfWall ( to , 4 ) ;
}
2009-08-26 17:09:55 +03:00
std : : map < int , int > : : const_iterator it = hexToPart . find ( hex ) ;
if ( it ! = hexToPart . end ( ) )
{
siegeH - > printPartOfWall ( to , it - > second ) ;
2009-09-04 17:11:42 +03:00
//print creature in turret
int posToSeek = - 1 ;
switch ( it - > second )
{
case 3 : //bottom turret
posToSeek = - 3 ;
break ;
case 8 : //upper turret
posToSeek = - 4 ;
break ;
case 2 : //keep
posToSeek = - 2 ;
break ;
}
if ( posToSeek ! = - 1 )
{
int ID = - 1 ;
for ( std : : map < int , CStack > : : const_iterator it = stacks . begin ( ) ; it ! = stacks . end ( ) ; + + it )
{
if ( it - > second . position = = posToSeek )
{
ID = it - > second . ID ;
break ;
}
}
2009-09-05 17:10:26 +03:00
if ( ID ! = - 1 )
2009-09-04 17:11:42 +03:00
{
2009-09-05 17:10:26 +03:00
showAliveStack ( ID , stacks , to ) ;
//blitting creature cover
switch ( posToSeek )
{
case - 3 : //bottom turret
siegeH - > printPartOfWall ( to , 16 ) ;
break ;
case - 4 : //upper turret
siegeH - > printPartOfWall ( to , 17 ) ;
break ;
case - 2 : //keep
siegeH - > printPartOfWall ( to , 15 ) ;
break ;
}
2009-09-04 17:11:42 +03:00
}
2009-09-05 17:10:26 +03:00
2009-09-04 17:11:42 +03:00
}
2009-08-26 17:09:55 +03:00
}
2009-09-04 17:11:42 +03:00
2009-08-26 17:09:55 +03:00
}
2009-01-15 19:01:08 +02:00
void CBattleInterface : : redrawBackgroundWithHexes ( int activeStack )
{
2009-02-05 16:44:27 +02:00
shadedHexes = LOCPLINT - > cb - > battleGetAvailableHexes ( activeStack , true ) ;
2009-01-15 19:01:08 +02:00
//preparating background graphic with hexes and shaded hexes
blitAt ( background , 0 , 0 , backgroundWithHexes ) ;
2009-03-28 20:46:20 +02:00
if ( settings . printCellBorders )
2009-01-15 19:01:08 +02:00
CSDL_Ext : : blit8bppAlphaTo24bpp ( cellBorders , NULL , backgroundWithHexes , NULL ) ;
2009-03-28 20:46:20 +02:00
if ( settings . printStackRange )
2009-01-15 19:01:08 +02:00
{
for ( size_t m = 0 ; m < shadedHexes . size ( ) ; + + m ) //rows
{
2009-01-16 19:58:41 +02:00
int i = shadedHexes [ m ] / BFIELD_WIDTH ; //row
int j = shadedHexes [ m ] % BFIELD_WIDTH - 1 ; //column
2009-01-15 19:01:08 +02: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 ] ;
2009-08-07 14:22:17 +03:00
const CStack * attacker = LOCPLINT - > cb - > battleGetStackByID ( IDby , false ) ;
2009-08-05 15:46:08 +03:00
const CStack * defender = LOCPLINT - > cb - > battleGetStackByID ( ID , false ) ;
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 ( ) ) ,
2009-01-15 19:01:08 +02:00
dmg ) ;
if ( killed > 0 )
{
if ( killed > 1 )
{
2009-08-05 15:46:08 +03:00
sprintf ( tabh + end , CGI - > generaltexth - > allTexts [ 379 ] . c_str ( ) , killed , defender - > creature - > namePl . c_str ( ) ) ;
2009-01-15 19:01:08 +02:00
}
else //killed == 1
{
2009-08-05 15:46:08 +03:00
sprintf ( tabh + end , CGI - > generaltexth - > allTexts [ 378 ] . c_str ( ) , defender - > creature - > nameSing . c_str ( ) ) ;
2009-01-15 19:01:08 +02:00
}
}
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 19:58:41 +02: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 19:01:08 +02: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 18:44:56 +02:00
if ( phase ! = 4 | | nextPhase ! = - 1 | | image < 4 )
2009-01-15 19:01:08 +02:00
{
2009-02-28 18:44:56 +02:00
if ( flagAnimCount % 2 = = 0 )
{
+ + image ;
}
2009-02-09 16:50:32 +02: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 18:44:56 +02:00
nextPhase = - 1 ;
2009-01-15 19:01:08 +02:00
image = 0 ;
}
break ;
}
}
}
void CBattleHero : : activate ( )
{
2009-08-11 19:05:33 +03:00
activateLClick ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleHero : : deactivate ( )
{
2009-08-11 19:05:33 +03:00
deactivateLClick ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleHero : : setPhase ( int newPhase )
{
2009-02-09 16:50:32 +02:00
if ( phase ! = 4 )
{
phase = newPhase ;
image = 0 ;
}
else
{
nextPhase = newPhase ;
}
2009-01-15 19:01:08 +02:00
}
2009-08-11 19:05:33 +03:00
void CBattleHero : : clickLeft ( tribool down , bool previousState )
2009-01-15 19:01:08 +02:00
{
2009-04-17 17:01:22 +03:00
if ( ! down & & myHero & & LOCPLINT - > cb - > battleCanCastSpell ( ) ) //check conditions
2009-01-15 19:01:08 +02: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-08-07 01:36:51 +03:00
GH . pushInt ( spellWindow ) ;
2009-01-15 19:01:08 +02:00
}
}
2009-08-19 08:00:59 +03:00
CBattleHero : : CBattleHero ( const std : : string & defName , int phaseG , int imageG , bool flipG , unsigned char player , const CGHeroInstance * hero , const CBattleInterface * owner ) : flip ( flipG ) , myHero ( hero ) , myOwner ( owner ) , phase ( phaseG ) , nextPhase ( - 1 ) , image ( imageG ) , flagAnim ( 0 ) , flagAnimCount ( 0 )
2009-01-15 19:01:08 +02: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 ;
}
2009-06-07 01:47:23 +03:00
CSDL_Ext : : alphaTransform ( dh - > ourImages [ i ] . bitmap ) ;
2009-01-15 19:01:08 +02:00
}
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 )
{
2009-06-07 01:47:23 +03:00
CSDL_Ext : : alphaTransform ( flag - > ourImages [ i ] . bitmap ) ;
2009-01-15 19:01:08 +02:00
graphics - > blueToPlayersAdv ( flag - > ourImages [ i ] . bitmap , player ) ;
}
}
CBattleHero : : ~ CBattleHero ( )
{
delete dh ;
delete flag ;
}
2009-09-06 12:13:16 +03:00
std : : pair < int , int > CBattleHex : : getXYUnitAnim ( const int & hexNum , const bool & attacker , const CStack * stack , const CBattleInterface * cbi )
2009-01-15 19:01:08 +02:00
{
2009-09-06 12:13:16 +03:00
if ( stack - > position < 0 ) //creatures in turrets
{
const CCreature & turretCreature = CGI - > creh - > creatures [ CGI - > creh - > factionToTurretCreature [ cbi - > siegeH - > town - > town - > typeID ] ] ;
int xShift = turretCreature . isDoubleWide ( ) ? 44 : 0 ;
switch ( stack - > position )
{
case - 2 : //keep
return std : : make_pair ( 505 + xShift , - 66 ) ;
break ;
case - 3 : //lower turret
return std : : make_pair ( 368 + xShift , 304 ) ;
break ;
case - 4 : //upper turret
return std : : make_pair ( 339 + xShift , - 192 ) ;
break ;
}
}
2009-01-15 19:01:08 +02:00
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
2009-08-05 15:46:08 +03:00
if ( stack & & stack - > hasFeatureOfType ( StackFeature : : DOUBLE_WIDE ) )
2009-01-15 19:01:08 +02:00
{
if ( attacker )
{
ret . first - = 42 ;
}
else
{
ret . first + = 42 ;
}
}
//returning
return ret ;
}
void CBattleHex : : activate ( )
{
2009-08-11 19:05:33 +03:00
activateHover ( ) ;
activateMouseMove ( ) ;
activateLClick ( ) ;
activateRClick ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleHex : : deactivate ( )
{
2009-08-11 19:05:33 +03:00
deactivateHover ( ) ;
deactivateMouseMove ( ) ;
deactivateLClick ( ) ;
deactivateRClick ( ) ;
2009-01-15 19:01:08 +02:00
}
void CBattleHex : : hover ( bool on )
{
hovered = on ;
2009-08-11 19:05:33 +03:00
//Hoverable::hover(on);
2009-01-15 19:01:08 +02:00
if ( ! on & & setAlterText )
{
myInterface - > console - > alterTxt = std : : string ( ) ;
setAlterText = false ;
}
}
2009-04-15 13:20:47 +03:00
CBattleHex : : CBattleHex ( ) : setAlterText ( false ) , myNumber ( - 1 ) , accesible ( true ) , hovered ( false ) , strictHovered ( false ) , myInterface ( NULL )
2009-01-15 19:01:08 +02:00
{
}
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 ;
}
}
2009-08-11 19:05:33 +03:00
void CBattleHex : : clickLeft ( tribool down , bool previousState )
2009-01-15 19:01:08 +02:00
{
if ( ! down & & hovered & & strictHovered ) //we've been really clicked!
{
myInterface - > hexLclicked ( myNumber ) ;
}
}
2009-08-11 19:05:33 +03:00
void CBattleHex : : clickRight ( tribool down , bool previousState )
2009-01-15 19:01:08 +02:00
{
int stID = LOCPLINT - > cb - > battleGetStack ( myNumber ) ; //id of stack being on this tile
if ( hovered & & strictHovered & & stID ! = - 1 )
{
2009-05-17 18:24:50 +03:00
const CStack & myst = * LOCPLINT - > cb - > battleGetStackByID ( stID ) ; //stack info
2009-01-15 19:01:08 +02:00
if ( ! myst . alive ( ) ) return ;
StackState * pom = NULL ;
if ( down )
{
pom = new StackState ( ) ;
const CGHeroInstance * h = myst . owner = = myInterface - > attackingHeroInstance - > tempOwner ? myInterface - > attackingHeroInstance : myInterface - > defendingHeroInstance ;
2009-05-17 18:24:50 +03:00
pom - > attackBonus = myst . Attack ( ) - myst . creature - > attack ;
pom - > defenseBonus = myst . Defense ( ) - myst . creature - > defence ;
pom - > luck = myst . Luck ( ) ;
pom - > morale = myst . Morale ( ) ;
pom - > speedBonus = myst . Speed ( ) - myst . creature - > speed ;
2009-06-28 16:49:39 +03:00
pom - > healthBonus = myst . MaxHealth ( ) - myst . creature - > hitPoints ;
2009-07-30 15:49:45 +03:00
if ( myst . hasFeatureOfType ( StackFeature : : SIEGE_WEAPON ) )
pom - > dmgMultiplier = h - > getPrimSkillLevel ( 0 ) + 1 ;
else
pom - > dmgMultiplier = 1 ;
2009-01-15 19:01:08 +02: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-08-07 01:36:51 +03:00
GH . pushInt ( new CCreInfoWindow ( myst . creature - > idNumber , 0 , myst . amount , pom , 0 , 0 , NULL ) ) ;
2009-01-15 19:01:08 +02:00
}
delete pom ;
}
}
2009-01-29 20:07:31 +02:00
CBattleConsole : : CBattleConsole ( ) : lastShown ( - 1 ) , alterTxt ( " " ) , whoSetAlter ( 0 )
2009-01-15 19:01:08 +02:00
{
}
CBattleConsole : : ~ CBattleConsole ( )
{
texts . clear ( ) ;
}
void CBattleConsole : : show ( SDL_Surface * to )
{
2009-04-03 18:55:26 +03: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 19:01:08 +02: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 ;
}
2009-06-01 06:36:13 +03:00
CBattleResultWindow : : CBattleResultWindow ( const BattleResult & br , const SDL_Rect & pos , const CBattleInterface * owner )
2009-01-15 19:01:08 +02:00
{
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-06-01 06:36:13 +03:00
exit = new AdventureMapButton ( std : : string ( ) , std : : string ( ) , boost : : bind ( & CBattleResultWindow : : bExitf , this ) , 384 + pos . x , 505 + pos . y , " iok6432.def " , SDLK_RETURN ) ;
2009-01-15 19:01:08 +02: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 ) ;
2009-06-17 19:46:16 +03:00
std : : ostringstream amount ;
2009-01-15 19:01:08 +02:00
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
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : winBattle ) ;
2009-06-28 19:02:39 +03:00
# ifdef _WIN32
CGI - > videoh - > open ( VIDEO_WIN ) ;
# else
CGI - > videoh - > open ( VIDEO_WIN , true ) ;
# endif
2009-01-15 19:01:08 +02:00
CSDL_Ext : : printAtMiddle ( CGI - > generaltexth - > allTexts [ 304 ] , 235 , 235 , GEOR13 , zwykly , background ) ;
}
else
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : loseCombat ) ;
2009-06-28 19:02:39 +03:00
CGI - > videoh - > open ( VIDEO_LOSE_BATTLE_START ) ;
2009-01-15 19:01:08 +02:00
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
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : winBattle ) ;
2009-06-28 19:02:39 +03:00
# ifdef _WIN32
CGI - > videoh - > open ( VIDEO_WIN ) ;
# else
CGI - > videoh - > open ( VIDEO_WIN , true ) ;
# endif
2009-01-15 19:01:08 +02:00
CSDL_Ext : : printAtMiddle ( CGI - > generaltexth - > allTexts [ 303 ] , 235 , 235 , GEOR13 , zwykly , background ) ;
}
else
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : retreatBattle ) ;
2009-06-28 19:02:39 +03:00
CGI - > videoh - > open ( VIDEO_RETREAT_START ) ;
2009-01-15 19:01:08 +02:00
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
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : winBattle ) ;
2009-06-28 19:02:39 +03:00
# ifdef _WIN32
CGI - > videoh - > open ( VIDEO_WIN ) ;
# else
CGI - > videoh - > open ( VIDEO_WIN , true ) ;
# endif
2009-01-15 19:01:08 +02:00
CSDL_Ext : : printAtMiddle ( CGI - > generaltexth - > allTexts [ 302 ] , 235 , 235 , GEOR13 , zwykly , background ) ;
}
else
{
2009-05-22 07:14:59 +03:00
CGI - > musich - > playMusic ( musicBase : : surrenderBattle ) ;
2009-06-28 19:02:39 +03:00
CGI - > videoh - > open ( VIDEO_SURRENDER ) ;
2009-01-15 19:01:08 +02:00
CSDL_Ext : : printAtMiddle ( CGI - > generaltexth - > allTexts [ 309 ] , 235 , 235 , GEOR13 , zwykly , background ) ;
}
break ;
}
}
2009-06-01 06:36:13 +03:00
CBattleResultWindow : : ~ CBattleResultWindow ( )
2009-01-15 19:01:08 +02:00
{
SDL_FreeSurface ( background ) ;
}
2009-06-01 06:36:13 +03:00
void CBattleResultWindow : : activate ( )
2009-01-15 19:01:08 +02:00
{
LOCPLINT - > showingDialog - > set ( true ) ;
exit - > activate ( ) ;
}
2009-06-01 06:36:13 +03:00
void CBattleResultWindow : : deactivate ( )
2009-01-15 19:01:08 +02:00
{
exit - > deactivate ( ) ;
}
2009-06-01 06:36:13 +03:00
void CBattleResultWindow : : show ( SDL_Surface * to )
2009-01-15 19:01:08 +02:00
{
//evaluating to
if ( ! to )
to = screen ;
2009-06-28 19:02:39 +03:00
CGI - > videoh - > update ( 107 , 70 , background , false , true ) ;
2009-01-15 19:01:08 +02:00
SDL_BlitSurface ( background , NULL , to , & pos ) ;
exit - > show ( to ) ;
}
2009-06-01 06:36:13 +03:00
void CBattleResultWindow : : bExitf ( )
2009-01-15 19:01:08 +02:00
{
2009-08-07 01:36:51 +03:00
GH . popInts ( 2 ) ; //first - we; second - battle interface
2009-04-14 15:47:09 +03:00
LOCPLINT - > showingDialog - > setn ( false ) ;
2009-06-28 19:02:39 +03:00
CGI - > videoh - > close ( ) ;
2009-01-15 19:01:08 +02: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 20:46:20 +02:00
viewGrid - > select ( owner - > settings . printCellBorders ) ;
2009-01-15 19:01:08 +02: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 20:46:20 +02:00
movementShadow - > select ( owner - > settings . printStackRange ) ;
2009-01-15 19:01:08 +02: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 20:46:20 +02:00
mouseShadow - > select ( owner - > settings . printMouseShadow ) ;
2009-01-15 19:01:08 +02: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-08-07 01:36:51 +03:00
GH . popIntTotally ( this ) ;
2009-01-15 19:01:08 +02:00
}
2009-08-24 15:55:05 +03:00
2009-08-28 13:05:45 +03:00
std : : string CBattleInterface : : SiegeHelper : : townTypeInfixes [ F_NUMBER ] = { " CS " , " RM " , " TW " , " IN " , " NC " , " DN " , " ST " , " FR " , " EL " } ;
2009-08-24 15:55:05 +03:00
2009-08-26 17:09:55 +03:00
CBattleInterface : : SiegeHelper : : SiegeHelper ( const CGTownInstance * siegeTown , const CBattleInterface * _owner )
: town ( siegeTown ) , owner ( _owner )
{
for ( int g = 0 ; g < ARRAY_COUNT ( walls ) ; + + g )
{
2009-09-01 16:54:13 +03:00
walls [ g ] = BitmapHandler : : loadBitmap ( getSiegeName ( g ) ) ;
2009-08-26 17:09:55 +03:00
}
}
CBattleInterface : : SiegeHelper : : ~ SiegeHelper ( )
{
for ( int g = 0 ; g < ARRAY_COUNT ( walls ) ; + + g )
{
SDL_FreeSurface ( walls [ g ] ) ;
}
}
std : : string CBattleInterface : : SiegeHelper : : getSiegeName ( ui16 what , ui16 additInfo ) const
{
2009-09-01 16:54:13 +03:00
if ( what = = 2 | | what = = 3 | | what = = 8 )
{
2009-09-05 17:10:26 +03:00
if ( additInfo = = 3 ) additInfo = 2 ;
2009-09-01 16:54:13 +03:00
}
2009-08-26 17:09:55 +03:00
char buf [ 100 ] ;
2009-08-27 02:38:17 +03:00
SDL_itoa ( additInfo , buf , 10 ) ;
2009-08-26 17:09:55 +03:00
std : : string addit ( buf ) ;
switch ( what )
{
case 0 : //background
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " BACK.BMP " ;
case 1 : //background wall
2009-08-28 12:03:58 +03:00
{
switch ( town - > town - > typeID )
{
case 5 : case 4 : case 1 : case 6 :
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TPW1.BMP " ;
case 0 : case 2 : case 3 : case 7 : case 8 :
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TPWL.BMP " ;
default :
return " " ;
}
}
2009-08-26 17:09:55 +03:00
case 2 : //keep
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " MAN " + addit + " .BMP " ;
case 3 : //bottom tower
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TW1 " + addit + " .BMP " ;
case 4 : //bottom wall
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA1 " + addit + " .BMP " ;
case 5 : //below gate
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA3 " + addit + " .BMP " ;
case 6 : //over gate
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA4 " + addit + " .BMP " ;
case 7 : //upper wall
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA6 " + addit + " .BMP " ;
case 8 : //upper tower
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TW2 " + addit + " .BMP " ;
case 9 : //gate
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " DRW " + addit + " .BMP " ;
case 10 : //gate arch
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " ARCH.BMP " ;
case 11 : //bottom static wall
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA2.BMP " ;
case 12 : //upper static wall
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " WA5.BMP " ;
2009-09-02 17:10:19 +03:00
case 13 : //moat
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " MOAT.BMP " ;
case 14 : //mlip
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " MLIP.BMP " ;
2009-09-04 17:11:42 +03:00
case 15 : //keep creature cover
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " MANC.BMP " ;
case 16 : //bottom turret creature cover
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TW1C.BMP " ;
case 17 : //upper turret creature cover
return " SG " + townTypeInfixes [ town - > town - > typeID ] + " TW2C.BMP " ;
2009-08-26 17:09:55 +03:00
default :
return " " ;
}
}
void CBattleInterface : : SiegeHelper : : printPartOfWall ( SDL_Surface * to , int what )
2009-08-24 15:55:05 +03:00
{
2009-08-26 17:09:55 +03:00
Point pos = Point ( - 1 , - 1 ) ;
switch ( what )
{
2009-08-28 13:49:11 +03:00
case 1 : //background wall
2009-09-01 16:54:13 +03:00
pos = Point ( owner - > pos . w + owner - > pos . x - walls [ 1 ] - > w , 55 + owner - > pos . y ) ;
2009-08-28 13:49:11 +03:00
break ;
2009-08-26 17:09:55 +03:00
case 2 : //keep
2009-09-01 16:54:13 +03:00
pos = Point ( owner - > pos . w + owner - > pos . x - walls [ 2 ] - > w , 154 + owner - > pos . y ) ;
2009-08-26 17:09:55 +03:00
break ;
case 3 : //bottom tower
case 4 : //bottom wall
case 5 : //below gate
case 6 : //over gate
case 7 : //upper wall
case 8 : //upper tower
case 9 : //gate
case 10 : //gate arch
case 11 : //bottom static wall
case 12 : //upper static wall
pos . x = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ what - 3 ] . first + owner - > pos . x ;
pos . y = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ what - 3 ] . second + owner - > pos . y ;
break ;
2009-09-04 17:11:42 +03:00
case 15 : //keep creature cover
pos = Point ( owner - > pos . w + owner - > pos . x - walls [ 2 ] - > w , 154 + owner - > pos . y ) ;
break ;
case 16 : //bottom turret creature cover
pos . x = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ 0 ] . first + owner - > pos . x ;
pos . y = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ 0 ] . second + owner - > pos . y ;
break ;
case 17 : //upper turret creature cover
pos . x = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ 5 ] . first + owner - > pos . x ;
pos . y = CGI - > heroh - > wallPositions [ town - > town - > typeID ] [ 5 ] . second + owner - > pos . y ;
break ;
2009-08-26 17:09:55 +03:00
} ;
if ( pos . x ! = - 1 )
{
2009-09-01 16:54:13 +03:00
blitAt ( walls [ what ] , pos . x , pos . y , to ) ;
2009-08-26 17:09:55 +03:00
}
2009-08-24 15:55:05 +03:00
}