Browse Source

♻️ add possition points to monsters

pull/1681/head
Anders Jenbo 5 years ago
parent
commit
efbe8a8338
  1. 12
      Source/controls/plrctrls.cpp
  2. 2
      Source/debug.cpp
  3. 4
      Source/diablo.cpp
  4. 2
      Source/effects.cpp
  5. 19
      Source/engine.h
  6. 92
      Source/loadsave.cpp
  7. 42
      Source/missiles.cpp
  8. 879
      Source/monster.cpp
  9. 37
      Source/monster.h
  10. 31
      Source/msg.cpp
  11. 2
      Source/multi.cpp
  12. 4
      Source/objects.cpp
  13. 84
      Source/player.cpp
  14. 21
      Source/player.h
  15. 4
      Source/scrollrt.cpp
  16. 23
      Source/sync.cpp

12
Source/controls/plrctrls.cpp

@ -194,8 +194,8 @@ bool CanTargetMonster(int mi)
if (monst._mhitpoints >> 6 <= 0) // dead if (monst._mhitpoints >> 6 <= 0) // dead
return false; return false;
const int mx = monst._mx; const int mx = monst.position.current.x;
const int my = monst._my; const int my = monst.position.current.y;
if ((dFlags[mx][my] & BFLAG_LIT) == 0) // not visible if ((dFlags[mx][my] & BFLAG_LIT) == 0) // not visible
return false; return false;
if (dMonster[mx][my] == 0) if (dMonster[mx][my] == 0)
@ -213,8 +213,8 @@ void FindRangedTarget()
// The first MAX_PLRS monsters are reserved for players' golems. // The first MAX_PLRS monsters are reserved for players' golems.
for (int mi = MAX_PLRS; mi < MAXMONSTERS; mi++) { for (int mi = MAX_PLRS; mi < MAXMONSTERS; mi++) {
const MonsterStruct &monst = monster[mi]; const MonsterStruct &monst = monster[mi];
const int mx = monst._mfutx; const int mx = monst.position.future.x;
const int my = monst._mfuty; const int my = monst.position.future.y;
if (!CanTargetMonster(mi)) if (!CanTargetMonster(mi))
continue; continue;
@ -1129,8 +1129,8 @@ bool SpellHasActorTarget()
return false; return false;
if (spl == SPL_FIREWALL && pcursmonst != -1) { if (spl == SPL_FIREWALL && pcursmonst != -1) {
cursmx = monster[pcursmonst]._mx; cursmx = monster[pcursmonst].position.current.x;
cursmy = monster[pcursmonst]._my; cursmy = monster[pcursmonst].position.current.y;
} }
return pcursplr != -1 || pcursmonst != -1; return pcursplr != -1 || pcursmonst != -1;

2
Source/debug.cpp

@ -177,7 +177,7 @@ void PrintDebugMonster(int m)
sprintf(dstr, "Monster %i = %s", m, monster[m].mName); sprintf(dstr, "Monster %i = %s", m, monster[m].mName);
NetSendCmdString(1 << myplr, dstr); NetSendCmdString(1 << myplr, dstr);
sprintf(dstr, "X = %i, Y = %i", monster[m]._mx, monster[m]._my); sprintf(dstr, "X = %i, Y = %i", monster[m].position.current.x, monster[m].position.current.y);
NetSendCmdString(1 << myplr, dstr); NetSendCmdString(1 << myplr, dstr);
sprintf(dstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints); sprintf(dstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints);
NetSendCmdString(1 << myplr, dstr); NetSendCmdString(1 << myplr, dstr);

4
Source/diablo.cpp

@ -1798,8 +1798,8 @@ static void UpdateMonsterLights()
} }
LightListStruct *lid = &LightList[mon->mlid]; LightListStruct *lid = &LightList[mon->mlid];
if (mon->_mx != lid->_lx || mon->_my != lid->_ly) { if (mon->position.current.x != lid->_lx || mon->position.current.y != lid->_ly) {
ChangeLightXY(mon->mlid, mon->_mx, mon->_my); ChangeLightXY(mon->mlid, mon->position.current.x, mon->position.current.y);
} }
} }
} }

2
Source/effects.cpp

@ -1242,7 +1242,7 @@ void PlayEffect(int i, int mode)
return; return;
} }
if (!calc_snd_position(monster[i]._mx, monster[i]._my, &lVolume, &lPan)) if (!calc_snd_position(monster[i].position.current.x, monster[i].position.current.y, &lVolume, &lPan))
return; return;
snd_play_snd(snd, lVolume, lPan); snd_play_snd(snd, lVolume, lPan);

19
Source/engine.h

