Use scoped enums for DungeonFlags/BFLAG (#3135)
This commit is contained in:
parent
9f25b57771
commit
796e2813cf
21 changed files with 179 additions and 141 deletions
|
|
@ -567,7 +567,7 @@ void InitAutomap()
|
|||
|
||||
for (auto &column : dFlags)
|
||||
for (auto &dFlag : column)
|
||||
dFlag &= ~BFLAG_EXPLORED;
|
||||
dFlag &= ~DungeonFlag::Explored;
|
||||
}
|
||||
|
||||
void StartAutomap()
|
||||
|
|
|
|||
|
|
@ -206,10 +206,11 @@ bool CanTargetMonster(const Monster &monster)
|
|||
if (monster._mhitpoints >> 6 <= 0) // dead
|
||||
return false;
|
||||
|
||||
if (!IsTileLit(monster.position.tile)) // not visible
|
||||
return false;
|
||||
|
||||
const int mx = monster.position.tile.x;
|
||||
const int my = monster.position.tile.y;
|
||||
if ((dFlags[mx][my] & BFLAG_LIT) == 0) // not visible
|
||||
return false;
|
||||
if (dMonster[mx][my] == 0)
|
||||
return false;
|
||||
|
||||
|
|
@ -349,7 +350,7 @@ void CheckPlayerNearby()
|
|||
const int mx = player.position.future.x;
|
||||
const int my = player.position.future.y;
|
||||
if (dPlayer[mx][my] == 0
|
||||
|| (dFlags[mx][my] & BFLAG_LIT) == 0
|
||||
|| !IsTileLit(player.position.future)
|
||||
|| (player._pHitPoints == 0 && spl != SPL_RESURRECT))
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ void CheckCursMove()
|
|||
const auto &monster = Monsters[pcursmonst];
|
||||
if (monster._mDelFlag || monster._mhitpoints >> 6 <= 0
|
||||
|| (monster._mFlags & MFLAG_HIDDEN) != 0
|
||||
|| ((dFlags[monster.position.tile.x][monster.position.tile.y] & BFLAG_LIT) == 0)) {
|
||||
|| !IsTileLit(monster.position.tile)) {
|
||||
pcursmonst = -1;
|
||||
}
|
||||
} else if (pcursobj != -1) {
|
||||
|
|
@ -345,7 +345,7 @@ void CheckCursMove()
|
|||
auto &targetPlayer = Players[pcursplr];
|
||||
if (targetPlayer._pmode == PM_DEATH || targetPlayer._pmode == PM_QUIT || !targetPlayer.plractive
|
||||
|| currlevel != targetPlayer.plrlevel || targetPlayer._pHitPoints >> 6 <= 0
|
||||
|| ((dFlags[targetPlayer.position.tile.x][targetPlayer.position.tile.y] & BFLAG_LIT) == 0))
|
||||
|| !IsTileLit(targetPlayer.position.tile))
|
||||
pcursplr = -1;
|
||||
}
|
||||
|
||||
|
|
@ -400,51 +400,49 @@ void CheckCursMove()
|
|||
|
||||
if (leveltype != DTYPE_TOWN) {
|
||||
if (pcurstemp != -1) {
|
||||
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && (dFlags[mx + 2][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) {
|
||||
int mi = dMonster[mx + 2][my + 1] > 0 ? dMonster[mx + 2][my + 1] - 1 : -(dMonster[mx + 2][my + 1] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
/// BUGFIX: 'mx + 2' (fixed)
|
||||
/// BUGFIX: 'my + 1' (fixed)
|
||||
cursPosition = Point { mx, my } + Displacement { 2, 1 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && (dFlags[mx + 1][my + 2] & BFLAG_LIT) != 0) {
|
||||
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) {
|
||||
int mi = dMonster[mx + 1][my + 2] > 0 ? dMonster[mx + 1][my + 2] - 1 : -(dMonster[mx + 1][my + 2] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 2 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && (dFlags[mx + 2][my + 2] & BFLAG_LIT) != 0) {
|
||||
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) {
|
||||
int mi = dMonster[mx + 2][my + 2] > 0 ? dMonster[mx + 2][my + 2] - 1 : -(dMonster[mx + 2][my + 2] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 2, 2 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (mx + 1 < MAXDUNX && !flipflag && dMonster[mx + 1][my] != 0 && (dFlags[mx + 1][my] & BFLAG_LIT) != 0) {
|
||||
if (mx + 1 < MAXDUNX && !flipflag && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) {
|
||||
int mi = dMonster[mx + 1][my] > 0 ? dMonster[mx + 1][my] - 1 : -(dMonster[mx + 1][my] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 0 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (my + 1 < MAXDUNY && flipflag && dMonster[mx][my + 1] != 0 && (dFlags[mx][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (my + 1 < MAXDUNY && flipflag && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) {
|
||||
int mi = dMonster[mx][my + 1] > 0 ? dMonster[mx][my + 1] - 1 : -(dMonster[mx][my + 1] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 0, 1 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (dMonster[mx][my] != 0 && (dFlags[mx][my] & BFLAG_LIT) != 0) {
|
||||
if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) {
|
||||
int mi = dMonster[mx][my] > 0 ? dMonster[mx][my] - 1 : -(dMonster[mx][my] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 1) != 0) {
|
||||
cursPosition = { mx, my };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && (dFlags[mx + 1][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) {
|
||||
int mi = dMonster[mx + 1][my + 1] > 0 ? dMonster[mx + 1][my + 1] - 1 : -(dMonster[mx + 1][my + 1] + 1);
|
||||
if (mi == pcurstemp && Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 1 };
|
||||
|
|
@ -462,49 +460,49 @@ void CheckCursMove()
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && (dFlags[mx + 2][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (!flipflag && mx + 2 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 2][my + 1] != 0 && IsTileLit({ mx + 2, my + 1 })) {
|
||||
int mi = dMonster[mx + 2][my + 1] > 0 ? dMonster[mx + 2][my + 1] - 1 : -(dMonster[mx + 2][my + 1] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 2, 1 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && (dFlags[mx + 1][my + 2] & BFLAG_LIT) != 0) {
|
||||
if (flipflag && mx + 1 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 1][my + 2] != 0 && IsTileLit({ mx + 1, my + 2 })) {
|
||||
int mi = dMonster[mx + 1][my + 2] > 0 ? dMonster[mx + 1][my + 2] - 1 : -(dMonster[mx + 1][my + 2] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 2 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && (dFlags[mx + 2][my + 2] & BFLAG_LIT) != 0) {
|
||||
if (mx + 2 < MAXDUNX && my + 2 < MAXDUNY && dMonster[mx + 2][my + 2] != 0 && IsTileLit({ mx + 2, my + 2 })) {
|
||||
int mi = dMonster[mx + 2][my + 2] > 0 ? dMonster[mx + 2][my + 2] - 1 : -(dMonster[mx + 2][my + 2] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 4) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 2, 2 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (!flipflag && mx + 1 < MAXDUNX && dMonster[mx + 1][my] != 0 && (dFlags[mx + 1][my] & BFLAG_LIT) != 0) {
|
||||
if (!flipflag && mx + 1 < MAXDUNX && dMonster[mx + 1][my] != 0 && IsTileLit({ mx + 1, my })) {
|
||||
int mi = dMonster[mx + 1][my] > 0 ? dMonster[mx + 1][my] - 1 : -(dMonster[mx + 1][my] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 0 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (flipflag && my + 1 < MAXDUNY && dMonster[mx][my + 1] != 0 && (dFlags[mx][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (flipflag && my + 1 < MAXDUNY && dMonster[mx][my + 1] != 0 && IsTileLit({ mx, my + 1 })) {
|
||||
int mi = dMonster[mx][my + 1] > 0 ? dMonster[mx][my + 1] - 1 : -(dMonster[mx][my + 1] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 0, 1 };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (dMonster[mx][my] != 0 && (dFlags[mx][my] & BFLAG_LIT) != 0) {
|
||||
if (dMonster[mx][my] != 0 && IsTileLit({ mx, my })) {
|
||||
int mi = dMonster[mx][my] > 0 ? dMonster[mx][my] - 1 : -(dMonster[mx][my] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 1) != 0) {
|
||||
cursPosition = { mx, my };
|
||||
pcursmonst = mi;
|
||||
}
|
||||
}
|
||||
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && (dFlags[mx + 1][my + 1] & BFLAG_LIT) != 0) {
|
||||
if (mx + 1 < MAXDUNX && my + 1 < MAXDUNY && dMonster[mx + 1][my + 1] != 0 && IsTileLit({ mx + 1, my + 1 })) {
|
||||
int mi = dMonster[mx + 1][my + 1] > 0 ? dMonster[mx + 1][my + 1] - 1 : -(dMonster[mx + 1][my + 1] + 1);
|
||||
if (Monsters[mi]._mhitpoints >> 6 > 0 && (Monsters[mi].MData->mSelFlag & 2) != 0) {
|
||||
cursPosition = Point { mx, my } + Displacement { 1, 1 };
|
||||
|
|
@ -559,9 +557,9 @@ void CheckCursMove()
|
|||
pcursplr = bv;
|
||||
}
|
||||
}
|
||||
if ((dFlags[mx][my] & BFLAG_DEAD_PLAYER) != 0) {
|
||||
if (TileContainsDeadPlayer({ mx, my })) {
|
||||
for (int i = 0; i < MAX_PLRS; i++) {
|
||||
if (Players[i].position.tile.x == mx && Players[i].position.tile.y == my && i != MyPlayerId) {
|
||||
if (Players[i].position.tile == Point { mx, my } && i != MyPlayerId) {
|
||||
cursPosition = { mx, my };
|
||||
pcursplr = i;
|
||||
}
|
||||
|
|
@ -570,7 +568,7 @@ void CheckCursMove()
|
|||
if (pcurs == CURSOR_RESURRECT) {
|
||||
for (int xx = -1; xx < 2; xx++) {
|
||||
for (int yy = -1; yy < 2; yy++) {
|
||||
if (mx + xx < MAXDUNX && my + yy < MAXDUNY && (dFlags[mx + xx][my + yy] & BFLAG_DEAD_PLAYER) != 0) {
|
||||
if (TileContainsDeadPlayer({ mx + xx, my + yy })) {
|
||||
for (int i = 0; i < MAX_PLRS; i++) {
|
||||
if (Players[i].position.tile.x == mx + xx && Players[i].position.tile.y == my + yy && i != MyPlayerId) {
|
||||
cursPosition = Point { mx, my } + Displacement { xx, yy };
|
||||
|
|
|
|||
|
|
@ -873,7 +873,7 @@ bool GetDebugGridText(Point dungeonCoords, char *debugGridTextBuffer)
|
|||
info = dPreLight[dungeonCoords.x][dungeonCoords.y];
|
||||
break;
|
||||
case DebugGridTextItem::dFlags:
|
||||
info = dFlags[dungeonCoords.x][dungeonCoords.y];
|
||||
info = static_cast<int>(dFlags[dungeonCoords.x][dungeonCoords.y]);
|
||||
break;
|
||||
case DebugGridTextItem::dPlayer:
|
||||
info = dPlayer[dungeonCoords.x][dungeonCoords.y];
|
||||
|
|
|
|||
|
|
@ -1936,7 +1936,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
|
|||
} else {
|
||||
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
dFlags[i][j] |= BFLAG_LIT;
|
||||
dFlags[i][j] |= DungeonFlag::Lit;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2011,7 +2011,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
|
|||
else
|
||||
SyncInitPlrPos(i);
|
||||
} else {
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ MICROS dpiece_defs_map_2[MAXDUNX][MAXDUNY];
|
|||
int8_t dTransVal[MAXDUNX][MAXDUNY];
|
||||
char dLight[MAXDUNX][MAXDUNY];
|
||||
char dPreLight[MAXDUNX][MAXDUNY];
|
||||
int8_t dFlags[MAXDUNX][MAXDUNY];
|
||||
DungeonFlag dFlags[MAXDUNX][MAXDUNY];
|
||||
int8_t dPlayer[MAXDUNX][MAXDUNY];
|
||||
int16_t dMonster[MAXDUNX][MAXDUNY];
|
||||
int8_t dCorpse[MAXDUNX][MAXDUNY];
|
||||
|
|
@ -315,11 +315,6 @@ void FindTransparencyValues(int i, int j, int x, int y, int d, uint8_t floorID)
|
|||
|
||||
} // namespace
|
||||
|
||||
bool InDungeonBounds(Point position)
|
||||
{
|
||||
return position.x >= 0 && position.x < MAXDUNX && position.y >= 0 && position.y < MAXDUNY;
|
||||
}
|
||||
|
||||
void FillSolidBlockTbls()
|
||||
{
|
||||
size_t tileCount;
|
||||
|
|
@ -445,7 +440,7 @@ void DRLG_SetPC()
|
|||
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < w; i++) {
|
||||
dFlags[i + x][j + y] |= BFLAG_POPULATED;
|
||||
dFlags[i + x][j + y] |= DungeonFlag::Populated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -459,7 +454,7 @@ void Make_SetPC(int x, int y, int w, int h)
|
|||
|
||||
for (int j = 0; j < dh; j++) {
|
||||
for (int i = 0; i < dw; i++) {
|
||||
dFlags[i + dx][j + dy] |= BFLAG_POPULATED;
|
||||
dFlags[i + dx][j + dy] |= DungeonFlag::Populated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -506,10 +501,10 @@ void DRLG_HoldThemeRooms()
|
|||
for (int x = themeLoc[i].x; x < themeLoc[i].x + themeLoc[i].width - 1; x++) {
|
||||
int xx = 2 * x + 16;
|
||||
int yy = 2 * y + 16;
|
||||
dFlags[xx][yy] |= BFLAG_POPULATED;
|
||||
dFlags[xx + 1][yy] |= BFLAG_POPULATED;
|
||||
dFlags[xx][yy + 1] |= BFLAG_POPULATED;
|
||||
dFlags[xx + 1][yy + 1] |= BFLAG_POPULATED;
|
||||
dFlags[xx][yy] |= DungeonFlag::Populated;
|
||||
dFlags[xx + 1][yy] |= DungeonFlag::Populated;
|
||||
dFlags[xx][yy + 1] |= DungeonFlag::Populated;
|
||||
dFlags[xx + 1][yy + 1] |= DungeonFlag::Populated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "engine/cel_sprite.hpp"
|
||||
#include "engine/point.hpp"
|
||||
#include "scrollrt.h"
|
||||
#include "utils/enum_traits.h"
|
||||
#include "utils/stdcompat/optional.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
|
@ -69,18 +70,21 @@ enum {
|
|||
// clang-format on
|
||||
};
|
||||
|
||||
enum {
|
||||
enum class DungeonFlag : uint8_t {
|
||||
// clang-format off
|
||||
BFLAG_MISSILE = 1 << 0,
|
||||
BFLAG_VISIBLE = 1 << 1,
|
||||
BFLAG_DEAD_PLAYER = 1 << 2,
|
||||
BFLAG_POPULATED = 1 << 3,
|
||||
BFLAG_MONSTLR = 1 << 4,
|
||||
BFLAG_PLAYERLR = 1 << 5,
|
||||
BFLAG_LIT = 1 << 6,
|
||||
BFLAG_EXPLORED = 1 << 7,
|
||||
None = 0, // Only used by lighting/automap
|
||||
Missile = 1 << 0,
|
||||
Visible = 1 << 1,
|
||||
DeadPlayer = 1 << 2,
|
||||
Populated = 1 << 3,
|
||||
// 1 << 4 and 1 << 5 were used as workarounds for a bug with horizontal movement (relative to the screen) for monsters and players respectively
|
||||
Lit = 1 << 6,
|
||||
Explored = 1 << 7,
|
||||
SavedFlags = (Populated | Lit | Explored), // ~(Missile | Visible | DeadPlayer)
|
||||
LoadedFlags = (Missile | Visible | DeadPlayer | Populated | Lit | Explored)
|
||||
// clang-format on
|
||||
};
|
||||
use_enum_as_flags(DungeonFlag);
|
||||
|
||||
enum _difficulty : uint8_t {
|
||||
DIFF_NORMAL,
|
||||
|
|
@ -199,7 +203,9 @@ extern MICROS dpiece_defs_map_2[MAXDUNX][MAXDUNY];
|
|||
extern int8_t dTransVal[MAXDUNX][MAXDUNY];
|
||||
extern char dLight[MAXDUNX][MAXDUNY];
|
||||
extern char dPreLight[MAXDUNX][MAXDUNY];
|
||||
extern int8_t dFlags[MAXDUNX][MAXDUNY];
|
||||
/** Holds various information about dungeon tiles, @see DungeonFlag */
|
||||
extern DungeonFlag dFlags[MAXDUNX][MAXDUNY];
|
||||
|
||||
/** Contains the player numbers (players array indices) of the map. */
|
||||
extern int8_t dPlayer[MAXDUNX][MAXDUNY];
|
||||
/**
|
||||
|
|
@ -228,7 +234,67 @@ extern char dSpecial[MAXDUNX][MAXDUNY];
|
|||
extern int themeCount;
|
||||
extern THEME_LOC themeLoc[MAXTHEMES];
|
||||
|
||||
bool InDungeonBounds(Point position);
|
||||
constexpr bool InDungeonBounds(Point position)
|
||||
{
|
||||
return position.x >= 0 && position.x < MAXDUNX && position.y >= 0 && position.y < MAXDUNY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a given tile contains at least one missile
|
||||
* @param position Coordinates of the dungeon tile to check
|
||||
* @return true if a missile exists at this position
|
||||
*/
|
||||
constexpr bool TileContainsMissile(Point position)
|
||||
{
|
||||
return InDungeonBounds(position) && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::Missile);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a given tile contains a player corpse
|
||||
* @param position Coordinates of the dungeon tile to check
|
||||
* @return true if a dead player exists at this position
|
||||
*/
|
||||
constexpr bool TileContainsDeadPlayer(Point position)
|
||||
{
|
||||
return InDungeonBounds(position) && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::DeadPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if a given tile contains a decorative object (or similar non-pathable set piece)
|
||||
*
|
||||
* This appears to include stairs so that monsters do not spawn or path onto them, but players can path to them to navigate between layers
|
||||
*
|
||||
* @param position Coordinates of the dungeon tile to check
|
||||
* @return true if a set piece was spawned at this position
|
||||
*/
|
||||
constexpr bool TileContainsSetPiece(Point position)
|
||||
{
|
||||
return InDungeonBounds(position) && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::Populated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if any player can currently see this tile
|
||||
*
|
||||
* Currently only used by monster AI routines so basic monsters out of sight can be ignored until they're likely to interact with the player
|
||||
*
|
||||
* @param position Coordinates of the dungeon tile to check
|
||||
* @return true if the tile is within at least one players vision
|
||||
*/
|
||||
constexpr bool IsTileVisible(Point position)
|
||||
{
|
||||
return InDungeonBounds(position) && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::Visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if a light source is illuminating this tile
|
||||
* @param position Coordinates of the dungeon tile to check
|
||||
* @return true if the tile is within the radius of at least one light source
|
||||
*/
|
||||
constexpr bool IsTileLit(Point position)
|
||||
{
|
||||
return InDungeonBounds(position) && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::Lit);
|
||||
}
|
||||
|
||||
void FillSolidBlockTbls();
|
||||
void SetDungeonMicros();
|
||||
void DRLG_InitTrans();
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ bool ItemPlace(Point position)
|
|||
return false;
|
||||
if (dObject[position.x][position.y] != 0)
|
||||
return false;
|
||||
if ((dFlags[position.x][position.y] & BFLAG_POPULATED) != 0)
|
||||
if (TileContainsSetPiece(position))
|
||||
return false;
|
||||
if (nSolidTable[dPiece[position.x][position.y]])
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ void DoUnVision(Point position, int nRadius)
|
|||
|
||||
for (int i = x1; i < x2; i++) {
|
||||
for (int j = y1; j < y2; j++) {
|
||||
dFlags[i][j] &= ~(BFLAG_VISIBLE | BFLAG_LIT);
|
||||
dFlags[i][j] &= ~(DungeonFlag::Visible | DungeonFlag::Lit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -649,15 +649,15 @@ void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool vi
|
|||
{
|
||||
if (InDungeonBounds(position)) {
|
||||
if (doautomap != MAP_EXP_NONE) {
|
||||
if (dFlags[position.x][position.y] != 0) {
|
||||
if (dFlags[position.x][position.y] != DungeonFlag::None) {
|
||||
SetAutomapView(position, doautomap);
|
||||
}
|
||||
dFlags[position.x][position.y] |= BFLAG_EXPLORED;
|
||||
dFlags[position.x][position.y] |= DungeonFlag::Explored;
|
||||
}
|
||||
if (visible) {
|
||||
dFlags[position.x][position.y] |= BFLAG_LIT;
|
||||
dFlags[position.x][position.y] |= DungeonFlag::Lit;
|
||||
}
|
||||
dFlags[position.x][position.y] |= BFLAG_VISIBLE;
|
||||
dFlags[position.x][position.y] |= DungeonFlag::Visible;
|
||||
}
|
||||
|
||||
for (int v = 0; v < 4; v++) {
|
||||
|
|
@ -712,15 +712,15 @@ void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool vi
|
|||
|| (InDungeonBounds({ x2adj + nCrawlX, y2adj + nCrawlY })
|
||||
&& !nBlockTable[dPiece[x2adj + nCrawlX][y2adj + nCrawlY]])) {
|
||||
if (doautomap != MAP_EXP_NONE) {
|
||||
if (dFlags[nCrawlX][nCrawlY] != 0) {
|
||||
if (dFlags[nCrawlX][nCrawlY] != DungeonFlag::None) {
|
||||
SetAutomapView({ nCrawlX, nCrawlY }, doautomap);
|
||||
}
|
||||
dFlags[nCrawlX][nCrawlY] |= BFLAG_EXPLORED;
|
||||
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Explored;
|
||||
}
|
||||
if (visible) {
|
||||
dFlags[nCrawlX][nCrawlY] |= BFLAG_LIT;
|
||||
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Lit;
|
||||
}
|
||||
dFlags[nCrawlX][nCrawlY] |= BFLAG_VISIBLE;
|
||||
dFlags[nCrawlX][nCrawlY] |= DungeonFlag::Visible;
|
||||
if (!nBlockerFlag) {
|
||||
int8_t nTrans = dTransVal[nCrawlX][nCrawlY];
|
||||
if (nTrans != 0) {
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ void LoadPlayer(LoadHelper &file, Player &player)
|
|||
player.position.temp.y = file.NextLE<int32_t>();
|
||||
player.tempDirection = static_cast<Direction>(file.NextLE<int32_t>());
|
||||
player.spellLevel = file.NextLE<int32_t>();
|
||||
file.Skip(4); // skip _pVar5, was used for storing position of a tile which should have its BFLAG_PLAYERLR flag removed after walking
|
||||
file.Skip(4); // skip _pVar5, was used for storing position of a tile which should have its HorizontalMovingPlayer flag removed after walking
|
||||
player.position.offset2.deltaX = file.NextLE<int32_t>();
|
||||
player.position.offset2.deltaY = file.NextLE<int32_t>();
|
||||
file.Skip(4); // Skip actionFrame
|
||||
|
|
@ -1115,7 +1115,7 @@ void SavePlayer(SaveHelper &file, const Player &player)
|
|||
file.WriteLE<int32_t>(player.position.temp.y);
|
||||
file.WriteLE<int32_t>(static_cast<int32_t>(player.tempDirection));
|
||||
file.WriteLE<int32_t>(player.spellLevel);
|
||||
file.Skip<int32_t>(); // skip _pVar5, was used for storing position of a tile which should have its BFLAG_PLAYERLR flag removed after walking
|
||||
file.Skip<int32_t>(); // skip _pVar5, was used for storing position of a tile which should have its HorizontalMovingPlayer flag removed after walking
|
||||
file.WriteLE<int32_t>(player.position.offset2.deltaX);
|
||||
file.WriteLE<int32_t>(player.position.offset2.deltaY);
|
||||
file.Skip<int32_t>(); // Skip _pVar8
|
||||
|
|
@ -1803,7 +1803,7 @@ void LoadGame(bool firstflag)
|
|||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
dFlags[i][j] = file.NextLE<int8_t>() & ~(BFLAG_PLAYERLR | BFLAG_MONSTLR);
|
||||
dFlags[i][j] = static_cast<DungeonFlag>(file.NextLE<uint8_t>()) & DungeonFlag::LoadedFlags;
|
||||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
|
|
@ -1997,7 +1997,7 @@ void SaveGameData()
|
|||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
file.WriteLE<int8_t>(dFlags[i][j] & ~(BFLAG_MISSILE | BFLAG_VISIBLE | BFLAG_DEAD_PLAYER));
|
||||
file.WriteLE<uint8_t>(static_cast<uint8_t>(dFlags[i][j] & DungeonFlag::SavedFlags));
|
||||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
|
|
@ -2035,7 +2035,7 @@ void SaveGameData()
|
|||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
file.WriteLE<int8_t>((dFlags[i][j] & BFLAG_MISSILE) != 0 ? -1 : 0); // For backwards compatability
|
||||
file.WriteLE<int8_t>(TileContainsMissile({ i, j }) ? -1 : 0); // For backwards compatability
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2104,7 +2104,7 @@ void SaveLevel()
|
|||
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
file.WriteLE<int8_t>(dFlags[i][j] & ~(BFLAG_MISSILE | BFLAG_VISIBLE | BFLAG_DEAD_PLAYER));
|
||||
file.WriteLE<uint8_t>(static_cast<uint8_t>(dFlags[i][j] & DungeonFlag::SavedFlags));
|
||||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
|
|
@ -2186,7 +2186,7 @@ void LoadLevel()
|
|||
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
dFlags[i][j] = file.NextLE<int8_t>() & ~(BFLAG_PLAYERLR | BFLAG_MONSTLR);
|
||||
dFlags[i][j] = static_cast<DungeonFlag>(file.NextLE<uint8_t>()) & DungeonFlag::LoadedFlags;
|
||||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ void PutMissile(Missile &missile)
|
|||
return;
|
||||
}
|
||||
|
||||
dFlags[position.x][position.y] |= BFLAG_MISSILE;
|
||||
dFlags[position.x][position.y] |= DungeonFlag::Missile;
|
||||
|
||||
if (missile._miPreFlag)
|
||||
MissilePreFlag = true;
|
||||
|
|
@ -706,7 +706,7 @@ void AddRune(Missile &missile, Point dst, missile_id missileID)
|
|||
continue;
|
||||
|
||||
int dp = dPiece[target.x][target.y];
|
||||
if (nSolidTable[dp] || dObject[target.x][target.y] != 0 || (dFlags[target.x][target.y] & BFLAG_MISSILE) != 0)
|
||||
if (nSolidTable[dp] || dObject[target.x][target.y] != 0 || TileContainsMissile(target))
|
||||
continue;
|
||||
|
||||
missile.position.tile = target;
|
||||
|
|
@ -1295,7 +1295,7 @@ void InitMissiles()
|
|||
}
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
|
||||
dFlags[i][j] &= ~BFLAG_MISSILE;
|
||||
dFlags[i][j] &= ~DungeonFlag::Missile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2087,7 +2087,7 @@ void AddTown(Missile &missile, Point dst, Direction /*midir*/)
|
|||
continue;
|
||||
|
||||
int dp = dPiece[target.x][target.y];
|
||||
if ((dFlags[target.x][target.y] & BFLAG_MISSILE) == 0 && !nSolidTable[dp] && !nMissileTable[dp] && dObject[target.x][target.y] == 0 && dPlayer[target.x][target.y] == 0) {
|
||||
if (!TileContainsMissile(target) && !nSolidTable[dp] && !nMissileTable[dp] && dObject[target.x][target.y] == 0 && dPlayer[target.x][target.y] == 0) {
|
||||
if (!CheckIfTrig(target)) {
|
||||
missile.position.tile = target;
|
||||
missile.position.start = target;
|
||||
|
|
@ -2201,7 +2201,7 @@ void AddGuardian(Missile &missile, Point dst, Direction /*midir*/)
|
|||
|
||||
if (LineClearMissile(missile.position.start, target)) {
|
||||
int dp = dPiece[target.x][target.y];
|
||||
if (dMonster[target.x][target.y] == 0 && !nSolidTable[dp] && !nMissileTable[dp] && dObject[target.x][target.y] == 0 && (dFlags[target.x][target.y] & BFLAG_MISSILE) == 0) {
|
||||
if (dMonster[target.x][target.y] == 0 && !nSolidTable[dp] && !nMissileTable[dp] && dObject[target.x][target.y] == 0 && !TileContainsMissile(target)) {
|
||||
missile.position.tile = target;
|
||||
missile.position.start = target;
|
||||
missile._miDelFlag = false;
|
||||
|
|
@ -4245,7 +4245,7 @@ void ProcessMissiles()
|
|||
for (int i = 0; i < ActiveMissileCount; i++) {
|
||||
auto &missile = Missiles[ActiveMissiles[i]];
|
||||
const auto &position = missile.position.tile;
|
||||
dFlags[position.x][position.y] &= ~BFLAG_MISSILE;
|
||||
dFlags[position.x][position.y] &= ~DungeonFlag::Missile;
|
||||
if (!InDungeonBounds(position))
|
||||
missile._miDelFlag = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,21 +251,17 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
|
|||
|
||||
bool CanPlaceMonster(int xp, int yp)
|
||||
{
|
||||
char f;
|
||||
|
||||
if (!InDungeonBounds({ xp, yp })
|
||||
|| dMonster[xp][yp] != 0
|
||||
|| dPlayer[xp][yp] != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
f = dFlags[xp][yp];
|
||||
|
||||
if ((f & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible({ xp, yp })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((f & BFLAG_POPULATED) != 0) {
|
||||
if (TileContainsSetPiece({ xp, yp })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1996,7 +1992,7 @@ bool RandomWalk2(int i, Direction md)
|
|||
*/
|
||||
bool IsTileSafe(const Monster &monster, Point position)
|
||||
{
|
||||
if ((dFlags[position.x][position.y] & BFLAG_MISSILE) == 0) {
|
||||
if (!TileContainsMissile(position)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2309,14 +2305,12 @@ void ZombieAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) == 0) {
|
||||
if (!IsTileVisible(monster.position.tile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GenerateRnd(100) < 2 * monster._mint + 10) {
|
||||
int dist = monster.enemyPosition.WalkingDistance({ mx, my });
|
||||
int dist = monster.enemyPosition.WalkingDistance(monster.position.tile);
|
||||
if (dist >= 2) {
|
||||
if (dist >= 2 * monster._mint + 4) {
|
||||
Direction md = monster._mdir;
|
||||
|
|
@ -2929,13 +2923,11 @@ void GharbadAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
|
||||
if (monster.mtalkmsg >= TEXT_GARBUD1
|
||||
&& monster.mtalkmsg <= TEXT_GARBUD3
|
||||
&& (dFlags[mx][my] & BFLAG_VISIBLE) == 0
|
||||
&& !IsTileVisible(monster.position.tile)
|
||||
&& monster._mgoal == MGOAL_TALKING) {
|
||||
monster._mgoal = MGOAL_INQUIRING;
|
||||
switch (monster.mtalkmsg) {
|
||||
|
|
@ -2953,7 +2945,7 @@ void GharbadAi(int i)
|
|||
}
|
||||
}
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (monster.mtalkmsg == TEXT_GARBUD4) {
|
||||
if (!effect_is_playing(USFX_GARBUD4) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster._mgoal = MGOAL_NORMAL;
|
||||
|
|
@ -2988,11 +2980,9 @@ void SnotSpilAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
|
||||
if (monster.mtalkmsg == TEXT_BANNER10 && (dFlags[mx][my] & BFLAG_VISIBLE) == 0 && monster._mgoal == MGOAL_TALKING) {
|
||||
if (monster.mtalkmsg == TEXT_BANNER10 && !IsTileVisible(monster.position.tile) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster.mtalkmsg = TEXT_BANNER11;
|
||||
monster._mgoal = MGOAL_INQUIRING;
|
||||
}
|
||||
|
|
@ -3002,7 +2992,7 @@ void SnotSpilAi(int i)
|
|||
monster._mgoal = MGOAL_NORMAL;
|
||||
}
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (monster.mtalkmsg == TEXT_BANNER12) {
|
||||
if (!effect_is_playing(USFX_SNOT3) && monster._mgoal == MGOAL_TALKING) {
|
||||
ObjChangeMap(setpc_x, setpc_y, setpc_x + setpc_w + 1, setpc_y + setpc_h + 1);
|
||||
|
|
@ -3158,15 +3148,13 @@ void ZharAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
if (monster.mtalkmsg == TEXT_ZHAR1 && (dFlags[mx][my] & BFLAG_VISIBLE) == 0 && monster._mgoal == MGOAL_TALKING) {
|
||||
if (monster.mtalkmsg == TEXT_ZHAR1 && !IsTileVisible(monster.position.tile) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster.mtalkmsg = TEXT_ZHAR2;
|
||||
monster._mgoal = MGOAL_INQUIRING;
|
||||
}
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (monster.mtalkmsg == TEXT_ZHAR2) {
|
||||
if (!effect_is_playing(USFX_ZHAR2) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster._msquelch = UINT8_MAX;
|
||||
|
|
@ -3265,13 +3253,11 @@ void LazarusAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (!gbIsMultiplayer) {
|
||||
auto &myPlayer = Players[MyPlayerId];
|
||||
if (monster.mtalkmsg == TEXT_VILE13 && monster._mgoal == MGOAL_INQUIRING && myPlayer.position.tile.x == 35 && myPlayer.position.tile.y == 46) {
|
||||
if (monster.mtalkmsg == TEXT_VILE13 && monster._mgoal == MGOAL_INQUIRING && myPlayer.position.tile == Point { 35, 46 }) {
|
||||
PlayInGameMovie("gendata\\fprst3.smk");
|
||||
monster._mmode = MonsterMode::Talk;
|
||||
Quests[Q_BETRAYER]._qvar1 = 5;
|
||||
|
|
@ -3313,11 +3299,9 @@ void LazarusMinionAi(int i)
|
|||
if (monster._mmode != MonsterMode::Stand)
|
||||
return;
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (!gbIsMultiplayer) {
|
||||
if (Quests[Q_BETRAYER]._qvar1 <= 5) {
|
||||
monster._mgoal = MGOAL_INQUIRING;
|
||||
|
|
@ -3343,16 +3327,14 @@ void LachdananAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
|
||||
if (monster.mtalkmsg == TEXT_VEIL9 && (dFlags[mx][my] & BFLAG_VISIBLE) == 0 && monster._mgoal == MGOAL_TALKING) {
|
||||
if (monster.mtalkmsg == TEXT_VEIL9 && !IsTileVisible(monster.position.tile) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster.mtalkmsg = TEXT_VEIL10;
|
||||
monster._mgoal = MGOAL_INQUIRING;
|
||||
}
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (monster.mtalkmsg == TEXT_VEIL11) {
|
||||
if (!effect_is_playing(USFX_LACH3) && monster._mgoal == MGOAL_TALKING) {
|
||||
monster.mtalkmsg = TEXT_NONE;
|
||||
|
|
@ -3374,10 +3356,8 @@ void WarlordAi(int i)
|
|||
return;
|
||||
}
|
||||
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
Direction md = GetMonsterDirection(monster);
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
if (monster.mtalkmsg == TEXT_WARLRD9 && monster._mgoal == MGOAL_INQUIRING)
|
||||
monster._mmode = MonsterMode::Talk;
|
||||
if (monster.mtalkmsg == TEXT_WARLRD9 && !effect_is_playing(USFX_WARLRD1) && monster._mgoal == MGOAL_TALKING) {
|
||||
|
|
@ -4282,10 +4262,8 @@ void ProcessMonsters()
|
|||
monster._mhitpoints += monster.mLevel;
|
||||
}
|
||||
}
|
||||
int mx = monster.position.tile.x;
|
||||
int my = monster.position.tile.y;
|
||||
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0 && monster._msquelch == 0) {
|
||||
if (IsTileVisible(monster.position.tile) && monster._msquelch == 0) {
|
||||
if (monster.MType->mtype == MT_CLEAVER) {
|
||||
PlaySFX(USFX_CLEAVER);
|
||||
}
|
||||
|
|
@ -4312,7 +4290,7 @@ void ProcessMonsters()
|
|||
assert(monster._menemy >= 0 && monster._menemy < MAX_PLRS);
|
||||
auto &player = Players[monster._menemy];
|
||||
monster.enemyPosition = player.position.future;
|
||||
if ((dFlags[mx][my] & BFLAG_VISIBLE) != 0) {
|
||||
if (IsTileVisible(monster.position.tile)) {
|
||||
monster._msquelch = UINT8_MAX;
|
||||
monster.position.last = player.position.future;
|
||||
} else if (monster._msquelch != 0 && monster.MType->mtype != MT_DIABLO) { /// BUGFIX: change '_mAi' to 'MType->mtype'
|
||||
|
|
|
|||
|
|
@ -1669,7 +1669,7 @@ DWORD OnPlayerJoinLevel(const TCmd *pCmd, int pnum)
|
|||
player._pmode = PM_DEATH;
|
||||
NewPlrAnim(player, player_graphic::Death, Direction::South, player._pDFrames, 1);
|
||||
player.AnimInfo.CurrentFrame = player.AnimInfo.NumberOfFrames - 1;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
|
||||
}
|
||||
|
||||
player._pvid = AddVision(player.position.tile, player._pLightRad, pnum == MyPlayerId);
|
||||
|
|
|
|||
|
|
@ -822,7 +822,7 @@ void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv)
|
|||
player._pmode = PM_DEATH;
|
||||
NewPlrAnim(player, player_graphic::Death, Direction::South, player._pDFrames, 1);
|
||||
player.AnimInfo.CurrentFrame = player.AnimInfo.NumberOfFrames - 1;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ bool RndLocOk(int xp, int yp)
|
|||
return false;
|
||||
if (dObject[xp][yp] != 0)
|
||||
return false;
|
||||
if ((dFlags[xp][yp] & BFLAG_POPULATED) != 0)
|
||||
if (TileContainsSetPiece({ xp, yp }))
|
||||
return false;
|
||||
if (nSolidTable[dPiece[xp][yp]])
|
||||
return false;
|
||||
|
|
@ -306,7 +306,7 @@ bool RndLocOk(int xp, int yp)
|
|||
|
||||
bool CanPlaceWallTrap(int xp, int yp)
|
||||
{
|
||||
if ((dFlags[xp][yp] & BFLAG_POPULATED) != 0)
|
||||
if (TileContainsSetPiece({ xp, yp }))
|
||||
return false;
|
||||
|
||||
return nTrapTable[dPiece[xp][yp]];
|
||||
|
|
@ -550,16 +550,11 @@ void AddL3Objs(int x1, int y1, int x2, int y2)
|
|||
}
|
||||
}
|
||||
|
||||
bool TorchLocOK(int xp, int yp)
|
||||
{
|
||||
return (dFlags[xp][yp] & BFLAG_POPULATED) == 0;
|
||||
}
|
||||
|
||||
void AddL2Torches()
|
||||
{
|
||||
for (int j = 0; j < MAXDUNY; j++) {
|
||||
for (int i = 0; i < MAXDUNX; i++) {
|
||||
if (!TorchLocOK(i, j))
|
||||
if (TileContainsSetPiece({ i, j }))
|
||||
continue;
|
||||
|
||||
int pn = dPiece[i][j];
|
||||
|
|
|
|||
|
|
@ -1511,7 +1511,7 @@ bool DoDeath(int pnum)
|
|||
|
||||
player.AnimInfo.TicksPerFrame = 10000;
|
||||
player.AnimInfo.CurrentFrame = player.AnimInfo.NumberOfFrames;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
|
||||
}
|
||||
|
||||
if (player.deathFrame < 100) {
|
||||
|
|
@ -3005,7 +3005,7 @@ StartPlayerKill(int pnum, int earflag)
|
|||
if (player.plrlevel == currlevel) {
|
||||
FixPlayerLocation(pnum, player._pdir);
|
||||
RemovePlrFromMap(pnum);
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[player.position.tile.x][player.position.tile.y] |= DungeonFlag::DeadPlayer;
|
||||
SetPlayerOld(player);
|
||||
|
||||
if (pnum == MyPlayerId) {
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ void RemovePortalMissile(int id)
|
|||
int mi = ActiveMissiles[i];
|
||||
auto &missile = Missiles[mi];
|
||||
if (missile._mitype == MIS_TOWN && missile._misource == id) {
|
||||
dFlags[missile.position.tile.x][missile.position.tile.y] &= ~BFLAG_MISSILE;
|
||||
dFlags[missile.position.tile.x][missile.position.tile.y] &= ~DungeonFlag::Missile;
|
||||
|
||||
if (Portals[id].level != 0)
|
||||
AddUnLight(missile._mlid);
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ void DrawMonster(const Surface &out, Point tilePosition, Point targetBufferPosit
|
|||
|
||||
const auto &cel = *monster.AnimInfo.pCelSprite;
|
||||
|
||||
if ((dFlags[tilePosition.x][tilePosition.y] & BFLAG_LIT) == 0) {
|
||||
if (!IsTileLit(tilePosition)) {
|
||||
Cl2DrawLightTbl(out, targetBufferPosition.x, targetBufferPosition.y, cel, nCel, 1);
|
||||
return;
|
||||
}
|
||||
|
|
@ -509,7 +509,7 @@ void DrawPlayerIcons(const Surface &out, int pnum, Point position, bool lighting
|
|||
*/
|
||||
void DrawPlayer(const Surface &out, int pnum, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
if ((dFlags[tilePosition.x][tilePosition.y] & BFLAG_LIT) == 0 && !Players[MyPlayerId]._pInfraFlag && leveltype != DTYPE_TOWN) {
|
||||
if (!IsTileLit(tilePosition) && !Players[MyPlayerId]._pInfraFlag && leveltype != DTYPE_TOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -548,7 +548,7 @@ void DrawPlayer(const Surface &out, int pnum, Point tilePosition, Point targetBu
|
|||
return;
|
||||
}
|
||||
|
||||
if ((dFlags[tilePosition.x][tilePosition.y] & BFLAG_LIT) == 0 || (Players[MyPlayerId]._pInfraFlag && LightTableIndex > 8)) {
|
||||
if (!IsTileLit(tilePosition) || (Players[MyPlayerId]._pInfraFlag && LightTableIndex > 8)) {
|
||||
Cl2DrawLightTbl(out, targetBufferPosition.x, targetBufferPosition.y, *pCelSprite, nCel, 1);
|
||||
DrawPlayerIcons(out, pnum, targetBufferPosition, true);
|
||||
return;
|
||||
|
|
@ -574,12 +574,12 @@ void DrawPlayer(const Surface &out, int pnum, Point tilePosition, Point targetBu
|
|||
*/
|
||||
void DrawDeadPlayer(const Surface &out, Point tilePosition, Point targetBufferPosition)
|
||||
{
|
||||
dFlags[tilePosition.x][tilePosition.y] &= ~BFLAG_DEAD_PLAYER;
|
||||
dFlags[tilePosition.x][tilePosition.y] &= ~DungeonFlag::DeadPlayer;
|
||||
|
||||
for (int i = 0; i < MAX_PLRS; i++) {
|
||||
auto &player = Players[i];
|
||||
if (player.plractive && player._pHitPoints == 0 && player.plrlevel == (BYTE)currlevel && player.position.tile == tilePosition) {
|
||||
dFlags[tilePosition.x][tilePosition.y] |= BFLAG_DEAD_PLAYER;
|
||||
dFlags[tilePosition.x][tilePosition.y] |= DungeonFlag::DeadPlayer;
|
||||
const Displacement center { CalculateWidth2(player.AnimInfo.pCelSprite == nullptr ? 96 : player.AnimInfo.pCelSprite->Width()), 0 };
|
||||
const Point playerRenderPosition { targetBufferPosition + player.position.offset - center };
|
||||
DrawPlayer(out, i, tilePosition, playerRenderPosition);
|
||||
|
|
@ -758,7 +758,7 @@ void DrawMonsterHelper(const Surface &out, Point tilePosition, Point targetBuffe
|
|||
return;
|
||||
}
|
||||
|
||||
if ((dFlags[tilePosition.x][tilePosition.y] & BFLAG_LIT) == 0 && !Players[MyPlayerId]._pInfraFlag)
|
||||
if (!IsTileLit(tilePosition) && !Players[MyPlayerId]._pInfraFlag)
|
||||
return;
|
||||
|
||||
if (mi < 0 || mi >= MAXMONSTERS) {
|
||||
|
|
@ -836,12 +836,11 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
|
|||
|
||||
DrawCell(out, tilePosition, targetBufferPosition);
|
||||
|
||||
int8_t bFlag = dFlags[tilePosition.x][tilePosition.y];
|
||||
int8_t bDead = dCorpse[tilePosition.x][tilePosition.y];
|
||||
int8_t bMap = dTransVal[tilePosition.x][tilePosition.y];
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (DebugVision && (bFlag & BFLAG_LIT) != 0) {
|
||||
if (DebugVision && IsTileLit(tilePosition)) {
|
||||
CelClippedDrawTo(out, targetBufferPosition, *pSquareCel, 1);
|
||||
}
|
||||
DebugCoordsMap[tilePosition.x + tilePosition.y * MAXDUNX] = targetBufferPosition;
|
||||
|
|
@ -874,7 +873,7 @@ void DrawDungeon(const Surface &out, Point tilePosition, Point targetBufferPosit
|
|||
DrawObject(out, tilePosition, targetBufferPosition, true);
|
||||
DrawItem(out, tilePosition, targetBufferPosition, true);
|
||||
|
||||
if ((bFlag & BFLAG_DEAD_PLAYER) != 0) {
|
||||
if (TileContainsDeadPlayer(tilePosition)) {
|
||||
DrawDeadPlayer(out, tilePosition, targetBufferPosition);
|
||||
}
|
||||
if (dPlayer[tilePosition.x][tilePosition.y] > 0) {
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ bool CheckThemeRoom(int tv)
|
|||
for (int i = 0; i < MAXDUNX; i++) {
|
||||
if (dTransVal[i][j] != tv)
|
||||
continue;
|
||||
if ((dFlags[i][j] & BFLAG_POPULATED) != 0)
|
||||
if (TileContainsSetPiece({ i, j }))
|
||||
return false;
|
||||
|
||||
tarea++;
|
||||
|
|
@ -460,7 +460,7 @@ void HoldThemeRooms()
|
|||
for (int y = 0; y < MAXDUNY; y++) {
|
||||
for (int x = 0; x < MAXDUNX; x++) {
|
||||
if (dTransVal[x][y] == v) {
|
||||
dFlags[x][y] |= BFLAG_POPULATED;
|
||||
dFlags[x][y] |= DungeonFlag::Populated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -697,7 +697,7 @@ void Freeupstairs()
|
|||
|
||||
for (int yy = -2; yy <= 2; yy++) {
|
||||
for (int xx = -2; xx <= 2; xx++) {
|
||||
dFlags[tx + xx][ty + yy] |= BFLAG_POPULATED;
|
||||
dFlags[tx + xx][ty + yy] |= DungeonFlag::Populated;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,4 +105,10 @@ constexpr bool HasAnyOf(EnumType lhs, EnumType test)
|
|||
return (lhs & test) != static_cast<EnumType>(0); // Some flags enums may not use a None value outside this check so we don't require an EnumType::None definition here.
|
||||
}
|
||||
|
||||
template <typename EnumType, std::enable_if_t<std::is_enum<EnumType>::value && is_flags_enum<EnumType>::value, bool> = true>
|
||||
constexpr bool HasNoneOf(EnumType lhs, EnumType test)
|
||||
{
|
||||
return !HasAnyOf(lhs, test);
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue