Browse Source

♻️ Replace Point addition with 'Point + Displacement'

pull/2262/head^2
Juliano Leal Goncalves 5 years ago committed by Anders Jenbo
parent
commit
cbb84199c2
  1. 58
      Source/automap.cpp
  2. 3
      Source/automap.h
  3. 2
      Source/control.cpp
  4. 8
      Source/controls/modifier_hints.cpp
  5. 8
      Source/controls/plrctrls.cpp
  6. 14
      Source/cursor.cpp
  7. 2
      Source/effects.cpp
  8. 6
      Source/engine/actor_position.hpp
  9. 44
      Source/engine/point.hpp
  10. 2
      Source/gendung.h
  11. 6
      Source/inv.cpp
  12. 8
      Source/items.cpp
  13. 72
      Source/loadsave.cpp
  14. 126
      Source/missiles.cpp
  15. 6
      Source/missiles.h
  16. 24
      Source/monster.cpp
  17. 6
      Source/objects.cpp
  18. 43
      Source/player.cpp
  19. 40
      Source/scrollrt.cpp
  20. 2
      Source/scrollrt.h
  21. 2
      Source/spells.cpp
  22. 10
      Source/towners.cpp
  23. 44
      test/automap_test.cpp

58
Source/automap.cpp

@ -109,7 +109,7 @@ void DrawAutomapTile(const CelOutputBuffer &out, Point center, uint16_t automapT
if ((flags & MapFlagsStairs) != 0) { if ((flags & MapFlagsStairs) != 0) {
constexpr int NumStairSteps = 4; constexpr int NumStairSteps = 4;
const Point offset = { -AmLine8, AmLine4 }; const Displacement offset = { -AmLine8, AmLine4 };
Point p = { center.x - AmLine8, center.y - AmLine8 - AmLine4 }; Point p = { center.x - AmLine8, center.y - AmLine8 - AmLine4 };
for (int i = 0; i < NumStairSteps; ++i) { for (int i = 0; i < NumStairSteps; ++i) {
DrawMapLineSE(out, p, AmLine16, MapColorsBright); DrawMapLineSE(out, p, AmLine16, MapColorsBright);
@ -230,12 +230,12 @@ void SearchAutomapItem(const CelOutputBuffer &out)
if (dItem[i][j] == 0) if (dItem[i][j] == 0)
continue; continue;
int px = i - 2 * AutomapOffset.x - ViewX; int px = i - 2 * AutomapOffset.deltaX - ViewX;
int py = j - 2 * AutomapOffset.y - ViewY; int py = j - 2 * AutomapOffset.deltaY - ViewY;
Point screen = { Point screen = {
(ScrollInfo.offset.x * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2, (ScrollInfo.offset.deltaX * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2,
(ScrollInfo.offset.y * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2 (ScrollInfo.offset.deltaY * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2
}; };
if (CanPanelsCoverView()) { if (CanPanelsCoverView()) {
@ -267,12 +267,12 @@ void DrawAutomapPlr(const CelOutputBuffer &out, int playerId)
tile.y++; tile.y++;
} }
int px = tile.x - 2 * AutomapOffset.x - ViewX; int px = tile.x - 2 * AutomapOffset.deltaX - ViewX;
int py = tile.y - 2 * AutomapOffset.y - ViewY; int py = tile.y - 2 * AutomapOffset.deltaY - ViewY;
Point base = { Point base = {
(player.position.offset.x * AutoMapScale / 100 / 2) + (ScrollInfo.offset.x * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2, (player.position.offset.deltaX * AutoMapScale / 100 / 2) + (ScrollInfo.offset.deltaX * AutoMapScale / 100 / 2) + (px - py) * AmLine16 + gnScreenWidth / 2,
(player.position.offset.y * AutoMapScale / 100 / 2) + (ScrollInfo.offset.y * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2 (player.position.offset.deltaY * AutoMapScale / 100 / 2) + (ScrollInfo.offset.deltaY * AutoMapScale / 100 / 2) + (px + py) * AmLine8 + (gnScreenHeight - PANEL_HEIGHT) / 2
}; };
if (CanPanelsCoverView()) { if (CanPanelsCoverView()) {
@ -442,7 +442,7 @@ std::unique_ptr<uint16_t[]> LoadAutomapData(size_t &tileCount)
bool AutomapActive; bool AutomapActive;
bool AutomapView[DMAXX][DMAXY]; bool AutomapView[DMAXX][DMAXY];
int AutoMapScale; int AutoMapScale;
Point AutomapOffset; Displacement AutomapOffset;
int AmLine64; int AmLine64;
int AmLine32; int AmLine32;
int AmLine16; int AmLine16;
@ -484,26 +484,26 @@ void StartAutomap()
void AutomapUp() void AutomapUp()
{ {
AutomapOffset.x--; AutomapOffset.deltaX--;
AutomapOffset.y--; AutomapOffset.deltaY--;
} }
void AutomapDown() void AutomapDown()
{ {
AutomapOffset.x++; AutomapOffset.deltaX++;
AutomapOffset.y++; AutomapOffset.deltaY++;
} }
void AutomapLeft() void AutomapLeft()
{ {
AutomapOffset.x--; AutomapOffset.deltaX--;
AutomapOffset.y++; AutomapOffset.deltaY++;
} }
void AutomapRight() void AutomapRight()
{ {
AutomapOffset.x++; AutomapOffset.deltaX++;
AutomapOffset.y--; AutomapOffset.deltaY--;
} }
void AutomapZoomIn() void AutomapZoomIn()
@ -540,15 +540,15 @@ void DrawAutomap(const CelOutputBuffer &out)
} }
Automap = { (ViewX - 16) / 2, (ViewY - 16) / 2 }; Automap = { (ViewX - 16) / 2, (ViewY - 16) / 2 };
while (Automap.x + AutomapOffset.x < 0) while (Automap.x + AutomapOffset.deltaX < 0)
AutomapOffset.x++; AutomapOffset.deltaX++;
while (Automap.x + AutomapOffset.x >= DMAXX) while (Automap.x + AutomapOffset.deltaX >= DMAXX)
AutomapOffset.x--; AutomapOffset.deltaX--;
while (Automap.y + AutomapOffset.y < 0) while (Automap.y + AutomapOffset.deltaY < 0)
AutomapOffset.y++; AutomapOffset.deltaY++;
while (Automap.y + AutomapOffset.y >= DMAXY) while (Automap.y + AutomapOffset.deltaY >= DMAXY)
AutomapOffset.y--; AutomapOffset.deltaY--;
Automap += AutomapOffset; Automap += AutomapOffset;
@ -558,7 +558,7 @@ void DrawAutomap(const CelOutputBuffer &out)
cells++; cells++;
if (((gnScreenWidth / 2) % d) >= (AutoMapScale * 32) / 100) if (((gnScreenWidth / 2) % d) >= (AutoMapScale * 32) / 100)
cells++; cells++;
if ((ScrollInfo.offset.x + ScrollInfo.offset.y) != 0) if ((ScrollInfo.offset.deltaX + ScrollInfo.offset.deltaY) != 0)
cells++; cells++;
Point screen { Point screen {
@ -581,8 +581,8 @@ void DrawAutomap(const CelOutputBuffer &out)
screen.y -= AmLine8; screen.y -= AmLine8;
} }
screen.x += AutoMapScale * ScrollInfo.offset.x / 100 / 2; screen.x += AutoMapScale * ScrollInfo.offset.deltaX / 100 / 2;
screen.y += AutoMapScale * ScrollInfo.offset.y / 100 / 2; screen.y += AutoMapScale * ScrollInfo.offset.deltaY / 100 / 2;
if (CanPanelsCoverView()) { if (CanPanelsCoverView()) {
if (invflag || sbookflag) { if (invflag || sbookflag) {

3
Source/automap.h

@ -8,6 +8,7 @@
#include <cstdint> #include <cstdint>
#include "engine.h" #include "engine.h"
#include "engine/displacement.hpp"
#include "engine/point.hpp" #include "engine/point.hpp"
#include "gendung.h" #include "gendung.h"
@ -19,7 +20,7 @@ extern bool AutomapActive;
extern bool AutomapView[DMAXX][DMAXY]; extern bool AutomapView[DMAXX][DMAXY];
/** Specifies the scale of the automap. */ /** Specifies the scale of the automap. */
extern int AutoMapScale; extern int AutoMapScale;
extern Point AutomapOffset; extern Displacement AutomapOffset;
extern int AmLine64; extern int AmLine64;
extern int AmLine32; extern int AmLine32;
extern int AmLine16; extern int AmLine16;

2
Source/control.cpp

@ -326,7 +326,7 @@ static void PrintSBookHotkey(const CelOutputBuffer &out, Point position, const s
position += Displacement { SPLICONLENGTH - (GetLineWidth(text.c_str()) + 5), 17 - SPLICONLENGTH }; position += Displacement { SPLICONLENGTH - (GetLineWidth(text.c_str()) + 5), 17 - SPLICONLENGTH };
// Draw a drop shadow below and to the left of the text // Draw a drop shadow below and to the left of the text
DrawString(out, text.c_str(), position + Point { -1, 1 }, UIS_BLACK); DrawString(out, text.c_str(), position + Displacement { -1, 1 }, UIS_BLACK);
// Then draw the text over the top // Then draw the text over the top
DrawString(out, text.c_str(), position, UIS_SILVER); DrawString(out, text.c_str(), position, UIS_SILVER);
} }

8
Source/controls/modifier_hints.cpp

@ -106,12 +106,12 @@ uint16_t CircleMenuHintTextColor(bool active)
*/ */
void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, const Point &origin) void DrawCircleMenuHint(const CelOutputBuffer &out, const CircleMenuHint &hint, const Point &origin)
{ {
DrawString(out, hint.top, origin + Point { hint.xMid - hint.topW / 2, 0 }, CircleMenuHintTextColor(IsTopActive(hint))); DrawString(out, hint.top, origin + Displacement { hint.xMid - hint.topW / 2, 0 }, CircleMenuHintTextColor(IsTopActive(hint)));
DrawString(out, hint.left, origin + Point { 0, LineHeight }, CircleMenuHintTextColor(IsLeftActive(hint))); DrawString(out, hint.left, origin + Displacement { 0, LineHeight }, CircleMenuHintTextColor(IsLeftActive(hint)));
DrawString(out, hint.right, origin + Point { hint.leftW + MidSpaces * SpaceWidth(), LineHeight }, CircleMenuHintTextColor(IsRightActive(hint))); DrawString(out, hint.right, origin + Displacement { hint.leftW + MidSpaces * SpaceWidth(), LineHeight }, CircleMenuHintTextColor(IsRightActive(hint)));
DrawString(out, hint.bottom, origin + Point { hint.xMid - hint.bottomW / 2, LineHeight * 2 }, CircleMenuHintTextColor(IsBottomActive(hint))); DrawString(out, hint.bottom, origin + Displacement { hint.xMid - hint.bottomW / 2, LineHeight * 2 }, CircleMenuHintTextColor(IsBottomActive(hint)));
} }
void DrawStartModifierMenu(const CelOutputBuffer &out) void DrawStartModifierMenu(const CelOutputBuffer &out)

8
Source/controls/plrctrls.cpp

@ -976,11 +976,11 @@ void HotSpellMove(AxisDirection dir)
} }
if (dir.y == AxisDirectionY_UP) { if (dir.y == AxisDirectionY_UP) {
if (HSExists(newMousePosition - Point { 0, SPLICONLENGTH })) { if (HSExists(newMousePosition - Displacement { 0, SPLICONLENGTH })) {
newMousePosition.y -= SPLICONLENGTH; newMousePosition.y -= SPLICONLENGTH;
} }
} else if (dir.y == AxisDirectionY_DOWN) { } else if (dir.y == AxisDirectionY_DOWN) {
if (HSExists(newMousePosition + Point { 0, SPLICONLENGTH })) { if (HSExists(newMousePosition + Displacement { 0, SPLICONLENGTH })) {
newMousePosition.y += SPLICONLENGTH; newMousePosition.y += SPLICONLENGTH;
} }
} }
@ -1267,8 +1267,8 @@ void HandleRightStickMotion()
int dx = 0; int dx = 0;
int dy = 0; int dy = 0;
acc.Pool(&dx, &dy, 32); acc.Pool(&dx, &dy, 32);
AutomapOffset.x += dy + dx; AutomapOffset.deltaX += dy + dx;
AutomapOffset.y += dy - dx; AutomapOffset.deltaY += dy - dx;
return; return;
} }

14
Source/cursor.cpp

@ -301,17 +301,17 @@ void CheckCursMove()
int yo = 0; int yo = 0;
CalcTileOffset(&xo, &yo); CalcTileOffset(&xo, &yo);
const auto &myPlayer = plr[myplr]; const auto &myPlayer = plr[myplr];
Point offset = ScrollInfo.offset; Displacement offset = ScrollInfo.offset;
if (myPlayer.IsWalking()) if (myPlayer.IsWalking())
offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true); offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true);
sx -= offset.x - xo; sx -= offset.deltaX - xo;
sy -= offset.y - yo; sy -= offset.deltaY - yo;
// Predict the next frame when walking to avoid input jitter // Predict the next frame when walking to avoid input jitter
int fx = myPlayer.position.offset2.x / 256; int fx = myPlayer.position.offset2.deltaX / 256;
int fy = myPlayer.position.offset2.y / 256; int fy = myPlayer.position.offset2.deltaY / 256;
fx -= (myPlayer.position.offset2.x + myPlayer.position.velocity.x) / 256; fx -= (myPlayer.position.offset2.deltaX + myPlayer.position.velocity.deltaX) / 256;
fy -= (myPlayer.position.offset2.y + myPlayer.position.velocity.y) / 256; fy -= (myPlayer.position.offset2.deltaY + myPlayer.position.velocity.deltaY) / 256;
if (ScrollInfo._sdir != SDIR_NONE) { if (ScrollInfo._sdir != SDIR_NONE) {
sx -= fx; sx -= fx;
sy -= fy; sy -= fy;

2
Source/effects.cpp

@ -1151,7 +1151,7 @@ bool calc_snd_position(Point soundPosition, int *plVolume, int *plPan)
const auto &playerPosition = plr[myplr].position.tile; const auto &playerPosition = plr[myplr].position.tile;
const auto delta = soundPosition - playerPosition; const auto delta = soundPosition - playerPosition;
pan = (delta.x - delta.y) * 256; pan = (delta.deltaX - delta.deltaY) * 256;
*plPan = clamp(pan, PAN_MIN, PAN_MAX); *plPan = clamp(pan, PAN_MIN, PAN_MAX);
volume = playerPosition.ApproxDistance(soundPosition); volume = playerPosition.ApproxDistance(soundPosition);

6
Source/engine/actor_position.hpp

@ -13,11 +13,11 @@ struct ActorPosition {
/** Most recent position in dPlayer. */ /** Most recent position in dPlayer. */
Point old; Point old;
/** Pixel offset from tile. */ /** Pixel offset from tile. */
Point offset; Displacement offset;
/** Same as offset but contains the value in a higher range */ /** Same as offset but contains the value in a higher range */
Point offset2; Displacement offset2;
/** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */ /** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */
Point velocity; Displacement velocity;
/** Used for referring to position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks) */ /** Used for referring to position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks) */
Point temp; Point temp;
}; };

44
Source/engine/point.hpp

@ -23,13 +23,6 @@ struct Point {
return !(*this == other); return !(*this == other);
} }
constexpr Point &operator+=(const Point &other)
{
x += other.x;
y += other.y;
return *this;
}
constexpr Point &operator+=(const Displacement &displacement) constexpr Point &operator+=(const Displacement &displacement)
{ {
x += displacement.deltaX; x += displacement.deltaX;
@ -42,10 +35,10 @@ struct Point {
return (*this) += Displacement::fromDirection(direction); return (*this) += Displacement::fromDirection(direction);
} }
constexpr Point &operator-=(const Point &other) constexpr Point &operator-=(const Displacement &displacement)
{ {
x -= other.x; x -= displacement.deltaX;
y -= other.y; y -= displacement.deltaY;
return *this; return *this;
} }
@ -63,12 +56,6 @@ struct Point {
return *this; return *this;
} }
constexpr friend Point operator+(Point a, const Point &b)
{
a += b;
return a;
}
constexpr friend Point operator+(Point a, Displacement displacement) constexpr friend Point operator+(Point a, Displacement displacement)
{ {
a += displacement; a += displacement;
@ -81,10 +68,9 @@ struct Point {
return a; return a;
} }
constexpr friend Point operator-(Point a, const Point &b) constexpr friend Displacement operator-(Point a, const Point &b)
{ {
a -= b; return { a.x - b.x, a.y - b.y };
return a;
} }
constexpr friend Point operator-(const Point &a) constexpr friend Point operator-(const Point &a)
@ -92,6 +78,12 @@ struct Point {
return { -a.x, -a.y }; return { -a.x, -a.y };
} }
constexpr friend Point operator-(Point a, Displacement displacement)
{
a -= displacement;
return a;
}
constexpr friend Point operator*(Point a, const float factor) constexpr friend Point operator*(Point a, const float factor)
{ {
a *= factor; a *= factor;
@ -112,8 +104,8 @@ struct Point {
constexpr int ApproxDistance(Point other) const constexpr int ApproxDistance(Point other) const
{ {
Point offset = abs(other - *this); Displacement offset = abs(other - *this);
auto minMax = std::minmax(offset.x, offset.y); auto minMax = std::minmax(offset.deltaX, offset.deltaY);
int min = minMax.first; int min = minMax.first;
int max = minMax.second; int max = minMax.second;
@ -136,7 +128,7 @@ struct Point {
auto vector = *this - other; //No need to call abs() as we square the values anyway auto vector = *this - other; //No need to call abs() as we square the values anyway
// Casting multiplication operands to a wide type to address overflow warnings // Casting multiplication operands to a wide type to address overflow warnings
return static_cast<int>(std::sqrt(static_cast<int64_t>(vector.x) * vector.x + static_cast<int64_t>(vector.y) * vector.y)); return static_cast<int>(std::sqrt(static_cast<int64_t>(vector.deltaX) * vector.deltaX + static_cast<int64_t>(vector.deltaY) * vector.deltaY));
} }
constexpr friend Point abs(Point a) constexpr friend Point abs(Point a)
@ -146,16 +138,16 @@ struct Point {
constexpr int ManhattanDistance(Point other) const constexpr int ManhattanDistance(Point other) const
{ {
Point offset = abs(*this - other); Displacement offset = abs(*this - other);
return offset.x + offset.y; return offset.deltaX + offset.deltaY;
} }
constexpr int WalkingDistance(Point other) const constexpr int WalkingDistance(Point other) const
{ {
Point offset = abs(*this - other); Displacement offset = abs(*this - other);
return std::max<int>(offset.x, offset.y); return std::max<int>(offset.deltaX, offset.deltaY);
} }
}; };

2
Source/gendung.h

@ -88,7 +88,7 @@ struct ScrollStruct {
/** @brief Tile offset of camera. */ /** @brief Tile offset of camera. */
Point tile; Point tile;
/** @brief Pixel offset of camera. */ /** @brief Pixel offset of camera. */
Point offset; Displacement offset;
/** @brief Move direction of camera. */ /** @brief Move direction of camera. */
_scroll_direction _sdir; _scroll_direction _sdir;
}; };

6
Source/inv.cpp

@ -267,7 +267,7 @@ void DrawInv(const CelOutputBuffer &out)
if (myPlayer.InvGrid[i] != 0) { if (myPlayer.InvGrid[i] != 0) {
InvDrawSlotBack( InvDrawSlotBack(
out, out,
InvRect[i + SLOTXY_INV_FIRST] + Point { RIGHT_PANEL_X, -1 }, InvRect[i + SLOTXY_INV_FIRST] + Displacement { RIGHT_PANEL_X, -1 },
InventorySlotSizeInPixels); InventorySlotSizeInPixels);
} }
} }
@ -1815,8 +1815,8 @@ int InvPutItem(PlayerStruct &player, Point position)
int yp = cursmy; int yp = cursmy;
int xp = cursmx; int xp = cursmx;
if (player.HoldItem._iCurs == ICURS_RUNE_BOMB && xp >= 79 && xp <= 82 && yp >= 61 && yp <= 64) { if (player.HoldItem._iCurs == ICURS_RUNE_BOMB && xp >= 79 && xp <= 82 && yp >= 61 && yp <= 64) {
Point relativePosition = position - player.position.tile; Displacement relativePosition = position - player.position.tile;
NetSendCmdLocParam2(false, CMD_OPENHIVE, player.position.tile, relativePosition.x, relativePosition.y); NetSendCmdLocParam2(false, CMD_OPENHIVE, player.position.tile, relativePosition.deltaX, relativePosition.deltaY);
quests[Q_FARMER]._qactive = QUEST_DONE; quests[Q_FARMER]._qactive = QUEST_DONE;
if (gbIsMultiplayer) { if (gbIsMultiplayer) {
NetSendCmdQuest(true, Q_FARMER); NetSendCmdQuest(true, Q_FARMER);

8
Source/items.cpp

@ -456,7 +456,7 @@ Point GetRandomAvailableItemPosition()
{ {
Point position = {}; Point position = {};
do { do {
position = Point { 16, 16 } + Point { GenerateRnd(80), GenerateRnd(80) }; position = Point { GenerateRnd(80), GenerateRnd(80) } + Displacement { 16, 16 };
} while (!ItemPlace(position)); } while (!ItemPlace(position));
return position; return position;
@ -1378,7 +1378,7 @@ static void GetSuperItemSpace(Point position, int8_t inum)
for (int k = 2; k < 50; k++) { for (int k = 2; k < 50; k++) {
for (int j = -k; j <= k; j++) { for (int j = -k; j <= k; j++) {
for (int i = -k; i <= k; i++) { for (int i = -k; i <= k; i++) {
Point offset = { i, j }; Displacement offset = { i, j };
positionToCheck = position + offset; positionToCheck = position + offset;
if (!ItemSpaceOk(positionToCheck)) if (!ItemSpaceOk(positionToCheck))
continue; continue;
@ -1395,7 +1395,7 @@ Point GetSuperItemLoc(Point position)
for (int k = 1; k < 50; k++) { for (int k = 1; k < 50; k++) {
for (int j = -k; j <= k; j++) { for (int j = -k; j <= k; j++) {
for (int i = -k; i <= k; i++) { for (int i = -k; i <= k; i++) {
Point offset = { i, j }; Displacement offset = { i, j };
Point positionToCheck = position + offset; Point positionToCheck = position + offset;
if (ItemSpaceOk(positionToCheck)) { if (ItemSpaceOk(positionToCheck)) {
return positionToCheck; return positionToCheck;
@ -2811,7 +2811,7 @@ void SpawnQuestItem(int itemid, Point position, int randarea, int selflag)
bool failed = false; bool failed = false;
for (int i = 0; i < randarea && !failed; i++) { for (int i = 0; i < randarea && !failed; i++) {
for (int j = 0; j < randarea && !failed; j++) { for (int j = 0; j < randarea && !failed; j++) {
failed = !ItemSpaceOk(position + Point { i, j }); failed = !ItemSpaceOk(position + Displacement { i, j });
} }
} }
if (!failed) if (!failed)

72
Source/loadsave.cpp

@ -333,10 +333,10 @@ static void LoadPlayer(LoadHelper *file, int p)
player.position.last.y = file->nextLE<int32_t>(); player.position.last.y = file->nextLE<int32_t>();
player.position.old.x = file->nextLE<int32_t>(); player.position.old.x = file->nextLE<int32_t>();
player.position.old.y = file->nextLE<int32_t>(); player.position.old.y = file->nextLE<int32_t>();
player.position.offset.x = file->nextLE<int32_t>(); player.position.offset.deltaX = file->nextLE<int32_t>();
player.position.offset.y = file->nextLE<int32_t>(); player.position.offset.deltaY = file->nextLE<int32_t>();
player.position.velocity.x = file->nextLE<int32_t>(); player.position.velocity.deltaX = file->nextLE<int32_t>();
player.position.velocity.y = file->nextLE<int32_t>(); player.position.velocity.deltaY = file->nextLE<int32_t>();
player._pdir = static_cast<Direction>(file->nextLE<int32_t>()); player._pdir = static_cast<Direction>(file->nextLE<int32_t>());
file->skip(4); // Unused file->skip(4); // Unused
player._pgfxnum = file->nextLE<int32_t>(); player._pgfxnum = file->nextLE<int32_t>();
@ -427,8 +427,8 @@ static void LoadPlayer(LoadHelper *file, int p)
player.tempDirection = static_cast<Direction>(file->nextLE<int32_t>()); player.tempDirection = static_cast<Direction>(file->nextLE<int32_t>());
player._pVar4 = file->nextLE<int32_t>(); player._pVar4 = file->nextLE<int32_t>();
player._pVar5 = file->nextLE<int32_t>(); player._pVar5 = file->nextLE<int32_t>();
player.position.offset2.x = file->nextLE<int32_t>(); player.position.offset2.deltaX = file->nextLE<int32_t>();
player.position.offset2.y = file->nextLE<int32_t>(); player.position.offset2.deltaY = file->nextLE<int32_t>();
file->skip(4); // Skip actionFrame file->skip(4); // Skip actionFrame
for (uint8_t i = 0; i < giNumberOfLevels; i++) for (uint8_t i = 0; i < giNumberOfLevels; i++)
player._pLvlVisited[i] = file->nextBool8(); player._pLvlVisited[i] = file->nextBool8();
@ -555,10 +555,10 @@ static void LoadMonster(LoadHelper *file, int i)
pMonster->position.future.y = file->nextLE<int32_t>(); pMonster->position.future.y = file->nextLE<int32_t>();
pMonster->position.old.x = file->nextLE<int32_t>(); pMonster->position.old.x = file->nextLE<int32_t>();
pMonster->position.old.y = file->nextLE<int32_t>(); pMonster->position.old.y = file->nextLE<int32_t>();
pMonster->position.offset.x = file->nextLE<int32_t>(); pMonster->position.offset.deltaX = file->nextLE<int32_t>();
pMonster->position.offset.y = file->nextLE<int32_t>(); pMonster->position.offset.deltaY = file->nextLE<int32_t>();
pMonster->position.velocity.x = file->nextLE<int32_t>(); pMonster->position.velocity.deltaX = file->nextLE<int32_t>();
pMonster->position.velocity.y = file->nextLE<int32_t>(); pMonster->position.velocity.deltaY = file->nextLE<int32_t>();
pMonster->_mdir = static_cast<Direction>(file->nextLE<int32_t>()); pMonster->_mdir = static_cast<Direction>(file->nextLE<int32_t>());
pMonster->_menemy = file->nextLE<int32_t>(); pMonster->_menemy = file->nextLE<int32_t>();
pMonster->enemyPosition.x = file->nextLE<uint8_t>(); pMonster->enemyPosition.x = file->nextLE<uint8_t>();
@ -578,8 +578,8 @@ static void LoadMonster(LoadHelper *file, int i)
pMonster->_mVar3 = file->nextLE<int32_t>(); pMonster->_mVar3 = file->nextLE<int32_t>();
pMonster->position.temp.x = file->nextLE<int32_t>(); pMonster->position.temp.x = file->nextLE<int32_t>();
pMonster->position.temp.y = file->nextLE<int32_t>(); pMonster->position.temp.y = file->nextLE<int32_t>();
pMonster->position.offset2.x = file->nextLE<int32_t>(); pMonster->position.offset2.deltaX = file->nextLE<int32_t>();
pMonster->position.offset2.y = file->nextLE<int32_t>(); pMonster->position.offset2.deltaY = file->nextLE<int32_t>();
file->skip(4); // Skip actionFrame file->skip(4); // Skip actionFrame
pMonster->_mmaxhp = file->nextLE<int32_t>(); pMonster->_mmaxhp = file->nextLE<int32_t>();
pMonster->_mhitpoints = file->nextLE<int32_t>(); pMonster->_mhitpoints = file->nextLE<int32_t>();
@ -647,14 +647,14 @@ static void LoadMissile(LoadHelper *file, int i)
pMissile->_mitype = file->nextLE<int32_t>(); pMissile->_mitype = file->nextLE<int32_t>();
pMissile->position.tile.x = file->nextLE<int32_t>(); pMissile->position.tile.x = file->nextLE<int32_t>();
pMissile->position.tile.y = file->nextLE<int32_t>(); pMissile->position.tile.y = file->nextLE<int32_t>();
pMissile->position.offset.x = file->nextLE<int32_t>(); pMissile->position.offset.deltaX = file->nextLE<int32_t>();
pMissile->position.offset.y = file->nextLE<int32_t>(); pMissile->position.offset.deltaY = file->nextLE<int32_t>();
pMissile->position.velocity.x = file->nextLE<int32_t>(); pMissile->position.velocity.deltaX = file->nextLE<int32_t>();
pMissile->position.velocity.y = file->nextLE<int32_t>(); pMissile->position.velocity.deltaY = file->nextLE<int32_t>();
pMissile->position.start.x = file->nextLE<int32_t>(); pMissile->position.start.x = file->nextLE<int32_t>();
pMissile->position.start.y = file->nextLE<int32_t>(); pMissile->position.start.y = file->nextLE<int32_t>();
pMissile->position.traveled.x = file->nextLE<int32_t>(); pMissile->position.traveled.deltaX = file->nextLE<int32_t>();
pMissile->position.traveled.y = file->nextLE<int32_t>(); pMissile->position.traveled.deltaY = file->nextLE<int32_t>();
pMissile->_mimfnum = file->nextLE<int32_t>(); pMissile->_mimfnum = file->nextLE<int32_t>();
pMissile->_mispllvl = file->nextLE<int32_t>(); pMissile->_mispllvl = file->nextLE<int32_t>();
pMissile->_miDelFlag = file->nextBool32(); pMissile->_miDelFlag = file->nextBool32();
@ -1397,10 +1397,10 @@ static void SavePlayer(SaveHelper *file, int p)
file->writeLE<int32_t>(player.position.last.y); file->writeLE<int32_t>(player.position.last.y);
file->writeLE<int32_t>(player.position.old.x); file->writeLE<int32_t>(player.position.old.x);
file->writeLE<int32_t>(player.position.old.y); file->writeLE<int32_t>(player.position.old.y);
file->writeLE<int32_t>(player.position.offset.x); file->writeLE<int32_t>(player.position.offset.deltaX);
file->writeLE<int32_t>(player.position.offset.y); file->writeLE<int32_t>(player.position.offset.deltaY);
file->writeLE<int32_t>(player.position.velocity.x); file->writeLE<int32_t>(player.position.velocity.deltaX);
file->writeLE<int32_t>(player.position.velocity.y); file->writeLE<int32_t>(player.position.velocity.deltaY);
file->writeLE<int32_t>(player._pdir); file->writeLE<int32_t>(player._pdir);
file->skip(4); // Unused file->skip(4); // Unused
file->writeLE<int32_t>(player._pgfxnum); file->writeLE<int32_t>(player._pgfxnum);
@ -1492,8 +1492,8 @@ static void SavePlayer(SaveHelper *file, int p)
file->writeLE<int32_t>(player.tempDirection); file->writeLE<int32_t>(player.tempDirection);
file->writeLE<int32_t>(player._pVar4); file->writeLE<int32_t>(player._pVar4);
file->writeLE<int32_t>(player._pVar5); file->writeLE<int32_t>(player._pVar5);
file->writeLE<int32_t>(player.position.offset2.x); file->writeLE<int32_t>(player.position.offset2.deltaX);
file->writeLE<int32_t>(player.position.offset2.y); file->writeLE<int32_t>(player.position.offset2.deltaY);
// Write actionFrame for vanilla compatibility // Write actionFrame for vanilla compatibility
file->writeLE<int32_t>(0); file->writeLE<int32_t>(0);
for (uint8_t i = 0; i < giNumberOfLevels; i++) for (uint8_t i = 0; i < giNumberOfLevels; i++)
@ -1612,10 +1612,10 @@ static void SaveMonster(SaveHelper *file, int i)
file->writeLE<int32_t>(pMonster->position.future.y); file->writeLE<int32_t>(pMonster->position.future.y);
file->writeLE<int32_t>(pMonster->position.old.x); file->writeLE<int32_t>(pMonster->position.old.x);
file->writeLE<int32_t>(pMonster->position.old.y); file->writeLE<int32_t>(pMonster->position.old.y);
file->writeLE<int32_t>(pMonster->position.offset.x); file->writeLE<int32_t>(pMonster->position.offset.deltaX);
file->writeLE<int32_t>(pMonster->position.offset.y); file->writeLE<int32_t>(pMonster->position.offset.deltaY);
file->writeLE<int32_t>(pMonster->position.velocity.x); file->writeLE<int32_t>(pMonster->position.velocity.deltaX);
file->writeLE<int32_t>(pMonster->position.velocity.y); file->writeLE<int32_t>(pMonster->position.velocity.deltaY);
file->writeLE<int32_t>(pMonster->_mdir); file->writeLE<int32_t>(pMonster->_mdir);
file->writeLE<int32_t>(pMonster->_menemy); file->writeLE<int32_t>(pMonster->_menemy);
file->writeLE<uint8_t>(pMonster->enemyPosition.x); file->writeLE<uint8_t>(pMonster->enemyPosition.x);
@ -1634,8 +1634,8 @@ static void SaveMonster(SaveHelper *file, int i)
file->writeLE<int32_t>(pMonster->_mVar3); file->writeLE<int32_t>(pMonster->_mVar3);
file->writeLE<int32_t>(pMonster->position.temp.x); file->writeLE<int32_t>(pMonster->position.temp.x);
file->writeLE<int32_t>(pMonster->position.temp.y); file->writeLE<int32_t>(pMonster->position.temp.y);
file->writeLE<int32_t>(pMonster->position.offset2.x); file->writeLE<int32_t>(pMonster->position.offset2.deltaX);
file->writeLE<int32_t>(pMonster->position.offset2.y); file->writeLE<int32_t>(pMonster->position.offset2.deltaY);
// Write actionFrame for vanilla compatibility // Write actionFrame for vanilla compatibility
file->writeLE<int32_t>(0); file->writeLE<int32_t>(0);
file->writeLE<int32_t>(pMonster->_mmaxhp); file->writeLE<int32_t>(pMonster->_mmaxhp);
@ -1692,14 +1692,14 @@ static void SaveMissile(SaveHelper *file, int i)
file->writeLE<int32_t>(pMissile->_mitype); file->writeLE<int32_t>(pMissile->_mitype);
file->writeLE<int32_t>(pMissile->position.tile.x); file->writeLE<int32_t>(pMissile->position.tile.x);
file->writeLE<int32_t>(pMissile->position.tile.y); file->writeLE<int32_t>(pMissile->position.tile.y);
file->writeLE<int32_t>(pMissile->position.offset.x); file->writeLE<int32_t>(pMissile->position.offset.deltaX);
file->writeLE<int32_t>(pMissile->position.offset.y); file->writeLE<int32_t>(pMissile->position.offset.deltaY);
file->writeLE<int32_t>(pMissile->position.velocity.x); file->writeLE<int32_t>(pMissile->position.velocity.deltaX);
file->writeLE<int32_t>(pMissile->position.velocity.y); file->writeLE<int32_t>(pMissile->position.velocity.deltaY);
file->writeLE<int32_t>(pMissile->position.start.x); file->writeLE<int32_t>(pMissile->position.start.x);
file->writeLE<int32_t>(pMissile->position.start.y); file->writeLE<int32_t>(pMissile->position.start.y);
file->writeLE<int32_t>(pMissile->position.traveled.x); file->writeLE<int32_t>(pMissile->position.traveled.deltaX);
file->writeLE<int32_t>(pMissile->position.traveled.y); file->writeLE<int32_t>(pMissile->position.traveled.deltaY);
file->writeLE<int32_t>(pMissile->_mimfnum); file->writeLE<int32_t>(pMissile->_mimfnum);
file->writeLE<int32_t>(pMissile->_mispllvl); file->writeLE<int32_t>(pMissile->_mispllvl);
file->writeLE<uint32_t>(pMissile->_miDelFlag ? 1 : 0); file->writeLE<uint32_t>(pMissile->_miDelFlag ? 1 : 0);

126
Source/missiles.cpp

@ -262,21 +262,21 @@ constexpr Direction16 Direction16Flip(Direction16 x, Direction16 pivot)
*/ */
Direction16 GetDirection16(Point p1, Point p2) Direction16 GetDirection16(Point p1, Point p2)
{ {
Point offset = p2 - p1; Displacement offset = p2 - p1;
Point absolute = abs(offset); Displacement absolute = abs(offset);
bool flipY = offset.x != absolute.x; bool flipY = offset.deltaX != absolute.deltaX;
bool flipX = offset.y != absolute.y; bool flipX = offset.deltaY != absolute.deltaY;
bool flipMedian = false; bool flipMedian = false;
if (absolute.x > absolute.y) { if (absolute.deltaX > absolute.deltaY) {
std::swap(absolute.x, absolute.y); std::swap(absolute.deltaX, absolute.deltaY);
flipMedian = true; flipMedian = true;
} }
Direction16 ret = DIR16_S; Direction16 ret = DIR16_S;
if (3 * absolute.x <= (absolute.y * 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.x < absolute.y) // 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 = DIR16_SW;
else else
ret = DIR16_Sw; ret = DIR16_Sw;
@ -321,8 +321,8 @@ static void GetMissileVel(int i, Point source, Point destination, int v)
double dxp = (destination.x + source.y - source.x - destination.y) * (1 << 21); double dxp = (destination.x + source.y - source.x - destination.y) * (1 << 21);
double dyp = (destination.y + destination.x - source.x - source.y) * (1 << 21); double dyp = (destination.y + destination.x - source.x - source.y) * (1 << 21);
double dr = sqrt(dxp * dxp + dyp * dyp); double dr = sqrt(dxp * dxp + dyp * dyp);
missile[i].position.velocity.x = (dxp * (v << 16)) / dr; missile[i].position.velocity.deltaX = (dxp * (v << 16)) / dr;
missile[i].position.velocity.y = (dyp * (v << 15)) / dr; missile[i].position.velocity.deltaY = (dyp * (v << 15)) / dr;
} }
static void PutMissile(int i) static void PutMissile(int i)
@ -346,8 +346,8 @@ static void GetMissilePos(int i)
{ {
int lx, ly; int lx, ly;
int mx = missile[i].position.traveled.x >> 16; int mx = missile[i].position.traveled.deltaX >> 16;
int my = missile[i].position.traveled.y >> 16; int my = missile[i].position.traveled.deltaY >> 16;
int dx = mx + 2 * my; int dx = mx + 2 * my;
int dy = 2 * my - mx; int dy = 2 * my - mx;
if (dx < 0) { if (dx < 0) {
@ -364,9 +364,9 @@ static void GetMissilePos(int i)
ly = dy / 8; ly = dy / 8;
dy = dy / 64; dy = dy / 64;
} }
missile[i].position.tile = Point { dx, dy } + missile[i].position.start; missile[i].position.tile = missile[i].position.start + Displacement { dx, dy };
missile[i].position.offset.x = mx + (dy * 32) - (dx * 32); missile[i].position.offset.deltaX = mx + (dy * 32) - (dx * 32);
missile[i].position.offset.y = my - (dx * 16) - (dy * 16); missile[i].position.offset.deltaY = my - (dx * 16) - (dy * 16);
ChangeLightOff(missile[i]._mlid, { lx - (dx * 8), ly - (dy * 8) }); ChangeLightOff(missile[i]._mlid, { lx - (dx * 8), ly - (dy * 8) });
} }
@ -413,8 +413,8 @@ void MoveMissilePos(int i)
if (PosOkMonst(missile[i]._misource, { x, y })) { if (PosOkMonst(missile[i]._misource, { x, y })) {
missile[i].position.tile.x += dx; missile[i].position.tile.x += dx;
missile[i].position.tile.y += dy; missile[i].position.tile.y += dy;
missile[i].position.offset.x += (dy * 32) - (dx * 32); missile[i].position.offset.deltaX += (dy * 32) - (dx * 32);
missile[i].position.offset.y -= (dy * 16) + (dx * 16); missile[i].position.offset.deltaY -= (dy * 16) + (dx * 16);
} }
} }
@ -1589,12 +1589,12 @@ void AddWarp(int mi, Point src, Point /*dst*/, int /*midir*/, int8_t mienemy, in
if (trg->_tmsg == 1032 || trg->_tmsg == 1027 || trg->_tmsg == 1026 || trg->_tmsg == 1028) { if (trg->_tmsg == 1032 || trg->_tmsg == 1027 || trg->_tmsg == 1026 || trg->_tmsg == 1028) {
Point candidate = trg->position; Point candidate = trg->position;
if ((leveltype == 1 || leveltype == 2) && (trg->_tmsg == 1026 || trg->_tmsg == 1027 || trg->_tmsg == 1028)) { if ((leveltype == 1 || leveltype == 2) && (trg->_tmsg == 1026 || trg->_tmsg == 1027 || trg->_tmsg == 1028)) {
candidate += Point { 0, 1 }; candidate += Displacement { 0, 1 };
} else { } else {
candidate += Point { 1, 0 }; candidate += Displacement { 1, 0 };
} }
Point off = src - candidate; Displacement off = src - candidate;
int distanceSq = off.y * off.y + off.x * off.x; int distanceSq = off.deltaY * off.deltaY + off.deltaX * off.deltaX;
if (distanceSq < minDistanceSq) { if (distanceSq < minDistanceSq) {
minDistanceSq = distanceSq; minDistanceSq = distanceSq;
tile = candidate; tile = candidate;
@ -1631,8 +1631,8 @@ void AddRuneExplosion(int mi, Point src, Point /*dst*/, int /*midir*/, int8_t mi
missile[mi]._midam = dmg; missile[mi]._midam = dmg;
constexpr Point offsets[] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } }; constexpr Displacement offsets[] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } };
for (Point offset : offsets) for (Displacement offset : offsets)
CheckMissileCol(mi, dmg, dmg, false, missile[mi].position.tile + offset, true); CheckMissileCol(mi, dmg, dmg, false, missile[mi].position.tile + offset, true);
} }
missile[mi]._mlid = AddLight(src, 8); missile[mi]._mlid = AddLight(src, 8);
@ -1980,10 +1980,10 @@ void AddFirebolt(int mi, Point src, Point dst, int midir, int8_t micaster, int i
void AddMagmaball(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/, int /*id*/, int /*dam*/) void AddMagmaball(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/, int /*id*/, int /*dam*/)
{ {
GetMissileVel(mi, src, dst, 16); GetMissileVel(mi, src, dst, 16);
missile[mi].position.traveled.x += 3 * missile[mi].position.velocity.x; missile[mi].position.traveled.deltaX += 3 * missile[mi].position.velocity.deltaX;
missile[mi].position.traveled.y += 3 * missile[mi].position.velocity.y; missile[mi].position.traveled.deltaY += 3 * missile[mi].position.velocity.deltaY;
GetMissilePos(mi); GetMissilePos(mi);
if (!gbIsHellfire || (missile[mi].position.velocity.x & 0xFFFF0000) != 0 || (missile[mi].position.velocity.y & 0xFFFF0000) != 0) if (!gbIsHellfire || (missile[mi].position.velocity.deltaX & 0xFFFF0000) != 0 || (missile[mi].position.velocity.deltaY & 0xFFFF0000) != 0)
missile[mi]._mirange = 256; missile[mi]._mirange = 256;
else else
missile[mi]._mirange = 1; missile[mi]._mirange = 1;
@ -2277,7 +2277,7 @@ void AddFiremove(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/
missile[mi]._miVar2 = 0; missile[mi]._miVar2 = 0;
missile[mi].position.tile.x++; missile[mi].position.tile.x++;
missile[mi].position.tile.y++; missile[mi].position.tile.y++;
missile[mi].position.offset.y -= 32; missile[mi].position.offset.deltaY -= 32;
} }
void AddGuardian(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/, int id, int /*dam*/) void AddGuardian(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/, int id, int /*dam*/)
@ -2452,7 +2452,7 @@ void AddAcid(int mi, Point src, Point dst, int /*midir*/, int8_t /*mienemy*/, in
{ {
GetMissileVel(mi, src, dst, 16); GetMissileVel(mi, src, dst, 16);
SetMissDir(mi, GetDirection16(src, dst)); SetMissDir(mi, GetDirection16(src, dst));
if ((!gbIsHellfire && (missile[mi].position.velocity.x & 0xFFFF0000) != 0) || (missile[mi].position.velocity.y & 0xFFFF0000) != 0) if ((!gbIsHellfire && (missile[mi].position.velocity.deltaX & 0xFFFF0000) != 0) || (missile[mi].position.velocity.deltaY & 0xFFFF0000) != 0)
missile[mi]._mirange = 5 * (monster[id]._mint + 4); missile[mi]._mirange = 5 * (monster[id]._mint + 4);
else else
missile[mi]._mirange = 1; missile[mi]._mirange = 1;
@ -3161,8 +3161,8 @@ void MI_LArrow(int i)
} }
if (missile[i]._mirange == 0) { if (missile[i]._mirange == 0) {
missile[i]._mimfnum = 0; missile[i]._mimfnum = 0;
missile[i].position.traveled.x -= missile[i].position.velocity.x; missile[i].position.traveled.deltaX -= missile[i].position.velocity.deltaX;
missile[i].position.traveled.y -= missile[i].position.velocity.y; missile[i].position.traveled.deltaY -= missile[i].position.velocity.deltaY;
GetMissilePos(i); GetMissilePos(i);
if (missile[i]._mitype == MIS_LARROW) if (missile[i]._mitype == MIS_LARROW)
SetMissAnim(i, MFILE_MINILTNG); SetMissAnim(i, MFILE_MINILTNG);
@ -3219,8 +3219,8 @@ void MI_Firebolt(int i)
missile[i]._mirange--; missile[i]._mirange--;
if (missile[i]._mitype != MIS_BONESPIRIT || missile[i]._mimfnum != 8) { if (missile[i]._mitype != MIS_BONESPIRIT || missile[i]._mimfnum != 8) {
omx = missile[i].position.traveled.x; omx = missile[i].position.traveled.deltaX;
omy = missile[i].position.traveled.y; omy = missile[i].position.traveled.deltaY;
missile[i].position.traveled += missile[i].position.velocity; missile[i].position.traveled += missile[i].position.velocity;
GetMissilePos(i); GetMissilePos(i);
p = missile[i]._misource; p = missile[i]._misource;
@ -3392,7 +3392,7 @@ void MI_Firewall(int i)
PutMissile(i); PutMissile(i);
} }
static void FireballUpdate(int i, Point offset, bool alwaysDelete) static void FireballUpdate(int i, Displacement offset, bool alwaysDelete)
{ {
missile[i]._mirange--; missile[i]._mirange--;
@ -3414,27 +3414,27 @@ static void FireballUpdate(int i, Point offset, bool alwaysDelete)
Point m = missile[i].position.tile; Point m = missile[i].position.tile;
ChangeLight(missile[i]._mlid, missile[i].position.tile, missile[i]._miAnimFrame); ChangeLight(missile[i]._mlid, missile[i].position.tile, missile[i]._miAnimFrame);
constexpr Point Offsets[] = { { 0, 0 }, { 0, 1 }, { 0, -1 }, { 1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 0 }, { -1, 1 }, { -1, -1 } }; constexpr Displacement Offsets[] = { { 0, 0 }, { 0, 1 }, { 0, -1 }, { 1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 0 }, { -1, 1 }, { -1, -1 } };
for (Point offset : Offsets) { for (Displacement offset : Offsets) {
if (!CheckBlock(p, m + offset)) if (!CheckBlock(p, m + offset))
CheckMissileCol(i, dam, dam, false, m + offset, true); CheckMissileCol(i, dam, dam, false, m + offset, true);
} }
if (!TransList[dTransVal[m.x][m.y]] if (!TransList[dTransVal[m.x][m.y]]
|| (missile[i].position.velocity.x < 0 && ((TransList[dTransVal[m.x][m.y + 1]] && nSolidTable[dPiece[m.x][m.y + 1]]) || (TransList[dTransVal[m.x][m.y - 1]] && nSolidTable[dPiece[m.x][m.y - 1]])))) { || (missile[i].position.velocity.deltaX < 0 && ((TransList[dTransVal[m.x][m.y + 1]] && nSolidTable[dPiece[m.x][m.y + 1]]) || (TransList[dTransVal[m.x][m.y - 1]] && nSolidTable[dPiece[m.x][m.y - 1]])))) {
missile[i].position.tile.x++; missile[i].position.tile.x++;
missile[i].position.tile.y++; missile[i].position.tile.y++;
missile[i].position.offset.y -= 32; missile[i].position.offset.deltaY -= 32;
} }
if (missile[i].position.velocity.y > 0 if (missile[i].position.velocity.deltaY > 0
&& ((TransList[dTransVal[m.x + 1][m.y]] && nSolidTable[dPiece[m.x + 1][m.y]]) && ((TransList[dTransVal[m.x + 1][m.y]] && nSolidTable[dPiece[m.x + 1][m.y]])
|| (TransList[dTransVal[m.x - 1][m.y]] && nSolidTable[dPiece[m.x - 1][m.y]]))) { || (TransList[dTransVal[m.x - 1][m.y]] && nSolidTable[dPiece[m.x - 1][m.y]]))) {
missile[i].position.offset.y -= 32; missile[i].position.offset.deltaY -= 32;
} }
if (missile[i].position.velocity.x > 0 if (missile[i].position.velocity.deltaX > 0
&& ((TransList[dTransVal[m.x][m.y + 1]] && nSolidTable[dPiece[m.x][m.y + 1]]) && ((TransList[dTransVal[m.x][m.y + 1]] && nSolidTable[dPiece[m.x][m.y + 1]])
|| (TransList[dTransVal[m.x][m.y - 1]] && nSolidTable[dPiece[m.x][m.y - 1]]))) { || (TransList[dTransVal[m.x][m.y - 1]] && nSolidTable[dPiece[m.x][m.y - 1]]))) {
missile[i].position.offset.x -= 32; missile[i].position.offset.deltaX -= 32;
} }
missile[i]._mimfnum = 0; missile[i]._mimfnum = 0;
SetMissAnim(i, MFILE_BIGEXP); SetMissAnim(i, MFILE_BIGEXP);
@ -3554,16 +3554,16 @@ void MI_Immolation(int i)
missile[i]._miVar7--; missile[i]._miVar7--;
} }
Point offset = missile[i].position.velocity; Displacement offset = missile[i].position.velocity;
switch (missile[i]._mimfnum) { switch (missile[i]._mimfnum) {
case DIR_S: case DIR_S:
case DIR_N: case DIR_N:
offset.y = 0; offset.deltaY = 0;
break; break;
case DIR_W: case DIR_W:
case DIR_E: case DIR_E:
offset.x = 0; offset.deltaX = 0;
break; break;
default: default:
break; break;
@ -3647,8 +3647,8 @@ void MI_FlashFront(int i)
int src = missile[i]._misource; int src = missile[i]._misource;
if (missile[i]._micaster == TARGET_MONSTERS && src != -1) { if (missile[i]._micaster == TARGET_MONSTERS && src != -1) {
missile[i].position.tile = plr[src].position.tile; missile[i].position.tile = plr[src].position.tile;
missile[i].position.traveled.x = plr[src].position.offset.x << 16; missile[i].position.traveled.deltaX = plr[src].position.offset.deltaX << 16;
missile[i].position.traveled.y = plr[src].position.offset.y << 16; missile[i].position.traveled.deltaY = plr[src].position.offset.deltaY << 16;
} }
missile[i]._mirange--; missile[i]._mirange--;
if (missile[i]._mirange == 0) { if (missile[i]._mirange == 0) {
@ -3803,8 +3803,8 @@ void MI_FireNova(int i)
} }
for (const auto &k : vCrawlTable) { for (const auto &k : vCrawlTable) {
if (sx1 != k[6] || sy1 != k[7]) { if (sx1 != k[6] || sy1 != k[7]) {
Point offsets[] = { { k[6], k[7] }, { -k[6], -k[7] }, { -k[6], +k[7] }, { +k[6], -k[7] } }; Displacement offsets[] = { { k[6], k[7] }, { -k[6], -k[7] }, { -k[6], +k[7] }, { +k[6], -k[7] } };
for (Point offset : offsets) for (Displacement offset : offsets)
AddMissile(src, src + offset, dir, MIS_FIRENOVA, en, id, dam, missile[i]._mispllvl); AddMissile(src, src + offset, dir, MIS_FIRENOVA, en, id, dam, missile[i]._mispllvl);
sx1 = k[6]; sx1 = k[6];
sy1 = k[7]; sy1 = k[7];
@ -3992,8 +3992,8 @@ void MI_Flash(int i)
} }
missile[i]._mirange--; missile[i]._mirange--;
constexpr Point Offsets[] = { { -1, 0 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } }; constexpr Displacement Offsets[] = { { -1, 0 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } };
for (Point offset : Offsets) for (Displacement offset : Offsets)
CheckMissileCol(i, missile[i]._midam, missile[i]._midam, true, missile[i].position.tile + offset, true); CheckMissileCol(i, missile[i]._midam, missile[i]._midam, true, missile[i].position.tile + offset, true);
if (missile[i]._mirange == 0) { if (missile[i]._mirange == 0) {
@ -4014,8 +4014,8 @@ void MI_Flash2(int i)
} }
missile[i]._mirange--; missile[i]._mirange--;
constexpr Point Offsets[] = { { -1, -1 }, { 0, -1 }, { 1, -1 } }; constexpr Displacement Offsets[] = { { -1, -1 }, { 0, -1 }, { 1, -1 } };
for (Point offset : Offsets) for (Displacement offset : Offsets)
CheckMissileCol(i, missile[i]._midam, missile[i]._midam, true, missile[i].position.tile + offset, true); CheckMissileCol(i, missile[i]._midam, missile[i]._midam, true, missile[i].position.tile + offset, true);
if (missile[i]._mirange == 0) { if (missile[i]._mirange == 0) {
@ -4053,8 +4053,8 @@ void MI_Etherealize(int i)
auto &player = plr[missile[i]._misource]; auto &player = plr[missile[i]._misource];
missile[i].position.tile = player.position.tile; missile[i].position.tile = player.position.tile;
missile[i].position.traveled.x = player.position.offset.x << 16; missile[i].position.traveled.deltaX = player.position.offset.deltaX << 16;
missile[i].position.traveled.y = player.position.offset.y << 16; missile[i].position.traveled.deltaY = player.position.offset.deltaY << 16;
if (player._pmode == PM_WALK3) { if (player._pmode == PM_WALK3) {
missile[i].position.start = player.position.future; missile[i].position.start = player.position.future;
} else { } else {
@ -4082,7 +4082,7 @@ void MI_Firemove(int i)
missile[i].position.tile.x--; missile[i].position.tile.x--;
missile[i].position.tile.y--; missile[i].position.tile.y--;
missile[i].position.offset.y += 32; missile[i].position.offset.deltaY += 32;
missile[i]._miVar1++; missile[i]._miVar1++;
if (missile[i]._miVar1 == missile[i]._miAnimLen) { if (missile[i]._miVar1 == missile[i]._miAnimLen) {
SetMissDir(i, 1); SetMissDir(i, 1);
@ -4112,7 +4112,7 @@ void MI_Firemove(int i)
} }
missile[i].position.tile.x++; missile[i].position.tile.x++;
missile[i].position.tile.y++; missile[i].position.tile.y++;
missile[i].position.offset.y -= 32; missile[i].position.offset.deltaY -= 32;
PutMissile(i); PutMissile(i);
} }
@ -4289,7 +4289,7 @@ void MI_Acidsplat(int i)
if (missile[i]._mirange == missile[i]._miAnimLen) { if (missile[i]._mirange == missile[i]._miAnimLen) {
missile[i].position.tile.x++; missile[i].position.tile.x++;
missile[i].position.tile.y++; missile[i].position.tile.y++;
missile[i].position.offset.y -= 32; missile[i].position.offset.deltaY -= 32;
} }
missile[i]._mirange--; missile[i]._mirange--;
if (missile[i]._mirange == 0) { if (missile[i]._mirange == 0) {
@ -4579,10 +4579,10 @@ void MI_Nova(int i)
} }
for (const auto &k : vCrawlTable) { for (const auto &k : vCrawlTable) {
if (sx1 != k[6] || sy1 != k[7]) { if (sx1 != k[6] || sy1 != k[7]) {
AddMissile(src, src + Point { k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); AddMissile(src, src + Displacement { k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
AddMissile(src, src + Point { -k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); AddMissile(src, src + Displacement { -k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
AddMissile(src, src + Point { -k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); AddMissile(src, src + Displacement { -k[6], k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
AddMissile(src, src + Point { k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl); AddMissile(src, src + Displacement { k[6], -k[7] }, dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
sx1 = k[6]; sx1 = k[6];
sy1 = k[7]; sy1 = k[7];
} }
@ -4769,8 +4769,8 @@ void MI_Element(int i)
if (!CheckBlock(p, c)) if (!CheckBlock(p, c))
CheckMissileCol(i, dam, dam, true, c, true); CheckMissileCol(i, dam, dam, true, c, true);
constexpr Point Offsets[] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 0 }, { -1, 1 }, { -1, -1 } }; constexpr Displacement Offsets[] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 0 }, { -1, 1 }, { -1, -1 } };
for (Point offset : Offsets) { for (Displacement offset : Offsets) {
if (!CheckBlock(p, c + offset)) if (!CheckBlock(p, c + offset))
CheckMissileCol(i, dam, dam, true, c + offset, true); CheckMissileCol(i, dam, dam, true, c + offset, true);
} }

6
Source/missiles.h

@ -26,13 +26,13 @@ struct ChainStruct {
struct MissilePosition { struct MissilePosition {
Point tile; Point tile;
/** Sprite's pixel offset from tile. */ /** Sprite's pixel offset from tile. */
Point offset; Displacement offset;
/** Pixel velocity while moving */ /** Pixel velocity while moving */
Point velocity; Displacement velocity;
/** Start position */ /** Start position */
Point start; Point start;
/** Start position */ /** Start position */
Point traveled; Displacement traveled;
}; };

24
Source/monster.cpp

@ -1129,7 +1129,7 @@ void InitMonsters()
for (i = 0; i < nt; i++) { for (i = 0; i < nt; i++) {
for (s = -2; s < 2; s++) { for (s = -2; s < 2; s++) {
for (t = -2; t < 2; t++) for (t = -2; t < 2; t++)
DoVision(Point { s, t } + trigs[i].position, 15, false, false); DoVision(trigs[i].position + Displacement { s, t }, 15, false, false);
} }
} }
if (!gbIsSpawn) if (!gbIsSpawn)
@ -1170,7 +1170,7 @@ void InitMonsters()
for (i = 0; i < nt; i++) { for (i = 0; i < nt; i++) {
for (s = -2; s < 2; s++) { for (s = -2; s < 2; s++) {
for (t = -2; t < 2; t++) for (t = -2; t < 2; t++)
DoUnVision(Point { s, t } + trigs[i].position, 15); DoUnVision(trigs[i].position + Displacement { s, t }, 15);
} }
} }
} }
@ -1653,7 +1653,7 @@ void M_DiabloDeath(int i, bool sendmsg)
Monst->_mVar3 = ViewX << 16; Monst->_mVar3 = ViewX << 16;
Monst->position.temp.x = ViewY << 16; Monst->position.temp.x = ViewY << 16;
Monst->position.temp.y = (int)((Monst->_mVar3 - (Monst->position.tile.x << 16)) / (double)dist); Monst->position.temp.y = (int)((Monst->_mVar3 - (Monst->position.tile.x << 16)) / (double)dist);
Monst->position.offset2.x = (int)((Monst->position.temp.x - (Monst->position.tile.y << 16)) / (double)dist); Monst->position.offset2.deltaX = (int)((Monst->position.temp.x - (Monst->position.tile.y << 16)) / (double)dist);
} }
void SpawnLoot(int i, bool sendmsg) void SpawnLoot(int i, bool sendmsg)
@ -1663,7 +1663,7 @@ void SpawnLoot(int i, bool sendmsg)
Monst = &monster[i]; Monst = &monster[i];
if (QuestStatus(Q_GARBUD) && Monst->_uniqtype - 1 == UMT_GARBUD) { if (QuestStatus(Q_GARBUD) && Monst->_uniqtype - 1 == UMT_GARBUD) {
CreateTypeItem(Monst->position.tile + Point { 1, 1 }, true, ITYPE_MACE, IMISC_NONE, true, false); CreateTypeItem(Monst->position.tile + Displacement { 1, 1 }, true, ITYPE_MACE, IMISC_NONE, true, false);
} else if (Monst->_uniqtype - 1 == UMT_DEFILER) { } else if (Monst->_uniqtype - 1 == UMT_DEFILER) {
if (effect_is_playing(USFX_DEFILER8)) if (effect_is_playing(USFX_DEFILER8))
stream_stop(); stream_stop();
@ -1914,8 +1914,8 @@ void M_ChangeLightOffset(int monst)
assurance((DWORD)monst < MAXMONSTERS, monst); assurance((DWORD)monst < MAXMONSTERS, monst);
lx = monster[monst].position.offset.x + 2 * monster[monst].position.offset.y; lx = monster[monst].position.offset.deltaX + 2 * monster[monst].position.offset.deltaY;
ly = 2 * monster[monst].position.offset.y - monster[monst].position.offset.x; ly = 2 * monster[monst].position.offset.deltaY - monster[monst].position.offset.deltaX;
if (lx < 0) { if (lx < 0) {
sign = -1; sign = -1;
@ -1996,8 +1996,8 @@ bool M_DoWalk(int i, int variant)
if (monster[i].AnimInfo.CurrentFrame == 0 && monster[i].MType->mtype == MT_FLESTHNG) if (monster[i].AnimInfo.CurrentFrame == 0 && monster[i].MType->mtype == MT_FLESTHNG)
PlayEffect(i, 3); PlayEffect(i, 3);
monster[i].position.offset2 += monster[i].position.velocity; monster[i].position.offset2 += monster[i].position.velocity;
monster[i].position.offset.x = monster[i].position.offset2.x >> 4; monster[i].position.offset.deltaX = monster[i].position.offset2.deltaX >> 4;
monster[i].position.offset.y = monster[i].position.offset2.y >> 4; monster[i].position.offset.deltaY = monster[i].position.offset2.deltaY >> 4;
} }
returnValue = false; returnValue = false;
} }
@ -2408,7 +2408,7 @@ bool M_DoTalk(int i)
quests[Q_GARBUD]._qlog = true; // BUGFIX: (?) for other quests qactive and qlog go together, maybe this should actually go into the if above (fixed) quests[Q_GARBUD]._qlog = true; // BUGFIX: (?) for other quests qactive and qlog go together, maybe this should actually go into the if above (fixed)
} }
if (monster[i].mtalkmsg == TEXT_GARBUD2 && (monster[i]._mFlags & MFLAG_QUEST_COMPLETE) == 0) { if (monster[i].mtalkmsg == TEXT_GARBUD2 && (monster[i]._mFlags & MFLAG_QUEST_COMPLETE) == 0) {
SpawnItem(i, monster[i].position.tile + Point { 1, 1 }, true); SpawnItem(i, monster[i].position.tile + Displacement { 1, 1 }, true);
monster[i]._mFlags |= MFLAG_QUEST_COMPLETE; monster[i]._mFlags |= MFLAG_QUEST_COMPLETE;
} }
} }
@ -2417,7 +2417,7 @@ bool M_DoTalk(int i)
&& (monster[i]._mFlags & MFLAG_QUEST_COMPLETE) == 0) { && (monster[i]._mFlags & MFLAG_QUEST_COMPLETE) == 0) {
quests[Q_ZHAR]._qactive = QUEST_ACTIVE; quests[Q_ZHAR]._qactive = QUEST_ACTIVE;
quests[Q_ZHAR]._qlog = true; quests[Q_ZHAR]._qlog = true;
CreateTypeItem(monster[i].position.tile + Point { 1, 1 }, false, ITYPE_MISC, IMISC_BOOK, true, false); CreateTypeItem(monster[i].position.tile + Displacement { 1, 1 }, false, ITYPE_MISC, IMISC_BOOK, true, false);
monster[i]._mFlags |= MFLAG_QUEST_COMPLETE; monster[i]._mFlags |= MFLAG_QUEST_COMPLETE;
} }
if (monster[i]._uniqtype - 1 == UMT_SNOTSPIL) { if (monster[i]._uniqtype - 1 == UMT_SNOTSPIL) {
@ -3607,7 +3607,7 @@ void MAI_Scav(int i)
done = dDead[Monst->position.tile.x + x][Monst->position.tile.y + y] != 0 done = dDead[Monst->position.tile.x + x][Monst->position.tile.y + y] != 0
&& LineClearSolid( && LineClearSolid(
Monst->position.tile, Monst->position.tile,
Monst->position.tile + Point { x, y }); Monst->position.tile + Displacement { x, y });
} }
} }
x--; x--;
@ -3621,7 +3621,7 @@ void MAI_Scav(int i)
done = dDead[Monst->position.tile.x + x][Monst->position.tile.y + y] != 0 done = dDead[Monst->position.tile.x + x][Monst->position.tile.y + y] != 0
&& LineClearSolid( && LineClearSolid(
Monst->position.tile, Monst->position.tile,
Monst->position.tile + Point { x, y }); Monst->position.tile + Displacement { x, y });
} }
} }
x++; x++;

6
Source/objects.cpp

@ -2953,7 +2953,7 @@ void OperateBook(int pnum, int i)
InitDiabloMsg(EMSG_BONECHAMB); InitDiabloMsg(EMSG_BONECHAMB);
AddMissile( AddMissile(
plr[pnum].position.tile, plr[pnum].position.tile,
object[i].position + Point { -2, -4 }, object[i].position + Displacement { -2, -4 },
plr[pnum]._pdir, plr[pnum]._pdir,
MIS_GUARDIAN, MIS_GUARDIAN,
TARGET_MONSTERS, TARGET_MONSTERS,
@ -3003,7 +3003,7 @@ void OperateBookLever(int pnum, int i)
if (object[i]._otype != OBJ_BLOODBOOK) if (object[i]._otype != OBJ_BLOODBOOK)
ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4);
if (object[i]._otype == OBJ_BLINDBOOK) { if (object[i]._otype == OBJ_BLINDBOOK) {
SpawnUnique(UITEM_OPTAMULET, Point { x, y } + Point { 5, 5 }); SpawnUnique(UITEM_OPTAMULET, Point { x, y } + Displacement { 5, 5 });
tren = TransVal; tren = TransVal;
TransVal = 9; TransVal = 9;
DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); DRLG_MRectTrans(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4);
@ -3299,7 +3299,7 @@ void OperatePedistal(int pnum, int i)
PlaySfxLoc(LS_BLODSTAR, object[i].position); PlaySfxLoc(LS_BLODSTAR, object[i].position);
ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4); ObjChangeMap(object[i]._oVar1, object[i]._oVar2, object[i]._oVar3, object[i]._oVar4);
LoadMapObjs("Levels\\L2Data\\Blood2.DUN", 2 * setpc_x, 2 * setpc_y); LoadMapObjs("Levels\\L2Data\\Blood2.DUN", 2 * setpc_x, 2 * setpc_y);
SpawnUnique(UITEM_ARMOFVAL, Point { setpc_x, setpc_y } * 2 + Point { 25, 19 }); SpawnUnique(UITEM_ARMOFVAL, Point { setpc_x, setpc_y } * 2 + Displacement { 25, 19 });
object[i]._oSelFlag = 0; object[i]._oSelFlag = 0;
} }
} }

43
Source/player.cpp

@ -33,9 +33,9 @@ namespace {
struct DirectionSettings { struct DirectionSettings {
Direction dir; Direction dir;
Point tileAdd; Displacement tileAdd;
Point offset; Displacement offset;
Point map; Displacement map;
_scroll_direction scrollDir; _scroll_direction scrollDir;
PLR_MODE walkMode; PLR_MODE walkMode;
void (*walkModeHandler)(int, const DirectionSettings &); void (*walkModeHandler)(int, const DirectionSettings &);
@ -47,8 +47,8 @@ void PM_ChangeLightOff(PlayerStruct &player)
return; return;
const LightListStruct *l = &LightList[player._plid]; const LightListStruct *l = &LightList[player._plid];
int x = 2 * player.position.offset.y + player.position.offset.x; int x = 2 * player.position.offset.deltaY + player.position.offset.deltaX;
int y = 2 * player.position.offset.y - player.position.offset.x; int y = 2 * player.position.offset.deltaY - player.position.offset.deltaX;
x = (x / 8) * (x < 0 ? 1 : -1); x = (x / 8) * (x < 0 ? 1 : -1);
y = (y / 8) * (y < 0 ? 1 : -1); y = (y / 8) * (y < 0 ? 1 : -1);
@ -67,7 +67,7 @@ void WalkUpwards(int pnum, const DirectionSettings &walkParams)
{ {
auto &player = plr[pnum]; auto &player = plr[pnum];
dPlayer[player.position.future.x][player.position.future.y] = -(pnum + 1); dPlayer[player.position.future.x][player.position.future.y] = -(pnum + 1);
player.position.temp = walkParams.tileAdd; player.position.temp = { walkParams.tileAdd.deltaX, walkParams.tileAdd.deltaY };
} }
void WalkDownwards(int pnum, const DirectionSettings & /*walkParams*/) void WalkDownwards(int pnum, const DirectionSettings & /*walkParams*/)
@ -85,7 +85,7 @@ void WalkSides(int pnum, const DirectionSettings &walkParams)
{ {
auto &player = plr[pnum]; auto &player = plr[pnum];
Point const nextPosition = walkParams.map + player.position.tile; Point const nextPosition = player.position.tile + walkParams.map;
dPlayer[player.position.tile.x][player.position.tile.y] = -(pnum + 1); dPlayer[player.position.tile.x][player.position.tile.y] = -(pnum + 1);
dPlayer[player.position.future.x][player.position.future.y] = -(pnum + 1); dPlayer[player.position.future.x][player.position.future.y] = -(pnum + 1);
@ -156,7 +156,7 @@ bool PlrDirOK(int pnum, Direction dir)
return true; return true;
} }
void HandleWalkMode(int pnum, Point vel, Direction dir) void HandleWalkMode(int pnum, Displacement vel, Direction dir)
{ {
auto &player = plr[pnum]; auto &player = plr[pnum];
const auto &dirModeParams = directionSettings[dir]; const auto &dirModeParams = directionSettings[dir];
@ -167,7 +167,7 @@ void HandleWalkMode(int pnum, Point vel, Direction dir)
player.position.offset = dirModeParams.offset; // Offset player sprite to align with their previous tile position player.position.offset = dirModeParams.offset; // Offset player sprite to align with their previous tile position
//The player's tile position after finishing this movement action //The player's tile position after finishing this movement action
player.position.future = dirModeParams.tileAdd + player.position.tile; player.position.future = player.position.tile + dirModeParams.tileAdd;
dirModeParams.walkModeHandler(pnum, dirModeParams); dirModeParams.walkModeHandler(pnum, dirModeParams);
@ -192,7 +192,7 @@ void StartWalkAnimation(PlayerStruct &player, Direction dir, bool pmWillBeCalled
/** /**
* @brief Start moving a player to a new tile * @brief Start moving a player to a new tile
*/ */
void StartWalk(int pnum, Point vel, Direction dir, bool pmWillBeCalled) void StartWalk(int pnum, Displacement vel, Direction dir, bool pmWillBeCalled)
{ {
auto &player = plr[pnum]; auto &player = plr[pnum];
@ -1224,7 +1224,7 @@ void InitPlayer(int pnum, bool FirstTime)
player.position.tile = { ViewX, ViewY }; player.position.tile = { ViewX, ViewY };
} }
} else { } else {
for (i = 0; i < 8 && !PosOkPlayer(pnum, Point { plrxoff2[i], plryoff2[i] } + player.position.tile); i++) for (i = 0; i < 8 && !PosOkPlayer(pnum, player.position.tile + Displacement { plrxoff2[i], plryoff2[i] }); i++)
; ;
player.position.tile.x += plrxoff2[i]; player.position.tile.x += plrxoff2[i];
player.position.tile.y += plryoff2[i]; player.position.tile.y += plryoff2[i];
@ -1396,8 +1396,8 @@ void PM_ChangeOffset(int pnum)
} }
auto &player = plr[pnum]; auto &player = plr[pnum];
int px = player.position.offset2.x / 256; int px = player.position.offset2.deltaX / 256;
int py = player.position.offset2.y / 256; int py = player.position.offset2.deltaY / 256;
player.position.offset2 += player.position.velocity; player.position.offset2 += player.position.velocity;
@ -1405,14 +1405,13 @@ void PM_ChangeOffset(int pnum)
player.position.offset2 += player.position.velocity; player.position.offset2 += player.position.velocity;
} }
player.position.offset = { player.position.offset2.x >> 8, player.position.offset2.y >> 8 }; player.position.offset = { player.position.offset2.deltaX >> 8, player.position.offset2.deltaY >> 8 };
px -= player.position.offset2.x >> 8; px -= player.position.offset2.deltaX >> 8;
py -= player.position.offset2.y >> 8; py -= player.position.offset2.deltaY >> 8;
if (pnum == myplr && ScrollInfo._sdir != SDIR_NONE) { if (pnum == myplr && ScrollInfo._sdir != SDIR_NONE) {
ScrollInfo.offset.x += px; ScrollInfo.offset += { px, py };
ScrollInfo.offset.y += py;
} }
PM_ChangeLightOff(player); PM_ChangeLightOff(player);
@ -1676,7 +1675,7 @@ static void PlrDeadItem(PlayerStruct &player, ItemStruct *itm, Displacement dire
for (int k = 1; k < 50; k++) { for (int k = 1; k < 50; k++) {
for (int j = -k; j <= k; j++) { for (int j = -k; j <= k; j++) {
for (int i = -k; i <= k; i++) { for (int i = -k; i <= k; i++) {
Point target = Point { i, j } + player.position.tile; Point target = player.position.tile + Displacement { i, j };
if (ItemSpaceOk(target)) { if (ItemSpaceOk(target)) {
RespawnDeadItem(itm, target); RespawnDeadItem(itm, target);
player.HoldItem = *itm; player.HoldItem = *itm;
@ -2104,7 +2103,7 @@ bool PM_DoWalk(int pnum, int variant)
switch (variant) { switch (variant) {
case PM_WALK: case PM_WALK:
dPlayer[player.position.tile.x][player.position.tile.y] = 0; dPlayer[player.position.tile.x][player.position.tile.y] = 0;
player.position.tile += player.position.temp; player.position.tile += { player.position.temp.x, player.position.temp.y };
dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1; dPlayer[player.position.tile.x][player.position.tile.y] = pnum + 1;
break; break;
case PM_WALK2: case PM_WALK2:
@ -2736,7 +2735,7 @@ bool PM_DoRangeAttack(int pnum)
AddMissile( AddMissile(
player.position.tile, player.position.tile,
player.position.temp + Point { xoff, yoff }, player.position.temp + Displacement { xoff, yoff },
player._pdir, player._pdir,
mistype, mistype,
TARGET_MONSTERS, TARGET_MONSTERS,
@ -3705,7 +3704,7 @@ void SyncInitPlrPos(int pnum)
Point position = {}; Point position = {};
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
position = player.position.tile + Point { plrxoff2[i], plryoff2[i] }; position = player.position.tile + Displacement { plrxoff2[i], plryoff2[i] };
if (PosOkPlayer(pnum, position)) { if (PosOkPlayer(pnum, position)) {
break; break;
} }

40
Source/scrollrt.cpp

@ -127,25 +127,25 @@ const char *const szPlrModeAssert[] = {
"quitting" "quitting"
}; };
Point GetOffsetForWalking(const AnimationInfo &animationInfo, const Direction dir, bool cameraMode /*= false*/) Displacement GetOffsetForWalking(const AnimationInfo &animationInfo, const Direction dir, bool cameraMode /*= false*/)
{ {
// clang-format off // clang-format off
// DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_N, DIR_NE, DIR_E, DIR_SE, // DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_N, DIR_NE, DIR_E, DIR_SE,
constexpr Point startOffset[8] = { { 0, -32 }, { 32, -16 }, { 32, -16 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { -32, -16 }, { -32, -16 } }; constexpr Displacement startOffset[8] = { { 0, -32 }, { 32, -16 }, { 32, -16 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { -32, -16 }, { -32, -16 } };
constexpr Point movingOffset[8] = { { 0, 32 }, { -32, 16 }, { -64, 0 }, { -32, -16 }, { 0, -32 }, { 32, -16 }, { 64, 0 }, { 32, 16 } }; constexpr Displacement movingOffset[8] = { { 0, 32 }, { -32, 16 }, { -64, 0 }, { -32, -16 }, { 0, -32 }, { 32, -16 }, { 64, 0 }, { 32, 16 } };
constexpr bool isDiagionalWalk[8] = { false, true, false, true, false, true, false, true }; constexpr bool isDiagionalWalk[8] = { false, true, false, true, false, true, false, true };
// clang-format on // clang-format on
float fAnimationProgress = animationInfo.GetAnimationProgress(); float fAnimationProgress = animationInfo.GetAnimationProgress();
Point offset = movingOffset[dir]; Displacement offset = movingOffset[dir];
offset *= fAnimationProgress; offset *= fAnimationProgress;
// In diagonal walks the offset for y is smaller than x. // In diagonal walks the offset for y is smaller than x.
// This means that sometimes x is updated but y not. // This means that sometimes x is updated but y not.
// That results in a small stuttering. // That results in a small stuttering.
// To fix this we disallow odd x as this is the only case where y is not updated. // To fix this we disallow odd x as this is the only case where y is not updated.
if (isDiagionalWalk[dir] && ((offset.x % 2) != 0)) { if (isDiagionalWalk[dir] && ((offset.deltaX % 2) != 0)) {
offset.x -= offset.x > 0 ? 1 : -1; offset.deltaX -= offset.deltaX > 0 ? 1 : -1;
} }
if (cameraMode) { if (cameraMode) {
@ -229,7 +229,7 @@ static void DrawCursor(const CelOutputBuffer &out)
Clip(sgdwCursY, sgdwCursHgt, out.h()); Clip(sgdwCursY, sgdwCursHgt, out.h());
BlitCursor(sgSaveBack, sgdwCursWdt, out.at(sgdwCursX, sgdwCursY), out.pitch()); BlitCursor(sgSaveBack, sgdwCursWdt, out.at(sgdwCursX, sgdwCursY), out.pitch());
CelDrawCursor(out, MousePosition + Point { 0, cursH - 1 }, pcurs); CelDrawCursor(out, MousePosition + Displacement { 0, cursH - 1 }, pcurs);
} }
/** /**
@ -256,8 +256,8 @@ void DrawMissilePrivate(const CelOutputBuffer &out, MissileStruct *m, int sx, in
Log("Draw Missile 2: frame {} of {}, missile type=={}", nCel, frames, m->_mitype); Log("Draw Missile 2: frame {} of {}, missile type=={}", nCel, frames, m->_mitype);
return; return;
} }
int mx = sx + m->position.offset.x - m->_miAnimWidth2; int mx = sx + m->position.offset.deltaX - m->_miAnimWidth2;
int my = sy + m->position.offset.y; int my = sy + m->position.offset.deltaY;
CelSprite cel { m->_miAnimData, m->_miAnimWidth }; CelSprite cel { m->_miAnimData, m->_miAnimWidth };
if (m->_miUniqTrans != 0) if (m->_miUniqTrans != 0)
Cl2DrawLightTbl(out, mx, my, cel, m->_miAnimFrame, m->_miUniqTrans + 3); Cl2DrawLightTbl(out, mx, my, cel, m->_miAnimFrame, m->_miUniqTrans + 3);
@ -485,8 +485,8 @@ void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy)
auto &player = plr[i]; auto &player = plr[i];
if (player.plractive && player._pHitPoints == 0 && player.plrlevel == (BYTE)currlevel && player.position.tile.x == x && player.position.tile.y == y) { if (player.plractive && player._pHitPoints == 0 && player.plrlevel == (BYTE)currlevel && player.position.tile.x == x && player.position.tile.y == y) {
dFlags[x][y] |= BFLAG_DEAD_PLAYER; dFlags[x][y] |= BFLAG_DEAD_PLAYER;
int px = sx + player.position.offset.x - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width()); int px = sx + player.position.offset.deltaX - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width());
int py = sy + player.position.offset.y; int py = sy + player.position.offset.deltaY;
DrawPlayer(out, i, x, y, px, py); DrawPlayer(out, i, x, y, px, py);
} }
} }
@ -695,13 +695,13 @@ static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy,
const CelSprite &cel = *pMonster->AnimInfo.pCelSprite; const CelSprite &cel = *pMonster->AnimInfo.pCelSprite;
Point offset = pMonster->position.offset; Displacement offset = pMonster->position.offset;
if (pMonster->IsWalking()) { if (pMonster->IsWalking()) {
offset = GetOffsetForWalking(pMonster->AnimInfo, pMonster->_mdir); offset = GetOffsetForWalking(pMonster->AnimInfo, pMonster->_mdir);
} }
int px = sx + offset.x - CalculateWidth2(cel.Width()); int px = sx + offset.deltaX - CalculateWidth2(cel.Width());
int py = sy + offset.y; int py = sy + offset.deltaY;
if (mi == pcursmonst) { if (mi == pcursmonst) {
Cl2DrawOutline(out, 233, px, py, cel, pMonster->AnimInfo.GetFrameToUseForRendering()); Cl2DrawOutline(out, 233, px, py, cel, pMonster->AnimInfo.GetFrameToUseForRendering());
} }
@ -727,12 +727,12 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i
} }
auto &player = plr[p]; auto &player = plr[p];
Point offset = player.position.offset; Displacement offset = player.position.offset;
if (player.IsWalking()) { if (player.IsWalking()) {
offset = GetOffsetForWalking(player.AnimInfo, player._pdir); offset = GetOffsetForWalking(player.AnimInfo, player._pdir);
} }
int px = sx + offset.x - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width()); int px = sx + offset.deltaX - CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width());
int py = sy + offset.y; int py = sy + offset.deltaY;
DrawPlayer(out, p, x, y, px, py); DrawPlayer(out, p, x, y, px, py);
} }
@ -1162,11 +1162,11 @@ static void DrawGame(const CelOutputBuffer &full_out, int x, int y)
// Adjust by player offset and tile grid alignment // Adjust by player offset and tile grid alignment
auto &myPlayer = plr[myplr]; auto &myPlayer = plr[myplr];
Point offset = ScrollInfo.offset; Displacement offset = ScrollInfo.offset;
if (myPlayer.IsWalking()) if (myPlayer.IsWalking())
offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true); offset = GetOffsetForWalking(myPlayer.AnimInfo, myPlayer._pdir, true);
int sx = offset.x + tileOffsetX; int sx = offset.deltaX + tileOffsetX;
int sy = offset.y + tileOffsetY; int sy = offset.deltaY + tileOffsetY;
int columns = tileColums; int columns = tileColums;
int rows = tileRows; int rows = tileRows;

2
Source/scrollrt.h

@ -43,7 +43,7 @@ extern bool AutoMapShowItems;
* @param dir walking direction * @param dir walking direction
* @param cameraMode Adjusts the offset relative to the camera * @param cameraMode Adjusts the offset relative to the camera
*/ */
Point GetOffsetForWalking(const AnimationInfo &animationInfo, const Direction dir, bool cameraMode = false); Displacement GetOffsetForWalking(const AnimationInfo &animationInfo, const Direction dir, bool cameraMode = false);
void ClearCursor(); void ClearCursor();
void ShiftGrid(int *x, int *y, int horizontal, int vertical); void ShiftGrid(int *x, int *y, int horizontal, int vertical);

2
Source/spells.cpp

@ -205,7 +205,7 @@ static void PlacePlayer(int pnum)
if (plr[pnum].plrlevel == currlevel) { if (plr[pnum].plrlevel == currlevel) {
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
newPosition = plr[pnum].position.tile + Point { plrxoff2[i], plryoff2[i] }; newPosition = plr[pnum].position.tile + Displacement { plrxoff2[i], plryoff2[i] };
if (PosOkPlayer(pnum, newPosition)) { if (PosOkPlayer(pnum, newPosition)) {
break; break;
} }

10
Source/towners.cpp

@ -21,7 +21,7 @@ int CowClicks;
* placing cows in Tristram. A single cow may require space of up * placing cows in Tristram. A single cow may require space of up
* to three tiles when being placed on the map. * to three tiles when being placed on the map.
*/ */
Point CowOffsets[8] = { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } }; Displacement CowOffsets[8] = { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };
/** Specifies the active sound effect ID for interacting with cows. */ /** Specifies the active sound effect ID for interacting with cows. */
_sfx_id CowPlaying = SFX_NONE; _sfx_id CowPlaying = SFX_NONE;
@ -522,7 +522,7 @@ void TalkToHealer(PlayerStruct &player, TownerStruct &healer)
} }
if (quests[Q_MUSHROOM]._qactive == QUEST_ACTIVE) { if (quests[Q_MUSHROOM]._qactive == QUEST_ACTIVE) {
if (quests[Q_MUSHROOM]._qvar1 >= QS_MUSHGIVEN && quests[Q_MUSHROOM]._qvar1 < QS_BRAINGIVEN && player.TryRemoveInvItemById(IDI_BRAIN)) { if (quests[Q_MUSHROOM]._qvar1 >= QS_MUSHGIVEN && quests[Q_MUSHROOM]._qvar1 < QS_BRAINGIVEN && player.TryRemoveInvItemById(IDI_BRAIN)) {
SpawnQuestItem(IDI_SPECELIX, healer.position + Point { 0, 1 }, 0, 0); SpawnQuestItem(IDI_SPECELIX, healer.position + Displacement { 0, 1 }, 0, 0);
InitQTextMsg(TEXT_MUSH4); InitQTextMsg(TEXT_MUSH4);
quests[Q_MUSHROOM]._qvar1 = QS_BRAINGIVEN; quests[Q_MUSHROOM]._qvar1 = QS_BRAINGIVEN;
Qtalklist[TOWN_HEALER][Q_MUSHROOM] = TEXT_NONE; Qtalklist[TOWN_HEALER][Q_MUSHROOM] = TEXT_NONE;
@ -632,7 +632,7 @@ void TalkToFarmer(PlayerStruct &player, TownerStruct &farmer)
quests[Q_FARMER]._qvar1 = 1; quests[Q_FARMER]._qvar1 = 1;
quests[Q_FARMER]._qlog = true; quests[Q_FARMER]._qlog = true;
quests[Q_FARMER]._qmsg = TEXT_FARMER1; quests[Q_FARMER]._qmsg = TEXT_FARMER1;
SpawnRuneBomb(farmer.position + Point { 1, 0 }); SpawnRuneBomb(farmer.position + Displacement { 1, 0 });
if (gbIsMultiplayer) if (gbIsMultiplayer)
NetSendCmdQuest(true, Q_FARMER); NetSendCmdQuest(true, Q_FARMER);
break; break;
@ -641,7 +641,7 @@ void TalkToFarmer(PlayerStruct &player, TownerStruct &farmer)
break; break;
case QUEST_DONE: case QUEST_DONE:
InitQTextMsg(TEXT_FARMER4); InitQTextMsg(TEXT_FARMER4);
SpawnRewardItem(IDI_AURIC, farmer.position + Point { 1, 0 }); SpawnRewardItem(IDI_AURIC, farmer.position + Displacement { 1, 0 });
quests[Q_FARMER]._qactive = QUEST_HIVE_DONE; quests[Q_FARMER]._qactive = QUEST_HIVE_DONE;
quests[Q_FARMER]._qlog = false; quests[Q_FARMER]._qlog = false;
if (gbIsMultiplayer) if (gbIsMultiplayer)
@ -724,7 +724,7 @@ void TalkToCowFarmer(PlayerStruct &player, TownerStruct &cowFarmer)
quests[Q_JERSEY]._qvar1 = 1; quests[Q_JERSEY]._qvar1 = 1;
quests[Q_JERSEY]._qmsg = TEXT_JERSEY4; quests[Q_JERSEY]._qmsg = TEXT_JERSEY4;
quests[Q_JERSEY]._qlog = true; quests[Q_JERSEY]._qlog = true;
SpawnRuneBomb(cowFarmer.position + Point { 1, 0 }); SpawnRuneBomb(cowFarmer.position + Displacement { 1, 0 });
if (gbIsMultiplayer) if (gbIsMultiplayer)
NetSendCmdQuest(true, Q_JERSEY); NetSendCmdQuest(true, Q_JERSEY);
break; break;

44
test/automap_test.cpp

@ -19,45 +19,45 @@ TEST(Automap, InitAutomap)
TEST(Automap, StartAutomap) TEST(Automap, StartAutomap)
{ {
StartAutomap(); StartAutomap();
EXPECT_EQ(AutomapOffset.x, 0); EXPECT_EQ(AutomapOffset.deltaX, 0);
EXPECT_EQ(AutomapOffset.y, 0); EXPECT_EQ(AutomapOffset.deltaY, 0);
EXPECT_EQ(AutomapActive, true); EXPECT_EQ(AutomapActive, true);
} }
TEST(Automap, AutomapUp) TEST(Automap, AutomapUp)
{ {
AutomapOffset.x = 1; AutomapOffset.deltaX = 1;
AutomapOffset.y = 1; AutomapOffset.deltaY = 1;
AutomapUp(); AutomapUp();
EXPECT_EQ(AutomapOffset.x, 0); EXPECT_EQ(AutomapOffset.deltaX, 0);
EXPECT_EQ(AutomapOffset.y, 0); EXPECT_EQ(AutomapOffset.deltaY, 0);
} }
TEST(Automap, AutomapDown) TEST(Automap, AutomapDown)
{ {
AutomapOffset.x = 1; AutomapOffset.deltaX = 1;
AutomapOffset.y = 1; AutomapOffset.deltaY = 1;
AutomapDown(); AutomapDown();
EXPECT_EQ(AutomapOffset.x, 2); EXPECT_EQ(AutomapOffset.deltaX, 2);
EXPECT_EQ(AutomapOffset.y, 2); EXPECT_EQ(AutomapOffset.deltaY, 2);
} }
TEST(Automap, AutomapLeft) TEST(Automap, AutomapLeft)
{ {
AutomapOffset.x = 1; AutomapOffset.deltaX = 1;
AutomapOffset.y = 1; AutomapOffset.deltaY = 1;
AutomapLeft(); AutomapLeft();
EXPECT_EQ(AutomapOffset.x, 0); EXPECT_EQ(AutomapOffset.deltaX, 0);
EXPECT_EQ(AutomapOffset.y, 2); EXPECT_EQ(AutomapOffset.deltaY, 2);
} }
TEST(Automap, AutomapRight) TEST(Automap, AutomapRight)
{ {
AutomapOffset.x = 1; AutomapOffset.deltaX = 1;
AutomapOffset.y = 1; AutomapOffset.deltaY = 1;
AutomapRight(); AutomapRight();
EXPECT_EQ(AutomapOffset.x, 2); EXPECT_EQ(AutomapOffset.deltaX, 2);
EXPECT_EQ(AutomapOffset.y, 0); EXPECT_EQ(AutomapOffset.deltaY, 0);
} }
TEST(Automap, AutomapZoomIn) TEST(Automap, AutomapZoomIn)
@ -113,11 +113,11 @@ TEST(Automap, AutomapZoomOut_Min)
TEST(Automap, AutomapZoomReset) TEST(Automap, AutomapZoomReset)
{ {
AutoMapScale = 50; AutoMapScale = 50;
AutomapOffset.x = 1; AutomapOffset.deltaX = 1;
AutomapOffset.y = 1; AutomapOffset.deltaY = 1;
AutomapZoomReset(); AutomapZoomReset();
EXPECT_EQ(AutomapOffset.x, 0); EXPECT_EQ(AutomapOffset.deltaX, 0);
EXPECT_EQ(AutomapOffset.y, 0); EXPECT_EQ(AutomapOffset.deltaY, 0);
EXPECT_EQ(AutoMapScale, 50); EXPECT_EQ(AutoMapScale, 50);
EXPECT_EQ(AmLine64, 32); EXPECT_EQ(AmLine64, 32);
EXPECT_EQ(AmLine32, 16); EXPECT_EQ(AmLine32, 16);

Loading…
Cancel
Save