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) 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); return static_cast<Direction16>(ret);
} }
@ -1023,22 +1023,22 @@ Direction16 GetDirection16(Point p1, Point p2)
flipMedian = true; 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 (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) if (5 * absolute.deltaX < absolute.deltaY) // mx/my < 0.2, approximation of tan(11.25)
ret = DIR16_SW; ret = Direction16::SouthWest;
else else
ret = DIR16_Sw; ret = Direction16::South_SouthWest;
} }
Direction16 medianPivot = DIR16_S; Direction16 medianPivot = Direction16::South;
if (flipY) { if (flipY) {
ret = Direction16Flip(ret, DIR16_SW); ret = Direction16Flip(ret, Direction16::SouthWest);
medianPivot = Direction16Flip(medianPivot, DIR16_SW); medianPivot = Direction16Flip(medianPivot, Direction16::SouthWest);
} }
if (flipX) { if (flipX) {
ret = Direction16Flip(ret, DIR16_SE); ret = Direction16Flip(ret, Direction16::SouthEast);
medianPivot = Direction16Flip(medianPivot, DIR16_SE); medianPivot = Direction16Flip(medianPivot, Direction16::SouthEast);
} }
if (flipMedian) if (flipMedian)
ret = Direction16Flip(ret, medianPivot); ret = Direction16Flip(ret, medianPivot);
@ -1853,7 +1853,7 @@ void AddArrow(Missile &missile, Point dst, Direction midir)
} }
} }
UpdateMissileVelocity(missile, dst, av); 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; missile._mirange = 256;
} }

75
Source/missiles.h

