27 changed files with 2572 additions and 2572 deletions
@ -1,154 +1,154 @@
|
||||
/**
|
||||
* @file animationinfo.cpp |
||||
* |
||||
* Contains the core animation information and related logic |
||||
*/ |
||||
|
||||
#include "animationinfo.h" |
||||
#include "appfat.h" |
||||
#include "nthread.h" |
||||
#include "utils/log.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
int AnimationInfo::GetFrameToUseForRendering() const |
||||
{ |
||||
// Normal logic is used,
|
||||
// - if no frame-skipping is required and so we have exactly one Animationframe per game tick
|
||||
// or
|
||||
// - if we load from a savegame where the new variables are not stored (we don't want to break savegame compatiblity because of smoother rendering of one animation)
|
||||
if (RelevantFramesForDistributing <= 0) |
||||
return CurrentFrame; |
||||
|
||||
if (CurrentFrame > RelevantFramesForDistributing) |
||||
return CurrentFrame; |
||||
|
||||
assert(TicksSinceSequenceStarted >= 0); |
||||
|
||||
// we don't use the processed game ticks alone but also the fragtion of the next game tick (if a rendering happens between game ticks). This helps to smooth the animations.
|
||||
float totalTicksForCurrentAnimationSequence = gfProgressToNextGameTick + (float)TicksSinceSequenceStarted; |
||||
|
||||
// 1 added for rounding reasons. float to int cast always truncate.
|
||||
int absoluteAnimationFrame = 1 + (int)(totalTicksForCurrentAnimationSequence * TickModifier); |
||||
if (SkippedFramesFromPreviousAnimation > 0) { |
||||
// absoluteAnimationFrames contains also the Frames from the previous Animation, so if we want to get the current Frame we have to remove them
|
||||
absoluteAnimationFrame -= SkippedFramesFromPreviousAnimation; |
||||
if (absoluteAnimationFrame <= 0) { |
||||
// We still display the remains of the previous Animation
|
||||
absoluteAnimationFrame = NumberOfFrames + absoluteAnimationFrame; |
||||
} |
||||
} else if (absoluteAnimationFrame > RelevantFramesForDistributing) { |
||||
// this can happen if we are at the last frame and the next game tick is due (gfProgressToNextGameTick >= 1.0f)
|
||||
if (absoluteAnimationFrame > (RelevantFramesForDistributing + 1)) { |
||||
// we should never have +2 frames even if next game tick is due
|
||||
Log("GetFrameToUseForRendering: Calculated an invalid Animation Frame (Calculated {} MaxFrame {})", absoluteAnimationFrame, RelevantFramesForDistributing); |
||||
} |
||||
return RelevantFramesForDistributing; |
||||
} |
||||
if (absoluteAnimationFrame <= 0) { |
||||
Log("GetFrameToUseForRendering: Calculated an invalid Animation Frame (Calculated {})", absoluteAnimationFrame); |
||||
return 1; |
||||
} |
||||
return absoluteAnimationFrame; |
||||
} |
||||
|
||||
void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) |
||||
{ |
||||
if ((flags & AnimationDistributionFlags::RepeatedAction) == AnimationDistributionFlags::RepeatedAction && distributeFramesBeforeFrame != 0 && NumberOfFrames == numberOfFrames && CurrentFrame >= distributeFramesBeforeFrame && CurrentFrame != NumberOfFrames) { |
||||
// We showed the same Animation (for example a melee attack) before but truncated the Animation.
|
||||
// So now we should add them back to the new Animation. This increases the speed of the current Animation but the game logic/ticks isn't affected.
|
||||
SkippedFramesFromPreviousAnimation = NumberOfFrames - CurrentFrame; |
||||
} else { |
||||
SkippedFramesFromPreviousAnimation = 0; |
||||
} |
||||
|
||||
this->pData = pData; |
||||
NumberOfFrames = numberOfFrames; |
||||
CurrentFrame = 1; |
||||
DelayCounter = 0; |
||||
DelayLen = delayLen; |
||||
TicksSinceSequenceStarted = 0; |
||||
RelevantFramesForDistributing = 0; |
||||
TickModifier = 0.0f; |
||||
|
||||
if (numSkippedFrames != 0 || flags != AnimationDistributionFlags::None) { |
||||
// Animation Frames that will be adjusted for the skipped Frames/game ticks
|
||||
int relevantAnimationFramesForDistributing = numberOfFrames; |
||||
if (distributeFramesBeforeFrame != 0) { |
||||
// After an attack hits (_pAFNum or _pSFNum) it can be canceled or another attack can be queued and this means the animation is canceled.
|
||||
// In normal attacks frame skipping always happens before the attack actual hit.
|
||||
// This has the advantage that the sword or bow always points to the enemy when the hit happens (_pAFNum or _pSFNum).
|
||||
// Our distribution logic must also regard this behaviour, so we are not allowed to distribute the skipped animations after the actual hit (_pAnimStopDistributingAfterFrame).
|
||||
relevantAnimationFramesForDistributing = distributeFramesBeforeFrame - 1; |
||||
} |
||||
|
||||
// How many game ticks are needed to advance one Animation Frame
|
||||
int ticksPerFrame = (delayLen + 1); |
||||
|
||||
// Game ticks that will be adjusted for the skipped Frames/game ticks
|
||||
int relevantAnimationTicksForDistribution = relevantAnimationFramesForDistributing * ticksPerFrame; |
||||
|
||||
// How many game ticks will the Animation be really shown (skipped Frames and game ticks removed)
|
||||
int relevantAnimationTicksWithSkipping = relevantAnimationTicksForDistribution - (numSkippedFrames * ticksPerFrame); |
||||
|
||||
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).
|
||||
// Because of that, we only the remove one game tick from the time the Animation is shown
|
||||
relevantAnimationTicksWithSkipping -= 1; |
||||
// The Animation Distribution Logic needs to account how many game ticks passed since the Animation started.
|
||||
// Because ProcessAnimation will increase this later (in same game tick as SetNewAnimation), we correct this upfront.
|
||||
// This also means Rendering should never hapen with TicksSinceSequenceStarted < 0.
|
||||
TicksSinceSequenceStarted = -1; |
||||
} |
||||
|
||||
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:
|
||||
// If we have a animation with 3 frames and with a delay of 1 (ticksPerFrame = 2).
|
||||
// The logic checks "if (frame == 3) { start_new_animation(); }"
|
||||
// This will result that frame 4 is the last shown Animation Frame.
|
||||
// GameTick Frame Cnt
|
||||
// 1 1 0
|
||||
// 2 1 1
|
||||
// 3 2 0
|
||||
// 3 2 1
|
||||
// 4 3 0
|
||||
// 5 - -
|
||||
// in game tick 5 ProcessPlayer sees Frame = 3 and stops the animation.
|
||||
// But Frame 3 is only shown 1 game tick and all other Frames are shown 2 game ticks.
|
||||
// Thats why we need to remove the Delay of the last Frame from the time (game ticks) the Animation is shown
|
||||
relevantAnimationTicksWithSkipping -= delayLen; |
||||
} |
||||
|
||||
// The truncated Frames from previous Animation will also be shown, so we also have to distribute them for the given time (game ticks)
|
||||
relevantAnimationTicksForDistribution += (SkippedFramesFromPreviousAnimation * ticksPerFrame); |
||||
|
||||
// if we skipped Frames we need to expand the game ticks to make one game tick for this Animation "faster"
|
||||
float tickModifier = (float)relevantAnimationTicksForDistribution / (float)relevantAnimationTicksWithSkipping; |
||||
|
||||
// tickModifier specifies the Animation fraction per game tick, so we have to remove the delay from the variable
|
||||
tickModifier /= ticksPerFrame; |
||||
|
||||
RelevantFramesForDistributing = relevantAnimationFramesForDistributing; |
||||
TickModifier = tickModifier; |
||||
} |
||||
} |
||||
|
||||
void AnimationInfo::ProcessAnimation() |
||||
{ |
||||
DelayCounter++; |
||||
TicksSinceSequenceStarted++; |
||||
if (DelayCounter > DelayLen) { |
||||
DelayCounter = 0; |
||||
CurrentFrame++; |
||||
if (CurrentFrame > NumberOfFrames) { |
||||
CurrentFrame = 1; |
||||
TicksSinceSequenceStarted = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
/**
|
||||
* @file animationinfo.cpp |
||||
* |
||||
* Contains the core animation information and related logic |
||||
*/ |
||||
|
||||
#include "animationinfo.h" |
||||
#include "appfat.h" |
||||
#include "nthread.h" |
||||
#include "utils/log.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
int AnimationInfo::GetFrameToUseForRendering() const |
||||
{ |
||||
// Normal logic is used,
|
||||
// - if no frame-skipping is required and so we have exactly one Animationframe per game tick
|
||||
// or
|
||||
// - if we load from a savegame where the new variables are not stored (we don't want to break savegame compatiblity because of smoother rendering of one animation)
|
||||
if (RelevantFramesForDistributing <= 0) |
||||
return CurrentFrame; |
||||
|
||||
if (CurrentFrame > RelevantFramesForDistributing) |
||||
return CurrentFrame; |
||||
|
||||
assert(TicksSinceSequenceStarted >= 0); |
||||
|
||||
// we don't use the processed game ticks alone but also the fragtion of the next game tick (if a rendering happens between game ticks). This helps to smooth the animations.
|
||||
float totalTicksForCurrentAnimationSequence = gfProgressToNextGameTick + (float)TicksSinceSequenceStarted; |
||||
|
||||
// 1 added for rounding reasons. float to int cast always truncate.
|
||||
int absoluteAnimationFrame = 1 + (int)(totalTicksForCurrentAnimationSequence * TickModifier); |
||||
if (SkippedFramesFromPreviousAnimation > 0) { |
||||
// absoluteAnimationFrames contains also the Frames from the previous Animation, so if we want to get the current Frame we have to remove them
|
||||
absoluteAnimationFrame -= SkippedFramesFromPreviousAnimation; |
||||
if (absoluteAnimationFrame <= 0) { |
||||
// We still display the remains of the previous Animation
|
||||
absoluteAnimationFrame = NumberOfFrames + absoluteAnimationFrame; |
||||
} |
||||
} else if (absoluteAnimationFrame > RelevantFramesForDistributing) { |
||||
// this can happen if we are at the last frame and the next game tick is due (gfProgressToNextGameTick >= 1.0f)
|
||||
if (absoluteAnimationFrame > (RelevantFramesForDistributing + 1)) { |
||||
// we should never have +2 frames even if next game tick is due
|
||||
Log("GetFrameToUseForRendering: Calculated an invalid Animation Frame (Calculated {} MaxFrame {})", absoluteAnimationFrame, RelevantFramesForDistributing); |
||||
} |
||||
return RelevantFramesForDistributing; |
||||
} |
||||
if (absoluteAnimationFrame <= 0) { |
||||
Log("GetFrameToUseForRendering: Calculated an invalid Animation Frame (Calculated {})", absoluteAnimationFrame); |
||||
return 1; |
||||
} |
||||
return absoluteAnimationFrame; |
||||
} |
||||
|
||||
void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/) |
||||
{ |
||||
if ((flags & AnimationDistributionFlags::RepeatedAction) == AnimationDistributionFlags::RepeatedAction && distributeFramesBeforeFrame != 0 && NumberOfFrames == numberOfFrames && CurrentFrame >= distributeFramesBeforeFrame && CurrentFrame != NumberOfFrames) { |
||||
// We showed the same Animation (for example a melee attack) before but truncated the Animation.
|
||||
// So now we should add them back to the new Animation. This increases the speed of the current Animation but the game logic/ticks isn't affected.
|
||||
SkippedFramesFromPreviousAnimation = NumberOfFrames - CurrentFrame; |
||||
} else { |
||||
SkippedFramesFromPreviousAnimation = 0; |
||||
} |
||||
|
||||
this->pData = pData; |
||||
NumberOfFrames = numberOfFrames; |
||||
CurrentFrame = 1; |
||||
DelayCounter = 0; |
||||
DelayLen = delayLen; |
||||
TicksSinceSequenceStarted = 0; |
||||
RelevantFramesForDistributing = 0; |
||||
TickModifier = 0.0f; |
||||
|
||||
if (numSkippedFrames != 0 || flags != AnimationDistributionFlags::None) { |
||||
// Animation Frames that will be adjusted for the skipped Frames/game ticks
|
||||
int relevantAnimationFramesForDistributing = numberOfFrames; |
||||
if (distributeFramesBeforeFrame != 0) { |
||||
// After an attack hits (_pAFNum or _pSFNum) it can be canceled or another attack can be queued and this means the animation is canceled.
|
||||
// In normal attacks frame skipping always happens before the attack actual hit.
|
||||
// This has the advantage that the sword or bow always points to the enemy when the hit happens (_pAFNum or _pSFNum).
|
||||
// Our distribution logic must also regard this behaviour, so we are not allowed to distribute the skipped animations after the actual hit (_pAnimStopDistributingAfterFrame).
|
||||
relevantAnimationFramesForDistributing = distributeFramesBeforeFrame - 1; |
||||
} |
||||
|
||||
// How many game ticks are needed to advance one Animation Frame
|
||||
int ticksPerFrame = (delayLen + 1); |
||||
|
||||
// Game ticks that will be adjusted for the skipped Frames/game ticks
|
||||
int relevantAnimationTicksForDistribution = relevantAnimationFramesForDistributing * ticksPerFrame; |
||||
|
||||
// How many game ticks will the Animation be really shown (skipped Frames and game ticks removed)
|
||||
int relevantAnimationTicksWithSkipping = relevantAnimationTicksForDistribution - (numSkippedFrames * ticksPerFrame); |
||||
|
||||
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).
|
||||
// Because of that, we only the remove one game tick from the time the Animation is shown
|
||||
relevantAnimationTicksWithSkipping -= 1; |
||||
// The Animation Distribution Logic needs to account how many game ticks passed since the Animation started.
|
||||
// Because ProcessAnimation will increase this later (in same game tick as SetNewAnimation), we correct this upfront.
|
||||
// This also means Rendering should never hapen with TicksSinceSequenceStarted < 0.
|
||||
TicksSinceSequenceStarted = -1; |
||||
} |
||||
|
||||
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:
|
||||
// If we have a animation with 3 frames and with a delay of 1 (ticksPerFrame = 2).
|
||||
// The logic checks "if (frame == 3) { start_new_animation(); }"
|
||||
// This will result that frame 4 is the last shown Animation Frame.
|
||||
// GameTick Frame Cnt
|
||||
// 1 1 0
|
||||
// 2 1 1
|
||||
// 3 2 0
|
||||
// 3 2 1
|
||||
// 4 3 0
|
||||
// 5 - -
|
||||
// in game tick 5 ProcessPlayer sees Frame = 3 and stops the animation.
|
||||
// But Frame 3 is only shown 1 game tick and all other Frames are shown 2 game ticks.
|
||||
// Thats why we need to remove the Delay of the last Frame from the time (game ticks) the Animation is shown
|
||||
relevantAnimationTicksWithSkipping -= delayLen; |
||||
} |
||||
|
||||
// The truncated Frames from previous Animation will also be shown, so we also have to distribute them for the given time (game ticks)
|
||||
relevantAnimationTicksForDistribution += (SkippedFramesFromPreviousAnimation * ticksPerFrame); |
||||
|
||||
// if we skipped Frames we need to expand the game ticks to make one game tick for this Animation "faster"
|
||||
float tickModifier = (float)relevantAnimationTicksForDistribution / (float)relevantAnimationTicksWithSkipping; |
||||
|
||||
// tickModifier specifies the Animation fraction per game tick, so we have to remove the delay from the variable
|
||||
tickModifier /= ticksPerFrame; |
||||
|
||||
RelevantFramesForDistributing = relevantAnimationFramesForDistributing; |
||||
TickModifier = tickModifier; |
||||
} |
||||
} |
||||
|
||||
void AnimationInfo::ProcessAnimation() |
||||
{ |
||||
DelayCounter++; |
||||
TicksSinceSequenceStarted++; |
||||
if (DelayCounter > DelayLen) { |
||||
DelayCounter = 0; |
||||
CurrentFrame++; |
||||
if (CurrentFrame > NumberOfFrames) { |
||||
CurrentFrame = 1; |
||||
TicksSinceSequenceStarted = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
|
||||
@ -1,101 +1,101 @@
|
||||
/**
|
||||
* @file animationinfo.h |
||||
* |
||||
* Contains the core animation information and related logic |
||||
*/ |
||||
#pragma once |
||||
|
||||
#include <stdint.h> |
||||
#include <type_traits> |
||||
|
||||
#include "engine.h" |
||||
|
||||
namespace devilution { |
||||
|
||||
/**
|
||||
* @brief Specifies what special logics are applied for a Animation |
||||
*/ |
||||
enum AnimationDistributionFlags : uint8_t { |
||||
None = 0, |
||||
/**
|
||||
* @brief ProcessAnimation will be called after SetNewAnimation (in same game tick as NewPlrAnim) |
||||
*/ |
||||
ProcessAnimationPending = 1 << 0, |
||||
/**
|
||||
* @brief Delay of last Frame is ignored (for example, because only Frame and not delay is checked in game_logic) |
||||
*/ |
||||
SkipsDelayOfLastFrame = 1 << 1, |
||||
/**
|
||||
* @brief Repeated Animation (for example same player melee attack, that can be repeated directly after hit frame and doesn't need to show all animation frames) |
||||
*/ |
||||
RepeatedAction = 1 << 2, |
||||
}; |
||||
|
||||
/*
|
||||
* @brief Contains the core animation information and related logic |
||||
*/ |
||||
class AnimationInfo { |
||||
public: |
||||
/**
|
||||
* @brief Pointer to Animation Data |
||||
*/ |
||||
byte *pData; |
||||
/**
|
||||
* @brief Additional delay of each animation in the current animation |
||||
*/ |
||||
int DelayLen; |
||||
/**
|
||||
* @brief Increases by one each game tick, counting how close we are to DelayLen |
||||
*/ |
||||
int DelayCounter; |
||||
/**
|
||||
* @brief Number of frames in current animation |
||||
*/ |
||||
int NumberOfFrames; |
||||
/**
|
||||
* @brief Current frame of animation |
||||
*/ |
||||
int CurrentFrame; |
||||
|
||||
/**
|
||||
* @brief Calculates the Frame to use for the Animation rendering |
||||
* @return The Frame to use for rendering |
||||
*/ |
||||
int GetFrameToUseForRendering() const; |
||||
|
||||
/**
|
||||
* @brief Sets the new Animation with all relevant information for rendering |
||||
* @param pData Pointer to Animation Data |
||||
* @param numberOfFrames Number of Frames in Animation |
||||
* @param delayLen Delay after each Animation sequence |
||||
* @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(byte *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) |
||||
*/ |
||||
void ProcessAnimation(); |
||||
|
||||
private: |
||||
/**
|
||||
* @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). |
||||
*/ |
||||
float TickModifier; |
||||
/**
|
||||
* @brief Number of game ticks after the current animation sequence started |
||||
*/ |
||||
int TicksSinceSequenceStarted; |
||||
/**
|
||||
* @brief Animation Frames that will be adjusted for the skipped Frames/game ticks |
||||
*/ |
||||
int RelevantFramesForDistributing; |
||||
/**
|
||||
* @brief Animation Frames that wasn't shown from previous Animation |
||||
*/ |
||||
int SkippedFramesFromPreviousAnimation; |
||||
}; |
||||
|
||||
} // namespace devilution
|
||||
/**
|
||||
* @file animationinfo.h |
||||
* |
||||
* Contains the core animation information and related logic |
||||
*/ |
||||
#pragma once |
||||
|
||||
#include <stdint.h> |
||||
#include <type_traits> |
||||
|
||||
#include "engine.h" |
||||
|
||||
namespace devilution { |
||||
|
||||
/**
|
||||
* @brief Specifies what special logics are applied for a Animation |
||||
*/ |
||||
enum AnimationDistributionFlags : uint8_t { |
||||
None = 0, |
||||
/**
|
||||
* @brief ProcessAnimation will be called after SetNewAnimation (in same game tick as NewPlrAnim) |
||||
*/ |
||||
ProcessAnimationPending = 1 << 0, |
||||
/**
|
||||
* @brief Delay of last Frame is ignored (for example, because only Frame and not delay is checked in game_logic) |
||||
*/ |
||||
SkipsDelayOfLastFrame = 1 << 1, |
||||
/**
|
||||
* @brief Repeated Animation (for example same player melee attack, that can be repeated directly after hit frame and doesn't need to show all animation frames) |
||||
*/ |
||||
RepeatedAction = 1 << 2, |
||||
}; |
||||
|
||||
/*
|
||||
* @brief Contains the core animation information and related logic |
||||
*/ |
||||
class AnimationInfo { |
||||
public: |
||||
/**
|
||||
* @brief Pointer to Animation Data |
||||
*/ |
||||
byte *pData; |
||||
/**
|
||||
* @brief Additional delay of each animation in the current animation |
||||
*/ |
||||
int DelayLen; |
||||
/**
|
||||
* @brief Increases by one each game tick, counting how close we are to DelayLen |
||||
*/ |
||||
int DelayCounter; |
||||
/**
|
||||
* @brief Number of frames in current animation |
||||
*/ |
||||
int NumberOfFrames; |
||||
/**
|
||||
* @brief Current frame of animation |
||||
*/ |
||||
int CurrentFrame; |
||||
|
||||
/**
|
||||
* @brief Calculates the Frame to use for the Animation rendering |
||||
* @return The Frame to use for rendering |
||||
*/ |
||||
int GetFrameToUseForRendering() const; |
||||
|
||||
/**
|
||||
* @brief Sets the new Animation with all relevant information for rendering |
||||
* @param pData Pointer to Animation Data |
||||
* @param numberOfFrames Number of Frames in Animation |
||||
* @param delayLen Delay after each Animation sequence |
||||
* @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(byte *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) |
||||
*/ |
||||
void ProcessAnimation(); |
||||
|
||||
private: |
||||
/**
|
||||
* @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). |
||||
*/ |
||||
float TickModifier; |
||||
/**
|
||||
* @brief Number of game ticks after the current animation sequence started |
||||
*/ |
||||
int TicksSinceSequenceStarted; |
||||
/**
|
||||
* @brief Animation Frames that will be adjusted for the skipped Frames/game ticks |
||||
*/ |
||||
int RelevantFramesForDistributing; |
||||
/**
|
||||
* @brief Animation Frames that wasn't shown from previous Animation |
||||
*/ |
||||
int SkippedFramesFromPreviousAnimation; |
||||
}; |
||||
|
||||
} // namespace devilution
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once |
||||
|
||||
void DvlNet_SendInfoRequest(); |
||||
std::vector<std::string> DvlNet_GetGamelist(); |
||||
void DvlNet_SetPassword(std::string pw); |
||||
#pragma once |
||||
|
||||
void DvlNet_SendInfoRequest(); |
||||
std::vector<std::string> DvlNet_GetGamelist(); |
||||
void DvlNet_SetPassword(std::string pw); |
||||
|
||||
@ -1,73 +1,73 @@
|
||||
/**
|
||||
* @file math.h |
||||
* |
||||
* Math utility functions |
||||
*/ |
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
namespace math { |
||||
|
||||
/**
|
||||
* @brief Compute sign of t |
||||
* @tparam T Any arithmetic type |
||||
* @param t Value to compute sign of |
||||
* @return -1 if t < 0, 1 if t > 0, 0 if t == 0 |
||||
*/ |
||||
template <typename T> |
||||
int Sign(T t) |
||||
{ |
||||
return (t > T(0)) - (t < T(0)); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Linearly interpolate from a towards b using mixing value t |
||||
* @tparam V Any arithmetic type, used for interpolants and return value |
||||
* @tparam T Any arithmetic type, used for interpolator |
||||
* @param a Low interpolation value (returned when t == 0) |
||||
* @param b High interpolation value (returned when t == 1) |
||||
* @param t Interpolator, commonly in range [0..1], values outside this range will extrapolate |
||||
* @return a + (b - a) * t |
||||
*/ |
||||
template <typename V, typename T> |
||||
V Lerp(V a, V b, T t) |
||||
{ |
||||
return a + (b - a) * t; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Inverse lerp, given two key values a and b, and a free value v, determine mixing factor t so that v = Lerp(a, b, t) |
||||
* @tparam T Any arithmetic type |
||||
* @param a Low key value (function returns 0 if v == a) |
||||
* @param b High key value (function returns 1 if v == b) |
||||
* @param v Mixing factor, commonly in range [a..b] to get a return [0..1] |
||||
* @return Value t so that v = Lerp(a, b, t); or 0 if b == a |
||||
*/ |
||||
template <typename T> |
||||
T InvLerp(T a, T b, T v) |
||||
{ |
||||
if (b == a) |
||||
return T(0); |
||||
|
||||
return (v - a) / (b - a); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Remaps value v from range [inMin, inMax] to [outMin, outMax] |
||||
* @tparam T Any arithmetic type |
||||
* @param inMin First bound of input range |
||||
* @param inMax Second bound of input range |
||||
* @param outMin First bound of output range |
||||
* @param outMax Second bound of output range |
||||
* @param v Value to remap |
||||
* @return Transformed value so that InvLerp(inMin, inMax, v) == InvLerp(outMin, outMax, return) |
||||
*/ |
||||
template <typename T> |
||||
T Remap(T inMin, T inMax, T outMin, T outMax, T v) |
||||
{ |
||||
auto t = InvLerp(inMin, inMax, v); |
||||
return Lerp(outMin, outMax, t); |
||||
} |
||||
|
||||
} // namespace math
|
||||
} // namespace devilution
|
||||
/**
|
||||
* @file math.h |
||||
* |
||||
* Math utility functions |
||||
*/ |
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
namespace math { |
||||
|
||||
/**
|
||||
* @brief Compute sign of t |
||||
* @tparam T Any arithmetic type |
||||
* @param t Value to compute sign of |
||||
* @return -1 if t < 0, 1 if t > 0, 0 if t == 0 |
||||
*/ |
||||
template <typename T> |
||||
int Sign(T t) |
||||
{ |
||||
return (t > T(0)) - (t < T(0)); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Linearly interpolate from a towards b using mixing value t |
||||
* @tparam V Any arithmetic type, used for interpolants and return value |
||||
* @tparam T Any arithmetic type, used for interpolator |
||||
* @param a Low interpolation value (returned when t == 0) |
||||
* @param b High interpolation value (returned when t == 1) |
||||
* @param t Interpolator, commonly in range [0..1], values outside this range will extrapolate |
||||
* @return a + (b - a) * t |
||||
*/ |
||||
template <typename V, typename T> |
||||
V Lerp(V a, V b, T t) |
||||
{ |
||||
return a + (b - a) * t; |
||||
} |
||||
|
||||
/**
|
||||
* @brief Inverse lerp, given two key values a and b, and a free value v, determine mixing factor t so that v = Lerp(a, b, t) |
||||
* @tparam T Any arithmetic type |
||||
* @param a Low key value (function returns 0 if v == a) |
||||
* @param b High key value (function returns 1 if v == b) |
||||
* @param v Mixing factor, commonly in range [a..b] to get a return [0..1] |
||||
* @return Value t so that v = Lerp(a, b, t); or 0 if b == a |
||||
*/ |
||||
template <typename T> |
||||
T InvLerp(T a, T b, T v) |
||||
{ |
||||
if (b == a) |
||||
return T(0); |
||||
|
||||
return (v - a) / (b - a); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Remaps value v from range [inMin, inMax] to [outMin, outMax] |
||||
* @tparam T Any arithmetic type |
||||
* @param inMin First bound of input range |
||||
* @param inMax Second bound of input range |
||||
* @param outMin First bound of output range |
||||
* @param outMax Second bound of output range |
||||
* @param v Value to remap |
||||
* @return Transformed value so that InvLerp(inMin, inMax, v) == InvLerp(outMin, outMax, return) |
||||
*/ |
||||
template <typename T> |
||||
T Remap(T inMin, T inMax, T outMin, T outMax, T v) |
||||
{ |
||||
auto t = InvLerp(inMin, inMax, v); |
||||
return Lerp(outMin, outMax, t); |
||||
} |
||||
|
||||
} // namespace math
|
||||
} // namespace devilution
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#pragma once |
||||
|
||||
#ifdef __has_include |
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && __has_include(<string_view>) // should be 201606L, but STL headers disagree
|
||||
#include <string_view> // IWYU pragma: export |
||||
namespace devilution { |
||||
using string_view = std::string_view; |
||||
} |
||||
#elif __has_include(<experimental/string_view>) |
||||
#include <experimental/string_view> // IWYU pragma: export |
||||
namespace devilution { |
||||
using string_view = std::experimental::string_view; |
||||
} |
||||
#else |
||||
#error "Missing support for <string_view> or <experimental/string_view>" |
||||
#endif |
||||
#else |
||||
#error "__has_include unavailable" |
||||
#endif |
||||
#pragma once |
||||
|
||||
#ifdef __has_include |
||||
#if defined(__cplusplus) && __cplusplus >= 201703L && __has_include(<string_view>) // should be 201606L, but STL headers disagree
|
||||
#include <string_view> // IWYU pragma: export |
||||
namespace devilution { |
||||
using string_view = std::string_view; |
||||
} |
||||
#elif __has_include(<experimental/string_view>) |
||||
#include <experimental/string_view> // IWYU pragma: export |
||||
namespace devilution { |
||||
using string_view = std::experimental::string_view; |
||||
} |
||||
#else |
||||
#error "Missing support for <string_view> or <experimental/string_view>" |
||||
#endif |
||||
#else |
||||
#error "__has_include unavailable" |
||||
#endif |
||||
|
||||
@ -1,31 +1,31 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "appfat.h" |
||||
#include "diablo.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Appfat, app_fatal) |
||||
{ |
||||
EXPECT_EXIT(app_fatal("test"), ::testing::ExitedWithCode(1), "test"); |
||||
} |
||||
|
||||
TEST(Appfat, ErrDlg) |
||||
{ |
||||
EXPECT_EXIT(ErrDlg("Title", "Unknown error", "appfat.cpp", 7), ::testing::ExitedWithCode(1), "Unknown error\n\nThe error occurred at: appfat.cpp line 7"); |
||||
} |
||||
|
||||
TEST(Appfat, FileErrDlg) |
||||
{ |
||||
EXPECT_EXIT(FileErrDlg("devilution/image.cl2"), ::testing::ExitedWithCode(1), "devilution/image.cl2"); |
||||
} |
||||
|
||||
TEST(Appfat, InsertCDDlg) |
||||
{ |
||||
EXPECT_EXIT(InsertCDDlg(), ::testing::ExitedWithCode(1), "diabdat.mpq"); |
||||
} |
||||
|
||||
TEST(Appfat, DirErrorDlg) |
||||
{ |
||||
EXPECT_EXIT(DirErrorDlg("/"), ::testing::ExitedWithCode(1), "Unable to write to location:\n/"); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "appfat.h" |
||||
#include "diablo.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Appfat, app_fatal) |
||||
{ |
||||
EXPECT_EXIT(app_fatal("test"), ::testing::ExitedWithCode(1), "test"); |
||||
} |
||||
|
||||
TEST(Appfat, ErrDlg) |
||||
{ |
||||
EXPECT_EXIT(ErrDlg("Title", "Unknown error", "appfat.cpp", 7), ::testing::ExitedWithCode(1), "Unknown error\n\nThe error occurred at: appfat.cpp line 7"); |
||||
} |
||||
|
||||
TEST(Appfat, FileErrDlg) |
||||
{ |
||||
EXPECT_EXIT(FileErrDlg("devilution/image.cl2"), ::testing::ExitedWithCode(1), "devilution/image.cl2"); |
||||
} |
||||
|
||||
TEST(Appfat, InsertCDDlg) |
||||
{ |
||||
EXPECT_EXIT(InsertCDDlg(), ::testing::ExitedWithCode(1), "diabdat.mpq"); |
||||
} |
||||
|
||||
TEST(Appfat, DirErrorDlg) |
||||
{ |
||||
EXPECT_EXIT(DirErrorDlg("/"), ::testing::ExitedWithCode(1), "Unable to write to location:\n/"); |
||||
} |
||||
|
||||
@ -1,127 +1,127 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "automap.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Automap, InitAutomap) |
||||
{ |
||||
InitAutomapOnce(); |
||||
EXPECT_EQ(AutomapActive, false); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, StartAutomap) |
||||
{ |
||||
StartAutomap(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
EXPECT_EQ(AutomapActive, true); |
||||
} |
||||
|
||||
TEST(Automap, AutomapUp) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapUp(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
} |
||||
|
||||
TEST(Automap, AutomapDown) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapDown(); |
||||
EXPECT_EQ(AutomapOffset.x, 2); |
||||
EXPECT_EQ(AutomapOffset.y, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapLeft) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapLeft(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapRight) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapRight(); |
||||
EXPECT_EQ(AutomapOffset.x, 2); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomIn) |
||||
{ |
||||
AutoMapScale = 50; |
||||
AutomapZoomIn(); |
||||
EXPECT_EQ(AutoMapScale, 55); |
||||
EXPECT_EQ(AmLine64, 35); |
||||
EXPECT_EQ(AmLine32, 17); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomIn_Max) |
||||
{ |
||||
AutoMapScale = 195; |
||||
AutomapZoomIn(); |
||||
AutomapZoomIn(); |
||||
EXPECT_EQ(AutoMapScale, 200); |
||||
EXPECT_EQ(AmLine64, 128); |
||||
EXPECT_EQ(AmLine32, 64); |
||||
EXPECT_EQ(AmLine16, 32); |
||||
EXPECT_EQ(AmLine8, 16); |
||||
EXPECT_EQ(AmLine4, 8); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomOut) |
||||
{ |
||||
AutoMapScale = 200; |
||||
AutomapZoomOut(); |
||||
EXPECT_EQ(AutoMapScale, 195); |
||||
EXPECT_EQ(AmLine64, 124); |
||||
EXPECT_EQ(AmLine32, 62); |
||||
EXPECT_EQ(AmLine16, 31); |
||||
EXPECT_EQ(AmLine8, 15); |
||||
EXPECT_EQ(AmLine4, 7); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomOut_Min) |
||||
{ |
||||
AutoMapScale = 55; |
||||
AutomapZoomOut(); |
||||
AutomapZoomOut(); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomReset) |
||||
{ |
||||
AutoMapScale = 50; |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapZoomReset(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "automap.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Automap, InitAutomap) |
||||
{ |
||||
InitAutomapOnce(); |
||||
EXPECT_EQ(AutomapActive, false); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, StartAutomap) |
||||
{ |
||||
StartAutomap(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
EXPECT_EQ(AutomapActive, true); |
||||
} |
||||
|
||||
TEST(Automap, AutomapUp) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapUp(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
} |
||||
|
||||
TEST(Automap, AutomapDown) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapDown(); |
||||
EXPECT_EQ(AutomapOffset.x, 2); |
||||
EXPECT_EQ(AutomapOffset.y, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapLeft) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapLeft(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapRight) |
||||
{ |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapRight(); |
||||
EXPECT_EQ(AutomapOffset.x, 2); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomIn) |
||||
{ |
||||
AutoMapScale = 50; |
||||
AutomapZoomIn(); |
||||
EXPECT_EQ(AutoMapScale, 55); |
||||
EXPECT_EQ(AmLine64, 35); |
||||
EXPECT_EQ(AmLine32, 17); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomIn_Max) |
||||
{ |
||||
AutoMapScale = 195; |
||||
AutomapZoomIn(); |
||||
AutomapZoomIn(); |
||||
EXPECT_EQ(AutoMapScale, 200); |
||||
EXPECT_EQ(AmLine64, 128); |
||||
EXPECT_EQ(AmLine32, 64); |
||||
EXPECT_EQ(AmLine16, 32); |
||||
EXPECT_EQ(AmLine8, 16); |
||||
EXPECT_EQ(AmLine4, 8); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomOut) |
||||
{ |
||||
AutoMapScale = 200; |
||||
AutomapZoomOut(); |
||||
EXPECT_EQ(AutoMapScale, 195); |
||||
EXPECT_EQ(AmLine64, 124); |
||||
EXPECT_EQ(AmLine32, 62); |
||||
EXPECT_EQ(AmLine16, 31); |
||||
EXPECT_EQ(AmLine8, 15); |
||||
EXPECT_EQ(AmLine4, 7); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomOut_Min) |
||||
{ |
||||
AutoMapScale = 55; |
||||
AutomapZoomOut(); |
||||
AutomapZoomOut(); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
TEST(Automap, AutomapZoomReset) |
||||
{ |
||||
AutoMapScale = 50; |
||||
AutomapOffset.x = 1; |
||||
AutomapOffset.y = 1; |
||||
AutomapZoomReset(); |
||||
EXPECT_EQ(AutomapOffset.x, 0); |
||||
EXPECT_EQ(AutomapOffset.y, 0); |
||||
EXPECT_EQ(AutoMapScale, 50); |
||||
EXPECT_EQ(AmLine64, 32); |
||||
EXPECT_EQ(AmLine32, 16); |
||||
EXPECT_EQ(AmLine16, 8); |
||||
EXPECT_EQ(AmLine8, 4); |
||||
EXPECT_EQ(AmLine4, 2); |
||||
} |
||||
|
||||
@ -1,15 +1,15 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "codec.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Codec, codec_get_encoded_len) |
||||
{ |
||||
EXPECT_EQ(codec_get_encoded_len(50), 72); |
||||
} |
||||
|
||||
TEST(Codec, codec_get_encoded_len_eq) |
||||
{ |
||||
EXPECT_EQ(codec_get_encoded_len(128), 136); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "codec.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Codec, codec_get_encoded_len) |
||||
{ |
||||
EXPECT_EQ(codec_get_encoded_len(50), 72); |
||||
} |
||||
|
||||
TEST(Codec, codec_get_encoded_len_eq) |
||||
{ |
||||
EXPECT_EQ(codec_get_encoded_len(128), 136); |
||||
} |
||||
|
||||
@ -1,29 +1,29 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "control.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Control, SetSpell) |
||||
{ |
||||
pnumlines = 1; |
||||
pinfoflag = true; |
||||
pSpell = SPL_FIREBOLT; |
||||
pSplType = RSPLTYPE_CHARGES; |
||||
SetSpell(); |
||||
EXPECT_EQ(spselflag, false); |
||||
EXPECT_EQ(plr[myplr]._pRSpell, SPL_FIREBOLT); |
||||
EXPECT_EQ(plr[myplr]._pRSplType, RSPLTYPE_CHARGES); |
||||
EXPECT_EQ(pnumlines, 0); |
||||
EXPECT_EQ(pinfoflag, false); |
||||
EXPECT_EQ(force_redraw, 255); |
||||
} |
||||
|
||||
TEST(Control, ClearPanel) |
||||
{ |
||||
pnumlines = 1; |
||||
pinfoflag = true; |
||||
ClearPanel(); |
||||
EXPECT_EQ(pnumlines, 0); |
||||
EXPECT_EQ(pinfoflag, false); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "control.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Control, SetSpell) |
||||
{ |
||||
pnumlines = 1; |
||||
pinfoflag = true; |
||||
pSpell = SPL_FIREBOLT; |
||||
pSplType = RSPLTYPE_CHARGES; |
||||
SetSpell(); |
||||
EXPECT_EQ(spselflag, false); |
||||
EXPECT_EQ(plr[myplr]._pRSpell, SPL_FIREBOLT); |
||||
EXPECT_EQ(plr[myplr]._pRSplType, RSPLTYPE_CHARGES); |
||||
EXPECT_EQ(pnumlines, 0); |
||||
EXPECT_EQ(pinfoflag, false); |
||||
EXPECT_EQ(force_redraw, 255); |
||||
} |
||||
|
||||
TEST(Control, ClearPanel) |
||||
{ |
||||
pnumlines = 1; |
||||
pinfoflag = true; |
||||
ClearPanel(); |
||||
EXPECT_EQ(pnumlines, 0); |
||||
EXPECT_EQ(pinfoflag, false); |
||||
} |
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "cursor.h" |
||||
#include "itemdat.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Cursor, SetCursor) |
||||
{ |
||||
int i = ICURS_SPIKED_CLUB + CURSOR_FIRSTITEM; |
||||
NewCursor(i); |
||||
EXPECT_EQ(pcurs, i); |
||||
EXPECT_EQ(cursW, 1 * 28); |
||||
EXPECT_EQ(cursH, 3 * 28); |
||||
EXPECT_EQ(icursW, 1 * 28); |
||||
EXPECT_EQ(icursH, 3 * 28); |
||||
EXPECT_EQ(icursW28, 1); |
||||
EXPECT_EQ(icursH28, 3); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "cursor.h" |
||||
#include "itemdat.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Cursor, SetCursor) |
||||
{ |
||||
int i = ICURS_SPIKED_CLUB + CURSOR_FIRSTITEM; |
||||
NewCursor(i); |
||||
EXPECT_EQ(pcurs, i); |
||||
EXPECT_EQ(cursW, 1 * 28); |
||||
EXPECT_EQ(cursH, 3 * 28); |
||||
EXPECT_EQ(icursW, 1 * 28); |
||||
EXPECT_EQ(icursH, 3 * 28); |
||||
EXPECT_EQ(icursW28, 1); |
||||
EXPECT_EQ(icursH28, 3); |
||||
} |
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "dead.h" |
||||
#include "engine.h" |
||||
#include "gendung.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Dead, AddDead) |
||||
{ |
||||
AddDead({21, 48}, 8, DIR_W); |
||||
EXPECT_EQ(dDead[21][48], 8 + (DIR_W << 5)); |
||||
} |
||||
|
||||
TEST(Dead, AddDead_OOB) |
||||
{ |
||||
AddDead({21, 48}, MaxDead + 1, DIR_W); |
||||
EXPECT_EQ(dDead[21][48], 0 + (DIR_W << 5)); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "dead.h" |
||||
#include "engine.h" |
||||
#include "gendung.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Dead, AddDead) |
||||
{ |
||||
AddDead({21, 48}, 8, DIR_W); |
||||
EXPECT_EQ(dDead[21][48], 8 + (DIR_W << 5)); |
||||
} |
||||
|
||||
TEST(Dead, AddDead_OOB) |
||||
{ |
||||
AddDead({21, 48}, MaxDead + 1, DIR_W); |
||||
EXPECT_EQ(dDead[21][48], 0 + (DIR_W << 5)); |
||||
} |
||||
|
||||
@ -1,14 +1,14 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "multi.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Diablo, diablo_pause_game_unpause) |
||||
{ |
||||
gbIsMultiplayer = false; |
||||
PauseMode = 1; |
||||
diablo_pause_game(); |
||||
EXPECT_EQ(PauseMode, 0); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "multi.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Diablo, diablo_pause_game_unpause) |
||||
{ |
||||
gbIsMultiplayer = false; |
||||
PauseMode = 1; |
||||
diablo_pause_game(); |
||||
EXPECT_EQ(PauseMode, 0); |
||||
} |
||||
|
||||
@ -1,17 +1,17 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "doom.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Doom, doom_get_frame_from_time) |
||||
{ |
||||
DoomQuestState = 1200 * 8 + 548; |
||||
EXPECT_EQ(doom_get_frame_from_time(), 8); |
||||
} |
||||
|
||||
TEST(Doom, doom_get_frame_from_time_max) |
||||
{ |
||||
DoomQuestState = 1200 * 30 + 1; |
||||
EXPECT_EQ(doom_get_frame_from_time(), 31); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "doom.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Doom, doom_get_frame_from_time) |
||||
{ |
||||
DoomQuestState = 1200 * 8 + 548; |
||||
EXPECT_EQ(doom_get_frame_from_time(), 8); |
||||
} |
||||
|
||||
TEST(Doom, doom_get_frame_from_time_max) |
||||
{ |
||||
DoomQuestState = 1200 * 30 + 1; |
||||
EXPECT_EQ(doom_get_frame_from_time(), 31); |
||||
} |
||||
|
||||
@ -1,21 +1,21 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "drlg_l1.h" |
||||
#include "lighting.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l1, DRLG_Init_Globals_noflag) |
||||
{ |
||||
lightflag = false; |
||||
DRLG_Init_Globals(); |
||||
EXPECT_EQ(dLight[0][0], 15); |
||||
} |
||||
|
||||
TEST(Drlg_l1, DRLG_Init_Globals) |
||||
{ |
||||
lightflag = true; |
||||
DRLG_Init_Globals(); |
||||
EXPECT_EQ(dLight[0][0], 0); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "drlg_l1.h" |
||||
#include "lighting.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l1, DRLG_Init_Globals_noflag) |
||||
{ |
||||
lightflag = false; |
||||
DRLG_Init_Globals(); |
||||
EXPECT_EQ(dLight[0][0], 15); |
||||
} |
||||
|
||||
TEST(Drlg_l1, DRLG_Init_Globals) |
||||
{ |
||||
lightflag = true; |
||||
DRLG_Init_Globals(); |
||||
EXPECT_EQ(dLight[0][0], 0); |
||||
} |
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l2.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l2, InitDungeon) |
||||
{ |
||||
InitDungeon(); |
||||
EXPECT_EQ(predungeon[0][0], 32); |
||||
EXPECT_EQ(dflags[0][0], 0); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l2.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l2, InitDungeon) |
||||
{ |
||||
InitDungeon(); |
||||
EXPECT_EQ(predungeon[0][0], 32); |
||||
EXPECT_EQ(dflags[0][0], 0); |
||||
} |
||||
|
||||
@ -1,35 +1,35 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l3.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_x) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5 - 1][5] = 130; |
||||
dungeon[5 + 1][5] = 152; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 146); |
||||
} |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_y) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5][5 - 1] = 130; |
||||
dungeon[5][5 + 1] = 152; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 147); |
||||
} |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_no) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5 - 1][5] = 130; |
||||
dungeon[5 + 1][5] = 153; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 7); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l3.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_x) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5 - 1][5] = 130; |
||||
dungeon[5 + 1][5] = 152; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 146); |
||||
} |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_y) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5][5 - 1] = 130; |
||||
dungeon[5][5 + 1] = 152; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 147); |
||||
} |
||||
|
||||
TEST(Drlg_l3, AddFenceDoors_no) |
||||
{ |
||||
memset(dungeon, 0, sizeof(dungeon)); |
||||
dungeon[5][5] = 7; |
||||
dungeon[5 - 1][5] = 130; |
||||
dungeon[5 + 1][5] = 153; |
||||
AddFenceDoors(); |
||||
EXPECT_EQ(dungeon[5][5], 7); |
||||
} |
||||
|
||||
@ -1,21 +1,21 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l4.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l4, IsDURWall) |
||||
{ |
||||
EXPECT_EQ(IsDURWall(25), true); |
||||
EXPECT_EQ(IsDURWall(28), true); |
||||
EXPECT_EQ(IsDURWall(23), true); |
||||
EXPECT_EQ(IsDURWall(20), false); |
||||
} |
||||
|
||||
TEST(Drlg_l4, IsDLLWall) |
||||
{ |
||||
EXPECT_EQ(IsDLLWall(27), true); |
||||
EXPECT_EQ(IsDLLWall(26), true); |
||||
EXPECT_EQ(IsDLLWall(22), true); |
||||
EXPECT_EQ(IsDLLWall(20), false); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "drlg_l4.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Drlg_l4, IsDURWall) |
||||
{ |
||||
EXPECT_EQ(IsDURWall(25), true); |
||||
EXPECT_EQ(IsDURWall(28), true); |
||||
EXPECT_EQ(IsDURWall(23), true); |
||||
EXPECT_EQ(IsDURWall(20), false); |
||||
} |
||||
|
||||
TEST(Drlg_l4, IsDLLWall) |
||||
{ |
||||
EXPECT_EQ(IsDLLWall(27), true); |
||||
EXPECT_EQ(IsDLLWall(26), true); |
||||
EXPECT_EQ(IsDLLWall(22), true); |
||||
EXPECT_EQ(IsDLLWall(20), false); |
||||
} |
||||
|
||||
@ -1,56 +1,56 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "effects.h" |
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Effects, calc_snd_position_center) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(50, 50, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, 0); |
||||
EXPECT_EQ(plPan, 0); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_near) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(55, 50, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -320); |
||||
EXPECT_EQ(plPan, 1280); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_out_of_range) |
||||
{ |
||||
plr[myplr].position.tile = { 12, 12 }; |
||||
int plVolume = 1234; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(112, 112, &plVolume, &plPan), false); |
||||
EXPECT_EQ(plVolume, 1234); |
||||
EXPECT_EQ(plPan, 0); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_extreme_right) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(75, 25, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -2176); |
||||
EXPECT_EQ(plPan, 6400); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_extreme_left) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(25, 75, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -2176); |
||||
EXPECT_EQ(plPan, -6400); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "effects.h" |
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Effects, calc_snd_position_center) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(50, 50, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, 0); |
||||
EXPECT_EQ(plPan, 0); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_near) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(55, 50, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -320); |
||||
EXPECT_EQ(plPan, 1280); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_out_of_range) |
||||
{ |
||||
plr[myplr].position.tile = { 12, 12 }; |
||||
int plVolume = 1234; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(112, 112, &plVolume, &plPan), false); |
||||
EXPECT_EQ(plVolume, 1234); |
||||
EXPECT_EQ(plPan, 0); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_extreme_right) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(75, 25, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -2176); |
||||
EXPECT_EQ(plPan, 6400); |
||||
} |
||||
|
||||
TEST(Effects, calc_snd_position_extreme_left) |
||||
{ |
||||
plr[myplr].position.tile = { 50, 50 }; |
||||
int plVolume = 0; |
||||
int plPan = 0; |
||||
EXPECT_EQ(calc_snd_position(25, 75, &plVolume, &plPan), true); |
||||
EXPECT_EQ(plVolume, -2176); |
||||
EXPECT_EQ(plPan, -6400); |
||||
} |
||||
|
||||
@ -1,226 +1,226 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "cursor.h" |
||||
#include "inv.h" |
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
/* Set up a given item as a spell scroll, allowing for its usage. */ |
||||
void set_up_scroll(ItemStruct &item, spell_id spell) |
||||
{ |
||||
pcurs = CURSOR_HAND; |
||||
leveltype = DTYPE_CATACOMBS; |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(spell); |
||||
item._itype = ITYPE_MISC; |
||||
item._iMiscId = IMISC_SCROLL; |
||||
item._iSpell = spell; |
||||
} |
||||
|
||||
/* Clear the inventory of myplr. */ |
||||
void clear_inventory() |
||||
{ |
||||
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) { |
||||
memset(&plr[myplr].InvList[i], 0, sizeof(ItemStruct)); |
||||
plr[myplr].InvGrid[i] = 0; |
||||
} |
||||
plr[myplr]._pNumInv = 0; |
||||
} |
||||
|
||||
// Test that the scroll is used in the inventory in correct conditions
|
||||
TEST(Inv, UseScroll_from_inventory) |
||||
{ |
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pNumInv = 5; |
||||
EXPECT_TRUE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is used in the belt in correct conditions
|
||||
TEST(Inv, UseScroll_from_belt) |
||||
{ |
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
EXPECT_TRUE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is not used in the inventory for each invalid condition
|
||||
TEST(Inv, UseScroll_from_inventory_invalid_conditions) |
||||
{ |
||||
// Empty the belt to prevent using a scroll from the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
pcurs = CURSOR_IDENTIFY; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
leveltype = DTYPE_TOWN; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_HEAL); |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr].InvList[2]._iMiscId = IMISC_STAFF; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr].InvList[2]._itype = ITYPE_NONE; |
||||
EXPECT_FALSE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is not used in the belt for each invalid condition
|
||||
TEST(Inv, UseScroll_from_belt_invalid_conditions) |
||||
{ |
||||
// Disable the inventory to prevent using a scroll from the inventory
|
||||
plr[myplr]._pNumInv = 0; |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
pcurs = CURSOR_IDENTIFY; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
leveltype = DTYPE_TOWN; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_HEAL); |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr].SpdList[2]._iMiscId = IMISC_STAFF; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr].SpdList[2]._itype = ITYPE_NONE; |
||||
EXPECT_FALSE(UseScroll()); |
||||
} |
||||
|
||||
// Test gold calculation
|
||||
TEST(Inv, CalculateGold) |
||||
{ |
||||
plr[myplr]._pNumInv = 10; |
||||
// Set up two slots of gold both in the belt and inventory
|
||||
plr[myplr].SpdList[1]._itype = ITYPE_GOLD; |
||||
plr[myplr].SpdList[5]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[2]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[3]._itype = ITYPE_GOLD; |
||||
// Set the gold amount to arbitrary values
|
||||
plr[myplr].SpdList[1]._ivalue = 100; |
||||
plr[myplr].SpdList[5]._ivalue = 200; |
||||
plr[myplr].InvList[2]._ivalue = 3; |
||||
plr[myplr].InvList[3]._ivalue = 30; |
||||
|
||||
EXPECT_EQ(CalculateGold(myplr), 333); |
||||
} |
||||
|
||||
// Test automatic gold placing
|
||||
TEST(Inv, GoldAutoPlace) |
||||
{ |
||||
// Empty the inventory
|
||||
clear_inventory(); |
||||
|
||||
// Put gold into the inventory:
|
||||
// | 1000 | ... | ...
|
||||
plr[myplr].InvList[0]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[0]._ivalue = 1000; |
||||
plr[myplr]._pNumInv = 1; |
||||
// Put (max gold - 100) gold, which is 4900, into the player's hand
|
||||
plr[myplr].HoldItem._itype = ITYPE_GOLD; |
||||
plr[myplr].HoldItem._ivalue = GOLD_MAX_LIMIT - 100; |
||||
|
||||
GoldAutoPlace(myplr); |
||||
// We expect the inventory:
|
||||
// | 5000 | 900 | ...
|
||||
EXPECT_EQ(plr[myplr].InvList[0]._ivalue, GOLD_MAX_LIMIT); |
||||
EXPECT_EQ(plr[myplr].InvList[1]._ivalue, 900); |
||||
} |
||||
|
||||
// Test removing an item from inventory with no other items.
|
||||
TEST(Inv, RemoveInvItem) |
||||
{ |
||||
clear_inventory(); |
||||
// Put a two-slot misc item into the inventory:
|
||||
// | (item) | (item) | ... | ...
|
||||
plr[myplr]._pNumInv = 1; |
||||
plr[myplr].InvGrid[0] = 1; |
||||
plr[myplr].InvGrid[1] = -1; |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
|
||||
plr[myplr].RemoveInvItem(0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[1], 0); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 0); |
||||
} |
||||
|
||||
// Test removing an item from inventory with other items in it.
|
||||
TEST(Inv, RemoveInvItem_other_item) |
||||
{ |
||||
clear_inventory(); |
||||
// Put a two-slot misc item and a ring into the inventory:
|
||||
// | (item) | (item) | (ring) | ...
|
||||
plr[myplr]._pNumInv = 2; |
||||
plr[myplr].InvGrid[0] = 1; |
||||
plr[myplr].InvGrid[1] = -1; |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
|
||||
plr[myplr].InvGrid[2] = 2; |
||||
plr[myplr].InvList[1]._itype = ITYPE_RING; |
||||
|
||||
plr[myplr].RemoveInvItem(0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[1], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[2], 1); |
||||
EXPECT_EQ(plr[myplr].InvList[0]._itype, ITYPE_RING); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 1); |
||||
} |
||||
|
||||
// Test removing an item from the belt
|
||||
TEST(Inv, RemoveSpdBarItem) |
||||
{ |
||||
// Clear the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
// Put an item in the belt: | x | x | item | x | x | x | x | x |
|
||||
plr[myplr].SpdList[3]._itype = ITYPE_MISC; |
||||
|
||||
RemoveSpdBarItem(myplr, 3); |
||||
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE); |
||||
} |
||||
|
||||
// Test removing a scroll from the inventory
|
||||
TEST(Inv, RemoveScroll_inventory) |
||||
{ |
||||
clear_inventory(); |
||||
|
||||
// Put a firebolt scroll into the inventory
|
||||
plr[myplr]._pNumInv = 1; |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_FIREBOLT); |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
plr[myplr].InvList[0]._iMiscId = IMISC_SCROLL; |
||||
plr[myplr].InvList[0]._iSpell = SPL_FIREBOLT; |
||||
|
||||
RemoveScroll(myplr); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 0); |
||||
} |
||||
|
||||
// Test removing a scroll from the belt
|
||||
TEST(Inv, RemoveScroll_belt) |
||||
{ |
||||
// Clear the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
// Put a firebolt scroll into the belt
|
||||
plr[myplr]._pSpell = static_cast<spell_id>(SPL_FIREBOLT); |
||||
plr[myplr].SpdList[3]._itype = ITYPE_MISC; |
||||
plr[myplr].SpdList[3]._iMiscId = IMISC_SCROLL; |
||||
plr[myplr].SpdList[3]._iSpell = SPL_FIREBOLT; |
||||
|
||||
RemoveScroll(myplr); |
||||
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "cursor.h" |
||||
#include "inv.h" |
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
/* Set up a given item as a spell scroll, allowing for its usage. */ |
||||
void set_up_scroll(ItemStruct &item, spell_id spell) |
||||
{ |
||||
pcurs = CURSOR_HAND; |
||||
leveltype = DTYPE_CATACOMBS; |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(spell); |
||||
item._itype = ITYPE_MISC; |
||||
item._iMiscId = IMISC_SCROLL; |
||||
item._iSpell = spell; |
||||
} |
||||
|
||||
/* Clear the inventory of myplr. */ |
||||
void clear_inventory() |
||||
{ |
||||
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) { |
||||
memset(&plr[myplr].InvList[i], 0, sizeof(ItemStruct)); |
||||
plr[myplr].InvGrid[i] = 0; |
||||
} |
||||
plr[myplr]._pNumInv = 0; |
||||
} |
||||
|
||||
// Test that the scroll is used in the inventory in correct conditions
|
||||
TEST(Inv, UseScroll_from_inventory) |
||||
{ |
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pNumInv = 5; |
||||
EXPECT_TRUE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is used in the belt in correct conditions
|
||||
TEST(Inv, UseScroll_from_belt) |
||||
{ |
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
EXPECT_TRUE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is not used in the inventory for each invalid condition
|
||||
TEST(Inv, UseScroll_from_inventory_invalid_conditions) |
||||
{ |
||||
// Empty the belt to prevent using a scroll from the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
pcurs = CURSOR_IDENTIFY; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
leveltype = DTYPE_TOWN; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_HEAL); |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr].InvList[2]._iMiscId = IMISC_STAFF; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].InvList[2], SPL_FIREBOLT); |
||||
plr[myplr].InvList[2]._itype = ITYPE_NONE; |
||||
EXPECT_FALSE(UseScroll()); |
||||
} |
||||
|
||||
// Test that the scroll is not used in the belt for each invalid condition
|
||||
TEST(Inv, UseScroll_from_belt_invalid_conditions) |
||||
{ |
||||
// Disable the inventory to prevent using a scroll from the inventory
|
||||
plr[myplr]._pNumInv = 0; |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
pcurs = CURSOR_IDENTIFY; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
leveltype = DTYPE_TOWN; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_HEAL); |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr].SpdList[2]._iMiscId = IMISC_STAFF; |
||||
EXPECT_FALSE(UseScroll()); |
||||
|
||||
set_up_scroll(plr[myplr].SpdList[2], SPL_FIREBOLT); |
||||
plr[myplr].SpdList[2]._itype = ITYPE_NONE; |
||||
EXPECT_FALSE(UseScroll()); |
||||
} |
||||
|
||||
// Test gold calculation
|
||||
TEST(Inv, CalculateGold) |
||||
{ |
||||
plr[myplr]._pNumInv = 10; |
||||
// Set up two slots of gold both in the belt and inventory
|
||||
plr[myplr].SpdList[1]._itype = ITYPE_GOLD; |
||||
plr[myplr].SpdList[5]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[2]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[3]._itype = ITYPE_GOLD; |
||||
// Set the gold amount to arbitrary values
|
||||
plr[myplr].SpdList[1]._ivalue = 100; |
||||
plr[myplr].SpdList[5]._ivalue = 200; |
||||
plr[myplr].InvList[2]._ivalue = 3; |
||||
plr[myplr].InvList[3]._ivalue = 30; |
||||
|
||||
EXPECT_EQ(CalculateGold(myplr), 333); |
||||
} |
||||
|
||||
// Test automatic gold placing
|
||||
TEST(Inv, GoldAutoPlace) |
||||
{ |
||||
// Empty the inventory
|
||||
clear_inventory(); |
||||
|
||||
// Put gold into the inventory:
|
||||
// | 1000 | ... | ...
|
||||
plr[myplr].InvList[0]._itype = ITYPE_GOLD; |
||||
plr[myplr].InvList[0]._ivalue = 1000; |
||||
plr[myplr]._pNumInv = 1; |
||||
// Put (max gold - 100) gold, which is 4900, into the player's hand
|
||||
plr[myplr].HoldItem._itype = ITYPE_GOLD; |
||||
plr[myplr].HoldItem._ivalue = GOLD_MAX_LIMIT - 100; |
||||
|
||||
GoldAutoPlace(myplr); |
||||
// We expect the inventory:
|
||||
// | 5000 | 900 | ...
|
||||
EXPECT_EQ(plr[myplr].InvList[0]._ivalue, GOLD_MAX_LIMIT); |
||||
EXPECT_EQ(plr[myplr].InvList[1]._ivalue, 900); |
||||
} |
||||
|
||||
// Test removing an item from inventory with no other items.
|
||||
TEST(Inv, RemoveInvItem) |
||||
{ |
||||
clear_inventory(); |
||||
// Put a two-slot misc item into the inventory:
|
||||
// | (item) | (item) | ... | ...
|
||||
plr[myplr]._pNumInv = 1; |
||||
plr[myplr].InvGrid[0] = 1; |
||||
plr[myplr].InvGrid[1] = -1; |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
|
||||
plr[myplr].RemoveInvItem(0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[1], 0); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 0); |
||||
} |
||||
|
||||
// Test removing an item from inventory with other items in it.
|
||||
TEST(Inv, RemoveInvItem_other_item) |
||||
{ |
||||
clear_inventory(); |
||||
// Put a two-slot misc item and a ring into the inventory:
|
||||
// | (item) | (item) | (ring) | ...
|
||||
plr[myplr]._pNumInv = 2; |
||||
plr[myplr].InvGrid[0] = 1; |
||||
plr[myplr].InvGrid[1] = -1; |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
|
||||
plr[myplr].InvGrid[2] = 2; |
||||
plr[myplr].InvList[1]._itype = ITYPE_RING; |
||||
|
||||
plr[myplr].RemoveInvItem(0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[1], 0); |
||||
EXPECT_EQ(plr[myplr].InvGrid[2], 1); |
||||
EXPECT_EQ(plr[myplr].InvList[0]._itype, ITYPE_RING); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 1); |
||||
} |
||||
|
||||
// Test removing an item from the belt
|
||||
TEST(Inv, RemoveSpdBarItem) |
||||
{ |
||||
// Clear the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
// Put an item in the belt: | x | x | item | x | x | x | x | x |
|
||||
plr[myplr].SpdList[3]._itype = ITYPE_MISC; |
||||
|
||||
RemoveSpdBarItem(myplr, 3); |
||||
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE); |
||||
} |
||||
|
||||
// Test removing a scroll from the inventory
|
||||
TEST(Inv, RemoveScroll_inventory) |
||||
{ |
||||
clear_inventory(); |
||||
|
||||
// Put a firebolt scroll into the inventory
|
||||
plr[myplr]._pNumInv = 1; |
||||
plr[myplr]._pRSpell = static_cast<spell_id>(SPL_FIREBOLT); |
||||
plr[myplr].InvList[0]._itype = ITYPE_MISC; |
||||
plr[myplr].InvList[0]._iMiscId = IMISC_SCROLL; |
||||
plr[myplr].InvList[0]._iSpell = SPL_FIREBOLT; |
||||
|
||||
RemoveScroll(myplr); |
||||
EXPECT_EQ(plr[myplr].InvGrid[0], 0); |
||||
EXPECT_EQ(plr[myplr]._pNumInv, 0); |
||||
} |
||||
|
||||
// Test removing a scroll from the belt
|
||||
TEST(Inv, RemoveScroll_belt) |
||||
{ |
||||
// Clear the belt
|
||||
for (int i = 0; i < MAXBELTITEMS; i++) { |
||||
plr[myplr].SpdList[i]._itype = ITYPE_NONE; |
||||
} |
||||
// Put a firebolt scroll into the belt
|
||||
plr[myplr]._pSpell = static_cast<spell_id>(SPL_FIREBOLT); |
||||
plr[myplr].SpdList[3]._itype = ITYPE_MISC; |
||||
plr[myplr].SpdList[3]._iMiscId = IMISC_SCROLL; |
||||
plr[myplr].SpdList[3]._iSpell = SPL_FIREBOLT; |
||||
|
||||
RemoveScroll(myplr); |
||||
EXPECT_EQ(plr[myplr].SpdList[3]._itype, ITYPE_NONE); |
||||
} |
||||
|
||||
@ -1,38 +1,38 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "control.h" |
||||
#include "lighting.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Lighting, CrawlTables) |
||||
{ |
||||
int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; |
||||
|
||||
bool added[40][40]; |
||||
memset(added, 0, sizeof(added)); |
||||
|
||||
for (int j = 0; j < 19; j++) { |
||||
int x = 20; |
||||
int y = 20; |
||||
int cr = CrawlNum[j] + 1; |
||||
for (unsigned i = (uint8_t)CrawlTable[cr - 1]; i > 0; i--, cr += 2) { |
||||
int dx = x + CrawlTable[cr]; |
||||
int dy = y + CrawlTable[cr + 1]; |
||||
sprintf(tempstr, "location %d:%d added twice.", dx - 20, dy - 20); |
||||
EXPECT_EQ(added[dx][dy], false) << tempstr; |
||||
added[dx][dy] = true; |
||||
} |
||||
} |
||||
|
||||
for (int i = -18; i <= 18; i++) { |
||||
for (int j = -18; j <= 18; j++) { |
||||
if (added[i + 20][j + 20]) |
||||
continue; |
||||
if ((i == -18 && j == -18) || (i == -18 && j == 18) || (i == 18 && j == -18) || (i == 18 && j == 18)) |
||||
continue; // Limit of the crawl table rage
|
||||
sprintf(tempstr, "while checking location %d:%d.", i, j); |
||||
EXPECT_EQ(false, true) << tempstr; |
||||
} |
||||
} |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "control.h" |
||||
#include "lighting.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Lighting, CrawlTables) |
||||
{ |
||||
int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 }; |
||||
|
||||
bool added[40][40]; |
||||
memset(added, 0, sizeof(added)); |
||||
|
||||
for (int j = 0; j < 19; j++) { |
||||
int x = 20; |
||||
int y = 20; |
||||
int cr = CrawlNum[j] + 1; |
||||
for (unsigned i = (uint8_t)CrawlTable[cr - 1]; i > 0; i--, cr += 2) { |
||||
int dx = x + CrawlTable[cr]; |
||||
int dy = y + CrawlTable[cr + 1]; |
||||
sprintf(tempstr, "location %d:%d added twice.", dx - 20, dy - 20); |
||||
EXPECT_EQ(added[dx][dy], false) << tempstr; |
||||
added[dx][dy] = true; |
||||
} |
||||
} |
||||
|
||||
for (int i = -18; i <= 18; i++) { |
||||
for (int j = -18; j <= 18; j++) { |
||||
if (added[i + 20][j + 20]) |
||||
continue; |
||||
if ((i == -18 && j == -18) || (i == -18 && j == 18) || (i == 18 && j == -18) || (i == 18 && j == 18)) |
||||
continue; // Limit of the crawl table rage
|
||||
sprintf(tempstr, "while checking location %d:%d.", i, j); |
||||
EXPECT_EQ(false, true) << tempstr; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,87 +1,87 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "missiles.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Missiles, GetDirection8) |
||||
{ |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 15 })); |
||||
EXPECT_EQ(1, GetDirection({ 0, 0 }, { 0, 15 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 15 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 8 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 8 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 7 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 11, 7 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 11 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(5, GetDirection({ 0, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 8 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 8 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 7 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 11, 7 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 11 }, { 0, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 15, 0 })); |
||||
EXPECT_EQ(7, GetDirection({ 0, 0 }, { 15, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 15, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 8, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 8, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 7, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 11 }, { 7, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 11, 0 })); |
||||
|
||||
EXPECT_EQ(0, GetDirection({ 1, 1 }, { 2, 2 })); |
||||
EXPECT_EQ(1, GetDirection({ 1, 1 }, { 1, 2 })); |
||||
EXPECT_EQ(2, GetDirection({ 1, 1 }, { 0, 2 })); |
||||
EXPECT_EQ(3, GetDirection({ 1, 1 }, { 0, 1 })); |
||||
EXPECT_EQ(4, GetDirection({ 1, 1 }, { 0, 0 })); |
||||
EXPECT_EQ(5, GetDirection({ 1, 1 }, { 1, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 1, 1 }, { 2, 0 })); |
||||
EXPECT_EQ(7, GetDirection({ 1, 1 }, { 2, 1 })); |
||||
} |
||||
|
||||
TEST(Missiles, GetDirection16) |
||||
{ |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 15, 15)); |
||||
EXPECT_EQ(2, GetDirection16(0, 0, 0, 15)); |
||||
EXPECT_EQ(1, GetDirection16(0, 0, 8, 15)); |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 8, 8)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 15, 8)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 15, 7)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 11, 7)); |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 8, 11)); |
||||
EXPECT_EQ(8, GetDirection16(15, 15, 0, 0)); |
||||
EXPECT_EQ(10, GetDirection16(0, 15, 0, 0)); |
||||
EXPECT_EQ(9, GetDirection16(8, 15, 0, 0)); |
||||
EXPECT_EQ(8, GetDirection16(8, 8, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(15, 8, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(15, 7, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(11, 7, 0, 0)); |
||||
EXPECT_EQ(8, GetDirection16(8, 11, 0, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 15, 15, 0)); |
||||
EXPECT_EQ(14, GetDirection16(0, 0, 15, 0)); |
||||
EXPECT_EQ(13, GetDirection16(0, 8, 15, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 8, 8, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 15, 8, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 15, 7, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 11, 7, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 8, 11, 0)); |
||||
|
||||
EXPECT_EQ(0, GetDirection16(2, 2, 3, 3)); |
||||
EXPECT_EQ(1, GetDirection16(2, 2, 3, 4)); |
||||
EXPECT_EQ(2, GetDirection16(2, 2, 2, 4)); |
||||
EXPECT_EQ(3, GetDirection16(2, 2, 1, 4)); |
||||
EXPECT_EQ(4, GetDirection16(2, 2, 1, 3)); |
||||
EXPECT_EQ(5, GetDirection16(2, 2, 0, 3)); |
||||
EXPECT_EQ(6, GetDirection16(2, 2, 0, 2)); |
||||
EXPECT_EQ(7, GetDirection16(2, 2, 0, 1)); |
||||
EXPECT_EQ(8, GetDirection16(2, 2, 1, 1)); |
||||
EXPECT_EQ(9, GetDirection16(2, 2, 1, 0)); |
||||
EXPECT_EQ(10, GetDirection16(2, 2, 2, 0)); |
||||
EXPECT_EQ(11, GetDirection16(2, 2, 3, 0)); |
||||
EXPECT_EQ(12, GetDirection16(2, 2, 3, 1)); |
||||
EXPECT_EQ(13, GetDirection16(2, 2, 4, 1)); |
||||
EXPECT_EQ(14, GetDirection16(2, 2, 4, 2)); |
||||
EXPECT_EQ(15, GetDirection16(2, 2, 4, 3)); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "missiles.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
TEST(Missiles, GetDirection8) |
||||
{ |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 15 })); |
||||
EXPECT_EQ(1, GetDirection({ 0, 0 }, { 0, 15 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 15 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 8 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 8 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 7 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 11, 7 })); |
||||
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 11 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(5, GetDirection({ 0, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 15 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 8 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 8 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 15, 7 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 11, 7 }, { 0, 0 })); |
||||
EXPECT_EQ(4, GetDirection({ 8, 11 }, { 0, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 15, 0 })); |
||||
EXPECT_EQ(7, GetDirection({ 0, 0 }, { 15, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 15, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 8, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 8, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 7, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 11 }, { 7, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 11, 0 })); |
||||
|
||||
EXPECT_EQ(0, GetDirection({ 1, 1 }, { 2, 2 })); |
||||
EXPECT_EQ(1, GetDirection({ 1, 1 }, { 1, 2 })); |
||||
EXPECT_EQ(2, GetDirection({ 1, 1 }, { 0, 2 })); |
||||
EXPECT_EQ(3, GetDirection({ 1, 1 }, { 0, 1 })); |
||||
EXPECT_EQ(4, GetDirection({ 1, 1 }, { 0, 0 })); |
||||
EXPECT_EQ(5, GetDirection({ 1, 1 }, { 1, 0 })); |
||||
EXPECT_EQ(6, GetDirection({ 1, 1 }, { 2, 0 })); |
||||
EXPECT_EQ(7, GetDirection({ 1, 1 }, { 2, 1 })); |
||||
} |
||||
|
||||
TEST(Missiles, GetDirection16) |
||||
{ |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 15, 15)); |
||||
EXPECT_EQ(2, GetDirection16(0, 0, 0, 15)); |
||||
EXPECT_EQ(1, GetDirection16(0, 0, 8, 15)); |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 8, 8)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 15, 8)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 15, 7)); |
||||
EXPECT_EQ(15, GetDirection16(0, 0, 11, 7)); |
||||
EXPECT_EQ(0, GetDirection16(0, 0, 8, 11)); |
||||
EXPECT_EQ(8, GetDirection16(15, 15, 0, 0)); |
||||
EXPECT_EQ(10, GetDirection16(0, 15, 0, 0)); |
||||
EXPECT_EQ(9, GetDirection16(8, 15, 0, 0)); |
||||
EXPECT_EQ(8, GetDirection16(8, 8, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(15, 8, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(15, 7, 0, 0)); |
||||
EXPECT_EQ(7, GetDirection16(11, 7, 0, 0)); |
||||
EXPECT_EQ(8, GetDirection16(8, 11, 0, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 15, 15, 0)); |
||||
EXPECT_EQ(14, GetDirection16(0, 0, 15, 0)); |
||||
EXPECT_EQ(13, GetDirection16(0, 8, 15, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 8, 8, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 15, 8, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 15, 7, 0)); |
||||
EXPECT_EQ(11, GetDirection16(0, 11, 7, 0)); |
||||
EXPECT_EQ(12, GetDirection16(0, 8, 11, 0)); |
||||
|
||||
EXPECT_EQ(0, GetDirection16(2, 2, 3, 3)); |
||||
EXPECT_EQ(1, GetDirection16(2, 2, 3, 4)); |
||||
EXPECT_EQ(2, GetDirection16(2, 2, 2, 4)); |
||||
EXPECT_EQ(3, GetDirection16(2, 2, 1, 4)); |
||||
EXPECT_EQ(4, GetDirection16(2, 2, 1, 3)); |
||||
EXPECT_EQ(5, GetDirection16(2, 2, 0, 3)); |
||||
EXPECT_EQ(6, GetDirection16(2, 2, 0, 2)); |
||||
EXPECT_EQ(7, GetDirection16(2, 2, 0, 1)); |
||||
EXPECT_EQ(8, GetDirection16(2, 2, 1, 1)); |
||||
EXPECT_EQ(9, GetDirection16(2, 2, 1, 0)); |
||||
EXPECT_EQ(10, GetDirection16(2, 2, 2, 0)); |
||||
EXPECT_EQ(11, GetDirection16(2, 2, 3, 0)); |
||||
EXPECT_EQ(12, GetDirection16(2, 2, 3, 1)); |
||||
EXPECT_EQ(13, GetDirection16(2, 2, 4, 1)); |
||||
EXPECT_EQ(14, GetDirection16(2, 2, 4, 2)); |
||||
EXPECT_EQ(15, GetDirection16(2, 2, 4, 3)); |
||||
} |
||||
|
||||
@ -1,83 +1,83 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
namespace devilution { |
||||
extern bool PM_DoGotHit(int pnum); |
||||
} |
||||
|
||||
int RunBlockTest(int frames, int flags) |
||||
{ |
||||
int pnum = 0; |
||||
plr[pnum].AnimInfo.CurrentFrame = 1; |
||||
plr[pnum]._pHFrames = frames; |
||||
plr[pnum].actionFrame = 1; |
||||
plr[pnum]._pIFlags = flags; |
||||
plr[pnum]._pmode = PM_GOTHIT; |
||||
plr[pnum]._pGFXLoad = -1; |
||||
|
||||
int i = 1; |
||||
for (; i < 100; i++) { |
||||
PM_DoGotHit(pnum); |
||||
if (plr[pnum]._pmode != PM_GOTHIT) |
||||
break; |
||||
plr[pnum].AnimInfo.CurrentFrame++; |
||||
} |
||||
|
||||
return i; |
||||
} |
||||
|
||||
#define NORM 0 |
||||
#define BAL ISPL_FASTRECOVER |
||||
#define STA ISPL_FASTERRECOVER |
||||
#define HAR ISPL_FASTESTRECOVER |
||||
#define BALSTA (ISPL_FASTRECOVER | ISPL_FASTERRECOVER) |
||||
#define BALHAR (ISPL_FASTRECOVER | ISPL_FASTESTRECOVER) |
||||
#define STAHAR (ISPL_FASTERRECOVER | ISPL_FASTESTRECOVER) |
||||
#define ZEN (ISPL_FASTRECOVER | ISPL_FASTERRECOVER | ISPL_FASTESTRECOVER) |
||||
#define WAR 6 |
||||
#define ROU 7 |
||||
#define SRC 8 |
||||
|
||||
int BlockData[][3] = { |
||||
{ 6, WAR, NORM }, |
||||
{ 7, ROU, NORM }, |
||||
{ 8, SRC, NORM }, |
||||
|
||||
{ 5, WAR, BAL }, |
||||
{ 6, ROU, BAL }, |
||||
{ 7, SRC, BAL }, |
||||
|
||||
{ 4, WAR, STA }, |
||||
{ 5, ROU, STA }, |
||||
{ 6, SRC, STA }, |
||||
|
||||
{ 3, WAR, HAR }, |
||||
{ 4, ROU, HAR }, |
||||
{ 5, SRC, HAR }, |
||||
|
||||
{ 4, WAR, BALSTA }, |
||||
{ 5, ROU, BALSTA }, |
||||
{ 6, SRC, BALSTA }, |
||||
|
||||
{ 3, WAR, BALHAR }, |
||||
{ 4, ROU, BALHAR }, |
||||
{ 5, SRC, BALHAR }, |
||||
|
||||
{ 3, WAR, STAHAR }, |
||||
{ 4, ROU, STAHAR }, |
||||
{ 5, SRC, STAHAR }, |
||||
|
||||
{ 2, WAR, ZEN }, |
||||
{ 3, ROU, ZEN }, |
||||
{ 4, SRC, ZEN }, |
||||
}; |
||||
|
||||
TEST(Player, PM_DoGotHit) |
||||
{ |
||||
for (size_t i = 0; i < sizeof(BlockData) / sizeof(*BlockData); i++) { |
||||
EXPECT_EQ(BlockData[i][0], RunBlockTest(BlockData[i][1], BlockData[i][2])); |
||||
} |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "player.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
namespace devilution { |
||||
extern bool PM_DoGotHit(int pnum); |
||||
} |
||||
|
||||
int RunBlockTest(int frames, int flags) |
||||
{ |
||||
int pnum = 0; |
||||
plr[pnum].AnimInfo.CurrentFrame = 1; |
||||
plr[pnum]._pHFrames = frames; |
||||
plr[pnum].actionFrame = 1; |
||||
plr[pnum]._pIFlags = flags; |
||||
plr[pnum]._pmode = PM_GOTHIT; |
||||
plr[pnum]._pGFXLoad = -1; |
||||
|
||||
int i = 1; |
||||
for (; i < 100; i++) { |
||||
PM_DoGotHit(pnum); |
||||
if (plr[pnum]._pmode != PM_GOTHIT) |
||||
break; |
||||
plr[pnum].AnimInfo.CurrentFrame++; |
||||
} |
||||
|
||||
return i; |
||||
} |
||||
|
||||
#define NORM 0 |
||||
#define BAL ISPL_FASTRECOVER |
||||
#define STA ISPL_FASTERRECOVER |
||||
#define HAR ISPL_FASTESTRECOVER |
||||
#define BALSTA (ISPL_FASTRECOVER | ISPL_FASTERRECOVER) |
||||
#define BALHAR (ISPL_FASTRECOVER | ISPL_FASTESTRECOVER) |
||||
#define STAHAR (ISPL_FASTERRECOVER | ISPL_FASTESTRECOVER) |
||||
#define ZEN (ISPL_FASTRECOVER | ISPL_FASTERRECOVER | ISPL_FASTESTRECOVER) |
||||
#define WAR 6 |
||||
#define ROU 7 |
||||
#define SRC 8 |
||||
|
||||
int BlockData[][3] = { |
||||
{ 6, WAR, NORM }, |
||||
{ 7, ROU, NORM }, |
||||
{ 8, SRC, NORM }, |
||||
|
||||
{ 5, WAR, BAL }, |
||||
{ 6, ROU, BAL }, |
||||
{ 7, SRC, BAL }, |
||||
|
||||
{ 4, WAR, STA }, |
||||
{ 5, ROU, STA }, |
||||
{ 6, SRC, STA }, |
||||
|
||||
{ 3, WAR, HAR }, |
||||
{ 4, ROU, HAR }, |
||||
{ 5, SRC, HAR }, |
||||
|
||||
{ 4, WAR, BALSTA }, |
||||
{ 5, ROU, BALSTA }, |
||||
{ 6, SRC, BALSTA }, |
||||
|
||||
{ 3, WAR, BALHAR }, |
||||
{ 4, ROU, BALHAR }, |
||||
{ 5, SRC, BALHAR }, |
||||
|
||||
{ 3, WAR, STAHAR }, |
||||
{ 4, ROU, STAHAR }, |
||||
{ 5, SRC, STAHAR }, |
||||
|
||||
{ 2, WAR, ZEN }, |
||||
{ 3, ROU, ZEN }, |
||||
{ 4, SRC, ZEN }, |
||||
}; |
||||
|
||||
TEST(Player, PM_DoGotHit) |
||||
{ |
||||
for (size_t i = 0; i < sizeof(BlockData) / sizeof(*BlockData); i++) { |
||||
EXPECT_EQ(BlockData[i][0], RunBlockTest(BlockData[i][1], BlockData[i][2])); |
||||
} |
||||
} |
||||
|
||||
@ -1,164 +1,164 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "scrollrt.h" |
||||
#include "utils/ui_fwd.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
// TilesInView
|
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 10); |
||||
EXPECT_EQ(rows, 11); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_original_zoom) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = false; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 5); |
||||
EXPECT_EQ(rows, 6); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_960_540) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
gnScreenHeight = 540; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 15); |
||||
EXPECT_EQ(rows, 17); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_640_512) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 512; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 10); |
||||
EXPECT_EQ(rows, 12); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_768_480_zoom) |
||||
{ |
||||
gnScreenWidth = 768; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = false; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 6); |
||||
EXPECT_EQ(rows, 8); |
||||
} |
||||
|
||||
// CalcTileOffset
|
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_original_zoom) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = false; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 8); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_960_540) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
gnScreenHeight = 540; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 2); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_853_480) |
||||
{ |
||||
gnScreenWidth = 853; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 21); |
||||
EXPECT_EQ(y, 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_768_480_zoom) |
||||
{ |
||||
gnScreenWidth = 768; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = false; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 8); |
||||
} |
||||
|
||||
// RowsCoveredByPanel
|
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
zoomflag = true; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_960) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
zoomflag = true; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 4); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_960_zoom) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
zoomflag = false; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 2); |
||||
} |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "diablo.h" |
||||
#include "scrollrt.h" |
||||
#include "utils/ui_fwd.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
// TilesInView
|
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 10); |
||||
EXPECT_EQ(rows, 11); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_original_zoom) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = false; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 5); |
||||
EXPECT_EQ(rows, 6); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_960_540) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
gnScreenHeight = 540; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 15); |
||||
EXPECT_EQ(rows, 17); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_640_512) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 512; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 10); |
||||
EXPECT_EQ(rows, 12); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_in_view_768_480_zoom) |
||||
{ |
||||
gnScreenWidth = 768; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = false; |
||||
int columns = 0; |
||||
int rows = 0; |
||||
TilesInView(&columns, &rows); |
||||
EXPECT_EQ(columns, 6); |
||||
EXPECT_EQ(rows, 8); |
||||
} |
||||
|
||||
// CalcTileOffset
|
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_original_zoom) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight - 128; |
||||
zoomflag = false; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 8); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_960_540) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
gnScreenHeight = 540; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 2); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_853_480) |
||||
{ |
||||
gnScreenWidth = 853; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = true; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 21); |
||||
EXPECT_EQ(y, 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tile_offset_768_480_zoom) |
||||
{ |
||||
gnScreenWidth = 768; |
||||
gnScreenHeight = 480; |
||||
gnViewportHeight = gnScreenHeight; |
||||
zoomflag = false; |
||||
int x = 0; |
||||
int y = 0; |
||||
CalcTileOffset(&x, &y); |
||||
EXPECT_EQ(x, 0); |
||||
EXPECT_EQ(y, 8); |
||||
} |
||||
|
||||
// RowsCoveredByPanel
|
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_original) |
||||
{ |
||||
gnScreenWidth = 640; |
||||
zoomflag = true; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 0); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_960) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
zoomflag = true; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 4); |
||||
} |
||||
|
||||
TEST(Scrool_rt, calc_tiles_covered_by_panel_960_zoom) |
||||
{ |
||||
gnScreenWidth = 960; |
||||
zoomflag = false; |
||||
EXPECT_EQ(RowsCoveredByPanel(), 2); |
||||
} |
||||
|
||||
@ -1,74 +1,74 @@
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "stores.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
namespace { |
||||
|
||||
TEST(Stores, AddStoreHoldRepair_magic) |
||||
{ |
||||
ItemStruct *item; |
||||
|
||||
item = &storehold[0]; |
||||
|
||||
item->_iMaxDur = 60; |
||||
item->_iDurability = item->_iMaxDur; |
||||
item->_iMagical = ITEM_QUALITY_MAGIC; |
||||
item->_iIdentified = true; |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = 19000; |
||||
|
||||
for (int i = 1; i < item->_iMaxDur; i++) { |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = 19000; |
||||
item->_iDurability = i; |
||||
storenumh = 0; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(95 * (item->_iMaxDur - i) / 2, item->_ivalue); |
||||
} |
||||
|
||||
item->_iDurability = 59; |
||||
storenumh = 0; |
||||
item->_ivalue = 500; |
||||
item->_iIvalue = 30; // To cheap to repair
|
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(0, storenumh); |
||||
EXPECT_EQ(30, item->_iIvalue); |
||||
EXPECT_EQ(500, item->_ivalue); |
||||
} |
||||
|
||||
TEST(Stores, AddStoreHoldRepair_normal) |
||||
{ |
||||
ItemStruct *item; |
||||
|
||||
item = &storehold[0]; |
||||
|
||||
item->_iMaxDur = 20; |
||||
item->_iDurability = item->_iMaxDur; |
||||
item->_iMagical = ITEM_QUALITY_NORMAL; |
||||
item->_iIdentified = true; |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = item->_ivalue; |
||||
|
||||
for (int i = 1; i < item->_iMaxDur; i++) { |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = item->_ivalue; |
||||
item->_iDurability = i; |
||||
storenumh = 0; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(50 * (item->_iMaxDur - i), item->_ivalue); |
||||
} |
||||
|
||||
item->_iDurability = 19; |
||||
storenumh = 0; |
||||
item->_ivalue = 10; // less then 1 per dur
|
||||
item->_iIvalue = item->_ivalue; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(1, item->_ivalue); |
||||
EXPECT_EQ(1, item->_iIvalue); |
||||
} |
||||
} // namespace
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "stores.h" |
||||
|
||||
using namespace devilution; |
||||
|
||||
namespace { |
||||
|
||||
TEST(Stores, AddStoreHoldRepair_magic) |
||||
{ |
||||
ItemStruct *item; |
||||
|
||||
item = &storehold[0]; |
||||
|
||||
item->_iMaxDur = 60; |
||||
item->_iDurability = item->_iMaxDur; |
||||
item->_iMagical = ITEM_QUALITY_MAGIC; |
||||
item->_iIdentified = true; |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = 19000; |
||||
|
||||
for (int i = 1; i < item->_iMaxDur; i++) { |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = 19000; |
||||
item->_iDurability = i; |
||||
storenumh = 0; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(95 * (item->_iMaxDur - i) / 2, item->_ivalue); |
||||
} |
||||
|
||||
item->_iDurability = 59; |
||||
storenumh = 0; |
||||
item->_ivalue = 500; |
||||
item->_iIvalue = 30; // To cheap to repair
|
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(0, storenumh); |
||||
EXPECT_EQ(30, item->_iIvalue); |
||||
EXPECT_EQ(500, item->_ivalue); |
||||
} |
||||
|
||||
TEST(Stores, AddStoreHoldRepair_normal) |
||||
{ |
||||
ItemStruct *item; |
||||
|
||||
item = &storehold[0]; |
||||
|
||||
item->_iMaxDur = 20; |
||||
item->_iDurability = item->_iMaxDur; |
||||
item->_iMagical = ITEM_QUALITY_NORMAL; |
||||
item->_iIdentified = true; |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = item->_ivalue; |
||||
|
||||
for (int i = 1; i < item->_iMaxDur; i++) { |
||||
item->_ivalue = 2000; |
||||
item->_iIvalue = item->_ivalue; |
||||
item->_iDurability = i; |
||||
storenumh = 0; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(50 * (item->_iMaxDur - i), item->_ivalue); |
||||
} |
||||
|
||||
item->_iDurability = 19; |
||||
storenumh = 0; |
||||
item->_ivalue = 10; // less then 1 per dur
|
||||
item->_iIvalue = item->_ivalue; |
||||
AddStoreHoldRepair(item, 0); |
||||
EXPECT_EQ(1, storenumh); |
||||
EXPECT_EQ(1, item->_ivalue); |
||||
EXPECT_EQ(1, item->_iIvalue); |
||||
} |
||||
} // namespace
|
||||
|
||||
Loading…
Reference in new issue