From f794644c2a64925a1f4574682ba281f1c1cbaa8d Mon Sep 17 00:00:00 2001 From: mateuszb Date: Fri, 3 Apr 2009 15:55:26 +0000 Subject: [PATCH] * basic in-game console --- CAdvmapInterface.cpp | 8 +- CBattleInterface.cpp | 12 +- CBattleInterface.h | 574 ++++++++++++++++++++++--------------------- CMT.cpp | 1 + CPlayerInterface.cpp | 161 +++++++++++- CPlayerInterface.h | 30 ++- SDL_Extensions.cpp | 28 +++ SDL_Extensions.h | 1 + 8 files changed, 515 insertions(+), 300 deletions(-) diff --git a/CAdvmapInterface.cpp b/CAdvmapInterface.cpp index deba7baff..1de077656 100644 --- a/CAdvmapInterface.cpp +++ b/CAdvmapInterface.cpp @@ -1387,6 +1387,8 @@ void CAdvMapInt::activate() terrain.activate(); KeyInterested::activate(); show(); + + LOCPLINT->cingconsole->activate(); } void CAdvMapInt::deactivate() { @@ -1397,6 +1399,8 @@ void CAdvMapInt::deactivate() } KeyInterested::deactivate(); hide(); + + LOCPLINT->cingconsole->deactivate(); } void CAdvMapInt::show(SDL_Surface *to) { @@ -1424,6 +1428,7 @@ void CAdvMapInt::show(SDL_Surface *to) statusbar.show(); infoBar.draw(); + LOCPLINT->cingconsole->show(); } void CAdvMapInt::hide() { @@ -1491,7 +1496,8 @@ void CAdvMapInt::update() terrain.show(); for(int i=0;i<4;i++) blitAt(gems[i]->ourImages[LOCPLINT->playerID].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i]); - updateScreen=false; + updateScreen=false; + LOCPLINT->cingconsole->show(); } if (updateMinimap) { diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index e9a98ca2c..d8b145ea9 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -350,6 +350,8 @@ void CBattleInterface::activate() attackingHero->activate(); if(defendingHero) defendingHero->activate(); + + LOCPLINT->cingconsole->activate(); } void CBattleInterface::deactivate() @@ -373,6 +375,8 @@ void CBattleInterface::deactivate() attackingHero->deactivate(); if(defendingHero) defendingHero->deactivate(); + + LOCPLINT->cingconsole->deactivate(); } void CBattleInterface::show(SDL_Surface * to) @@ -655,6 +659,8 @@ void CBattleInterface::show(SDL_Surface * to) resWindow->show(to); } + //showing in-gmae console + LOCPLINT->cingconsole->show(); //printing border around interface if(screen->w != 800 || screen->h !=600) @@ -2454,7 +2460,11 @@ CBattleConsole::~CBattleConsole() void CBattleConsole::show(SDL_Surface * to) { - if(alterTxt.size()) + if(ingcAlter.size()) + { + CSDL_Ext::printAtMiddleWB(ingcAlter, pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to); + } + else if(alterTxt.size()) { CSDL_Ext::printAtMiddleWB(alterTxt, pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to); } diff --git a/CBattleInterface.h b/CBattleInterface.h index 0844091bf..1887c093d 100644 --- a/CBattleInterface.h +++ b/CBattleInterface.h @@ -1,287 +1,289 @@ -#ifndef __CBATTLEINTERFACE_H__ -#define __CBATTLEINTERFACE_H__ - -#include "global.h" -#include "CPlayerInterface.h" -#include - -class CCreatureSet; -class CGHeroInstance; -class CDefHandler; -class CStack; -class CCallback; -class AdventureMapButton; -class CHighlightableButton; -class CHighlightableButtonsGroup; -struct BattleResult; -struct SpellCasted; -template struct CondSh; - -class CBattleInterface; - -class CBattleHero : public IShowable, public ClickableL -{ -public: - bool flip; //false if it's attacking hero, true otherwise - CDefHandler * dh, *flag; //animation and flag - const CGHeroInstance * myHero; //this animation's hero instance - const CBattleInterface * myOwner; //battle interface to which this animation is assigned - int phase; //stage of animation - int nextPhase; //stage of animation to be set after current phase is fully displayed - int image; //frame of animation - unsigned char flagAnim, flagAnimCount; //for flag animation - void show(SDL_Surface * to); //prints next frame of animation to to - void activate(); - void deactivate(); - void setPhase(int newPhase); //sets phase of hero animation - void clickLeft(boost::logic::tribool down); //call-in - CBattleHero(const std::string & defName, int phaseG, int imageG, bool filpG, unsigned char player, const CGHeroInstance * hero, const CBattleInterface * owner); //c-tor - ~CBattleHero(); //d-tor -}; - -class CBattleHex : public Hoverable, public MotionInterested, public ClickableL, public ClickableR -{ -private: - bool setAlterText; //if true, this hex has set alternative text in console and will clean it -public: - unsigned int myNumber; //number of hex in commonly used format - bool accesible; //if true, this hex is accessible for units - //CStack * ourStack; - bool hovered, strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering) - CBattleInterface * myInterface; //interface that owns me - static std::pair getXYUnitAnim(const int & hexNum, const bool & attacker, const CCreature * creature); //returns (x, y) of left top corner of animation - //for user interactions - void hover (bool on); - void activate(); - void deactivate(); - void mouseMoved (const SDL_MouseMotionEvent & sEvent); - void clickLeft(boost::logic::tribool down); - void clickRight(boost::logic::tribool down); - CBattleHex(); -}; - -class CBattleObstacle -{ - std::vector lockedHexes; -}; - -class CBattleConsole : public IShowable, public CIntObject -{ -private: - std::vector< std::string > texts; //a place where texts are stored - int lastShown; //last shown line of text -public: - std::string alterTxt; //if it's not empty, this text is displayed - int whoSetAlter; //who set alter text; 0 - battle interface or none, 1 - button - CBattleConsole(); //c-tor - ~CBattleConsole(); //d-tor - void show(SDL_Surface * to = 0); - bool addText(const std::string & text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters) - void eraseText(unsigned int pos); //erases added text at position pos - void changeTextAt(const std::string & text, unsigned int pos); //if we have more than pos texts, pos-th is changed to given one - void scrollUp(unsigned int by = 1); //scrolls console up by 'by' positions - void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions -}; - -class CBattleReslutWindow : public IShowable, public CIntObject, public IActivable -{ -private: - SDL_Surface * background; - AdventureMapButton * exit; -public: - CBattleReslutWindow(const BattleResult & br, const SDL_Rect & pos, const CBattleInterface * owner); //c-tor - ~CBattleReslutWindow(); //d-tor - - void bExitf(); //exit button callback - - void activate(); - void deactivate(); - void show(SDL_Surface * to = 0); -}; - -class CBattleOptionsWindow : public IShowable, public CIntObject, public IActivable -{ -private: - CBattleInterface * myInt; - SDL_Surface * background; - AdventureMapButton * setToDefault, * exit; - CHighlightableButton * viewGrid, * movementShadow, * mouseShadow; - CHighlightableButtonsGroup * animSpeeds; -public: - CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface * owner); //c-tor - ~CBattleOptionsWindow(); //d-tor - - void bDefaultf(); //dafault button callback - void bExitf(); //exit button callback - - void activate(); - void deactivate(); - void show(SDL_Surface * to = 0); -}; - -struct BattleSettings -{ - BattleSettings() - { - printCellBorders = true; - printStackRange = true; - animSpeed = 2; - printMouseShadow = true; - } - bool printCellBorders; //if true, cell borders will be printed - bool printStackRange; //if true,range of active stack will be printed - int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest - bool printMouseShadow; //if true, hex under mouse will be shaded - +#ifndef __CBATTLEINTERFACE_H__ +#define __CBATTLEINTERFACE_H__ - template void serialize(Handler &h, const int version) - { - h & printCellBorders & printStackRange & printMouseShadow; - } -}; - -class CBattleInterface : public CMainInterface, public MotionInterested, public KeyInterested -{ -private: - SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes; - AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell, - * bWait, * bDefence, * bConsoleUp, * bConsoleDown; - CBattleConsole * console; - CBattleHero * attackingHero, * defendingHero; //fighting heroes - CCreatureSet * army1, * army2; //fighting armies - 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 creaures (creatureID, defhandler) - std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield - std::map< int, bool > creDir; // - std::map< int, int > spellToEffect; //which effect should be played when different spells are casted (spellID, effectID) - unsigned char animCount; - int activeStack; //number of active stack; -1 - no one - int mouseHoveredStack; //stack hovered by mouse; if -1 -> none - std::vector shadedHexes; //hexes available for active stack - 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) - float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group - std::map standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves' - - bool spellDestSelectMode; //if true, player is choosing destination for his spell - int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location - BattleAction * spellToCast; //spell for which player is choosing destination - - class CAttHelper - { - public: - int ID; //attacking stack - int IDby; //attacked stack - int dest; //atacked hex - int frame, maxframe; //frame of animation, number of frames of animation - int hitCount; //for delaying animation - bool reversing; - int posShiftDueToDist; - bool shooting; - int shootingGroup; //if shooting is true, print this animation group - } * attackingInfo; - void attackingShowHelper(); - void redrawBackgroundWithHexes(int activeStack); - void printConsoleAttacked(int ID, int dmg, int killed, int IDby); - - struct SProjectileInfo - { - int x, y; //position on the screen - int dx, dy; //change in position in one step - int step, lastStep; //to know when finish showing this projectile - int creID; //ID of creature that shot this projectile - int frameNum; //frame to display form projectile animation - bool spin; //if true, frameNum will be increased - int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit) - bool reverse; //if true, projectile will be flipped by vertical asix - }; - std::list projectiles; //projectiles flying on battlefield - void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield - void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1); - bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles - - struct SBattleEffect - { - int x, y; //position on the screen - int frame, maxFrame; - CDefHandler * anim; //animation to display - }; - std::list battleEffects; //different animations to display on the screen like spell effects -public: - CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect); //c-tor - ~CBattleInterface(); //d-tor - - //std::vector timeinterested; //animation handling - static BattleSettings settings; - 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 - - CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each - std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield - SDL_Surface * cellBorder, * cellShade; - CondSh *givenCommand; //data != NULL if we have i.e. moved current unit - bool myTurn; //if true, interface is active (commands can be ordered - CBattleReslutWindow * resWindow; //window of end of battle - bool showStackQueue; //if true, queue of stacks will be shown - - bool moveStarted; //if true, the creature that is already moving is going to make its first step - - //button handle funcs: - void bOptionsf(); - void bSurrenderf(); - void bFleef(); - void reallyFlee(); //performs fleeing without asking player - void bAutofightf(); - void bSpellf(); - void bWaitf(); - void bDefencef(); - void bConsoleUpf(); - void bConsoleDownf(); - //end of button handle funcs - //napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem - void activate(); - void deactivate(); - void show(SDL_Surface * to = NULL); - void keyPressed(const SDL_KeyboardEvent & key); - void mouseMoved(const SDL_MouseMotionEvent &sEvent); - bool reverseCreature(int number, int hex, bool wideTrick = false); //reverses animation of given creature playing animation of reversing - void handleStartMoving(int number); //animation of starting move; some units don't have this animation (ie. halberdier) - - struct SStackAttackedInfo - { - int ID; //id of attacked stack - int dmg; //damage dealt - int amountKilled; //how many creatures in stack has been killed - int IDby; //ID of attacking stack - bool byShooting; //if true, stack has been attacked by shooting - bool killed; //if true, stack has been killed - }; - - //call-ins - void newStack(CStack stack); //new stack appeared on battlefield - void stackRemoved(CStack stack); //stack disappeared from batlefiled - //void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //stack has been killed (but corpses remain) - void stackActivated(int number); //active stack has been changed - void stackMoved(int number, int destHex, bool endMoving, int distance); //stack with id number moved to destHex - void stacksAreAttacked(std::vector attackedInfos); //called when a certain amount of stacks has been attacked - void stackAttacking(int ID, int dest); //called when stack with id ID is attacking something on hex dest - void newRound(int number); //caled when round is ended; number is the number of round - void hexLclicked(int whichOne); //hex only call-in - void stackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest - void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed - void spellCasted(SpellCasted * 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 - - friend class CBattleHex; - friend class CBattleReslutWindow; - friend class CPlayerInterface; - friend class AdventureMapButton; -}; - -#endif // __CBATTLEINTERFACE_H__ +#include "global.h" +#include "CPlayerInterface.h" +#include + +class CCreatureSet; +class CGHeroInstance; +class CDefHandler; +class CStack; +class CCallback; +class AdventureMapButton; +class CHighlightableButton; +class CHighlightableButtonsGroup; +struct BattleResult; +struct SpellCasted; +template struct CondSh; + +class CBattleInterface; + +class CBattleHero : public IShowable, public ClickableL +{ +public: + bool flip; //false if it's attacking hero, true otherwise + CDefHandler * dh, *flag; //animation and flag + const CGHeroInstance * myHero; //this animation's hero instance + const CBattleInterface * myOwner; //battle interface to which this animation is assigned + int phase; //stage of animation + int nextPhase; //stage of animation to be set after current phase is fully displayed + int image; //frame of animation + unsigned char flagAnim, flagAnimCount; //for flag animation + void show(SDL_Surface * to); //prints next frame of animation to to + void activate(); + void deactivate(); + void setPhase(int newPhase); //sets phase of hero animation + void clickLeft(boost::logic::tribool down); //call-in + CBattleHero(const std::string & defName, int phaseG, int imageG, bool filpG, unsigned char player, const CGHeroInstance * hero, const CBattleInterface * owner); //c-tor + ~CBattleHero(); //d-tor +}; + +class CBattleHex : public Hoverable, public MotionInterested, public ClickableL, public ClickableR +{ +private: + bool setAlterText; //if true, this hex has set alternative text in console and will clean it +public: + unsigned int myNumber; //number of hex in commonly used format + bool accesible; //if true, this hex is accessible for units + //CStack * ourStack; + bool hovered, strictHovered; //for determining if hex is hovered by mouse (this is different problem than hex's graphic hovering) + CBattleInterface * myInterface; //interface that owns me + static std::pair getXYUnitAnim(const int & hexNum, const bool & attacker, const CCreature * creature); //returns (x, y) of left top corner of animation + //for user interactions + void hover (bool on); + void activate(); + void deactivate(); + void mouseMoved (const SDL_MouseMotionEvent & sEvent); + void clickLeft(boost::logic::tribool down); + void clickRight(boost::logic::tribool down); + CBattleHex(); +}; + +class CBattleObstacle +{ + std::vector lockedHexes; +}; + +class CBattleConsole : public IShowable, public CIntObject +{ +private: + std::vector< std::string > texts; //a place where texts are stored + int lastShown; //last shown line of text +public: + std::string alterTxt; //if it's not empty, this text is displayed + std::string ingcAlter; //alternative text set by in-game console - very important! + int whoSetAlter; //who set alter text; 0 - battle interface or none, 1 - button + CBattleConsole(); //c-tor + ~CBattleConsole(); //d-tor + void show(SDL_Surface * to = 0); + bool addText(const std::string & text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters) + void eraseText(unsigned int pos); //erases added text at position pos + void changeTextAt(const std::string & text, unsigned int pos); //if we have more than pos texts, pos-th is changed to given one + void scrollUp(unsigned int by = 1); //scrolls console up by 'by' positions + void scrollDown(unsigned int by = 1); //scrolls console up by 'by' positions +}; + +class CBattleReslutWindow : public IShowable, public CIntObject, public IActivable +{ +private: + SDL_Surface * background; + AdventureMapButton * exit; +public: + CBattleReslutWindow(const BattleResult & br, const SDL_Rect & pos, const CBattleInterface * owner); //c-tor + ~CBattleReslutWindow(); //d-tor + + void bExitf(); //exit button callback + + void activate(); + void deactivate(); + void show(SDL_Surface * to = 0); +}; + +class CBattleOptionsWindow : public IShowable, public CIntObject, public IActivable +{ +private: + CBattleInterface * myInt; + SDL_Surface * background; + AdventureMapButton * setToDefault, * exit; + CHighlightableButton * viewGrid, * movementShadow, * mouseShadow; + CHighlightableButtonsGroup * animSpeeds; +public: + CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface * owner); //c-tor + ~CBattleOptionsWindow(); //d-tor + + void bDefaultf(); //dafault button callback + void bExitf(); //exit button callback + + void activate(); + void deactivate(); + void show(SDL_Surface * to = 0); +}; + +struct BattleSettings +{ + BattleSettings() + { + printCellBorders = true; + printStackRange = true; + animSpeed = 2; + printMouseShadow = true; + } + bool printCellBorders; //if true, cell borders will be printed + bool printStackRange; //if true,range of active stack will be printed + int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest + bool printMouseShadow; //if true, hex under mouse will be shaded + + + template void serialize(Handler &h, const int version) + { + h & printCellBorders & printStackRange & printMouseShadow; + } +}; + +class CBattleInterface : public CMainInterface, public MotionInterested, public KeyInterested +{ +private: + SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes; + AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell, + * bWait, * bDefence, * bConsoleUp, * bConsoleDown; + CBattleConsole * console; + CBattleHero * attackingHero, * defendingHero; //fighting heroes + CCreatureSet * army1, * army2; //fighting armies + 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 creaures (creatureID, defhandler) + std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield + std::map< int, bool > creDir; // + std::map< int, int > spellToEffect; //which effect should be played when different spells are casted (spellID, effectID) + unsigned char animCount; + int activeStack; //number of active stack; -1 - no one + int mouseHoveredStack; //stack hovered by mouse; if -1 -> none + std::vector shadedHexes; //hexes available for active stack + 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) + float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group + std::map standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves' + + bool spellDestSelectMode; //if true, player is choosing destination for his spell + int spellSelMode; //0 - any location, 1 - any firendly creature, 2 - any hostile creature, 3 - any creature, 4 - obstacle, -1 - no location + BattleAction * spellToCast; //spell for which player is choosing destination + + class CAttHelper + { + public: + int ID; //attacking stack + int IDby; //attacked stack + int dest; //atacked hex + int frame, maxframe; //frame of animation, number of frames of animation + int hitCount; //for delaying animation + bool reversing; + int posShiftDueToDist; + bool shooting; + int shootingGroup; //if shooting is true, print this animation group + } * attackingInfo; + void attackingShowHelper(); + void redrawBackgroundWithHexes(int activeStack); + void printConsoleAttacked(int ID, int dmg, int killed, int IDby); + + struct SProjectileInfo + { + int x, y; //position on the screen + int dx, dy; //change in position in one step + int step, lastStep; //to know when finish showing this projectile + int creID; //ID of creature that shot this projectile + int frameNum; //frame to display form projectile animation + bool spin; //if true, frameNum will be increased + int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit) + bool reverse; //if true, projectile will be flipped by vertical asix + }; + std::list projectiles; //projectiles flying on battlefield + void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield + void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1); + bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles + + struct SBattleEffect + { + int x, y; //position on the screen + int frame, maxFrame; + CDefHandler * anim; //animation to display + }; + std::list battleEffects; //different animations to display on the screen like spell effects +public: + CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect); //c-tor + ~CBattleInterface(); //d-tor + + //std::vector timeinterested; //animation handling + static BattleSettings settings; + 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 + + CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each + std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield + SDL_Surface * cellBorder, * cellShade; + CondSh *givenCommand; //data != NULL if we have i.e. moved current unit + bool myTurn; //if true, interface is active (commands can be ordered + CBattleReslutWindow * resWindow; //window of end of battle + bool showStackQueue; //if true, queue of stacks will be shown + + bool moveStarted; //if true, the creature that is already moving is going to make its first step + + //button handle funcs: + void bOptionsf(); + void bSurrenderf(); + void bFleef(); + void reallyFlee(); //performs fleeing without asking player + void bAutofightf(); + void bSpellf(); + void bWaitf(); + void bDefencef(); + void bConsoleUpf(); + void bConsoleDownf(); + //end of button handle funcs + //napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem + void activate(); + void deactivate(); + void show(SDL_Surface * to = NULL); + void keyPressed(const SDL_KeyboardEvent & key); + void mouseMoved(const SDL_MouseMotionEvent &sEvent); + bool reverseCreature(int number, int hex, bool wideTrick = false); //reverses animation of given creature playing animation of reversing + void handleStartMoving(int number); //animation of starting move; some units don't have this animation (ie. halberdier) + + struct SStackAttackedInfo + { + int ID; //id of attacked stack + int dmg; //damage dealt + int amountKilled; //how many creatures in stack has been killed + int IDby; //ID of attacking stack + bool byShooting; //if true, stack has been attacked by shooting + bool killed; //if true, stack has been killed + }; + + //call-ins + void newStack(CStack stack); //new stack appeared on battlefield + void stackRemoved(CStack stack); //stack disappeared from batlefiled + //void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //stack has been killed (but corpses remain) + void stackActivated(int number); //active stack has been changed + void stackMoved(int number, int destHex, bool endMoving, int distance); //stack with id number moved to destHex + void stacksAreAttacked(std::vector attackedInfos); //called when a certain amount of stacks has been attacked + void stackAttacking(int ID, int dest); //called when stack with id ID is attacking something on hex dest + void newRound(int number); //caled when round is ended; number is the number of round + void hexLclicked(int whichOne); //hex only call-in + void stackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest + void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed + void spellCasted(SpellCasted * 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 + + friend class CBattleHex; + friend class CBattleReslutWindow; + friend class CPlayerInterface; + friend class AdventureMapButton; + friend class CInGameConsole; +}; + +#endif // __CBATTLEINTERFACE_H__ diff --git a/CMT.cpp b/CMT.cpp index 9a8cad519..89e97db4e 100644 --- a/CMT.cpp +++ b/CMT.cpp @@ -79,6 +79,7 @@ int main(int argc, char** argv) CGameInfo * cgi = CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler itp.) if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO)==0) { + SDL_EnableUNICODE(1); screen = SDL_SetVideoMode(800,600,conf.cc.bpp,SDL_SWSURFACE|SDL_DOUBLEBUF|(conf.cc.fullscreen?SDL_FULLSCREEN:0)); //initializing important global surface tlog0 <<"\tInitializing screen: "<::iterator i=graphics->heroWins.begin(); i!= graphics->heroWins.end(); i++) SDL_FreeSurface(i->second); @@ -1911,9 +1913,19 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent) key.keysym.sym = (SDLKey)SDLK_RETURN; } + bool keysCaptured = false; + for(std::list::iterator i=keyinterested.begin(); i != keyinterested.end();i++) + { + if((*i)->captureAllKeys) + { + keysCaptured = true; + break; + } + } + std::list miCopy = keyinterested; for(std::list::iterator i=miCopy.begin(); i != miCopy.end();i++) - if(vstd::contains(keyinterested,*i)) + if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureAllKeys)) (**i).keyPressed(key); } else if(sEvent->type==SDL_MOUSEMOTION) @@ -2605,16 +2617,19 @@ CStatusBar::~CStatusBar() } void CStatusBar::clear() { - current=""; - SDL_Rect pom = genRect(pos.h,pos.w,pos.x,pos.y); - SDL_BlitSurface(bg,&genRect(pos.h,pos.w,0,0),screen,&pom); + if(LOCPLINT->cingconsole->enteredText == "") //for appropriate support for in-game console + { + current=""; + show(); + } } void CStatusBar::print(const std::string & text) { - current=text; - SDL_Rect pom = genRect(pos.h,pos.w,pos.x,pos.y); - SDL_BlitSurface(bg,&genRect(pos.h,pos.w,0,0),screen,&pom); - printAtMiddle(current,middlex,middley,GEOR13,zwykly); + if(LOCPLINT->cingconsole->enteredText == "" || text == LOCPLINT->cingconsole->enteredText) //for appropriate support for in-game console + { + current=text; + show(); + } } void CStatusBar::show() { @@ -4570,4 +4585,132 @@ void CTavernWindow::HeroPortrait::hover( bool on ) LOCPLINT->statusbar->print(hoverName); else LOCPLINT->statusbar->clear(); -} \ No newline at end of file +} + +void CInGameConsole::activate() +{ + KeyInterested::activate(); +} + +void CInGameConsole::deactivate() +{ + KeyInterested::deactivate(); +} + +void CInGameConsole::show(SDL_Surface * to) +{ + int number = 0; + + std::vector >::iterator> toDel; + + for(std::list< std::pair< std::string, int > >::iterator it = texts.begin(); it != texts.end(); ++it, ++number) + { + SDL_Color green = {0,0xff,0,0}; + CSDL_Ext::printAtWR(it->first, 50, conf.cc.resy - texts.size() * 30 - 80 + number*30, GEOR16, green); + if(SDL_GetTicks() - it->second > defaultTimeout) + { + toDel.push_back(it); + } + } + + for(int it=0; it 0) + { + if(captureAllKeys) + { + captureAllKeys = false; + endEnteringText(true); + } + } + break; + } + default: + { + if(enteredText.size() > 0) + { + if( key.keysym.unicode < 0x80 && key.keysym.unicode > 0 ) + { + enteredText[enteredText.size()-1] = (char)key.keysym.unicode; + enteredText += "_"; + if(LOCPLINT->curint == LOCPLINT->adventureInt) + { + LOCPLINT->statusbar->print(enteredText); + } + else if(LOCPLINT->curint == LOCPLINT->battleInt) + { + LOCPLINT->battleInt->console->ingcAlter = enteredText; + } + } + } + break; + } + } + } +} + +void CInGameConsole::startEnteringText() +{ + enteredText = "_"; + if(LOCPLINT->curint == LOCPLINT->adventureInt) + { + LOCPLINT->statusbar->print(enteredText); + } + else if(LOCPLINT->curint == LOCPLINT->battleInt) + { + LOCPLINT->battleInt->console->ingcAlter = enteredText; + } +} + +void CInGameConsole::endEnteringText(bool printEnteredText) +{ + if(printEnteredText) + { + texts.push_back(std::make_pair(enteredText.substr(0, enteredText.size()-1), SDL_GetTicks())); + if(texts.size() > maxDisplayedTexts) + { + texts.pop_front(); + } + } + enteredText = ""; + if(LOCPLINT->curint == LOCPLINT->adventureInt) + { + LOCPLINT->statusbar->clear(); + } + else if(LOCPLINT->curint == LOCPLINT->battleInt) + { + LOCPLINT->battleInt->console->ingcAlter = ""; + } + +} + +CInGameConsole::CInGameConsole() : defaultTimeout(10000), maxDisplayedTexts(10) +{ +} + diff --git a/CPlayerInterface.h b/CPlayerInterface.h index 3eda80dd7..9bac47b50 100644 --- a/CPlayerInterface.h +++ b/CPlayerInterface.h @@ -40,6 +40,7 @@ class CGObjectInstance; class CSlider; struct UpgradeInfo; template struct CondSh; +class CInGameConsole; namespace boost { @@ -290,7 +291,7 @@ public: class Hoverable : public virtual CIntObject { public: - Hoverable(){hovered=false;} //c-tor + Hoverable() : hovered(false){} //c-tor virtual ~Hoverable();//{}; //d-tor bool hovered; //for determining if object is hovered virtual void hover (bool on)=0; @@ -298,8 +299,10 @@ public: virtual void deactivate()=0; }; class KeyInterested : public virtual CIntObject -{ +{ public: + bool captureAllKeys; //if true, only this object should get info about pressed keys + KeyInterested(): captureAllKeys(false){} virtual ~KeyInterested();//{}; virtual void keyPressed(const SDL_KeyboardEvent & key)=0; virtual void activate()=0; @@ -335,6 +338,7 @@ public: virtual void activate(); virtual void deactivate(); }; + class CInfoWindow : public CSimpleWindow //text + comp. + ok button { //window able to delete its components when closed public: @@ -506,6 +510,7 @@ public: CAdvMapInt * adventureInt; CCastleInterface * castleInt; CBattleInterface * battleInt; + CInGameConsole * cingconsole; FPSmanager * mainFPSmng; IStatusBar *statusbar; //advmap statusbar; should it be used by other windows with statusbar? //to commucate with engine @@ -546,7 +551,7 @@ public: void yourTurn(); void availableCreaturesChanged(const CGTownInstance *town); void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain);//if gain hero received bonus, else he lost it - void serialize(COSer &h, const int version); //saving + void serialize(COSer &h, const int version); //saving void serialize(CISer &h, const int version); //loading //for battles @@ -897,6 +902,25 @@ public: void show(SDL_Surface * to = NULL); }; +class CInGameConsole : public IShowActivable, public KeyInterested +{ +private: + std::list< std::pair< std::string, int > > texts; // + int defaultTimeout; //timeout for new texts (in ms) + int maxDisplayedTexts; //hiw many texts can be displayed simultaneously +public: + std::string enteredText; + void activate(); + void deactivate(); + void show(SDL_Surface * to = NULL); + void keyPressed (const SDL_KeyboardEvent & key); //call-in + + void startEnteringText(); + void endEnteringText(bool printEnteredText); + + CInGameConsole(); //c-tor +}; + extern CPlayerInterface * LOCPLINT; diff --git a/SDL_Extensions.cpp b/SDL_Extensions.cpp index 091d80e96..c2389dcd2 100644 --- a/SDL_Extensions.cpp +++ b/SDL_Extensions.cpp @@ -139,6 +139,34 @@ void CSDL_Ext::printAtMiddle(const std::string & text, int x, int y, TTF_Font * SDL_UpdateRect(dst,x-(temp->w/2),y-(temp->h/2),temp->w,temp->h); SDL_FreeSurface(temp); } +void CSDL_Ext::printAtWR(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, unsigned char quality) +{ + if (text.length()==0) + return; + SDL_Surface * temp; + switch (quality) + { + case 0: + temp = TTF_RenderText_Solid(font,text.c_str(),kolor); + break; + case 1: + SDL_Color tem; + tem.b = 0xff-kolor.b; + tem.g = 0xff-kolor.g; + tem.r = 0xff-kolor.r; + tem.unused = 0xff-kolor.unused; + temp = TTF_RenderText_Shaded(font,text.c_str(),kolor,tem); + break; + case 2: + temp = TTF_RenderText_Blended(font,text.c_str(),kolor); + break; + default: + temp = TTF_RenderText_Blended(font,text.c_str(),kolor); + break; + } + SDL_BlitSurface(temp,NULL,dst,&genRect(temp->h,temp->w,x,y)); + SDL_FreeSurface(temp); +} void CSDL_Ext::printAt(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor, SDL_Surface * dst, unsigned char quality) { if (text.length()==0) diff --git a/SDL_Extensions.h b/SDL_Extensions.h index 90cf36008..ea831e489 100644 --- a/SDL_Extensions.h +++ b/SDL_Extensions.h @@ -67,6 +67,7 @@ namespace CSDL_Ext void printAtMiddleWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor=tytulowy, SDL_Surface * dst=screen); void printAtWB(const std::string & text, int x, int y, TTF_Font * font, int charpr, SDL_Color kolor=tytulowy, SDL_Surface * dst=screen); void printAt(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor=tytulowy, SDL_Surface * dst=screen, unsigned char quality = 2); // quality: 0 - lowest, 1 - medium, 2 - highest + void printAtWR(const std::string & text, int x, int y, TTF_Font * font, SDL_Color kolor=tytulowy, SDL_Surface * dst=screen, unsigned char quality = 2); // quality: 0 - lowest, 1 - medium, 2 - highest void update(SDL_Surface * what = screen); //updates whole surface (default - main screen) void drawBorder(SDL_Surface * sur, int x, int y, int w, int h, int3 color); void setPlayerColor(SDL_Surface * sur, unsigned char player); //sets correct color of flags; -1 for neutral