فهرست منبع

Moved battle animation enum's into new file

Ivan Savenko 2 سال پیش
والد
کامیت
1dea1854ae

+ 1 - 0
client/CMakeLists.txt

@@ -98,6 +98,7 @@ set(client_HEADERS
 		battle/BattleSiegeController.h
 		battle/BattleStacksController.h
 		battle/CreatureAnimation.h
+		battle/BattleConstants.h
 
 		gui/CAnimation.h
 		gui/Canvas.h

+ 66 - 66
client/battle/BattleAnimationClasses.cpp

@@ -150,7 +150,7 @@ void CAttackAnimation::nextFrame()
 
 CAttackAnimation::~CAttackAnimation()
 {
-	myAnim->setType(CCreatureAnim::HOLDING);
+	myAnim->setType(ECreatureAnimType::HOLDING);
 }
 
 bool CAttackAnimation::checkInitialConditions()
@@ -180,7 +180,7 @@ const CCreature * CAttackAnimation::getCreature() const
 CAttackAnimation::CAttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
 	: CBattleStackAnimation(owner, attacker),
 	  shooting(false),
-	  group(CCreatureAnim::SHOOT_FRONT),
+	  group(ECreatureAnimType::SHOOT_FRONT),
 	  soundPlayed(false),
 	  dest(_dest),
 	  attackedStack(defender),
@@ -249,14 +249,14 @@ bool CDefenceAnimation::init()
 
 	// synchronize animation with attacker, unless defending or attacked by shooter:
 	// wait for 1/2 of attack animation
-	if (!rangedAttack && getMyAnimType() != CCreatureAnim::DEFENCE)
+	if (!rangedAttack && getMyAnimType() != ECreatureAnimType::DEFENCE)
 	{
 		float frameLength = AnimationControls::getCreatureAnimationSpeed(
 								  stack->getCreature(), stackAnimation(stack).get(), getMyAnimType());
 
 		timeToWait = myAnim->framesInGroup(getMyAnimType()) * frameLength / 2;
 
-		myAnim->setType(CCreatureAnim::HOLDING);
+		myAnim->setType(ECreatureAnimType::HOLDING);
 	}
 	else
 	{
@@ -277,20 +277,20 @@ std::string CDefenceAnimation::getMySound()
 		return battle_sound(stack->getCreature(), wince);
 }
 
-CCreatureAnim::EAnimType CDefenceAnimation::getMyAnimType()
+ECreatureAnimType::Type CDefenceAnimation::getMyAnimType()
 {
 	if(killed)
 	{
-		if(rangedAttack && myAnim->framesInGroup(CCreatureAnim::DEATH_RANGED) > 0)
-			return CCreatureAnim::DEATH_RANGED;
+		if(rangedAttack && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0)
+			return ECreatureAnimType::DEATH_RANGED;
 		else
-			return CCreatureAnim::DEATH;
+			return ECreatureAnimType::DEATH;
 	}
 
 	if(stack->defendingAnim)
-		return CCreatureAnim::DEFENCE;
+		return ECreatureAnimType::DEFENCE;
 	else
-		return CCreatureAnim::HITTED;
+		return ECreatureAnimType::HITTED;
 }
 
 void CDefenceAnimation::startAnimation()
@@ -316,14 +316,14 @@ CDefenceAnimation::~CDefenceAnimation()
 {
 	if(killed)
 	{
-		if(rangedAttack && myAnim->framesInGroup(CCreatureAnim::DEAD_RANGED) > 0)
-			myAnim->setType(CCreatureAnim::DEAD_RANGED);
+		if(rangedAttack && myAnim->framesInGroup(ECreatureAnimType::DEAD_RANGED) > 0)
+			myAnim->setType(ECreatureAnimType::DEAD_RANGED);
 		else
-			myAnim->setType(CCreatureAnim::DEAD);
+			myAnim->setType(ECreatureAnimType::DEAD);
 	}
 	else
 	{
-		myAnim->setType(CCreatureAnim::HOLDING);
+		myAnim->setType(ECreatureAnimType::HOLDING);
 	}
 }
 
@@ -375,24 +375,24 @@ bool CMeleeAttackAnimation::init()
 
 	shooting = false;
 
-	static const CCreatureAnim::EAnimType mutPosToGroup[] =
+	static const ECreatureAnimType::Type mutPosToGroup[] =
 	{
-		CCreatureAnim::ATTACK_UP,
-		CCreatureAnim::ATTACK_UP,
-		CCreatureAnim::ATTACK_FRONT,
-		CCreatureAnim::ATTACK_DOWN,
-		CCreatureAnim::ATTACK_DOWN,
-		CCreatureAnim::ATTACK_FRONT
+		ECreatureAnimType::ATTACK_UP,
+		ECreatureAnimType::ATTACK_UP,
+		ECreatureAnimType::ATTACK_FRONT,
+		ECreatureAnimType::ATTACK_DOWN,
+		ECreatureAnimType::ATTACK_DOWN,
+		ECreatureAnimType::ATTACK_FRONT
 	};
 
-	static const CCreatureAnim::EAnimType mutPosToGroup2H[] =
+	static const ECreatureAnimType::Type mutPosToGroup2H[] =
 	{
-		CCreatureAnim::VCMI_2HEX_UP,
-		CCreatureAnim::VCMI_2HEX_UP,
-		CCreatureAnim::VCMI_2HEX_FRONT,
-		CCreatureAnim::VCMI_2HEX_DOWN,
-		CCreatureAnim::VCMI_2HEX_DOWN,
-		CCreatureAnim::VCMI_2HEX_FRONT
+		ECreatureAnimType::VCMI_2HEX_UP,
+		ECreatureAnimType::VCMI_2HEX_UP,
+		ECreatureAnimType::VCMI_2HEX_FRONT,
+		ECreatureAnimType::VCMI_2HEX_DOWN,
+		ECreatureAnimType::VCMI_2HEX_DOWN,
+		ECreatureAnimType::VCMI_2HEX_FRONT
 	};
 
 	int revShiftattacker = (attackingStack->side == BattleSide::ATTACKER ? -1 : 1);
@@ -423,7 +423,7 @@ bool CMeleeAttackAnimation::init()
 		group = mutPosToGroup[mutPos];
 		if(attackingStack->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH))
 		{
-			CCreatureAnim::EAnimType group2H = mutPosToGroup2H[mutPos];
+			ECreatureAnimType::Type group2H = mutPosToGroup2H[mutPos];
 			if(myAnim->framesInGroup(group2H)>0)
 				group = group2H;
 		}