@ -62,6 +62,25 @@ struct Point {
int y; int y;
}; };
struct ActorPosition {
/** Tile position */
Point current;
/** Future tile position. Set at start of walking animation. */
Point future;
/** Tile position of player. Set via network on player input. */
Point last;
/** Most recent position in dPlayer. */
Point old;
/** Player sprite's pixel offset from tile. */
Point offset;
/** Same as offset but contains the value in a higher range */
Point offset2;
/** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */
Point velocity;
/** 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;
};
// `malloc` that returns a user-friendly error on OOM. // `malloc` that returns a user-friendly error on OOM.
// //
// Defined as a macro so that: // Defined as a macro so that:

92
Source/loadsave.cpp

@ -329,8 +329,8 @@ static void LoadPlayer(LoadHelper *file, int p)
pPlayer->position.future.x = file->nextLE<int32_t>(); pPlayer->position.future.x = file->nextLE<int32_t>();
pPlayer->position.future.y = file->nextLE<int32_t>(); pPlayer->position.future.y = file->nextLE<int32_t>();
file->skip(8); // Skip _ptargx and _ptargy file->skip(8); // Skip _ptargx and _ptargy
pPlayer->position.owner.x = file->nextLE<int32_t>(); pPlayer->position.last.x = file->nextLE<int32_t>();
pPlayer->position.owner.y = file->nextLE<int32_t>(); pPlayer->position.last.y = file->nextLE<int32_t>();
pPlayer->position.old.x = file->nextLE<int32_t>(); pPlayer->position.old.x = file->nextLE<int32_t>();
pPlayer->position.old.y = file->nextLE<int32_t>(); pPlayer->position.old.y = file->nextLE<int32_t>();
pPlayer->position.offset.x = file->nextLE<int32_t>(); pPlayer->position.offset.x = file->nextLE<int32_t>();
@ -421,8 +421,8 @@ static void LoadPlayer(LoadHelper *file, int p)
pPlayer->_pGold = file->nextLE<int32_t>(); pPlayer->_pGold = file->nextLE<int32_t>();
pPlayer->_pInfraFlag = file->nextBool32(); pPlayer->_pInfraFlag = file->nextBool32();
pPlayer->tempPoint.x = file->nextLE<int32_t>(); pPlayer->position.temp.x = file->nextLE<int32_t>();
pPlayer->tempPoint.y = file->nextLE<int32_t>(); pPlayer->position.temp.y = file->nextLE<int32_t>();
pPlayer->tempDirection = static_cast<direction>(file->nextLE<int32_t>()); pPlayer->tempDirection = static_cast<direction>(file->nextLE<int32_t>());
pPlayer->_pVar4 = file->nextLE<int32_t>(); pPlayer->_pVar4 = file->nextLE<int32_t>();
pPlayer->_pVar5 = file->nextLE<int32_t>(); pPlayer->_pVar5 = file->nextLE<int32_t>();
@ -549,20 +549,20 @@ static void LoadMonster(LoadHelper *file, int i)
file->skip(4); // Unused file->skip(4); // Unused
pMonster->_pathcount = file->nextLE<uint8_t>(); pMonster->_pathcount = file->nextLE<uint8_t>();
file->skip(3); // Alignment file->skip(3); // Alignment
pMonster->_mx = file->nextLE<int32_t>(); pMonster->position.current.x = file->nextLE<int32_t>();
pMonster->_my = file->nextLE<int32_t>(); pMonster->position.current.y = file->nextLE<int32_t>();
pMonster->_mfutx = file->nextLE<int32_t>(); pMonster->position.future.x = file->nextLE<int32_t>();
pMonster->_mfuty = file->nextLE<int32_t>(); pMonster->position.future.y = file->nextLE<int32_t>();
pMonster->_moldx = file->nextLE<int32_t>(); pMonster->position.old.x = file->nextLE<int32_t>();
pMonster->_moldy = file->nextLE<int32_t>(); pMonster->position.old.y = file->nextLE<int32_t>();
pMonster->_mxoff = file->nextLE<int32_t>(); pMonster->position.offset.x = file->nextLE<int32_t>();
pMonster->_myoff = file->nextLE<int32_t>(); pMonster->position.offset.y = file->nextLE<int32_t>();
pMonster->_mxvel = file->nextLE<int32_t>(); pMonster->position.velocity.x = file->nextLE<int32_t>();
pMonster->_myvel = file->nextLE<int32_t>(); pMonster->position.velocity.y = 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->_menemyx = file->nextLE<uint8_t>(); pMonster->enemyPosition.x = file->nextLE<uint8_t>();
pMonster->_menemyy = file->nextLE<uint8_t>(); pMonster->enemyPosition.y = file->nextLE<uint8_t>();
file->skip(2); // Unused file->skip(2); // Unused
file->skip(4); // Skip pointer _mAnimData file->skip(4); // Skip pointer _mAnimData
@ -575,11 +575,11 @@ static void LoadMonster(LoadHelper *file, int i)
pMonster->_mVar1 = file->nextLE<int32_t>(); pMonster->_mVar1 = file->nextLE<int32_t>();
pMonster->_mVar2 = file->nextLE<int32_t>(); pMonster->_mVar2 = file->nextLE<int32_t>();
pMonster->_mVar3 = file->nextLE<int32_t>(); pMonster->_mVar3 = file->nextLE<int32_t>();
pMonster->_mVar4 = file->nextLE<int32_t>(); pMonster->position.temp.x = file->nextLE<int32_t>();
pMonster->_mVar5 = file->nextLE<int32_t>(); pMonster->position.temp.y = file->nextLE<int32_t>();
pMonster->_mVar6 = file->nextLE<int32_t>(); pMonster->position.offset2.x = file->nextLE<int32_t>();
pMonster->_mVar7 = file->nextLE<int32_t>(); pMonster->position.offset2.y = file->nextLE<int32_t>();
pMonster->_mVar8 = file->nextLE<int32_t>(); pMonster->actionFrame = file->nextLE<int32_t>();
pMonster->_mmaxhp = file->nextLE<int32_t>(); pMonster->_mmaxhp = file->nextLE<int32_t>();
pMonster->_mhitpoints = file->nextLE<int32_t>(); pMonster->_mhitpoints = file->nextLE<int32_t>();
@ -590,8 +590,8 @@ static void LoadMonster(LoadHelper *file, int i)
pMonster->_msquelch = file->nextLE<uint8_t>(); pMonster->_msquelch = file->nextLE<uint8_t>();
file->skip(3); // Alignment file->skip(3); // Alignment
file->skip(4); // Unused file->skip(4); // Unused
pMonster->_lastx = file->nextLE<int32_t>(); pMonster->position.last.x = file->nextLE<int32_t>();
pMonster->_lasty = file->nextLE<int32_t>(); pMonster->position.last.y = file->nextLE<int32_t>();
pMonster->_mRndSeed = file->nextLE<int32_t>(); pMonster->_mRndSeed = file->nextLE<int32_t>();
pMonster->_mAISeed = file->nextLE<int32_t>(); pMonster->_mAISeed = file->nextLE<int32_t>();
file->skip(4); // Unused file->skip(4); // Unused
@ -1310,8 +1310,8 @@ static void SavePlayer(SaveHelper *file, int p)
file->writeLE<int32_t>(target.x); file->writeLE<int32_t>(target.x);
file->writeLE<int32_t>(target.y); file->writeLE<int32_t>(target.y);
file->writeLE<int32_t>(pPlayer->position.owner.x); file->writeLE<int32_t>(pPlayer->position.last.x);
file->writeLE<int32_t>(pPlayer->position.owner.y); file->writeLE<int32_t>(pPlayer->position.last.y);
file->writeLE<int32_t>(pPlayer->position.old.x); file->writeLE<int32_t>(pPlayer->position.old.x);
file->writeLE<int32_t>(pPlayer->position.old.y); file->writeLE<int32_t>(pPlayer->position.old.y);
file->writeLE<int32_t>(pPlayer->position.offset.x); file->writeLE<int32_t>(pPlayer->position.offset.x);
@ -1401,8 +1401,8 @@ static void SavePlayer(SaveHelper *file, int p)
file->writeLE<int32_t>(pPlayer->_pGold); file->writeLE<int32_t>(pPlayer->_pGold);
file->writeLE<uint32_t>(pPlayer->_pInfraFlag); file->writeLE<uint32_t>(pPlayer->_pInfraFlag);
file->writeLE<int32_t>(pPlayer->tempPoint.x); file->writeLE<int32_t>(pPlayer->position.temp.x);
file->writeLE<int32_t>(pPlayer->tempPoint.y); file->writeLE<int32_t>(pPlayer->position.temp.y);
file->writeLE<int32_t>(pPlayer->tempDirection); file->writeLE<int32_t>(pPlayer->tempDirection);
file->writeLE<int32_t>(pPlayer->_pVar4); file->writeLE<int32_t>(pPlayer->_pVar4);
file->writeLE<int32_t>(pPlayer->_pVar5); file->writeLE<int32_t>(pPlayer->_pVar5);
@ -1518,20 +1518,20 @@ static void SaveMonster(SaveHelper *file, int i)
file->skip(4); // Unused file->skip(4); // Unused
file->writeLE<uint8_t>(pMonster->_pathcount); file->writeLE<uint8_t>(pMonster->_pathcount);
file->skip(3); // Alignment file->skip(3); // Alignment
file->writeLE<int32_t>(pMonster->_mx); file->writeLE<int32_t>(pMonster->position.current.x);
file->writeLE<int32_t>(pMonster->_my); file->writeLE<int32_t>(pMonster->position.current.y);
file->writeLE<int32_t>(pMonster->_mfutx); file->writeLE<int32_t>(pMonster->position.future.x);
file->writeLE<int32_t>(pMonster->_mfuty); file->writeLE<int32_t>(pMonster->position.future.y);
file->writeLE<int32_t>(pMonster->_moldx); file->writeLE<int32_t>(pMonster->position.old.x);
file->writeLE<int32_t>(pMonster->_moldy); file->writeLE<int32_t>(pMonster->position.old.y);
file->writeLE<int32_t>(pMonster->_mxoff); file->writeLE<int32_t>(pMonster->position.offset.x);
file->writeLE<int32_t>(pMonster->_myoff); file->writeLE<int32_t>(pMonster->position.offset.y);
file->writeLE<int32_t>(pMonster->_mxvel); file->writeLE<int32_t>(pMonster->position.velocity.x);
file->writeLE<int32_t>(pMonster->_myvel); file->writeLE<int32_t>(pMonster->position.velocity.y);
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->_menemyx); file->writeLE<uint8_t>(pMonster->enemyPosition.x);
file->writeLE<uint8_t>(pMonster->_menemyy); file->writeLE<uint8_t>(pMonster->enemyPosition.y);
file->skip(2); // Unused file->skip(2); // Unused
file->skip(4); // Skip pointer _mAnimData file->skip(4); // Skip pointer _mAnimData
@ -1544,11 +1544,11 @@ static void SaveMonster(SaveHelper *file, int i)
file->writeLE<int32_t>(pMonster->_mVar1); file->writeLE<int32_t>(pMonster->_mVar1);
file->writeLE<int32_t>(pMonster->_mVar2); file->writeLE<int32_t>(pMonster->_mVar2);
file->writeLE<int32_t>(pMonster->_mVar3); file->writeLE<int32_t>(pMonster->_mVar3);
file->writeLE<int32_t>(pMonster->_mVar4); file->writeLE<int32_t>(pMonster->position.temp.x);
file->writeLE<int32_t>(pMonster->_mVar5); file->writeLE<int32_t>(pMonster->position.temp.y);
file->writeLE<int32_t>(pMonster->_mVar6); file->writeLE<int32_t>(pMonster->position.offset2.x);
file->writeLE<int32_t>(pMonster->_mVar7); file->writeLE<int32_t>(pMonster->position.offset2.y);
file->writeLE<int32_t>(pMonster->_mVar8); file->writeLE<int32_t>(pMonster->actionFrame);
file->writeLE<int32_t>(pMonster->_mmaxhp); file->writeLE<int32_t>(pMonster->_mmaxhp);
file->writeLE<int32_t>(pMonster->_mhitpoints); file->writeLE<int32_t>(pMonster->_mhitpoints);
@ -1559,8 +1559,8 @@ static void SaveMonster(SaveHelper *file, int i)
file->writeLE<uint8_t>(pMonster->_msquelch); file->writeLE<uint8_t>(pMonster->_msquelch);
file->skip(3); // Alignment file->skip(3); // Alignment
file->skip(4); // Unused file->skip(4); // Unused
file->writeLE<int32_t>(pMonster->_lastx); file->writeLE<int32_t>(pMonster->position.last.x);
file->writeLE<int32_t>(pMonster->_lasty); file->writeLE<int32_t>(pMonster->position.last.y);
file->writeLE<int32_t>(pMonster->_mRndSeed); file->writeLE<int32_t>(pMonster->_mRndSeed);
file->writeLE<int32_t>(pMonster->_mAISeed); file->writeLE<int32_t>(pMonster->_mAISeed);
file->skip(4); // Unused file->skip(4); // Unused

42
Source/missiles.cpp

@ -678,8 +678,7 @@ bool MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, bool
if (monster[m]._msquelch == 0) { if (monster[m]._msquelch == 0) {
monster[m]._msquelch = UCHAR_MAX; monster[m]._msquelch = UCHAR_MAX;
monster[m]._lastx = plr[pnum].position.current.x; monster[m].position.last = plr[pnum].position.current;
monster[m]._lasty = plr[pnum].position.current.y;
} }
return true; return true;
} }
@ -799,7 +798,7 @@ bool PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, bool s
if ((resper <= 0 || gbIsHellfire) && blk < blkper) { if ((resper <= 0 || gbIsHellfire) && blk < blkper) {
direction dir = plr[pnum]._pdir; direction dir = plr[pnum]._pdir;
if (m != -1) { if (m != -1) {
dir = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[m]._mx, monster[m]._my); dir = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[m].position.current.x, monster[m].position.current.y);
} }
*blocked = true; *blocked = true;
StartPlrBlock(pnum, dir); StartPlrBlock(pnum, dir);
@ -1435,7 +1434,7 @@ void AddBerserk(int mi, int sx, int sy, int dx, int dy, int midir, int8_t mienem
r = 3; r = 3;
else else
r = 9; r = 9;
monster[dm].mlid = AddLight(monster[dm]._mx, monster[dm]._my, r); monster[dm].mlid = AddLight(monster[dm].position.current.x, monster[dm].position.current.y, r);
UseMana(id, SPL_BERSERK); UseMana(id, SPL_BERSERK);
break; break;
} }
@ -2577,7 +2576,7 @@ void AddFireman(int mi, int sx, int sy, int dx, int dy, int midir, int8_t mienem
if (monster[id]._uniqtype != 0) if (monster[id]._uniqtype != 0)
missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1; missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1;
mon = &monster[id]; mon = &monster[id];
dMonster[mon->_mx][mon->_my] = 0; dMonster[mon->position.current.x][mon->position.current.y] = 0;
missile[mi]._mirange = 256; missile[mi]._mirange = 256;
PutMissile(mi); PutMissile(mi);
} }
@ -2717,7 +2716,7 @@ void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, int8_t mienemy,
missile[mi]._miVar2 = sy; missile[mi]._miVar2 = sy;
missile[mi]._miVar4 = dx; missile[mi]._miVar4 = dx;
missile[mi]._miVar5 = dy; missile[mi]._miVar5 = dy;
if ((monster[id]._mx != 1 || monster[id]._my) && id == myplr) if ((monster[id].position.current.x != 1 || monster[id].position.current.y) && id == myplr)
M_StartKill(id, id); M_StartKill(id, id);
UseMana(id, SPL_GOLEM); UseMana(id, SPL_GOLEM);
} }
@ -3307,7 +3306,7 @@ void MI_Golem(int i)
const char *ct; const char *ct;
src = missile[i]._misource; src = missile[i]._misource;
if (monster[src]._mx == 1 && monster[src]._my == 0) { if (monster[src].position.current.x == 1 && monster[src].position.current.y == 0) {
for (l = 0; l < 6; l++) { for (l = 0; l < 6; l++) {
k = CrawlNum[l]; k = CrawlNum[l];
tid = k + 2; tid = k + 2;
@ -3637,8 +3636,8 @@ void FireballUpdate(int i, int xof, int yof, bool alwaysDelete)
px = plr[id].position.current.x; px = plr[id].position.current.x;
py = plr[id].position.current.y; py = plr[id].position.current.y;
} else { } else {
px = monster[id]._mx; px = monster[id].position.current.x;
py = monster[id]._my; py = monster[id].position.current.y;
} }
if (missile[i]._miAnimType == MFILE_BIGEXP) { if (missile[i]._miAnimType == MFILE_BIGEXP) {
@ -3760,7 +3759,7 @@ void MI_Rune(int i)
mid = mid - 1; mid = mid - 1;
else else
mid = -(mid + 1); mid = -(mid + 1);
dir = GetDirection(missile[i]._mix, missile[i]._miy, monster[mid]._mx, monster[mid]._my); dir = GetDirection(missile[i]._mix, missile[i]._miy, monster[mid].position.current.x, monster[mid].position.current.y);
} else { } else {
if (pid > 0) if (pid > 0)
pid = pid - 1; pid = pid - 1;
@ -4680,7 +4679,7 @@ void MI_Stone(int i)
if (monster[m]._mhitpoints > 0) if (monster[m]._mhitpoints > 0)
monster[m]._mmode = (MON_MODE)missile[i]._miVar1; monster[m]._mmode = (MON_MODE)missile[i]._miVar1;
else else
AddDead(monster[m]._mx, monster[m]._my, stonendx, monster[m]._mdir); AddDead(monster[m].position.current.x, monster[m].position.current.y, stonendx, monster[m]._mdir);
} }
if (missile[i]._miAnimType == MFILE_SHATTER1) if (missile[i]._miAnimType == MFILE_SHATTER1)
PutMissile(i); PutMissile(i);
@ -4731,13 +4730,10 @@ void MI_Rhino(int i)
missile[i]._miDelFlag = true; missile[i]._miDelFlag = true;
return; return;
} }
monster[monst]._mfutx = omx; monster[monst].position.future = { omx, omy };
monster[monst]._moldx = omx; monster[monst].position.old = { omx, omy };
monster[monst].position.current = { omx, omy };
dMonster[omx][omy] = -(monst + 1); dMonster[omx][omy] = -(monst + 1);
monster[monst]._mx = omx;
monster[monst]._mfuty = omy;
monster[monst]._moldy = omy;
monster[monst]._my = omy;
if (monster[monst]._uniqtype != 0) if (monster[monst]._uniqtype != 0)
ChangeLightXY(missile[i]._mlid, omx, omy); ChangeLightXY(missile[i]._mlid, omx, omy);
MoveMissilePos(i); MoveMissilePos(i);
@ -4762,8 +4758,8 @@ void MI_Fireman(int i)
cx = plr[enemy].position.current.x; cx = plr[enemy].position.current.x;
cy = plr[enemy].position.current.y; cy = plr[enemy].position.current.y;
} else { } else {
cx = monster[enemy]._mx; cx = monster[enemy].position.current.x;
cy = monster[enemy]._my; cy = monster[enemy].position.current.y;
} }
if ((bx != ax || by != ay) && ((missile[i]._miVar1 & 1 && (abs(ax - cx) >= 4 || abs(ay - cy) >= 4)) || missile[i]._miVar2 > 1) && PosOkMonst(missile[i]._misource, ax, ay)) { if ((bx != ax || by != ay) && ((missile[i]._miVar1 & 1 && (abs(ax - cx) >= 4 || abs(ay - cy) >= 4)) || missile[i]._miVar2 > 1) && PosOkMonst(missile[i]._misource, ax, ay)) {
MissToMonst(i, ax, ay); MissToMonst(i, ax, ay);
@ -5154,9 +5150,9 @@ void MI_Element(int i)
missile[i]._mirange = 255; missile[i]._mirange = 255;
mid = FindClosest(cx, cy, 19); mid = FindClosest(cx, cy, 19);
if (mid > 0) { if (mid > 0) {
direction sd = GetDirection(cx, cy, monster[mid]._mx, monster[mid]._my); direction sd = GetDirection(cx, cy, monster[mid].position.current.x, monster[mid].position.current.y);
SetMissDir(i, sd); SetMissDir(i, sd);
GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); GetMissileVel(i, cx, cy, monster[mid].position.current.x, monster[mid].position.current.y, 16);
} else { } else {
direction sd = plr[id]._pdir; direction sd = plr[id]._pdir;
SetMissDir(i, sd); SetMissDir(i, sd);
@ -5207,8 +5203,8 @@ void MI_Bonespirit(int i)
mid = FindClosest(cx, cy, 19); mid = FindClosest(cx, cy, 19);
if (mid > 0) { if (mid > 0) {
missile[i]._midam = monster[mid]._mhitpoints >> 7; missile[i]._midam = monster[mid]._mhitpoints >> 7;
SetMissDir(i, GetDirection(cx, cy, monster[mid]._mx, monster[mid]._my)); SetMissDir(i, GetDirection(cx, cy, monster[mid].position.current.x, monster[mid].position.current.y));
GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16); GetMissileVel(i, cx, cy, monster[mid].position.current.x, monster[mid].position.current.y, 16);
} else { } else {
direction sd = plr[id]._pdir; direction sd = plr[id]._pdir;
SetMissDir(i, sd); SetMissDir(i, sd);

879
Source/monster.cpp

File diff suppressed because it is too large Load Diff

37
Source/monster.h

@ -140,34 +140,13 @@ struct MonsterStruct { // note: missing field _mAFNum
int _mgoalvar2; int _mgoalvar2;
int _mgoalvar3; int _mgoalvar3;
uint8_t _pathcount; uint8_t _pathcount;
/** Tile X-position of monster */ ActorPosition position;
int _mx;
/** Tile Y-position of monster */
int _my;
/** Future tile X-position of monster. Set at start of walking animation */
int _mfutx;
/** Future tile Y-position of monster. Set at start of walking animation */
int _mfuty;
/** Most recent X-position in dMonster. */
int _moldx;
/** Most recent Y-position in dMonster. */
int _moldy;
/** Monster sprite's pixel X-offset from tile. */
int _mxoff;
/** Monster sprite's pixel Y-offset from tile. */
int _myoff;
/** Pixel X-velocity while walking. Applied to _mxoff */
int _mxvel;
/** Pixel Y-velocity while walking. Applied to _myoff */
int _myvel;
/** Direction faced by monster (direction enum) */ /** Direction faced by monster (direction enum) */
direction _mdir; direction _mdir;
/** The current target of the mosnter. An index in to either the plr or monster array based on the _meflag value. */ /** The current target of the mosnter. An index in to either the plr or monster array based on the _meflag value. */
int _menemy; int _menemy;
/** X-coordinate of enemy (usually correspond's to the enemy's futx value) */ /** Usually correspond's to the enemy's future position */
uint8_t _menemyx; Point enemyPosition;
/** Y-coordinate of enemy (usually correspond's to the enemy's futy value) */
uint8_t _menemyy;
uint8_t *_mAnimData; uint8_t *_mAnimData;
/** Tick length of each frame in the current animation */ /** Tick length of each frame in the current animation */
int _mAnimDelay; int _mAnimDelay;
@ -181,22 +160,14 @@ struct MonsterStruct { // note: missing field _mAFNum
int _mVar1; int _mVar1;
int _mVar2; int _mVar2;
int _mVar3; int _mVar3;
int _mVar4;
int _mVar5;
/** Used as _mxoff but with a higher range so that we can correctly apply velocities of a smaller number */
int _mVar6;
/** Used as _myoff but with a higher range so that we can correctly apply velocities of a smaller number */
int _mVar7;
/** Value used to measure progress for moving from one tile to another */ /** Value used to measure progress for moving from one tile to another */
int _mVar8; int actionFrame;
int _mmaxhp; int _mmaxhp;
int _mhitpoints; int _mhitpoints;
_mai_id _mAi; _mai_id _mAi;
uint8_t _mint; uint8_t _mint;
uint32_t _mFlags; uint32_t _mFlags;
uint8_t _msquelch; uint8_t _msquelch;
int _lastx;
int _lasty;
int _mRndSeed; int _mRndSeed;
int _mAISeed; int _mAISeed;
uint8_t _uniqtype; uint8_t _uniqtype;

31
Source/msg.cpp

@ -510,8 +510,8 @@ void delta_leave_sync(BYTE bLevel)
continue; continue;
sgbDeltaChanged = true; sgbDeltaChanged = true;
DMonsterStr *pD = &sgLevels[bLevel].monster[ma]; DMonsterStr *pD = &sgLevels[bLevel].monster[ma];
pD->_mx = monster[ma]._mx; pD->_mx = monster[ma].position.current.x;
pD->_my = monster[ma]._my; pD->_my = monster[ma].position.current.y;
pD->_mdir = monster[ma]._mdir; pD->_mdir = monster[ma]._mdir;
pD->_menemy = encode_enemy(ma); pD->_menemy = encode_enemy(ma);
pD->_mhitpoints = monster[ma]._mhitpoints; pD->_mhitpoints = monster[ma]._mhitpoints;
@ -709,32 +709,29 @@ void DeltaLoadLevel()
M_ClearSquares(i); M_ClearSquares(i);
x = sgLevels[currlevel].monster[i]._mx; x = sgLevels[currlevel].monster[i]._mx;
y = sgLevels[currlevel].monster[i]._my; y = sgLevels[currlevel].monster[i]._my;
monster[i]._mx = x; monster[i].position.current = { x, y };
monster[i]._my = y; monster[i].position.old = { x, y };
monster[i]._moldx = x; monster[i].position.future = { x, y };
monster[i]._moldy = y;
monster[i]._mfutx = x;
monster[i]._mfuty = y;
if (sgLevels[currlevel].monster[i]._mhitpoints != -1) if (sgLevels[currlevel].monster[i]._mhitpoints != -1)
monster[i]._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints; monster[i]._mhitpoints = sgLevels[currlevel].monster[i]._mhitpoints;
if (sgLevels[currlevel].monster[i]._mhitpoints == 0) { if (sgLevels[currlevel].monster[i]._mhitpoints == 0) {
monster[i]._moldx = sgLevels[currlevel].monster[i]._mx; // CODEFIX: useless assignment monster[i].position.old.x = sgLevels[currlevel].monster[i]._mx; // CODEFIX: useless assignment
monster[i]._moldy = sgLevels[currlevel].monster[i]._my; // CODEFIX: useless assignment monster[i].position.old.y = sgLevels[currlevel].monster[i]._my; // CODEFIX: useless assignment
M_ClearSquares(i); M_ClearSquares(i);
if (monster[i]._mAi != AI_DIABLO) { if (monster[i]._mAi != AI_DIABLO) {
if (monster[i]._uniqtype == 0) { if (monster[i]._uniqtype == 0) {
assert(monster[i].MType != nullptr); assert(monster[i].MType != nullptr);
AddDead(monster[i]._mx, monster[i]._my, monster[i].MType->mdeadval, monster[i]._mdir); AddDead(monster[i].position.current.x, monster[i].position.current.y, monster[i].MType->mdeadval, monster[i]._mdir);
} else { } else {
AddDead(monster[i]._mx, monster[i]._my, monster[i]._udeadval, monster[i]._mdir); AddDead(monster[i].position.current.x, monster[i].position.current.y, monster[i]._udeadval, monster[i]._mdir);
} }
} }
monster[i]._mDelFlag = true; monster[i]._mDelFlag = true;
M_UpdateLeader(i); M_UpdateLeader(i);
} else { } else {
decode_enemy(i, sgLevels[currlevel].monster[i]._menemy); decode_enemy(i, sgLevels[currlevel].monster[i]._menemy);
if ((monster[i]._mx && monster[i]._mx != 1) || monster[i]._my) if ((monster[i].position.current.x && monster[i].position.current.x != 1) || monster[i].position.current.y)
dMonster[monster[i]._mx][monster[i]._my] = i + 1; dMonster[monster[i].position.current.x][monster[i].position.current.y] = i + 1;
if (i < MAX_PLRS) { if (i < MAX_PLRS) {
MAI_Golum(i); MAI_Golum(i);
monster[i]._mFlags |= (MFLAG_TARGETS_MONSTER | MFLAG_GOLEM); monster[i]._mFlags |= (MFLAG_TARGETS_MONSTER | MFLAG_GOLEM);
@ -1759,10 +1756,10 @@ static DWORD On_ATTACKID(TCmd *pCmd, int pnum)
auto *p = (TCmdParam1 *)pCmd; auto *p = (TCmdParam1 *)pCmd;
if (gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) { if (gbBufferMsgs != 1 && currlevel == plr[pnum].plrlevel) {
int distx = abs(plr[pnum].position.current.x - monster[p->wParam1]._mfutx); int distx = abs(plr[pnum].position.current.x - monster[p->wParam1].position.future.x);
int disty = abs(plr[pnum].position.current.y - monster[p->wParam1]._mfuty); int disty = abs(plr[pnum].position.current.y - monster[p->wParam1].position.future.y);
if (distx > 1 || disty > 1) if (distx > 1 || disty > 1)
MakePlrPath(pnum, monster[p->wParam1]._mfutx, monster[p->wParam1]._mfuty, false); MakePlrPath(pnum, monster[p->wParam1].position.future.x, monster[p->wParam1].position.future.y, false);
plr[pnum].destAction = ACTION_ATTACKMON; plr[pnum].destAction = ACTION_ATTACKMON;
plr[pnum].destParam1 = p->wParam1; plr[pnum].destParam1 = p->wParam1;
} }

2
Source/multi.cpp

@ -475,7 +475,7 @@ void multi_process_network_packets()
continue; continue;
if (pkt->wLen != dwMsgSize) if (pkt->wLen != dwMsgSize)
continue; continue;
plr[dwID].position.owner = { pkt->px, pkt->py }; plr[dwID].position.last = { pkt->px, pkt->py };
if (dwID != myplr) { if (dwID != myplr) {
assert(gbBufferMsgs != 2); assert(gbBufferMsgs != 2);
plr[dwID]._pHitPoints = pkt->php; plr[dwID]._pHitPoints = pkt->php;

4
Source/objects.cpp

@ -2819,8 +2819,8 @@ void MonstCheckDoors(int m)
int i, oi; int i, oi;
int dpx, dpy, mx, my; int dpx, dpy, mx, my;
mx = monster[m]._mx; mx = monster[m].position.current.x;
my = monster[m]._my; my = monster[m].position.current.y;
if (dObject[mx - 1][my - 1] != 0 if (dObject[mx - 1][my - 1] != 0
|| dObject[mx][my - 1] != 0 || dObject[mx][my - 1] != 0
|| dObject[mx + 1][my - 1] != 0 || dObject[mx + 1][my - 1] != 0

84
Source/player.cpp

@ -631,7 +631,7 @@ void ClearPlrPVars(int pnum)
app_fatal("ClearPlrPVars: illegal player %d", pnum); app_fatal("ClearPlrPVars: illegal player %d", pnum);
} }
plr[pnum].tempPoint = { 0, 0 }; plr[pnum].position.temp = { 0, 0 };
plr[pnum].tempDirection = DIR_S; plr[pnum].tempDirection = DIR_S;
plr[pnum]._pVar4 = 0; plr[pnum]._pVar4 = 0;
plr[pnum]._pVar5 = 0; plr[pnum]._pVar5 = 0;
@ -1472,14 +1472,14 @@ void StartWalk(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int y
plr[pnum]._pmode = PM_WALK; plr[pnum]._pmode = PM_WALK;
plr[pnum].position.velocity = { xvel, yvel }; plr[pnum].position.velocity = { xvel, yvel };
plr[pnum].position.offset = { 0, 0 }; plr[pnum].position.offset = { 0, 0 };
plr[pnum].tempPoint = { xadd, yadd }; plr[pnum].position.temp = { xadd, yadd };
plr[pnum].tempDirection = EndDir; plr[pnum].tempDirection = EndDir;
plr[pnum].position.offset2 = { 0, 0 }; plr[pnum].position.offset2 = { 0, 0 };
break; break;
case PM_WALK2: case PM_WALK2:
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = -(pnum + 1); dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = -(pnum + 1);
plr[pnum].tempPoint = plr[pnum].position.current; plr[pnum].position.temp = plr[pnum].position.current;
plr[pnum].position.current = { px, py }; // Move player to the next tile to maintain correct render order plr[pnum].position.current = { px, py }; // Move player to the next tile to maintain correct render order
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1; dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1;
plr[pnum].position.offset = { xoff, yoff }; // Offset player sprite to align with their previous tile position plr[pnum].position.offset = { xoff, yoff }; // Offset player sprite to align with their previous tile position
@ -1510,7 +1510,7 @@ void StartWalk(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int y
plr[pnum]._pmode = PM_WALK3; plr[pnum]._pmode = PM_WALK3;
plr[pnum].position.velocity = { xvel, yvel }; plr[pnum].position.velocity = { xvel, yvel };
plr[pnum].tempPoint = { px, py }; plr[pnum].position.temp = { px, py };
plr[pnum].position.offset2 = { xoff * 256, yoff * 256 }; plr[pnum].position.offset2 = { xoff * 256, yoff * 256 };
plr[pnum].tempDirection = EndDir; plr[pnum].tempDirection = EndDir;
break; break;
@ -1603,7 +1603,7 @@ void StartRangeAttack(int pnum, direction d, int cx, int cy)
plr[pnum]._pmode = PM_RATTACK; plr[pnum]._pmode = PM_RATTACK;
FixPlayerLocation(pnum, d); FixPlayerLocation(pnum, d);
SetPlayerOld(pnum); SetPlayerOld(pnum);
plr[pnum].tempPoint = { cx, cy }; plr[pnum].position.temp = { cx, cy };
} }
void StartPlrBlock(int pnum, direction dir) void StartPlrBlock(int pnum, direction dir)
@ -1675,7 +1675,7 @@ void StartSpell(int pnum, direction d, int cx, int cy)
FixPlayerLocation(pnum, d); FixPlayerLocation(pnum, d);
SetPlayerOld(pnum); SetPlayerOld(pnum);
plr[pnum].tempPoint = { cx, cy }; plr[pnum].position.temp = { cx, cy };
plr[pnum]._pVar4 = GetSpellLevel(pnum, plr[pnum]._pSpell); plr[pnum]._pVar4 = GetSpellLevel(pnum, plr[pnum]._pSpell);
plr[pnum].actionFrame = 1; plr[pnum].actionFrame = 1;
} }
@ -2152,11 +2152,11 @@ void RemovePlrMissiles(int pnum)
int i, am; int i, am;
int mx, my; int mx, my;
if (currlevel != 0 && pnum == myplr && (monster[myplr]._mx != 1 || monster[myplr]._my != 0)) { if (currlevel != 0 && pnum == myplr && (monster[myplr].position.current.x != 1 || monster[myplr].position.current.y != 0)) {
M_StartKill(myplr, myplr); M_StartKill(myplr, myplr);
AddDead(monster[myplr]._mx, monster[myplr]._my, (monster[myplr].MType)->mdeadval, monster[myplr]._mdir); AddDead(monster[myplr].position.current.x, monster[myplr].position.current.y, (monster[myplr].MType)->mdeadval, monster[myplr]._mdir);
mx = monster[myplr]._mx; mx = monster[myplr].position.current.x;
my = monster[myplr]._my; my = monster[myplr].position.current.y;
dMonster[mx][my] = 0; dMonster[mx][my] = 0;
monster[myplr]._mDelFlag = true; monster[myplr]._mDelFlag = true;
DeleteMonsterList(); DeleteMonsterList();
@ -2333,17 +2333,17 @@ bool PM_DoWalk(int pnum, int variant)
switch (variant) { switch (variant) {
case PM_WALK: case PM_WALK:
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = 0; dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = 0;
plr[pnum].position.current.x += plr[pnum].tempPoint.x; plr[pnum].position.current.x += plr[pnum].position.temp.x;
plr[pnum].position.current.y += plr[pnum].tempPoint.y; plr[pnum].position.current.y += plr[pnum].position.temp.y;
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1; dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1;
break; break;
case PM_WALK2: case PM_WALK2:
dPlayer[plr[pnum].tempPoint.x][plr[pnum].tempPoint.y] = 0; dPlayer[plr[pnum].position.temp.x][plr[pnum].position.temp.y] = 0;
break; break;
case PM_WALK3: case PM_WALK3:
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = 0; dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = 0;
dFlags[plr[pnum]._pVar4][plr[pnum]._pVar5] &= ~BFLAG_PLAYERLR; dFlags[plr[pnum]._pVar4][plr[pnum]._pVar5] &= ~BFLAG_PLAYERLR;
plr[pnum].position.current = plr[pnum].tempPoint; plr[pnum].position.current = plr[pnum].position.temp;
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1; dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1;
break; break;
} }
@ -2557,7 +2557,7 @@ bool PlrHitMonst(int pnum, int m)
#endif #endif
if (plr[pnum]._pIFlags & ISPL_FIREDAM && plr[pnum]._pIFlags & ISPL_LIGHTDAM) { if (plr[pnum]._pIFlags & ISPL_FIREDAM && plr[pnum]._pIFlags & ISPL_LIGHTDAM) {
int midam = plr[pnum]._pIFMinDam + GenerateRnd(plr[pnum]._pIFMaxDam - plr[pnum]._pIFMinDam); int midam = plr[pnum]._pIFMinDam + GenerateRnd(plr[pnum]._pIFMaxDam - plr[pnum]._pIFMinDam);
AddMissile(plr[pnum].position.current.x, plr[pnum].position.current.y, plr[pnum].tempPoint.x, plr[pnum].tempPoint.y, plr[pnum]._pdir, MIS_SPECARROW, TARGET_MONSTERS, pnum, midam, 0); AddMissile(plr[pnum].position.current.x, plr[pnum].position.current.y, plr[pnum].position.temp.x, plr[pnum].position.temp.y, plr[pnum]._pdir, MIS_SPECARROW, TARGET_MONSTERS, pnum, midam, 0);
} }
mind = plr[pnum]._pIMinDam; mind = plr[pnum]._pIMinDam;
maxd = plr[pnum]._pIMaxDam; maxd = plr[pnum]._pIMaxDam;
@ -2860,7 +2860,7 @@ bool PM_DoAttack(int pnum)
m = -(dMonster[dx][dy] + 1); m = -(dMonster[dx][dy] + 1);
} }
if (CanTalkToMonst(m)) { if (CanTalkToMonst(m)) {
plr[pnum].tempPoint.x = 0; /** @todo Looks to be irrelevant, probably just remove it */ plr[pnum].position.temp.x = 0; /** @todo Looks to be irrelevant, probably just remove it */
return false; return false;
} }
} }
@ -2906,14 +2906,14 @@ bool PM_DoAttack(int pnum)
dx = plr[pnum].position.current.x + offset_x[(plr[pnum]._pdir + 1) % 8]; dx = plr[pnum].position.current.x + offset_x[(plr[pnum]._pdir + 1) % 8];
dy = plr[pnum].position.current.y + offset_y[(plr[pnum]._pdir + 1) % 8]; dy = plr[pnum].position.current.y + offset_y[(plr[pnum]._pdir + 1) % 8];
m = ((dMonster[dx][dy] > 0) ? dMonster[dx][dy] : -dMonster[dx][dy]) - 1; m = ((dMonster[dx][dy] > 0) ? dMonster[dx][dy] : -dMonster[dx][dy]) - 1;
if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && monster[m]._moldx == dx && monster[m]._moldy == dy) { if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && monster[m].position.old.x == dx && monster[m].position.old.y == dy) {
if (PlrHitMonst(-pnum, m)) if (PlrHitMonst(-pnum, m))
didhit = true; didhit = true;
} }
dx = plr[pnum].position.current.x + offset_x[(plr[pnum]._pdir + 7) % 8]; dx = plr[pnum].position.current.x + offset_x[(plr[pnum]._pdir + 7) % 8];
dy = plr[pnum].position.current.y + offset_y[(plr[pnum]._pdir + 7) % 8]; dy = plr[pnum].position.current.y + offset_y[(plr[pnum]._pdir + 7) % 8];
m = ((dMonster[dx][dy] > 0) ? dMonster[dx][dy] : -dMonster[dx][dy]) - 1; m = ((dMonster[dx][dy] > 0) ? dMonster[dx][dy] : -dMonster[dx][dy]) - 1;
if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && monster[m]._moldx == dx && monster[m]._moldy == dy) { if (dMonster[dx][dy] != 0 && !CanTalkToMonst(m) && monster[m].position.old.x == dx && monster[m].position.old.y == dy) {
if (PlrHitMonst(-pnum, m)) if (PlrHitMonst(-pnum, m))
didhit = true; didhit = true;
} }
@ -2965,10 +2965,10 @@ bool PM_DoRangeAttack(int pnum)
int yoff = 0; int yoff = 0;
if (arrows != 1) { if (arrows != 1) {
int angle = arrow == 0 ? -1 : 1; int angle = arrow == 0 ? -1 : 1;
int x = plr[pnum].tempPoint.x - plr[pnum].position.current.x; int x = plr[pnum].position.temp.x - plr[pnum].position.current.x;
if (x != 0) if (x != 0)
yoff = x < 0 ? angle : -angle; yoff = x < 0 ? angle : -angle;
int y = plr[pnum].tempPoint.y - plr[pnum].position.current.y; int y = plr[pnum].position.temp.y - plr[pnum].position.current.y;
if (y != 0) if (y != 0)
xoff = y < 0 ? -angle : angle; xoff = y < 0 ? -angle : angle;
} }
@ -2989,8 +2989,8 @@ bool PM_DoRangeAttack(int pnum)
AddMissile( AddMissile(
plr[pnum].position.current.x, plr[pnum].position.current.x,
plr[pnum].position.current.y, plr[pnum].position.current.y,
plr[pnum].tempPoint.x + xoff, plr[pnum].position.temp.x + xoff,
plr[pnum].tempPoint.y + yoff, plr[pnum].position.temp.y + yoff,
plr[pnum]._pdir, plr[pnum]._pdir,
mistype, mistype,
TARGET_MONSTERS, TARGET_MONSTERS,
@ -3137,8 +3137,8 @@ bool PM_DoSpell(int pnum)
plr[pnum]._pSpell, plr[pnum]._pSpell,
plr[pnum].position.current.x, plr[pnum].position.current.x,
plr[pnum].position.current.y, plr[pnum].position.current.y,
plr[pnum].tempPoint.x, plr[pnum].position.temp.x,
plr[pnum].tempPoint.y, plr[pnum].position.temp.y,
plr[pnum]._pVar4); plr[pnum]._pVar4);
if (plr[pnum]._pSplFrom == 0) { if (plr[pnum]._pSplFrom == 0) {
@ -3235,7 +3235,7 @@ void CheckNewPath(int pnum)
if (plr[pnum].destAction == ACTION_ATTACKMON) { if (plr[pnum].destAction == ACTION_ATTACKMON) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
MakePlrPath(pnum, monster[i]._mfutx, monster[i]._mfuty, false); MakePlrPath(pnum, monster[i].position.future.x, monster[i].position.future.y, false);
} }
if (plr[pnum].destAction == ACTION_ATTACKPLR) { if (plr[pnum].destAction == ACTION_ATTACKPLR) {
@ -3251,9 +3251,9 @@ void CheckNewPath(int pnum)
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
if (plr[pnum].destAction == ACTION_ATTACKMON) { if (plr[pnum].destAction == ACTION_ATTACKMON) {
x = abs(plr[pnum].position.future.x - monster[i]._mfutx); x = abs(plr[pnum].position.future.x - monster[i].position.future.x);
y = abs(plr[pnum].position.future.y - monster[i]._mfuty); 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]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
} else { } else {
x = abs(plr[pnum].position.future.x - plr[i].position.future.x); x = abs(plr[pnum].position.future.x - plr[i].position.future.x);
y = abs(plr[pnum].position.future.y - plr[i].position.future.y); y = abs(plr[pnum].position.future.y - plr[i].position.future.y);
@ -3335,10 +3335,10 @@ void CheckNewPath(int pnum)
break; break;
case ACTION_ATTACKMON: case ACTION_ATTACKMON:
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
x = abs(plr[pnum].position.current.x - monster[i]._mfutx); x = abs(plr[pnum].position.current.x - monster[i].position.future.x);
y = abs(plr[pnum].position.current.y - monster[i]._mfuty); y = abs(plr[pnum].position.current.y - monster[i].position.future.y);
if (x <= 1 && y <= 1) { if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) { if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
TalktoMonster(i); TalktoMonster(i);
} else { } else {
@ -3361,11 +3361,11 @@ void CheckNewPath(int pnum)
break; break;
case ACTION_RATTACKMON: case ACTION_RATTACKMON:
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) { if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
TalktoMonster(i); TalktoMonster(i);
} else { } else {
StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty); StartRangeAttack(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
} }
break; break;
case ACTION_RATTACKPLR: case ACTION_RATTACKPLR:
@ -3385,8 +3385,8 @@ void CheckNewPath(int pnum)
break; break;
case ACTION_SPELLMON: case ACTION_SPELLMON:
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i].position.future.x, monster[i].position.future.y);
StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty); StartSpell(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum]._pVar4 = plr[pnum].destParam2; plr[pnum]._pVar4 = plr[pnum].destParam2;
break; break;
case ACTION_SPELLPLR: case ACTION_SPELLPLR:
@ -3477,10 +3477,10 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_ATTACKMON) { } else if (plr[pnum].destAction == ACTION_ATTACKMON) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
x = abs(plr[pnum].position.current.x - monster[i]._mfutx); x = abs(plr[pnum].position.current.x - monster[i].position.future.x);
y = abs(plr[pnum].position.current.y - monster[i]._mfuty); y = abs(plr[pnum].position.current.y - monster[i].position.future.y);
if (x <= 1 && y <= 1) { if (x <= 1 && y <= 1) {
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i].position.future.x, monster[i].position.future.y);
StartAttack(pnum, d); StartAttack(pnum, d);
} }
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
@ -3518,8 +3518,8 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKMON) { } else if (plr[pnum].destAction == ACTION_RATTACKMON) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i].position.future.x, monster[i].position.future.y);
StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty); StartRangeAttack(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKPLR) { } else if (plr[pnum].destAction == ACTION_RATTACKPLR) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
@ -3536,8 +3536,8 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLMON) { } else if (plr[pnum].destAction == ACTION_SPELLMON) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty); d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i].position.future.x, monster[i].position.future.y);
StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty); StartSpell(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE; plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLPLR) { } else if (plr[pnum].destAction == ACTION_SPELLPLR) {
i = plr[pnum].destParam1; i = plr[pnum].destParam1;

21
Source/player.h

@ -147,23 +147,6 @@ enum player_weapon_type : uint8_t {
WT_RANGED, WT_RANGED,
}; };
struct PlayerPosition {
/** Tile position */
Point current; // 256
/** Future tile position. Set at start of walking animation. */
Point future;
/** Tile position of player. Set via network on player input. */
Point owner;
/** Most recent position in dPlayer. */
Point old;
/** Player sprite's pixel offset from tile. */
Point offset;
/** Same as offset but contains the value in a higher range */
Point offset2;
/** Pixel velocity while walking. Indirectly applied to offset via _pvar6/7 */
Point velocity;
};
struct PlayerStruct { struct PlayerStruct {
PLR_MODE _pmode; PLR_MODE _pmode;
int8_t walkpath[MAX_PATH_LENGTH]; int8_t walkpath[MAX_PATH_LENGTH];
@ -174,7 +157,7 @@ struct PlayerStruct {
direction destParam3; direction destParam3;
int destParam4; int destParam4;
int plrlevel; int plrlevel;
PlayerPosition position; ActorPosition position;
direction _pdir; // Direction faced by player (direction enum) direction _pdir; // Direction faced by player (direction enum)
int _pgfxnum; // Bitmask indicating what variant of the sprite the player is using. Lower byte define weapon (anim_weapon_id) and higher values define armour (starting with anim_armor_id) int _pgfxnum; // Bitmask indicating what variant of the sprite the player is using. Lower byte define weapon (anim_weapon_id) and higher values define armour (starting with anim_armor_id)
uint8_t *_pAnimData; uint8_t *_pAnimData;
@ -255,8 +238,6 @@ struct PlayerStruct {
bool _pInfraFlag; bool _pInfraFlag;
/** Player's direction when ending movement. Also used for casting direction of SPL_FIREWALL. */ /** Player's direction when ending movement. Also used for casting direction of SPL_FIREWALL. */
direction tempDirection; direction tempDirection;
/** Used for referring to position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks) */
Point tempPoint;
/** Used for spell level, and X component of _pVar5 */ /** Used for spell level, and X component of _pVar5 */
int _pVar4; int _pVar4;
/** Used for storing position of a tile which should have its BFLAG_PLAYERLR flag removed after walking. When starting to walk the game places the player in the dPlayer array -1 in the Y coordinate, and uses BFLAG_PLAYERLR to check if it should be using -1 to the Y coordinate when rendering the player (also used for storing the level of a spell when the player casts it) */ /** Used for storing position of a tile which should have its BFLAG_PLAYERLR flag removed after walking. When starting to walk the game places the player in the dPlayer array -1 in the Y coordinate, and uses BFLAG_PLAYERLR to check if it should be using -1 to the Y coordinate when rendering the player (also used for storing the level of a spell when the player casts it) */

4
Source/scrollrt.cpp

@ -691,8 +691,8 @@ static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy,
return; return;
} }
px = sx + pMonster->_mxoff - pMonster->MType->width2; px = sx + pMonster->position.offset.x - pMonster->MType->width2;
py = sy + pMonster->_myoff; py = sy + pMonster->position.offset.y;
if (mi == pcursmonst) { if (mi == pcursmonst) {
Cl2DrawOutline(out, 233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->width); Cl2DrawOutline(out, 233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->width);
} }

23
Source/sync.cpp

@ -26,7 +26,7 @@ static void sync_one_monster()
for (i = 0; i < nummonsters; i++) { for (i = 0; i < nummonsters; i++) {
m = monstactive[i]; m = monstactive[i];
sgnMonsterPriority[m] = abs(plr[myplr].position.current.x - monster[m]._mx) + abs(plr[myplr].position.current.y - monster[m]._my); sgnMonsterPriority[m] = abs(plr[myplr].position.current.x - monster[m].position.current.x) + abs(plr[myplr].position.current.y - monster[m].position.current.y);
if (monster[m]._msquelch == 0) { if (monster[m]._msquelch == 0) {
sgnMonsterPriority[m] += 0x1000; sgnMonsterPriority[m] += 0x1000;
} else if (sgwLRU[m] != 0) { } else if (sgwLRU[m] != 0) {
@ -38,8 +38,8 @@ static void sync_one_monster()
static void sync_monster_pos(TSyncMonster *p, int ndx) static void sync_monster_pos(TSyncMonster *p, int ndx)
{ {
p->_mndx = ndx; p->_mndx = ndx;
p->_mx = monster[ndx]._mx; p->_mx = monster[ndx].position.current.x;
p->_my = monster[ndx]._my; p->_my = monster[ndx].position.current.y;
p->_menemy = encode_enemy(ndx); p->_menemy = encode_enemy(ndx);
p->_mdelta = sgnMonsterPriority[ndx] > 255 ? 255 : sgnMonsterPriority[ndx]; p->_mdelta = sgnMonsterPriority[ndx] > 255 ? 255 : sgnMonsterPriority[ndx];
@ -213,7 +213,7 @@ static void sync_monster(int pnum, const TSyncMonster *p)
return; return;
} }
delta = abs(plr[myplr].position.current.x - monster[ndx]._mx) + abs(plr[myplr].position.current.y - monster[ndx]._my); delta = abs(plr[myplr].position.current.x - monster[ndx].position.current.x) + abs(plr[myplr].position.current.y - monster[ndx].position.current.y);
if (delta > 255) { if (delta > 255) {
delta = 255; delta = 255;
} }
@ -221,21 +221,21 @@ static void sync_monster(int pnum, const TSyncMonster *p)
if (delta < p->_mdelta || (delta == p->_mdelta && pnum > myplr)) { if (delta < p->_mdelta || (delta == p->_mdelta && pnum > myplr)) {
return; return;
} }
if (monster[ndx]._mfutx == p->_mx && monster[ndx]._mfuty == p->_my) { if (monster[ndx].position.future.x == p->_mx && monster[ndx].position.future.y == p->_my) {
return; return;
} }
if (monster[ndx]._mmode == MM_CHARGE || monster[ndx]._mmode == MM_STONE) { if (monster[ndx]._mmode == MM_CHARGE || monster[ndx]._mmode == MM_STONE) {
return; return;
} }
mdx = abs(monster[ndx]._mx - p->_mx); mdx = abs(monster[ndx].position.current.x - p->_mx);
mdy = abs(monster[ndx]._my - p->_my); mdy = abs(monster[ndx].position.current.y - p->_my);
if (mdx <= 2 && mdy <= 2) { if (mdx <= 2 && mdy <= 2) {
if (monster[ndx]._mmode < MM_WALK || monster[ndx]._mmode > MM_WALK3) { if (monster[ndx]._mmode < MM_WALK || monster[ndx]._mmode > MM_WALK3) {
direction md = GetDirection(monster[ndx]._mx, monster[ndx]._my, p->_mx, p->_my); direction md = GetDirection(monster[ndx].position.current.x, monster[ndx].position.current.y, p->_mx, p->_my);
if (DirOK(ndx, md)) { if (DirOK(ndx, md)) {
M_ClearSquares(ndx); M_ClearSquares(ndx);
dMonster[monster[ndx]._mx][monster[ndx]._my] = ndx + 1; dMonster[monster[ndx].position.current.x][monster[ndx].position.current.y] = ndx + 1;
M_WalkDir(ndx, md); M_WalkDir(ndx, md);
monster[ndx]._msquelch = UCHAR_MAX; monster[ndx]._msquelch = UCHAR_MAX;
} }
@ -243,10 +243,9 @@ static void sync_monster(int pnum, const TSyncMonster *p)
} else if (dMonster[p->_mx][p->_my] == 0) { } else if (dMonster[p->_mx][p->_my] == 0) {
M_ClearSquares(ndx); M_ClearSquares(ndx);
dMonster[p->_mx][p->_my] = ndx + 1; dMonster[p->_mx][p->_my] = ndx + 1;
monster[ndx]._mx = p->_mx; monster[ndx].position.current = { p->_mx, p->_my };
monster[ndx]._my = p->_my;
decode_enemy(ndx, p->_menemy); decode_enemy(ndx, p->_menemy);
direction md = GetDirection(p->_mx, p->_my, monster[ndx]._menemyx, monster[ndx]._menemyy); direction md = GetDirection(p->_mx, p->_my, monster[ndx].enemyPosition.x, monster[ndx].enemyPosition.y);
M_StartStand(ndx, md); M_StartStand(ndx, md);
monster[ndx]._msquelch = UCHAR_MAX; monster[ndx]._msquelch = UCHAR_MAX;
} }

Loading…
Cancel
Save