فهرست منبع

Use CAnimation fro custom battle effects

AlexVinS 8 سال پیش
والد
کامیت
78b86224a0
3فایلهای تغییر یافته به همراه60 افزوده شده و 67 حذف شده
  1. 52 61
      client/battle/CBattleAnimations.cpp
  2. 6 4
      client/battle/CBattleInterface.cpp
  3. 2 2
      client/battle/CBattleInterface.h

+ 52 - 61
client/battle/CBattleAnimations.cpp

@@ -21,6 +21,7 @@
 #include "../CMusicHandler.h"
 #include "../CPlayerInterface.h"
 #include "../Graphics.h"
+#include "../gui/CAnimation.h"
 #include "../gui/CCursorHandler.h"
 #include "../gui/CGuiHandler.h"
 #include "../gui/SDL_Extensions.h"
@@ -909,91 +910,82 @@ bool CSpellEffectAnimation::init()
 
 	const bool areaEffect = (!destTile.isValid() && x == -1 && y == -1);
 
-	if(areaEffect) //f.e. armageddon
+	std::shared_ptr<CAnimation> animation = std::make_shared<CAnimation>(customAnim);
+
+	animation->preload();
+	if(Vflip)
+		animation->verticalFlip();
+
+	IImage * first = animation->getImage(0, 0, true);
+	if(!first)
 	{
-		CDefHandler * anim = CDefHandler::giveDef(customAnim);
+		endAnim();
+		return false;
+	}
 
-		for(int i=0; i * anim->width < owner->pos.w ; ++i)
+	if(areaEffect) //f.e. armageddon
+	{
+		for(int i=0; i * first->width() < owner->pos.w ; ++i)
 		{
-			for(int j=0; j * anim->height < owner->pos.h ; ++j)
+			for(int j=0; j * first->height() < owner->pos.h ; ++j)
 			{
 				BattleEffect be;
 				be.effectID = ID;
-				be.anim = CDefHandler::giveDef(customAnim);
-				if (Vflip)
-				{
-					for (auto & elem : be.anim->ourImages)
-					{
-						CSDL_Ext::VflipSurf(elem.bitmap);
-					}
-				}
+				be.animation = animation;
 				be.currentFrame = 0;
-				be.maxFrame = be.anim->ourImages.size();
-				be.x = i * anim->width + owner->pos.x;
-				be.y = j * anim->height + owner->pos.y;
+
+				be.x = i * first->width() + owner->pos.x;
+				be.y = j * first->height() + owner->pos.y;
 				be.position = BattleHex::INVALID;
 
 				owner->battleEffects.push_back(be);
 			}
 		}
-
-		delete anim;
 	}
 	else // Effects targeted at a specific creature/hex.
 	{
+		const CStack * destStack = owner->getCurrentPlayerInterface()->cb->battleGetStackByPos(destTile, false);
+		Rect & tilePos = owner->bfield[destTile]->pos;
+		BattleEffect be;
+		be.effectID = ID;
+		be.animation = animation;
+		be.currentFrame = 0;
 
-			const CStack* destStack = owner->getCurrentPlayerInterface()->cb->battleGetStackByPos(destTile, false);
-			Rect & tilePos = owner->bfield[destTile]->pos;
-			BattleEffect be;
-			be.effectID = ID;
-			be.anim = CDefHandler::giveDef(customAnim);
 
-			if (Vflip)
-			{
-				for (auto & elem : be.anim->ourImages)
-				{
-					CSDL_Ext::VflipSurf(elem.bitmap);
-				}
-			}
-
-			be.currentFrame = 0;
-			be.maxFrame = be.anim->ourImages.size();
-
-			//todo: lightning anim frame count override
+		//todo: lightning anim frame count override
 
 //			if(effect == 1)
 //				be.maxFrame = 3;
 
-			if(x == -1)
-			{
-				be.x = tilePos.x + tilePos.w/2 - be.anim->width/2;
-			}
-			else
-			{
-				be.x = x;
-			}
+		if(x == -1)
+		{
+			be.x = tilePos.x + tilePos.w/2 - first->width()/2;
+		}
+		else
+		{
+			be.x = x;
+		}
 
-			if(y == -1)
-			{
-				if(alignToBottom)
-					be.y = tilePos.y + tilePos.h - be.anim->height;
-				else
-					be.y = tilePos.y - be.anim->height/2;
-			}
+		if(y == -1)
+		{
+			if(alignToBottom)
+				be.y = tilePos.y + tilePos.h - first->height();
 			else
-			{
-				be.y = y;
-			}
-
-			// Correction for 2-hex creatures.
-			if (destStack != nullptr && destStack->doubleWide())
-				be.x += (destStack->side == BattleSide::ATTACKER ? -1 : 1)*tilePos.w/2;
+				be.y = tilePos.y - first->height()/2;
+		}
+		else
+		{
+			be.y = y;
+		}
 
-			//Indicate if effect should be drawn on top of everything or just on top of the hex
-			be.position = destTile;
+		// Correction for 2-hex creatures.
+		if(destStack != nullptr && destStack->doubleWide())
+			be.x += (destStack->side == BattleSide::ATTACKER ? -1 : 1)*tilePos.w/2;
 
-			owner->battleEffects.push_back(be);
+		//Indicate if effect should be drawn on top of everything or just on top of the hex
+		be.position = destTile;
 
+		owner->battleEffects.push_back(be);
 	}
 	//battleEffects
 	return true;
@@ -1008,7 +1000,7 @@ void CSpellEffectAnimation::nextFrame()
 		{
 			elem.currentFrame += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
 
-			if(elem.currentFrame >= elem.maxFrame)
+			if(elem.currentFrame >= elem.animation->size())
 			{
 				endAnim();
 				break;
@@ -1038,7 +1030,6 @@ void CSpellEffectAnimation::endAnim()
 
 	for(auto & elem : toDel)
 	{
-		delete elem->anim;
 		owner->battleEffects.erase(elem);
 	}
 

+ 6 - 4
client/battle/CBattleInterface.cpp

@@ -3375,11 +3375,13 @@ void CBattleInterface::showBattleEffects(SDL_Surface *to, const std::vector<cons
 	for (auto & elem : battleEffects)
 	{
 		int currentFrame = floor(elem->currentFrame);
-		currentFrame %= elem->anim->ourImages.size();
+		currentFrame %= elem->animation->size();
 
-		SDL_Surface *bitmapToBlit = elem->anim->ourImages[currentFrame].bitmap;
-		SDL_Rect temp_rect = genRect(bitmapToBlit->h, bitmapToBlit->w, elem->x, elem->y);
-		SDL_BlitSurface(bitmapToBlit, nullptr, to, &temp_rect);
+		IImage * img = elem->animation->getImage(currentFrame);
+
+		SDL_Rect temp_rect = genRect(img->height(), img->width(), elem->x, elem->y);
+
+		img->draw(to, &temp_rect, nullptr);
 	}
 }
 

+ 2 - 2
client/battle/CBattleInterface.h

@@ -48,6 +48,7 @@ struct BattleHex;
 struct InfoAboutHero;
 struct BattleAction;
 class CBattleGameInterface;
+class CAnimation;
 
 /// Small struct which contains information about the id of the attacked stack, the damage dealt,...
 struct StackAttackedInfo
@@ -67,8 +68,7 @@ struct BattleEffect
 {
 	int x, y; //position on the screen
 	float currentFrame;
-	int maxFrame;
-	CDefHandler *anim; //animation to display
+	std::shared_ptr<CAnimation> animation;
 	int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
 	BattleHex position; //Indicates if effect which hex the effect is drawn on
 };