Browse Source

♻️Make GetDirection take Points instead of ints

pull/1689/head
Anders Jenbo 5 years ago
parent
commit
f77c52941a
  1. 2
      Source/controls/plrctrls.cpp
  2. 6
      Source/engine.cpp
  3. 8
      Source/engine.h
  4. 4
      Source/inv.cpp
  5. 26
      Source/missiles.cpp
  6. 78
      Source/monster.cpp
  7. 8
      Source/objects.cpp
  8. 50
      Source/player.cpp
  9. 4
      Source/sync.cpp
  10. 64
      test/missiles_test.cpp

2
Source/controls/plrctrls.cpp

@ -59,7 +59,7 @@ int GetRotaryDistance(int x, int y)
return -1;
d1 = plr[myplr]._pdir;
d2 = GetDirection(plr[myplr].position.future.x, plr[myplr].position.future.y, x, y);
d2 = GetDirection(plr[myplr].position.future, { x, y });
d = abs(d1 - d2);
if (d > 4)

6
Source/engine.cpp

@ -542,12 +542,12 @@ void DrawHalfTransparentRectTo(const CelOutputBuffer &out, int sx, int sy, int w
* @param y2 the y coordinate of p2
* @return the direction of the p1->p2 vector
*/
direction GetDirection(int x1, int y1, int x2, int y2)
direction GetDirection(Point start, Point destination)
{
direction md = DIR_S;
int mx = x2 - x1;
int my = y2 - y1;
int mx = destination.x - start.x;
int my = destination.y - start.y;
if (mx >= 0) {
if (my >= 0) {
if (5 * mx <= (my * 2)) // mx/my <= 0.4, approximation of tan(22.5)

8
Source/engine.h

@ -476,13 +476,11 @@ void DrawHalfTransparentRectTo(const CelOutputBuffer &out, int sx, int sy, int w
/**
* @brief Calculate the best fit direction between two points
* @param x1 Tile coordinate
* @param y1 Tile coordinate
* @param x2 Tile coordinate
* @param y2 Tile coordinate
* @param start Tile coordinate
* @param destination Tile coordinate
* @return A value from the direction enum
*/
direction GetDirection(int x1, int y1, int x2, int y2);
direction GetDirection(Point start, Point destination);
void SetRndSeed(int32_t s);
int32_t AdvanceRndSeed();

4
Source/inv.cpp

@ -1870,7 +1870,7 @@ bool TryInvPut()
if (numitems >= MAXITEMS)
return false;
direction dir = GetDirection(plr[myplr].position.tile.x, plr[myplr].position.tile.y, cursmx, cursmy);
direction dir = GetDirection(plr[myplr].position.tile, { cursmx, cursmy });
if (CanPut(plr[myplr].position.tile.x + offset_x[dir], plr[myplr].position.tile.y + offset_y[dir])) {
return true;
}
@ -1907,7 +1907,7 @@ static int PutItem(int pnum, int &x, int &y)
int xx = x - plr[pnum].position.tile.x;
int yy = y - plr[pnum].position.tile.y;
direction d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, x, y);
direction d = GetDirection(plr[pnum].position.tile, { x, y });
if (abs(xx) > 1 || abs(yy) > 1) {
x = plr[pnum].position.tile.x + offset_x[d];

26
Source/missiles.cpp

@ -229,7 +229,7 @@ void GetDamageAmt(int i, int *mind, int *maxd)
bool CheckBlock(int fx, int fy, int tx, int ty)
{
while (fx != tx || fy != ty) {
direction pn = GetDirection(fx, fy, tx, ty);
direction pn = GetDirection({ fx, fy }, { tx, ty });
fx += XDirAdd[pn];
fy += YDirAdd[pn];
if (nSolidTable[dPiece[fx][fy]])
@ -796,7 +796,7 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
if ((resper <= 0 || gbIsHellfire) && blk < blkper) {
direction dir = plr[pnum]._pdir;
if (m != -1) {
dir = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, monster[m].position.tile.x, monster[m].position.tile.y);
dir = GetDirection(plr[pnum].position.tile, monster[m].position.tile);
}
*blocked = true;
StartPlrBlock(pnum, dir);
@ -924,7 +924,7 @@ bool Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, b
return true;
}
if (blkper < blk) {
StartPlrBlock(p, GetDirection(plr[p].position.tile.x, plr[p].position.tile.y, plr[pnum].position.tile.x, plr[pnum].position.tile.y));
StartPlrBlock(p, GetDirection(plr[p].position.tile, plr[pnum].position.tile));
*blocked = true;
} else {
if (pnum == myplr)
@ -2789,7 +2789,7 @@ void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, int8_t mienem
}
missile[mi]._midam /= 2;
GetMissileVel(mi, sx, sy, dx, dy, 16);
SetMissDir(mi, GetDirection(sx, sy, dx, dy));
SetMissDir(mi, GetDirection({ sx, sy }, { dx, dy }));
missile[mi]._mirange = 256;
missile[mi]._miVar1 = sx;
missile[mi]._miVar2 = sy;
@ -3125,7 +3125,7 @@ void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, int8_t mie
}
missile[mi]._midam = 0;
GetMissileVel(mi, sx, sy, dx, dy, 16);
SetMissDir(mi, GetDirection(sx, sy, dx, dy));
SetMissDir(mi, GetDirection({ sx, sy }, { dx, dy }));
missile[mi]._mirange = 256;
missile[mi]._miVar1 = sx;
missile[mi]._miVar2 = sy;
@ -3232,7 +3232,7 @@ int Sentfire(int i, int sx, int sy)
int ex = 0;
if (LineClearMissile(missile[i].position.tile.x, missile[i].position.tile.y, sx, sy)) {
if (dMonster[sx][sy] > 0 && monster[dMonster[sx][sy] - 1]._mhitpoints >> 6 > 0 && dMonster[sx][sy] - 1 > MAX_PLRS - 1) {
direction dir = GetDirection(missile[i].position.tile.x, missile[i].position.tile.y, sx, sy);
direction dir = GetDirection(missile[i].position.tile, { sx, sy });
missile[i]._miVar3 = missileavail[0];
AddMissile(missile[i].position.tile.x, missile[i].position.tile.y, sx, sy, dir, MIS_FIREBOLT, TARGET_MONSTERS, missile[i]._misource, missile[i]._midam, GetSpellLevel(missile[i]._misource, SPL_FIREBOLT));
ex = -1;
@ -3709,13 +3709,13 @@ void MI_Rune(int i)
mid = mid - 1;
else
mid = -(mid + 1);
dir = GetDirection(missile[i].position.tile.x, missile[i].position.tile.y, monster[mid].position.tile.x, monster[mid].position.tile.y);
dir = GetDirection(missile[i].position.tile, monster[mid].position.tile);
} else {
if (pid > 0)
pid = pid - 1;
else
pid = -(pid + 1);
dir = GetDirection(missile[i].position.tile.x, missile[i].position.tile.y, plr[pid].position.tile.x, plr[pid].position.tile.y);
dir = GetDirection(missile[i].position.tile, plr[pid].position.tile);
}
missile[i]._miDelFlag = true;
AddUnLight(missile[i]._mlid);
@ -4466,7 +4466,7 @@ void MI_Chain(int i)
id = missile[i]._misource;
sx = missile[i].position.tile.x;
sy = missile[i].position.tile.y;
direction dir = GetDirection(sx, sy, missile[i]._miVar1, missile[i]._miVar2);
direction dir = GetDirection({ sx, sy }, { missile[i]._miVar1, missile[i]._miVar2 });
AddMissile(sx, sy, missile[i]._miVar1, missile[i]._miVar2, dir, MIS_LIGHTCTRL, TARGET_MONSTERS, id, 1, missile[i]._mispllvl);
rad = missile[i]._mispllvl + 3;
if (rad > 19)
@ -4478,7 +4478,7 @@ void MI_Chain(int i)
tx = sx + CrawlTable[l - 1];
ty = sy + CrawlTable[l];
if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY && dMonster[tx][ty] > 0) {
dir = GetDirection(sx, sy, tx, ty);
dir = GetDirection({ sx, sy }, { tx, ty });
AddMissile(sx, sy, tx, ty, dir, MIS_LIGHTCTRL, TARGET_MONSTERS, id, 1, missile[i]._mispllvl);
}
l += 2;
@ -4808,7 +4808,7 @@ void MI_Wave(int i)
sy = missile[i].position.tile.y;
v1 = missile[i]._miVar1;
v2 = missile[i]._miVar2;
direction sd = GetDirection(sx, sy, v1, v2);
direction sd = GetDirection({ sx, sy }, { v1, v2 });
direction dira = left[left[sd]];
direction dirb = right[right[sd]];
nxa = sx + XDirAdd[sd];
@ -5089,7 +5089,7 @@ void MI_Element(int i)
missile[i]._mirange = 255;
mid = FindClosest(cx, cy, 19);
if (mid > 0) {
direction sd = GetDirection(cx, cy, monster[mid].position.tile.x, monster[mid].position.tile.y);
direction sd = GetDirection({ cx, cy }, monster[mid].position.tile);
SetMissDir(i, sd);
GetMissileVel(i, cx, cy, monster[mid].position.tile.x, monster[mid].position.tile.y, 16);
} else {
@ -5142,7 +5142,7 @@ void MI_Bonespirit(int i)
mid = FindClosest(cx, cy, 19);
if (mid > 0) {
missile[i]._midam = monster[mid]._mhitpoints >> 7;
SetMissDir(i, GetDirection(cx, cy, monster[mid].position.tile.x, monster[mid].position.tile.y));
SetMissDir(i, GetDirection({ cx, cy }, monster[mid].position.tile));
GetMissileVel(i, cx, cy, monster[mid].position.tile.x, monster[mid].position.tile.y, 16);
} else {
direction sd = plr[id]._pdir;

78
Source/monster.cpp

@ -1384,7 +1384,7 @@ void M_Enemy(int i)
direction M_GetDir(int i)
{
return GetDirection(monster[i].position.tile.x, monster[i].position.tile.y, monster[i].enemyPosition.x, monster[i].enemyPosition.y);
return GetDirection(monster[i].position.tile, monster[i].enemyPosition);
}
void M_StartStand(int i, direction md)
@ -2117,7 +2117,7 @@ void M_TryH2HHit(int i, int pnum, int Hit, int MinDam, int MaxDam)
if (hper >= hit)
return;
if (blkper < blk) {
direction dir = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, monster[i].position.tile.x, monster[i].position.tile.y);
direction dir = GetDirection(plr[pnum].position.tile, monster[i].position.tile);
StartPlrBlock(pnum, dir);
if (pnum == myplr && plr[pnum].wReflections > 0) {
plr[pnum].wReflections--;
@ -2928,21 +2928,16 @@ void MAI_Zombie(int i)
void MAI_SkelSd(int i)
{
MonsterStruct *Monst;
int mx, my, x, y;
assurance((DWORD)i < MAXMONSTERS, i);
Monst = &monster[i];
MonsterStruct *Monst = &monster[i];
if (Monst->_mmode != MM_STAND || Monst->_msquelch == 0) {
return;
}
mx = Monst->position.tile.x;
my = Monst->position.tile.y;
x = mx - Monst->enemyPosition.x;
y = my - Monst->enemyPosition.y;
direction md = GetDirection(mx, my, Monst->position.last.x, Monst->position.last.y);
int x = Monst->position.tile.x - Monst->enemyPosition.x;
int y = Monst->position.tile.y - Monst->enemyPosition.y;
direction md = GetDirection(Monst->position.tile, Monst->position.last);
Monst->_mdir = md;
if (abs(x) >= 2 || abs(y) >= 2) {
if (Monst->_mVar1 == MM_DELAY || (GenerateRnd(100) >= 35 - 4 * Monst->_mint)) {
@ -3020,7 +3015,7 @@ void MAI_Snake(int i)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
Monst->_mdir = md;
if (abs(mx) >= 2 || abs(my) >= 2) {
if (abs(mx) < 3 && abs(my) < 3 && LineClear(PosOkMonst, i, Monst->position.tile.x, Monst->position.tile.y, fx, fy) && Monst->_mVar1 != MM_CHARGE) {
@ -3084,7 +3079,7 @@ void MAI_Bat(int i)
xd = Monst->position.tile.x - Monst->enemyPosition.x;
yd = Monst->position.tile.y - Monst->enemyPosition.y;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
Monst->_mdir = md;
v = GenerateRnd(100);
if (Monst->_mgoal == MGOAL_RETREAT) {
@ -3237,9 +3232,9 @@ void MAI_Sneak(int i)
}
if (Monst->_mgoal == MGOAL_RETREAT && !(Monst->_mFlags & MFLAG_NO_ENEMY)) {
if (Monst->_mFlags & MFLAG_TARGETS_MONSTER)
md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, monster[Monst->_menemy].position.tile.x, monster[Monst->_menemy].position.tile.y);
md = GetDirection(Monst->position.tile, monster[Monst->_menemy].position.tile);
else
md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, plr[Monst->_menemy].position.last.x, plr[Monst->_menemy].position.last.y);
md = GetDirection(Monst->position.tile, plr[Monst->_menemy].position.last);
md = opposite[md];
if (Monst->MType->mtype == MT_UNSEEN) {
if (GenerateRnd(2) != 0)
@ -3417,7 +3412,7 @@ void MAI_Cleaver(int i)
x = mx - Monst->enemyPosition.x;
y = my - Monst->enemyPosition.y;
direction md = GetDirection(mx, my, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection({ mx, my }, Monst->position.last);
Monst->_mdir = md;
if (abs(x) >= 2 || abs(y) >= 2)
@ -3443,7 +3438,7 @@ void MAI_Round(int i, bool special)
fx = Monst->enemyPosition.x;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(100);
@ -3532,7 +3527,7 @@ void MAI_Ranged(int i, int missile_type, bool special)
} else if (Monst->_msquelch != 0) {
fx = Monst->position.last.x;
fy = Monst->position.last.y;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, fx, fy);
direction md = GetDirection(Monst->position.tile, { fx, fy });
M_CallWalk(i, md);
}
}
@ -3668,7 +3663,7 @@ void MAI_Scav(int i)
if (Monst->_mgoalvar1) {
x = Monst->_mgoalvar1 - 1;
y = Monst->_mgoalvar2 - 1;
Monst->_mdir = GetDirection(Monst->position.tile.x, Monst->position.tile.y, x, y);
Monst->_mdir = GetDirection(Monst->position.tile, { x, y });
M_CallWalk(i, Monst->_mdir);
}
}
@ -3731,7 +3726,7 @@ void MAI_RoundRanged(int i, int missile_type, bool checkdoors, int dam, int less
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (checkdoors && Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(10000);
@ -3823,7 +3818,7 @@ void MAI_RR2(int i, int mistype, int dam)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(100);
@ -3879,14 +3874,9 @@ void MAI_Mega(int i)
void MAI_Golum(int i)
{
int mx, my, _mex, _mey;
int j, k, _menemy;
MonsterStruct *Monst;
bool have_enemy, ok;
assurance((DWORD)i < MAXMONSTERS, i);
Monst = &monster[i];
MonsterStruct *Monst = &monster[i];
if (Monst->position.tile.x == 1 && Monst->position.tile.y == 0) {
return;
}
@ -3900,19 +3890,17 @@ void MAI_Golum(int i)
if (!(Monst->_mFlags & MFLAG_TARGETS_MONSTER))
M_Enemy(i);
have_enemy = !(monster[i]._mFlags & MFLAG_NO_ENEMY);
bool have_enemy = !(monster[i]._mFlags & MFLAG_NO_ENEMY);
if (Monst->_mmode == MM_ATTACK) {
return;
}
_menemy = monster[i]._menemy;
int _menemy = monster[i]._menemy;
mx = monster[i].position.tile.x;
my = monster[i].position.tile.y;
_mex = mx - monster[_menemy].position.future.x;
_mey = my - monster[_menemy].position.future.y;
direction md = GetDirection(mx, my, monster[_menemy].position.tile.x, monster[_menemy].position.tile.y);
int _mex = monster[i].position.tile.x - monster[_menemy].position.future.x;
int _mey = monster[i].position.tile.y - monster[_menemy].position.future.y;
direction md = GetDirection(monster[i].position.tile, monster[_menemy].position.tile);
monster[i]._mdir = md;
if (abs(_mex) < 2 && abs(_mey) < 2 && have_enemy) {
_menemy = monster[i]._menemy;
@ -3920,8 +3908,8 @@ void MAI_Golum(int i)
if (monster[_menemy]._msquelch == 0) {
monster[_menemy]._msquelch = UCHAR_MAX;
monster[monster[i]._menemy].position.last = monster[i].position.tile;
for (j = 0; j < 5; j++) {
for (k = 0; k < 5; k++) {
for (int j = 0; j < 5; j++) {
for (int k = 0; k < 5; k++) {
_menemy = dMonster[monster[i].position.tile.x + k - 2][monster[i].position.tile.y + j - 2];
if (_menemy > 0)
monster[_menemy - 1]._msquelch = UCHAR_MAX; // BUGFIX: should be `monster[_menemy-1]`, not monster[_menemy]. (fixed)
@ -3939,12 +3927,12 @@ void MAI_Golum(int i)
if (monster[i]._pathcount > 8)
monster[i]._pathcount = 5;
ok = M_CallWalk(i, plr[i]._pdir);
bool ok = M_CallWalk(i, plr[i]._pdir);
if (ok)
return;
md = left[md];
for (j = 0; j < 8 && !ok; j++) {
for (int j = 0; j < 8 && !ok; j++) {
md = right[md];
ok = DirOK(i, md);
}
@ -3965,7 +3953,7 @@ void MAI_SkelKing(int i)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(100);
@ -4028,7 +4016,7 @@ void MAI_Rhino(int i)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(100);
@ -4098,7 +4086,7 @@ void MAI_HorkDemon(int i)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < 255) {
MonstCheckDoors(i);
@ -4165,7 +4153,7 @@ void MAI_Counselor(int i)
fy = Monst->enemyPosition.y;
mx = Monst->position.tile.x - fx;
my = Monst->position.tile.y - fy;
direction md = GetDirection(Monst->position.tile.x, Monst->position.tile.y, Monst->position.last.x, Monst->position.last.y);
direction md = GetDirection(Monst->position.tile, Monst->position.last);
if (Monst->_msquelch < UCHAR_MAX)
MonstCheckDoors(i);
v = GenerateRnd(100);
@ -4956,7 +4944,7 @@ void M_FallenFear(int x, int y)
&& m->_mhitpoints >> 6 > 0) {
m->_mgoal = MGOAL_RETREAT;
m->_mgoalvar1 = rundist;
m->_mdir = GetDirection(x, y, m->position.tile.x, m->position.tile.y);
m->_mdir = GetDirection({ x, y }, m->position.tile);
}
}
}
@ -5317,7 +5305,7 @@ bool SpawnSkeleton(int ii, int x, int y)
return false;
if (PosOkMonst(-1, x, y)) {
direction dir = GetDirection(x, y, x, y);
direction dir = GetDirection({ x, y }, { x, y }); // TODO useless calculation
ActivateSpawn(ii, x, y, dir);
return true;
}
@ -5356,7 +5344,7 @@ bool SpawnSkeleton(int ii, int x, int y)
dx = x - 1 + xx;
dy = y - 1 + yy;
direction dir = GetDirection(dx, dy, x, y);
direction dir = GetDirection({ dx, dy }, { x, y });
ActivateSpawn(ii, dx, dy, dir);
return true;

8
Source/objects.cpp

@ -2118,8 +2118,6 @@ void Obj_Trap(int i)
}
object[i]._oVar4 = 1;
int sx = object[i].position.x;
int sy = object[i].position.y;
int dx = object[oti].position.x;
int dy = object[oti].position.y;
for (int y = dy - 1; y <= object[oti].position.y + 1; y++) {
@ -2131,7 +2129,9 @@ void Obj_Trap(int i)
}
}
if (!deltaload) {
direction dir = GetDirection(sx, sy, dx, dy);
direction dir = GetDirection(object[i].position, object[oti].position);
int sx = object[i].position.x;
int sy = object[i].position.y;
AddMissile(sx, sy, dx, dy, dir, object[i]._oVar3, TARGET_PLAYERS, -1, 0, 0);
PlaySfxLoc(IS_TRAP, object[oti].position.x, object[oti].position.y);
}
@ -3126,7 +3126,7 @@ void OperateChest(int pnum, int i, bool sendmsg)
}
}
if (object[i]._oTrapFlag && object[i]._otype >= OBJ_TCHEST1 && object[i]._otype <= OBJ_TCHEST3) {
direction mdir = GetDirection(object[i].position.x, object[i].position.y, plr[pnum].position.tile.x, plr[pnum].position.tile.y);
direction mdir = GetDirection(object[i].position, plr[pnum].position.tile);
switch (object[i]._oVar4) {
case 0:
mtype = MIS_ARROW;

50
Source/player.cpp

@ -2746,7 +2746,7 @@ bool PlrHitPlr(int pnum, int8_t p)
if (hit < hper) {
if (blk < blkper) {
direction dir = GetDirection(plr[p].position.tile.x, plr[p].position.tile.y, plr[pnum].position.tile.x, plr[pnum].position.tile.y);
direction dir = GetDirection(plr[p].position.tile, plr[pnum].position.tile);
StartPlrBlock(p, dir);
} else {
mind = plr[pnum]._pIMinDam;
@ -3234,11 +3234,11 @@ void CheckNewPath(int pnum)
if (plr[pnum].destAction == ACTION_ATTACKMON) {
x = abs(plr[pnum].position.future.x - monster[i].position.future.x);
y = abs(plr[pnum].position.future.y - monster[i].position.future.y);
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.future, monster[i].position.future);
} else {
x = abs(plr[pnum].position.future.x - plr[i].position.future.x);
y = abs(plr[pnum].position.future.y - plr[i].position.future.y);
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.future, plr[i].position.future);
}
if (x < 2 && y < 2) {
@ -3311,7 +3311,7 @@ void CheckNewPath(int pnum)
if (plr[pnum]._pmode == PM_STAND) {
switch (plr[pnum].destAction) {
case ACTION_ATTACK:
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.tile, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartAttack(pnum, d);
break;
case ACTION_ATTACKMON:
@ -3319,7 +3319,7 @@ void CheckNewPath(int pnum)
x = abs(plr[pnum].position.tile.x - monster[i].position.future.x);
y = abs(plr[pnum].position.tile.y - monster[i].position.future.y);
if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.future, monster[i].position.future);
if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
TalktoMonster(i);
} else {
@ -3332,17 +3332,17 @@ void CheckNewPath(int pnum)
x = abs(plr[pnum].position.tile.x - plr[i].position.future.x);
y = abs(plr[pnum].position.tile.y - plr[i].position.future.y);
if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.future, plr[i].position.future);
StartAttack(pnum, d);
}
break;
case ACTION_RATTACK:
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.tile, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
break;
case ACTION_RATTACKMON:
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.future, monster[i].position.future);
if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
TalktoMonster(i);
} else {
@ -3351,11 +3351,11 @@ void CheckNewPath(int pnum)
break;
case ACTION_RATTACKPLR:
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.future, plr[i].position.future);
StartRangeAttack(pnum, d, plr[i].position.future.x, plr[i].position.future.y);
break;
case ACTION_SPELL:
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.tile, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
plr[pnum]._pVar4 = plr[pnum].destParam3;
break;
@ -3366,13 +3366,13 @@ void CheckNewPath(int pnum)
break;
case ACTION_SPELLMON:
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, monster[i].position.future);
StartSpell(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum]._pVar4 = plr[pnum].destParam2;
break;
case ACTION_SPELLPLR:
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, plr[i].position.future);
StartSpell(pnum, d, plr[i].position.future.x, plr[i].position.future.y);
plr[pnum]._pVar4 = plr[pnum].destParam2;
break;
@ -3385,7 +3385,7 @@ void CheckNewPath(int pnum)
}
if (x <= 1 && y <= 1) {
if (object[i]._oBreak == 1) {
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, object[i].position.x, object[i].position.y);
d = GetDirection(plr[pnum].position.tile, object[i].position);
StartAttack(pnum, d);
} else {
OperateObject(pnum, i, false);
@ -3401,7 +3401,7 @@ void CheckNewPath(int pnum)
}
if (x <= 1 && y <= 1) {
if (object[i]._oBreak == 1) {
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, object[i].position.x, object[i].position.y);
d = GetDirection(plr[pnum].position.tile, object[i].position);
StartAttack(pnum, d);
} else {
TryDisarm(pnum, i);
@ -3453,7 +3453,7 @@ void CheckNewPath(int pnum)
if (plr[pnum]._pmode == PM_ATTACK && plr[pnum]._pAnimFrame > plr[myplr]._pAFNum) {
if (plr[pnum].destAction == ACTION_ATTACK) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.future, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartAttack(pnum, d);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_ATTACKMON) {
@ -3461,7 +3461,7 @@ void CheckNewPath(int pnum)
x = abs(plr[pnum].position.tile.x - monster[i].position.future.x);
y = abs(plr[pnum].position.tile.y - monster[i].position.future.y);
if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.future, monster[i].position.future);
StartAttack(pnum, d);
}
plr[pnum].destAction = ACTION_NONE;
@ -3470,7 +3470,7 @@ void CheckNewPath(int pnum)
x = abs(plr[pnum].position.tile.x - plr[i].position.future.x);
y = abs(plr[pnum].position.tile.y - plr[i].position.future.y);
if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.future, plr[i].position.future);
StartAttack(pnum, d);
}
plr[pnum].destAction = ACTION_NONE;
@ -3483,7 +3483,7 @@ void CheckNewPath(int pnum)
}
if (x <= 1 && y <= 1) {
if (object[i]._oBreak == 1) {
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, object[i].position.x, object[i].position.y);
d = GetDirection(plr[pnum].position.tile, object[i].position);
StartAttack(pnum, d);
} else {
OperateObject(pnum, i, false);
@ -3494,17 +3494,17 @@ void CheckNewPath(int pnum)
if (plr[pnum]._pmode == PM_RATTACK && plr[pnum]._pAnimFrame > plr[myplr]._pAFNum) {
if (plr[pnum].destAction == ACTION_RATTACK) {
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.tile, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKMON) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, monster[i].position.future);
StartRangeAttack(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKPLR) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, plr[i].position.future);
StartRangeAttack(pnum, d, plr[i].position.future.x, plr[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
}
@ -3512,17 +3512,17 @@ void CheckNewPath(int pnum)
if (plr[pnum]._pmode == PM_SPELL && plr[pnum]._pAnimFrame > plr[pnum]._pSFNum) {
if (plr[pnum].destAction == ACTION_SPELL) {
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[pnum].destParam1, plr[pnum].destParam2);
d = GetDirection(plr[pnum].position.tile, { plr[pnum].destParam1, plr[pnum].destParam2 });
StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLMON) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, monster[i].position.future.x, monster[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, monster[i].position.future);
StartSpell(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLPLR) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.tile.x, plr[pnum].position.tile.y, plr[i].position.future.x, plr[i].position.future.y);
d = GetDirection(plr[pnum].position.tile, plr[i].position.future);
StartSpell(pnum, d, plr[i].position.future.x, plr[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
}
@ -3950,7 +3950,7 @@ void CheckPlrSpell()
if (addflag) {
if (plr[myplr]._pRSpell == SPL_FIREWALL || plr[myplr]._pRSpell == SPL_LIGHTWALL) {
direction sd = GetDirection(plr[myplr].position.tile.x, plr[myplr].position.tile.y, cursmx, cursmy);
direction sd = GetDirection(plr[myplr].position.tile, { cursmx, cursmy });
sl = GetSpellLevel(myplr, plr[myplr]._pRSpell);
NetSendCmdLocParam3(true, CMD_SPELLXYD, cursmx, cursmy, plr[myplr]._pRSpell, sd, sl);
} else if (pcursmonst != -1) {

4
Source/sync.cpp

@ -232,7 +232,7 @@ static void sync_monster(int pnum, const TSyncMonster *p)
mdy = abs(monster[ndx].position.tile.y - p->_my);
if (mdx <= 2 && mdy <= 2) {
if (monster[ndx]._mmode < MM_WALK || monster[ndx]._mmode > MM_WALK3) {
direction md = GetDirection(monster[ndx].position.tile.x, monster[ndx].position.tile.y, p->_mx, p->_my);
direction md = GetDirection(monster[ndx].position.tile, { p->_mx, p->_my });
if (DirOK(ndx, md)) {
M_ClearSquares(ndx);
dMonster[monster[ndx].position.tile.x][monster[ndx].position.tile.y] = ndx + 1;
@ -245,7 +245,7 @@ static void sync_monster(int pnum, const TSyncMonster *p)
dMonster[p->_mx][p->_my] = ndx + 1;
monster[ndx].position.tile = { p->_mx, p->_my };
decode_enemy(ndx, p->_menemy);
direction md = GetDirection(p->_mx, p->_my, monster[ndx].enemyPosition.x, monster[ndx].enemyPosition.y);
direction md = GetDirection({ p->_mx, p->_my }, monster[ndx].enemyPosition);
M_StartStand(ndx, md);
monster[ndx]._msquelch = UCHAR_MAX;
}

64
test/missiles_test.cpp

@ -6,39 +6,39 @@ using namespace devilution;
TEST(Missiles, GetDirection8)
{
EXPECT_EQ(0, GetDirection(0, 0, 15, 15));
EXPECT_EQ(1, GetDirection(0, 0, 0, 15));
EXPECT_EQ(0, GetDirection(0, 0, 8, 15));
EXPECT_EQ(0, GetDirection(0, 0, 8, 8));
EXPECT_EQ(0, GetDirection(0, 0, 15, 8));
EXPECT_EQ(0, GetDirection(0, 0, 15, 7));
EXPECT_EQ(0, GetDirection(0, 0, 11, 7));
EXPECT_EQ(0, GetDirection(0, 0, 8, 11));
EXPECT_EQ(4, GetDirection(15, 15, 0, 0));
EXPECT_EQ(5, GetDirection(0, 15, 0, 0));
EXPECT_EQ(4, GetDirection(8, 15, 0, 0));
EXPECT_EQ(4, GetDirection(8, 8, 0, 0));
EXPECT_EQ(4, GetDirection(15, 8, 0, 0));
EXPECT_EQ(4, GetDirection(15, 7, 0, 0));
EXPECT_EQ(4, GetDirection(11, 7, 0, 0));
EXPECT_EQ(4, GetDirection(8, 11, 0, 0));
EXPECT_EQ(6, GetDirection(0, 15, 15, 0));
EXPECT_EQ(7, GetDirection(0, 0, 15, 0));
EXPECT_EQ(6, GetDirection(0, 8, 15, 0));
EXPECT_EQ(6, GetDirection(0, 8, 8, 0));
EXPECT_EQ(6, GetDirection(0, 15, 8, 0));
EXPECT_EQ(6, GetDirection(0, 15, 7, 0));
EXPECT_EQ(6, GetDirection(0, 11, 7, 0));
EXPECT_EQ(6, GetDirection(0, 8, 11, 0));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 15 }));
EXPECT_EQ(1, GetDirection({ 0, 0 }, { 0, 15 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 15 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 8 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 8 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 15, 7 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 11, 7 }));
EXPECT_EQ(0, GetDirection({ 0, 0 }, { 8, 11 }));
EXPECT_EQ(4, GetDirection({ 15, 15 }, { 0, 0 }));
EXPECT_EQ(5, GetDirection({ 0, 15 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 8, 15 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 8, 8 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 15, 8 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 15, 7 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 11, 7 }, { 0, 0 }));
EXPECT_EQ(4, GetDirection({ 8, 11 }, { 0, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 15, 0 }));
EXPECT_EQ(7, GetDirection({ 0, 0 }, { 15, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 15, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 8, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 8, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 15 }, { 7, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 11 }, { 7, 0 }));
EXPECT_EQ(6, GetDirection({ 0, 8 }, { 11, 0 }));
EXPECT_EQ(0, GetDirection(1, 1, 2, 2));
EXPECT_EQ(1, GetDirection(1, 1, 1, 2));
EXPECT_EQ(2, GetDirection(1, 1, 0, 2));
EXPECT_EQ(3, GetDirection(1, 1, 0, 1));
EXPECT_EQ(4, GetDirection(1, 1, 0, 0));
EXPECT_EQ(5, GetDirection(1, 1, 1, 0));
EXPECT_EQ(6, GetDirection(1, 1, 2, 0));
EXPECT_EQ(7, GetDirection(1, 1, 2, 1));
EXPECT_EQ(0, GetDirection({ 1, 1 }, { 2, 2 }));
EXPECT_EQ(1, GetDirection({ 1, 1 }, { 1, 2 }));
EXPECT_EQ(2, GetDirection({ 1, 1 }, { 0, 2 }));
EXPECT_EQ(3, GetDirection({ 1, 1 }, { 0, 1 }));
EXPECT_EQ(4, GetDirection({ 1, 1 }, { 0, 0 }));
EXPECT_EQ(5, GetDirection({ 1, 1 }, { 1, 0 }));
EXPECT_EQ(6, GetDirection({ 1, 1 }, { 2, 0 }));
EXPECT_EQ(7, GetDirection({ 1, 1 }, { 2, 1 }));
}
TEST(Missiles, GetDirection16)

Loading…
Cancel
Save