@ -57,34 +57,39 @@ struct MissilePosition {
} }
}; };
/* /**
* W sW SW Sw S * Represent a more fine-grained direction than the 8 value Direction enum.
* ^ *
* nW | Se * 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)
* NW ------+-----> SE *
* | * W WSW SW SSW S
* Nw | sE * ^
* | * WNW | SSE
* N Ne NE nE E * |
* NW -------+------> SE
* |
* NNW | ESE
* |
* N NNE NE ENE E
*/ */
enum Direction16 { enum class Direction16 {
DIR16_S, South,
DIR16_Sw, South_SouthWest,
DIR16_SW, SouthWest,
DIR16_sW, West_SouthWest,
DIR16_W, West,
DIR16_nW, West_NorthWest,
DIR16_NW, NorthWest,
DIR16_Nw, North_NorthWest,
DIR16_N, North,
DIR16_Ne, North_NorthEast,
DIR16_NE, NorthEast,
DIR16_nE, East_NorthEast,
DIR16_E, East,
DIR16_sE, East_SouthEast,
DIR16_SE, SouthEast,
DIR16_Se, South_SouthEast,
}; };
struct Missile { 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); 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 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); 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 missile this object
* @param dir Desired facing * @param dir Desired facing
*/ */
@ -160,6 +165,16 @@ inline void SetMissDir(Missile &missile, Direction dir)
SetMissDir(missile, static_cast<int>(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 InitMissiles();
void AddHiveExplosion(Missile &missile, Point dst, Direction midir); void AddHiveExplosion(Missile &missile, Point dst, Direction midir);
void AddFireRune(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) TEST(Missiles, GetDirection16)
{ {
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 15, 15 })); EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 15, 15 }));
EXPECT_EQ(Direction16::DIR16_SW, GetDirection16({ 0, 0 }, { 0, 15 })); EXPECT_EQ(Direction16::SouthWest, GetDirection16({ 0, 0 }, { 0, 15 }));
EXPECT_EQ(Direction16::DIR16_Sw, GetDirection16({ 0, 0 }, { 8, 15 })); EXPECT_EQ(Direction16::South_SouthWest, GetDirection16({ 0, 0 }, { 8, 15 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 8, 8 })); EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 8, 8 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 15, 8 })); EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 15, 8 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 15, 7 })); EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 15, 7 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 0, 0 }, { 11, 7 })); EXPECT_EQ(Direction16::South_SouthEast, GetDirection16({ 0, 0 }, { 11, 7 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 0, 0 }, { 8, 11 })); EXPECT_EQ(Direction16::South, GetDirection16({ 0, 0 }, { 8, 11 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 15, 15 }, { 0, 0 })); EXPECT_EQ(Direction16::North, GetDirection16({ 15, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_NE, GetDirection16({ 0, 15 }, { 0, 0 })); EXPECT_EQ(Direction16::NorthEast, GetDirection16({ 0, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Ne, GetDirection16({ 8, 15 }, { 0, 0 })); EXPECT_EQ(Direction16::North_NorthEast, GetDirection16({ 8, 15 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 8, 8 }, { 0, 0 })); EXPECT_EQ(Direction16::North, GetDirection16({ 8, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 15, 8 }, { 0, 0 })); EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 15, 8 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 15, 7 }, { 0, 0 })); EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 15, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 11, 7 }, { 0, 0 })); EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 11, 7 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 8, 11 }, { 0, 0 })); EXPECT_EQ(Direction16::North, GetDirection16({ 8, 11 }, { 0, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 15 }, { 15, 0 })); EXPECT_EQ(Direction16::East, GetDirection16({ 0, 15 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_SE, GetDirection16({ 0, 0 }, { 15, 0 })); EXPECT_EQ(Direction16::SouthEast, GetDirection16({ 0, 0 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_sE, GetDirection16({ 0, 8 }, { 15, 0 })); EXPECT_EQ(Direction16::East_SouthEast, GetDirection16({ 0, 8 }, { 15, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 8 }, { 8, 0 })); EXPECT_EQ(Direction16::East, GetDirection16({ 0, 8 }, { 8, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 15 }, { 8, 0 })); EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 15 }, { 8, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 15 }, { 7, 0 })); EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 15 }, { 7, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 0, 11 }, { 7, 0 })); EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 0, 11 }, { 7, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 0, 8 }, { 11, 0 })); EXPECT_EQ(Direction16::East, GetDirection16({ 0, 8 }, { 11, 0 }));
EXPECT_EQ(Direction16::DIR16_S, GetDirection16({ 2, 2 }, { 3, 3 })); EXPECT_EQ(Direction16::South, GetDirection16({ 2, 2 }, { 3, 3 }));
EXPECT_EQ(Direction16::DIR16_Sw, GetDirection16({ 2, 2 }, { 3, 4 })); EXPECT_EQ(Direction16::South_SouthWest, GetDirection16({ 2, 2 }, { 3, 4 }));
EXPECT_EQ(Direction16::DIR16_SW, GetDirection16({ 2, 2 }, { 2, 4 })); EXPECT_EQ(Direction16::SouthWest, GetDirection16({ 2, 2 }, { 2, 4 }));
EXPECT_EQ(Direction16::DIR16_sW, GetDirection16({ 2, 2 }, { 1, 4 })); EXPECT_EQ(Direction16::West_SouthWest, GetDirection16({ 2, 2 }, { 1, 4 }));
EXPECT_EQ(Direction16::DIR16_W, GetDirection16({ 2, 2 }, { 1, 3 })); EXPECT_EQ(Direction16::West, GetDirection16({ 2, 2 }, { 1, 3 }));
EXPECT_EQ(Direction16::DIR16_nW, GetDirection16({ 2, 2 }, { 0, 3 })); EXPECT_EQ(Direction16::West_NorthWest, GetDirection16({ 2, 2 }, { 0, 3 }));
EXPECT_EQ(Direction16::DIR16_NW, GetDirection16({ 2, 2 }, { 0, 2 })); EXPECT_EQ(Direction16::NorthWest, GetDirection16({ 2, 2 }, { 0, 2 }));
EXPECT_EQ(Direction16::DIR16_Nw, GetDirection16({ 2, 2 }, { 0, 1 })); EXPECT_EQ(Direction16::North_NorthWest, GetDirection16({ 2, 2 }, { 0, 1 }));
EXPECT_EQ(Direction16::DIR16_N, GetDirection16({ 2, 2 }, { 1, 1 })); EXPECT_EQ(Direction16::North, GetDirection16({ 2, 2 }, { 1, 1 }));
EXPECT_EQ(Direction16::DIR16_Ne, GetDirection16({ 2, 2 }, { 1, 0 })); EXPECT_EQ(Direction16::North_NorthEast, GetDirection16({ 2, 2 }, { 1, 0 }));
EXPECT_EQ(Direction16::DIR16_NE, GetDirection16({ 2, 2 }, { 2, 0 })); EXPECT_EQ(Direction16::NorthEast, GetDirection16({ 2, 2 }, { 2, 0 }));
EXPECT_EQ(Direction16::DIR16_nE, GetDirection16({ 2, 2 }, { 3, 0 })); EXPECT_EQ(Direction16::East_NorthEast, GetDirection16({ 2, 2 }, { 3, 0 }));
EXPECT_EQ(Direction16::DIR16_E, GetDirection16({ 2, 2 }, { 3, 1 })); EXPECT_EQ(Direction16::East, GetDirection16({ 2, 2 }, { 3, 1 }));
EXPECT_EQ(Direction16::DIR16_sE, GetDirection16({ 2, 2 }, { 4, 1 })); EXPECT_EQ(Direction16::East_SouthEast, GetDirection16({ 2, 2 }, { 4, 1 }));
EXPECT_EQ(Direction16::DIR16_SE, GetDirection16({ 2, 2 }, { 4, 2 })); EXPECT_EQ(Direction16::SouthEast, GetDirection16({ 2, 2 }, { 4, 2 }));
EXPECT_EQ(Direction16::DIR16_Se, GetDirection16({ 2, 2 }, { 4, 3 })); 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