Browse Source

Optimize IsTileSafe

Add dungeon flags for Fire/Lightning Wall and use them to check if the
monster considers the tile safe.
pull/5590/head
Gleb Mazovetskiy 3 years ago committed by Anders Jenbo
parent
commit
09d7f99c32
  1. 21
      Source/levels/gendung.h
  2. 11
      Source/missiles.cpp
  3. 23
      Source/monster.cpp

21
Source/levels/gendung.h

@ -84,16 +84,17 @@ enum lvl_entry : uint8_t {
enum class DungeonFlag : uint8_t {
// clang-format off
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)
None = 0, // Only used by lighting/automap
Missile = 1 << 0,
Visible = 1 << 1,
DeadPlayer = 1 << 2,
Populated = 1 << 3,
MissileFireWall = 1 << 4,
MissileLightningWall = 1 << 5,
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);

11
Source/missiles.cpp

@ -131,7 +131,12 @@ void PutMissile(Missile &missile)
return;
}
dFlags[position.x][position.y] |= DungeonFlag::Missile;
DungeonFlag &flags = dFlags[position.x][position.y];
flags |= DungeonFlag::Missile;
if (missile._mitype == MIS_FIREWALL)
flags |= DungeonFlag::MissileFireWall;
if (missile._mitype == MIS_LIGHTWALL)
flags |= DungeonFlag::MissileLightningWall;
if (missile._miPreFlag)
MissilePreFlag = true;
@ -1107,7 +1112,7 @@ void InitMissiles()
Missiles.clear();
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) { // NOLINT(modernize-loop-convert)
dFlags[i][j] &= ~DungeonFlag::Missile;
dFlags[i][j] &= ~(DungeonFlag::Missile | DungeonFlag::MissileFireWall | DungeonFlag::MissileLightningWall);
}
}
}
@ -4070,7 +4075,7 @@ void ProcessMissiles()
for (auto &missile : Missiles) {
const auto &position = missile.position.tile;
if (InDungeonBounds(position)) {
dFlags[position.x][position.y] &= ~DungeonFlag::Missile;
dFlags[position.x][position.y] &= ~(DungeonFlag::Missile | DungeonFlag::MissileFireWall | DungeonFlag::MissileLightningWall);
} else {
missile._miDelFlag = true;
}

23
Source/monster.cpp

@ -1685,25 +1685,14 @@ bool RandomWalk2(Monster &monster, Direction md)
*/
bool IsTileSafe(const Monster &monster, Point position)
{
if (!TileContainsMissile(position)) {
return true;
}
if (!InDungeonBounds(position))
return false;
bool fearsFire = (monster.resistance & IMMUNE_FIRE) == 0 || monster.type().type == MT_DIABLO;
bool fearsLightning = (monster.resistance & IMMUNE_LIGHTNING) == 0 || monster.type().type == MT_DIABLO;
const bool fearsFire = (monster.resistance & IMMUNE_FIRE) == 0 || monster.type().type == MT_DIABLO;
const bool fearsLightning = (monster.resistance & IMMUNE_LIGHTNING) == 0 || monster.type().type == MT_DIABLO;
for (auto &missile : Missiles) {
if (missile.position.tile == position) {
if (fearsFire && missile._mitype == MIS_FIREWALL) {
return false;
}
if (fearsLightning && missile._mitype == MIS_LIGHTWALL) {
return false;
}
}
}
return true;
return !(fearsFire && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::MissileFireWall))
&& !(fearsLightning && HasAnyOf(dFlags[position.x][position.y], DungeonFlag::MissileLightningWall));
}
/**

Loading…
Cancel
Save