diff --git a/Source/engine/animationinfo.cpp b/Source/engine/animationinfo.cpp index 854d636eb..f81548235 100644 --- a/Source/engine/animationinfo.cpp +++ b/Source/engine/animationinfo.cpp @@ -52,7 +52,7 @@ int AnimationInfo::GetFrameToUseForRendering() const return absoluteAnimationFrame; } -void AnimationInfo::SetNewAnimation(uint8_t *pData, int numberOfFrames, int delayLen, AnimationDistributionParams params /*= AnimationDistributionParams::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) +void AnimationInfo::SetNewAnimation(uint8_t *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) { if (pData == this->pData && distributeFramesBeforeFrame != 0 && NumberOfFrames == numberOfFrames && CurrentFrame >= distributeFramesBeforeFrame && CurrentFrame != NumberOfFrames) { // We showed the same Animation (for example a melee attack) before but truncated the Animation. @@ -71,7 +71,7 @@ void AnimationInfo::SetNewAnimation(uint8_t *pData, int numberOfFrames, int dela RelevantFramesForDistributing = 0; TickModifier = 0.0f; - if (numSkippedFrames != 0 || params != AnimationDistributionParams::None) { + if (numSkippedFrames != 0 || flags != AnimationDistributionFlags::None) { // Animation Frames that will be adjusted for the skipped Frames/game ticks int relevantAnimationFramesForDistributing = numberOfFrames; if (distributeFramesBeforeFrame != 0) { @@ -91,7 +91,7 @@ void AnimationInfo::SetNewAnimation(uint8_t *pData, int numberOfFrames, int dela // How many game ticks will the Animation be really shown (skipped Frames and game ticks removed) int relevantAnimationTicksWithSkipping = relevantAnimationTicksForDistribution - (numSkippedFrames * ticksPerFrame); - if (params == AnimationDistributionParams::ProcessAnimationPending) { + if ((flags & AnimationDistributionFlags::ProcessAnimationPending) == AnimationDistributionFlags::ProcessAnimationPending) { // If ProcessAnimation will be called after SetNewAnimation (in same game tick as SetNewAnimation), we increment the Animation-Counter. // If no delay is specified, this will result in complete skipped frame (see ProcessAnimation). // But if we have a delay specified, this would only result in a reduced time the first frame is shown (one skipped delay). @@ -103,7 +103,7 @@ void AnimationInfo::SetNewAnimation(uint8_t *pData, int numberOfFrames, int dela TicksSinceSequenceStarted = -1; } - if (params == AnimationDistributionParams::SkipsDelayOfLastFrame) { + if ((flags & AnimationDistributionFlags::SkipsDelayOfLastFrame) == AnimationDistributionFlags::SkipsDelayOfLastFrame) { // The logic for player/monster/... (not ProcessAnimation) only checks the frame not the delay. // That means if a delay is specified, the last-frame is shown less then the other frames // Example: diff --git a/Source/engine/animationinfo.h b/Source/engine/animationinfo.h index c59b7e8cd..e250d5b1a 100644 --- a/Source/engine/animationinfo.h +++ b/Source/engine/animationinfo.h @@ -6,22 +6,23 @@ #pragma once #include +#include namespace devilution { /** * @brief Specifies what special logics are applied for a Animation */ -enum class AnimationDistributionParams : uint8_t { - None, +enum AnimationDistributionFlags : uint8_t { + None = 0, /* * @brief ProcessAnimation will be called after SetNewAnimation (in same game tick as NewPlrAnim) */ - ProcessAnimationPending, + ProcessAnimationPending = 1 << 0, /* * @brief Delay of last Frame is ignored (for example, because only Frame and not delay is checked in game_logic) */ - SkipsDelayOfLastFrame, + SkipsDelayOfLastFrame = 1 << 1, }; /* @@ -61,11 +62,11 @@ public: * @param pData Pointer to Animation Data * @param numberOfFrames Number of Frames in Animation * @param delayLen Delay after each Animation sequence - * @param params Specifies what special logics are applied to this Animation + * @param flags Specifies what special logics are applied to this Animation * @param numSkippedFrames Number of Frames that will be skipped (for example with modifier "faster attack") * @param distributeFramesBeforeFrame Distribute the numSkippedFrames only before this frame */ - void SetNewAnimation(uint8_t *pData, int numberOfFrames, int delayLen, AnimationDistributionParams params = AnimationDistributionParams::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); + void SetNewAnimation(uint8_t *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); /* * @brief Process the Animation for a game tick (for example advances the frame) diff --git a/Source/player.cpp b/Source/player.cpp index b89115852..427542a93 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -552,14 +552,14 @@ void FreePlayerGFX(int pnum) plr[pnum]._pGFXLoad = 0; } -void NewPlrAnim(int pnum, BYTE *pData, int numberOfFrames, int delayLen, int width, AnimationDistributionParams params /*= AnimationDistributionParams::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) +void NewPlrAnim(int pnum, BYTE *pData, int numberOfFrames, int delayLen, int width, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) { if ((DWORD)pnum >= MAX_PLRS) { app_fatal("NewPlrAnim: illegal player %d", pnum); } plr[pnum]._pAnimWidth = width; - plr[pnum].AnimInfo.SetNewAnimation(pData, numberOfFrames, delayLen, params, numSkippedFrames, distributeFramesBeforeFrame); + plr[pnum].AnimInfo.SetNewAnimation(pData, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame); } void ClearPlrPVars(int pnum) @@ -1489,7 +1489,7 @@ void StartAttack(int pnum, direction d) skippedAnimationFrames = 2; } - NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth, AnimationDistributionParams::ProcessAnimationPending, skippedAnimationFrames, plr[pnum]._pAFNum); + NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth, AnimationDistributionFlags::ProcessAnimationPending, skippedAnimationFrames, plr[pnum]._pAFNum); plr[pnum]._pmode = PM_ATTACK; FixPlayerLocation(pnum, d); SetPlayerOld(pnum); @@ -1517,7 +1517,7 @@ void StartRangeAttack(int pnum, direction d, int cx, int cy) } } - NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth, AnimationDistributionParams::ProcessAnimationPending, skippedAnimationFrames, plr[pnum]._pAFNum); + NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth, AnimationDistributionFlags::ProcessAnimationPending, skippedAnimationFrames, plr[pnum]._pAFNum); plr[pnum]._pmode = PM_RATTACK; FixPlayerLocation(pnum, d); @@ -1547,7 +1547,7 @@ void StartPlrBlock(int pnum, direction dir) skippedAnimationFrames = (plr[pnum]._pBFrames - 2); // ISPL_FASTBLOCK means we cancel the animation if frame 2 was shown } - NewPlrAnim(pnum, plr[pnum]._pBAnim[dir], plr[pnum]._pBFrames, 2, plr[pnum]._pBWidth, AnimationDistributionParams::SkipsDelayOfLastFrame, skippedAnimationFrames); + NewPlrAnim(pnum, plr[pnum]._pBAnim[dir], plr[pnum]._pBFrames, 2, plr[pnum]._pBWidth, AnimationDistributionFlags::SkipsDelayOfLastFrame, skippedAnimationFrames); plr[pnum]._pmode = PM_BLOCK; FixPlayerLocation(pnum, dir); @@ -1570,19 +1570,19 @@ void StartSpell(int pnum, direction d, int cx, int cy) if ((plr[pnum]._pGFXLoad & PFILE_FIRE) == 0) { LoadPlrGFX(pnum, PFILE_FIRE); } - NewPlrAnim(pnum, plr[pnum]._pFAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionParams::ProcessAnimationPending, 0, plr[pnum]._pSFNum); + NewPlrAnim(pnum, plr[pnum]._pFAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionFlags::ProcessAnimationPending, 0, plr[pnum]._pSFNum); break; case STYPE_LIGHTNING: if ((plr[pnum]._pGFXLoad & PFILE_LIGHTNING) == 0) { LoadPlrGFX(pnum, PFILE_LIGHTNING); } - NewPlrAnim(pnum, plr[pnum]._pLAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionParams::ProcessAnimationPending, 0, plr[pnum]._pSFNum); + NewPlrAnim(pnum, plr[pnum]._pLAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionFlags::ProcessAnimationPending, 0, plr[pnum]._pSFNum); break; case STYPE_MAGIC: if ((plr[pnum]._pGFXLoad & PFILE_MAGIC) == 0) { LoadPlrGFX(pnum, PFILE_MAGIC); } - NewPlrAnim(pnum, plr[pnum]._pTAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionParams::ProcessAnimationPending, 0, plr[pnum]._pSFNum); + NewPlrAnim(pnum, plr[pnum]._pTAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth, AnimationDistributionFlags::ProcessAnimationPending, 0, plr[pnum]._pSFNum); break; } } @@ -1693,7 +1693,7 @@ void StartPlrHit(int pnum, int dam, bool forcehit) skippedAnimationFrames = 0; } - NewPlrAnim(pnum, plr[pnum]._pHAnim[pd], plr[pnum]._pHFrames, 0, plr[pnum]._pHWidth, AnimationDistributionParams::None, skippedAnimationFrames); + NewPlrAnim(pnum, plr[pnum]._pHAnim[pd], plr[pnum]._pHFrames, 0, plr[pnum]._pHWidth, AnimationDistributionFlags::None, skippedAnimationFrames); plr[pnum]._pmode = PM_GOTHIT; FixPlayerLocation(pnum, pd); diff --git a/Source/player.h b/Source/player.h index 513ab10d8..5374d0c8c 100644 --- a/Source/player.h +++ b/Source/player.h @@ -399,11 +399,11 @@ void FreePlayerGFX(int pnum); * @param numberOfFrames Number of Frames in Animation * @param delayLen Delay after each Animation sequence * @param width Width of sprite - * @param params Specifies what special logics are applied to this Animation + * @param flags Specifies what special logics are applied to this Animation * @param numSkippedFrames Number of Frames that will be skipped (for example with modifier "faster attack") * @param distributeFramesBeforeFrame Distribute the numSkippedFrames only before this frame */ -void NewPlrAnim(int pnum, BYTE *pData, int numberOfFrames, int delayLen, int width, AnimationDistributionParams params = AnimationDistributionParams::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); +void NewPlrAnim(int pnum, BYTE *pData, int numberOfFrames, int delayLen, int width, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0); void SetPlrAnims(int pnum); void CreatePlayer(int pnum, HeroClass c); int CalcStatDiff(int pnum); diff --git a/test/animationinfo_test.cpp b/test/animationinfo_test.cpp index 563162d9e..3aaa65f77 100644 --- a/test/animationinfo_test.cpp +++ b/test/animationinfo_test.cpp @@ -16,7 +16,7 @@ struct TestData { * @brief Represents a call to SetNewAnimation */ struct SetNewAnimationData : TestData { - SetNewAnimationData(int numberOfFrames, int delayLen, AnimationDistributionParams params = AnimationDistributionParams::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0) + SetNewAnimationData(int numberOfFrames, int delayLen, AnimationDistributionFlags params = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0) { _NumberOfFrames = numberOfFrames; _DelayLen = delayLen; @@ -26,7 +26,7 @@ struct SetNewAnimationData : TestData { } int _NumberOfFrames; int _DelayLen; - AnimationDistributionParams _Params; + AnimationDistributionFlags _Params; int _NumSkippedFrames; int _DistributeFramesBeforeFrame; }; @@ -111,7 +111,7 @@ TEST(AnimationInfo, AttackSwordWarrior) // ProcessAnimationPending should be con { RunAnimationTest( { - new SetNewAnimationData(16, 0, AnimationDistributionParams::ProcessAnimationPending, 0, 9), + new SetNewAnimationData(16, 0, AnimationDistributionFlags::ProcessAnimationPending, 0, 9), // ProcessAnimation directly after StartAttack (in same GameTick). So we don't see any rendering before. new GameTickData(2, 0), new RenderingData(0.0f, 1), @@ -174,7 +174,7 @@ TEST(AnimationInfo, AttackSwordWarriorWithFastestAttack) // Skipped frames and P { RunAnimationTest( { - new SetNewAnimationData(16, 0, AnimationDistributionParams::ProcessAnimationPending, 2, 9), + new SetNewAnimationData(16, 0, AnimationDistributionFlags::ProcessAnimationPending, 2, 9), // ProcessAnimation directly after StartAttack (in same GameTick). So we don't see any rendering before. new GameTickData(2, 0), new RenderingData(0.0f, 1), @@ -230,7 +230,7 @@ TEST(AnimationInfo, AttackSwordWarriorRepeated) { RunAnimationTest( { - new SetNewAnimationData(16, 0, AnimationDistributionParams::ProcessAnimationPending, 0, 9), + new SetNewAnimationData(16, 0, AnimationDistributionFlags::ProcessAnimationPending, 0, 9), // ProcessAnimation directly after StartAttack (in same GameTick). So we don't see any rendering before. new GameTickData(2, 0), new RenderingData(0.0f, 1), @@ -275,7 +275,7 @@ TEST(AnimationInfo, AttackSwordWarriorRepeated) new RenderingData(0.3f, 10), // Start of repeated attack, cause plr[pnum].AnimInfo.CurrentFrame > plr[myplr]._pAFNum - new SetNewAnimationData(16, 0, AnimationDistributionParams::ProcessAnimationPending, 0, 9), + new SetNewAnimationData(16, 0, AnimationDistributionFlags::ProcessAnimationPending, 0, 9), // ProcessAnimation directly after StartAttack (in same GameTick). So we don't see any rendering before. new GameTickData(2, 0), new RenderingData(0.0f, 11), @@ -338,7 +338,7 @@ TEST(AnimationInfo, BlockingWarriorNormal) // Ignored delay for last Frame shoul { RunAnimationTest( { - new SetNewAnimationData(2, 2, AnimationDistributionParams::SkipsDelayOfLastFrame), + new SetNewAnimationData(2, 2, AnimationDistributionFlags::SkipsDelayOfLastFrame), new RenderingData(0.0f, 1), new RenderingData(0.3f, 1), new RenderingData(0.6f, 1), @@ -366,7 +366,7 @@ TEST(AnimationInfo, BlockingSorcererWithFastBlock) // Skipped frames and ignored { RunAnimationTest( { - new SetNewAnimationData(6, 2, AnimationDistributionParams::SkipsDelayOfLastFrame, 4), + new SetNewAnimationData(6, 2, AnimationDistributionFlags::SkipsDelayOfLastFrame, 4), new RenderingData(0.0f, 1), new RenderingData(0.3f, 1), new RenderingData(0.6f, 1), @@ -394,7 +394,7 @@ TEST(AnimationInfo, HitRecoverySorcererZenMode) // Skipped frames and ignored de { RunAnimationTest( { - new SetNewAnimationData(8, 0, AnimationDistributionParams::None, 4), + new SetNewAnimationData(8, 0, AnimationDistributionFlags::None, 4), new RenderingData(0.0f, 1), new RenderingData(0.3f, 1), new RenderingData(0.6f, 2),