@@ -431,7 +431,7 @@ bool CMeleeAttackAnimation::init()
 		break;
 	default:
 		logGlobal->error("Critical Error! Wrong dest in stackAttacking! dest: %d; attacking stack pos: %d; mutual pos: %d", dest.hex, attackingStackPosBeforeReturn, mutPos);
-		group = CCreatureAnim::ATTACK_FRONT;
+		group = ECreatureAnimType::ATTACK_FRONT;
 		break;
 	}
 
@@ -462,7 +462,7 @@ bool CMovementAnimation::init()
 		return false;
 	}
 
-	if(stackAnimation(stack)->framesInGroup(CCreatureAnim::MOVING) == 0 ||
+	if(stackAnimation(stack)->framesInGroup(ECreatureAnimType::MOVING) == 0 ||
 	   stack->hasBonus(Selector::typeSubtype(Bonus::FLYING, 1)))
 	{
 		//no movement or teleport, end immediately
@@ -486,9 +486,9 @@ bool CMovementAnimation::init()
 		}
 	}
 
-	if(myAnim->getType() != CCreatureAnim::MOVING)
+	if(myAnim->getType() != ECreatureAnimType::MOVING)
 	{
-		myAnim->setType(CCreatureAnim::MOVING);
+		myAnim->setType(ECreatureAnimType::MOVING);
 	}
 
 	if (owner.moveSoundHander == -1)
@@ -587,7 +587,7 @@ bool CMovementEndAnimation::init()
 	//if( !isEarliest(true) )
 	//	return false;
 
-	if(!stack || myAnim->framesInGroup(CCreatureAnim::MOVE_END) == 0 ||
+	if(!stack || myAnim->framesInGroup(ECreatureAnimType::MOVE_END) == 0 ||
 		myAnim->isDeadOrDying())
 	{
 		delete this;
@@ -596,7 +596,7 @@ bool CMovementEndAnimation::init()
 
 	CCS->soundh->playSound(battle_sound(stack->getCreature(), endMoving));
 
-	myAnim->setType(CCreatureAnim::MOVE_END);
+	myAnim->setType(ECreatureAnimType::MOVE_END);
 
 	myAnim->onAnimationReset += [&](){ delete this; };
 
@@ -605,8 +605,8 @@ bool CMovementEndAnimation::init()
 
 CMovementEndAnimation::~CMovementEndAnimation()
 {
-	if(myAnim->getType() != CCreatureAnim::DEAD)
-		myAnim->setType(CCreatureAnim::HOLDING); //resetting to default
+	if(myAnim->getType() != ECreatureAnimType::DEAD)
+		myAnim->setType(ECreatureAnimType::HOLDING); //resetting to default
 
 	CCS->curh->show();
 }
@@ -630,7 +630,7 @@ bool CMovementStartAnimation::init()
 	}
 
 	CCS->soundh->playSound(battle_sound(stack->getCreature(), startMoving));
-	myAnim->setType(CCreatureAnim::MOVE_START);
+	myAnim->setType(ECreatureAnimType::MOVE_START);
 	myAnim->onAnimationReset += [&](){ delete this; };
 
 	return true;
@@ -654,9 +654,9 @@ bool CReverseAnimation::init()
 	if(!priority && !CBattleAnimation::checkInitialConditions())
 		return false;
 
-	if(myAnim->framesInGroup(CCreatureAnim::TURN_L))
+	if(myAnim->framesInGroup(ECreatureAnimType::TURN_L))
 	{
-		myAnim->setType(CCreatureAnim::TURN_L);
+		myAnim->setType(ECreatureAnimType::TURN_L);
 		myAnim->onAnimationReset += std::bind(&CReverseAnimation::setupSecondPart, this);
 	}
 	else
@@ -669,7 +669,7 @@ bool CReverseAnimation::init()
 CReverseAnimation::~CReverseAnimation()
 {
 	if( stack && stack->alive() )//don't do that if stack is dead
-		myAnim->setType(CCreatureAnim::HOLDING);
+		myAnim->setType(ECreatureAnimType::HOLDING);
 }
 
 void CBattleStackAnimation::rotateStack(BattleHex hex)
@@ -689,9 +689,9 @@ void CReverseAnimation::setupSecondPart()
 
 	rotateStack(currentHex);
 
-	if(myAnim->framesInGroup(CCreatureAnim::TURN_R))
+	if(myAnim->framesInGroup(ECreatureAnimType::TURN_R))
 	{
-		myAnim->setType(CCreatureAnim::TURN_R);
+		myAnim->setType(ECreatureAnimType::TURN_R);
 		myAnim->onAnimationReset += [&](){ delete this; };
 	}
 	else
@@ -864,19 +864,19 @@ uint32_t CShootingAnimation::getAttackClimaxFrame() const
 	return shooterInfo->animation.attackClimaxFrame;
 }
 
-CCreatureAnim::EAnimType CShootingAnimation::getUpwardsGroup() const
+ECreatureAnimType::Type CShootingAnimation::getUpwardsGroup() const
 {
-	return CCreatureAnim::SHOOT_UP;
+	return ECreatureAnimType::SHOOT_UP;
 }
 
-CCreatureAnim::EAnimType CShootingAnimation::getForwardGroup() const
+ECreatureAnimType::Type CShootingAnimation::getForwardGroup() const
 {
-	return CCreatureAnim::SHOOT_FRONT;
+	return ECreatureAnimType::SHOOT_FRONT;
 }
 
-CCreatureAnim::EAnimType CShootingAnimation::getDownwardsGroup() const
+ECreatureAnimType::Type CShootingAnimation::getDownwardsGroup() const
 {
-	return CCreatureAnim::SHOOT_DOWN;
+	return ECreatureAnimType::SHOOT_DOWN;
 }
 
 CCatapultAnimation::CCatapultAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, int _catapultDmg)
