2011-12-14 00:35:28 +03:00
# pragma once
# include "../../lib/CCreatureSet.h"
# include "../../lib/ConstTransitivePtr.h" //may be reundant
# include "../CAnimation.h"
# include "../../lib/GameConstants.h"
2012-12-01 09:30:52 +03:00
# include "CBattleAnimations.h"
2011-12-14 00:35:28 +03:00
/*
* CBattleInterface . h , 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
*
*/
class CLabel ;
class CCreatureSet ;
class CGHeroInstance ;
class CDefHandler ;
class CStack ;
class CCallback ;
2011-12-22 16:05:19 +03:00
class CAdventureMapButton ;
2011-12-14 00:35:28 +03:00
class CHighlightableButton ;
class CHighlightableButtonsGroup ;
struct BattleResult ;
struct BattleSpellCast ;
struct CObstacleInstance ;
template < typename T > struct CondSh ;
2012-09-15 22:16:16 +03:00
struct SetStackEffect ;
2011-12-14 00:35:28 +03:00
struct BattleAction ;
class CGTownInstance ;
struct CatapultAttack ;
2011-12-22 16:05:19 +03:00
struct CatapultProjectileInfo ;
2011-12-14 00:35:28 +03:00
struct BattleTriggerEffect ;
class CBattleAnimation ;
class CBattleHero ;
class CBattleConsole ;
class CBattleResultWindow ;
class CStackQueue ;
2011-12-17 21:59:59 +03:00
class CPlayerInterface ;
2011-12-22 16:05:19 +03:00
class CCreatureAnimation ;
struct ProjectileInfo ;
class CClickableHex ;
struct BattleHex ;
2012-08-26 12:07:48 +03:00
struct InfoAboutHero ;
2013-02-12 01:36:12 +03:00
struct BattleAction ;
2011-12-14 00:35:28 +03:00
/// Class which manages the locked hex fields that are blocked e.g. by obstacles
class CBattleObstacle
{
std : : vector < int > lockedHexes ;
} ;
2011-12-22 16:05:19 +03:00
/// Small struct which contains information about the id of the attacked stack, the damage dealt,...
struct StackAttackedInfo
{
const CStack * defender ; //attacked stack
2012-04-08 13:34:23 +03:00
unsigned int dmg ; //damage dealt
unsigned int amountKilled ; //how many creatures in stack has been killed
2011-12-22 16:05:19 +03:00
const CStack * attacker ; //attacking stack
bool byShooting ; //if true, stack has been attacked by shooting
bool killed ; //if true, stack has been killed
bool rebirth ; //if true, play rebirth animation after all
2012-02-18 20:39:47 +03:00
bool cloneKilled ;
2011-12-22 16:05:19 +03:00
} ;
2011-12-14 00:35:28 +03:00
/// Struct for battle effect animation e.g. morale, prayer, armageddon, bless,...
2011-12-22 16:05:19 +03:00
struct BattleEffect
2011-12-14 00:35:28 +03:00
{
int x , y ; //position on the screen
int frame , maxFrame ;
CDefHandler * anim ; //animation to display
int effectID ; //uniqueID equal ot ID of appropriate CSpellEffectAnim
} ;
/// Small struct which is needed for drawing the parabolic trajectory of the catapult cannon
2011-12-22 16:05:19 +03:00
struct CatapultProjectileInfo
2011-12-14 00:35:28 +03:00
{
2013-04-04 21:20:25 +03:00
CatapultProjectileInfo ( Point from , Point dest ) ;
2011-12-14 00:35:28 +03:00
2013-04-04 21:20:25 +03:00
double facA , facB , facC ;
2011-12-14 00:35:28 +03:00
double calculateY ( double x ) ;
} ;
/// Big class which handles the overall battle interface actions and it is also responsible for
/// drawing everything correctly.
class CBattleInterface : public CIntObject
{
2012-04-04 11:03:52 +03:00
enum PossibleActions // actions performed at l-click
{
2012-04-17 11:46:09 +03:00
INVALID = - 1 , CREATURE_INFO ,
2012-04-04 11:03:52 +03:00
MOVE_TACTICS , CHOOSE_TACTICS_STACK ,
MOVE_STACK , ATTACK , WALK_AND_ATTACK , ATTACK_AND_RETURN , SHOOT , //OPEN_GATE, //we can open castle gate during siege
2012-04-17 11:46:09 +03:00
NO_LOCATION , ANY_LOCATION , FRIENDLY_CREATURE_SPELL , HOSTILE_CREATURE_SPELL , RISING_SPELL , ANY_CREATURE , OBSTACLE , TELEPORT , SACRIFICE , RANDOM_GENIE_SPELL ,
2012-05-18 23:50:16 +03:00
FREE_LOCATION , //used with Force Field and Fire Wall - all tiles affected by spell must be free
2012-04-04 11:03:52 +03:00
CATAPULT , HEAL , RISE_DEMONS
} ;
2011-12-14 00:35:28 +03:00
private :
SDL_Surface * background , * menu , * amountNormal , * amountNegative , * amountPositive , * amountEffNeutral , * cellBorders , * backgroundWithHexes ;
2011-12-22 16:05:19 +03:00
CAdventureMapButton * bOptions , * bSurrender , * bFlee , * bAutofight , * bSpell ,
2011-12-14 00:35:28 +03:00
* bWait , * bDefence , * bConsoleUp , * bConsoleDown , * btactNext , * btactEnd ;
CBattleConsole * console ;
CBattleHero * attackingHero , * defendingHero ; //fighting heroes
CStackQueue * queue ;
const CCreatureSet * army1 , * army2 ; //copy of initial armies (for result window)
const CGHeroInstance * attackingHeroInstance , * defendingHeroInstance ;
std : : map < int , CCreatureAnimation * > creAnims ; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
std : : map < int , CDefHandler * > idToProjectile ; //projectiles of creatures (creatureID, defhandler)
std : : map < int , CDefHandler * > idToObstacle ; //obstacles located on the battlefield
2012-04-23 22:56:37 +03:00
std : : map < int , SDL_Surface * > idToAbsoluteObstacle ; //obstacles located on the battlefield
2012-05-18 23:50:16 +03:00
//TODO these should be loaded only when needed (and freed then) but I believe it's rather work for resource manager,
//so I didn't implement that (having ongoing RM development)
2012-05-05 00:16:39 +03:00
CDefHandler * landMine ;
CDefHandler * quicksand ;
2012-05-18 23:50:16 +03:00
CDefHandler * fireWall ;
CDefHandler * smallForceField [ 2 ] , * bigForceField [ 2 ] ; // [side]
2012-05-05 00:16:39 +03:00
2012-11-29 18:02:55 +03:00
std : : map < int , bool > creDir ; // <creatureID, if false reverse creature's animation> //TODO: move it to battle callback
2011-12-14 00:35:28 +03:00
ui8 animCount ;
const CStack * activeStack ; //number of active stack; NULL - no one
const CStack * stackToActivate ; //when animation is playing, we should wait till the end to make the next stack active; NULL of none
2012-04-28 22:40:27 +03:00
const CStack * selectedStack ; //for Teleport / Sacrifice
2011-12-14 00:35:28 +03:00
void activateStack ( ) ; //sets activeStack to stackToActivate etc.
int mouseHoveredStack ; //stack hovered by mouse; if -1 -> none
time_t lastMouseHoveredStackAnimationTime ; // time when last mouse hovered animation occurred
static const time_t HOVER_ANIM_DELTA ;
2011-12-22 16:05:19 +03:00
std : : vector < BattleHex > occupyableHexes , //hexes available for active stack
2011-12-14 00:35:28 +03:00
attackableHexes ; //hexes attackable by active stack
bool stackCountOutsideHexes [ GameConstants : : BFIELD_SIZE ] ; // hexes that when in front of a unit cause it's amount box to move back
int previouslyHoveredHex ; //number of hex that was hovered by the cursor a while ago
int currentlyHoveredHex ; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
int attackingHex ; //hex from which the stack would perform attack with current cursor
double getAnimSpeedMultiplier ( ) const ; //returns multiplier for number of frames in a group
std : : map < int , int > standingFrame ; //number of frame in standing animation by stack ID, helps in showing 'random moves'
2011-12-17 21:59:59 +03:00
CPlayerInterface * tacticianInterface ; //used during tactics mode, points to the interface of player with higher tactics (can be either attacker or defender in hot-seat), valid onloy for human players
2011-12-14 00:35:28 +03:00
bool tacticsMode ;
bool stackCanCastSpell ; //if true, active stack could possibly cats some target spell
2012-04-16 20:12:39 +03:00
bool creatureCasting ; //if true, stack currently aims to cats a spell
2012-04-18 12:01:08 +03:00
bool spellDestSelectMode ; //if true, player is choosing destination for his spell - only for GUI / console
2012-04-16 20:12:39 +03:00
PossibleActions spellSelMode ;
2011-12-14 00:35:28 +03:00
BattleAction * spellToCast ; //spell for which player is choosing destination
2012-04-16 20:12:39 +03:00
const CSpell * sp ; //spell pointer for convenience
2012-03-31 00:36:07 +03:00
si32 creatureSpellToCast ;
2012-04-16 20:12:39 +03:00
std : : vector < PossibleActions > possibleActions ; //all actions possible to call at the moment by player
std : : vector < PossibleActions > localActions ; //actions possible to take on hovered hex
std : : vector < PossibleActions > illegalActions ; //these actions display message in case of illegal target
PossibleActions currentAction ; //action that will be performed on l-click
PossibleActions selectedAction ; //last action chosen (and saved) by player
PossibleActions illegalAction ; //most likely action that can't be performed here
2012-04-04 11:03:52 +03:00
void getPossibleActionsForStack ( const CStack * stack ) ; //called when stack gets its turn
2011-12-14 00:35:28 +03:00
void endCastingSpell ( ) ; //ends casting spell (eg. when spell has been cast or canceled)
void showAliveStack ( const CStack * stack , SDL_Surface * to ) ; //helper function for function show
void showAliveStacks ( std : : vector < const CStack * > * aliveStacks , int hex , std : : vector < const CStack * > * flyingStacks , SDL_Surface * to ) ; // loops through all stacks at a given hex position
void showPieceOfWall ( SDL_Surface * to , int hex , const std : : vector < const CStack * > & stacks ) ; //helper function for show
2012-05-18 23:50:16 +03:00
void showObstacles ( std : : multimap < BattleHex , int > * hexToObstacle , std : : vector < shared_ptr < const CObstacleInstance > > & obstacles , int hex , SDL_Surface * to ) ; // show all obstacles at a given hex position
2012-05-05 00:16:39 +03:00
SDL_Surface * imageOfObstacle ( const CObstacleInstance & oi ) const ;
Point whereToBlitObstacleImage ( SDL_Surface * image , const CObstacleInstance & obstacle ) const ;
2011-12-14 00:35:28 +03:00
void redrawBackgroundWithHexes ( const CStack * activeStack ) ;
void printConsoleAttacked ( const CStack * defender , int dmg , int killed , const CStack * attacker , bool Multiple ) ;
2011-12-22 16:05:19 +03:00
std : : list < ProjectileInfo > projectiles ; //projectiles flying on battlefield
2011-12-14 00:35:28 +03:00
void projectileShowHelper ( SDL_Surface * to ) ; //prints projectiles present on the battlefield
2013-02-04 00:05:44 +03:00
void giveCommand ( Battle : : ActionType action , BattleHex tile , ui32 stackID , si32 additional = - 1 , si32 selectedStack = - 1 ) ;
2011-12-22 16:05:19 +03:00
bool isTileAttackable ( const BattleHex & number ) const ; //returns true if tile 'number' is neighboring any tile from active stack's range or is one of these tiles
bool isCatapultAttackable ( BattleHex hex ) const ; //returns true if given tile can be attacked by catapult
2011-12-14 00:35:28 +03:00
2011-12-22 16:05:19 +03:00
std : : list < BattleEffect > battleEffects ; //different animations to display on the screen like spell effects
2011-12-14 00:35:28 +03:00
/// Class which is responsible for drawing the wall of a siege during battle
class SiegeHelper
{
private :
SDL_Surface * walls [ 18 ] ;
const CBattleInterface * owner ;
public :
const CGTownInstance * town ; //besieged town
SiegeHelper ( const CGTownInstance * siegeTown , const CBattleInterface * _owner ) ; //c-tor
~ SiegeHelper ( ) ; //d-tor
//filename getters
std : : string getSiegeName ( ui16 what , ui16 additInfo = 1 ) const ; //what: 0 - background, 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 13 - moat, 14 - mlip, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover; additInfo: 1 - intact, 2 - damaged, 3 - destroyed
void printPartOfWall ( SDL_Surface * to , int what ) ; //what: 1 - background wall, 2 - keep, 3 - bottom tower, 4 - bottom wall, 5 - below gate, 6 - over gate, 7 - upper wall, 8 - uppert tower, 9 - gate, 10 - gate arch, 11 - bottom static wall, 12 - upper static wall, 15 - keep creature cover, 16 - bottom turret creature cover, 17 - upper turret creature cover
friend class CBattleInterface ;
} * siegeH ;
CPlayerInterface * attackerInt , * defenderInt ; //because LOCPLINT is not enough in hotSeat
const CGHeroInstance * getActiveHero ( ) ; //returns hero that can currently cast a spell
public :
CPlayerInterface * curInt ; //current player interface
std : : list < std : : pair < CBattleAnimation * , bool > > pendingAnims ; //currently displayed animations <anim, initialized>
void addNewAnim ( CBattleAnimation * anim ) ; //adds new anim to pendingAnims
ui32 animIDhelper ; //for giving IDs for animations
static CondSh < bool > animsAreDisplayed ; //for waiting with the end of battle for end of anims
CBattleInterface ( const CCreatureSet * army1 , const CCreatureSet * army2 , CGHeroInstance * hero1 , CGHeroInstance * hero2 , const SDL_Rect & myRect , CPlayerInterface * att , CPlayerInterface * defen ) ; //c-tor
~ CBattleInterface ( ) ; //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling
void setPrintCellBorders ( bool set ) ; //if true, cell borders will be printed
void setPrintStackRange ( bool set ) ; //if true,range of active stack will be printed
void setPrintMouseShadow ( bool set ) ; //if true, hex under mouse will be shaded
void setAnimSpeed ( int set ) ; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
int getAnimSpeed ( ) const ; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
2012-06-09 19:45:45 +03:00
std : : vector < CClickableHex * > bfield ; //11 lines, 17 hexes on each
2011-12-14 00:35:28 +03:00
//std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
SDL_Surface * cellBorder , * cellShade ;
CondSh < BattleAction * > * givenCommand ; //data != NULL if we have i.e. moved current unit
bool myTurn ; //if true, interface is active (commands can be ordered)
CBattleResultWindow * resWindow ; //window of end of battle
bool moveStarted ; //if true, the creature that is already moving is going to make its first step
int moveSh ; // sound handler used when moving a unit
//button handle funcs:
void bOptionsf ( ) ;
void bSurrenderf ( ) ;
void bFleef ( ) ;
void reallyFlee ( ) ; //performs fleeing without asking player
void reallySurrender ( ) ; //performs surrendering without asking player
void bAutofightf ( ) ;
void bSpellf ( ) ;
void bWaitf ( ) ;
void bDefencef ( ) ;
void bConsoleUpf ( ) ;
void bConsoleDownf ( ) ;
2012-04-03 02:23:14 +03:00
void bTacticNextStack ( const CStack * current = NULL ) ;
2011-12-14 00:35:28 +03:00
void bEndTacticPhase ( ) ;
//end of button handle funcs
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
void activate ( ) ;
void deactivate ( ) ;
2012-06-02 18:16:54 +03:00
void showAll ( SDL_Surface * to ) ;
2011-12-14 00:35:28 +03:00
void show ( SDL_Surface * to ) ;
void keyPressed ( const SDL_KeyboardEvent & key ) ;
void mouseMoved ( const SDL_MouseMotionEvent & sEvent ) ;
void clickRight ( tribool down , bool previousState ) ;
//call-ins
void startAction ( const BattleAction * action ) ;
void newStack ( const CStack * stack ) ; //new stack appeared on battlefield
void stackRemoved ( int stackID ) ; //stack disappeared from batlefiled
void stackActivated ( const CStack * stack ) ; //active stack has been changed
2011-12-22 16:05:19 +03:00
void stackMoved ( const CStack * stack , std : : vector < BattleHex > destHex , int distance ) ; //stack with id number moved to destHex
2011-12-14 00:35:28 +03:00
void waitForAnims ( ) ;
2011-12-22 16:05:19 +03:00
void stacksAreAttacked ( std : : vector < StackAttackedInfo > attackedInfos ) ; //called when a certain amount of stacks has been attacked
void stackAttacking ( const CStack * attacker , BattleHex dest , const CStack * attacked , bool shooting ) ; //called when stack with id ID is attacking something on hex dest
2011-12-14 00:35:28 +03:00
void newRoundFirst ( int round ) ;
void newRound ( int number ) ; //caled when round is ended; number is the number of round
void hexLclicked ( int whichOne ) ; //hex only call-in
void stackIsCatapulting ( const CatapultAttack & ca ) ; //called when a stack is attacking walls
void battleFinished ( const BattleResult & br ) ; //called when battle is finished - battleresult window should be printed
const BattleResult * bresult ; //result of a battle; if non-zero then display when all animations end
void displayBattleFinished ( ) ; //displays battle result
void spellCast ( const BattleSpellCast * sc ) ; //called when a hero casts a spell
void battleStacksEffectsSet ( const SetStackEffect & sse ) ; //called when a specific effect is set to stacks
void castThisSpell ( int spellID ) ; //called when player has chosen a spell from spellbook
void displayEffect ( ui32 effect , int destTile ) ; //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
void battleTriggerEffect ( const BattleTriggerEffect & bte ) ;
2012-03-31 00:36:07 +03:00
void setBattleCursor ( const int myNumber ) ; //really complex and messy, sets attackingHex
2011-12-14 00:35:28 +03:00
void endAction ( const BattleAction * action ) ;
void hideQueue ( ) ;
void showQueue ( ) ;
2012-04-16 20:12:39 +03:00
PossibleActions selectionTypeByPositiveness ( const CSpell & spell ) ;
2012-04-23 22:56:37 +03:00
Rect hexPosition ( BattleHex hex ) const ;
2012-02-17 00:19:07 +03:00
2012-03-31 00:36:07 +03:00
void handleHex ( BattleHex myNumber , int eventType ) ;
2012-04-16 20:12:39 +03:00
bool isCastingPossibleHere ( const CStack * sactive , const CStack * shere , BattleHex myNumber ) ;
2012-04-18 12:01:08 +03:00
bool canStackMoveHere ( const CStack * sactive , BattleHex MyNumber ) ; //TODO: move to BattleState / callback
2012-03-31 00:36:07 +03:00
BattleHex fromWhichHexAttack ( BattleHex myNumber ) ;
2012-05-05 00:16:39 +03:00
void obstaclePlaced ( const CObstacleInstance & oi ) ;
2012-08-26 12:07:48 +03:00
const CGHeroInstance * currentHero ( ) const ;
InfoAboutHero enemyHero ( ) const ;
2011-12-14 00:35:28 +03:00
friend class CPlayerInterface ;
2011-12-22 16:05:19 +03:00
friend class CAdventureMapButton ;
2011-12-14 00:35:28 +03:00
friend class CInGameConsole ;
friend class CBattleResultWindow ;
friend class CBattleHero ;
friend class CSpellEffectAnimation ;
friend class CBattleStackAnimation ;
friend class CReverseAnimation ;
friend class CDefenceAnimation ;
friend class CMovementAnimation ;
friend class CMovementStartAnimation ;
friend class CAttackAnimation ;
friend class CMeleeAttackAnimation ;
friend class CShootingAnimation ;
2011-12-17 21:59:59 +03:00
friend class CClickableHex ;
2011-12-14 00:35:28 +03:00
} ;