diff --git a/Source/debug.cpp b/Source/debug.cpp index 30b241ef5..cd2f54384 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -63,11 +63,9 @@ enum class DebugGridTextItem : uint16_t { objectindex, // take dPiece as index - nBlockTable, - nSolidTable, - nTransTable, - nMissileTable, - nTrapTable, + Solid, + Transparent, + Trap, // megatiles AutomapView, @@ -846,11 +844,9 @@ std::string DebugCmdShowTileData(const string_view parameter) "coords", "cursorcoords", "objectindex", - "nBlockTable", - "nSolidTable", - "nTransTable", - "nMissileTable", - "nTrapTable", + "solid", + "transparent", + "trap", "AutomapView", "dungeon", "pdungeon", @@ -1132,20 +1128,14 @@ bool GetDebugGridText(Point dungeonCoords, char *debugGridTextBuffer) case DebugGridTextItem::dObject: info = dObject[dungeonCoords.x][dungeonCoords.y]; break; - case DebugGridTextItem::nBlockTable: - info = nBlockTable[dPiece[dungeonCoords.x][dungeonCoords.y]]; + case DebugGridTextItem::Solid: + info = TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::Solid) << 0 | TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::BlockLight) << 1 | TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::BlockMissile) << 2; break; - case DebugGridTextItem::nSolidTable: - info = nSolidTable[dPiece[dungeonCoords.x][dungeonCoords.y]]; + case DebugGridTextItem::Transparent: + info = TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::Transparent) << 0 | TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::TransparentLeft) << 1 | TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::TransparentRight) << 2; break; - case DebugGridTextItem::nTransTable: - info = nTransTable[dPiece[dungeonCoords.x][dungeonCoords.y]]; - break; - case DebugGridTextItem::nMissileTable: - info = nMissileTable[dPiece[dungeonCoords.x][dungeonCoords.y]]; - break; - case DebugGridTextItem::nTrapTable: - info = nTrapTable[dPiece[dungeonCoords.x][dungeonCoords.y]]; + case DebugGridTextItem::Trap: + info = TileHasAny(dPiece[dungeonCoords.x][dungeonCoords.y], TileProperties::Trap); break; case DebugGridTextItem::AutomapView: info = AutomapView[megaCoords.x][megaCoords.y]; diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 96fccacfb..15a03a9be 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2133,7 +2133,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) if (!setlevel) { CreateLevel(lvldir); IncProgress(); - FillSolidBlockTbls(); + LoadLevelSOLData(); SetRndSeed(glSeedTbl[currlevel]); if (leveltype != DTYPE_TOWN) { @@ -2254,7 +2254,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) IncProgress(); InitCorpses(); IncProgress(); - FillSolidBlockTbls(); + LoadLevelSOLData(); IncProgress(); if (lvldir == ENTRY_WARPLVL) diff --git a/Source/engine/render/dun_render.cpp b/Source/engine/render/dun_render.cpp index 86b01783b..25801d4b3 100644 --- a/Source/engine/render/dun_render.cpp +++ b/Source/engine/render/dun_render.cpp @@ -1131,12 +1131,12 @@ const std::uint32_t *GetMask(TileType tile) return &WallMaskFullyTrasparent[TILE_HEIGHT - 1]; } if (arch_draw_type == 1 && tile != TileType::LeftTriangle) { - if ((block_lvid[level_piece_id] & 0x01) != 0) { + if (TileHasAny(level_piece_id, TileProperties::TransparentLeft)) { return &LeftMaskTransparent[TILE_HEIGHT - 1]; } } if (arch_draw_type == 2 && tile != TileType::RightTriangle) { - if ((block_lvid[level_piece_id] & 0x02) != 0) { + if (TileHasAny(level_piece_id, TileProperties::TransparentRight)) { return &RightMaskTransparent[TILE_HEIGHT - 1]; } } diff --git a/Source/gendung.cpp b/Source/gendung.cpp index 37b42350b..66726cc72 100644 --- a/Source/gendung.cpp +++ b/Source/gendung.cpp @@ -30,12 +30,7 @@ std::optional pSpecialCels; std::unique_ptr pMegaTiles; std::unique_ptr pLevelPieces; std::unique_ptr pDungeonCels; -std::array block_lvid; -std::array nBlockTable; -std::array nSolidTable; -std::array nTransTable; -std::array nMissileTable; -std::array nTrapTable; +std::array SOLData; Point dminPosition; Point dmaxPosition; dungeon_type leveltype; @@ -64,30 +59,6 @@ THEME_LOC themeLoc[MAXTHEMES]; namespace { -std::unique_ptr LoadLevelSOLData(size_t &tileCount) -{ - switch (leveltype) { - case DTYPE_TOWN: - if (gbIsHellfire) - return LoadFileInMem("NLevels\\TownData\\Town.SOL", &tileCount); - return LoadFileInMem("Levels\\TownData\\Town.SOL", &tileCount); - case DTYPE_CATHEDRAL: - return LoadFileInMem("Levels\\L1Data\\L1.SOL", &tileCount); - case DTYPE_CATACOMBS: - return LoadFileInMem("Levels\\L2Data\\L2.SOL", &tileCount); - case DTYPE_CAVES: - return LoadFileInMem("Levels\\L3Data\\L3.SOL", &tileCount); - case DTYPE_HELL: - return LoadFileInMem("Levels\\L4Data\\L4.SOL", &tileCount); - case DTYPE_NEST: - return LoadFileInMem("NLevels\\L6Data\\L6.SOL", &tileCount); - case DTYPE_CRYPT: - return LoadFileInMem("NLevels\\L5Data\\L5.SOL", &tileCount); - default: - app_fatal("FillSolidBlockTbls"); - } -} - bool WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height) { bool yFlag = true; @@ -443,19 +414,43 @@ void CreateDungeon(uint32_t rseed, lvl_entry entry) Make_SetPC(SetPiece); } -void FillSolidBlockTbls() +bool TileHasAny(int tileId, TileProperties property) +{ + if (tileId == 0) + return false; // Change town to place 219 (218) instead of 0 and make dPiece zero indexed + + return HasAnyOf(SOLData[tileId - 1], property); +} + +void LoadLevelSOLData() { - size_t tileCount; - auto pSBFile = LoadLevelSOLData(tileCount); - - for (unsigned i = 0; i < tileCount; i++) { - uint8_t bv = pSBFile[i]; - nSolidTable[i + 1] = (bv & 0x01) != 0; - nBlockTable[i + 1] = (bv & 0x02) != 0; - nMissileTable[i + 1] = (bv & 0x04) != 0; - nTransTable[i + 1] = (bv & 0x08) != 0; - nTrapTable[i + 1] = (bv & 0x80) != 0; - block_lvid[i + 1] = (bv & 0x30) >> 4; + switch (leveltype) { + case DTYPE_TOWN: + if (gbIsHellfire) + LoadFileInMem("NLevels\\TownData\\Town.SOL", SOLData); + else + LoadFileInMem("Levels\\TownData\\Town.SOL", SOLData); + break; + case DTYPE_CATHEDRAL: + LoadFileInMem("Levels\\L1Data\\L1.SOL", SOLData); + break; + case DTYPE_CATACOMBS: + LoadFileInMem("Levels\\L2Data\\L2.SOL", SOLData); + break; + case DTYPE_CAVES: + LoadFileInMem("Levels\\L3Data\\L3.SOL", SOLData); + break; + case DTYPE_HELL: + LoadFileInMem("Levels\\L4Data\\L4.SOL", SOLData); + break; + case DTYPE_NEST: + LoadFileInMem("NLevels\\L6Data\\L6.SOL", SOLData); + break; + case DTYPE_CRYPT: + LoadFileInMem("NLevels\\L5Data\\L5.SOL", SOLData); + break; + default: + app_fatal("LoadLevelSOLData"); } } diff --git a/Source/gendung.h b/Source/gendung.h index a756cc28f..c750d4bd7 100644 --- a/Source/gendung.h +++ b/Source/gendung.h @@ -26,7 +26,7 @@ namespace devilution { #define MAXDUNY (16 + DMAXY * 2 + 16) #define MAXTHEMES 50 -#define MAXTILES 2048 +#define MAXTILES 1376 enum _setlevels : int8_t { SL_NONE, @@ -79,6 +79,20 @@ enum class DungeonFlag : uint8_t { }; use_enum_as_flags(DungeonFlag); +enum class TileProperties : uint8_t { + // clang-format off + None = 0, + Solid = 1 << 0, + BlockLight = 1 << 1, + BlockMissile = 1 << 2, + Transparent = 1 << 3, + TransparentLeft = 1 << 4, + TransparentRight = 1 << 5, + Trap = 1 << 7, + // clang-format on +}; +use_enum_as_flags(TileProperties); + enum _difficulty : uint8_t { DIFF_NORMAL, DIFF_NIGHTMARE, @@ -139,26 +153,9 @@ extern DVL_API_FOR_TEST std::unique_ptr pMegaTiles; extern std::unique_ptr pLevelPieces; extern std::unique_ptr pDungeonCels; /** - * List of transparency masks to use for dPieces - */ -extern std::array block_lvid; -/** - * List of light blocking dPieces - */ -extern std::array nBlockTable; -/** - * List of path blocking dPieces - */ -extern DVL_API_FOR_TEST std::array nSolidTable; -/** - * List of transparent dPieces - */ -extern std::array nTransTable; -/** - * List of missile blocking dPieces + * List tile properties */ -extern std::array nMissileTable; -extern std::array nTrapTable; +extern std::array SOLData; /** Specifies the minimum X,Y-coordinates of the map. */ extern Point dminPosition; /** Specifies the maximum X,Y-coordinates of the map. */ @@ -316,7 +313,8 @@ struct Miniset { } }; -void FillSolidBlockTbls(); +bool TileHasAny(int tileId, TileProperties property); +void LoadLevelSOLData(); void SetDungeonMicros(); void DRLG_InitTrans(); void DRLG_MRectTrans(Point origin, Point extent); diff --git a/Source/lighting.cpp b/Source/lighting.cpp index 8a655e2c6..17279116b 100644 --- a/Source/lighting.cpp +++ b/Source/lighting.cpp @@ -670,11 +670,11 @@ void DoVision(Point position, int nRadius, MapExplorationType doautomap, bool vi break; } if (InDungeonBounds({ nCrawlX, nCrawlY })) { - nBlockerFlag = nBlockTable[dPiece[nCrawlX][nCrawlY]]; + nBlockerFlag = TileHasAny(dPiece[nCrawlX][nCrawlY], TileProperties::BlockLight); if ((InDungeonBounds({ x1adj + nCrawlX, y1adj + nCrawlY }) - && !nBlockTable[dPiece[x1adj + nCrawlX][y1adj + nCrawlY]]) + && !TileHasAny(dPiece[x1adj + nCrawlX][y1adj + nCrawlY], TileProperties::BlockLight)) || (InDungeonBounds({ x2adj + nCrawlX, y2adj + nCrawlY }) - && !nBlockTable[dPiece[x2adj + nCrawlX][y2adj + nCrawlY]])) { + && !TileHasAny(dPiece[x2adj + nCrawlX][y2adj + nCrawlY], TileProperties::BlockLight))) { if (doautomap != MAP_EXP_NONE) { if (dFlags[nCrawlX][nCrawlY] != DungeonFlag::None) { SetAutomapView({ nCrawlX, nCrawlY }, doautomap); diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 45b46f0da..1e4ff1adc 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -69,7 +69,7 @@ bool CheckBlock(Point from, Point to) { while (from != to) { from += GetDirection(from, to); - if (nSolidTable[dPiece[from.x][from.y]]) + if (TileHasAny(dPiece[from.x][from.y], TileProperties::Solid)) return true; } @@ -573,7 +573,7 @@ void AddRune(Missile &missile, Point dst, missile_id missileID) if (TileContainsMissile(target)) { return false; } - if (nSolidTable[dPiece[target.x][target.y]]) { + if (TileHasAny(dPiece[target.x][target.y], TileProperties::Solid)) { return false; } return true; @@ -628,7 +628,7 @@ bool GrowWall(int playerId, Point position, Point target, missile_id type, int s int dp = dPiece[position.x][position.y]; assert(dp <= MAXTILES && dp >= 0); - if (nMissileTable[dp] || !InDungeonBounds(target)) { + if (TileHasAny(dp, TileProperties::BlockMissile) || !InDungeonBounds(target)) { return false; } @@ -648,12 +648,12 @@ void SpawnLightning(Missile &missile, int dam) assert(pn >= 0 && pn <= MAXTILES); if (!missile.IsTrap() || position != missile.position.start) { - if (nMissileTable[pn]) { + if (TileHasAny(pn, TileProperties::BlockMissile)) { missile._mirange = 0; } } - if (!nMissileTable[pn]) { + if (!TileHasAny(pn, TileProperties::BlockMissile)) { if (position != Point { missile.var1, missile.var2 } && InDungeonBounds(position)) { missile_id type = MIS_LIGHTNING; if (!missile.IsTrap() && missile._micaster == TARGET_PLAYERS @@ -687,7 +687,7 @@ bool IsMissileBlockedByTile(Point tile) return true; } - if (nMissileTable[dPiece[tile.x][tile.y]]) { + if (TileHasAny(dPiece[tile.x][tile.y], TileProperties::BlockMissile)) { return true; } @@ -1871,7 +1871,7 @@ void AddTown(Missile &missile, const AddMissileParameter ¶meter) } int dp = dPiece[target.x][target.y]; - if (nSolidTable[dp] || nMissileTable[dp]) { + if (TileHasAny(dp, TileProperties::Solid | TileProperties::BlockMissile)) { return false; } return !CheckIfTrig(target); @@ -1988,7 +1988,7 @@ void AddGuardian(Missile &missile, const AddMissileParameter ¶meter) } int dp = dPiece[target.x][target.y]; - if (nSolidTable[dp] || nMissileTable[dp]) { + if (TileHasAny(dp, TileProperties::Solid | TileProperties::BlockMissile)) { return false; } @@ -2909,18 +2909,18 @@ void MI_Fireball(Missile &missile) } if (!TransList[dTransVal[missilePosition.x][missilePosition.y]] - || (missile.position.velocity.deltaX < 0 && ((TransList[dTransVal[missilePosition.x][missilePosition.y + 1]] && nSolidTable[dPiece[missilePosition.x][missilePosition.y + 1]]) || (TransList[dTransVal[missilePosition.x][missilePosition.y - 1]] && nSolidTable[dPiece[missilePosition.x][missilePosition.y - 1]])))) { + || (missile.position.velocity.deltaX < 0 && ((TransList[dTransVal[missilePosition.x][missilePosition.y + 1]] && TileHasAny(dPiece[missilePosition.x][missilePosition.y + 1], TileProperties::Solid)) || (TransList[dTransVal[missilePosition.x][missilePosition.y - 1]] && TileHasAny(dPiece[missilePosition.x][missilePosition.y - 1], TileProperties::Solid))))) { missile.position.tile += Displacement { 1, 1 }; missile.position.offset.deltaY -= 32; } if (missile.position.velocity.deltaY > 0 - && ((TransList[dTransVal[missilePosition.x + 1][missilePosition.y]] && nSolidTable[dPiece[missilePosition.x + 1][missilePosition.y]]) - || (TransList[dTransVal[missilePosition.x - 1][missilePosition.y]] && nSolidTable[dPiece[missilePosition.x - 1][missilePosition.y]]))) { + && ((TransList[dTransVal[missilePosition.x + 1][missilePosition.y]] && TileHasAny(dPiece[missilePosition.x + 1][missilePosition.y], TileProperties::Solid)) + || (TransList[dTransVal[missilePosition.x - 1][missilePosition.y]] && TileHasAny(dPiece[missilePosition.x - 1][missilePosition.y], TileProperties::Solid)))) { missile.position.offset.deltaY -= 32; } if (missile.position.velocity.deltaX > 0 - && ((TransList[dTransVal[missilePosition.x][missilePosition.y + 1]] && nSolidTable[dPiece[missilePosition.x][missilePosition.y + 1]]) - || (TransList[dTransVal[missilePosition.x][missilePosition.y - 1]] && nSolidTable[dPiece[missilePosition.x][missilePosition.y - 1]]))) { + && ((TransList[dTransVal[missilePosition.x][missilePosition.y + 1]] && TileHasAny(dPiece[missilePosition.x][missilePosition.y + 1], TileProperties::Solid)) + || (TransList[dTransVal[missilePosition.x][missilePosition.y - 1]] && TileHasAny(dPiece[missilePosition.x][missilePosition.y - 1], TileProperties::Solid)))) { missile.position.offset.deltaX -= 32; } missile._mimfnum = 0; @@ -3024,13 +3024,13 @@ void MI_FireRing(Missile &missile) if (!InDungeonBounds(target)) continue; int dp = dPiece[target.x][target.y]; - if (nSolidTable[dp]) + if (TileHasAny(dp, TileProperties::Solid)) continue; if (IsObjectAtPosition(target)) continue; if (!LineClearMissile(missile.position.tile, target)) continue; - if (nMissileTable[dp] || missile.limitReached) { + if (TileHasAny(dp, TileProperties::BlockMissile) || missile.limitReached) { missile.limitReached = true; continue; } @@ -3611,7 +3611,7 @@ void MI_Apoca(Missile &missile) continue; if (Monsters[mid].MType->mtype == MT_GOLEM) continue; - if (nSolidTable[dPiece[k][j]]) + if (TileHasAny(dPiece[k][j], TileProperties::Solid)) continue; if (gbIsHellfire && !LineClearMissile(missile.position.tile, { k, j })) continue; @@ -3640,7 +3640,7 @@ void MI_Wave(Missile &missile) Point na = src + sd; int pn = dPiece[na.x][na.y]; assert(pn >= 0 && pn <= MAXTILES); - if (!nMissileTable[pn]) { + if (!TileHasAny(pn, TileProperties::BlockMissile)) { Direction pdir = Players[id]._pdir; AddMissile(na, na + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile._mispllvl); na += dira; @@ -3648,7 +3648,7 @@ void MI_Wave(Missile &missile) for (int j = 0; j < (missile._mispllvl / 2) + 2; j++) { pn = dPiece[na.x][na.y]; // BUGFIX: dPiece is accessed before check against dungeon size and 0 assert(pn >= 0 && pn <= MAXTILES); - if (nMissileTable[pn] || f1 || !InDungeonBounds(na)) { + if (TileHasAny(pn, TileProperties::BlockMissile) || f1 || !InDungeonBounds(na)) { f1 = true; } else { AddMissile(na, na + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile._mispllvl); @@ -3656,7 +3656,7 @@ void MI_Wave(Missile &missile) } pn = dPiece[nb.x][nb.y]; // BUGFIX: dPiece is accessed before check against dungeon size and 0 assert(pn >= 0 && pn <= MAXTILES); - if (nMissileTable[pn] || f2 || !InDungeonBounds(nb)) { + if (TileHasAny(pn, TileProperties::BlockMissile) || f2 || !InDungeonBounds(nb)) { f2 = true; } else { AddMissile(nb, nb + sd, pdir, MIS_FIREMOVE, TARGET_MONSTERS, id, 0, missile._mispllvl); @@ -3760,7 +3760,7 @@ void MI_Flamec(Missile &missile) UpdateMissilePos(missile); if (missile.position.tile != Point { missile.var1, missile.var2 }) { int id = dPiece[missile.position.tile.x][missile.position.tile.y]; - if (!nMissileTable[id]) { + if (!TileHasAny(id, TileProperties::BlockMissile)) { AddMissile( missile.position.tile, missile.position.start, diff --git a/Source/monster.cpp b/Source/monster.cpp index 97fe8b19d..19758c77c 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -4405,7 +4405,7 @@ bool DirOK(int i, Direction mdir) bool PosOkMissile(Point position) { - return !nMissileTable[dPiece[position.x][position.y]]; + return !TileHasAny(dPiece[position.x][position.y], TileProperties::BlockMissile); } bool LineClearMissile(Point startPoint, Point endPoint) diff --git a/Source/objects.cpp b/Source/objects.cpp index e3173f935..faf786481 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -301,7 +301,7 @@ bool RndLocOk(int xp, int yp) return false; if (TileContainsSetPiece({ xp, yp })) return false; - if (nSolidTable[dPiece[xp][yp]]) + if (TileHasAny(dPiece[xp][yp], TileProperties::Solid)) return false; return IsNoneOf(leveltype, DTYPE_CATHEDRAL, DTYPE_CRYPT) || dPiece[xp][yp] <= 126 || dPiece[xp][yp] >= 144; } @@ -313,7 +313,7 @@ bool CanPlaceWallTrap(int xp, int yp) if (TileContainsSetPiece({ xp, yp })) return false; - return nTrapTable[dPiece[xp][yp]]; + return TileHasAny(dPiece[xp][yp], TileProperties::Trap); } void InitRndLocObj(int min, int max, _object_id objtype) diff --git a/Source/path.cpp b/Source/path.cpp index 28ae1c7be..583d60af8 100644 --- a/Source/path.cpp +++ b/Source/path.cpp @@ -291,7 +291,7 @@ bool IsTileNotSolid(Point position) return false; } - return !nSolidTable[dPiece[position.x][position.y]]; + return !TileHasAny(dPiece[position.x][position.y], TileProperties::Solid); } bool IsTileSolid(Point position) @@ -300,7 +300,7 @@ bool IsTileSolid(Point position) return false; } - return nSolidTable[dPiece[position.x][position.y]]; + return TileHasAny(dPiece[position.x][position.y], TileProperties::Solid); } bool IsTileWalkable(Point position, bool ignoreDoors) diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 060e64fcd..7dc2a2c57 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -656,8 +656,8 @@ void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition { MICROS *pMap = &dpiece_defs_map_2[tilePosition.x][tilePosition.y]; level_piece_id = dPiece[tilePosition.x][tilePosition.y]; - cel_transparency_active = nTransTable[level_piece_id] && TransList[dTransVal[tilePosition.x][tilePosition.y]]; - cel_foliage_active = !nSolidTable[level_piece_id]; + cel_transparency_active = TileHasAny(level_piece_id, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]]; + cel_foliage_active = !TileHasAny(level_piece_id, TileProperties::Solid); for (int i = 0; i < (MicroTileLen / 2); i++) { level_cel_block = pMap->mt[2 * i]; if (level_cel_block != 0) { @@ -930,7 +930,7 @@ void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPositio if (InDungeonBounds(tilePosition)) { level_piece_id = dPiece[tilePosition.x][tilePosition.y]; if (level_piece_id != 0) { - if (!nSolidTable[level_piece_id]) + if (!TileHasAny(level_piece_id, TileProperties::Solid)) DrawFloor(out, tilePosition, targetBufferPosition); } else { world_draw_black_tile(out, targetBufferPosition.x, targetBufferPosition.y); @@ -959,7 +959,7 @@ void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPositio } } -#define IsWall(x, y) (dPiece[x][y] == 0 || nSolidTable[dPiece[x][y]] || dSpecial[x][y] != 0) +#define IsWall(x, y) (dPiece[x][y] == 0 || TileHasAny(dPiece[x][y], TileProperties::Solid) || dSpecial[x][y] != 0) #define IsWalkable(x, y) (dPiece[x][y] != 0 && IsTileNotSolid({ x, y })) /** diff --git a/Source/themes.cpp b/Source/themes.cpp index 8d4a6523b..b88e3de6b 100644 --- a/Source/themes.cpp +++ b/Source/themes.cpp @@ -58,7 +58,7 @@ bool TFit_Shrine(int i) while (found == 0) { Point testPosition { xp, yp }; if (dTransVal[xp][yp] == themes[i].ttval) { - if (nTrapTable[dPiece[xp][yp - 1]] + if (TileHasAny(dPiece[xp][yp - 1], TileProperties::Trap) && IsTileNotSolid(testPosition + Direction::NorthWest) && IsTileNotSolid(testPosition + Direction::SouthEast) && dTransVal[xp - 1][yp] == themes[i].ttval @@ -68,7 +68,7 @@ bool TFit_Shrine(int i) found = 1; } if (found == 0 - && nTrapTable[dPiece[xp - 1][yp]] + && TileHasAny(dPiece[xp - 1][yp], TileProperties::Trap) && IsTileNotSolid(testPosition + Direction::NorthEast) && IsTileNotSolid(testPosition + Direction::SouthWest) && dTransVal[xp][yp - 1] == themes[i].ttval @@ -106,7 +106,7 @@ bool TFit_Obj5(int t) if (dTransVal[xp][yp] == themes[t].ttval && IsTileNotSolid({ xp, yp })) { found = true; for (int i = 0; found && i < 25; i++) { - if (nSolidTable[dPiece[xp + trm5x[i]][yp + trm5y[i]]]) { + if (TileHasAny(dPiece[xp + trm5x[i]][yp + trm5y[i]], TileProperties::Solid)) { found = false; } if (dTransVal[xp + trm5x[i]][yp + trm5y[i]] != themes[t].ttval) { @@ -368,7 +368,7 @@ bool CheckThemeRoom(int tv) for (int j = 0; j < MAXDUNY; j++) { for (int i = 0; i < MAXDUNX; i++) { - if (dTransVal[i][j] != tv || nSolidTable[dPiece[i][j]]) + if (dTransVal[i][j] != tv || TileHasAny(dPiece[i][j], TileProperties::Solid)) continue; if (dTransVal[i - 1][j] != tv && IsTileNotSolid({ i - 1, j })) return false; diff --git a/test/path_test.cpp b/test/path_test.cpp index 728c30880..408f3f582 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -44,13 +44,13 @@ TEST(PathTest, Heuristics) TEST(PathTest, Solid) { - dPiece[5][5] = 0; - nSolidTable[0] = true; + dPiece[5][5] = 1; + SOLData[0] = TileProperties::Solid; EXPECT_TRUE(IsTileSolid({ 5, 5 })) << "Solid in-bounds tiles are solid"; EXPECT_FALSE(IsTileNotSolid({ 5, 5 })) << "IsTileNotSolid returns the inverse of IsTileSolid for in-bounds tiles"; - dPiece[6][6] = 1; - nSolidTable[1] = false; + dPiece[6][6] = 2; + SOLData[1] = TileProperties::None; EXPECT_FALSE(IsTileSolid({ 6, 6 })) << "Non-solid in-bounds tiles are not solid"; EXPECT_TRUE(IsTileNotSolid({ 6, 6 })) << "IsTileNotSolid returns the inverse of IsTileSolid for in-bounds tiles"; @@ -60,18 +60,18 @@ TEST(PathTest, Solid) TEST(PathTest, SolidPieces) { - dPiece[0][0] = 0; - dPiece[0][1] = 0; - dPiece[1][0] = 0; - dPiece[1][1] = 0; - nSolidTable[0] = false; + dPiece[0][0] = 1; + dPiece[0][1] = 1; + dPiece[1][0] = 1; + dPiece[1][1] = 1; + SOLData[0] = TileProperties::None; EXPECT_TRUE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "A step in open space is free of solid pieces"; EXPECT_TRUE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "A step in open space is free of solid pieces"; EXPECT_TRUE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "A step in open space is free of solid pieces"; EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "A step in open space is free of solid pieces"; - nSolidTable[1] = true; - dPiece[1][0] = 1; + SOLData[1] = TileProperties::Solid; + dPiece[1][0] = 2; EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can path to a destination which is solid"; EXPECT_TRUE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can path from a starting position which is solid"; EXPECT_TRUE(path_solid_pieces({ 0, 1 }, { 1, 1 })) << "Stepping in a cardinal direction ignores solid pieces"; @@ -81,24 +81,24 @@ TEST(PathTest, SolidPieces) EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't cut a solid corner"; EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't cut a solid corner"; - dPiece[0][1] = 1; + dPiece[0][1] = 2; EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't walk through the boundary between two corners"; EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't walk through the boundary between two corners"; - dPiece[1][0] = 0; + dPiece[1][0] = 1; EXPECT_FALSE(path_solid_pieces({ 0, 0 }, { 1, 1 })) << "Can't cut a solid corner"; EXPECT_FALSE(path_solid_pieces({ 1, 1 }, { 0, 0 })) << "Can't cut a solid corner"; - dPiece[0][1] = 0; + dPiece[0][1] = 1; - dPiece[0][0] = 1; + dPiece[0][0] = 2; EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't cut a solid corner"; EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't cut a solid corner"; - dPiece[1][1] = 1; + dPiece[1][1] = 2; EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't walk through the boundary between two corners"; EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't walk through the boundary between two corners"; - dPiece[0][0] = 0; + dPiece[0][0] = 1; EXPECT_FALSE(path_solid_pieces({ 1, 0 }, { 0, 1 })) << "Can't cut a solid corner"; EXPECT_FALSE(path_solid_pieces({ 0, 1 }, { 1, 0 })) << "Can't cut a solid corner"; - dPiece[1][1] = 0; + dPiece[1][1] = 1; } void CheckPath(Point startPosition, Point destinationPosition, std::vector expectedSteps) @@ -139,12 +139,12 @@ TEST(PathTest, FindPath) TEST(PathTest, Walkable) { - dPiece[5][5] = 0; - nSolidTable[0] = true; // Doing this manually to save running through the code in gendung.cpp + dPiece[5][5] = 1; + SOLData[0] = TileProperties::Solid; // Doing this manually to save running through the code in gendung.cpp EXPECT_FALSE(IsTileWalkable({ 5, 5 })) << "Tile which is marked as solid should be considered blocked"; EXPECT_FALSE(IsTileWalkable({ 5, 5 }, true)) << "Solid non-door tiles remain unwalkable when ignoring doors"; - nSolidTable[0] = false; + SOLData[0] = TileProperties::None; EXPECT_TRUE(IsTileWalkable({ 5, 5 })) << "Non-solid tiles are walkable"; EXPECT_TRUE(IsTileWalkable({ 5, 5 }, true)) << "Non-solid tiles remain walkable when ignoring doors"; @@ -161,7 +161,7 @@ TEST(PathTest, Walkable) EXPECT_TRUE(IsTileWalkable({ 5, 5 })) << "Tile occupied by an open door is walkable"; EXPECT_TRUE(IsTileWalkable({ 5, 5 }, true)) << "Tile occupied by a door is considered walkable when ignoring doors"; - nSolidTable[0] = true; + SOLData[0] = TileProperties::Solid; EXPECT_FALSE(IsTileWalkable({ 5, 5 })) << "Solid tiles occupied by an open door remain unwalkable"; EXPECT_TRUE(IsTileWalkable({ 5, 5 }, true)) << "Solid tiles occupied by an open door become walkable when ignoring doors"; }