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

Implemented teleportation animation effect

This commit is contained in:
Ivan Savenko 2022-12-18 18:26:43 +02:00
parent a6622b5896
commit e9e549148d
15 changed files with 81 additions and 32 deletions

View File

@ -202,7 +202,7 @@ void CStupidAI::battleNewRound(int round)
print("battleNewRound called");
}
void CStupidAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance)
void CStupidAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport)
{
print("battleStackMoved called");
}

View File

@ -36,7 +36,7 @@ public:
//void battleResultsApplied() override; //called when all effects of last battle are applied
void battleNewRoundFirst(int round) override; //called at the beginning of each turn before changes are applied;
void battleNewRound(int round) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance) override;
void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
void battleSpellCast(const BattleSpellCast *sc) override;
void battleStacksEffectsSet(const SetStackEffect & sse) override;//called when a specific effect is set to stacks
//void battleTriggerEffect(const BattleTriggerEffect & bte) override;

View File

@ -913,12 +913,12 @@ void CPlayerInterface::battleLogMessage(const std::vector<MetaString> & lines)
battleInt->displayBattleLog(lines);
}
void CPlayerInterface::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance)
void CPlayerInterface::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport)
{
EVENT_HANDLER_CALLED_BY_CLIENT;
BATTLE_EVENT_POSSIBLE_RETURN;
battleInt->stackMoved(stack, dest, distance);
battleInt->stackMoved(stack, dest, distance, teleport);
}
void CPlayerInterface::battleSpellCast( const BattleSpellCast *sc )
{

View File

@ -193,7 +193,7 @@ public:
void battleNewRoundFirst(int round) override; //called at the beginning of each turn before changes are applied; used for HP regen handling
void battleNewRound(int round) override; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
void battleLogMessage(const std::vector<MetaString> & lines) override;
void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance) override;
void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
void battleSpellCast(const BattleSpellCast *sc) override;
void battleStacksEffectsSet(const SetStackEffect & sse) override; //called when a specific effect is set to stacks
void battleTriggerEffect(const BattleTriggerEffect & bte) override; //various one-shot effect

View File

@ -738,7 +738,7 @@ void BattleResult::applyFirstCl(CClient *cl)
void BattleStackMoved::applyFirstCl(CClient *cl)
{
const CStack * movedStack = GS(cl)->curB->battleGetStackByID(stack);
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStackMoved, movedStack, tilesToMove, distance);
callBattleInterfaceIfPresentForBothSides(cl, &IBattleEventsReceiver::battleStackMoved, movedStack, tilesToMove, distance, teleporting);
}
void BattleAttack::applyFirstCl(CClient *cl)

View File

@ -331,11 +331,11 @@ bool MovementAnimation::init()
{
assert(stack);
assert(!myAnim->isDeadOrDying());
assert(stackAnimation(stack)->framesInGroup(ECreatureAnimType::MOVING) > 0);
if(stackAnimation(stack)->framesInGroup(ECreatureAnimType::MOVING) == 0 ||
stack->hasBonus(Selector::typeSubtype(Bonus::FLYING, 1)))
if(stackAnimation(stack)->framesInGroup(ECreatureAnimType::MOVING) == 0)
{
//no movement or teleport, end immediately
//no movement, end immediately
delete this;
return false;
}
@ -576,6 +576,11 @@ ResurrectionAnimation::ResurrectionAnimation(BattleInterface & owner, const CSta
logAnim->debug("Created ResurrectionAnimation for %s", stack->getName());
}
bool ColorTransformAnimation::init()
{
return true;
}
void ColorTransformAnimation::nextFrame()
{
float elapsed = GH.mainFPSmng->getElapsedMilliseconds() / 1000.f;
@ -614,7 +619,7 @@ void ColorTransformAnimation::nextFrame()
}
ColorTransformAnimation::ColorTransformAnimation(BattleInterface & owner, const CStack * _stack, const CSpell * spell):
StackActionAnimation(owner, _stack),
BattleStackAnimation(owner, _stack),
spell(spell),
totalProgress(0.f)
{
@ -658,20 +663,35 @@ ColorTransformAnimation * ColorTransformAnimation::petrifyAnimation(BattleInterf
return result;
}
ColorTransformAnimation * ColorTransformAnimation::fadeInAnimation(BattleInterface & owner, const CStack * stack)
ColorTransformAnimation * ColorTransformAnimation::summonAnimation(BattleInterface & owner, const CStack * stack)
{
auto result = teleportInAnimation(owner, stack);
result->timePoints.back() = 1.0f;
return result;
}
ColorTransformAnimation * ColorTransformAnimation::teleportInAnimation(BattleInterface & owner, const CStack * stack)
{
auto result = new ColorTransformAnimation(owner, stack, nullptr);
result->steps.push_back(ColorFilter::genAlphaShifter(0.f));
result->steps.push_back(ColorFilter::genEmptyShifter());
result->timePoints.push_back(0.f);
result->timePoints.push_back(1.f);
result->timePoints.push_back(0.0f);
result->timePoints.push_back(0.2f);
return result;
}
ColorTransformAnimation * ColorTransformAnimation::teleportOutAnimation(BattleInterface & owner, const CStack * stack)
{
auto result = teleportInAnimation(owner, stack);
std::swap(result->steps[0], result->steps[1]);
return result;
}
ColorTransformAnimation * ColorTransformAnimation::fadeOutAnimation(BattleInterface & owner, const CStack * stack)
{
auto result = fadeInAnimation(owner, stack);
std::swap(result->steps[0], result->steps[1]);
auto result = teleportOutAnimation(owner, stack);
result->timePoints.back() = 1.0f;
return result;
}

View File

@ -112,7 +112,7 @@ public:
ResurrectionAnimation(BattleInterface & owner, const CStack * _stack);
};
class ColorTransformAnimation : public StackActionAnimation
class ColorTransformAnimation : public BattleStackAnimation
{
std::vector<ColorFilter> steps;
std::vector<float> timePoints;
@ -120,16 +120,19 @@ class ColorTransformAnimation : public StackActionAnimation
float totalProgress;
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);
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 * summonAnimation (BattleInterface & owner, const CStack * _stack);
static ColorTransformAnimation * fadeOutAnimation (BattleInterface & owner, const CStack * _stack);
static ColorTransformAnimation * teleportInAnimation (BattleInterface & owner, const CStack * _stack);
static ColorTransformAnimation * teleportOutAnimation (BattleInterface & owner, const CStack * _stack);
};
/// Base class for all animations that play during stack movement

View File

@ -335,9 +335,12 @@ void BattleInterface::stackActivated(const CStack *stack)
stacksController->stackActivated(stack);
}
void BattleInterface::stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance)
void BattleInterface::stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance, bool teleport)
{
stacksController->stackMoved(stack, destHex, distance);
if (teleport)
stacksController->stackTeleported(stack, destHex, distance);
else
stacksController->stackMoved(stack, destHex, distance);
}
void BattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos)

View File

@ -197,7 +197,7 @@ public:
void stackAdded(const CStack * stack); //new stack appeared on battlefield
void stackRemoved(uint32_t stackID); //stack disappeared from batlefiled
void stackActivated(const CStack *stack); //active stack has been changed
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance); //stack with id number moved to destHex
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance, bool teleport); //stack with id number moved to destHex
void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
void stackAttacking(const StackAttackInfo & attackInfo); //called when stack with id ID is attacking something on hex dest
void newRoundFirst( int round );

View File

