Forráskód Böngészése

Use CAnimation in CBattleInterfaceClasses

AlexVinS 8 éve
szülő
commit
882e279818

+ 9 - 2
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
 	{

+ 45 - 48
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; it<GameConstants::BFIELD_SIZE; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
 		{
@@ -205,6 +218,9 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
 
 void CBattleHero::clickRight(tribool down, bool previousState)
 {
+	if(boost::logic::indeterminate(down))
+		return;
+
 	Point windowPosition;
 	windowPosition.x = (!flip) ? myOwner->pos.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<CAnimation>(animationPath);
+	animation->preload();
+	if(flipG)
+		animation->verticalFlip();
 
 	if(flip)
-		flag = CDefHandler::giveDef("CMFLAGR.DEF");
+		flagAnimation = std::make_shared<CAnimation>("CMFLAGR");
 	else
-		flag = CDefHandler::giveDef("CMFLAGL.DEF");
+		flagAnimation = std::make_shared<CAnimation>("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)
 {

+ 8 - 4
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<CAnimation> animation;
+	std::shared_ptr<CAnimation> 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();
 };
 

+ 22 - 1
client/gui/CAnimation.cpp

@@ -29,7 +29,7 @@ typedef std::map <size_t, std::vector <JsonNode> > source_map;
 typedef std::map<size_t, IImage* > image_map;
 typedef std::map<size_t, image_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)

+ 4 - 0
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;