Explorar el Código

Fix playback of shooter animations at max speed

Ivan Savenko hace 2 años
padre
commit
31b718898a

+ 7 - 0
client/battle/BattleAnimationClasses.cpp

@@ -711,6 +711,13 @@ void RangedAttackAnimation::nextFrame()
 
 	}
 
+	bool stackHasProjectile = owner.projectilesController->hasActiveProjectile(stack, true);
+
+	if (!projectileEmitted || stackHasProjectile)
+		stackAnimation(attackingStack)->playUntil(getAttackClimaxFrame());
+	else
+		stackAnimation(attackingStack)->playUntil(static_cast<size_t>(-1));
+
 	AttackAnimation::nextFrame();
 
 	if (!projectileEmitted)

+ 0 - 7
client/battle/BattleStacksController.cpp

@@ -329,13 +329,6 @@ void BattleStacksController::showStack(Canvas & canvas, const CStack * stack)
 			fullFilter = ColorFilter::genCombined(fullFilter, filter.effect);
 	}
 
-	bool stackHasProjectile = owner.projectilesController->hasActiveProjectile(stack, true);
-
-	if (stackHasProjectile)
-		stackAnimation[stack->ID]->pause();
-	else
-		stackAnimation[stack->ID]->play();
-
 	stackAnimation[stack->ID]->nextFrame(canvas, fullFilter, facingRight(stack)); // do actual blit
 	stackAnimation[stack->ID]->incrementFrame(float(GH.mainFPSmng->getElapsedMilliseconds()) / 1000);
 }

+ 11 - 13
client/battle/CreatureAnimation.cpp

@@ -183,7 +183,7 @@ void CreatureAnimation::setType(ECreatureAnimType type)
 	currentFrame = 0;
 	once = false;
 
-	play();
+	speed = speedController(this, type);
 }
 
 CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController controller)
@@ -191,6 +191,7 @@ CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController
 	  speed(0.1f),
 	  shadowAlpha(128),
 	  currentFrame(0),
+	  animationEnd(-1),
 	  elapsedTime(0),
 	  type(ECreatureAnimType::HOLDING),
 	  border(CSDL_Ext::makeColor(0, 0, 0, 0)),
@@ -248,7 +249,7 @@ CreatureAnimation::CreatureAnimation(const std::string & name_, TSpeedController
 
 	reverse->verticalFlip();
 
-	play();
+	speed = speedController(this, type);
 }
 
 void CreatureAnimation::endAnimation()
@@ -263,6 +264,9 @@ bool CreatureAnimation::incrementFrame(float timePassed)
 {
 	elapsedTime += timePassed;
 	currentFrame += timePassed * speed;
+	if (animationEnd >= 0)
+		currentFrame = std::min(currentFrame, animationEnd);
+
 	const auto framesNumber = framesInGroup(type);
 
 	if(framesNumber <= 0)
@@ -375,6 +379,11 @@ void CreatureAnimation::nextFrame(Canvas & canvas, const ColorFilter & shifter,
 	}
 }
 
+void CreatureAnimation::playUntil(size_t frameIndex)
+{
+	animationEnd = frameIndex;
+}
+
 int CreatureAnimation::framesInGroup(ECreatureAnimType group) const
 {
 	return static_cast<int>(forward->size(size_t(group)));
@@ -421,14 +430,3 @@ bool CreatureAnimation::isShooting() const
 		|| getType() == ECreatureAnimType::SHOOT_FRONT
 		|| getType() == ECreatureAnimType::SHOOT_DOWN;
 }
-
-void CreatureAnimation::pause()
-{
-	speed = 0;
-}
-
-void CreatureAnimation::play()
-{
-	//logAnim->trace("Play %s group %d at %d:%d", name, static_cast<int>(getType()), pos.x, pos.y);
-	speed = speedController(this, type);
-}

+ 2 - 2
client/battle/CreatureAnimation.h

@@ -88,6 +88,7 @@ private:
 	/// currently displayed frame. Float to allow H3-style animations where frames
 	/// don't display for integer number of frames
 	float currentFrame;
+	float animationEnd;
 
 	/// cumulative, real-time duration of animation. Used for effects like selection border
 	float elapsedTime;
@@ -146,8 +147,7 @@ public:
 	/// returns number of frames in selected animation type
 	int framesInGroup(ECreatureAnimType group) const;
 
-	void pause();
-	void play();
+	void playUntil(size_t frameIndex);
 
 	/// helpers to classify current type of animation
 	bool isDead() const;