@ -223,7 +223,7 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
owner.executeOnAnimationCondition(EAnimationEvents::HIT, true, [=]()
{
addNewAnim(ColorTransformAnimation::fadeInAnimation(owner, stack));
addNewAnim(ColorTransformAnimation::summonAnimation(owner, stack));
if (stack->isClone())
addNewAnim(ColorTransformAnimation::cloneAnimation(owner, stack, SpellID(SpellID::CLONE).toSpell()));
});
@ -472,6 +472,23 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
executeAttackAnimations();
}
void BattleStacksController::stackTeleported(const CStack *stack, std::vector<BattleHex> destHex, int distance)
{
assert(destHex.size() > 0);
assert(owner.getAnimationCondition(EAnimationEvents::ACTION) == false);
owner.executeOnAnimationCondition(EAnimationEvents::HIT, true, [=](){
addNewAnim( ColorTransformAnimation::teleportOutAnimation(owner, stack) );
});
owner.executeOnAnimationCondition(EAnimationEvents::AFTER_HIT, true, [=](){
stackAnimation[stack->ID]->pos.moveTo(getStackPositionAtHex(destHex.back(), stack));
addNewAnim( ColorTransformAnimation::teleportInAnimation(owner, stack) );
});
// animations will be executed by spell
}
void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance)
{
assert(destHex.size() > 0);
@ -486,8 +503,12 @@ void BattleStacksController::stackMoved(const CStack *stack, std::vector<BattleH
addNewAnim(new MovementStartAnimation(owner, stack));
owner.waitForAnimationCondition(EAnimationEvents::ACTION, false);
addNewAnim(new MovementAnimation(owner, stack, destHex, distance));
owner.waitForAnimationCondition(EAnimationEvents::ACTION, false);
// if creature can teleport, e.g Devils - skip movement animation
if ( !stack->hasBonus(Selector::typeSubtype(Bonus::FLYING, 1)) )
{
addNewAnim(new MovementAnimation(owner, stack, destHex, distance));
owner.waitForAnimationCondition(EAnimationEvents::ACTION, false);
}
addNewAnim(new MovementEndAnimation(owner, stack, destHex.back()));
owner.waitForAnimationCondition(EAnimationEvents::ACTION, false);
@ -806,7 +827,7 @@ void BattleStacksController::removeExpiredColorFilters()
return false;
if (filter.effect == ColorFilter::genEmptyShifter())
return false;
if (filter.target->hasBonus(Selector::source(Bonus::SPELL_EFFECT, filter.source->id)))
if (filter.source && filter.target->hasBonus(Selector::source(Bonus::SPELL_EFFECT, filter.source->id)))
return false;
return true;
});

View File

@ -113,6 +113,7 @@ public:
void stackRemoved(uint32_t stackID); //stack disappeared from batlefiled
void stackActivated(const CStack *stack); //active stack has been changed
void stackMoved(const CStack *stack, std::vector<BattleHex> destHex, int distance); //stack with id number moved to destHex
void stackTeleported(const CStack *stack, std::vector<BattleHex> destHex, int distance); //stack with id number moved to destHex
void stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
void stackAttacking(const StackAttackInfo & info); //called when stack with id ID is attacking something on hex dest

View File

@ -204,9 +204,9 @@ void CAdventureAI::battleObstaclesChanged(const std::vector<ObstacleChanges> & o
battleAI->battleObstaclesChanged(obstacles);
}
void CAdventureAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance)
void CAdventureAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport)
{
battleAI->battleStackMoved(stack, dest, distance);
battleAI->battleStackMoved(stack, dest, distance, teleport);
}
void CAdventureAI::battleAttack(const BattleAttack * ba)

View File

@ -160,7 +160,7 @@ public:
virtual void actionFinished(const BattleAction &action) override;
virtual void battleStacksEffectsSet(const SetStackEffect & sse) override;
virtual void battleObstaclesChanged(const std::vector<ObstacleChanges> & obstacles) override;
virtual void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance) override;
virtual void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport) override;
virtual void battleAttack(const BattleAttack *ba) override;
virtual void battleSpellCast(const BattleSpellCast *sc) override;
virtual void battleEnd(const BattleResult *br) override;

View File

@ -63,7 +63,7 @@ public:
virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied;
virtual void battleNewRound(int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
virtual void battleLogMessage(const std::vector<MetaString> & lines){};
virtual void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance){};
virtual void battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance, bool teleport){};
virtual void battleSpellCast(const BattleSpellCast *sc){};
virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks
virtual void battleTriggerEffect(const BattleTriggerEffect & bte){}; //called for various one-shot effects

View File

@ -1545,6 +1545,7 @@ struct BattleStackMoved : public CPackForClient
h & stack;
h & tilesToMove;
h & distance;
h & teleporting;
}
};