Prechádzať zdrojové kódy

* 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)

mateuszb 16 rokov pred
rodič
commit
3f5c98ac7c

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 934 - 502
client/CBattleInterface.cpp


+ 176 - 41
client/CBattleInterface.h

@@ -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__

+ 4 - 4
client/CPlayerInterface.cpp

@@ -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);
 	}
 

+ 4 - 1
lib/NetPacksLib.cpp

@@ -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:

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov