mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Cleaned up BattleHero class
This commit is contained in:
@ -93,7 +93,6 @@ BattleStackAnimation::BattleStackAnimation(BattleInterface & owner, const CStack
|
|||||||
|
|
||||||
void AttackAnimation::nextFrame()
|
void AttackAnimation::nextFrame()
|
||||||
{
|
{
|
||||||
assert(myAnim->getType() == group);
|
|
||||||
if(myAnim->getType() != group)
|
if(myAnim->getType() != group)
|
||||||
{
|
{
|
||||||
myAnim->setType(group);
|
myAnim->setType(group);
|
||||||
|
@ -328,6 +328,12 @@ public:
|
|||||||
void nextFrame() override;
|
void nextFrame() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HeroAnimation : public BattleAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HeroAnimation(BattleInterface * owner_, const CStack * shooter);
|
||||||
|
};
|
||||||
|
|
||||||
/// Class that waits till projectile of certain shooter hits a target
|
/// Class that waits till projectile of certain shooter hits a target
|
||||||
class WaitingProjectileAnimation : public BattleAnimation
|
class WaitingProjectileAnimation : public BattleAnimation
|
||||||
{
|
{
|
||||||
|
@ -43,9 +43,7 @@ namespace EBattleEffect
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace EHeroAnimType
|
enum class EHeroAnimType
|
||||||
{
|
|
||||||
enum Type
|
|
||||||
{
|
{
|
||||||
HOLDING = 0,
|
HOLDING = 0,
|
||||||
IDLE = 1, // idling movement that happens from time to time
|
IDLE = 1, // idling movement that happens from time to time
|
||||||
@ -53,7 +51,6 @@ enum Type
|
|||||||
VICTORY = 3, // when enemy stack killed or huge damage is dealt
|
VICTORY = 3, // when enemy stack killed or huge damage is dealt
|
||||||
CAST_SPELL = 4 // spellcasting
|
CAST_SPELL = 4 // spellcasting
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace ECreatureAnimType
|
namespace ECreatureAnimType
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ BattleControlPanel::BattleControlPanel(BattleInterface & owner, const Point & po
|
|||||||
bOptions = std::make_shared<CButton> (Point( 3, 5), "icm003.def", CGI->generaltexth->zelp[381], std::bind(&BattleControlPanel::bOptionsf,this), SDLK_o);
|
bOptions = std::make_shared<CButton> (Point( 3, 5), "icm003.def", CGI->generaltexth->zelp[381], std::bind(&BattleControlPanel::bOptionsf,this), SDLK_o);
|
||||||
bSurrender = std::make_shared<CButton> (Point( 54, 5), "icm001.def", CGI->generaltexth->zelp[379], std::bind(&BattleControlPanel::bSurrenderf,this), SDLK_s);
|
bSurrender = std::make_shared<CButton> (Point( 54, 5), "icm001.def", CGI->generaltexth->zelp[379], std::bind(&BattleControlPanel::bSurrenderf,this), SDLK_s);
|
||||||
bFlee = std::make_shared<CButton> (Point(105, 5), "icm002.def", CGI->generaltexth->zelp[380], std::bind(&BattleControlPanel::bFleef,this), SDLK_r);
|
bFlee = std::make_shared<CButton> (Point(105, 5), "icm002.def", CGI->generaltexth->zelp[380], std::bind(&BattleControlPanel::bFleef,this), SDLK_r);
|
||||||
bAutofight = std::make_shared<CButton> (Point(157, 5), "icm004.def", CGI->generaltexth->zelp[382], std::bind(&BattleControlPanel::bAutofightf,this), SDLK_a);
|
bAutofight = std::make_shared<CButton> (Point(158, 5), "icm004.def", CGI->generaltexth->zelp[382], std::bind(&BattleControlPanel::bAutofightf,this), SDLK_a);
|
||||||
bSpell = std::make_shared<CButton> (Point(645, 5), "icm005.def", CGI->generaltexth->zelp[385], std::bind(&BattleControlPanel::bSpellf,this), SDLK_c);
|
bSpell = std::make_shared<CButton> (Point(645, 5), "icm005.def", CGI->generaltexth->zelp[385], std::bind(&BattleControlPanel::bSpellf,this), SDLK_c);
|
||||||
bWait = std::make_shared<CButton> (Point(696, 5), "icm006.def", CGI->generaltexth->zelp[386], std::bind(&BattleControlPanel::bWaitf,this), SDLK_w);
|
bWait = std::make_shared<CButton> (Point(696, 5), "icm006.def", CGI->generaltexth->zelp[386], std::bind(&BattleControlPanel::bWaitf,this), SDLK_w);
|
||||||
bDefence = std::make_shared<CButton> (Point(747, 5), "icm007.def", CGI->generaltexth->zelp[387], std::bind(&BattleControlPanel::bDefencef,this), SDLK_d);
|
bDefence = std::make_shared<CButton> (Point(747, 5), "icm007.def", CGI->generaltexth->zelp[387], std::bind(&BattleControlPanel::bDefencef,this), SDLK_d);
|
||||||
|
@ -107,7 +107,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
|||||||
queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
|
queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CPlayerInterface::battleInt = this;
|
CPlayerInterface::battleInt = this;
|
||||||
|
|
||||||
//initializing armies
|
//initializing armies
|
||||||
@ -142,10 +141,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
|||||||
}
|
}
|
||||||
|
|
||||||
attackingHero = std::make_shared<BattleHero>(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, *this);
|
attackingHero = std::make_shared<BattleHero>(battleImage, false, hero1->tempOwner, hero1->tempOwner == curInt->playerID ? hero1 : nullptr, *this);
|
||||||
|
|
||||||
auto img = attackingHero->animation->getImage(0, 0, true);
|
|
||||||
if(img)
|
|
||||||
attackingHero->pos = genRect(img->height(), img->width(), pos.x - 43, pos.y - 19);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,10 +161,6 @@ BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *
|
|||||||
}
|
}
|
||||||
|
|
||||||
defendingHero = std::make_shared<BattleHero>(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, *this);
|
defendingHero = std::make_shared<BattleHero>(battleImage, true, hero2->tempOwner, hero2->tempOwner == curInt->playerID ? hero2 : nullptr, *this);
|
||||||
|
|
||||||
auto img = defendingHero->animation->getImage(0, 0, true);
|
|
||||||
if(img)
|
|
||||||
defendingHero->pos = genRect(img->height(), img->width(), pos.x + 693, pos.y - 19);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obstacleController.reset(new BattleObstacleController(*this));
|
obstacleController.reset(new BattleObstacleController(*this));
|
||||||
@ -588,7 +579,7 @@ void BattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
|
|||||||
fieldController->redrawBackgroundWithHexes();
|
fieldController->redrawBackgroundWithHexes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleInterface::setHeroAnimation(ui8 side, int phase)
|
void BattleInterface::setHeroAnimation(ui8 side, EHeroAnimType phase)
|
||||||
{
|
{
|
||||||
if(side == BattleSide::ATTACKER)
|
if(side == BattleSide::ATTACKER)
|
||||||
{
|
{
|
||||||
@ -714,9 +705,6 @@ void BattleInterface::endAction(const BattleAction* action)
|
|||||||
{
|
{
|
||||||
const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
||||||
|
|
||||||
if(action->actionType == EActionType::HERO_SPELL)
|
|
||||||
setHeroAnimation(action->side, EHeroAnimType::HOLDING);
|
|
||||||
|
|
||||||
stacksController->endAction(action);
|
stacksController->endAction(action);
|
||||||
|
|
||||||
queue->update();
|
queue->update();
|
||||||
|
@ -138,7 +138,7 @@ private:
|
|||||||
|
|
||||||
void showInterface(SDL_Surface * to);
|
void showInterface(SDL_Surface * to);
|
||||||
|
|
||||||
void setHeroAnimation(ui8 side, int phase);
|
void setHeroAnimation(ui8 side, EHeroAnimType phase);
|
||||||
|
|
||||||
void executeSpellCast(); //called when a hero casts a spell
|
void executeSpellCast(); //called when a hero casts a spell
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
|
|
||||||
void BattleConsole::showAll(SDL_Surface * to)
|
void BattleConsole::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
Point consolePos(pos.x + 10, pos.y + 17);
|
Point consolePos(pos.x + 10, pos.y + 19);
|
||||||
Point textPos (pos.x + pos.w/2, pos.y + 17);
|
Point textPos (pos.x + pos.w/2, pos.y + 19);
|
||||||
|
|
||||||
if (!consoleText.empty())
|
if (!consoleText.empty())
|
||||||
{
|
{
|
||||||
@ -160,46 +160,60 @@ void BattleConsole::clear()
|
|||||||
|
|
||||||
void BattleHero::render(Canvas & canvas)
|
void BattleHero::render(Canvas & canvas)
|
||||||
{
|
{
|
||||||
auto flagFrame = flagAnimation->getImage(flagAnim, 0, true);
|
size_t groupIndex = static_cast<size_t>(phase);
|
||||||
|
|
||||||
if(!flagFrame)
|
auto flagFrame = flagAnimation->getImage(flagCurrentFrame, 0, true);
|
||||||
return;
|
auto heroFrame = animation->getImage(currentFrame, groupIndex, true);
|
||||||
|
|
||||||
//animation of flag
|
Point heroPosition = pos.center() - heroFrame->dimensions() / 2;
|
||||||
Point flagPosition = pos.topLeft();
|
Point flagPosition = pos.center() - flagFrame->dimensions() / 2;
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
flagPosition += Point(61, 39);
|
flagPosition += Point(-4, -41);
|
||||||
else
|
else
|
||||||
flagPosition += Point(72, 39);
|
flagPosition += Point(4, -41);
|
||||||
|
|
||||||
|
|
||||||
auto heroFrame = animation->getImage(currentFrame, phase, true);
|
|
||||||
|
|
||||||
canvas.draw(flagFrame, flagPosition);
|
canvas.draw(flagFrame, flagPosition);
|
||||||
canvas.draw(heroFrame, pos.topLeft());
|
canvas.draw(heroFrame, heroPosition);
|
||||||
|
|
||||||
if(++animCount >= 4)
|
//FIXME: un-hardcode speed
|
||||||
|
flagCurrentFrame += 0.25f;
|
||||||
|
currentFrame += 0.25f;
|
||||||
|
|
||||||
|
if(flagCurrentFrame >= flagAnimation->size(0))
|
||||||
|
flagCurrentFrame -= flagAnimation->size(0);
|
||||||
|
|
||||||
|
if(currentFrame >= animation->size(groupIndex))
|
||||||
{
|
{
|
||||||
animCount = 0;
|
currentFrame -= animation->size(groupIndex);
|
||||||
if(++flagAnim >= flagAnimation->size(0))
|
if (phaseFinishedCallback)
|
||||||
flagAnim = 0;
|
{
|
||||||
|
phaseFinishedCallback();
|
||||||
if(++currentFrame >= lastFrame)
|
phaseFinishedCallback = std::function<void()>();
|
||||||
switchToNextPhase();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleHero::setPhase(int newPhase)
|
float BattleHero::getFrame() const
|
||||||
|
{
|
||||||
|
return currentFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleHero::onPhaseFinished(const std::function<void()> & callback)
|
||||||
|
{
|
||||||
|
phaseFinishedCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleHero::setPhase(EHeroAnimType newPhase)
|
||||||
{
|
{
|
||||||
nextPhase = newPhase;
|
nextPhase = newPhase;
|
||||||
switchToNextPhase(); //immediately switch to next phase and then restore idling phase
|
switchToNextPhase(); //immediately switch to next phase and then restore idling phase
|
||||||
nextPhase = 0;
|
nextPhase = EHeroAnimType::HOLDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleHero::hover(bool on)
|
void BattleHero::hover(bool on)
|
||||||
{
|
{
|
||||||
//TODO: Make lines below work properly
|
//TODO: BROKEN CODE
|
||||||
if (on)
|
if (on)
|
||||||
CCS->curh->changeGraphic(ECursor::COMBAT, 5);
|
CCS->curh->changeGraphic(ECursor::COMBAT, 5);
|
||||||
else
|
else
|
||||||
@ -208,25 +222,25 @@ void BattleHero::hover(bool on)
|
|||||||
|
|
||||||
void BattleHero::clickLeft(tribool down, bool previousState)
|
void BattleHero::clickLeft(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
if(myOwner->actionsController->spellcastingModeActive()) //we are casting a spell
|
if(owner.actionsController->spellcastingModeActive()) //we are casting a spell
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(boost::logic::indeterminate(down))
|
if(boost::logic::indeterminate(down))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!myHero || down || !myOwner->myTurn)
|
if(!myHero || down || !owner.myTurn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(myOwner->getCurrentPlayerInterface()->cb->battleCanCastSpell(myHero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
|
if(owner.getCurrentPlayerInterface()->cb->battleCanCastSpell(myHero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
|
||||||
{
|
{
|
||||||
BattleHex hoveredHex = myOwner->fieldController->getHoveredHex();
|
BattleHex hoveredHex = owner.fieldController->getHoveredHex();
|
||||||
//do nothing when any hex is hovered - hero's animation overlaps battlefield
|
//do nothing when any hex is hovered - hero's animation overlaps battlefield
|
||||||
if ( hoveredHex != BattleHex::INVALID )
|
if ( hoveredHex != BattleHex::INVALID )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
|
CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
|
||||||
|
|
||||||
GH.pushIntT<CSpellWindow>(myHero, myOwner->getCurrentPlayerInterface());
|
GH.pushIntT<CSpellWindow>(myHero, owner.getCurrentPlayerInterface());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,44 +250,47 @@ void BattleHero::clickRight(tribool down, bool previousState)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Point windowPosition;
|
Point windowPosition;
|
||||||
windowPosition.x = (!flip) ? myOwner->pos.topLeft().x + 1 : myOwner->pos.topRight().x - 79;
|
windowPosition.x = (!flip) ? owner.pos.topLeft().x + 1 : owner.pos.topRight().x - 79;
|
||||||
windowPosition.y = myOwner->pos.y + 135;
|
windowPosition.y = owner.pos.y + 135;
|
||||||
|
|
||||||
InfoAboutHero targetHero;
|
InfoAboutHero targetHero;
|
||||||
if(down && (myOwner->myTurn || settings["session"]["spectate"].Bool()))
|
if(down && (owner.myTurn || settings["session"]["spectate"].Bool()))
|
||||||
{
|
{
|
||||||
auto h = flip ? myOwner->defendingHeroInstance : myOwner->attackingHeroInstance;
|
auto h = flip ? owner.defendingHeroInstance : owner.attackingHeroInstance;
|
||||||
targetHero.initFromHero(h, InfoAboutHero::EInfoLevel::INBATTLE);
|
targetHero.initFromHero(h, InfoAboutHero::EInfoLevel::INBATTLE);
|
||||||
GH.pushIntT<HeroInfoWindow>(targetHero, &windowPosition);
|
GH.pushIntT<HeroInfoWindow>(targetHero, &windowPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleHero::switchToNextPhase()
|
void BattleHero::switchToNextPhase()
|
||||||
{
|
|
||||||
if(phase != nextPhase)
|
|
||||||
{
|
{
|
||||||
phase = nextPhase;
|
phase = nextPhase;
|
||||||
|
currentFrame = 0.f;
|
||||||
firstFrame = 0;
|
if (phaseFinishedCallback)
|
||||||
|
{
|
||||||
lastFrame = static_cast<int>(animation->size(phase));
|
phaseFinishedCallback();
|
||||||
|
phaseFinishedCallback = std::function<void()>();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFrame = firstFrame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleHero::BattleHero(const std::string & animationPath, bool flipG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface & owner):
|
BattleHero::BattleHero(const std::string & animationPath, bool flipG, PlayerColor player, const CGHeroInstance * hero, const BattleInterface & owner):
|
||||||
flip(flipG),
|
flip(flipG),
|
||||||
myHero(hero),
|
myHero(hero),
|
||||||
myOwner(&owner),
|
owner(owner),
|
||||||
phase(1),
|
phase(EHeroAnimType::HOLDING),
|
||||||
nextPhase(0),
|
nextPhase(EHeroAnimType::HOLDING),
|
||||||
flagAnim(0),
|
currentFrame(0.f),
|
||||||
animCount(0)
|
flagCurrentFrame(0.f)
|
||||||
{
|
{
|
||||||
animation = std::make_shared<CAnimation>(animationPath);
|
animation = std::make_shared<CAnimation>(animationPath);
|
||||||
animation->preload();
|
animation->preload();
|
||||||
if(flipG)
|
|
||||||
|
pos.w = 64;
|
||||||
|
pos.h = 136;
|
||||||
|
pos.x = owner.pos.x + (flipG ? (owner.pos.w - pos.w) : 0);
|
||||||
|
pos.y = owner.pos.y;
|
||||||
|
|
||||||
|
if(flip)
|
||||||
animation->verticalFlip();
|
animation->verticalFlip();
|
||||||
|
|
||||||
if(flip)
|
if(flip)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "BattleConstants.h"
|
||||||
#include "../gui/CIntObject.h"
|
#include "../gui/CIntObject.h"
|
||||||
#include "../../lib/battle/BattleHex.h"
|
#include "../../lib/battle/BattleHex.h"
|
||||||
#include "../windows/CWindowObject.h"
|
#include "../windows/CWindowObject.h"
|
||||||
@ -77,23 +78,30 @@ public:
|
|||||||
/// Hero battle animation
|
/// Hero battle animation
|
||||||
class BattleHero : public CIntObject
|
class BattleHero : public CIntObject
|
||||||
{
|
{
|
||||||
void switchToNextPhase();
|
|
||||||
public:
|
|
||||||
bool flip; //false if it's attacking hero, true otherwise
|
bool flip; //false if it's attacking hero, true otherwise
|
||||||
|
|
||||||
|
std::function<void()> phaseFinishedCallback;
|
||||||
std::shared_ptr<CAnimation> animation;
|
std::shared_ptr<CAnimation> animation;
|
||||||
std::shared_ptr<CAnimation> flagAnimation;
|
std::shared_ptr<CAnimation> flagAnimation;
|
||||||
|
|
||||||
const CGHeroInstance * myHero; //this animation's hero instance
|
const CGHeroInstance * myHero; //this animation's hero instance
|
||||||
const BattleInterface * myOwner; //battle interface to which this animation is assigned
|
const BattleInterface & owner; //battle interface to which this animation is assigned
|
||||||
int phase; //stage of animation
|
|
||||||
int nextPhase; //stage of animation to be set after current phase is fully displayed
|
|
||||||
int currentFrame, firstFrame, lastFrame; //frame of animation
|
|
||||||
|
|
||||||
size_t flagAnim;
|
EHeroAnimType phase; //stage of animation
|
||||||
ui8 animCount; //for flag animation
|
EHeroAnimType nextPhase; //stage of animation to be set after current phase is fully displayed
|
||||||
|
|
||||||
|
float currentFrame; //frame of animation
|
||||||
|
float flagCurrentFrame;
|
||||||
|
|
||||||
|
void switchToNextPhase();
|
||||||
|
|
||||||
|
public:
|
||||||
void render(Canvas & canvas); //prints next frame of animation to to
|
void render(Canvas & canvas); //prints next frame of animation to to
|
||||||
void setPhase(int newPhase); //sets phase of hero animation
|
void setPhase(EHeroAnimType newPhase); //sets phase of hero animation
|
||||||
|
|
||||||
|
float getFrame() const;
|
||||||
|
void onPhaseFinished(const std::function<void()> &);
|
||||||
|
|
||||||
void hover(bool on) override;
|
void hover(bool on) override;
|
||||||
void clickLeft(tribool down, bool previousState) override; //call-in
|
void clickLeft(tribool down, bool previousState) override; //call-in
|
||||||
void clickRight(tribool down, bool previousState) override; //call-in
|
void clickRight(tribool down, bool previousState) override; //call-in
|
||||||
|
@ -160,6 +160,14 @@ struct Rect : public SDL_Rect
|
|||||||
{
|
{
|
||||||
return Point(x+w,y+h);
|
return Point(x+w,y+h);
|
||||||
}
|
}
|
||||||
|
Point center() const
|
||||||
|
{
|
||||||
|
return Point(x+w/2,y+h/2);
|
||||||
|
}
|
||||||
|
Point dimensions() const
|
||||||
|
{
|
||||||
|
return Point(w,h);
|
||||||
|
}
|
||||||
Rect operator+(const Rect &p) const //moves this rect by p's rect position
|
Rect operator+(const Rect &p) const //moves this rect by p's rect position
|
||||||
{
|
{
|
||||||
return Rect(x+p.x,y+p.y,w,h);
|
return Rect(x+p.x,y+p.y,w,h);
|
||||||
|
Reference in New Issue
Block a user