1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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:
mateuszb 2009-09-10 11:28:34 +00:00
parent 3d2ab9c753
commit 3f5c98ac7c
4 changed files with 1100 additions and 794 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,170 @@ class CGTownInstance;
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
{
public:
@ -182,37 +346,11 @@ private:
BattleAction * spellToCast; //spell for which player is choosing destination
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 showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show
void redrawBackgroundWithHexes(int activeStack);
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
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
@ -220,8 +358,6 @@ private:
bool blockedByObstacle(int hex) const;
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
{
int x, y; //position on the screen
@ -249,6 +385,9 @@ private:
friend class CPlayerInterface;
} * siegeH;
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(); //d-tor
@ -291,19 +430,6 @@ public:
void mouseMoved(const SDL_MouseMotionEvent &sEvent);
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
void newStack(int stackID); //new stack appeared on battlefield
void stackRemoved(int stackID); //stack disappeared from batlefiled
@ -326,6 +452,15 @@ public:
friend class CPlayerInterface;
friend class AdventureMapButton;
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__

View File

@ -1029,7 +1029,7 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
battleInt->moveStarted = true;
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
{
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";
std::vector<CBattleInterface::SStackAttackedInfo> arg;
std::vector<SStackAttackedInfo> arg;
for(std::set<BattleStackAttacked>::iterator i = bsa.begin(); i != bsa.end(); i++)
{
if(i->isEffect() && i->effect != 12) //and not armageddon
@ -1170,7 +1170,7 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
if (stack != NULL)
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);
}

View File

@ -720,7 +720,10 @@ DLL_EXPORT void BattleAttack::applyGs( CGameState *gs )
DLL_EXPORT void StartAction::applyGs( CGameState *gs )
{
CStack *st = gs->curB->getStack(ba.stackNumber);
assert(st);
if(ba.actionType != 1) //don't check for stack if it's custom action by hero
assert(st);
switch(ba.actionType)
{
case 3: