diff --git a/client/battle/CBattleInterface.cpp b/client/battle/CBattleInterface.cpp index add4babdc..794807bcf 100644 --- a/client/battle/CBattleInterface.cpp +++ b/client/battle/CBattleInterface.cpp @@ -23,6 +23,7 @@ #include "../CPlayerInterface.h" #include "../CVideoHandler.h" #include "../Graphics.h" +#include "../gui/CAnimation.h" #include "../gui/CCursorHandler.h" #include "../gui/CGuiHandler.h" #include "../gui/SDL_Extensions.h" @@ -263,7 +264,10 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet battleImage = hero1->type->heroClass->imageBattleMale; attackingHero = new CBattleHero(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, this); - attackingHero->pos = genRect(attackingHero->dh->ourImages[0].bitmap->h, attackingHero->dh->ourImages[0].bitmap->w, pos.x - 43, pos.y - 19); + + IImage * img = attackingHero->animation->getImage(0, 0, true); + if(img) + attackingHero->pos = genRect(img->height(), img->width(), pos.x - 43, pos.y - 19); } else { @@ -278,7 +282,10 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet battleImage = hero2->type->heroClass->imageBattleMale; defendingHero = new CBattleHero(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, this); - defendingHero->pos = genRect(defendingHero->dh->ourImages[0].bitmap->h, defendingHero->dh->ourImages[0].bitmap->w, pos.x + 693, pos.y - 19); + + IImage * img = defendingHero->animation->getImage(0, 0, true); + if(img) + defendingHero->pos = genRect(img->height(), img->width(), pos.x + 693, pos.y - 19); } else { diff --git a/client/battle/CBattleInterfaceClasses.cpp b/client/battle/CBattleInterfaceClasses.cpp index 688991469..2853482c0 100644 --- a/client/battle/CBattleInterfaceClasses.cpp +++ b/client/battle/CBattleInterfaceClasses.cpp @@ -13,13 +13,13 @@ #include "CBattleInterface.h" #include "../CBitmapHandler.h" -#include "../CDefHandler.h" #include "../CGameInfo.h" #include "../CMessage.h" #include "../CMusicHandler.h" #include "../CPlayerInterface.h" #include "../CVideoHandler.h" #include "../Graphics.h" +#include "../gui/CAnimation.h" #include "../gui/CCursorHandler.h" #include "../gui/CGuiHandler.h" #include "../gui/SDL_Extensions.h" @@ -129,13 +129,18 @@ CBattleConsole::CBattleConsole() : lastShown(-1), alterTxt(""), whoSetAlter(0) void CBattleHero::show(SDL_Surface * to) { + IImage * flagFrame = flagAnimation->getImage(flagAnim, 0, true); + + if(!flagFrame) + return; + //animation of flag SDL_Rect temp_rect; if(flip) { temp_rect = genRect( - flag->ourImages[flagAnim].bitmap->h, - flag->ourImages[flagAnim].bitmap->w, + flagFrame->height(), + flagFrame->width(), pos.x + 61, pos.y + 39); @@ -143,28 +148,30 @@ void CBattleHero::show(SDL_Surface * to) else { temp_rect = genRect( - flag->ourImages[flagAnim].bitmap->h, - flag->ourImages[flagAnim].bitmap->w, + flagFrame->height(), + flagFrame->width(), pos.x + 72, pos.y + 39); } - CSDL_Ext::blit8bppAlphaTo24bpp( - flag->ourImages[flagAnim].bitmap, - nullptr, - screen, - &temp_rect); + + flagFrame->draw(screen, &temp_rect, nullptr); //FIXME: why screen? //animation of hero SDL_Rect rect = pos; - CSDL_Ext::blit8bppAlphaTo24bpp(dh->ourImages[currentFrame].bitmap, nullptr, to, &rect); - if ( ++animCount == 4 ) + IImage * heroFrame = animation->getImage(currentFrame, phase, true); + if(!heroFrame) + return; + + heroFrame->draw(to, &rect, nullptr); + + if(++animCount >= 4) { animCount = 0; - if ( ++flagAnim >= flag->ourImages.size()) + if(++flagAnim >= flagAnimation->size(0)) flagAnim = 0; - if ( ++currentFrame >= lastFrame) + if(++currentFrame >= lastFrame) switchToNextPhase(); } } @@ -190,7 +197,13 @@ void CBattleHero::clickLeft(tribool down, bool previousState) if(myOwner->spellDestSelectMode) //we are casting a spell return; - if(myHero != nullptr && !down && myOwner->myTurn && myOwner->getCurrentPlayerInterface()->cb->battleCanCastSpell(myHero, ECastingMode::HERO_CASTING) == ESpellCastProblem::OK) //check conditions + if(boost::logic::indeterminate(down)) + return; + + if(!myHero || down || !myOwner->myTurn) + return; + + if(myOwner->getCurrentPlayerInterface()->cb->battleCanCastSpell(myHero, ECastingMode::HERO_CASTING) == ESpellCastProblem::OK) //check conditions { for(int it=0; itpos.topLeft().x + 1 : myOwner->pos.topRight().x - 79; windowPosition.y = myOwner->pos.y + 135; @@ -220,24 +236,19 @@ void CBattleHero::clickRight(tribool down, bool previousState) void CBattleHero::switchToNextPhase() { - if (phase != nextPhase) + if(phase != nextPhase) { phase = nextPhase; - //find first and last frames of our animation - for (firstFrame = 0; - firstFrame < dh->ourImages.size() && dh->ourImages[firstFrame].groupNumber != phase; - firstFrame++); + firstFrame = 0; - for (lastFrame = firstFrame; - lastFrame < dh->ourImages.size() && dh->ourImages[lastFrame].groupNumber == phase; - lastFrame++); + lastFrame = animation->size(phase); } currentFrame = firstFrame; } -CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor player, const CGHeroInstance * hero, const CBattleInterface * owner): +CBattleHero::CBattleHero(const std::string & animationPath, bool flipG, PlayerColor player, const CGHeroInstance * hero, const CBattleInterface * owner): flip(flipG), myHero(hero), myOwner(owner), @@ -246,39 +257,25 @@ CBattleHero::CBattleHero(const std::string & defName, bool flipG, PlayerColor pl flagAnim(0), animCount(0) { - dh = CDefHandler::giveDef( defName ); - for(auto & elem : dh->ourImages) //transforming images - { - if(flip) - { - SDL_Surface * hlp = CSDL_Ext::verticalFlip(elem.bitmap); - SDL_FreeSurface(elem.bitmap); - elem.bitmap = hlp; - } - CSDL_Ext::alphaTransform(elem.bitmap); - } + animation = std::make_shared(animationPath); + animation->preload(); + if(flipG) + animation->verticalFlip(); if(flip) - flag = CDefHandler::giveDef("CMFLAGR.DEF"); + flagAnimation = std::make_shared("CMFLAGR"); else - flag = CDefHandler::giveDef("CMFLAGL.DEF"); + flagAnimation = std::make_shared("CMFLAGL"); + + flagAnimation->preload(); + flagAnimation->playerColored(player); - //coloring flag and adding transparency - for(auto & elem : flag->ourImages) - { - CSDL_Ext::alphaTransform(elem.bitmap); - graphics->blueToPlayersAdv(elem.bitmap, player); - } addUsedEvents(LCLICK | RCLICK | HOVER); switchToNextPhase(); } -CBattleHero::~CBattleHero() -{ - delete dh; - delete flag; -} +CBattleHero::~CBattleHero() = default; CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInterface *owner) { diff --git a/client/battle/CBattleInterfaceClasses.h b/client/battle/CBattleInterfaceClasses.h index 589dafc43..38af30b9a 100644 --- a/client/battle/CBattleInterfaceClasses.h +++ b/client/battle/CBattleInterfaceClasses.h @@ -14,7 +14,6 @@ #include "../windows/CWindowObject.h" struct SDL_Surface; -class CDefHandler; class CGHeroInstance; class CBattleInterface; class CPicture; @@ -53,19 +52,24 @@ class CBattleHero : public CIntObject void switchToNextPhase(); public: bool flip; //false if it's attacking hero, true otherwise - CDefHandler *dh, *flag; //animation and flag + + std::shared_ptr animation; + std::shared_ptr flagAnimation; + 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 currentFrame, firstFrame, lastFrame; //frame of animation - ui8 flagAnim, animCount; //for flag animation + + size_t flagAnim; + ui8 animCount; //for flag animation void show(SDL_Surface * to) override; //prints next frame of animation to to void setPhase(int newPhase); //sets phase of hero animation void hover(bool on) override; void clickLeft(tribool down, bool previousState) override; //call-in void clickRight(tribool down, bool previousState) override; //call-in - CBattleHero(const std::string &defName, bool filpG, PlayerColor player, const CGHeroInstance *hero, const CBattleInterface *owner); + CBattleHero(const std::string & animationPath, bool filpG, PlayerColor player, const CGHeroInstance * hero, const CBattleInterface * owner); ~CBattleHero(); }; diff --git a/client/gui/CAnimation.cpp b/client/gui/CAnimation.cpp index 48768709a..ce4b56d28 100644 --- a/client/gui/CAnimation.cpp +++ b/client/gui/CAnimation.cpp @@ -29,7 +29,7 @@ typedef std::map > source_map; typedef std::map image_map; typedef std::map group_map; - /// Class for def loading, methods are based on CDefHandler +/// Class for def loading /// After loading will store general info (palette and frame offsets) and pointer to file itself class CDefFile { @@ -1605,6 +1605,27 @@ size_t CAnimation::size(size_t group) const return 0; } +void CAnimation::horizontalFlip() +{ + for(auto & group : images) + for(auto & image : group.second) + image.second->horizontalFlip(); +} + +void CAnimation::verticalFlip() +{ + for(auto & group : images) + for(auto & image : group.second) + image.second->verticalFlip(); +} + +void CAnimation::playerColored(PlayerColor player) +{ + for(auto & group : images) + for(auto & image : group.second) + image.second->playerColored(player); +} + float CFadeAnimation::initialCounter() const { if (fadingMode == EMode::OUT) diff --git a/client/gui/CAnimation.h b/client/gui/CAnimation.h index 319094be5..3b52ed2f0 100644 --- a/client/gui/CAnimation.h +++ b/client/gui/CAnimation.h @@ -127,6 +127,10 @@ public: //total count of frames in group (including not loaded) size_t size(size_t group=0) const; + + void horizontalFlip(); + void verticalFlip(); + void playerColored(PlayerColor player); }; const float DEFAULT_DELTA = 0.05f;