@@ -925,7 +925,7 @@ CCastAnimation::CCastAnimation(BattleInterface & owner, const CStack * attacker,
 		dest = defender->getPosition();
 }
 
-CCreatureAnim::EAnimType CCastAnimation::findValidGroup( const std::vector<CCreatureAnim::EAnimType> candidates ) const
+ECreatureAnimType::Type CCastAnimation::findValidGroup( const std::vector<ECreatureAnimType::Type> candidates ) const
 {
 	for ( auto group : candidates)
 	{
@@ -934,36 +934,36 @@ CCreatureAnim::EAnimType CCastAnimation::findValidGroup( const std::vector<CCrea
 	}
 
 	assert(0);
-	return CCreatureAnim::HOLDING;
+	return ECreatureAnimType::HOLDING;
 }
 
-CCreatureAnim::EAnimType CCastAnimation::getUpwardsGroup() const
+ECreatureAnimType::Type CCastAnimation::getUpwardsGroup() const
 {
 	return findValidGroup({
-		CCreatureAnim::VCMI_CAST_UP,
-		CCreatureAnim::CAST_UP,
-		CCreatureAnim::SHOOT_UP,
-		CCreatureAnim::ATTACK_UP
+		ECreatureAnimType::VCMI_CAST_UP,
+		ECreatureAnimType::CAST_UP,
+		ECreatureAnimType::SHOOT_UP,
+		ECreatureAnimType::ATTACK_UP
 	});
 }
 
-CCreatureAnim::EAnimType CCastAnimation::getForwardGroup() const
+ECreatureAnimType::Type CCastAnimation::getForwardGroup() const
 {
 	return findValidGroup({
-		CCreatureAnim::VCMI_CAST_FRONT,
-		CCreatureAnim::CAST_FRONT,
-		CCreatureAnim::SHOOT_FRONT,
-		CCreatureAnim::ATTACK_FRONT
+		ECreatureAnimType::VCMI_CAST_FRONT,
+		ECreatureAnimType::CAST_FRONT,
+		ECreatureAnimType::SHOOT_FRONT,
+		ECreatureAnimType::ATTACK_FRONT
 	});
 }
 
-CCreatureAnim::EAnimType CCastAnimation::getDownwardsGroup() const
+ECreatureAnimType::Type CCastAnimation::getDownwardsGroup() const
 {
 	return findValidGroup({
-		CCreatureAnim::VCMI_CAST_DOWN,
-		CCreatureAnim::CAST_DOWN,
-		CCreatureAnim::SHOOT_DOWN,
-		CCreatureAnim::ATTACK_DOWN
+		ECreatureAnimType::VCMI_CAST_DOWN,
+		ECreatureAnimType::CAST_DOWN,
+		ECreatureAnimType::SHOOT_DOWN,
+		ECreatureAnimType::ATTACK_DOWN
 	});
 }
 

+ 18 - 13
client/battle/BattleAnimationClasses.h

@@ -11,19 +11,24 @@
 
 #include "../../lib/battle/BattleHex.h"
 #include "../../lib/CSoundBase.h"
-#include "../widgets/Images.h"
+#include "BattleConstants.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CStack;
+class CCreature;
+class CSpell;
 
 VCMI_LIB_NAMESPACE_END
 
+class CAnimation;
 class BattleInterface;
 class CreatureAnimation;
 class CBattleAnimation;
 struct CatapultProjectileInfo;
 struct StackAttackedInfo;
+struct Point;
+class ColorShifter;
 
 /// Base class of battle animations
 class CBattleAnimation
@@ -73,7 +78,7 @@ class CAttackAnimation : public CBattleStackAnimation
 protected:
 	BattleHex dest; //attacked hex
 	bool shooting;
-	CCreatureAnim::EAnimType group; //if shooting is true, print this animation group
+	ECreatureAnimType::Type group; //if shooting is true, print this animation group
 	const CStack *attackedStack;
 	const CStack *attackingStack;
 	int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
@@ -90,7 +95,7 @@ public:
 /// Animation of a defending unit
 class CDefenceAnimation : public CBattleStackAnimation
 {
-	CCreatureAnim::EAnimType getMyAnimType();
+	ECreatureAnimType::Type getMyAnimType();
 	std::string getMySound();
 
 	void startAnimation();
@@ -205,9 +210,9 @@ class CRangedAttackAnimation : public CAttackAnimation
 protected:
 	bool projectileEmitted;
 
-	virtual CCreatureAnim::EAnimType getUpwardsGroup() const = 0;
-	virtual CCreatureAnim::EAnimType getForwardGroup() const = 0;
-	virtual CCreatureAnim::EAnimType getDownwardsGroup() const = 0;
+	virtual ECreatureAnimType::Type getUpwardsGroup() const = 0;
+	virtual ECreatureAnimType::Type getForwardGroup() const = 0;
+	virtual ECreatureAnimType::Type getDownwardsGroup() const = 0;
 
 	virtual void createProjectile(const Point & from, const Point & dest) const = 0;
 	virtual uint32_t getAttackClimaxFrame() const = 0;
@@ -223,9 +228,9 @@ public:
 /// Shooting attack
 class CShootingAnimation : public CRangedAttackAnimation
 {
-	CCreatureAnim::EAnimType getUpwardsGroup() const override;
-	CCreatureAnim::EAnimType getForwardGroup() const override;
-	CCreatureAnim::EAnimType getDownwardsGroup() const override;
+	ECreatureAnimType::Type getUpwardsGroup() const override;
+	ECreatureAnimType::Type getForwardGroup() const override;
+	ECreatureAnimType::Type getDownwardsGroup() const override;
 
 	void createProjectile(const Point & from, const Point & dest) const override;
 	uint32_t getAttackClimaxFrame() const override;
@@ -253,10 +258,10 @@ class CCastAnimation : public CRangedAttackAnimation
 {
 	const CSpell * spell;
 
-	CCreatureAnim::EAnimType findValidGroup( const std::vector<CCreatureAnim::EAnimType> candidates ) const;
-	CCreatureAnim::EAnimType getUpwardsGroup() const override;
-	CCreatureAnim::EAnimType getForwardGroup() const override;
-	CCreatureAnim::EAnimType getDownwardsGroup() const override;
+	ECreatureAnimType::Type findValidGroup( const std::vector<ECreatureAnimType::Type> candidates ) const;
+	ECreatureAnimType::Type getUpwardsGroup() const override;
+	ECreatureAnimType::Type getForwardGroup() const override;
+	ECreatureAnimType::Type getDownwardsGroup() const override;
 
 	void createProjectile(const Point & from, const Point & dest) const override;
 	uint32_t getAttackClimaxFrame() const override;

+ 62 - 0
client/battle/BattleConstants.h

@@ -0,0 +1,62 @@
+/*
+ * BattleConstants.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
+ *
+ */
+#pragma once
+
+namespace EHeroAnimType
+{
+enum Type
+{
+	HOLDING    = 0,
+	IDLE       = 1, // idling movement that happens from time to time
+	DEFEAT     = 2, // played when army loses stack or on friendly fire
+	VICTORY    = 3, // when enemy stack killed or huge damage is dealt
+	CAST_SPELL = 4 // spellcasting
+};
+}
+
+namespace ECreatureAnimType
+{
+enum Type // list of creature animations, numbers were taken from def files
+{
+	MOVING          =0,
+	MOUSEON         =1,
+	HOLDING         =2,
+	HITTED          =3,
+	DEFENCE         =4,
+	DEATH           =5,
+	DEATH_RANGED    =6,
+	TURN_L          =7,
+	TURN_R          =8,
+	//TURN_L2       =9, //unused - identical to TURN_L
+	//TURN_R2       =10,//unused - identical to TURN_R
+	ATTACK_UP       =11,
+	ATTACK_FRONT    =12,
+	ATTACK_DOWN     =13,
+	SHOOT_UP        =14,
+	SHOOT_FRONT     =15,
+	SHOOT_DOWN      =16,
+	CAST_UP         =17,
+	CAST_FRONT      =18,
+	CAST_DOWN       =19,
+	MOVE_START      =20,
+	MOVE_END        =21,
+
+	DEAD            = 22, // new group, used to show dead stacks. If empty - last frame from "DEATH" will be copied here
+	DEAD_RANGED     = 23, // new group, used to show dead stacks (if DEATH_RANGED was used). If empty - last frame from "DEATH_RANGED" will be copied here
+	RESURRECTION    = 24, // new group, used for animating resurrection, if empty - reversed "DEATH" animation will be copiend here
+
+	VCMI_CAST_UP    = 30,
+	VCMI_CAST_FRONT = 31,
+	VCMI_CAST_DOWN  = 32,
+	VCMI_2HEX_UP    = 40,
+	VCMI_2HEX_FRONT = 41,
+	VCMI_2HEX_DOWN  = 42
+};
+}

+ 4 - 4
client/battle/BattleInterface.cpp

@@ -354,9 +354,9 @@ void BattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attackedI
 	for(ui8 side = 0; side < 2; side++)
 	{
 		if(killedBySide.at(side) > killedBySide.at(1-side))
-			setHeroAnimation(side, CCreatureAnim::HERO_DEFEAT);
+			setHeroAnimation(side, EHeroAnimType::DEFEAT);
 		else if(killedBySide.at(side) < killedBySide.at(1-side))
-			setHeroAnimation(side, CCreatureAnim::HERO_VICTORY);
+			setHeroAnimation(side, EHeroAnimType::VICTORY);
 	}
 }
 
@@ -683,7 +683,7 @@ void BattleInterface::endAction(const BattleAction* action)
 	const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
 
 	if(action->actionType == EActionType::HERO_SPELL)
-		setHeroAnimation(action->side, CCreatureAnim::HERO_HOLDING);
+		setHeroAnimation(action->side, EHeroAnimType::HOLDING);
 
 	stacksController->endAction(action);
 
@@ -762,7 +762,7 @@ void BattleInterface::startAction(const BattleAction* action)
 
 	if(action->actionType == EActionType::HERO_SPELL) //when hero casts spell
 	{
-		setHeroAnimation(action->side, CCreatureAnim::HERO_CAST_SPELL);
+		setHeroAnimation(action->side, EHeroAnimType::CAST_SPELL);
 		return;
 	}
 

+ 11 - 11
client/battle/BattleStacksController.cpp

@@ -44,16 +44,16 @@ static void onAnimationFinished(const CStack *stack, std::weak_ptr<CreatureAnima
 	{
 		const CCreature *creature = stack->getCreature();
 
-		if (animation->framesInGroup(CCreatureAnim::MOUSEON) > 0)
+		if (animation->framesInGroup(ECreatureAnimType::MOUSEON) > 0)
 		{
 			if (CRandomGenerator::getDefault().nextDouble(99.0) < creature->animation.timeBetweenFidgets *10)
-				animation->playOnce(CCreatureAnim::MOUSEON);
+				animation->playOnce(ECreatureAnimType::MOUSEON);
 			else
-				animation->setType(CCreatureAnim::HOLDING);
+				animation->setType(ECreatureAnimType::HOLDING);
 		}
 		else
 		{
-			animation->setType(CCreatureAnim::HOLDING);
+			animation->setType(ECreatureAnimType::HOLDING);
 		}
 	}
 	// always reset callback
@@ -126,7 +126,7 @@ void BattleStacksController::collectRenderableObjects(BattleRenderer & renderer)
 			continue;
 
 		//FIXME: hack to ignore ghost stacks
-		if ((stackAnimation[stack->ID]->getType() == CCreatureAnim::DEAD || stackAnimation[stack->ID]->getType() == CCreatureAnim::HOLDING) && stack->isGhost())
+		if ((stackAnimation[stack->ID]->getType() == ECreatureAnimType::DEAD || stackAnimation[stack->ID]->getType() == ECreatureAnimType::HOLDING) && stack->isGhost())
 			continue;
 
 		auto layer = stackAnimation[stack->ID]->isDead() ? EBattleFieldLayer::CORPSES : EBattleFieldLayer::STACKS;
@@ -158,7 +158,7 @@ void BattleStacksController::stackReset(const CStack * stack)
 	auto animation = iter->second;
 
 	if(stack->alive() && animation->isDeadOrDying())
-		animation->setType(CCreatureAnim::HOLDING);
+		animation->setType(ECreatureAnimType::HOLDING);
 
 	static const ColorShifterMultiplyAndAdd shifterClone ({255, 255, 0, 255}, {0, 0, 255, 0});
 
@@ -199,7 +199,7 @@ void BattleStacksController::stackAdded(const CStack * stack)
 	stackAnimation[stack->ID]->pos.x = coords.x;
 	stackAnimation[stack->ID]->pos.y = coords.y;
 	stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth();
-	stackAnimation[stack->ID]->setType(CCreatureAnim::HOLDING);
+	stackAnimation[stack->ID]->setType(ECreatureAnimType::HOLDING);
 }
 
 void BattleStacksController::setActiveStack(const CStack *stack)
@@ -231,8 +231,8 @@ void BattleStacksController::setHoveredStack(const CStack *stack)
 		if (mouseHoveredStack)
 		{
 			stackAnimation[mouseHoveredStack->ID]->setBorderColor(AnimationControls::getBlueBorder());
-			if (stackAnimation[mouseHoveredStack->ID]->framesInGroup(CCreatureAnim::MOUSEON) > 0)
-				stackAnimation[mouseHoveredStack->ID]->playOnce(CCreatureAnim::MOUSEON);
+			if (stackAnimation[mouseHoveredStack->ID]->framesInGroup(ECreatureAnimType::MOUSEON) > 0)
+				stackAnimation[mouseHoveredStack->ID]->playOnce(ECreatureAnimType::MOUSEON);
 		}
 	}
 	else
@@ -404,7 +404,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 	for (auto & attackedInfo : attackedInfos)
 	{
 		if (attackedInfo.rebirth)
-			stackAnimation[attackedInfo.defender->ID]->setType(CCreatureAnim::HOLDING);
+			stackAnimation[attackedInfo.defender->ID]->setType(ECreatureAnimType::HOLDING);
 		if (attackedInfo.cloneKilled)
 			stackRemoved(attackedInfo.defender->ID);
 	}
@@ -472,7 +472,7 @@ void BattleStacksController::startAction(const BattleAction* action)
 	{
 		assert(stack);
 		owner.moveStarted = true;
-		if (stackAnimation[action->stackNumber]->framesInGroup(CCreatureAnim::MOVE_START))
+		if (stackAnimation[action->stackNumber]->framesInGroup(ECreatureAnimType::MOVE_START))
 			addNewAnim(new CMovementStartAnimation(owner, stack));
 
 		//if(shouldRotate(stack, stack->getPosition(), actionTarget.at(0).hexValue))

+ 71 - 59
client/battle/CreatureAnimation.cpp

@@ -42,7 +42,7 @@ std::shared_ptr<CreatureAnimation> AnimationControls::getAnimation(const CCreatu
 
 float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, const CreatureAnimation * anim, size_t group)
 {
-	CCreatureAnim::EAnimType type = CCreatureAnim::EAnimType(group);
+	ECreatureAnimType::Type type = ECreatureAnimType::Type(group);
 
 	assert(creature->animation.walkAnimationTime != 0);
 	assert(creature->animation.attackAnimationTime != 0);
@@ -58,49 +58,50 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
 
 	switch (type)
 	{
-	case CCreatureAnim::MOVING:
+	case ECreatureAnimType::MOVING:
 		return static_cast<float>(speed * 2 * creature->animation.walkAnimationTime / anim->framesInGroup(type));
 
-	case CCreatureAnim::MOUSEON:
+	case ECreatureAnimType::MOUSEON:
 		return baseSpeed;
-	case CCreatureAnim::HOLDING:
+	case ECreatureAnimType::HOLDING:
 		return static_cast<float>(baseSpeed * creature->animation.idleAnimationTime / anim->framesInGroup(type));
 
-	case CCreatureAnim::SHOOT_UP:
-	case CCreatureAnim::SHOOT_FRONT:
-	case CCreatureAnim::SHOOT_DOWN:
-	case CCreatureAnim::CAST_UP:
-	case CCreatureAnim::CAST_FRONT:
-	case CCreatureAnim::CAST_DOWN:
-	case CCreatureAnim::VCMI_CAST_DOWN:
-	case CCreatureAnim::VCMI_CAST_FRONT:
-	case CCreatureAnim::VCMI_CAST_UP:
+	case ECreatureAnimType::SHOOT_UP:
+	case ECreatureAnimType::SHOOT_FRONT:
+	case ECreatureAnimType::SHOOT_DOWN:
+	case ECreatureAnimType::CAST_UP:
+	case ECreatureAnimType::CAST_FRONT:
+	case ECreatureAnimType::CAST_DOWN:
+	case ECreatureAnimType::VCMI_CAST_DOWN:
+	case ECreatureAnimType::VCMI_CAST_FRONT:
+	case ECreatureAnimType::VCMI_CAST_UP:
 		return static_cast<float>(speed * 4 * creature->animation.attackAnimationTime / anim->framesInGroup(type));
 
 	// as strange as it looks like "attackAnimationTime" does not affects melee attacks
 	// necessary because length of these animations must be same for all creatures for synchronization
-	case CCreatureAnim::ATTACK_UP:
-	case CCreatureAnim::ATTACK_FRONT:
-	case CCreatureAnim::ATTACK_DOWN:
-	case CCreatureAnim::HITTED:
-	case CCreatureAnim::DEFENCE:
-	case CCreatureAnim::DEATH:
-	case CCreatureAnim::DEATH_RANGED:
-	case CCreatureAnim::VCMI_2HEX_DOWN:
-	case CCreatureAnim::VCMI_2HEX_FRONT:
-	case CCreatureAnim::VCMI_2HEX_UP:
+	case ECreatureAnimType::ATTACK_UP:
+	case ECreatureAnimType::ATTACK_FRONT:
+	case ECreatureAnimType::ATTACK_DOWN:
+	case ECreatureAnimType::HITTED:
+	case ECreatureAnimType::DEFENCE:
+	case ECreatureAnimType::DEATH:
+	case ECreatureAnimType::DEATH_RANGED:
+	case ECreatureAnimType::RESURRECTION:
+	case ECreatureAnimType::VCMI_2HEX_DOWN:
+	case ECreatureAnimType::VCMI_2HEX_FRONT:
+	case ECreatureAnimType::VCMI_2HEX_UP:
 		return speed * 3 / anim->framesInGroup(type);
 
-	case CCreatureAnim::TURN_L:
-	case CCreatureAnim::TURN_R:
+	case ECreatureAnimType::TURN_L:
+	case ECreatureAnimType::TURN_R:
 		return speed / 3;
 
-	case CCreatureAnim::MOVE_START:
-	case CCreatureAnim::MOVE_END:
+	case ECreatureAnimType::MOVE_START:
+	case ECreatureAnimType::MOVE_END:
 		return speed / 3;
 
-	case CCreatureAnim::DEAD:
-	case CCreatureAnim::DEAD_RANGED:
+	case ECreatureAnimType::DEAD:
+	case ECreatureAnimType::DEAD_RANGED:
 		return speed;
 
 	default:
@@ -133,12 +134,12 @@ float AnimationControls::getFlightDistance(const CCreature * creature)
 	return static_cast<float>(creature->animation.flightAnimationDistance * 200);
 }
 
-CCreatureAnim::EAnimType CreatureAnimation::getType() const
+ECreatureAnimType::Type CreatureAnimation::getType() const
 {
 	return type;
 }
 
-void CreatureAnimation::setType(CCreatureAnim::EAnimType type)
+void CreatureAnimation::setType(ECreatureAnimType::Type type)
 {
 	this->type = type;
 	currentFrame = 0;
@@ -161,7 +162,7 @@ CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController
 	  speed(0.1f),
 	  currentFrame(0),
 	  elapsedTime(0),
-	  type(CCreatureAnim::HOLDING),
+	  type(ECreatureAnimType::HOLDING),
 	  border(CSDL_Ext::makeColor(0, 0, 0, 0)),
 	  speedController(controller),
 	  once(false)
@@ -174,16 +175,27 @@ CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController
 	reverse->preload();
 
 	// if necessary, add one frame into vcmi-only group DEAD
-	if(forward->size(CCreatureAnim::DEAD) == 0)
+	if(forward->size(ECreatureAnimType::DEAD) == 0)
 	{
-		forward->duplicateImage(CCreatureAnim::DEATH, forward->size(CCreatureAnim::DEATH)-1, CCreatureAnim::DEAD);
-		reverse->duplicateImage(CCreatureAnim::DEATH, reverse->size(CCreatureAnim::DEATH)-1, CCreatureAnim::DEAD);
+		forward->duplicateImage(ECreatureAnimType::DEATH, forward->size(ECreatureAnimType::DEATH)-1, ECreatureAnimType::DEAD);
+		reverse->duplicateImage(ECreatureAnimType::DEATH, reverse->size(ECreatureAnimType::DEATH)-1, ECreatureAnimType::DEAD);
 	}
 
-	if(forward->size(CCreatureAnim::DEAD_RANGED) == 0 && forward->size(CCreatureAnim::DEATH_RANGED) != 0)
+	if(forward->size(ECreatureAnimType::DEAD_RANGED) == 0 && forward->size(ECreatureAnimType::DEATH_RANGED) != 0)
 	{
-		forward->duplicateImage(CCreatureAnim::DEATH_RANGED, forward->size(CCreatureAnim::DEATH_RANGED)-1, CCreatureAnim::DEAD_RANGED);
-		reverse->duplicateImage(CCreatureAnim::DEATH_RANGED, reverse->size(CCreatureAnim::DEATH_RANGED)-1, CCreatureAnim::DEAD_RANGED);
+		forward->duplicateImage(ECreatureAnimType::DEATH_RANGED, forward->size(ECreatureAnimType::DEATH_RANGED)-1, ECreatureAnimType::DEAD_RANGED);
+		reverse->duplicateImage(ECreatureAnimType::DEATH_RANGED, reverse->size(ECreatureAnimType::DEATH_RANGED)-1, ECreatureAnimType::DEAD_RANGED);
+	}
+
+	if(forward->size(ECreatureAnimType::RESURRECTION) == 0)
+	{
+		for (size_t i = 0; i < forward->size(ECreatureAnimType::DEATH); ++i)
+		{
+			size_t current = forward->size(ECreatureAnimType::DEATH) - 1 - i;
+
+			forward->duplicateImage(ECreatureAnimType::DEATH, current, ECreatureAnimType::RESURRECTION);
+			reverse->duplicateImage(ECreatureAnimType::DEATH, current, ECreatureAnimType::RESURRECTION);
+		}
 	}
 
 	//TODO: get dimensions form CAnimation
@@ -228,7 +240,7 @@ bool CreatureAnimation::incrementFrame(float timePassed)
 			currentFrame -= framesNumber;
 
 		if(once)
-			setType(CCreatureAnim::HOLDING);
+			setType(ECreatureAnimType::HOLDING);
 
 		endAnimation();
 		return true;
@@ -256,7 +268,7 @@ float CreatureAnimation::getCurrentFrame() const
 	return currentFrame;
 }
 
-void CreatureAnimation::playOnce( CCreatureAnim::EAnimType type )
+void CreatureAnimation::playOnce( ECreatureAnimType::Type type )
 {
 	setType(type);
 	once = true;
@@ -323,51 +335,51 @@ void CreatureAnimation::nextFrame(Canvas & canvas, bool facingRight)
 	}
 }
 
-int CreatureAnimation::framesInGroup(CCreatureAnim::EAnimType group) const
+int CreatureAnimation::framesInGroup(ECreatureAnimType::Type group) const
 {
 	return static_cast<int>(forward->size(group));
 }
 
 bool CreatureAnimation::isDead() const
 {
-	return getType() == CCreatureAnim::DEAD
-		|| getType() == CCreatureAnim::DEAD_RANGED;
+	return getType() == ECreatureAnimType::DEAD
+		|| getType() == ECreatureAnimType::DEAD_RANGED;
 }
 
 bool CreatureAnimation::isDying() const
 {
-	return getType() == CCreatureAnim::DEATH
-		|| getType() == CCreatureAnim::DEATH_RANGED;
+	return getType() == ECreatureAnimType::DEATH
+		|| getType() == ECreatureAnimType::DEATH_RANGED;
 }
 
 bool CreatureAnimation::isDeadOrDying() const
 {
-	return getType() == CCreatureAnim::DEAD
-		|| getType() == CCreatureAnim::DEATH
-		|| getType() == CCreatureAnim::DEAD_RANGED
-		|| getType() == CCreatureAnim::DEATH_RANGED;
+	return getType() == ECreatureAnimType::DEAD
+		|| getType() == ECreatureAnimType::DEATH
+		|| getType() == ECreatureAnimType::DEAD_RANGED
+		|| getType() == ECreatureAnimType::DEATH_RANGED;
 }
 
 bool CreatureAnimation::isIdle() const
 {
-	return getType() == CCreatureAnim::HOLDING
-	    || getType() == CCreatureAnim::MOUSEON;
+	return getType() == ECreatureAnimType::HOLDING
+		|| getType() == ECreatureAnimType::MOUSEON;
 }
 
 bool CreatureAnimation::isMoving() const
 {
-	return getType() == CCreatureAnim::MOVE_START
-	    || getType() == CCreatureAnim::MOVING
-		|| getType() == CCreatureAnim::MOVE_END
-		|| getType() == CCreatureAnim::TURN_L
-		|| getType() == CCreatureAnim::TURN_R;
+	return getType() == ECreatureAnimType::MOVE_START
+		|| getType() == ECreatureAnimType::MOVING
+		|| getType() == ECreatureAnimType::MOVE_END
+		|| getType() == ECreatureAnimType::TURN_L
+		|| getType() == ECreatureAnimType::TURN_R;
 }
 
 bool CreatureAnimation::isShooting() const
 {
-	return getType() == CCreatureAnim::SHOOT_UP
-	    || getType() == CCreatureAnim::SHOOT_FRONT
-	    || getType() == CCreatureAnim::SHOOT_DOWN;
+	return getType() == ECreatureAnimType::SHOOT_UP
+		|| getType() == ECreatureAnimType::SHOOT_FRONT
+		|| getType() == ECreatureAnimType::SHOOT_DOWN;
 }
 
 void CreatureAnimation::pause()

+ 5 - 5
client/battle/CreatureAnimation.h

@@ -78,7 +78,7 @@ private:
 	float elapsedTime;
 
 	///type of animation being displayed
-	CCreatureAnim::EAnimType type;
+	ECreatureAnimType::Type type;
 
 	/// border color, disabled if alpha = 0
 	SDL_Color border;
@@ -107,10 +107,10 @@ public:
 	CreatureAnimation(const std::string & name_, TSpeedController speedController);
 
 	/// sets type of animation and resets framecount
-	void setType(CCreatureAnim::EAnimType type);
+	void setType(ECreatureAnimType::Type type);
 
 	/// returns currently rendered type of animation
-	CCreatureAnim::EAnimType getType() const;
+	ECreatureAnimType::Type getType() const;
 
 	void nextFrame(Canvas & canvas, bool facingRight);
 
@@ -126,10 +126,10 @@ public:
 	float getCurrentFrame() const;
 
 	/// plays once given type of animation, then resets to idle
-	void playOnce(CCreatureAnim::EAnimType type);
+	void playOnce(ECreatureAnimType::Type type);
 
 	/// returns number of frames in selected animation type
-	int framesInGroup(CCreatureAnim::EAnimType type) const;
+	int framesInGroup(ECreatureAnimType::Type group) const;
 
 	void pause();
 	void play();

+ 33 - 20
client/widgets/Images.cpp

@@ -466,7 +466,7 @@ void CShowableAnim::rotate(bool on, bool vertical)
 		flags &= ~flag;
 }
 
-CCreatureAnim::CCreatureAnim(int x, int y, std::string name, ui8 flags, EAnimType type):
+CCreatureAnim::CCreatureAnim(int x, int y, std::string name, ui8 flags, ECreatureAnimType::Type type):
 	CShowableAnim(x,y,name,flags,4,type)
 {
 	xOffset = 0;
@@ -475,10 +475,23 @@ CCreatureAnim::CCreatureAnim(int x, int y, std::string name, ui8 flags, EAnimTyp
 
 void CCreatureAnim::loopPreview(bool warMachine)
 {
-	std::vector<EAnimType> available;
+	std::vector<ECreatureAnimType::Type> available;
+
+	static const ECreatureAnimType::Type creaPreviewList[] = {
+		ECreatureAnimType::HOLDING,
+		ECreatureAnimType::HITTED,
+		ECreatureAnimType::DEFENCE,
+		ECreatureAnimType::ATTACK_FRONT,
+		ECreatureAnimType::CAST_FRONT
+	};
+	static const ECreatureAnimType::Type machPreviewList[] = {
+		ECreatureAnimType::HOLDING,
+		ECreatureAnimType::MOVING,
+		ECreatureAnimType::SHOOT_UP,
+		ECreatureAnimType::SHOOT_FRONT,
+		ECreatureAnimType::SHOOT_DOWN
+	};
 
-	static const EAnimType creaPreviewList[] = {HOLDING, HITTED, DEFENCE, ATTACK_FRONT, CAST_FRONT};
-	static const EAnimType machPreviewList[] = {HOLDING, MOVING, SHOOT_UP, SHOOT_FRONT, SHOOT_DOWN};
 	auto & previewList = warMachine ? machPreviewList : creaPreviewList;
 
 	for (auto & elem : previewList)
@@ -489,11 +502,11 @@ void CCreatureAnim::loopPreview(bool warMachine)
 
 	if (rnd >= available.size())
 	{
-		EAnimType type;
-		if ( anim->size(MOVING) == 0 )//no moving animation present
-			type = HOLDING;
+		ECreatureAnimType::Type type;
+		if ( anim->size(ECreatureAnimType::MOVING) == 0 )//no moving animation present
+			type = ECreatureAnimType::HOLDING;
 		else
-			type = MOVING;
+			type = ECreatureAnimType::MOVING;
 
 		//display this anim for ~1 second (time is random, but it looks good)
 		for (size_t i=0; i< 12/anim->size(type) + 1; i++)
@@ -503,17 +516,17 @@ void CCreatureAnim::loopPreview(bool warMachine)
 		addLast(available[rnd]);
 }
 
-void CCreatureAnim::addLast(EAnimType newType)
+void CCreatureAnim::addLast(ECreatureAnimType::Type newType)
 {
-	if (type != MOVING && newType == MOVING)//starting moving - play init sequence
+	if (type != ECreatureAnimType::MOVING && newType == ECreatureAnimType::MOVING)//starting moving - play init sequence
 	{
-		queue.push( MOVE_START );
+		queue.push( ECreatureAnimType::MOVE_START );
 	}
-	else if (type == MOVING && newType != MOVING )//previous anim was moving - finish it
+	else if (type == ECreatureAnimType::MOVING && newType != ECreatureAnimType::MOVING )//previous anim was moving - finish it
 	{
-		queue.push( MOVE_END );
+		queue.push( ECreatureAnimType::MOVE_END );
 	}
-	if (newType == TURN_L || newType == TURN_R)
+	if (newType == ECreatureAnimType::TURN_L || newType == ECreatureAnimType::TURN_R)
 		queue.push(newType);
 
 	queue.push(newType);
@@ -522,14 +535,14 @@ void CCreatureAnim::addLast(EAnimType newType)
 void CCreatureAnim::reset()
 {
 	//if we are in the middle of rotation - set flag
-	if (type == TURN_L && !queue.empty() && queue.front() == TURN_L)
+	if (type == ECreatureAnimType::TURN_L && !queue.empty() && queue.front() == ECreatureAnimType::TURN_L)
 		rotate(true);
-	if (type == TURN_R && !queue.empty() && queue.front() == TURN_R)
+	if (type == ECreatureAnimType::TURN_R && !queue.empty() && queue.front() == ECreatureAnimType::TURN_R)
 		rotate(false);
 
 	while (!queue.empty())
 	{
-		EAnimType at = queue.front();
+		ECreatureAnimType::Type at = queue.front();
 		queue.pop();
 		if (set(at))
 			return;
@@ -538,12 +551,12 @@ void CCreatureAnim::reset()
 		callback();
 	while (!queue.empty())
 	{
-		EAnimType at = queue.front();
+		ECreatureAnimType::Type at = queue.front();
 		queue.pop();
 		if (set(at))
 			return;
 	}
-	set(HOLDING);
+	set(ECreatureAnimType::HOLDING);
 }
 
 void CCreatureAnim::startPreview(bool warMachine)
@@ -551,7 +564,7 @@ void CCreatureAnim::startPreview(bool warMachine)
 	callback = std::bind(&CCreatureAnim::loopPreview, this, warMachine);
 }
 
-void CCreatureAnim::clearAndSet(EAnimType type)
+void CCreatureAnim::clearAndSet(ECreatureAnimType::Type type)
 {
 	while (!queue.empty())
 		queue.pop();

+ 5 - 51
client/widgets/Images.h

@@ -11,6 +11,7 @@
 
 #include "../gui/CIntObject.h"
 #include "../gui/SDL_Extensions.h"
+#include "../battle/BattleConstants.h"
 
 struct SDL_Surface;
 struct Rect;
@@ -165,56 +166,9 @@ public:
 /// Creature-dependend animations like attacking, moving,...
 class CCreatureAnim: public CShowableAnim
 {
-public:
-
-	enum EHeroAnimType
-	{
-		HERO_HOLDING = 0,
-		HERO_IDLE = 1, // idling movement that happens from time to time
-		HERO_DEFEAT = 2, // played when army loses stack or on friendly fire
-		HERO_VICTORY = 3, // when enemy stack killed or huge damage is dealt
-		HERO_CAST_SPELL = 4 // spellcasting
-	};
-
-	enum EAnimType // list of creature animations, numbers were taken from def files
-	{
-		MOVING=0,
-		MOUSEON=1,
-		HOLDING=2,
-		HITTED=3,
-		DEFENCE=4,
-		DEATH=5,
-		DEATH_RANGED=6,
-		TURN_L=7,
-		TURN_R=8, //same
-		//TURN_L2=9, //identical to previous?
-		//TURN_R2=10,
-		ATTACK_UP=11,
-		ATTACK_FRONT=12,
-		ATTACK_DOWN=13,
-		SHOOT_UP=14,
-		SHOOT_FRONT=15,
-		SHOOT_DOWN=16,
-		CAST_UP=17,
-		CAST_FRONT=18,
-		CAST_DOWN=19,
-		MOVE_START=20,
-		MOVE_END=21,
-
-		DEAD = 22, // new group, used to show dead stacks. If empty - last frame from "DEATH" will be copied here
-		DEAD_RANGED = 23, // new group, used to show dead stacks (if DEATH_RANGED was used). If empty - last frame from "DEATH_RANGED" will be copied here
-
-		VCMI_CAST_UP    = 30,
-		VCMI_CAST_FRONT = 31,
-		VCMI_CAST_DOWN  = 32,
-		VCMI_2HEX_UP    = 40,
-		VCMI_2HEX_FRONT = 41,
-		VCMI_2HEX_DOWN  = 42
-	};
-
 private:
 	//queue of animations waiting to be displayed
-	std::queue<EAnimType> queue;
+	std::queue<ECreatureAnimType::Type> queue;
 
 	//this function is used as callback if preview flag was set during construction
 	void loopPreview(bool warMachine);
@@ -224,13 +178,13 @@ public:
 	void reset() override;
 
 	//add sequence to the end of queue
-	void addLast(EAnimType newType);
+	void addLast(ECreatureAnimType::Type newType);
 
 	void startPreview(bool warMachine);
 
 	//clear queue and set animation to this sequence
-	void clearAndSet(EAnimType type);
+	void clearAndSet(ECreatureAnimType::Type type);
 
-	CCreatureAnim(int x, int y, std::string name, ui8 flags = 0, EAnimType = HOLDING);
+	CCreatureAnim(int x, int y, std::string name, ui8 flags = 0, ECreatureAnimType::Type = ECreatureAnimType::HOLDING);
 
 };