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
return false;
const int mx = monst._mx;
const int my = monst._my;
const int mx = monst.position.current.x;
const int my = monst.position.current.y;
if ((dFlags[mx][my] & BFLAG_LIT) == 0) // not visible
return false;
if (dMonster[mx][my] == 0)
@ -213,8 +213,8 @@ void FindRangedTarget()
// The first MAX_PLRS monsters are reserved for players' golems.
for (int mi = MAX_PLRS; mi < MAXMONSTERS; mi++) {
const MonsterStruct &monst = monster[mi];
const int mx = monst._mfutx;
const int my = monst._mfuty;
const int mx = monst.position.future.x;
const int my = monst.position.future.y;
if (!CanTargetMonster(mi))
continue;
@ -1129,8 +1129,8 @@ bool SpellHasActorTarget()
return false;
if (spl == SPL_FIREWALL && pcursmonst != -1) {
cursmx = monster[pcursmonst]._mx;
cursmy = monster[pcursmonst]._my;
cursmx = monster[pcursmonst].position.current.x;
cursmy = monster[pcursmonst].position.current.y;
}
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);
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);
sprintf(dstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints);
NetSendCmdString(1 << myplr, dstr);

4
Source/diablo.cpp

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

19
Source/engine.h

@ -62,6 +62,25 @@ struct Point {
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.
//
// 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.y = file->nextLE<int32_t>();
file->skip(8); // Skip _ptargx and _ptargy
pPlayer->position.owner.x = file->nextLE<int32_t>();
pPlayer->position.owner.y = file->nextLE<int32_t>();
pPlayer->position.last.x = file->nextLE<int32_t>();
pPlayer->position.last.y = file->nextLE<int32_t>();
pPlayer->position.old.x = file->nextLE<int32_t>();
pPlayer->position.old.y = 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->_pInfraFlag = file->nextBool32();
pPlayer->tempPoint.x = file->nextLE<int32_t>();
pPlayer->tempPoint.y = file->nextLE<int32_t>();
pPlayer->position.temp.x = file->nextLE<int32_t>();
pPlayer->position.temp.y = file->nextLE<int32_t>();
pPlayer->tempDirection = static_cast<direction>(file->nextLE<int32_t>());
pPlayer->_pVar4 = 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
pMonster->_pathcount = file->nextLE<uint8_t>();
file->skip(3); // Alignment
pMonster->_mx = file->nextLE<int32_t>();
pMonster->_my = file->nextLE<int32_t>();
pMonster->_mfutx = file->nextLE<int32_t>();
pMonster->_mfuty = file->nextLE<int32_t>();
pMonster->_moldx = file->nextLE<int32_t>();
pMonster->_moldy = file->nextLE<int32_t>();
pMonster->_mxoff = file->nextLE<int32_t>();
pMonster->_myoff = file->nextLE<int32_t>();
pMonster->_mxvel = file->nextLE<int32_t>();
pMonster->_myvel = file->nextLE<int32_t>();
pMonster->position.current.x = file->nextLE<int32_t>();
pMonster->position.current.y = file->nextLE<int32_t>();
pMonster->position.future.x = file->nextLE<int32_t>();
pMonster->position.future.y = file->nextLE<int32_t>();
pMonster->position.old.x = file->nextLE<int32_t>();
pMonster->position.old.y = file->nextLE<int32_t>();
pMonster->position.offset.x = file->nextLE<int32_t>();
pMonster->position.offset.y = file->nextLE<int32_t>();
pMonster->position.velocity.x = file->nextLE<int32_t>();
pMonster->position.velocity.y = file->nextLE<int32_t>();
pMonster->_mdir = static_cast<direction>(file->nextLE<int32_t>());
pMonster->_menemy = file->nextLE<int32_t>();
pMonster->_menemyx = file->nextLE<uint8_t>();
pMonster->_menemyy = file->nextLE<uint8_t>();
pMonster->enemyPosition.x = file->nextLE<uint8_t>();
pMonster->enemyPosition.y = file->nextLE<uint8_t>();
file->skip(2); // Unused
file->skip(4); // Skip pointer _mAnimData
@ -575,11 +575,11 @@ static void LoadMonster(LoadHelper *file, int i)
pMonster->_mVar1 = file->nextLE<int32_t>();
pMonster->_mVar2 = file->nextLE<int32_t>();
pMonster->_mVar3 = file->nextLE<int32_t>();
pMonster->_mVar4 = file->nextLE<int32_t>();
pMonster->_mVar5 = file->nextLE<int32_t>();
pMonster->_mVar6 = file->nextLE<int32_t>();
pMonster->_mVar7 = file->nextLE<int32_t>();
pMonster->_mVar8 = file->nextLE<int32_t>();
pMonster->position.temp.x = file->nextLE<int32_t>();
pMonster->position.temp.y = file->nextLE<int32_t>();
pMonster->position.offset2.x = file->nextLE<int32_t>();
pMonster->position.offset2.y = file->nextLE<int32_t>();
pMonster->actionFrame = file->nextLE<int32_t>();
pMonster->_mmaxhp = 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>();
file->skip(3); // Alignment
file->skip(4); // Unused
pMonster->_lastx = file->nextLE<int32_t>();
pMonster->_lasty = file->nextLE<int32_t>();
pMonster->position.last.x = file->nextLE<int32_t>();
pMonster->position.last.y = file->nextLE<int32_t>();
pMonster->_mRndSeed = file->nextLE<int32_t>();
pMonster->_mAISeed = file->nextLE<int32_t>();
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.y);
file->writeLE<int32_t>(pPlayer->position.owner.x);
file->writeLE<int32_t>(pPlayer->position.owner.y);
file->writeLE<int32_t>(pPlayer->position.last.x);
file->writeLE<int32_t>(pPlayer->position.last.y);
file->writeLE<int32_t>(pPlayer->position.old.x);
file->writeLE<int32_t>(pPlayer->position.old.y);
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<uint32_t>(pPlayer->_pInfraFlag);
file->writeLE<int32_t>(pPlayer->tempPoint.x);
file->writeLE<int32_t>(pPlayer->tempPoint.y);
file->writeLE<int32_t>(pPlayer->position.temp.x);
file->writeLE<int32_t>(pPlayer->position.temp.y);
file->writeLE<int32_t>(pPlayer->tempDirection);
file->writeLE<int32_t>(pPlayer->_pVar4);
file->writeLE<int32_t>(pPlayer->_pVar5);
@ -1518,20 +1518,20 @@ static void SaveMonster(SaveHelper *file, int i)
file->skip(4); // Unused
file->writeLE<uint8_t>(pMonster->_pathcount);
file->skip(3); // Alignment
file->writeLE<int32_t>(pMonster->_mx);
file->writeLE<int32_t>(pMonster->_my);
file->writeLE<int32_t>(pMonster->_mfutx);
file->writeLE<int32_t>(pMonster->_mfuty);
file->writeLE<int32_t>(pMonster->_moldx);
file->writeLE<int32_t>(pMonster->_moldy);
file->writeLE<int32_t>(pMonster->_mxoff);
file->writeLE<int32_t>(pMonster->_myoff);
file->writeLE<int32_t>(pMonster->_mxvel);
file->writeLE<int32_t>(pMonster->_myvel);
file->writeLE<int32_t>(pMonster->position.current.x);
file->writeLE<int32_t>(pMonster->position.current.y);
file->writeLE<int32_t>(pMonster->position.future.x);
file->writeLE<int32_t>(pMonster->position.future.y);
file->writeLE<int32_t>(pMonster->position.old.x);
file->writeLE<int32_t>(pMonster->position.old.y);
file->writeLE<int32_t>(pMonster->position.offset.x);
file->writeLE<int32_t>(pMonster->position.offset.y);
file->writeLE<int32_t>(pMonster->position.velocity.x);
file->writeLE<int32_t>(pMonster->position.velocity.y);
file->writeLE<int32_t>(pMonster->_mdir);
file->writeLE<int32_t>(pMonster->_menemy);
file->writeLE<uint8_t>(pMonster->_menemyx);
file->writeLE<uint8_t>(pMonster->_menemyy);
file->writeLE<uint8_t>(pMonster->enemyPosition.x);
file->writeLE<uint8_t>(pMonster->enemyPosition.y);
file->skip(2); // Unused
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->_mVar2);
file->writeLE<int32_t>(pMonster->_mVar3);
file->writeLE<int32_t>(pMonster->_mVar4);
file->writeLE<int32_t>(pMonster->_mVar5);
file->writeLE<int32_t>(pMonster->_mVar6);
file->writeLE<int32_t>(pMonster->_mVar7);
file->writeLE<int32_t>(pMonster->_mVar8);
file->writeLE<int32_t>(pMonster->position.temp.x);
file->writeLE<int32_t>(pMonster->position.temp.y);
file->writeLE<int32_t>(pMonster->position.offset2.x);
file->writeLE<int32_t>(pMonster->position.offset2.y);
file->writeLE<int32_t>(pMonster->actionFrame);
file->writeLE<int32_t>(pMonster->_mmaxhp);
file->writeLE<int32_t>(pMonster->_mhitpoints);
@ -1559,8 +1559,8 @@ static void SaveMonster(SaveHelper *file, int i)
file->writeLE<uint8_t>(pMonster->_msquelch);
file->skip(3); // Alignment
file->skip(4); // Unused
file->writeLE<int32_t>(pMonster->_lastx);
file->writeLE<int32_t>(pMonster->_lasty);
file->writeLE<int32_t>(pMonster->position.last.x);
file->writeLE<int32_t>(pMonster->position.last.y);
file->writeLE<int32_t>(pMonster->_mRndSeed);
file->writeLE<int32_t>(pMonster->_mAISeed);
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) {
monster[m]._msquelch = UCHAR_MAX;
monster[m]._lastx = plr[pnum].position.current.x;
monster[m]._lasty = plr[pnum].position.current.y;
monster[m].position.last = plr[pnum].position.current;
}
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) {
direction dir = plr[pnum]._pdir;
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;
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;
else
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);
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)
missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1;
mon = &monster[id];
dMonster[mon->_mx][mon->_my] = 0;
dMonster[mon->position.current.x][mon->position.current.y] = 0;
missile[mi]._mirange = 256;
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]._miVar4 = dx;
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);
UseMana(id, SPL_GOLEM);
}
@ -3307,7 +3306,7 @@ void MI_Golem(int i)
const char *ct;
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++) {
k = CrawlNum[l];
tid = k + 2;
@ -3637,8 +3636,8 @@ void FireballUpdate(int i, int xof, int yof, bool alwaysDelete)
px = plr[id].position.current.x;
py = plr[id].position.current.y;
} else {
px = monster[id]._mx;
py = monster[id]._my;
px = monster[id].position.current.x;
py = monster[id].position.current.y;
}
if (missile[i]._miAnimType == MFILE_BIGEXP) {
@ -3760,7 +3759,7 @@ void MI_Rune(int i)
mid = mid - 1;
else
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 {
if (pid > 0)
pid = pid - 1;
@ -4680,7 +4679,7 @@ void MI_Stone(int i)
if (monster[m]._mhitpoints > 0)
monster[m]._mmode = (MON_MODE)missile[i]._miVar1;
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)
PutMissile(i);
@ -4731,13 +4730,10 @@ void MI_Rhino(int i)
missile[i]._miDelFlag = true;
return;
}
monster[monst]._mfutx = omx;
monster[monst]._moldx = omx;
monster[monst].position.future = { omx, omy };
monster[monst].position.old = { omx, omy };
monster[monst].position.current = { omx, omy };
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)
ChangeLightXY(missile[i]._mlid, omx, omy);
MoveMissilePos(i);
@ -4762,8 +4758,8 @@ void MI_Fireman(int i)
cx = plr[enemy].position.current.x;
cy = plr[enemy].position.current.y;
} else {
cx = monster[enemy]._mx;
cy = monster[enemy]._my;
cx = monster[enemy].position.current.x;
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)) {
MissToMonst(i, ax, ay);
@ -5154,9 +5150,9 @@ void MI_Element(int i)
missile[i]._mirange = 255;
mid = FindClosest(cx, cy, 19);
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);
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 {
direction sd = plr[id]._pdir;
SetMissDir(i, sd);
@ -5207,8 +5203,8 @@ 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]._mx, monster[mid]._my));
GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16);
SetMissDir(i, GetDirection(cx, cy, monster[mid].position.current.x, monster[mid].position.current.y));
GetMissileVel(i, cx, cy, monster[mid].position.current.x, monster[mid].position.current.y, 16);
} else {
direction sd = plr[id]._pdir;
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 _mgoalvar3;
uint8_t _pathcount;
/** Tile X-position of monster */
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;
ActorPosition position;
/** Direction faced by monster (direction enum) */
direction _mdir;
/** The current target of the mosnter. An index in to either the plr or monster array based on the _meflag value. */
int _menemy;
/** X-coordinate of enemy (usually correspond's to the enemy's futx value) */
uint8_t _menemyx;
/** Y-coordinate of enemy (usually correspond's to the enemy's futy value) */
uint8_t _menemyy;
/** Usually correspond's to the enemy's future position */
Point enemyPosition;
uint8_t *_mAnimData;
/** Tick length of each frame in the current animation */
int _mAnimDelay;
@ -181,22 +160,14 @@ struct MonsterStruct { // note: missing field _mAFNum
int _mVar1;
int _mVar2;
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 */
int _mVar8;
int actionFrame;
int _mmaxhp;
int _mhitpoints;
_mai_id _mAi;
uint8_t _mint;
uint32_t _mFlags;
uint8_t _msquelch;
int _lastx;
int _lasty;
int _mRndSeed;
int _mAISeed;
uint8_t _uniqtype;

31
Source/msg.cpp

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

2
Source/multi.cpp

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

4
Source/objects.cpp

@ -2819,8 +2819,8 @@ void MonstCheckDoors(int m)
int i, oi;
int dpx, dpy, mx, my;
mx = monster[m]._mx;
my = monster[m]._my;
mx = monster[m].position.current.x;
my = monster[m].position.current.y;
if (dObject[mx - 1][my - 1] != 0
|| dObject[mx][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);
}
plr[pnum].tempPoint = { 0, 0 };
plr[pnum].position.temp = { 0, 0 };
plr[pnum].tempDirection = DIR_S;
plr[pnum]._pVar4 = 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].position.velocity = { xvel, yvel };
plr[pnum].position.offset = { 0, 0 };
plr[pnum].tempPoint = { xadd, yadd };
plr[pnum].position.temp = { xadd, yadd };
plr[pnum].tempDirection = EndDir;
plr[pnum].position.offset2 = { 0, 0 };
break;
case PM_WALK2:
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
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
@ -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].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].tempDirection = EndDir;
break;
@ -1603,7 +1603,7 @@ void StartRangeAttack(int pnum, direction d, int cx, int cy)
plr[pnum]._pmode = PM_RATTACK;
FixPlayerLocation(pnum, d);
SetPlayerOld(pnum);
plr[pnum].tempPoint = { cx, cy };
plr[pnum].position.temp = { cx, cy };
}
void StartPlrBlock(int pnum, direction dir)
@ -1675,7 +1675,7 @@ void StartSpell(int pnum, direction d, int cx, int cy)
FixPlayerLocation(pnum, d);
SetPlayerOld(pnum);
plr[pnum].tempPoint = { cx, cy };
plr[pnum].position.temp = { cx, cy };
plr[pnum]._pVar4 = GetSpellLevel(pnum, plr[pnum]._pSpell);
plr[pnum].actionFrame = 1;
}
@ -2152,11 +2152,11 @@ void RemovePlrMissiles(int pnum)
int i, am;
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);
AddDead(monster[myplr]._mx, monster[myplr]._my, (monster[myplr].MType)->mdeadval, monster[myplr]._mdir);
mx = monster[myplr]._mx;
my = monster[myplr]._my;
AddDead(monster[myplr].position.current.x, monster[myplr].position.current.y, (monster[myplr].MType)->mdeadval, monster[myplr]._mdir);
mx = monster[myplr].position.current.x;
my = monster[myplr].position.current.y;
dMonster[mx][my] = 0;
monster[myplr]._mDelFlag = true;
DeleteMonsterList();
@ -2333,17 +2333,17 @@ bool PM_DoWalk(int pnum, int variant)
switch (variant) {
case PM_WALK:
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.y += plr[pnum].tempPoint.y;
plr[pnum].position.current.x += plr[pnum].position.temp.x;
plr[pnum].position.current.y += plr[pnum].position.temp.y;
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = pnum + 1;
break;
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;
case PM_WALK3:
dPlayer[plr[pnum].position.current.x][plr[pnum].position.current.y] = 0;
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;
break;
}
@ -2557,7 +2557,7 @@ bool PlrHitMonst(int pnum, int m)
#endif
if (plr[pnum]._pIFlags & ISPL_FIREDAM && plr[pnum]._pIFlags & ISPL_LIGHTDAM) {
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;
maxd = plr[pnum]._pIMaxDam;
@ -2860,7 +2860,7 @@ bool PM_DoAttack(int pnum)
m = -(dMonster[dx][dy] + 1);
}
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;
}
}
@ -2906,14 +2906,14 @@ bool PM_DoAttack(int pnum)
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];
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))
didhit = true;
}
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];
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))
didhit = true;
}
@ -2965,10 +2965,10 @@ bool PM_DoRangeAttack(int pnum)
int yoff = 0;
if (arrows != 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)
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)
xoff = y < 0 ? -angle : angle;
}
@ -2989,8 +2989,8 @@ bool PM_DoRangeAttack(int pnum)
AddMissile(
plr[pnum].position.current.x,
plr[pnum].position.current.y,
plr[pnum].tempPoint.x + xoff,
plr[pnum].tempPoint.y + yoff,
plr[pnum].position.temp.x + xoff,
plr[pnum].position.temp.y + yoff,
plr[pnum]._pdir,
mistype,
TARGET_MONSTERS,
@ -3137,8 +3137,8 @@ bool PM_DoSpell(int pnum)
plr[pnum]._pSpell,
plr[pnum].position.current.x,
plr[pnum].position.current.y,
plr[pnum].tempPoint.x,
plr[pnum].tempPoint.y,
plr[pnum].position.temp.x,
plr[pnum].position.temp.y,
plr[pnum]._pVar4);
if (plr[pnum]._pSplFrom == 0) {
@ -3235,7 +3235,7 @@ void CheckNewPath(int pnum)
if (plr[pnum].destAction == ACTION_ATTACKMON) {
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) {
@ -3251,9 +3251,9 @@ void CheckNewPath(int pnum)
i = plr[pnum].destParam1;
if (plr[pnum].destAction == ACTION_ATTACKMON) {
x = abs(plr[pnum].position.future.x - monster[i]._mfutx);
y = abs(plr[pnum].position.future.y - monster[i]._mfuty);
d = GetDirection(plr[pnum].position.future.x, plr[pnum].position.future.y, monster[i]._mfutx, monster[i]._mfuty);
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);
} 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);
@ -3335,10 +3335,10 @@ void CheckNewPath(int pnum)
break;
case ACTION_ATTACKMON:
i = plr[pnum].destParam1;
x = abs(plr[pnum].position.current.x - monster[i]._mfutx);
y = abs(plr[pnum].position.current.y - monster[i]._mfuty);
x = abs(plr[pnum].position.current.x - monster[i].position.future.x);
y = abs(plr[pnum].position.current.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]._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) {
TalktoMonster(i);
} else {
@ -3361,11 +3361,11 @@ void CheckNewPath(int pnum)
break;
case ACTION_RATTACKMON:
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) {
TalktoMonster(i);
} else {
StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty);
StartRangeAttack(pnum, d, monster[i].position.future.x, monster[i].position.future.y);
}
break;
case ACTION_RATTACKPLR:
@ -3385,8 +3385,8 @@ void CheckNewPath(int pnum)
break;
case ACTION_SPELLMON:
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty);
StartSpell(pnum, d, 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].position.future.x, monster[i].position.future.y);
plr[pnum]._pVar4 = plr[pnum].destParam2;
break;
case ACTION_SPELLPLR:
@ -3477,10 +3477,10 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_ATTACKMON) {
i = plr[pnum].destParam1;
x = abs(plr[pnum].position.current.x - monster[i]._mfutx);
y = abs(plr[pnum].position.current.y - monster[i]._mfuty);
x = abs(plr[pnum].position.current.x - monster[i].position.future.x);
y = abs(plr[pnum].position.current.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]._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);
}
plr[pnum].destAction = ACTION_NONE;
@ -3518,8 +3518,8 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKMON) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty);
StartRangeAttack(pnum, d, 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].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_RATTACKPLR) {
i = plr[pnum].destParam1;
@ -3536,8 +3536,8 @@ void CheckNewPath(int pnum)
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLMON) {
i = plr[pnum].destParam1;
d = GetDirection(plr[pnum].position.current.x, plr[pnum].position.current.y, monster[i]._mfutx, monster[i]._mfuty);
StartSpell(pnum, d, 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].position.future.x, monster[i].position.future.y);
plr[pnum].destAction = ACTION_NONE;
} else if (plr[pnum].destAction == ACTION_SPELLPLR) {
i = plr[pnum].destParam1;

21
Source/player.h

@ -147,23 +147,6 @@ enum player_weapon_type : uint8_t {
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 {
PLR_MODE _pmode;
int8_t walkpath[MAX_PATH_LENGTH];
@ -174,7 +157,7 @@ struct PlayerStruct {
direction destParam3;
int destParam4;
int plrlevel;
PlayerPosition position;
ActorPosition position;
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)
uint8_t *_pAnimData;
@ -255,8 +238,6 @@ struct PlayerStruct {
bool _pInfraFlag;
/** Player's direction when ending movement. Also used for casting direction of SPL_FIREWALL. */
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 */
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) */

4
Source/scrollrt.cpp

@ -691,8 +691,8 @@ static void DrawMonsterHelper(const CelOutputBuffer &out, int x, int y, int oy,
return;
}
px = sx + pMonster->_mxoff - pMonster->MType->width2;
py = sy + pMonster->_myoff;
px = sx + pMonster->position.offset.x - pMonster->MType->width2;
py = sy + pMonster->position.offset.y;
if (mi == pcursmonst) {
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++) {
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) {
sgnMonsterPriority[m] += 0x1000;
} else if (sgwLRU[m] != 0) {
@ -38,8 +38,8 @@ static void sync_one_monster()
static void sync_monster_pos(TSyncMonster *p, int ndx)
{
p->_mndx = ndx;
p->_mx = monster[ndx]._mx;
p->_my = monster[ndx]._my;
p->_mx = monster[ndx].position.current.x;
p->_my = monster[ndx].position.current.y;
p->_menemy = encode_enemy(ndx);
p->_mdelta = sgnMonsterPriority[ndx] > 255 ? 255 : sgnMonsterPriority[ndx];
@ -213,7 +213,7 @@ static void sync_monster(int pnum, const TSyncMonster *p)
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) {
delta = 255;
}
@ -221,21 +221,21 @@ static void sync_monster(int pnum, const TSyncMonster *p)
if (delta < p->_mdelta || (delta == p->_mdelta && pnum > myplr)) {
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;
}
if (monster[ndx]._mmode == MM_CHARGE || monster[ndx]._mmode == MM_STONE) {
return;
}
mdx = abs(monster[ndx]._mx - p->_mx);
mdy = abs(monster[ndx]._my - p->_my);
mdx = abs(monster[ndx].position.current.x - p->_mx);
mdy = abs(monster[ndx].position.current.y - p->_my);
if (mdx <= 2 && mdy <= 2) {
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)) {
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);
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) {
M_ClearSquares(ndx);
dMonster[p->_mx][p->_my] = ndx + 1;
monster[ndx]._mx = p->_mx;
monster[ndx]._my = p->_my;
monster[ndx].position.current = { p->_mx, p->_my };
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);
monster[ndx]._msquelch = UCHAR_MAX;
}

Loading…
Cancel
Save