1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Moved battle animation enum's into new file

This commit is contained in:
Ivan Savenko 2022-12-08 19:41:02 +02:00
parent b3deea24e0
commit 1dea1854ae
10 changed files with 276 additions and 229 deletions

View File

@ -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

View File

@ -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
});
}

View File

@ -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;

View File

@ -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
};
}

View File

@ -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;
}

View File

@ -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))

View File

@ -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()

View File

@ -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();

View File

@ -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();

View File

@ -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);
};