mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
more improvements for battle animations
- synchronized attack/defence animation - spell animation speed uses game settings - added logging domain for battle animations - fixed disrupting ray duration
This commit is contained in:
parent
4f7c6b8d34
commit
1a77fee7f7
@ -866,7 +866,7 @@ void CPlayerInterface::battleStacksAttacked(const std::vector<BattleStackAttacke
|
|||||||
if (defender && !elem.isSecondary())
|
if (defender && !elem.isSecondary())
|
||||||
battleInt->displayEffect(elem.effect, defender->position);
|
battleInt->displayEffect(elem.effect, defender->position);
|
||||||
}
|
}
|
||||||
bool shooting = (LOCPLINT->curAction ? LOCPLINT->curAction->actionType == Battle::SHOOT : false); //FIXME: why action is deleted during enchanter cast?
|
bool shooting = (LOCPLINT->curAction ? LOCPLINT->curAction->actionType != Battle::WALK_AND_ATTACK : false); //FIXME: why action is deleted during enchanter cast?
|
||||||
StackAttackedInfo to_put = {defender, elem.damageAmount, elem.killedAmount, attacker, shooting, elem.killed(), elem.willRebirth(), elem.cloneKilled()};
|
StackAttackedInfo to_put = {defender, elem.damageAmount, elem.killedAmount, attacker, shooting, elem.killed(), elem.willRebirth(), elem.cloneKilled()};
|
||||||
arg.push_back(to_put);
|
arg.push_back(to_put);
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,18 @@
|
|||||||
|
|
||||||
CBattleAnimation::CBattleAnimation(CBattleInterface * _owner)
|
CBattleAnimation::CBattleAnimation(CBattleInterface * _owner)
|
||||||
: owner(_owner), ID(_owner->animIDhelper++)
|
: owner(_owner), ID(_owner->animIDhelper++)
|
||||||
{}
|
{
|
||||||
|
logAnim->traceStream() << "Animation #" << ID << " created";
|
||||||
|
}
|
||||||
|
|
||||||
|
CBattleAnimation::~CBattleAnimation()
|
||||||
|
{
|
||||||
|
logAnim->traceStream() << "Animation #" << ID << " deleted";
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleAnimation::endAnim()
|
void CBattleAnimation::endAnim()
|
||||||
{
|
{
|
||||||
|
logAnim->traceStream() << "Animation #" << ID << " ended, type is " << typeid(this).name();
|
||||||
for(auto & elem : owner->pendingAnims)
|
for(auto & elem : owner->pendingAnims)
|
||||||
{
|
{
|
||||||
if(elem.first == this)
|
if(elem.first == this)
|
||||||
@ -58,7 +66,7 @@ bool CBattleAnimation::isEarliest(bool perStackConcurrency)
|
|||||||
if(perStackConcurrency && stAnim && thAnim && stAnim->stack->ID != thAnim->stack->ID)
|
if(perStackConcurrency && stAnim && thAnim && stAnim->stack->ID != thAnim->stack->ID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sen && thSen && sen != thSen && perStackConcurrency)
|
if(perStackConcurrency && sen && thSen && sen != thSen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CReverseAnimation * revAnim = dynamic_cast<CReverseAnimation *>(stAnim);
|
CReverseAnimation * revAnim = dynamic_cast<CReverseAnimation *>(stAnim);
|
||||||
@ -105,6 +113,17 @@ void CAttackAnimation::endAnim()
|
|||||||
|
|
||||||
bool CAttackAnimation::checkInitialConditions()
|
bool CAttackAnimation::checkInitialConditions()
|
||||||
{
|
{
|
||||||
|
for(auto & elem : owner->pendingAnims)
|
||||||
|
{
|
||||||
|
CBattleStackAnimation * stAnim = dynamic_cast<CBattleStackAnimation *>(elem.first);
|
||||||
|
CReverseAnimation * revAnim = dynamic_cast<CReverseAnimation *>(stAnim);
|
||||||
|
|
||||||
|
if(revAnim) // enemy must be fully reversed
|
||||||
|
{
|
||||||
|
if (revAnim->stack->ID == attackedStack->ID)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return isEarliest(false);
|
return isEarliest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +143,7 @@ CAttackAnimation::CAttackAnimation(CBattleInterface *_owner, const CStack *attac
|
|||||||
|
|
||||||
CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, CBattleInterface * _owner)
|
CDefenceAnimation::CDefenceAnimation(StackAttackedInfo _attackedInfo, CBattleInterface * _owner)
|
||||||
: CBattleStackAnimation(_owner, _attackedInfo.defender),
|
: CBattleStackAnimation(_owner, _attackedInfo.defender),
|
||||||
attacker(_attackedInfo.attacker), byShooting(_attackedInfo.byShooting),
|
attacker(_attackedInfo.attacker), rangedAttack(_attackedInfo.rangedAttack),
|
||||||
killed(_attackedInfo.killed)
|
killed(_attackedInfo.killed)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -144,23 +163,15 @@ bool CDefenceAnimation::init()
|
|||||||
if(attAnim && attAnim->stack->ID != stack->ID)
|
if(attAnim && attAnim->stack->ID != stack->ID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(attacker != nullptr)
|
|
||||||
{
|
|
||||||
int attackerAnimType = owner->creAnims[attacker->ID]->getType();
|
|
||||||
if( ( attackerAnimType == CCreatureAnim::ATTACK_UP ||
|
|
||||||
attackerAnimType == CCreatureAnim::ATTACK_FRONT ||
|
|
||||||
attackerAnimType == CCreatureAnim::ATTACK_DOWN ) )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CReverseAnimation * animAsRev = dynamic_cast<CReverseAnimation *>(elem.first);
|
CReverseAnimation * animAsRev = dynamic_cast<CReverseAnimation *>(elem.first);
|
||||||
|
|
||||||
if(animAsRev && animAsRev->priority)
|
if(animAsRev /*&& animAsRev->priority*/)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(elem.first)
|
if(elem.first)
|
||||||
vstd::amin(lowestMoveID, elem.first->ID);
|
vstd::amin(lowestMoveID, elem.first->ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ID > lowestMoveID)
|
if(ID > lowestMoveID)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -172,7 +183,7 @@ bool CDefenceAnimation::init()
|
|||||||
}
|
}
|
||||||
//unit reversed
|
//unit reversed
|
||||||
|
|
||||||
if(byShooting) //delay hit animation
|
if(rangedAttack) //delay hit animation
|
||||||
{
|
{
|
||||||
for(std::list<ProjectileInfo>::const_iterator it = owner->projectiles.begin(); it != owner->projectiles.end(); ++it)
|
for(std::list<ProjectileInfo>::const_iterator it = owner->projectiles.begin(); it != owner->projectiles.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -183,27 +194,61 @@ bool CDefenceAnimation::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//initializing
|
// synchronize animation with attacker, unless defending or attacked by shooter:
|
||||||
if(killed)
|
// wait for 1/2 of attack animation
|
||||||
|
if (!rangedAttack && getMyAnimType() != CCreatureAnim::DEFENCE)
|
||||||
{
|
{
|
||||||
CCS->soundh->playSound(battle_sound(stack->getCreature(), killed));
|
float fps = AnimationControls::getCreatureAnimationSpeed(
|
||||||
myAnim->setType(CCreatureAnim::DEATH); //death
|
stack->getCreature(), owner->creAnims[stack->ID], getMyAnimType());
|
||||||
|
|
||||||
|
timeToWait = myAnim->framesInGroup(getMyAnimType()) / fps;
|
||||||
|
|
||||||
|
myAnim->setType(CCreatureAnim::HOLDING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: this block doesn't seems correct if the unit is defending.
|
timeToWait = 0;
|
||||||
CCS->soundh->playSound(battle_sound(stack->getCreature(), wince));
|
startAnimation();
|
||||||
myAnim->setType(CCreatureAnim::HITTED); //getting hit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myAnim->onAnimationReset += std::bind(&CDefenceAnimation::endAnim, this);
|
|
||||||
|
|
||||||
return true; //initialized successfuly
|
return true; //initialized successfuly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CDefenceAnimation::getMySound()
|
||||||
|
{
|
||||||
|
if(killed)
|
||||||
|
return battle_sound(stack->getCreature(), killed);
|
||||||
|
|
||||||
|
if (stack->valOfBonuses(Selector::durationType(Bonus::STACK_GETS_TURN)))
|
||||||
|
return battle_sound(stack->getCreature(), defend);
|
||||||
|
return battle_sound(stack->getCreature(), wince);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCreatureAnim::EAnimType CDefenceAnimation::getMyAnimType()
|
||||||
|
{
|
||||||
|
if(killed)
|
||||||
|
return CCreatureAnim::DEATH;
|
||||||
|
|
||||||
|
if (stack->valOfBonuses(Selector::durationType(Bonus::STACK_GETS_TURN)))
|
||||||
|
return CCreatureAnim::DEFENCE;
|
||||||
|
return CCreatureAnim::HITTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDefenceAnimation::startAnimation()
|
||||||
|
{
|
||||||
|
CCS->soundh->playSound(getMySound());
|
||||||
|
myAnim->setType(getMyAnimType());
|
||||||
|
myAnim->onAnimationReset += std::bind(&CDefenceAnimation::endAnim, this);
|
||||||
|
}
|
||||||
|
|
||||||
void CDefenceAnimation::nextFrame()
|
void CDefenceAnimation::nextFrame()
|
||||||
{
|
{
|
||||||
assert(myAnim->getType() == CCreatureAnim::HITTED || myAnim->getType() == CCreatureAnim::DEATH);
|
if (timeToWait > 0)
|
||||||
|
{
|
||||||
|
timeToWait -= float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000;
|
||||||
|
if (timeToWait <= 0)
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
CBattleAnimation::nextFrame();
|
CBattleAnimation::nextFrame();
|
||||||
}
|
}
|
||||||
@ -262,6 +307,12 @@ bool CMeleeAttackAnimation::init()
|
|||||||
owner->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
|
owner->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opponent must face attacker ( = different directions) before he can be attacked
|
||||||
|
if (attackingStack && attackedStack &&
|
||||||
|
owner->creDir[attackingStack->ID] == owner->creDir[attackedStack->ID])
|
||||||
|
return false;
|
||||||
|
|
||||||
//reversed
|
//reversed
|
||||||
|
|
||||||
shooting = false;
|
shooting = false;
|
||||||
@ -386,7 +437,7 @@ bool CMovementAnimation::init()
|
|||||||
{
|
{
|
||||||
float distance = sqrt(distanceX * distanceX + distanceY * distanceY);
|
float distance = sqrt(distanceX * distanceX + distanceY * distanceY);
|
||||||
|
|
||||||
timeToMove *= distance / AnimationControls::getFlightDistance(stack->getCreature());
|
timeToMove *= AnimationControls::getFlightDistance(stack->getCreature()) / distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -614,6 +665,11 @@ bool CShootingAnimation::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opponent must face attacker ( = different directions) before he can be attacked
|
||||||
|
if (attackingStack && attackedStack &&
|
||||||
|
owner->creDir[attackingStack->ID] == owner->creDir[attackedStack->ID])
|
||||||
|
return false;
|
||||||
|
|
||||||
// Create the projectile animation
|
// Create the projectile animation
|
||||||
|
|
||||||
//maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
//maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
||||||
@ -817,7 +873,7 @@ bool CSpellEffectAnimation::init()
|
|||||||
CSDL_Ext::VflipSurf(elem.bitmap);
|
CSDL_Ext::VflipSurf(elem.bitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
be.frame = 0;
|
be.currentFrame = 0;
|
||||||
be.maxFrame = be.anim->ourImages.size();
|
be.maxFrame = be.anim->ourImages.size();
|
||||||
be.x = i * anim->width + owner->pos.x;
|
be.x = i * anim->width + owner->pos.x;
|
||||||
be.y = j * anim->height + owner->pos.y;
|
be.y = j * anim->height + owner->pos.y;
|
||||||
@ -854,7 +910,7 @@ bool CSpellEffectAnimation::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
be.frame = 0;
|
be.currentFrame = 0;
|
||||||
be.maxFrame = be.anim->ourImages.size();
|
be.maxFrame = be.anim->ourImages.size();
|
||||||
if(effect == 1)
|
if(effect == 1)
|
||||||
be.maxFrame = 3;
|
be.maxFrame = 3;
|
||||||
@ -909,9 +965,9 @@ void CSpellEffectAnimation::nextFrame()
|
|||||||
{
|
{
|
||||||
if(elem.effectID == ID)
|
if(elem.effectID == ID)
|
||||||
{
|
{
|
||||||
++(elem.frame);
|
elem.currentFrame += AnimationControls::getSpellEffectSpeed() * GH.mainFPSmng->getElapsedMilliseconds() / 1000;
|
||||||
|
|
||||||
if(elem.frame == elem.maxFrame)
|
if(elem.currentFrame >= elem.maxFrame)
|
||||||
{
|
{
|
||||||
endAnim();
|
endAnim();
|
||||||
break;
|
break;
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
virtual bool init() = 0; //to be called - if returned false, call again until returns true
|
virtual bool init() = 0; //to be called - if returned false, call again until returns true
|
||||||
virtual void nextFrame() {} //call every new frame
|
virtual void nextFrame() {} //call every new frame
|
||||||
virtual void endAnim(); //to be called mostly internally; in this class it removes animation from pendingAnims list
|
virtual void endAnim(); //to be called mostly internally; in this class it removes animation from pendingAnims list
|
||||||
virtual ~CBattleAnimation(){}
|
virtual ~CBattleAnimation();
|
||||||
|
|
||||||
bool isEarliest(bool perStackConcurrency); //determines if this animation is earliest of all
|
bool isEarliest(bool perStackConcurrency); //determines if this animation is earliest of all
|
||||||
|
|
||||||
@ -69,11 +69,16 @@ public:
|
|||||||
/// Animation of a defending unit
|
/// Animation of a defending unit
|
||||||
class CDefenceAnimation : public CBattleStackAnimation
|
class CDefenceAnimation : public CBattleStackAnimation
|
||||||
{
|
{
|
||||||
private:
|
CCreatureAnim::EAnimType getMyAnimType();
|
||||||
//std::vector<StackAttackedInfo> attackedInfos;
|
std::string getMySound();
|
||||||
|
|
||||||
|
void startAnimation();
|
||||||
|
|
||||||
const CStack * attacker; //attacking stack
|
const CStack * attacker; //attacking stack
|
||||||
bool byShooting; //if true, stack has been attacked by shooting
|
bool rangedAttack; //if true, stack has been attacked by shooting
|
||||||
bool killed; //if true, stack has been killed
|
bool killed; //if true, stack has been killed
|
||||||
|
|
||||||
|
float timeToWait; // for how long this animation should be paused
|
||||||
public:
|
public:
|
||||||
bool init();
|
bool init();
|
||||||
void nextFrame();
|
void nextFrame();
|
||||||
|
@ -1010,7 +1010,10 @@ void CBattleInterface::showBattleEffects(const std::vector<const BattleEffect *>
|
|||||||
{
|
{
|
||||||
for(auto & elem : battleEffects)
|
for(auto & elem : battleEffects)
|
||||||
{
|
{
|
||||||
SDL_Surface * bitmapToBlit = elem->anim->ourImages[(elem->frame)%elem->anim->ourImages.size()].bitmap;
|
int currentFrame = floor(elem->currentFrame);
|
||||||
|
currentFrame %= elem->anim->ourImages.size();
|
||||||
|
|
||||||
|
SDL_Surface * bitmapToBlit = elem->anim->ourImages[currentFrame].bitmap;
|
||||||
SDL_Rect temp_rect = genRect(bitmapToBlit->h, bitmapToBlit->w, elem->x, elem->y);
|
SDL_Rect temp_rect = genRect(bitmapToBlit->h, bitmapToBlit->w, elem->x, elem->y);
|
||||||
SDL_BlitSurface(bitmapToBlit, nullptr, to, &temp_rect);
|
SDL_BlitSurface(bitmapToBlit, nullptr, to, &temp_rect);
|
||||||
}
|
}
|
||||||
@ -1520,16 +1523,11 @@ void CBattleInterface::stackAttacking( const CStack * attacker, BattleHex dest,
|
|||||||
{
|
{
|
||||||
addNewAnim(new CMeleeAttackAnimation(this, attacker, dest, attacked));
|
addNewAnim(new CMeleeAttackAnimation(this, attacker, dest, attacked));
|
||||||
}
|
}
|
||||||
waitForAnims();
|
//waitForAnims();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::newRoundFirst( int round )
|
void CBattleInterface::newRoundFirst( int round )
|
||||||
{
|
{
|
||||||
//handle regeneration
|
|
||||||
std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(); //gets only alive stacks
|
|
||||||
// for(const CStack *s : stacks)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
waitForAnims();
|
waitForAnims();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1725,12 +1723,13 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
|||||||
|
|
||||||
//displaying animation
|
//displaying animation
|
||||||
CDefEssential * animDef = CDefHandler::giveDefEss(animToDisplay);
|
CDefEssential * animDef = CDefHandler::giveDefEss(animToDisplay);
|
||||||
|
double diffX = (destcoord.x - srccoord.x)*(destcoord.x - srccoord.x);
|
||||||
|
double diffY = (destcoord.y - srccoord.y)*(destcoord.y - srccoord.y);
|
||||||
|
double distance = sqrt(diffX + diffY);
|
||||||
|
|
||||||
int steps = sqrt(static_cast<double>((destcoord.x - srccoord.x)*(destcoord.x - srccoord.x) + (destcoord.y - srccoord.y) * (destcoord.y - srccoord.y))) / 40;
|
int steps = distance / AnimationControls::getSpellEffectSpeed() + 1;
|
||||||
if(steps <= 0)
|
int dx = (destcoord.x - srccoord.x - animDef->ourImages[0].bitmap->w)/steps;
|
||||||
steps = 1;
|
int dy = (destcoord.y - srccoord.y - animDef->ourImages[0].bitmap->h)/steps;
|
||||||
|
|
||||||
int dx = (destcoord.x - srccoord.x - animDef->ourImages[0].bitmap->w)/steps, dy = (destcoord.y - srccoord.y - animDef->ourImages[0].bitmap->h)/steps;
|
|
||||||
|
|
||||||
delete animDef;
|
delete animDef;
|
||||||
addNewAnim(new CSpellEffectAnimation(this, animToDisplay, srccoord.x, srccoord.y, dx, dy, Vflip));
|
addNewAnim(new CSpellEffectAnimation(this, animToDisplay, srccoord.x, srccoord.y, dx, dy, Vflip));
|
||||||
@ -2614,7 +2613,7 @@ void CBattleInterface::showQueue()
|
|||||||
|
|
||||||
void CBattleInterface::startAction(const BattleAction* action)
|
void CBattleInterface::startAction(const BattleAction* action)
|
||||||
{
|
{
|
||||||
setActiveStack(nullptr);
|
//setActiveStack(nullptr);
|
||||||
setHoveredStack(nullptr);
|
setHoveredStack(nullptr);
|
||||||
|
|
||||||
if(action->actionType == Battle::END_TACTIC_PHASE)
|
if(action->actionType == Battle::END_TACTIC_PHASE)
|
||||||
|
@ -57,7 +57,7 @@ struct StackAttackedInfo
|
|||||||
unsigned int dmg; //damage dealt
|
unsigned int dmg; //damage dealt
|
||||||
unsigned int amountKilled; //how many creatures in stack has been killed
|
unsigned int amountKilled; //how many creatures in stack has been killed
|
||||||
const CStack * attacker; //attacking stack
|
const CStack * attacker; //attacking stack
|
||||||
bool byShooting; //if true, stack has been attacked by shooting
|
bool rangedAttack; //if true, stack has been attacked by shooting
|
||||||
bool killed; //if true, stack has been killed
|
bool killed; //if true, stack has been killed
|
||||||
bool rebirth; //if true, play rebirth animation after all
|
bool rebirth; //if true, play rebirth animation after all
|
||||||
bool cloneKilled;
|
bool cloneKilled;
|
||||||
@ -67,7 +67,8 @@ struct StackAttackedInfo
|
|||||||
struct BattleEffect
|
struct BattleEffect
|
||||||
{
|
{
|
||||||
int x, y; //position on the screen
|
int x, y; //position on the screen
|
||||||
int frame, maxFrame;
|
float currentFrame;
|
||||||
|
int maxFrame;
|
||||||
CDefHandler * anim; //animation to display
|
CDefHandler * anim; //animation to display
|
||||||
int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
|
int effectID; //uniqueID equal ot ID of appropriate CSpellEffectAnim
|
||||||
BattleHex position; //Indicates if effect which hex the effect is drawn on
|
BattleHex position; //Indicates if effect which hex the effect is drawn on
|
||||||
|
@ -48,11 +48,8 @@ CCreatureAnimation * AnimationControls::getAnimation(const CCreature * creature)
|
|||||||
|
|
||||||
float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t group)
|
float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t group)
|
||||||
{
|
{
|
||||||
// possible new fields for creature format
|
// possible new fields for creature format:
|
||||||
//Shoot Animation Time
|
//split "Attack time" into "Shoot Time" and "Cast Time"
|
||||||
//Cast Animation Time
|
|
||||||
//Defence and/or Death Animation Time
|
|
||||||
|
|
||||||
|
|
||||||
// a lot of arbitrary multipliers, mostly to make animation speed closer to H3
|
// a lot of arbitrary multipliers, mostly to make animation speed closer to H3
|
||||||
CCreatureAnim::EAnimType type = CCreatureAnim::EAnimType(group);
|
CCreatureAnim::EAnimType type = CCreatureAnim::EAnimType(group);
|
||||||
@ -69,9 +66,6 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
|
|||||||
case CCreatureAnim::HOLDING:
|
case CCreatureAnim::HOLDING:
|
||||||
return baseSpeed;
|
return baseSpeed;
|
||||||
|
|
||||||
case CCreatureAnim::ATTACK_UP:
|
|
||||||
case CCreatureAnim::ATTACK_FRONT:
|
|
||||||
case CCreatureAnim::ATTACK_DOWN:
|
|
||||||
case CCreatureAnim::SHOOT_UP:
|
case CCreatureAnim::SHOOT_UP:
|
||||||
case CCreatureAnim::SHOOT_FRONT:
|
case CCreatureAnim::SHOOT_FRONT:
|
||||||
case CCreatureAnim::SHOOT_DOWN:
|
case CCreatureAnim::SHOOT_DOWN:
|
||||||
@ -80,6 +74,18 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
|
|||||||
case CCreatureAnim::CAST_DOWN:
|
case CCreatureAnim::CAST_DOWN:
|
||||||
return speed * 2 / creature->animation.attackAnimationTime / anim->framesInGroup(type);
|
return speed * 2 / creature->animation.attackAnimationTime / anim->framesInGroup(type);
|
||||||
|
|
||||||
|
// as strange as it looks like "attackAnimationTime" does not affects melee attacks
|
||||||
|
// necessary because length of attack animation must be same for all creatures for synchronization
|
||||||
|
case CCreatureAnim::ATTACK_UP:
|
||||||
|
case CCreatureAnim::ATTACK_FRONT:
|
||||||
|
case CCreatureAnim::ATTACK_DOWN:
|
||||||
|
case CCreatureAnim::DEFENCE:
|
||||||
|
return speed * 2 / anim->framesInGroup(type);
|
||||||
|
|
||||||
|
case CCreatureAnim::DEATH:
|
||||||
|
case CCreatureAnim::HITTED: // time-wise equals 1/2 of attack animation length
|
||||||
|
return speed / anim->framesInGroup(type);
|
||||||
|
|
||||||
case CCreatureAnim::TURN_L:
|
case CCreatureAnim::TURN_L:
|
||||||
case CCreatureAnim::TURN_R:
|
case CCreatureAnim::TURN_R:
|
||||||
return speed;
|
return speed;
|
||||||
@ -88,9 +94,6 @@ float AnimationControls::getCreatureAnimationSpeed(const CCreature * creature, c
|
|||||||
case CCreatureAnim::MOVE_END:
|
case CCreatureAnim::MOVE_END:
|
||||||
return speed / 5;
|
return speed / 5;
|
||||||
|
|
||||||
case CCreatureAnim::HITTED:
|
|
||||||
case CCreatureAnim::DEFENCE:
|
|
||||||
case CCreatureAnim::DEATH:
|
|
||||||
case CCreatureAnim::DEAD:
|
case CCreatureAnim::DEAD:
|
||||||
return speed / 5;
|
return speed / 5;
|
||||||
|
|
||||||
@ -105,6 +108,11 @@ float AnimationControls::getProjectileSpeed()
|
|||||||
return settings["battle"]["animationSpeed"].Float() * 100;
|
return settings["battle"]["animationSpeed"].Float() * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AnimationControls::getSpellEffectSpeed()
|
||||||
|
{
|
||||||
|
return settings["battle"]["animationSpeed"].Float() * 60;
|
||||||
|
}
|
||||||
|
|
||||||
float AnimationControls::getMovementDuration(const CCreature * creature)
|
float AnimationControls::getMovementDuration(const CCreature * creature)
|
||||||
{
|
{
|
||||||
return settings["battle"]["animationSpeed"].Float() * 4 / creature->animation.walkAnimationTime;
|
return settings["battle"]["animationSpeed"].Float() * 4 / creature->animation.walkAnimationTime;
|
||||||
@ -201,7 +209,7 @@ bool CCreatureAnimation::incrementFrame(float timePassed)
|
|||||||
currentFrame += timePassed * speed;
|
currentFrame += timePassed * speed;
|
||||||
if (currentFrame >= float(framesInGroup(type)))
|
if (currentFrame >= float(framesInGroup(type)))
|
||||||
{
|
{
|
||||||
// just in case of extremely low fps
|
// just in case of extremely low fps (or insanely high speed)
|
||||||
while (currentFrame >= float(framesInGroup(type)))
|
while (currentFrame >= float(framesInGroup(type)))
|
||||||
currentFrame -= framesInGroup(type);
|
currentFrame -= framesInGroup(type);
|
||||||
|
|
||||||
|
@ -28,13 +28,16 @@ namespace AnimationControls
|
|||||||
/// creates animation object with preset speed control
|
/// creates animation object with preset speed control
|
||||||
CCreatureAnimation * getAnimation(const CCreature * creature);
|
CCreatureAnimation * getAnimation(const CCreature * creature);
|
||||||
|
|
||||||
/// returns animation speed of specific group, taking in mind game setting
|
/// returns animation speed of specific group, taking in mind game setting (in frames per second)
|
||||||
float getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t groupID);
|
float getCreatureAnimationSpeed(const CCreature * creature, const CCreatureAnimation * anim, size_t groupID);
|
||||||
|
|
||||||
/// returns how far projectile should move each frame
|
/// returns how far projectile should move each frame
|
||||||
/// TODO: make it time-based
|
/// TODO: make it time-based
|
||||||
float getProjectileSpeed();
|
float getProjectileSpeed();
|
||||||
|
|
||||||
|
/// returns speed of any spell effects, including any special effects like morale (in frames per second)
|
||||||
|
float getSpellEffectSpeed();
|
||||||
|
|
||||||
/// returns duration of full movement animation, in seconds. Needed to move animation on screen
|
/// returns duration of full movement animation, in seconds. Needed to move animation on screen
|
||||||
float getMovementDuration(const CCreature * creature);
|
float getMovementDuration(const CCreature * creature);
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@
|
|||||||
"type": "PRIMARY_SKILL",
|
"type": "PRIMARY_SKILL",
|
||||||
"subtype": "primSkill.defence",
|
"subtype": "primSkill.defence",
|
||||||
"valueType": "ADDITIVE_VALUE",
|
"valueType": "ADDITIVE_VALUE",
|
||||||
"duration": "N_TURNS",
|
"duration": "ONE_BATTLE",
|
||||||
"values":[-3,-3,-4,-5]
|
"values":[-3,-3,-4,-5]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -54,10 +54,9 @@ boost::recursive_mutex CLogManager::smx;
|
|||||||
DLL_LINKAGE CLogger * logGlobal = CLogger::getGlobalLogger();
|
DLL_LINKAGE CLogger * logGlobal = CLogger::getGlobalLogger();
|
||||||
|
|
||||||
DLL_LINKAGE CLogger * logBonus = CLogger::getLogger(CLoggerDomain("bonus"));
|
DLL_LINKAGE CLogger * logBonus = CLogger::getLogger(CLoggerDomain("bonus"));
|
||||||
|
|
||||||
DLL_LINKAGE CLogger * logNetwork = CLogger::getLogger(CLoggerDomain("network"));
|
DLL_LINKAGE CLogger * logNetwork = CLogger::getLogger(CLoggerDomain("network"));
|
||||||
|
|
||||||
DLL_LINKAGE CLogger * logAi = CLogger::getLogger(CLoggerDomain("ai"));
|
DLL_LINKAGE CLogger * logAi = CLogger::getLogger(CLoggerDomain("ai"));
|
||||||
|
DLL_LINKAGE CLogger * logAnim = CLogger::getLogger(CLoggerDomain("animation"));
|
||||||
|
|
||||||
CLogger * CLogger::getLogger(const CLoggerDomain & domain)
|
CLogger * CLogger::getLogger(const CLoggerDomain & domain)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +125,7 @@ extern DLL_LINKAGE CLogger * logGlobal;
|
|||||||
extern DLL_LINKAGE CLogger * logBonus;
|
extern DLL_LINKAGE CLogger * logBonus;
|
||||||
extern DLL_LINKAGE CLogger * logNetwork;
|
extern DLL_LINKAGE CLogger * logNetwork;
|
||||||
extern DLL_LINKAGE CLogger * logAi;
|
extern DLL_LINKAGE CLogger * logAi;
|
||||||
|
extern DLL_LINKAGE CLogger * logAnim;
|
||||||
|
|
||||||
/// RAII class for tracing the program execution.
|
/// RAII class for tracing the program execution.
|
||||||
/// It prints "Leaving function XYZ" automatically when the object gets destructed.
|
/// It prints "Leaving function XYZ" automatically when the object gets destructed.
|
||||||
|
Loading…
Reference in New Issue
Block a user