From fb235212882b3a2ea506d74394a01fc7dd181a98 Mon Sep 17 00:00:00 2001 From: obligaron Date: Tue, 22 Jun 2021 17:06:46 +0200 Subject: [PATCH] Introduce AnimationInfo.IsPetrified to handle Stone Curse Spell --- Source/engine/animationinfo.cpp | 14 +++++++++++--- Source/engine/animationinfo.h | 9 +++++++++ Source/missiles.cpp | 6 ++++-- Source/monster.cpp | 1 + 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Source/engine/animationinfo.cpp b/Source/engine/animationinfo.cpp index 50911896f..a801109d4 100644 --- a/Source/engine/animationinfo.cpp +++ b/Source/engine/animationinfo.cpp @@ -26,7 +26,7 @@ int AnimationInfo::GetFrameToUseForRendering() const assert(TicksSinceSequenceStarted >= 0); // we don't use the processed game ticks alone but also the fraction of the next game tick (if a rendering happens between game ticks). This helps to smooth the animations. - float totalTicksForCurrentAnimationSequence = gfProgressToNextGameTick + (float)TicksSinceSequenceStarted; + float totalTicksForCurrentAnimationSequence = GetProgressToNextGameTick() + (float)TicksSinceSequenceStarted; // 1 added for rounding reasons. float to int cast always truncate. int absoluteAnimationFrame = 1 + (int)(totalTicksForCurrentAnimationSequence * TickModifier); @@ -58,12 +58,12 @@ float AnimationInfo::GetAnimationProgress() const // This logic is used if animation distrubtion is not active (see GetFrameToUseForRendering). // In this case the variables calculated with animation distribution are not initialized and we have to calculate them on the fly with the given informations. float ticksPerFrame = (DelayLen + 1); - float totalTicksForCurrentAnimationSequence = gfProgressToNextGameTick + (float)CurrentFrame + (DelayCounter / ticksPerFrame); + float totalTicksForCurrentAnimationSequence = GetProgressToNextGameTick() + (float)CurrentFrame + (DelayCounter / ticksPerFrame); float fAnimationFraction = totalTicksForCurrentAnimationSequence / ((float)NumberOfFrames * ticksPerFrame); return fAnimationFraction; } - float totalTicksForCurrentAnimationSequence = gfProgressToNextGameTick + (float)TicksSinceSequenceStarted; + float totalTicksForCurrentAnimationSequence = GetProgressToNextGameTick() + (float)TicksSinceSequenceStarted; float fProgressInAnimationFrames = totalTicksForCurrentAnimationSequence * TickModifier; float fAnimationFraction = fProgressInAnimationFrames / (float)NumberOfFrames; return fAnimationFraction; @@ -87,6 +87,7 @@ void AnimationInfo::SetNewAnimation(CelSprite *pCelSprite, int numberOfFrames, i TicksSinceSequenceStarted = 0; RelevantFramesForDistributing = 0; TickModifier = 0.0F; + IsPetrified = false; if (numSkippedFrames != 0 || flags != AnimationDistributionFlags::None) { // Animation Frames that will be adjusted for the skipped Frames/game ticks @@ -194,4 +195,11 @@ void AnimationInfo::ProcessAnimation(bool reverseAnimation /*= false*/, bool don } } +float AnimationInfo::GetProgressToNextGameTick() const +{ + if (IsPetrified) + return 0.0f; + return gfProgressToNextGameTick; +} + } // namespace devilution diff --git a/Source/engine/animationinfo.h b/Source/engine/animationinfo.h index 3f17da79c..69bbc3e37 100644 --- a/Source/engine/animationinfo.h +++ b/Source/engine/animationinfo.h @@ -56,6 +56,10 @@ public: * @brief Current frame of animation */ int CurrentFrame; + /** + * @brief Is the animation currently petrified and shouldn't advance with gfProgressToNextGameTick + */ + bool IsPetrified; /** * @brief Calculates the Frame to use for the Animation rendering @@ -95,6 +99,11 @@ public: void ProcessAnimation(bool reverseAnimation = false, bool dontProgressAnimation = false); private: + /** + * @brief returns the progress as a fraction (0.0f to 1.0f) in time to the next game tick or 0.0f if the animation is frozen + */ + float GetProgressToNextGameTick() const; + /** * @brief Specifies how many animations-fractions are displayed between two game ticks. this can be > 0, if animations are skipped or < 0 if the same animation is shown in multiple times (delay specified). */ diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 786756577..2e5367fbf 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -4349,10 +4349,12 @@ void MI_Stone(int i) if (missile[i]._mirange == 0) { missile[i]._miDelFlag = true; - if (monster[m]._mhitpoints > 0) + if (monster[m]._mhitpoints > 0) { monster[m]._mmode = (MON_MODE)missile[i]._miVar1; - else + monster[m].AnimInfo.IsPetrified = false; + } else { AddDead(monster[m].position.tile, stonendx, monster[m]._mdir); + } } if (missile[i]._miAnimType == MFILE_SHATTER1) PutMissile(i); diff --git a/Source/monster.cpp b/Source/monster.cpp index 79768d6e2..027bd10af 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -5422,6 +5422,7 @@ void MonsterStruct::CheckStandAnimationIsLoaded(int mdir) void MonsterStruct::Petrify() { _mmode = MM_STONE; + AnimInfo.IsPetrified = true; } } // namespace devilution