mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-11 11:31:52 +02:00
* reworked system of animations in battles; it's not fully working yet, but crashes should not occur
* fix for previous fix for two-hex creatures (my previous commit) (this one should work better, certainly has nicer code)
This commit is contained in:
parent
3d2ab9c753
commit
3f5c98ac7c
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,170 @@ class CGTownInstance;
|
|||||||
|
|
||||||
class CBattleInterface;
|
class CBattleInterface;
|
||||||
|
|
||||||
|
struct SStackAttackedInfo
|
||||||
|
{
|
||||||
|
int ID; //id of attacked stack
|
||||||
|
int dmg; //damage dealt
|
||||||
|
int amountKilled; //how many creatures in stack has been killed
|
||||||
|
int IDby; //ID of attacking stack
|
||||||
|
bool byShooting; //if true, stack has been attacked by shooting
|
||||||
|
bool killed; //if true, stack has been killed
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SProjectileInfo
|
||||||
|
{
|
||||||
|
int x, y; //position on the screen
|
||||||
|
int dx, dy; //change in position in one step
|
||||||
|
int step, lastStep; //to know when finish showing this projectile
|
||||||
|
int creID; //ID of creature that shot this projectile
|
||||||
|
int frameNum; //frame to display form projectile animation
|
||||||
|
bool spin; //if true, frameNum will be increased
|
||||||
|
int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit)
|
||||||
|
bool reverse; //if true, projectile will be flipped by vertical asix
|
||||||
|
};
|
||||||
|
|
||||||
|
//battle animation handlers
|
||||||
|
|
||||||
|
class CBattleAnimation
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
CBattleInterface * owner;
|
||||||
|
public:
|
||||||
|
virtual bool init()=0; //to be called - if returned false, call again until returns true
|
||||||
|
virtual void nextFrame()=0; //call every new frame
|
||||||
|
virtual void endAnim(); //to be called mostly internally; in this class it removes animation from pendingAnims list
|
||||||
|
|
||||||
|
bool isEarliest(); //determines if this animation is earlies of all
|
||||||
|
|
||||||
|
unsigned int ID; //unique identifier
|
||||||
|
|
||||||
|
CBattleAnimation(CBattleInterface * _owner);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBattleStackAnimation : public CBattleAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int stackID; //id of stack whose animation it is
|
||||||
|
|
||||||
|
CBattleStackAnimation(CBattleInterface * _owner, int stack);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CReverseAnim : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int partOfAnim; //1 - first, 2 - second
|
||||||
|
bool secondPartSetup;
|
||||||
|
int hex;
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CReverseAnim(CBattleInterface * _owner, int stack, int dest);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDefenceAnim : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//std::vector<SStackAttackedInfo> attackedInfos;
|
||||||
|
int dmg; //damage dealt
|
||||||
|
int amountKilled; //how many creatures in stack has been killed
|
||||||
|
int IDby; //ID of attacking stack
|
||||||
|
bool byShooting; //if true, stack has been attacked by shooting
|
||||||
|
bool killed; //if true, stack has been killed
|
||||||
|
|
||||||
|
bool continueAnim;
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CDefenceAnim(SStackAttackedInfo _attackedInfo, CBattleInterface * _owner);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBattleStackMoved : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int destHex; //destination
|
||||||
|
bool endMoving; //if this is end of move
|
||||||
|
int distance;
|
||||||
|
float stepX, stepY; //how far stack is moved in one frame
|
||||||
|
float posX, posY;
|
||||||
|
int steps, whichStep;
|
||||||
|
int curStackPos; //position of stack before move
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CBattleStackMoved(CBattleInterface * _owner, int _number, int _destHex, bool _endMoving, int _distance);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBattleMoveStart : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CBattleMoveStart(CBattleInterface * _owner, int stack);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBattleMoveEnd : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int destinationTile;
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CBattleMoveEnd(CBattleInterface * _owner, int stack, int destTile);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBattleAttack : public CBattleStackAnimation
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int IDby; //attacked stack
|
||||||
|
int dest; //atacked hex
|
||||||
|
int frame, maxframe; //frame of animation, number of frames of animation
|
||||||
|
int hitCount; //for delaying animation
|
||||||
|
bool reversing;
|
||||||
|
int posShiftDueToDist;
|
||||||
|
bool shooting;
|
||||||
|
int group; //if shooting is true, print this animation group
|
||||||
|
int sh; // temporary sound handler
|
||||||
|
public:
|
||||||
|
void nextFrame();
|
||||||
|
|
||||||
|
bool checkInitialConditions();
|
||||||
|
|
||||||
|
CBattleAttack(CBattleInterface * _owner, int _stackID);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CMeleeAttack : public CBattleAttack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CMeleeAttack(CBattleInterface * _owner, int attacker, int _dest);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CShootingAnim : public CBattleAttack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool init();
|
||||||
|
void nextFrame();
|
||||||
|
void endAnim();
|
||||||
|
|
||||||
|
CShootingAnim(CBattleInterface * _owner, int attacker, int _dest);
|
||||||
|
};
|
||||||
|
|
||||||
|
//end of battle animation handlers
|
||||||
|
|
||||||
|
|
||||||
class CBattleHero : public CIntObject
|
class CBattleHero : public CIntObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -182,37 +346,11 @@ private:
|
|||||||
BattleAction * spellToCast; //spell for which player is choosing destination
|
BattleAction * spellToCast; //spell for which player is choosing destination
|
||||||
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or cancelled)
|
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or cancelled)
|
||||||
|
|
||||||
class CAttHelper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int ID; //attacking stack
|
|
||||||
int IDby; //attacked stack
|
|
||||||
int dest; //atacked hex
|
|
||||||
int frame, maxframe; //frame of animation, number of frames of animation
|
|
||||||
int hitCount; //for delaying animation
|
|
||||||
bool reversing;
|
|
||||||
int posShiftDueToDist;
|
|
||||||
bool shooting;
|
|
||||||
int shootingGroup; //if shooting is true, print this animation group
|
|
||||||
int sh; // temporary sound handler
|
|
||||||
} * attackingInfo;
|
|
||||||
void attackingShowHelper();
|
|
||||||
void showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to); //helper function for function show
|
void showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to); //helper function for function show
|
||||||
void showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show
|
void showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show
|
||||||
void redrawBackgroundWithHexes(int activeStack);
|
void redrawBackgroundWithHexes(int activeStack);
|
||||||
void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
|
void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
|
||||||
|
|
||||||
struct SProjectileInfo
|
|
||||||
{
|
|
||||||
int x, y; //position on the screen
|
|
||||||
int dx, dy; //change in position in one step
|
|
||||||
int step, lastStep; //to know when finish showing this projectile
|
|
||||||
int creID; //ID of creature that shot this projectile
|
|
||||||
int frameNum; //frame to display form projectile animation
|
|
||||||
bool spin; //if true, frameNum will be increased
|
|
||||||
int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit)
|
|
||||||
bool reverse; //if true, projectile will be flipped by vertical asix
|
|
||||||
};
|
|
||||||
std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield
|
std::list<SProjectileInfo> projectiles; //projectiles flying on battlefield
|
||||||
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
|
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
|
||||||
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
|
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
|
||||||
@ -220,8 +358,6 @@ private:
|
|||||||
bool blockedByObstacle(int hex) const;
|
bool blockedByObstacle(int hex) const;
|
||||||
bool isCatapultAttackable(int hex) const; //returns true if given tile can be attacked by catapult
|
bool isCatapultAttackable(int hex) const; //returns true if given tile can be attacked by catapult
|
||||||
|
|
||||||
void handleEndOfMove(int stackNumber, int destinationTile); //helper function
|
|
||||||
|
|
||||||
struct SBattleEffect
|
struct SBattleEffect
|
||||||
{
|
{
|
||||||
int x, y; //position on the screen
|
int x, y; //position on the screen
|
||||||
@ -249,6 +385,9 @@ private:
|
|||||||
friend class CPlayerInterface;
|
friend class CPlayerInterface;
|
||||||
} * siegeH;
|
} * siegeH;
|
||||||
public:
|
public:
|
||||||
|
std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
|
||||||
|
unsigned int animIDhelper; //for giving IDs for animations
|
||||||
|
|
||||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect); //c-tor
|
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect); //c-tor
|
||||||
~CBattleInterface(); //d-tor
|
~CBattleInterface(); //d-tor
|
||||||
|
|
||||||
@ -291,19 +430,6 @@ public:
|
|||||||
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
|
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
|
||||||
void clickRight(tribool down, bool previousState);
|
void clickRight(tribool down, bool previousState);
|
||||||
|
|
||||||
bool reverseCreature(int number, int hex, bool wideTrick = false); //reverses animation of given creature playing animation of reversing
|
|
||||||
void handleStartMoving(int number); //animation of starting move; some units don't have this animation (ie. halberdier)
|
|
||||||
|
|
||||||
struct SStackAttackedInfo
|
|
||||||
{
|
|
||||||
int ID; //id of attacked stack
|
|
||||||
int dmg; //damage dealt
|
|
||||||
int amountKilled; //how many creatures in stack has been killed
|
|
||||||
int IDby; //ID of attacking stack
|
|
||||||
bool byShooting; //if true, stack has been attacked by shooting
|
|
||||||
bool killed; //if true, stack has been killed
|
|
||||||
};
|
|
||||||
|
|
||||||
//call-ins
|
//call-ins
|
||||||
void newStack(int stackID); //new stack appeared on battlefield
|
void newStack(int stackID); //new stack appeared on battlefield
|
||||||
void stackRemoved(int stackID); //stack disappeared from batlefiled
|
void stackRemoved(int stackID); //stack disappeared from batlefiled
|
||||||
@ -326,6 +452,15 @@ public:
|
|||||||
friend class CPlayerInterface;
|
friend class CPlayerInterface;
|
||||||
friend class AdventureMapButton;
|
friend class AdventureMapButton;
|
||||||
friend class CInGameConsole;
|
friend class CInGameConsole;
|
||||||
|
friend class CReverseAnim;
|
||||||
|
friend class CBattleAnimation;
|
||||||
|
friend class CDefenceAnim;
|
||||||
|
friend class CBattleStackMoved;
|
||||||
|
friend class CBattleMoveStart;
|
||||||
|
friend class CBattleMoveEnd;
|
||||||
|
friend class CBattleAttack;
|
||||||
|
friend class CMeleeAttack;
|
||||||
|
friend class CShootingAnim;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __CBATTLEINTERFACE_H__
|
#endif // __CBATTLEINTERFACE_H__
|
||||||
|
@ -1029,7 +1029,7 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
|
|||||||
battleInt->moveStarted = true;
|
battleInt->moveStarted = true;
|
||||||
if(battleInt->creAnims[action->stackNumber]->framesInGroup(20))
|
if(battleInt->creAnims[action->stackNumber]->framesInGroup(20))
|
||||||
{
|
{
|
||||||
battleInt->creAnims[action->stackNumber]->setType(20);
|
battleInt->pendingAnims.push_back(std::make_pair(new CBattleMoveStart(battleInt, action->stackNumber), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,7 +1098,7 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
|
|||||||
}
|
}
|
||||||
if(action->actionType == 6 || action->actionType == 2 && battleInt->creAnims[action->stackNumber]->getType() != 2) //walk or walk & attack
|
if(action->actionType == 6 || action->actionType == 2 && battleInt->creAnims[action->stackNumber]->getType() != 2) //walk or walk & attack
|
||||||
{
|
{
|
||||||
battleInt->handleEndOfMove(action->stackNumber, action->destinationTile);
|
battleInt->pendingAnims.push_back(std::make_pair(new CBattleMoveEnd(battleInt, action->stackNumber, action->destinationTile), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1161,7 +1161,7 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
|
|||||||
tlog5 << "done!\n";
|
tlog5 << "done!\n";
|
||||||
|
|
||||||
|
|
||||||
std::vector<CBattleInterface::SStackAttackedInfo> arg;
|
std::vector<SStackAttackedInfo> arg;
|
||||||
for(std::set<BattleStackAttacked>::iterator i = bsa.begin(); i != bsa.end(); i++)
|
for(std::set<BattleStackAttacked>::iterator i = bsa.begin(); i != bsa.end(); i++)
|
||||||
{
|
{
|
||||||
if(i->isEffect() && i->effect != 12) //and not armageddon
|
if(i->isEffect() && i->effect != 12) //and not armageddon
|
||||||
@ -1170,7 +1170,7 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
|
|||||||
if (stack != NULL)
|
if (stack != NULL)
|
||||||
battleInt->displayEffect(i->effect, stack->position);
|
battleInt->displayEffect(i->effect, stack->position);
|
||||||
}
|
}
|
||||||
CBattleInterface::SStackAttackedInfo to_put = {i->stackAttacked, i->damageAmount, i->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7, i->killed()};
|
SStackAttackedInfo to_put = {i->stackAttacked, i->damageAmount, i->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7, i->killed()};
|
||||||
arg.push_back(to_put);
|
arg.push_back(to_put);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,7 +720,10 @@ DLL_EXPORT void BattleAttack::applyGs( CGameState *gs )
|
|||||||
DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
||||||
{
|
{
|
||||||
CStack *st = gs->curB->getStack(ba.stackNumber);
|
CStack *st = gs->curB->getStack(ba.stackNumber);
|
||||||
|
|
||||||
|
if(ba.actionType != 1) //don't check for stack if it's custom action by hero
|
||||||
assert(st);
|
assert(st);
|
||||||
|
|
||||||
switch(ba.actionType)
|
switch(ba.actionType)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user