Browse Source

Use scoped enum for Direction16.

Allows renaming the members to share names with Direction members when
representing the same conceptual direction.
pull/2845/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
9ef77cb428
  1. 20
      Source/missiles.cpp
  2. 75
      Source/missiles.h
  3. 82
      test/missiles_test.cpp

20
Source/missiles.cpp

@ -109,7 +109,7 @@ Monster *FindClosest(Point source, int rad)
constexpr Direction16 Direction16Flip(Direction16 x, Direction16 pivot)
{
unsigned ret = (2 * pivot + 16 - x) % 16;
std::underlying_type_t<Direction16> ret = (2 * static_cast<std::underlying_type_t<Direction16>>(pivot) + 16 - static_cast<std::underlying_type_t<Direction16>>(x)) % 16;
return static_cast<Direction16>(ret);
}
@ -1023,22 +1023,22 @@ Direction16 GetDirection16(Point p1, Point p2)
flipMedian = true;
}
Direction16 ret = DIR16_S;
Direction16 ret = Direction16::South;
if (3 * absolute.deltaX <= (absolute.deltaY * 2)) { // mx/my <= 2/3, approximation of tan(33.75)
if (5 * absolute.deltaX < absolute.deltaY) // mx/my < 0.2, approximation of tan(11.25)
ret = DIR16_SW;
ret = Direction16::SouthWest;
else
ret = DIR16_Sw;
ret = Direction16::South_SouthWest;
}
Direction16 medianPivot = DIR16_S;
Direction16 medianPivot = Direction16::South;
if (flipY) {
ret = Direction16Flip(ret, DIR16_SW);
medianPivot = Direction16Flip(medianPivot, DIR16_SW);
ret = Direction16Flip(ret, Direction16::SouthWest);
medianPivot = Direction16Flip(medianPivot, Direction16::SouthWest);
}
if (flipX) {
ret = Direction16Flip(ret, DIR16_SE);
medianPivot = Direction16Flip(medianPivot, DIR16_SE);
ret = Direction16Flip(ret, Direction16::SouthEast);
medianPivot = Direction16Flip(medianPivot, Direction16::SouthEast);
}
if (flipMedian)
ret = Direction16Flip(ret, medianPivot);
@ -1853,7 +1853,7 @@ void AddArrow(Missile &missile, Point dst, Direction midir)
}
}
UpdateMissileVelocity(missile, dst, av);
missile._miAnimFrame = GetDirection16(missile.position.start, dst) + 1;
missile._miAnimFrame = static_cast<int>(GetDirection16(missile.position.start, dst)) + 1;
missile._mirange = 256;
}

75
Source/missiles.h

