1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

Fixes for creature rendering order

This commit is contained in:
Ivan Savenko 2022-11-28 22:35:38 +02:00
parent f5f719b78e
commit 9e11b8f38a
5 changed files with 64 additions and 39 deletions

View File

@ -352,7 +352,7 @@ bool CMeleeAttackAnimation::init()
if(!CAttackAnimation::checkInitialConditions())
return false;
if(!attackingStack || myAnim->isDead())
if(!attackingStack || myAnim->isDeadOrDying())
{
delete this;
return false;
@ -444,12 +444,19 @@ CMeleeAttackAnimation::CMeleeAttackAnimation(CBattleInterface * _owner, const CS
logAnim->debug("Created melee attack anim for %s", attacker->getName());
}
CStackMoveAnimation::CStackMoveAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex _currentHex):
CBattleStackAnimation(_owner, _stack),
currentHex(_currentHex)
{
}
bool CMovementAnimation::init()
{
if( !CBattleAnimation::checkInitialConditions() )
return false;
if(!stack || myAnim->isDead())
if(!stack || myAnim->isDeadOrDying())
{
delete this;
return false;
@ -464,7 +471,7 @@ bool CMovementAnimation::init()
}
//reverse unit if necessary
if(owner->stacksController->shouldRotate(stack, oldPos, nextHex))
if(owner->stacksController->shouldRotate(stack, oldPos, currentHex))
{
// it seems that H3 does NOT plays full rotation animation here in most situations
// Logical since it takes quite a lot of time
@ -490,7 +497,7 @@ bool CMovementAnimation::init()
}
Point begPosition = owner->stacksController->getStackPositionAtHex(oldPos, stack);
Point endPosition = owner->stacksController->getStackPositionAtHex(nextHex, stack);
Point endPosition = owner->stacksController->getStackPositionAtHex(currentHex, stack);
timeToMove = AnimationControls::getMovementDuration(stack->getCreature());
@ -523,7 +530,7 @@ void CMovementAnimation::nextFrame()
if(progress >= 1.0)
{
// Sets the position of the creature animation sprites
Point coords = owner->stacksController->getStackPositionAtHex(nextHex, stack);
Point coords = owner->stacksController->getStackPositionAtHex(currentHex, stack);
myAnim->pos = coords;
// true if creature haven't reached the final destination hex
@ -531,8 +538,8 @@ void CMovementAnimation::nextFrame()
{
// update the next hex field which has to be reached by the stack
curentMoveIndex++;
oldPos = nextHex;
nextHex = destTiles[curentMoveIndex];
oldPos = currentHex;
currentHex = destTiles[curentMoveIndex];
// request re-initialization
initialized = false;
@ -546,8 +553,8 @@ CMovementAnimation::~CMovementAnimation()
{
assert(stack);
myAnim->pos = owner->stacksController->getStackPositionAtHex(nextHex, stack);
owner->stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, nextHex));
myAnim->pos = owner->stacksController->getStackPositionAtHex(currentHex, stack);
owner->stacksController->addNewAnim(new CMovementEndAnimation(owner, stack, currentHex));
if(owner->moveSoundHander != -1)
{
@ -557,21 +564,20 @@ CMovementAnimation::~CMovementAnimation()
}
CMovementAnimation::CMovementAnimation(CBattleInterface *_owner, const CStack *_stack, std::vector<BattleHex> _destTiles, int _distance)
: CBattleStackAnimation(_owner, _stack),
: CStackMoveAnimation(_owner, _stack, _destTiles.front()),
destTiles(_destTiles),
curentMoveIndex(0),
oldPos(stack->getPosition()),
begX(0), begY(0),
distanceX(0), distanceY(0),
timeToMove(0.0),
progress(0.0),
nextHex(destTiles.front())
progress(0.0)
{
logAnim->debug("Created movement anim for %s", stack->getName());
}
CMovementEndAnimation::CMovementEndAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex destTile)
: CBattleStackAnimation(_owner, _stack), destinationTile(destTile)
: CStackMoveAnimation(_owner, _stack, destTile)
{
logAnim->debug("Created movement end anim for %s", stack->getName());
}
@ -582,7 +588,7 @@ bool CMovementEndAnimation::init()
// return false;
if(!stack || myAnim->framesInGroup(CCreatureAnim::MOVE_END) == 0 ||
myAnim->isDead())
myAnim->isDeadOrDying())
{
delete this;
return false;
@ -606,7 +612,7 @@ CMovementEndAnimation::~CMovementEndAnimation()
}
CMovementStartAnimation::CMovementStartAnimation(CBattleInterface * _owner, const CStack * _stack)
: CBattleStackAnimation(_owner, _stack)
: CStackMoveAnimation(_owner, _stack, _stack->getPosition())
{
logAnim->debug("Created movement start anim for %s", stack->getName());
}
@ -617,7 +623,7 @@ bool CMovementStartAnimation::init()
return false;
if(!stack || myAnim->isDead())
if(!stack || myAnim->isDeadOrDying())
{
delete this;
return false;
@ -631,8 +637,7 @@ bool CMovementStartAnimation::init()
}
CReverseAnimation::CReverseAnimation(CBattleInterface * _owner, const CStack * stack, BattleHex dest, bool _priority)
: CBattleStackAnimation(_owner, stack),
hex(dest),
: CStackMoveAnimation(_owner, stack, dest),
priority(_priority)
{
logAnim->debug("Created reverse anim for %s", stack->getName());
@ -640,7 +645,7 @@ CReverseAnimation::CReverseAnimation(CBattleInterface * _owner, const CStack * s
bool CReverseAnimation::init()
{
if(myAnim == nullptr || myAnim->isDead())
if(myAnim == nullptr || myAnim->isDeadOrDying())
{
delete this;
return false; //there is no such creature
@ -682,7 +687,7 @@ void CReverseAnimation::setupSecondPart()
return;
}
rotateStack(hex);
rotateStack(currentHex);
if(myAnim->framesInGroup(CCreatureAnim::TURN_R))
{
@ -715,9 +720,9 @@ bool CShootingAnimation::init()
return false;
assert(attackingStack);
assert(!myAnim->isDead());
assert(!myAnim->isDeadOrDying());
if(!attackingStack || myAnim->isDead())
if(!attackingStack || myAnim->isDeadOrDying())
{
//FIXME: how is this possible?
logAnim->warn("Shooting animation has not started yet but attacker is dead! Aborting...");
@ -884,7 +889,7 @@ bool CCastAnimation::init()
if(!CAttackAnimation::checkInitialConditions())
return false;
if(!attackingStack || myAnim->isDead())
if(!attackingStack || myAnim->isDeadOrDying())
{
delete this;
return false;

View File

@ -128,8 +128,16 @@ public:
CMeleeAttackAnimation(CBattleInterface * _owner, const CStack * attacker, BattleHex _dest, const CStack * _attacked);
};
class CStackMoveAnimation : public CBattleStackAnimation
{
public:
BattleHex currentHex;
CStackMoveAnimation(CBattleInterface * _owner, const CStack * _stack, BattleHex _currentHex);
};
/// Move animation of a creature
class CMovementAnimation : public CBattleStackAnimation
class CMovementAnimation : public CStackMoveAnimation
{
private:
std::vector<BattleHex> destTiles; //full path, includes already passed hexes
@ -144,8 +152,6 @@ private:
double progress; // range 0 -> 1, indicates move progrees. 0 = movement starts, 1 = move ends
public:
BattleHex nextHex; // next hex, to which creature move right now
bool init() override;
void nextFrame() override;
@ -154,10 +160,8 @@ public:
};
/// Move end animation of a creature
class CMovementEndAnimation : public CBattleStackAnimation
class CMovementEndAnimation : public CStackMoveAnimation
{
private:
BattleHex destinationTile;
public:
bool init() override;
@ -166,7 +170,7 @@ public:
};
/// Move start animation of a creature
class CMovementStartAnimation : public CBattleStackAnimation
class CMovementStartAnimation : public CStackMoveAnimation
{
public:
bool init() override;
@ -175,9 +179,8 @@ public:
};
/// Class responsible for animation of stack chaning direction (left <-> right)
class CReverseAnimation : public CBattleStackAnimation
class CReverseAnimation : public CStackMoveAnimation
{
BattleHex hex;
public:
bool priority; //true - high, false - low
bool init() override;

View File

@ -103,11 +103,12 @@ void CBattleStacksController::showBattlefieldObjects(std::shared_ptr<CCanvas> ca
// stack position will be updated only *after* movement is finished
// before this - stack is always at its initial position. Thus we need to find
// its current position. Which can be found only in this class
if (CMovementAnimation *move = dynamic_cast<CMovementAnimation*>(anim))
if (CStackMoveAnimation *move = dynamic_cast<CStackMoveAnimation*>(anim))
{
if (move->stack == stack)
return move->nextHex;
return move->currentHex;
}
}
return stack->getPosition();
};
@ -171,7 +172,7 @@ void CBattleStacksController::stackReset(const CStack * stack)
auto animation = iter->second;
if(stack->alive() && animation->isDead())
if(stack->alive() && animation->isDeadOrDying())
animation->setType(CCreatureAnim::HOLDING);
if (stack->isClone())

View File

@ -326,9 +326,21 @@ int CCreatureAnimation::framesInGroup(CCreatureAnim::EAnimType group) const
bool CCreatureAnimation::isDead() const
{
return getType() == CCreatureAnim::DEAD
|| getType() == CCreatureAnim::DEATH
|| getType() == CCreatureAnim::DEAD_RANGED
|| getType() == CCreatureAnim::DEATH_RANGED;
|| getType() == CCreatureAnim::DEAD_RANGED;
}
bool CCreatureAnimation::isDying() const
{
return getType() == CCreatureAnim::DEATH
|| getType() == CCreatureAnim::DEATH_RANGED;
}
bool CCreatureAnimation::isDeadOrDying() const
{
return getType() == CCreatureAnim::DEAD
|| getType() == CCreatureAnim::DEATH
|| getType() == CCreatureAnim::DEAD_RANGED
|| getType() == CCreatureAnim::DEATH_RANGED;
}
bool CCreatureAnimation::isIdle() const
@ -341,7 +353,9 @@ bool CCreatureAnimation::isMoving() const
{
return getType() == CCreatureAnim::MOVE_START
|| getType() == CCreatureAnim::MOVING
|| getType() == CCreatureAnim::MOVE_END;
|| getType() == CCreatureAnim::MOVE_END
|| getType() == CCreatureAnim::TURN_L
|| getType() == CCreatureAnim::TURN_R;
}
bool CCreatureAnimation::isShooting() const

View File

@ -119,6 +119,8 @@ public:
//helpers. TODO: move them somewhere else
bool isDead() const;
bool isDying() const;
bool isDeadOrDying() const;
bool isIdle() const;
bool isMoving() const;
bool isShooting() const;