Browse Source

Point: Safer `operator-`

1. Require both operands to have the same signedness to avoid surprises.
2. Only allow unary negation on signed points.

Fixes #6409
Also fixes a potential bug in the sound position calculation.
pull/6448/head
Gleb Mazovetskiy 3 years ago
parent
commit
999f44cf07
  1. 2
      Source/engine/point.hpp
  2. 9
      Source/engine/sound_position.cpp
  3. 6
      Source/missiles.cpp

2
Source/engine/point.hpp

@ -90,6 +90,7 @@ struct PointOf {
constexpr PointOf<CoordT> operator-() const
{
static_assert(std::is_signed<CoordT>::value, "CoordT must be signed");
return { -x, -y };
}
@ -193,6 +194,7 @@ constexpr PointOf<PointCoordT> operator+(PointOf<PointCoordT> a, Direction direc
template <typename PointCoordT, typename OtherPointCoordT>
constexpr DisplacementOf<PointCoordT> operator-(PointOf<PointCoordT> a, PointOf<OtherPointCoordT> b)
{
static_assert(std::is_signed<PointCoordT>::value == std::is_signed<OtherPointCoordT>::value, "points must have the same signedness");
return { static_cast<PointCoordT>(a.x - b.x), static_cast<PointCoordT>(a.y - b.y) };
}

9
Source/engine/sound_position.cpp

@ -7,14 +7,13 @@ namespace devilution {
bool CalculateSoundPosition(Point soundPosition, int *plVolume, int *plPan)
{
const auto &playerPosition = MyPlayer->position.tile;
const auto delta = soundPosition - playerPosition;
const Point playerPosition { MyPlayer->position.tile };
const Displacement delta = soundPosition - playerPosition;
int pan = (delta.deltaX - delta.deltaY) * 256;
const int pan = (delta.deltaX - delta.deltaY) * 256;
*plPan = clamp(pan, PAN_MIN, PAN_MAX);
int volume = playerPosition.ApproxDistance(soundPosition);
volume *= -64;
const int volume = playerPosition.ApproxDistance(soundPosition) * -64;
if (volume <= ATTENUATION_MIN)
return false;

6
Source/missiles.cpp

@ -1474,10 +1474,10 @@ void AddWarp(Missile &missile, AddMissileParameter &parameter)
}
app_fatal(StrCat("invalid leveltype", static_cast<int>(leveltype)));
};
Displacement triggerOffset = getTriggerOffset(trg);
const Displacement triggerOffset = getTriggerOffset(trg);
candidate += triggerOffset;
Displacement off = player.position.tile - candidate;
int distanceSq = off.deltaY * off.deltaY + off.deltaX * off.deltaX;
const Displacement off = Point { player.position.tile } - candidate;
const int distanceSq = off.deltaY * off.deltaY + off.deltaX * off.deltaX;
if (distanceSq < minDistanceSq) {
minDistanceSq = distanceSq;
tile = candidate;

Loading…
Cancel
Save