mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-28 23:06:24 +02:00
Petrify will freeze stack animations
This commit is contained in:
parent
8665f36778
commit
733f21f8dc
@ -93,6 +93,58 @@ BattleStackAnimation::BattleStackAnimation(BattleInterface & owner, const CStack
|
||||
assert(myAnim);
|
||||
}
|
||||
|
||||
StackActionAnimation::StackActionAnimation(BattleInterface & owner, const CStack * stack)
|
||||
: BattleStackAnimation(owner, stack)
|
||||
, nextGroup(ECreatureAnimType::HOLDING)
|
||||
, currGroup(ECreatureAnimType::HOLDING)
|
||||
{
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type StackActionAnimation::getGroup() const
|
||||
{
|
||||
return currGroup;
|
||||
}
|
||||
|
||||
void StackActionAnimation::setNextGroup( ECreatureAnimType::Type group )
|
||||
{
|
||||
nextGroup = group;
|
||||
}
|
||||
|
||||
void StackActionAnimation::setGroup( ECreatureAnimType::Type group )
|
||||
{
|
||||
currGroup = group;
|
||||
}
|
||||
|
||||
void StackActionAnimation::setSound( std::string sound )
|
||||
{
|
||||
this->sound = sound;
|
||||
}
|
||||
|
||||
bool StackActionAnimation::init()
|
||||
{
|
||||
if (!sound.empty())
|
||||
CCS->soundh->playSound(sound);
|
||||
|
||||
if (myAnim->framesInGroup(currGroup) > 0)
|
||||
{
|
||||
myAnim->playOnce(currGroup);
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
}
|
||||
else
|
||||
delete this;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
StackActionAnimation::~StackActionAnimation()
|
||||
{
|
||||
if (stack->isFrozen())
|
||||
myAnim->setType(ECreatureAnimType::HOLDING);
|
||||
else
|
||||
myAnim->setType(nextGroup);
|
||||
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type AttackAnimation::findValidGroup( const std::vector<ECreatureAnimType::Type> candidates ) const
|
||||
{
|
||||
for ( auto group : candidates)
|
||||
@ -105,26 +157,6 @@ ECreatureAnimType::Type AttackAnimation::findValidGroup( const std::vector<ECrea
|
||||
return ECreatureAnimType::HOLDING;
|
||||
}
|
||||
|
||||
void AttackAnimation::nextFrame()
|
||||
{
|
||||
if(myAnim->getType() != group)
|
||||
{
|
||||
myAnim->setType(group);
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
}
|
||||
|
||||
if(!soundPlayed)
|
||||
{
|
||||
playSound();
|
||||
soundPlayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
AttackAnimation::~AttackAnimation()
|
||||
{
|
||||
myAnim->setType(ECreatureAnimType::HOLDING);
|
||||
}
|
||||
|
||||
const CCreature * AttackAnimation::getCreature() const
|
||||
{
|
||||
if (attackingStack->getCreature()->idNumber == CreatureID::ARROW_TOWERS)
|
||||
@ -135,9 +167,7 @@ const CCreature * AttackAnimation::getCreature() const
|
||||
|
||||
|
||||
AttackAnimation::AttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
|
||||
: BattleStackAnimation(owner, attacker),
|
||||
group(ECreatureAnimType::SHOOT_FRONT),
|
||||
soundPlayed(false),
|
||||
: StackActionAnimation(owner, attacker),
|
||||
dest(_dest),
|
||||
defendingStack(defender),
|
||||
attackingStack(attacker)
|
||||
@ -146,61 +176,34 @@ AttackAnimation::AttackAnimation(BattleInterface & owner, const CStack *attacker
|
||||
attackingStackPosBeforeReturn = attackingStack->getPosition();
|
||||
}
|
||||
|
||||
bool HittedAnimation::init()
|
||||
{
|
||||
CCS->soundh->playSound(battle_sound(stack->getCreature(), wince));
|
||||
myAnim->playOnce(ECreatureAnimType::HITTED);
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
return true;
|
||||
}
|
||||
|
||||
HittedAnimation::HittedAnimation(BattleInterface & owner, const CStack * stack)
|
||||
: BattleStackAnimation(owner, stack)
|
||||
: StackActionAnimation(owner, stack)
|
||||
{
|
||||
setGroup(ECreatureAnimType::HITTED);
|
||||
setSound(battle_sound(stack->getCreature(), wince));
|
||||
}
|
||||
|
||||
DefenceAnimation::DefenceAnimation(BattleInterface & owner, const CStack * stack)
|
||||
: BattleStackAnimation(owner, stack)
|
||||
: StackActionAnimation(owner, stack)
|
||||
{
|
||||
}
|
||||
|
||||
bool DefenceAnimation::init()
|
||||
{
|
||||
CCS->soundh->playSound(battle_sound(stack->getCreature(), defend));
|
||||
myAnim->playOnce(ECreatureAnimType::DEFENCE);
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
|
||||
return true; //initialized successfuly
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type DeathAnimation::getMyAnimType()
|
||||
{
|
||||
if(rangedAttack && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0)
|
||||
return ECreatureAnimType::DEATH_RANGED;
|
||||
else
|
||||
return ECreatureAnimType::DEATH;
|
||||
}
|
||||
|
||||
bool DeathAnimation::init()
|
||||
{
|
||||
CCS->soundh->playSound(battle_sound(stack->getCreature(), killed));
|
||||
myAnim->playOnce(getMyAnimType());
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
return true;
|
||||
setGroup(ECreatureAnimType::DEFENCE);
|
||||
setSound(battle_sound(stack->getCreature(), defend));
|
||||
}
|
||||
|
||||
DeathAnimation::DeathAnimation(BattleInterface & owner, const CStack * stack, bool ranged):
|
||||
BattleStackAnimation(owner, stack),
|
||||
rangedAttack(ranged)
|
||||
StackActionAnimation(owner, stack)
|
||||
{
|
||||
}
|
||||
setSound(battle_sound(stack->getCreature(), killed));
|
||||
|
||||
DeathAnimation::~DeathAnimation()
|
||||
{
|
||||
if(rangedAttack && myAnim->framesInGroup(ECreatureAnimType::DEAD_RANGED) > 0)
|
||||
myAnim->setType(ECreatureAnimType::DEAD_RANGED);
|
||||
if(ranged && myAnim->framesInGroup(ECreatureAnimType::DEATH_RANGED) > 0)
|
||||
setGroup(ECreatureAnimType::DEATH_RANGED);
|
||||
else
|
||||
myAnim->setType(ECreatureAnimType::DEAD);
|
||||
setGroup(ECreatureAnimType::DEATH);
|
||||
|
||||
if(ranged && myAnim->framesInGroup(ECreatureAnimType::DEAD_RANGED) > 0)
|
||||
setNextGroup(ECreatureAnimType::DEAD_RANGED);
|
||||
else
|
||||
setNextGroup(ECreatureAnimType::DEAD);
|
||||
}
|
||||
|
||||
DummyAnimation::DummyAnimation(BattleInterface & owner, int howManyFrames)
|
||||
@ -223,7 +226,7 @@ void DummyAnimation::nextFrame()
|
||||
delete this;
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getUpwardsGroup() const
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getUpwardsGroup(bool multiAttack) const
|
||||
{
|
||||
if (!multiAttack)
|
||||
return ECreatureAnimType::ATTACK_UP;
|
||||
@ -235,7 +238,7 @@ ECreatureAnimType::Type MeleeAttackAnimation::getUpwardsGroup() const
|
||||
});
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getForwardGroup() const
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getForwardGroup(bool multiAttack) const
|
||||
{
|
||||
if (!multiAttack)
|
||||
return ECreatureAnimType::ATTACK_FRONT;
|
||||
@ -247,7 +250,7 @@ ECreatureAnimType::Type MeleeAttackAnimation::getForwardGroup() const
|
||||
});
|
||||
}
|
||||
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getDownwardsGroup() const
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::getDownwardsGroup(bool multiAttack) const
|
||||
{
|
||||
if (!multiAttack)
|
||||
return ECreatureAnimType::ATTACK_DOWN;
|
||||
@ -259,27 +262,16 @@ ECreatureAnimType::Type MeleeAttackAnimation::getDownwardsGroup() const
|
||||
});
|
||||
}
|
||||
|
||||
bool MeleeAttackAnimation::init()
|
||||
ECreatureAnimType::Type MeleeAttackAnimation::selectGroup(bool multiAttack)
|
||||
{
|
||||
assert(attackingStack);
|
||||
assert(!myAnim->isDeadOrDying());
|
||||
|
||||
if(!attackingStack || myAnim->isDeadOrDying())
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
logAnim->info("CMeleeAttackAnimation::init: stack %s -> stack %s", stack->getName(), defendingStack->getName());
|
||||
|
||||
const ECreatureAnimType::Type mutPosToGroup[] =
|
||||
{
|
||||
getUpwardsGroup(),
|
||||
getUpwardsGroup(),
|
||||
getForwardGroup(),
|
||||
getDownwardsGroup(),
|
||||
getDownwardsGroup(),
|
||||
getForwardGroup()
|
||||
getUpwardsGroup (multiAttack),
|
||||
getUpwardsGroup (multiAttack),
|
||||
getForwardGroup (multiAttack),
|
||||
getDownwardsGroup(multiAttack),
|
||||
getDownwardsGroup(multiAttack),
|
||||
getForwardGroup (multiAttack)
|
||||
};
|
||||
|
||||
int revShiftattacker = (attackingStack->side == BattleSide::ATTACKER ? -1 : 1);
|
||||
@ -300,14 +292,13 @@ bool MeleeAttackAnimation::init()
|
||||
|
||||
assert(mutPos >= 0 && mutPos <=5);
|
||||
|
||||
group = mutPosToGroup[mutPos];
|
||||
return true;
|
||||
return mutPosToGroup[mutPos];
|
||||
}
|
||||
|
||||
void MeleeAttackAnimation::nextFrame()
|
||||
{
|
||||
size_t currentFrame = stackAnimation(attackingStack)->getCurrentFrame();
|
||||
size_t totalFrames = stackAnimation(attackingStack)->framesInGroup(group);
|
||||
size_t totalFrames = stackAnimation(attackingStack)->framesInGroup(getGroup());
|
||||
|
||||
if ( currentFrame * 2 >= totalFrames )
|
||||
{
|
||||
@ -317,23 +308,18 @@ void MeleeAttackAnimation::nextFrame()
|
||||
AttackAnimation::nextFrame();
|
||||
}
|
||||
|
||||
void MeleeAttackAnimation::playSound()
|
||||
{
|
||||
CCS->soundh->playSound(battle_sound(getCreature(), attack));
|
||||
}
|
||||
|
||||
MeleeAttackAnimation::MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack)
|
||||
: AttackAnimation(owner, attacker, _dest, _attacked),
|
||||
multiAttack(multiAttack)
|
||||
: AttackAnimation(owner, attacker, _dest, _attacked)
|
||||
{
|
||||
logAnim->debug("Created melee attack anim for %s", attacker->getName());
|
||||
setSound(battle_sound(getCreature(), attack));
|
||||
setGroup(selectGroup(multiAttack));
|
||||
}
|
||||
|
||||
StackMoveAnimation::StackMoveAnimation(BattleInterface & owner, const CStack * _stack, BattleHex _currentHex):
|
||||
BattleStackAnimation(owner, _stack),
|
||||
currentHex(_currentHex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MovementAnimation::init()
|
||||
@ -585,32 +571,10 @@ void ReverseAnimation::setupSecondPart()
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool ResurrectionAnimation::init()
|
||||
{
|
||||
assert(stack);
|
||||
|
||||
if(!stack)
|
||||
{
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
logAnim->info("CResurrectionAnimation::init: stack %s", stack->getName());
|
||||
myAnim->playOnce(ECreatureAnimType::RESURRECTION);
|
||||
myAnim->onAnimationReset += [&](){ delete this; };
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ResurrectionAnimation::ResurrectionAnimation(BattleInterface & owner, const CStack * _stack):
|
||||
BattleStackAnimation(owner, _stack)
|
||||
StackActionAnimation(owner, _stack)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ColorTransformAnimation::init()
|
||||
{
|
||||
return true;
|
||||
setGroup(ECreatureAnimType::RESURRECTION);
|
||||
}
|
||||
|
||||
void ColorTransformAnimation::nextFrame()
|
||||
@ -651,7 +615,7 @@ void ColorTransformAnimation::nextFrame()
|
||||
}
|
||||
|
||||
ColorTransformAnimation::ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell):
|
||||
BattleStackAnimation(owner, _stack),
|
||||
StackActionAnimation(owner, _stack),
|
||||
spell(spell),
|
||||
totalProgress(0.f)
|
||||
{
|
||||
@ -716,31 +680,15 @@ RangedAttackAnimation::RangedAttackAnimation(BattleInterface & owner_, const CSt
|
||||
: AttackAnimation(owner_, attacker, dest_, defender),
|
||||
projectileEmitted(false)
|
||||
{
|
||||
}
|
||||
|
||||
void RangedAttackAnimation::playSound()
|
||||
{
|
||||
CCS->soundh->playSound(battle_sound(getCreature(), shoot));
|
||||
setSound(battle_sound(getCreature(), shoot));
|
||||
}
|
||||
|
||||
bool RangedAttackAnimation::init()
|
||||
{
|
||||
assert(attackingStack);
|
||||
assert(!myAnim->isDeadOrDying());
|
||||
|
||||
if(!attackingStack || myAnim->isDeadOrDying())
|
||||
{
|
||||
//FIXME: how is this possible?
|
||||
logAnim->warn("Shooting animation has not started yet but attacker is dead! Aborting...");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
logAnim->info("CRangedAttackAnimation::init: stack %s", stack->getName());
|
||||
|
||||
setAnimationGroup();
|
||||
initializeProjectile();
|
||||
return true;
|
||||
|
||||
return AttackAnimation::init();
|
||||
}
|
||||
|
||||
void RangedAttackAnimation::setAnimationGroup()
|
||||
@ -755,11 +703,11 @@ void RangedAttackAnimation::setAnimationGroup()
|
||||
|
||||
// Calculate projectile start position. Offsets are read out of the CRANIM.TXT.
|
||||
if (projectileAngle > straightAngle)
|
||||
group = getUpwardsGroup();
|
||||
setGroup(getUpwardsGroup());
|
||||
else if (projectileAngle < -straightAngle)
|
||||
group = getDownwardsGroup();
|
||||
setGroup(getDownwardsGroup());
|
||||
else
|
||||
group = getForwardGroup();
|
||||
setGroup(getForwardGroup());
|
||||
}
|
||||
|
||||
void RangedAttackAnimation::initializeProjectile()
|
||||
@ -769,17 +717,17 @@ void RangedAttackAnimation::initializeProjectile()
|
||||
Point shotOrigin = stackAnimation(attackingStack)->pos.topLeft() + Point(222, 265);
|
||||
int multiplier = stackFacingRight(attackingStack) ? 1 : -1;
|
||||
|
||||
if (group == getUpwardsGroup())
|
||||
if (getGroup() == getUpwardsGroup())
|
||||
{
|
||||
shotOrigin.x += ( -25 + shooterInfo->animation.upperRightMissleOffsetX ) * multiplier;
|
||||
shotOrigin.y += shooterInfo->animation.upperRightMissleOffsetY;
|
||||
}
|
||||
else if (group == getDownwardsGroup())
|
||||
else if (getGroup() == getDownwardsGroup())
|
||||
{
|
||||
shotOrigin.x += ( -25 + shooterInfo->animation.lowerRightMissleOffsetX ) * multiplier;
|
||||
shotOrigin.y += shooterInfo->animation.lowerRightMissleOffsetY;
|
||||
}
|
||||
else if (group == getForwardGroup())
|
||||
else if (getGroup() == getForwardGroup())
|
||||
{
|
||||
shotOrigin.x += ( -25 + shooterInfo->animation.rightMissleOffsetX ) * multiplier;
|
||||
shotOrigin.y += shooterInfo->animation.rightMissleOffsetY;
|
||||
@ -953,11 +901,9 @@ void CastAnimation::createProjectile(const Point & from, const Point & dest) con
|
||||
uint32_t CastAnimation::getAttackClimaxFrame() const
|
||||
{
|
||||
//TODO: allow defining this parameter in config file, separately from attackClimaxFrame of missile attacks
|
||||
uint32_t maxFrames = stackAnimation(attackingStack)->framesInGroup(group);
|
||||
uint32_t maxFrames = stackAnimation(attackingStack)->framesInGroup(getGroup());
|
||||
|
||||
if (maxFrames > 2)
|
||||
return maxFrames - 2;
|
||||
return 0;
|
||||
return maxFrames / 2;
|
||||
}
|
||||
|
||||
PointEffectAnimation::PointEffectAnimation(BattleInterface & owner, std::string soundName, std::string animationName, int effects):
|
||||
|
@ -63,86 +63,73 @@ public:
|
||||
const CStack * stack; //id of stack whose animation it is
|
||||
|
||||
BattleStackAnimation(BattleInterface & owner, const CStack * _stack);
|
||||
|
||||
void rotateStack(BattleHex hex);
|
||||
};
|
||||
|
||||
/// This class is responsible for managing the battle attack animation
|
||||
class AttackAnimation : public BattleStackAnimation
|
||||
class StackActionAnimation : public BattleStackAnimation
|
||||
{
|
||||
bool soundPlayed;
|
||||
protected:
|
||||
BattleHex dest; //attacked hex
|
||||
ECreatureAnimType::Type group;
|
||||
const CStack *defendingStack;
|
||||
const CStack *attackingStack;
|
||||
int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
|
||||
|
||||
const CCreature * getCreature() const;
|
||||
ECreatureAnimType::Type findValidGroup( const std::vector<ECreatureAnimType::Type> candidates ) const;
|
||||
|
||||
ECreatureAnimType::Type nextGroup;
|
||||
ECreatureAnimType::Type currGroup;
|
||||
std::string sound;
|
||||
public:
|
||||
virtual void playSound() = 0;
|
||||
void setNextGroup( ECreatureAnimType::Type group );
|
||||
void setGroup( ECreatureAnimType::Type group );
|
||||
void setSound( std::string sound );
|
||||
|
||||
void nextFrame() override;
|
||||
AttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender);
|
||||
~AttackAnimation();
|
||||
ECreatureAnimType::Type getGroup() const;
|
||||
|
||||
StackActionAnimation(BattleInterface & owner, const CStack * _stack);
|
||||
~StackActionAnimation();
|
||||
|
||||
bool init() override;
|
||||
};
|
||||
|
||||
/// Animation of a defending unit
|
||||
class DefenceAnimation : public BattleStackAnimation
|
||||
class DefenceAnimation : public StackActionAnimation
|
||||
{
|
||||
public:
|
||||
bool init() override;
|
||||
DefenceAnimation(BattleInterface & owner, const CStack * stack);
|
||||
};
|
||||
|
||||
/// Animation of a hit unit
|
||||
class HittedAnimation : public BattleStackAnimation
|
||||
class HittedAnimation : public StackActionAnimation
|
||||
{
|
||||
public:
|
||||
HittedAnimation(BattleInterface & owner, const CStack * stack);
|
||||
bool init() override;
|
||||
};
|
||||
|
||||
/// Animation of a dying unit
|
||||
class DeathAnimation : public BattleStackAnimation
|
||||
class DeathAnimation : public StackActionAnimation
|
||||
{
|
||||
bool rangedAttack;
|
||||
ECreatureAnimType::Type getMyAnimType();
|
||||
public:
|
||||
bool init() override;
|
||||
DeathAnimation(BattleInterface & owner, const CStack * stack, bool ranged);
|
||||
~DeathAnimation();
|
||||
};
|
||||
|
||||
class DummyAnimation : public BattleAnimation
|
||||
/// Resurrects stack from dead state
|
||||
class ResurrectionAnimation : public StackActionAnimation
|
||||
{
|
||||
private:
|
||||
int counter;
|
||||
int howMany;
|
||||
public:
|
||||
bool init() override;
|
||||
void nextFrame() override;
|
||||
|
||||
DummyAnimation(BattleInterface & owner, int howManyFrames);
|
||||
ResurrectionAnimation(BattleInterface & owner, const CStack * _stack);
|
||||
};
|
||||
|
||||
/// Hand-to-hand attack
|
||||
class MeleeAttackAnimation : public AttackAnimation
|
||||
class ColorTransformAnimation : public StackActionAnimation
|
||||
{
|
||||
bool multiAttack;
|
||||
std::vector<ColorFilter> steps;
|
||||
std::vector<float> timePoints;
|
||||
const CSpell * spell;
|
||||
|
||||
ECreatureAnimType::Type getUpwardsGroup() const;
|
||||
ECreatureAnimType::Type getForwardGroup() const;
|
||||
ECreatureAnimType::Type getDownwardsGroup() const;
|
||||
float totalProgress;
|
||||
|
||||
public:
|
||||
bool init() override;
|
||||
void nextFrame() override;
|
||||
void playSound() override;
|
||||
|
||||
MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack);
|
||||
ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
public:
|
||||
|
||||
static ColorTransformAnimation * petrifyAnimation (BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * cloneAnimation (BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * bloodlustAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * fadeInAnimation (BattleInterface & owner, const CStack * _stack);
|
||||
static ColorTransformAnimation * fadeOutAnimation (BattleInterface & owner, const CStack * _stack);
|
||||
};
|
||||
|
||||
/// Base class for all animations that play during stack movement
|
||||
@ -207,36 +194,38 @@ public:
|
||||
ReverseAnimation(BattleInterface & owner, const CStack * stack, BattleHex dest);
|
||||
};
|
||||
|
||||
/// Resurrects stack from dead state
|
||||
class ResurrectionAnimation : public BattleStackAnimation
|
||||
/// This class is responsible for managing the battle attack animation
|
||||
class AttackAnimation : public StackActionAnimation
|
||||
{
|
||||
public:
|
||||
bool init() override;
|
||||
protected:
|
||||
BattleHex dest; //attacked hex
|
||||
const CStack *defendingStack;
|
||||
const CStack *attackingStack;
|
||||
int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
|
||||
|
||||
ResurrectionAnimation(BattleInterface & owner, const CStack * _stack);
|
||||
const CCreature * getCreature() const;
|
||||
ECreatureAnimType::Type findValidGroup( const std::vector<ECreatureAnimType::Type> candidates ) const;
|
||||
|
||||
public:
|
||||
AttackAnimation(BattleInterface & owner, const CStack *attacker, BattleHex _dest, const CStack *defender);
|
||||
};
|
||||
|
||||
class ColorTransformAnimation : public BattleStackAnimation
|
||||
/// Hand-to-hand attack
|
||||
class MeleeAttackAnimation : public AttackAnimation
|
||||
{
|
||||
std::vector<ColorFilter> steps;
|
||||
std::vector<float> timePoints;
|
||||
const CSpell * spell;
|
||||
ECreatureAnimType::Type getUpwardsGroup(bool multiAttack) const;
|
||||
ECreatureAnimType::Type getForwardGroup(bool multiAttack) const;
|
||||
ECreatureAnimType::Type getDownwardsGroup(bool multiAttack) const;
|
||||
|
||||
float totalProgress;
|
||||
ECreatureAnimType::Type selectGroup(bool multiAttack);
|
||||
|
||||
public:
|
||||
MeleeAttackAnimation(BattleInterface & owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked, bool multiAttack);
|
||||
|
||||
bool init() override;
|
||||
void nextFrame() override;
|
||||
|
||||
ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
public:
|
||||
|
||||
static ColorTransformAnimation * petrifyAnimation (BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * cloneAnimation (BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * bloodlustAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell);
|
||||
static ColorTransformAnimation * fadeInAnimation (BattleInterface & owner, const CStack * _stack);
|
||||
static ColorTransformAnimation * fadeOutAnimation (BattleInterface & owner, const CStack * _stack);
|
||||
};
|
||||
|
||||
|
||||
class RangedAttackAnimation : public AttackAnimation
|
||||
{
|
||||
void setAnimationGroup();
|
||||
@ -260,7 +249,6 @@ public:
|
||||
|
||||
bool init() override;
|
||||
void nextFrame() override;
|
||||
void playSound() override;
|
||||
};
|
||||
|
||||
/// Shooting attack
|
||||
@ -307,6 +295,18 @@ public:
|
||||
CastAnimation(BattleInterface & owner, const CStack * attacker, BattleHex dest_, const CStack * defender, const CSpell * spell);
|
||||
};
|
||||
|
||||
class DummyAnimation : public BattleAnimation
|
||||
{
|
||||
private:
|
||||
int counter;
|
||||
int howMany;
|
||||
public:
|
||||
bool init() override;
|
||||
void nextFrame() override;
|
||||
|
||||
DummyAnimation(BattleInterface & owner, int howManyFrames);
|
||||
};
|
||||
|
||||
/// Class that plays effect at one or more positions along with (single) sound effect
|
||||
class PointEffectAnimation : public BattleAnimation
|
||||
{
|
||||
|
@ -56,6 +56,8 @@ namespace ECreatureAnimType
|
||||
{
|
||||
enum Type // list of creature animations, numbers were taken from def files
|
||||
{
|
||||
INVALID = -1,
|
||||
|
||||
MOVING = 0,
|
||||
MOUSEON = 1,
|
||||
HOLDING = 2, // base idling animation
|
||||
@ -82,6 +84,7 @@ enum Type // list of creature animations, numbers were taken from def files
|
||||
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
|
||||
FROZEN = 25, // new group, used when stack animation is paused (e.g. petrified). If empty - consist of first frame from HOLDING animation
|
||||
|
||||
CAST_UP = 30,
|
||||
CAST_FRONT = 31,
|
||||
|
@ -40,8 +40,14 @@ static void onAnimationFinished(const CStack *stack, std::weak_ptr<CreatureAnima
|
||||
if(!animation)
|
||||
return;
|
||||
|
||||
if (!stack->isFrozen() && animation->getType() == ECreatureAnimType::FROZEN)
|
||||
animation->setType(ECreatureAnimType::HOLDING);
|
||||
|
||||
if (animation->isIdle())
|
||||
{
|
||||
if (stack->isFrozen())
|
||||
animation->setType(ECreatureAnimType::FROZEN);
|
||||
|
||||
const CCreature *creature = stack->getCreature();
|
||||
|
||||
if (animation->framesInGroup(ECreatureAnimType::MOUSEON) > 0)
|
||||
@ -249,7 +255,7 @@ void BattleStacksController::setHoveredStack(const CStack *stack)
|
||||
{
|
||||
mouseHoveredStack = stack;
|
||||
|
||||
if (mouseHoveredStack)
|
||||
if (mouseHoveredStack && !mouseHoveredStack->isFrozen())
|
||||
{
|
||||
stackAnimation[mouseHoveredStack->ID]->setBorderColor(AnimationControls::getBlueBorder());
|
||||
if (stackAnimation[mouseHoveredStack->ID]->framesInGroup(ECreatureAnimType::MOUSEON) > 0)
|
||||
@ -361,8 +367,6 @@ void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
|
||||
}
|
||||
|
||||
bool stackHasProjectile = owner.projectilesController->hasActiveProjectile(stack, true);
|
||||
//bool stackPetrified = stack->hasBonus(Selector::source(Bonus::SPELL_EFFECT, SpellID::STONE_GAZE));
|
||||
//bool stackFrozen = stackHasProjectile || stackPetrified;
|
||||
|
||||
if (stackHasProjectile)
|
||||
stackAnimation[stack->ID]->pause();
|
||||
|
@ -190,6 +190,12 @@ CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController
|
||||
reverse->duplicateImage(ECreatureAnimType::DEATH_RANGED, reverse->size(ECreatureAnimType::DEATH_RANGED)-1, ECreatureAnimType::DEAD_RANGED);
|
||||
}
|
||||
|
||||
if(forward->size(ECreatureAnimType::FROZEN) == 0)
|
||||
{
|
||||
forward->duplicateImage(ECreatureAnimType::HOLDING, 0, ECreatureAnimType::FROZEN);
|
||||
reverse->duplicateImage(ECreatureAnimType::HOLDING, 0, ECreatureAnimType::FROZEN);
|
||||
}
|
||||
|
||||
if(forward->size(ECreatureAnimType::RESURRECTION) == 0)
|
||||
{
|
||||
for (size_t i = 0; i < forward->size(ECreatureAnimType::DEATH); ++i)
|
||||
|
@ -547,6 +547,11 @@ bool CUnitState::isGhost() const
|
||||
return ghost;
|
||||
}
|
||||
|
||||
bool CUnitState::isFrozen() const
|
||||
{
|
||||
return hasBonus(Selector::source(Bonus::SPELL_EFFECT, SpellID::STONE_GAZE));
|
||||
}
|
||||
|
||||
bool CUnitState::isValidTarget(bool allowDead) const
|
||||
{
|
||||
return (alive() || (allowDead && isDead())) && getPosition().isValid() && !isTurret();
|
||||
|
@ -195,6 +195,7 @@ public:
|
||||
bool ableToRetaliate() const override;
|
||||
bool alive() const override;
|
||||
bool isGhost() const override;
|
||||
bool isFrozen() const override;
|
||||
bool isValidTarget(bool allowDead = false) const override;
|
||||
|
||||
bool isClone() const override;
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
virtual bool ableToRetaliate() const = 0;
|
||||
virtual bool alive() const = 0;
|
||||
virtual bool isGhost() const = 0;
|
||||
virtual bool isFrozen() const = 0;
|
||||
|
||||
bool isDead() const;
|
||||
bool isTurret() const;
|
||||
|
Loading…
Reference in New Issue
Block a user