@ -57,34 +57,39 @@ struct MissilePosition {
}
};
/*
* W sW SW Sw S
* ^
* nW | Se
* |
* NW ------+-----> SE
* |
* Nw | sE
* |
* N Ne NE nE E
/**
* Represent a more fine-grained direction than the 8 value Direction enum.
*
* This is used when rendering projectiles like arrows which have additional sprites for "half-winds" on a 16-point compass.
* The sprite sheets are typically 0-indexed and use the following layout (relative to the screen projection)
*
* W WSW SW SSW S
* ^
* WNW | SSE
* |
* NW -------+------> SE
* |
* NNW | ESE
* |
* N NNE NE ENE E
*/
enum Direction16 {
DIR16_S,
DIR16_Sw,
DIR16_SW,
DIR16_sW,
DIR16_W,
DIR16_nW,
DIR16_NW,
DIR16_Nw,
DIR16_N,
DIR16_Ne,
DIR16_NE,
DIR16_nE,
DIR16_E,
DIR16_sE,
DIR16_SE,
DIR16_Se,
enum class Direction16 {
South,
South_SouthWest,
SouthWest,
West_SouthWest,
West,
West_NorthWest,
NorthWest,
North_NorthWest,
North,
North_NorthEast,
NorthEast,
East_NorthEast,
East,
East_SouthEast,
SouthEast,
South_SouthEast,
};
struct Missile {
@ -144,14 +149,14 @@ bool MonsterTrapHit(int m, int mindam, int maxdam, int dist, missile_id t, bool
bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, missile_id mtype, bool shift, int earflag, bool *blocked);
/**
* @brief Sets the missile sprite to represent the direction of travel
* @brief Sets the missile sprite to the given sheet frame
* @param missile this object
* @param dir Sprite frame representing the desired facing
* @param dir Sprite frame, typically representing a direction but there are some exceptions (arrows being 1 indexed, directionless spells)
*/
void SetMissDir(Missile &missile, int dir);
/**
* @brief Overload to convert a Direction value to the appropriate sprite frame
* @brief Sets the sprite for this missile so it matches the given Direction
* @param missile this object
* @param dir Desired facing
*/
@ -160,6 +165,16 @@ inline void SetMissDir(Missile &missile, Direction dir)
SetMissDir(missile, static_cast<int>(dir));
}
/**
* @brief Sets the sprite for this missile so it matches the given Direction16
* @param missile this object
* @param dir Desired facing at a 22.8125 degree resolution
*/
inline void SetMissDir(Missile &missile, Direction16 dir)
{
SetMissDir(missile, static_cast<int>(dir));
}
void InitMissiles();
void AddHiveExplosion(Missile &missile, Point dst, Direction midir);
void AddFireRune(Missile &missile, Point dst, Direction midir);

82
test/missiles_test.cpp

@ -45,47 +45,47 @@ TEST(Missiles, GetDirection8)
TEST(Missiles, GetDirection16)
{
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 15, 15 }));
EXPECT_EQ(Direction16::DIR16_SW, GetDirection16({ 0, 0 }, { 0, 15 }));
EXPECT_EQ(Direction16::DIR16_Sw, GetDirection16({ 0, 0 }, { 8, 15 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 8, 8 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 15, 8 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 15, 7 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 11, 7 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 8, 11 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 15, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_NE, GetDirection16({ 0, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Ne, GetDirection16({ 8, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 8, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 15, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 15, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 11, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 8, 11 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 15 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_SE, GetDirection16({ 0, 0 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_sE, GetDirection16({ 0, 8 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 8 }, { 8, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 15 }, { 8, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 15 }, { 7, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 11 }, { 7, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 8 }, { 11, 0 }));
EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 15, 15 }));
EXPECT_EQ(Direction16::SouthWest, GetDirection16({ 0, 0 }, { 0, 15 }));
EXPECT_EQ(Direction16::South_SouthWest, GetDirection16({ 0, 0 }, { 8, 15 }));
EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 8, 8 }));
EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 15, 8 }));
EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 15, 7 }));
EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 11, 7 }));
EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 8, 11 }));
EXPECT_EQ(Direction16::North, GetDirection16({ 15, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::NorthEast, GetDirection16({ 0, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::North_NorthEast, GetDirection16({ 8, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::North, GetDirection16({ 8, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 15, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 15, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 11, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::North, GetDirection16({ 8, 11 }, { 0, 0 }));
EXPECT_EQ(Direction16::East, GetDirection16({ 0, 15 }, { 15, 0 }));
EXPECT_EQ(Direction16::SouthEast, GetDirection16({ 0, 0 }, { 15, 0 }));
EXPECT_EQ(Direction16::East_SouthEast, GetDirection16({ 0, 8 }, { 15, 0 }));
EXPECT_EQ(Direction16::East, GetDirection16({ 0, 8 }, { 8, 0 }));
EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 15 }, { 8, 0 }));
EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 15 }, { 7, 0 }));
EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 11 }, { 7, 0 }));
EXPECT_EQ(Direction16::East, GetDirection16({ 0, 8 }, { 11, 0 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 2, 2 }, { 3, 3 }));
EXPECT_EQ(Direction16::DIR16_Sw, GetDirection16({ 2, 2 }, { 3, 4 }));
EXPECT_EQ(Direction16::DIR16_SW, GetDirection16({ 2, 2 }, { 2, 4 }));
EXPECT_EQ(Direction16::DIR16_sW, GetDirection16({ 2, 2 }, { 1, 4 }));
EXPECT_EQ(Direction16::DIR16_W, GetDirection16({ 2, 2 }, { 1, 3 }));
EXPECT_EQ(Direction16::DIR16_nW, GetDirection16({ 2, 2 }, { 0, 3 }));
EXPECT_EQ(Direction16::DIR16_NW, GetDirection16({ 2, 2 }, { 0, 2 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 2, 2 }, { 0, 1 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 2, 2 }, { 1, 1 }));
EXPECT_EQ(Direction16::DIR16_Ne, GetDirection16({ 2, 2 }, { 1, 0 }));
EXPECT_EQ(Direction16::DIR16_NE, GetDirection16({ 2, 2 }, { 2, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 2, 2 }, { 3, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 2, 2 }, { 3, 1 }));
EXPECT_EQ(Direction16::DIR16_sE, GetDirection16({ 2, 2 }, { 4, 1 }));
EXPECT_EQ(Direction16::DIR16_SE, GetDirection16({ 2, 2 }, { 4, 2 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 2, 2 }, { 4, 3 }));
EXPECT_EQ(Direction16::South, GetDirection16({ 2, 2 }, { 3, 3 }));
EXPECT_EQ(Direction16::South_SouthWest, GetDirection16({ 2, 2 }, { 3, 4 }));
EXPECT_EQ(Direction16::SouthWest, GetDirection16({ 2, 2 }, { 2, 4 }));
EXPECT_EQ(Direction16::West_SouthWest, GetDirection16({ 2, 2 }, { 1, 4 }));
EXPECT_EQ(Direction16::West, GetDirection16({ 2, 2 }, { 1, 3 }));
EXPECT_EQ(Direction16::West_NorthWest, GetDirection16({ 2, 2 }, { 0, 3 }));
EXPECT_EQ(Direction16::NorthWest, GetDirection16({ 2, 2 }, { 0, 2 }));
EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 2, 2 }, { 0, 1 }));
EXPECT_EQ(Direction16::North, GetDirection16({ 2, 2 }, { 1, 1 }));
EXPECT_EQ(Direction16::North_NorthEast, GetDirection16({ 2, 2 }, { 1, 0 }));
EXPECT_EQ(Direction16::NorthEast, GetDirection16({ 2, 2 }, { 2, 0 }));
EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 2, 2 }, { 3, 0 }));
EXPECT_EQ(Direction16::East, GetDirection16({ 2, 2 }, { 3, 1 }));
EXPECT_EQ(Direction16::East_SouthEast, GetDirection16({ 2, 2 }, { 4, 1 }));
EXPECT_EQ(Direction16::SouthEast, GetDirection16({ 2, 2 }, { 4, 2 }));
EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 2, 2 }, { 4, 3 }));
EXPECT_EQ(Direction16::DIR16_Sw, GetDirection16({ 0, 0 }, { 0, 0 })) << "GetDirection16 is expected to default to DIR16_Sw when the points occupy the same tile";
EXPECT_EQ(Direction16::South_SouthWest, GetDirection16({ 0, 0 }, { 0, 0 })) << "GetDirection16 is expected to default to Direction16::South_SouthWest when the points occupy the same tile";
}

Loading…
Cancel
Save