From 12035143836cb4e58adf9d3d8a53d592a747e121 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Mon, 6 Jun 2022 22:24:57 +0200 Subject: [PATCH] Clean up use of currlevel --- Source/automap.cpp | 13 +- Source/control.cpp | 2 +- Source/controls/modifier_hints.cpp | 2 +- Source/controls/plrctrls.cpp | 2 +- Source/debug.cpp | 4 +- Source/diablo.cpp | 17 +- Source/drlg_l1.cpp | 254 ++++++-------- Source/drlg_l2.cpp | 58 ++-- Source/drlg_l3.cpp | 539 ++++++++++++++--------------- Source/drlg_l4.cpp | 118 +++---- Source/gmenu.cpp | 2 +- Source/inv.cpp | 6 +- Source/items.cpp | 12 +- Source/lighting.cpp | 6 +- Source/loadsave.cpp | 6 +- Source/missiles.cpp | 10 +- Source/monster.cpp | 2 +- Source/msg.cpp | 28 +- Source/objects.cpp | 9 +- Source/panels/spell_book.cpp | 2 +- Source/panels/spell_list.cpp | 4 +- Source/player.cpp | 18 +- Source/portal.cpp | 10 +- Source/qol/monhealthbar.cpp | 2 +- Source/qol/stash.cpp | 2 +- Source/scrollrt.cpp | 2 +- Source/trigs.cpp | 420 +++++++++++----------- Source/trigs.h | 2 + test/drlg_l1_test.cpp | 6 +- test/drlg_l2_test.cpp | 4 +- test/drlg_l3_test.cpp | 4 +- test/drlg_l4_test.cpp | 4 +- 32 files changed, 755 insertions(+), 815 deletions(-) diff --git a/Source/automap.cpp b/Source/automap.cpp index 975ea3911..c8603367a 100644 --- a/Source/automap.cpp +++ b/Source/automap.cpp @@ -10,6 +10,7 @@ #include "control.h" #include "engine/load_file.hpp" #include "engine/render/automap_render.hpp" +#include "gendung.h" #include "palette.h" #include "player.h" #include "setmaps.h" @@ -501,14 +502,18 @@ void DrawAutomapText(const Surface &out) return; } - if (currlevel != 0) { + if (leveltype != DTYPE_TOWN) { std::string description; - if (currlevel >= 17 && currlevel <= 20) { + switch (leveltype) { + case DTYPE_NEST: description = fmt::format(_("Level: Nest {:d}"), currlevel - 16); - } else if (currlevel >= 21 && currlevel <= 24) { + break; + case DTYPE_CRYPT: description = fmt::format(_("Level: Crypt {:d}"), currlevel - 20); - } else { + break; + default: description = fmt::format(_("Level: {:d}"), currlevel); + break; } DrawString(out, description, linePosition); diff --git a/Source/control.cpp b/Source/control.cpp index c107045a2..2a9a2d5a3 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -687,7 +687,7 @@ void control_check_btn_press() void DoAutoMap() { - if (currlevel != 0 || gbIsMultiplayer) { + if (leveltype != DTYPE_TOWN || gbIsMultiplayer) { if (!AutomapActive) StartAutomap(); else diff --git a/Source/controls/modifier_hints.cpp b/Source/controls/modifier_hints.cpp index 74d9d0543..4ec4142cd 100644 --- a/Source/controls/modifier_hints.cpp +++ b/Source/controls/modifier_hints.cpp @@ -132,7 +132,7 @@ void DrawSpellsCircleMenuHint(const Surface &out, const Point &origin) splId = myPlayer._pSplHotKey[slot]; if (splId != SPL_INVALID && splId != SPL_NULL && (spells & GetSpellBitmask(splId)) != 0) - splType = (currlevel == 0 && !spelldata[splId].sTownSpell) ? RSPLTYPE_INVALID : myPlayer._pSplTHotKey[slot]; + splType = (leveltype == DTYPE_TOWN && !spelldata[splId].sTownSpell) ? RSPLTYPE_INVALID : myPlayer._pSplTHotKey[slot]; else { splType = RSPLTYPE_INVALID; splId = SPL_NULL; diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index f48da69b9..7e4ecdb42 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -1816,7 +1816,7 @@ bool TryDropItem() return false; } - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { if (UseItemOpensHive(myPlayer.HoldItem, myPlayer.position.tile)) { NetSendCmdPItem(true, CMD_PUTITEM, { 79, 61 }, myPlayer.HoldItem.pop()); NewCursor(CURSOR_HAND); diff --git a/Source/debug.cpp b/Source/debug.cpp index 6c3d394ab..793f4b88e 100644 --- a/Source/debug.cpp +++ b/Source/debug.cpp @@ -663,7 +663,7 @@ std::string DebugCmdLevelSeed(const string_view parameter) std::string DebugCmdSpawnUniqueMonster(const string_view parameter) { - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) return "Do you want to kill the towners?!?"; std::stringstream paramsStream(parameter.data()); @@ -750,7 +750,7 @@ std::string DebugCmdSpawnUniqueMonster(const string_view parameter) std::string DebugCmdSpawnMonster(const string_view parameter) { - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) return "Do you want to kill the towners?!?"; std::stringstream paramsStream(parameter.data()); diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 8d4831f83..64dbadedc 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1183,27 +1183,30 @@ void CreateLevel(lvl_entry entry) InitTownTriggers(); break; case DTYPE_CATHEDRAL: - case DTYPE_CRYPT: InitL1Triggers(); - Freeupstairs(); break; case DTYPE_CATACOMBS: InitL2Triggers(); - Freeupstairs(); break; case DTYPE_CAVES: - case DTYPE_NEST: InitL3Triggers(); - Freeupstairs(); break; case DTYPE_HELL: InitL4Triggers(); - Freeupstairs(); + break; + case DTYPE_NEST: + InitHiveTriggers(); + break; + case DTYPE_CRYPT: + InitCryptTriggers(); break; default: app_fatal("CreateLevel"); } + if (leveltype != DTYPE_TOWN) { + Freeupstairs(); + } LoadRndLvlPal(leveltype); } @@ -2313,7 +2316,7 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) ProcessVisionList(); } - if (currlevel >= 21) { + if (leveltype == DTYPE_CRYPT) { if (currlevel == 21) { CornerstoneLoad(CornerStone.position); } diff --git a/Source/drlg_l1.cpp b/Source/drlg_l1.cpp index 44c679d86..b1484447b 100644 --- a/Source/drlg_l1.cpp +++ b/Source/drlg_l1.cpp @@ -759,7 +759,7 @@ void ApplyShadowsPatterns() } } -int PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview, int noquad) +bool PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview, int noquad) { int sx; int sy; @@ -830,7 +830,7 @@ int PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool s } } if (++found > 4000) - return -1; + return false; } } @@ -859,14 +859,7 @@ int PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool s ViewPosition = Point { 19, 20 } + Displacement { sx, sy } * 2; } - if (sx < cx && sy < cy) - return 0; - if (sx > cx && sy < cy) - return 1; - if (sx < cx && sy > cy) - return 2; - - return 3; + return true; } void PlaceMiniSetRandom(const BYTE *miniset, int rndper) @@ -1988,32 +1981,32 @@ void FixTransparency() void FixDirtTiles() { - if (currlevel < 21) { - for (int j = 0; j < DMAXY - 1; j++) { - for (int i = 0; i < DMAXX - 1; i++) { - if (dungeon[i][j] == 21 && dungeon[i + 1][j] != 19) { - dungeon[i][j] = 202; - } - if (dungeon[i][j] == 19 && dungeon[i + 1][j] != 19) { - dungeon[i][j] = 200; - } - if (dungeon[i][j] == 24 && dungeon[i + 1][j] != 19) { - dungeon[i][j] = 205; - } - if (dungeon[i][j] == 18 && dungeon[i][j + 1] != 18) { - dungeon[i][j] = 199; - } - if (dungeon[i][j] == 21 && dungeon[i][j + 1] != 18) { - dungeon[i][j] = 202; - } - if (dungeon[i][j] == 23 && dungeon[i][j + 1] != 18) { - dungeon[i][j] = 204; - } + for (int j = 0; j < DMAXY - 1; j++) { + for (int i = 0; i < DMAXX - 1; i++) { + if (dungeon[i][j] == 21 && dungeon[i + 1][j] != 19) { + dungeon[i][j] = 202; + } + if (dungeon[i][j] == 19 && dungeon[i + 1][j] != 19) { + dungeon[i][j] = 200; + } + if (dungeon[i][j] == 24 && dungeon[i + 1][j] != 19) { + dungeon[i][j] = 205; + } + if (dungeon[i][j] == 18 && dungeon[i][j + 1] != 18) { + dungeon[i][j] = 199; + } + if (dungeon[i][j] == 21 && dungeon[i][j + 1] != 18) { + dungeon[i][j] = 202; + } + if (dungeon[i][j] == 23 && dungeon[i][j + 1] != 18) { + dungeon[i][j] = 204; } } - return; } +} +void FixCryptDirtTiles() +{ for (int j = 0; j < DMAXY - 1; j++) { for (int i = 0; i < DMAXX - 1; i++) { if (dungeon[i][j] == 19) @@ -2168,6 +2161,69 @@ void CryptPatternGroup7(int rndper) PlaceMiniSetRandom(CryptPattern8, rndper); } +bool PlaceCathedralStairs(lvl_entry entry) +{ + bool success = true; + + // Place poison water entrance + if (Quests[Q_PWATER].IsAvailable()) { + if (!PlaceMiniSet(PWATERIN, 1, 1, 0, 0, entry == ENTRY_RTNLVL, -1)) + success = false; + if (entry == ENTRY_RTNLVL) + ViewPosition += Displacement { 2, 3 }; + } + + // Place stairs up + if (!PlaceMiniSet(MyPlayer->pOriginalCathedral ? L5STAIRSUP : STAIRSUP, 1, 1, 0, 0, entry == ENTRY_MAIN, -1)) { + if (MyPlayer->pOriginalCathedral) + return false; + success = false; + } + + // Place stairs down + if (!Quests[Q_LTBANNER].IsAvailable() && !PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, entry == ENTRY_PREV, -1)) + success = false; + if (entry == ENTRY_PREV) { + if (Quests[Q_LTBANNER].IsAvailable()) + ViewPosition = Point { 20, 28 } + Displacement { setpc_x, setpc_y } * 2; + else + ViewPosition.y--; + } + + return success; +} + +bool PlaceCryptStairs(lvl_entry entry) +{ + bool success = true; + + // Place stairs up + bool enteringFromAbove = entry == ENTRY_MAIN || entry == ENTRY_TWARPDN; + if (!PlaceMiniSet(currlevel != 21 ? L5STAIRSUPHF : L5STAIRSTOWN, 1, 1, 0, 0, enteringFromAbove, -1)) + success = false; + if (enteringFromAbove) + ViewPosition.y++; + + // Place stairs down + if (currlevel != 24) { + if (!PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, entry == ENTRY_PREV, -1)) + success = false; + if (entry == ENTRY_PREV) + ViewPosition.y += 3; + } + + return success; +} + +bool PlaceStairs(lvl_entry entry) +{ + if (leveltype == DTYPE_CRYPT) { + return PlaceCryptStairs(entry); + } + + return PlaceCathedralStairs(entry); +} + void GenerateLevel(lvl_entry entry) { int minarea = 761; @@ -2182,8 +2238,7 @@ void GenerateLevel(lvl_entry entry) break; } - bool doneflag; - do { + while (true) { DRLG_InitTrans(); do { @@ -2198,111 +2253,9 @@ void GenerateLevel(lvl_entry entry) AddWall(); ClearFlags(); FloodTransparencyValues(13); - - doneflag = true; - - if (Quests[Q_PWATER].IsAvailable()) { - if (entry == ENTRY_MAIN) { - if (PlaceMiniSet(PWATERIN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - } else { - if (PlaceMiniSet(PWATERIN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - ViewPosition.y--; - } - } - if (Quests[Q_LTBANNER].IsAvailable()) { - if (entry == ENTRY_MAIN) { - if (PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - } else { - if (PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - if (entry == ENTRY_PREV) { - ViewPosition = Point { 20, 28 } + Displacement { setpc_x, setpc_y } * 2; - } else { - ViewPosition.y--; - } - } - } else if (entry == ENTRY_MAIN) { - if (currlevel < 21) { - if (!MyPlayer->pOriginalCathedral) { - if (PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - if (PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } else { - if (PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - else if (PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } - } else if (currlevel == 21) { - if (PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - ViewPosition.y++; - } else { - if (PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - if (currlevel != 24) { - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } - ViewPosition.y++; - } - } else if (!MyPlayer->pOriginalCathedral && entry == ENTRY_PREV) { - if (currlevel < 21) { - if (PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - if (PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - ViewPosition.y--; - } else if (currlevel == 21) { - if (PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - ViewPosition.y += 3; - } else { - if (PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - if (currlevel != 24) { - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - } - ViewPosition.y += 3; - } - } else { - if (currlevel < 21) { - if (!MyPlayer->pOriginalCathedral) { - if (PlaceMiniSet(STAIRSUP, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - if (PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } else { - if (PlaceMiniSet(L5STAIRSUP, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - else if (PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - ViewPosition.y--; - } - } else if (currlevel == 21) { - if (PlaceMiniSet(L5STAIRSTOWN, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } else { - if (PlaceMiniSet(L5STAIRSUPHF, 1, 1, 0, 0, true, -1) < 0) - doneflag = false; - if (currlevel != 24) { - if (PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, false, -1) < 0) - doneflag = false; - } - } - } - } while (!doneflag); + if (PlaceStairs(entry)) + break; + } for (int j = 0; j < DMAXY; j++) { for (int i = 0; i < DMAXX; i++) { @@ -2316,7 +2269,11 @@ void GenerateLevel(lvl_entry entry) } FixTransparency(); - FixDirtTiles(); + if (leveltype == DTYPE_CRYPT) { + FixCryptDirtTiles(); + } else { + FixDirtTiles(); + } FixCornerTiles(); for (int j = 0; j < DMAXY; j++) { @@ -2326,9 +2283,7 @@ void GenerateLevel(lvl_entry entry) } } - if (currlevel < 21) { - Substitution(); - } else { + if (leveltype == DTYPE_CRYPT) { CryptPatternGroup1(10); PlaceMiniSetRandom(CryptPattern1, 95); PlaceMiniSetRandom(CryptPattern2, 95); @@ -2374,9 +2329,8 @@ void GenerateLevel(lvl_entry entry) CryptLavafloor(); break; } - } - - if (currlevel < 21) { + } else { + Substitution(); ApplyShadowsPatterns(); PlaceMiniSet(LAMPS, 5, 10, 0, 0, false, -1); FillFloor(); @@ -2440,7 +2394,7 @@ void LoadL1Dungeon(const char *path, int vx, int vy) Pass3(); DRLG_Init_Globals(); - if (currlevel < 17) + if (leveltype != DTYPE_CRYPT) InitDungeonPieces(); SetMapMonsters(dunData.get(), { 0, 0 }); @@ -2508,10 +2462,10 @@ void CreateL5Dungeon(uint32_t rseed, lvl_entry entry) Pass3(); FreeQuestSetPieces(); - if (currlevel < 17) { - InitDungeonPieces(); - } else { + if (leveltype == DTYPE_CRYPT) { InitCryptPieces(); + } else { + InitDungeonPieces(); } DRLG_SetPC(); diff --git a/Source/drlg_l2.cpp b/Source/drlg_l2.cpp index 3c828ac6d..e0ff8b415 100644 --- a/Source/drlg_l2.cpp +++ b/Source/drlg_l2.cpp @@ -2864,10 +2864,34 @@ void FixDoors() } } +bool PlaceStairs(lvl_entry entry) +{ + // Place stairs up + if (!PlaceMiniSet(USTAIRS, 1, 1, -1, -1, entry == ENTRY_MAIN)) + return false; + if (entry == ENTRY_MAIN) + ViewPosition.y -= 2; + + // Place stairs down + if (!PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, entry == ENTRY_PREV)) + return false; + if (entry == ENTRY_PREV) + ViewPosition.x--; + + // Place town warp stairs + if (currlevel == 5) { + if (!PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, entry == ENTRY_TWARPDN)) + return false; + if (entry == ENTRY_TWARPDN) + ViewPosition.y -= 2; + } + + return true; +} + void GenerateLevel(lvl_entry entry) { - bool doneflag = false; - while (!doneflag) { + while (true) { nRoomCnt = 0; InitDungeonFlags(); DRLG_InitTrans(); @@ -2880,34 +2904,8 @@ void GenerateLevel(lvl_entry entry) } FloodTransparencyValues(3); FixTransparency(); - if (entry == ENTRY_MAIN) { - doneflag = PlaceMiniSet(USTAIRS, 1, 1, -1, -1, true); - if (doneflag) { - doneflag = PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel == 5) { - doneflag = PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, false); - } - } - ViewPosition.y -= 2; - } else if (entry == ENTRY_PREV) { - doneflag = PlaceMiniSet(USTAIRS, 1, 1, -1, -1, false); - if (doneflag) { - doneflag = PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, true); - if (doneflag && currlevel == 5) { - doneflag = PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, false); - } - } - ViewPosition.x--; - } else { - doneflag = PlaceMiniSet(USTAIRS, 1, 1, -1, -1, false); - if (doneflag) { - doneflag = PlaceMiniSet(DSTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel == 5) { - doneflag = PlaceMiniSet(WARPSTAIRS, 1, 1, -1, -1, true); - } - } - ViewPosition.y -= 2; - } + if (PlaceStairs(entry)) + break; } FixLockout(); diff --git a/Source/drlg_l3.cpp b/Source/drlg_l3.cpp index cd072a107..a263dfeab 100644 --- a/Source/drlg_l3.cpp +++ b/Source/drlg_l3.cpp @@ -20,8 +20,6 @@ namespace devilution { namespace { -/** This will be true if a lava pool has been generated for the level */ -uint8_t lavapool; int lockoutcnt; bool lockout[DMAXX][DMAXY]; @@ -1518,15 +1516,90 @@ bool Spawn(int x, int y, int *totarea) return false; } +bool HivePlaceSetRandom(const BYTE *miniset, int rndper) +{ + bool placed = false; + int sw = miniset[0]; + int sh = miniset[1]; + + for (int sy = 0; sy < DMAXX - sh; sy++) { + for (int sx = 0; sx < DMAXY - sw; sx++) { + bool found = true; + int ii = 2; + for (int yy = 0; yy < sh && found; yy++) { + for (int xx = 0; xx < sw && found; xx++) { + if (miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { + found = false; + } + if (dflags[xx + sx][yy + sy] != 0) { + found = false; + } + ii++; + } + } + int kk = sw * sh + 2; + if (found) { + if (miniset[kk] >= 84 && miniset[kk] <= 100) { + // BUGFIX: accesses to dungeon can go out of bounds + // BUGFIX: Comparisons vs 100 should use same tile as comparisons vs 84. + if (dungeon[sx - 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = false; + } + if (dungeon[sx + 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = false; + } + if (dungeon[sx][sy + 1] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = false; + } + if (dungeon[sx][sy - 1] >= 84 && dungeon[sx - 1][sy] <= 100) { + found = false; + } + } + } + if (found && GenerateRnd(100) < rndper) { + placed = true; + for (int yy = 0; yy < sh; yy++) { + for (int xx = 0; xx < sw; xx++) { + if (miniset[kk] != 0) { + dungeon[xx + sx][yy + sy] = miniset[kk]; + } + kk++; + } + } + } + } + } + + return placed; +} + +bool PlaceSlimePool() +{ + int lavapool = 0; + + if (HivePlaceSetRandom(HivePattern41, 30)) + lavapool++; + if (HivePlaceSetRandom(HivePattern42, 40)) + lavapool++; + if (HivePlaceSetRandom(HivePattern39, 50)) + lavapool++; + if (HivePlaceSetRandom(HivePattern40, 60)) + lavapool++; + + return lavapool >= 3; +} + /** * Flood fills dirt and wall tiles looking for * an area of at most 40 tiles and disconnected from the map edge. - * If it finds one, converts it to lava tiles and sets lavapool to true. + * If it finds one, converts it to lava tiles and return true. */ -void Pool() +bool PlaceLavaPool() { constexpr uint8_t Poolsub[15] = { 0, 35, 26, 36, 25, 29, 34, 7, 33, 28, 27, 37, 32, 31, 30 }; + bool lavePoolPlaced = false; + for (int duny = 0; duny < DMAXY; duny++) { for (int dunx = 0; dunx < DMAXY; dunx++) { if (dungeon[dunx][duny] != 8) { @@ -1565,13 +1638,24 @@ void Pool() if (k != 0 && k <= 37) { dungeon[i][j] = k; } - lavapool = 1; + lavePoolPlaced = true; } } } } } } + + return lavePoolPlaced; +} + +bool PlacePool() +{ + if (leveltype == DTYPE_NEST) { + return PlaceSlimePool(); + } + + return PlaceLavaPool(); } void PoolFix() @@ -1651,7 +1735,7 @@ bool PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool } } if (bailcnt >= 200) { - return true; + return false; } int ii = sw * sh + 2; @@ -1669,7 +1753,7 @@ bool PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool ViewPosition = Point { 17, 19 } + Displacement { sx, sy } * 2; } - return false; + return true; } void PlaceMiniSetRandom(const BYTE *miniset, int rndper) @@ -1725,63 +1809,6 @@ void PlaceMiniSetRandom(const BYTE *miniset, int rndper) } } -bool HivePlaceSetRandom(const BYTE *miniset, int rndper) -{ - bool placed = false; - int sw = miniset[0]; - int sh = miniset[1]; - - for (int sy = 0; sy < DMAXX - sh; sy++) { - for (int sx = 0; sx < DMAXY - sw; sx++) { - bool found = true; - int ii = 2; - for (int yy = 0; yy < sh && found; yy++) { - for (int xx = 0; xx < sw && found; xx++) { - if (miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) { - found = false; - } - if (dflags[xx + sx][yy + sy] != 0) { - found = false; - } - ii++; - } - } - int kk = sw * sh + 2; - if (found) { - if (miniset[kk] >= 84 && miniset[kk] <= 100) { - // BUGFIX: accesses to dungeon can go out of bounds - // BUGFIX: Comparisons vs 100 should use same tile as comparisons vs 84. - if (dungeon[sx - 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { - found = false; - } - if (dungeon[sx + 1][sy] >= 84 && dungeon[sx - 1][sy] <= 100) { - found = false; - } - if (dungeon[sx][sy + 1] >= 84 && dungeon[sx - 1][sy] <= 100) { - found = false; - } - if (dungeon[sx][sy - 1] >= 84 && dungeon[sx - 1][sy] <= 100) { - found = false; - } - } - } - if (found && GenerateRnd(100) < rndper) { - placed = true; - for (int yy = 0; yy < sh; yy++) { - for (int xx = 0; xx < sw; xx++) { - if (miniset[kk] != 0) { - dungeon[xx + sx][yy + sy] = miniset[kk]; - } - kk++; - } - } - } - } - } - - return placed; -} - bool FenceVerticalUp(int i, int y) { if ((dungeon[i + 1][y] > 152 || dungeon[i + 1][y] < 130) @@ -2078,7 +2105,7 @@ void Fence() FenceDoorFix(); } -bool Anvil() +bool PlaceAnvil() { int sw = L3ANVIL[0]; int sh = L3ANVIL[1]; @@ -2114,7 +2141,7 @@ bool Anvil() } } if (trys >= 200) { - return true; + return false; } int ii = sw * sh + 2; @@ -2133,7 +2160,7 @@ bool Anvil() setpc_w = sw; setpc_h = sh; - return false; + return true; } void Warp() @@ -2218,143 +2245,88 @@ bool Lockout() return t == lockoutcnt; } -void GenerateLevel(lvl_entry entry) +bool PlaceCaveStairs(lvl_entry entry) { - bool found; - bool genok; - - lavapool = 0; - - do { - do { - do { - InitDungeonFlags(); - int x1 = GenerateRnd(20) + 10; - int y1 = GenerateRnd(20) + 10; - int x2 = x1 + 2; - int y2 = y1 + 2; - FillRoom(x1, y1, x2, y2); - CreateBlock(x1, y1, 2, 0); - CreateBlock(x2, y1, 2, 1); - CreateBlock(x1, y2, 2, 2); - CreateBlock(x1, y1, 2, 3); - if (Quests[Q_ANVIL].IsAvailable()) { - x1 = GenerateRnd(10) + 10; - y1 = GenerateRnd(10) + 10; - x2 = x1 + 12; - y2 = y1 + 12; - FloorArea(x1, y1, x2, y2); - } - FillDiagonals(); - FillSingles(); - FillStraights(); - FillDiagonals(); - Edges(); - if (GetFloorArea() >= 600) { - found = Lockout(); - } else { - found = false; - } - } while (!found); - MakeMegas(); - if (entry == ENTRY_MAIN) { - if (currlevel < 17) { - genok = PlaceMiniSet(L3UP, 1, 1, -1, -1, true); - } else { - if (currlevel != 17) - genok = PlaceMiniSet(L6UP, 1, 1, -1, -1, true); - else - genok = PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, true); - } - if (!genok) { - if (currlevel < 17) { - genok = PlaceMiniSet(L3DOWN, 1, 1, -1, -1, false); - } else { - if (currlevel != 20) - genok = PlaceMiniSet(L6DOWN, 1, 1, -1, -1, false); - } - if (!genok && currlevel == 9) { - genok = PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, false); - } - } - } else if (entry == ENTRY_PREV) { - if (currlevel < 17) { - genok = PlaceMiniSet(L3UP, 1, 1, -1, -1, false); - } else { - if (currlevel != 17) - genok = PlaceMiniSet(L6UP, 1, 1, -1, -1, false); - else - genok = PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, false); - } - if (!genok) { - if (currlevel < 17) { - genok = PlaceMiniSet(L3DOWN, 1, 1, -1, -1, true); - ViewPosition += { 2, -2 }; - } else { - if (currlevel != 20) { - genok = PlaceMiniSet(L6DOWN, 1, 1, -1, -1, true); - ViewPosition += { 2, -2 }; - } - } - if (!genok && currlevel == 9) { - genok = PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, false); - } - } - } else { - if (currlevel < 17) { - genok = PlaceMiniSet(L3UP, 1, 1, -1, -1, false); - } else { - if (currlevel != 17) - genok = PlaceMiniSet(L6UP, 1, 1, -1, -1, false); - else - genok = PlaceMiniSet(L6HOLDWARP, 1, 1, -1, -1, true); - } - if (!genok) { - if (currlevel < 17) { - genok = PlaceMiniSet(L3DOWN, 1, 1, -1, -1, false); - } else { - if (currlevel != 20) - genok = PlaceMiniSet(L6DOWN, 1, 1, -1, -1, false); - } - if (!genok && currlevel == 9) { - genok = PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, true); - } - } - } - if (!genok && Quests[Q_ANVIL].IsAvailable()) { - genok = Anvil(); - } - } while (genok); - if (currlevel < 17) { - Pool(); - } else { - if (HivePlaceSetRandom(HivePattern41, 30)) - lavapool++; - if (HivePlaceSetRandom(HivePattern42, 40)) - lavapool++; - if (HivePlaceSetRandom(HivePattern39, 50)) - lavapool++; - if (HivePlaceSetRandom(HivePattern40, 60)) - lavapool++; - if (lavapool < 3) - lavapool = 0; - } - } while (lavapool == 0); - - if (currlevel < 17) - PoolFix(); - if (currlevel < 17) - Warp(); + // Place stairs up + if (!PlaceMiniSet(L3UP, 1, 1, -1, -1, entry == ENTRY_MAIN)) + return false; - if (currlevel < 17) { - PlaceMiniSetRandom(L3ISLE1, 70); - PlaceMiniSetRandom(L3ISLE2, 70); - PlaceMiniSetRandom(L3ISLE3, 30); - PlaceMiniSetRandom(L3ISLE4, 30); - PlaceMiniSetRandom(L3ISLE1, 100); - PlaceMiniSetRandom(L3ISLE2, 100); - PlaceMiniSetRandom(L3ISLE5, 90); - } else { + // Place stairs down + if (!PlaceMiniSet(L3DOWN, 1, 1, -1, -1, entry == ENTRY_PREV)) + return false; + if (entry == ENTRY_PREV) + ViewPosition += { 2, -2 }; + + // Place town warp stairs + if (currlevel == 9 && !PlaceMiniSet(L3HOLDWARP, 1, 1, -1, -1, entry == ENTRY_TWARPDN)) + return false; + + return true; +} + +bool PlaceNestStairs(lvl_entry entry) +{ + // Place stairs up + if (!PlaceMiniSet(currlevel != 17 ? L6UP : L6HOLDWARP, 1, 1, -1, -1, entry == ENTRY_MAIN || entry == ENTRY_TWARPDN)) + return false; + + // Place stairs down + if (currlevel != 20) { + if (!PlaceMiniSet(L6DOWN, 1, 1, -1, -1, entry == ENTRY_PREV)) + return false; + if (entry == ENTRY_PREV) + ViewPosition += { 2, -2 }; + } + + return true; +} + +bool PlaceStairs(lvl_entry entry) +{ + if (leveltype == DTYPE_NEST) { + return PlaceNestStairs(entry); + } + + return PlaceCaveStairs(entry); +} + +void GenerateLevel(lvl_entry entry) +{ + while (true) { + InitDungeonFlags(); + int x1 = GenerateRnd(20) + 10; + int y1 = GenerateRnd(20) + 10; + int x2 = x1 + 2; + int y2 = y1 + 2; + FillRoom(x1, y1, x2, y2); + CreateBlock(x1, y1, 2, 0); + CreateBlock(x2, y1, 2, 1); + CreateBlock(x1, y2, 2, 2); + CreateBlock(x1, y1, 2, 3); + if (Quests[Q_ANVIL].IsAvailable()) { + x1 = GenerateRnd(10) + 10; + y1 = GenerateRnd(10) + 10; + x2 = x1 + 12; + y2 = y1 + 12; + FloorArea(x1, y1, x2, y2); + } + FillDiagonals(); + FillSingles(); + FillStraights(); + FillDiagonals(); + Edges(); + if (GetFloorArea() < 600 || !Lockout()) + continue; + MakeMegas(); + if (!PlaceStairs(entry)) + continue; + if (Quests[Q_ANVIL].IsAvailable() && !PlaceAnvil()) + continue; + if (PlacePool()) + break; + } + + if (leveltype == DTYPE_NEST) { PlaceMiniSetRandom(L6ISLE1, 70); PlaceMiniSetRandom(L6ISLE2, 70); PlaceMiniSetRandom(L6ISLE3, 30); @@ -2362,55 +2334,6 @@ void GenerateLevel(lvl_entry entry) PlaceMiniSetRandom(L6ISLE1, 100); PlaceMiniSetRandom(L6ISLE2, 100); PlaceMiniSetRandom(L6ISLE5, 90); - } - - if (currlevel < 17) - HallOfHeroes(); - if (currlevel < 17) - River(); - - if (Quests[Q_ANVIL].IsAvailable()) { - dungeon[setpc_x + 7][setpc_y + 5] = 7; - dungeon[setpc_x + 8][setpc_y + 5] = 7; - dungeon[setpc_x + 9][setpc_y + 5] = 7; - if (dungeon[setpc_x + 10][setpc_y + 5] == 17 || dungeon[setpc_x + 10][setpc_y + 5] == 18) { - dungeon[setpc_x + 10][setpc_y + 5] = 45; - } - } - - if (currlevel < 17) - DRLG_PlaceThemeRooms(5, 10, 7, 0, false); - - if (currlevel < 17) { - Fence(); - PlaceMiniSetRandom(L3TITE1, 10); - PlaceMiniSetRandom(L3TITE2, 10); - PlaceMiniSetRandom(L3TITE3, 10); - PlaceMiniSetRandom(L3TITE6, 20); - PlaceMiniSetRandom(L3TITE7, 20); - PlaceMiniSetRandom(L3TITE8, 20); - PlaceMiniSetRandom(L3TITE9, 20); - PlaceMiniSetRandom(L3TITE10, 20); - PlaceMiniSetRandom(L3TITE11, 30); - PlaceMiniSetRandom(L3TITE12, 20); - PlaceMiniSetRandom(L3TITE13, 20); - PlaceMiniSetRandom(L3CREV1, 30); - PlaceMiniSetRandom(L3CREV2, 30); - PlaceMiniSetRandom(L3CREV3, 30); - PlaceMiniSetRandom(L3CREV4, 30); - PlaceMiniSetRandom(L3CREV5, 30); - PlaceMiniSetRandom(L3CREV6, 30); - PlaceMiniSetRandom(L3CREV7, 30); - PlaceMiniSetRandom(L3CREV8, 30); - PlaceMiniSetRandom(L3CREV9, 30); - PlaceMiniSetRandom(L3CREV10, 30); - PlaceMiniSetRandom(L3CREV11, 30); - PlaceMiniSetRandom(L3XTRA1, 25); - PlaceMiniSetRandom(L3XTRA2, 25); - PlaceMiniSetRandom(L3XTRA3, 25); - PlaceMiniSetRandom(L3XTRA4, 25); - PlaceMiniSetRandom(L3XTRA5, 25); - } else { PlaceMiniSetRandom(HivePattern1, 20); PlaceMiniSetRandom(HivePattern2, 20); PlaceMiniSetRandom(HivePattern3, 20); @@ -2459,6 +2382,59 @@ void GenerateLevel(lvl_entry entry) PlaceMiniSetRandom(HivePattern22, 25); PlaceMiniSetRandom(HivePattern27, 25); PlaceMiniSetRandom(HivePattern28, 25); + } else { + PoolFix(); + Warp(); + + PlaceMiniSetRandom(L3ISLE1, 70); + PlaceMiniSetRandom(L3ISLE2, 70); + PlaceMiniSetRandom(L3ISLE3, 30); + PlaceMiniSetRandom(L3ISLE4, 30); + PlaceMiniSetRandom(L3ISLE1, 100); + PlaceMiniSetRandom(L3ISLE2, 100); + PlaceMiniSetRandom(L3ISLE5, 90); + + HallOfHeroes(); + River(); + + if (Quests[Q_ANVIL].IsAvailable()) { + dungeon[setpc_x + 7][setpc_y + 5] = 7; + dungeon[setpc_x + 8][setpc_y + 5] = 7; + dungeon[setpc_x + 9][setpc_y + 5] = 7; + if (dungeon[setpc_x + 10][setpc_y + 5] == 17 || dungeon[setpc_x + 10][setpc_y + 5] == 18) { + dungeon[setpc_x + 10][setpc_y + 5] = 45; + } + } + + DRLG_PlaceThemeRooms(5, 10, 7, 0, false); + Fence(); + PlaceMiniSetRandom(L3TITE1, 10); + PlaceMiniSetRandom(L3TITE2, 10); + PlaceMiniSetRandom(L3TITE3, 10); + PlaceMiniSetRandom(L3TITE6, 20); + PlaceMiniSetRandom(L3TITE7, 20); + PlaceMiniSetRandom(L3TITE8, 20); + PlaceMiniSetRandom(L3TITE9, 20); + PlaceMiniSetRandom(L3TITE10, 20); + PlaceMiniSetRandom(L3TITE11, 30); + PlaceMiniSetRandom(L3TITE12, 20); + PlaceMiniSetRandom(L3TITE13, 20); + PlaceMiniSetRandom(L3CREV1, 30); + PlaceMiniSetRandom(L3CREV2, 30); + PlaceMiniSetRandom(L3CREV3, 30); + PlaceMiniSetRandom(L3CREV4, 30); + PlaceMiniSetRandom(L3CREV5, 30); + PlaceMiniSetRandom(L3CREV6, 30); + PlaceMiniSetRandom(L3CREV7, 30); + PlaceMiniSetRandom(L3CREV8, 30); + PlaceMiniSetRandom(L3CREV9, 30); + PlaceMiniSetRandom(L3CREV10, 30); + PlaceMiniSetRandom(L3CREV11, 30); + PlaceMiniSetRandom(L3XTRA1, 25); + PlaceMiniSetRandom(L3XTRA2, 25); + PlaceMiniSetRandom(L3XTRA3, 25); + PlaceMiniSetRandom(L3XTRA4, 25); + PlaceMiniSetRandom(L3XTRA5, 25); } for (int j = 0; j < DMAXY; j++) { @@ -2475,6 +2451,43 @@ void Pass3() DRLG_LPass3(8 - 1); } +void PlaceCaveLights() +{ + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] >= 56 && dPiece[i][j] <= 147) { + DoLighting({ i, j }, 7, -1); + } else if (dPiece[i][j] >= 154 && dPiece[i][j] <= 161) { + DoLighting({ i, j }, 7, -1); + } else if (IsAnyOf(dPiece[i][j], 150, 152)) { + DoLighting({ i, j }, 7, -1); + } + } + } +} + +void PlaceHiveLights() +{ + + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] >= 382 && dPiece[i][j] <= 457) { + DoLighting({ i, j }, 9, -1); + } + } + } +} + +void PlaceLights() +{ + if (leveltype == DTYPE_NEST) { + PlaceHiveLights(); + return; + } + + PlaceCaveLights(); +} + } // namespace void CreateL3Dungeon(uint32_t rseed, lvl_entry entry) @@ -2488,29 +2501,7 @@ void CreateL3Dungeon(uint32_t rseed, lvl_entry entry) DRLG_InitSetPC(); GenerateLevel(entry); Pass3(); - - if (currlevel < 17) { - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] >= 56 && dPiece[i][j] <= 147) { - DoLighting({ i, j }, 7, -1); - } else if (dPiece[i][j] >= 154 && dPiece[i][j] <= 161) { - DoLighting({ i, j }, 7, -1); - } else if (IsAnyOf(dPiece[i][j], 150, 152)) { - DoLighting({ i, j }, 7, -1); - } - } - } - } else { - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] >= 382 && dPiece[i][j] <= 457) { - DoLighting({ i, j }, 9, -1); - } - } - } - } - + PlaceLights(); DRLG_SetPC(); } diff --git a/Source/drlg_l4.cpp b/Source/drlg_l4.cpp index 596b17835..f4b7d7ee9 100644 --- a/Source/drlg_l4.cpp +++ b/Source/drlg_l4.cpp @@ -1283,12 +1283,50 @@ void GeneralFix() } } +bool PlaceStairs(lvl_entry entry) +{ + // Place stairs up + if (!PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, entry == ENTRY_MAIN)) + return false; + if (entry == ENTRY_MAIN) + ViewPosition.x++; + + if (currlevel != 15) { + // Place stairs down + if (currlevel != 16 && !Quests[Q_WARLORD].IsAvailable()) { + if (!PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, entry == ENTRY_PREV)) + return false; + } + + // Place town warp stairs + if (currlevel == 13) { + if (!PlaceMiniSet(L4TWARP, 1, 1, -1, -1, entry == ENTRY_TWARPDN)) + return false; + if (entry == ENTRY_TWARPDN) + ViewPosition.x++; + } + } else { + // Place hell gate + bool isGateOpen = gbIsMultiplayer || Quests[Q_DIABLO]._qactive == QUEST_ACTIVE; + if (!PlaceMiniSet(isGateOpen ? L4PENTA2 : L4PENTA, 1, 1, -1, -1, entry == ENTRY_PREV)) + return false; + } + + if (entry == ENTRY_PREV) { + if (Quests[Q_WARLORD].IsAvailable()) + ViewPosition = Point { 22, 22 } + Displacement { setpc_x, setpc_y } * 2; + else + ViewPosition.y++; + } + + return true; +} + void GenerateLevel(lvl_entry entry) { constexpr int Minarea = 173; int ar; - bool doneflag; - do { + while (true) { DRLG_InitTrans(); do { @@ -1323,79 +1361,9 @@ void GenerateLevel(lvl_entry entry) if (currlevel == 16) { LoadDiabQuads(true); } - if (Quests[Q_WARLORD].IsAvailable()) { - if (entry == ENTRY_MAIN) { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, true); - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, false); - } - ViewPosition.x++; - } else if (entry == ENTRY_PREV) { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, false); - } - ViewPosition = Point { 22, 22 } + Displacement { setpc_x, setpc_y } * 2; - } else { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, true); - } - ViewPosition.x++; - } - } else if (currlevel != 15) { - if (entry == ENTRY_MAIN) { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, true); - if (doneflag && currlevel != 16) { - doneflag = PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, false); - } - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, false); - } - ViewPosition.x++; - } else if (entry == ENTRY_PREV) { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel != 16) { - doneflag = PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, true); - } - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, false); - } - ViewPosition.y++; - } else { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, false); - if (doneflag && currlevel != 16) { - doneflag = PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, false); - } - if (doneflag && currlevel == 13) { - doneflag = PlaceMiniSet(L4TWARP, 1, 1, -1, -1, true); - } - ViewPosition.x++; - } - } else { - if (entry == ENTRY_MAIN) { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, true); - if (doneflag) { - if (!gbIsMultiplayer && Quests[Q_DIABLO]._qactive != QUEST_ACTIVE) { - doneflag = PlaceMiniSet(L4PENTA, 1, 1, -1, -1, false); - } else { - doneflag = PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, false); - } - } - ViewPosition.x++; - } else { - doneflag = PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, false); - if (doneflag) { - if (!gbIsMultiplayer && Quests[Q_DIABLO]._qactive != QUEST_ACTIVE) { - doneflag = PlaceMiniSet(L4PENTA, 1, 1, -1, -1, true); - } else { - doneflag = PlaceMiniSet(L4PENTA2, 1, 1, -1, -1, true); - } - } - ViewPosition.y++; - } - } - } while (!doneflag); + if (PlaceStairs(entry)) + break; + } GeneralFix(); diff --git a/Source/gmenu.cpp b/Source/gmenu.cpp index 198615290..64ba28542 100644 --- a/Source/gmenu.cpp +++ b/Source/gmenu.cpp @@ -164,7 +164,7 @@ TMenuItem *sgpCurrentMenu; void gmenu_draw_pause(const Surface &out) { - if (currlevel != 0) + if (leveltype != DTYPE_TOWN) RedBack(out); if (sgpCurrentMenu == nullptr) { LightTableIndex = 0; diff --git a/Source/inv.cpp b/Source/inv.cpp index b2c5acb8c..d628f0032 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -1728,7 +1728,7 @@ bool CanPut(Point position) return false; } - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { if (dMonster[position.x][position.y] != 0) { return false; } @@ -2084,11 +2084,11 @@ bool UseInvItem(int pnum, int cii) dropGoldValue = 0; } - if (item->isScroll() && currlevel == 0 && !spelldata[item->_iSpell].sTownSpell) { + if (item->isScroll() && leveltype == DTYPE_TOWN && !spelldata[item->_iSpell].sTownSpell) { return true; } - if (item->_iMiscId > IMISC_RUNEFIRST && item->_iMiscId < IMISC_RUNELAST && currlevel == 0) { + if (item->_iMiscId > IMISC_RUNEFIRST && item->_iMiscId < IMISC_RUNELAST && leveltype == DTYPE_TOWN) { return true; } diff --git a/Source/items.cpp b/Source/items.cpp index 47c4c86bb..67c0ad7c9 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -383,13 +383,13 @@ bool IsSuffixValidForItemType(int i, AffixItemType flgs) int ItemsGetCurrlevel() { - int lvl = currlevel; - if (currlevel >= 17 && currlevel <= 20) - lvl = currlevel - 8; - if (currlevel >= 21 && currlevel <= 24) - lvl = currlevel - 7; + if (leveltype == DTYPE_NEST) + return currlevel - 8; + + if (leveltype == DTYPE_CRYPT) + return currlevel - 7; - return lvl; + return currlevel; } bool ItemPlace(Point position) diff --git a/Source/lighting.cpp b/Source/lighting.cpp index 5354220a8..41b34b1ea 100644 --- a/Source/lighting.cpp +++ b/Source/lighting.cpp @@ -565,7 +565,7 @@ void DoLighting(Point position, int nRadius, int lnum) } if (InDungeonBounds(position)) { - if (currlevel < 17) { + if (IsNoneOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) { SetLight(position, 0); } else if (GetLight(position) > lightradius[nRadius][0]) { SetLight(position, lightradius[nRadius][0]); @@ -799,7 +799,7 @@ void MakeLightTable() } tbl += 224; } - if (currlevel >= 17) { + if (IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) { tbl = LightTables.data(); for (int i = 0; i < lights; i++) { *tbl++ = 0; @@ -856,7 +856,7 @@ void MakeLightTable() } } - if (currlevel >= 17) { + if (IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) { for (int j = 0; j < 16; j++) { double fa = (sqrt((double)(16 - j))) / 128; fa *= fa; diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 0ea7307a4..194b44293 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -642,7 +642,7 @@ void LoadMonster(LoadHelper *file, Monster &monster) monster.mlid = NO_LIGHT; // Correct incorect values in old saves if ((monster._mFlags & MFLAG_BERSERK) != 0) { - int lightRadius = (currlevel < 17 || currlevel > 20) ? 3 : 9; + int lightRadius = leveltype == DTYPE_NEST ? 9 : 3; monster.mlid = AddLight(monster.position.tile, lightRadius); } @@ -1991,7 +1991,7 @@ void LoadGame(bool firstflag) int tmpNummissiles = file.NextBE(); int tmpNobjects = file.NextBE(); - if (!gbIsHellfire && currlevel > 17) + if (!gbIsHellfire && IsAnyOf(leveltype, DTYPE_NEST, DTYPE_CRYPT)) app_fatal("%s", _("Player is on a Hellfire only level").c_str()); for (uint8_t i = 0; i < giNumberOfLevels; i++) { @@ -2404,7 +2404,7 @@ void SaveLevel() DoUnVision(myPlayer.position.tile, myPlayer._pLightRad); // fix for vision staying on the level - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) glSeedTbl[0] = AdvanceRndSeed(); char szName[MAX_PATH]; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index c2892b9d6..aec6abf44 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -1188,7 +1188,7 @@ void AddBerserk(Missile &missile, const AddMissileParameter ¶meter) monster.mMaxDamage = (GenerateRnd(10) + 120) * monster.mMaxDamage / 100 + slvl; monster.mMinDamage2 = (GenerateRnd(10) + 120) * monster.mMinDamage2 / 100 + slvl; monster.mMaxDamage2 = (GenerateRnd(10) + 120) * monster.mMaxDamage2 / 100 + slvl; - int lightRadius = (currlevel < 17 || currlevel > 20) ? 3 : 9; + int lightRadius = leveltype == DTYPE_NEST ? 9 : 3; monster.mlid = AddLight(monster.position.tile, lightRadius); UseMana(missile._misource, SPL_BERSERK); } @@ -1851,7 +1851,7 @@ void AddWeapexp(Missile &missile, const AddMissileParameter ¶meter) void AddTown(Missile &missile, const AddMissileParameter ¶meter) { - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { missile.position.tile = parameter.dst; missile.position.start = parameter.dst; } else { @@ -1894,7 +1894,7 @@ void AddTown(Missile &missile, const AddMissileParameter ¶meter) other._mirange = 0; } PutMissile(missile); - if (missile._misource == MyPlayerId && !missile._miDelFlag && currlevel != 0) { + if (missile._misource == MyPlayerId && !missile._miDelFlag && leveltype != DTYPE_TOWN) { if (!setlevel) { NetSendCmdLocParam3(true, CMD_ACTIVATEPORTAL, missile.position.tile, currlevel, leveltype, 0); } else { @@ -3195,7 +3195,7 @@ void MI_Town(Missile &missile) missile._mirange--; if (missile._mirange == missile.var1) SetMissDir(missile, 1); - if (currlevel != 0 && missile._mimfnum != 1 && missile._mirange != 0) { + if (leveltype != DTYPE_TOWN && missile._mimfnum != 1 && missile._mirange != 0) { if (missile.var2 == 0) missile._mlid = AddLight(missile.position.tile, 1); ChangeLight(missile._mlid, missile.position.tile, expLight[missile.var2]); @@ -3973,7 +3973,7 @@ void MI_Rportal(Missile &missile) if (missile._mirange == missile.var1) SetMissDir(missile, 1); - if (currlevel != 0 && missile._mimfnum != 1 && missile._mirange != 0) { + if (leveltype != DTYPE_TOWN && missile._mimfnum != 1 && missile._mirange != 0) { if (missile.var2 == 0) missile._mlid = AddLight(missile.position.tile, 1); ChangeLight(missile._mlid, missile.position.tile, expLight[missile.var2]); diff --git a/Source/monster.cpp b/Source/monster.cpp index 6363ddaca..470afc10f 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -3852,7 +3852,7 @@ void InitMonsters() int mtype = scattertypes[GenerateRnd(numscattypes)]; if (currlevel == 1 || GenerateRnd(2) == 0) na = 1; - else if (currlevel == 2 || (currlevel >= 21 && currlevel <= 24)) + else if (currlevel == 2 || leveltype == DTYPE_CRYPT) na = GenerateRnd(2) + 2; else na = GenerateRnd(3) + 3; diff --git a/Source/msg.cpp b/Source/msg.cpp index 9c0a5936c..8c297d26c 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -432,10 +432,10 @@ void DeltaLeaveSync(uint8_t bLevel) { if (!gbIsMultiplayer) return; - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) { glSeedTbl[0] = AdvanceRndSeed(); - if (currlevel <= 0) return; + } for (int i = 0; i < ActiveMonsterCount; i++) { int ma = ActiveMonsters[i]; @@ -1035,7 +1035,7 @@ DWORD OnSpellWall(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam1); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1070,7 +1070,7 @@ DWORD OnSpellTile(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam1); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1101,7 +1101,7 @@ DWORD OnTargetSpellTile(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam1); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1228,7 +1228,7 @@ DWORD OnSpellMonster(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam2); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1260,7 +1260,7 @@ DWORD OnSpellPlayer(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam2); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1292,7 +1292,7 @@ DWORD OnTargetSpellMonster(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam2); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1322,7 +1322,7 @@ DWORD OnTargetSpellPlayer(const TCmd *pCmd, Player &player) return sizeof(message); auto spell = static_cast(message.wParam2); - if (currlevel == 0 && !spelldata[spell].sTownSpell) { + if (leveltype == DTYPE_TOWN && !spelldata[spell].sTownSpell) { LogError(_("{:s} has cast an illegal spell.").c_str(), player._pName); return sizeof(message); } @@ -1530,7 +1530,7 @@ DWORD OnPlayerDamage(const TCmd *pCmd, Player &player) { const auto &message = *reinterpret_cast(pCmd); - if (message.bPlr == MyPlayerId && currlevel != 0 && gbBufferMsgs != 1) { + if (message.bPlr == MyPlayerId && leveltype != DTYPE_TOWN && gbBufferMsgs != 1) { if (currlevel == player.plrlevel && message.dwDam <= 192000 && Players[message.bPlr]._pHitPoints >> 6 > 0) { ApplyPlrDamage(message.bPlr, 0, 0, message.dwDam, 1); } @@ -1771,7 +1771,7 @@ DWORD OnActivatePortal(const TCmd *pCmd, int pnum) ActivatePortal(pnum, position, level, dungeonType, isSetLevel); if (pnum != MyPlayerId) { - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { AddInTownPortal(pnum); } else if (currlevel == Players[pnum].plrlevel) { bool addPortal = true; @@ -2012,7 +2012,7 @@ DWORD OnOpenCrypt(const TCmd *pCmd) if (gbBufferMsgs != 1) { TownOpenGrave(); InitTownTriggers(); - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) PlaySFX(IS_SARC); } return sizeof(*pCmd); @@ -2270,7 +2270,7 @@ void DeltaLoadLevel() return; deltaload = true; - if (currlevel != 0) { + if (leveltype != DTYPE_TOWN) { for (int i = 0; i < ActiveMonsterCount; i++) { if (sgLevels[currlevel].monster[i]._mx == 0xFF) continue; @@ -2376,7 +2376,7 @@ void DeltaLoadLevel() } } - if (currlevel != 0) { + if (leveltype != DTYPE_TOWN) { for (int i = 0; i < MAXOBJECTS; i++) { switch (sgLevels[currlevel].object[i].bCmd) { case CMD_OPENDOOR: diff --git a/Source/objects.cpp b/Source/objects.cpp index e6e80a5da..fbfdad94e 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -3762,9 +3762,7 @@ void OperateArmorStand(int pnum, int i, bool sendmsg) CreateTypeItem(Objects[i].position, uniqueRnd, ItemType::MediumArmor, IMISC_NONE, sendmsg, false); } else if (currlevel >= 10 && currlevel <= 12) { CreateTypeItem(Objects[i].position, false, ItemType::HeavyArmor, IMISC_NONE, sendmsg, false); - } else if (currlevel >= 13 && currlevel <= 16) { - CreateTypeItem(Objects[i].position, true, ItemType::HeavyArmor, IMISC_NONE, sendmsg, false); - } else if (currlevel >= 17) { + } else if (currlevel >= 13) { CreateTypeItem(Objects[i].position, true, ItemType::HeavyArmor, IMISC_NONE, sendmsg, false); } if (pnum == MyPlayerId) @@ -4637,7 +4635,7 @@ void InitObjects() } InitRndBarrels(); } - if (IsAnyOf(leveltype, DTYPE_CAVES, DTYPE_NEST)) { + if (leveltype == DTYPE_CAVES) { AddL3Objs(0, 0, MAXDUNX, MAXDUNY); InitRndBarrels(); } @@ -4673,6 +4671,9 @@ void InitObjects() InitRndBarrels(); AddL4Goodies(); } + if (leveltype == DTYPE_NEST) { + InitRndBarrels(); + } if (leveltype == DTYPE_CRYPT) { InitRndLocBigObj(10, 15, OBJ_L5SARC); AddCryptObjects(0, 0, MAXDUNX, MAXDUNY); diff --git a/Source/panels/spell_book.cpp b/Source/panels/spell_book.cpp index f56b0930d..499927d8c 100644 --- a/Source/panels/spell_book.cpp +++ b/Source/panels/spell_book.cpp @@ -71,7 +71,7 @@ spell_type GetSBookTrans(spell_id ii, bool townok) st = RSPLTYPE_INVALID; } } - if (townok && currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[ii].sTownSpell) { + if (townok && leveltype == DTYPE_TOWN && st != RSPLTYPE_INVALID && !spelldata[ii].sTownSpell) { st = RSPLTYPE_INVALID; } diff --git a/Source/panels/spell_list.cpp b/Source/panels/spell_list.cpp index aee7ea737..8494bb1a7 100644 --- a/Source/panels/spell_list.cpp +++ b/Source/panels/spell_list.cpp @@ -110,7 +110,7 @@ void DrawSpell(const Surface &out) if (tlvl <= 0) st = RSPLTYPE_INVALID; } - if (currlevel == 0 && st != RSPLTYPE_INVALID && !spelldata[spl].sTownSpell) + if (leveltype == DTYPE_TOWN && st != RSPLTYPE_INVALID && !spelldata[spl].sTownSpell) st = RSPLTYPE_INVALID; SetSpellTrans(st); const int nCel = (spl != SPL_INVALID) ? SpellITbl[spl] : 26; @@ -134,7 +134,7 @@ void DrawSpellList(const Surface &out) spell_type transType = spellListItem.type; int spellLevel = 0; const SpellData &spellDataItem = spelldata[static_cast(spellListItem.id)]; - if (currlevel == 0 && !spellDataItem.sTownSpell) { + if (leveltype == DTYPE_TOWN && !spellDataItem.sTownSpell) { transType = RSPLTYPE_INVALID; } if (spellListItem.type == RSPLTYPE_SPELL) { diff --git a/Source/player.cpp b/Source/player.cpp index 4b3bf0e4c..13b77053d 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -341,7 +341,7 @@ void HandleWalkMode(int pnum, Displacement vel, Direction dir) void StartWalkAnimation(Player &player, Direction dir, bool pmWillBeCalled) { int skippedFrames = -2; - if (currlevel == 0 && sgGameInitInfo.bRunInTown != 0) + if (leveltype == DTYPE_TOWN && sgGameInitInfo.bRunInTown != 0) skippedFrames = 2; if (pmWillBeCalled) skippedFrames += 1; @@ -416,7 +416,7 @@ void ChangeOffset(int pnum) player.position.offset2 += player.position.velocity; - if (currlevel == 0 && sgGameInitInfo.bRunInTown != 0) { + if (leveltype == DTYPE_TOWN && sgGameInitInfo.bRunInTown != 0) { player.position.offset2 += player.position.velocity; } @@ -661,7 +661,7 @@ bool DoWalk(int pnum, int variant) Player &player = Players[pnum]; // Play walking sound effect on certain animation frames - if (*sgOptions.Audio.walkingSound && (currlevel != 0 || sgGameInitInfo.bRunInTown == 0)) { + if (*sgOptions.Audio.walkingSound && (leveltype != DTYPE_TOWN || sgGameInitInfo.bRunInTown == 0)) { if (player.AnimInfo.CurrentFrame == 0 || player.AnimInfo.CurrentFrame == 4) { PlaySfxLoc(PS_WALK1, player.position.tile); @@ -1528,7 +1528,7 @@ void CheckNewPath(int pnum, bool pmWillBeCalled) int xvel3 = 2048; int xvel = 1024; int yvel = 512; - if (currlevel != 0) { + if (leveltype != DTYPE_TOWN) { xvel3 = PWVel[static_cast(player._pClass)][0]; xvel = PWVel[static_cast(player._pClass)][1]; yvel = PWVel[static_cast(player._pClass)][2]; @@ -2803,7 +2803,7 @@ void InitPlayer(Player &player, bool firstTime) player._pdir = Direction::South; if (&player == &myPlayer) { - if (!firstTime || currlevel != 0) { + if (!firstTime || leveltype != DTYPE_TOWN) { player.position.tile = ViewPosition; } } else { @@ -3211,7 +3211,7 @@ void SyncPlrKill(int pnum, int earflag) { Player &player = Players[pnum]; - if (player._pHitPoints <= 0 && currlevel == 0) { + if (player._pHitPoints <= 0 && leveltype == DTYPE_TOWN) { SetPlayerHitPoints(player, 64); return; } @@ -3222,7 +3222,7 @@ void SyncPlrKill(int pnum, int earflag) void RemovePlrMissiles(int pnum) { - if (currlevel != 0 && pnum == MyPlayerId) { + if (leveltype != DTYPE_TOWN && pnum == MyPlayerId) { auto &golem = Monsters[MyPlayerId]; if (golem.position.tile.x != 1 || golem.position.tile.y != 0) { M_StartKill(MyPlayerId, MyPlayerId); @@ -3378,7 +3378,7 @@ void ProcessPlayers() } if (pnum == MyPlayerId) { - if (HasAnyOf(player._pIFlags, ItemSpecialEffect::DrainLife) && currlevel != 0) { + if (HasAnyOf(player._pIFlags, ItemSpecialEffect::DrainLife) && leveltype != DTYPE_TOWN) { ApplyPlrDamage(pnum, 0, 0, 4); } if (HasAnyOf(player._pIFlags, ItemSpecialEffect::NoMana) && player._pManaBase > 0) { @@ -3458,7 +3458,7 @@ bool PosOkPlayer(const Player &player, Point position) } if (dMonster[position.x][position.y] != 0) { - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { return false; } if (dMonster[position.x][position.y] <= 0) { diff --git a/Source/portal.cpp b/Source/portal.cpp index 35d8adad5..f29122363 100644 --- a/Source/portal.cpp +++ b/Source/portal.cpp @@ -55,7 +55,7 @@ void AddWarpMissile(int i, Point position) if (missile != nullptr) { SetMissDir(*missile, 1); - if (currlevel != 0) + if (leveltype != DTYPE_TOWN) missile->_mlid = AddLight(missile->position.tile, 15); } @@ -67,7 +67,7 @@ void SyncPortals() for (int i = 0; i < MAXPORTAL; i++) { if (!Portals[i].open) continue; - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) AddWarpMissile(i, WarpDrop[i]); else { int lvl = currlevel; @@ -106,7 +106,7 @@ bool PortalOnLevel(int i) if (Portals[i].level == currlevel) return true; - return currlevel == 0; + return leveltype == DTYPE_TOWN; } void RemovePortalMissile(int id) @@ -131,7 +131,7 @@ void SetCurrentPortal(int p) void GetPortalLevel() { - if (currlevel != 0) { + if (leveltype != DTYPE_TOWN) { setlevel = false; currlevel = 0; MyPlayer->plrlevel = 0; @@ -160,7 +160,7 @@ void GetPortalLevel() void GetPortalLvlPos() { - if (currlevel == 0) { + if (leveltype == DTYPE_TOWN) { ViewPosition = WarpDrop[portalindex] + Displacement { 1, 1 }; } else { ViewPosition = Portals[portalindex].position; diff --git a/Source/qol/monhealthbar.cpp b/Source/qol/monhealthbar.cpp index 0095d137d..9e72c6ae1 100644 --- a/Source/qol/monhealthbar.cpp +++ b/Source/qol/monhealthbar.cpp @@ -66,7 +66,7 @@ void DrawMonsterHealthBar(const Surface &out) assert(healthBlue.surface != nullptr); assert(resistance.surface != nullptr); - if (currlevel == 0) + if (leveltype == DTYPE_TOWN) return; if (pcursmonst == -1) return; diff --git a/Source/qol/stash.cpp b/Source/qol/stash.cpp index 3e7c571cd..8f0c91617 100644 --- a/Source/qol/stash.cpp +++ b/Source/qol/stash.cpp @@ -474,7 +474,7 @@ bool UseStashItem(uint16_t c) return true; } - if (item->_iMiscId > IMISC_RUNEFIRST && item->_iMiscId < IMISC_RUNELAST && currlevel == 0) { + if (item->_iMiscId > IMISC_RUNEFIRST && item->_iMiscId < IMISC_RUNELAST && leveltype == DTYPE_TOWN) { return true; } diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 09dcf3b49..5c1786f3f 100644 --- a/Source/scrollrt.cpp +++ b/Source/scrollrt.cpp @@ -582,7 +582,7 @@ void DrawDeadPlayer(const Surface &out, Point tilePosition, Point targetBufferPo for (int i = 0; i < MAX_PLRS; i++) { Player &player = Players[i]; - if (player.plractive && player._pHitPoints == 0 && player.plrlevel == (BYTE)currlevel && player.position.tile == tilePosition) { + if (player.plractive && player._pHitPoints == 0 && player.plrlevel == currlevel && player.position.tile == tilePosition) { dFlags[tilePosition.x][tilePosition.y] |= DungeonFlag::DeadPlayer; const Point playerRenderPosition { targetBufferPosition + player.position.offset }; DrawPlayer(out, i, tilePosition, playerRenderPosition); diff --git a/Source/trigs.cpp b/Source/trigs.cpp index d3cc6da5d..d87031df9 100644 --- a/Source/trigs.cpp +++ b/Source/trigs.cpp @@ -144,40 +144,17 @@ void InitTownTriggers() void InitL1Triggers() { numtrigs = 0; - if (currlevel < 17) { - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] == 129) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABPREVLVL; - numtrigs++; - } - if (dPiece[i][j] == 115) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; - numtrigs++; - } + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] == 129) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; } - } - } else { - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] == 184) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABTWARPUP; - trigs[numtrigs]._tlvl = 0; - numtrigs++; - } - if (dPiece[i][j] == 158) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABPREVLVL; - numtrigs++; - } - if (dPiece[i][j] == 126) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; - numtrigs++; - } + if (dPiece[i][j] == 115) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; } } } @@ -214,50 +191,25 @@ void InitL2Triggers() void InitL3Triggers() { - if (currlevel < 17) { - numtrigs = 0; - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] == 171) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABPREVLVL; - numtrigs++; - } - - if (dPiece[i][j] == 168) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; - numtrigs++; - } - - if (dPiece[i][j] == 549) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABTWARPUP; - numtrigs++; - } + numtrigs = 0; + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] == 171) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; } - } - } else { - numtrigs = 0; - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] == 66) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABPREVLVL; - numtrigs++; - } - if (dPiece[i][j] == 63) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; - numtrigs++; - } + if (dPiece[i][j] == 168) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } - if (dPiece[i][j] == 80) { - trigs[numtrigs].position = { i, j }; - trigs[numtrigs]._tmsg = WM_DIABTWARPUP; - numtrigs++; - } + if (dPiece[i][j] == 549) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + numtrigs++; } } } @@ -302,6 +254,59 @@ void InitL4Triggers() trigflag = false; } +void InitHiveTriggers() +{ + numtrigs = 0; + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] == 66) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + + if (dPiece[i][j] == 63) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + + if (dPiece[i][j] == 80) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + numtrigs++; + } + } + } + trigflag = false; +} + +void InitCryptTriggers() +{ + numtrigs = 0; + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] == 184) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABTWARPUP; + trigs[numtrigs]._tlvl = 0; + numtrigs++; + } + if (dPiece[i][j] == 158) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABPREVLVL; + numtrigs++; + } + if (dPiece[i][j] == 126) { + trigs[numtrigs].position = { i, j }; + trigs[numtrigs]._tmsg = WM_DIABNEXTLVL; + numtrigs++; + } + } + } + trigflag = false; +} + void InitSKingTriggers() { trigflag = false; @@ -407,73 +412,27 @@ bool ForceTownTrig() bool ForceL1Trig() { - if (currlevel < 17) { - for (int i = 0; L1UpList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L1UpList[i]) { - if (currlevel > 1) - InfoString = fmt::format(_("Up to level {:d}"), currlevel - 1); - else - InfoString = _("Up to town"); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABPREVLVL) { - cursPosition = trigs[j].position; - return true; - } - } - } - } - for (int i = 0; L1DownList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L1DownList[i]) { - InfoString = fmt::format(_("Down to level {:d}"), currlevel + 1); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABNEXTLVL) { - cursPosition = trigs[j].position; - return true; - } - } - } - } - } else { - for (int i = 0; L5UpList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L5UpList[i]) { - InfoString = fmt::format(_("Up to Crypt level {:d}"), currlevel - 21); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABPREVLVL) { - cursPosition = trigs[j].position; - return true; - } - } - } - } - if (dPiece[cursPosition.x][cursPosition.y] == 317) { - InfoString = _("Cornerstone of the World"); - return true; - } - for (int i = 0; L5DownList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L5DownList[i]) { - InfoString = fmt::format(_("Down to Crypt level {:d}"), currlevel - 19); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABNEXTLVL) { - cursPosition = trigs[j].position; - return true; - } + for (int i = 0; L1UpList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L1UpList[i]) { + if (currlevel > 1) + InfoString = fmt::format(_("Up to level {:d}"), currlevel - 1); + else + InfoString = _("Up to town"); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursPosition = trigs[j].position; + return true; } } } - if (currlevel == 21) { - for (int i = 0; L5TWarpUpList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L5TWarpUpList[i]) { - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABTWARPUP) { - int dx = abs(trigs[j].position.x - cursPosition.x); - int dy = abs(trigs[j].position.y - cursPosition.y); - if (dx < 4 && dy < 4) { - InfoString = _("Up to town"); - cursPosition = trigs[j].position; - return true; - } - } - } + } + for (int i = 0; L1DownList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L1DownList[i]) { + InfoString = fmt::format(_("Down to level {:d}"), currlevel + 1); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursPosition = trigs[j].position; + return true; } } } @@ -535,57 +494,30 @@ bool ForceL2Trig() bool ForceL3Trig() { - if (currlevel < 17) { - for (int i = 0; L3UpList[i] != -1; ++i) { - if (dPiece[cursPosition.x][cursPosition.y] == L3UpList[i]) { - InfoString = fmt::format(_("Up to level {:d}"), currlevel - 1); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABPREVLVL) { - int dx = abs(trigs[j].position.x - cursPosition.x); - int dy = abs(trigs[j].position.y - cursPosition.y); - if (dx < 4 && dy < 4) { - cursPosition = trigs[j].position; - return true; - } - } - } - } - } - for (int i = 0; L3DownList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L3DownList[i] - || dPiece[cursPosition.x + 1][cursPosition.y] == L3DownList[i] - || dPiece[cursPosition.x + 2][cursPosition.y] == L3DownList[i]) { - InfoString = fmt::format(_("Down to level {:d}"), currlevel + 1); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABNEXTLVL) { - cursPosition = trigs[j].position; - return true; - } - } - } - } - } else { - for (int i = 0; L6UpList[i] != -1; ++i) { - if (dPiece[cursPosition.x][cursPosition.y] == L6UpList[i]) { - InfoString = fmt::format(_("Up to Nest level {:d}"), currlevel - 17); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABPREVLVL) { + for (int i = 0; L3UpList[i] != -1; ++i) { + if (dPiece[cursPosition.x][cursPosition.y] == L3UpList[i]) { + InfoString = fmt::format(_("Up to level {:d}"), currlevel - 1); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + int dx = abs(trigs[j].position.x - cursPosition.x); + int dy = abs(trigs[j].position.y - cursPosition.y); + if (dx < 4 && dy < 4) { cursPosition = trigs[j].position; return true; } } } } - for (int i = 0; L6DownList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L6DownList[i] - || dPiece[cursPosition.x + 1][cursPosition.y] == L6DownList[i] - || dPiece[cursPosition.x + 2][cursPosition.y] == L6DownList[i]) { - InfoString = fmt::format(_("Down to level {:d}"), currlevel - 15); - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABNEXTLVL) { - cursPosition = trigs[j].position; - return true; - } + } + for (int i = 0; L3DownList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L3DownList[i] + || dPiece[cursPosition.x + 1][cursPosition.y] == L3DownList[i] + || dPiece[cursPosition.x + 2][cursPosition.y] == L3DownList[i]) { + InfoString = fmt::format(_("Down to level {:d}"), currlevel + 1); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursPosition = trigs[j].position; + return true; } } } @@ -608,23 +540,6 @@ bool ForceL3Trig() } } } - if (currlevel == 17) { - for (int i = 0; L6TWarpUpList[i] != -1; i++) { - if (dPiece[cursPosition.x][cursPosition.y] == L6TWarpUpList[i]) { - for (int j = 0; j < numtrigs; j++) { - if (trigs[j]._tmsg == WM_DIABTWARPUP) { - int dx = abs(trigs[j].position.x - cursPosition.x); - int dy = abs(trigs[j].position.y - cursPosition.y); - if (dx < 4 && dy < 4) { - InfoString = _("Up to town"); - cursPosition = trigs[j].position; - return true; - } - } - } - } - } - } return false; } @@ -690,6 +605,103 @@ bool ForceL4Trig() return false; } +bool ForceHiveTrig() +{ + for (int i = 0; L6UpList[i] != -1; ++i) { + if (dPiece[cursPosition.x][cursPosition.y] == L6UpList[i]) { + InfoString = fmt::format(_("Up to Nest level {:d}"), currlevel - 17); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursPosition = trigs[j].position; + return true; + } + } + } + } + for (int i = 0; L6DownList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L6DownList[i] + || dPiece[cursPosition.x + 1][cursPosition.y] == L6DownList[i] + || dPiece[cursPosition.x + 2][cursPosition.y] == L6DownList[i]) { + InfoString = fmt::format(_("Down to level {:d}"), currlevel - 15); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursPosition = trigs[j].position; + return true; + } + } + } + } + + if (currlevel == 17) { + for (int i = 0; L6TWarpUpList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L6TWarpUpList[i]) { + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + int dx = abs(trigs[j].position.x - cursPosition.x); + int dy = abs(trigs[j].position.y - cursPosition.y); + if (dx < 4 && dy < 4) { + InfoString = _("Up to town"); + cursPosition = trigs[j].position; + return true; + } + } + } + } + } + } + + return false; +} + +bool ForceCryptTrig() +{ + for (int i = 0; L5UpList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L5UpList[i]) { + InfoString = fmt::format(_("Up to Crypt level {:d}"), currlevel - 21); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABPREVLVL) { + cursPosition = trigs[j].position; + return true; + } + } + } + } + if (dPiece[cursPosition.x][cursPosition.y] == 317) { + InfoString = _("Cornerstone of the World"); + return true; + } + for (int i = 0; L5DownList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L5DownList[i]) { + InfoString = fmt::format(_("Down to Crypt level {:d}"), currlevel - 19); + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABNEXTLVL) { + cursPosition = trigs[j].position; + return true; + } + } + } + } + if (currlevel == 21) { + for (int i = 0; L5TWarpUpList[i] != -1; i++) { + if (dPiece[cursPosition.x][cursPosition.y] == L5TWarpUpList[i]) { + for (int j = 0; j < numtrigs; j++) { + if (trigs[j]._tmsg == WM_DIABTWARPUP) { + int dx = abs(trigs[j].position.x - cursPosition.x); + int dy = abs(trigs[j].position.y - cursPosition.y); + if (dx < 4 && dy < 4) { + InfoString = _("Up to town"); + cursPosition = trigs[j].position; + return true; + } + } + } + } + } + } + + return false; +} + void Freeupstairs() { for (int i = 0; i < numtrigs; i++) { @@ -760,19 +772,23 @@ void CheckTrigForce() trigflag = ForceTownTrig(); break; case DTYPE_CATHEDRAL: - case DTYPE_CRYPT: trigflag = ForceL1Trig(); break; case DTYPE_CATACOMBS: trigflag = ForceL2Trig(); break; case DTYPE_CAVES: - case DTYPE_NEST: trigflag = ForceL3Trig(); break; case DTYPE_HELL: trigflag = ForceL4Trig(); break; + case DTYPE_NEST: + trigflag = ForceHiveTrig(); + break; + case DTYPE_CRYPT: + trigflag = ForceCryptTrig(); + break; default: break; } diff --git a/Source/trigs.h b/Source/trigs.h index 66c694dc1..31323666c 100644 --- a/Source/trigs.h +++ b/Source/trigs.h @@ -31,6 +31,8 @@ void InitL1Triggers(); void InitL2Triggers(); void InitL3Triggers(); void InitL4Triggers(); +void InitHiveTriggers(); +void InitCryptTriggers(); void InitSKingTriggers(); void InitSChambTriggers(); void InitPWaterTriggers(); diff --git a/test/drlg_l1_test.cpp b/test/drlg_l1_test.cpp index 7d6e3f27f..33a1ee3bf 100644 --- a/test/drlg_l1_test.cpp +++ b/test/drlg_l1_test.cpp @@ -50,6 +50,8 @@ TEST(Drlg_l1, CreateL5Dungeon_diablo_2_1383137027) EXPECT_EQ(ViewPosition, Point(57, 74)); TestCreateDungeon(2, 1383137027, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(57, 79)); + TestCreateDungeon(2, 1383137027, ENTRY_RTNLVL); + EXPECT_EQ(ViewPosition, Point(49, 89)); } TEST(Drlg_l1, CreateL5Dungeon_diablo_3_844660068) @@ -180,8 +182,8 @@ TEST(Drlg_l1, CreateL5Dungeon_crypt_1_2122696790) { LoadExpectedLevelData("hellfire/21-2122696790.dun"); - TestCreateDungeon(21, 2122696790, ENTRY_TWARPUP); - EXPECT_EQ(ViewPosition, Point(61, 80)); + TestCreateDungeon(21, 2122696790, ENTRY_TWARPDN); + EXPECT_EQ(ViewPosition, Point(61, 81)); TestCreateDungeon(21, 2122696790, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(53, 67)); } diff --git a/test/drlg_l2_test.cpp b/test/drlg_l2_test.cpp index 0b7585ff6..68d8ccca6 100644 --- a/test/drlg_l2_test.cpp +++ b/test/drlg_l2_test.cpp @@ -20,7 +20,7 @@ TEST(Drlg_l2, CreateL2Dungeon_diablo_5_1677631846) EXPECT_EQ(ViewPosition, Point(27, 28)); TestCreateDungeon(5, 1677631846, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(26, 62)); - TestCreateDungeon(5, 1677631846, ENTRY_TWARPUP); + TestCreateDungeon(5, 1677631846, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(33, 56)); } @@ -35,7 +35,7 @@ TEST(Drlg_l2, CreateL2Dungeon_diablo_5_68685319) EXPECT_EQ(ViewPosition, Point(37, 36)); TestCreateDungeon(5, 68685319, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(44, 28)); - TestCreateDungeon(5, 68685319, ENTRY_TWARPUP); + TestCreateDungeon(5, 68685319, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(45, 76)); } diff --git a/test/drlg_l3_test.cpp b/test/drlg_l3_test.cpp index 607ba511a..db2b2e505 100644 --- a/test/drlg_l3_test.cpp +++ b/test/drlg_l3_test.cpp @@ -17,7 +17,7 @@ TEST(Drlg_l3, CreateL3Dungeon_diablo_9_262005438) EXPECT_EQ(ViewPosition, Point(41, 73)); TestCreateDungeon(9, 262005438, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(73, 59)); - TestCreateDungeon(9, 262005438, ENTRY_TWARPUP); + TestCreateDungeon(9, 262005438, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(37, 35)); } @@ -70,7 +70,7 @@ TEST(Drlg_l3, CreateL3Dungeon_hive_1_19770182) { LoadExpectedLevelData("hellfire/17-19770182.dun"); - TestCreateDungeon(17, 19770182, ENTRY_TWARPUP); + TestCreateDungeon(17, 19770182, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(75, 81)); TestCreateDungeon(17, 19770182, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(59, 41)); diff --git a/test/drlg_l4_test.cpp b/test/drlg_l4_test.cpp index b3aed55e0..1615d8ec4 100644 --- a/test/drlg_l4_test.cpp +++ b/test/drlg_l4_test.cpp @@ -21,7 +21,7 @@ TEST(Drlg_l4, CreateL4Dungeon_diablo_13_428074402) EXPECT_EQ(ViewPosition, Point(26, 64)); TestCreateDungeon(13, 428074402, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(47, 79)); - TestCreateDungeon(13, 428074402, ENTRY_TWARPUP); + TestCreateDungeon(13, 428074402, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(26, 44)); } @@ -36,7 +36,7 @@ TEST(Drlg_l4, CreateL4Dungeon_diablo_13_594689775) EXPECT_EQ(ViewPosition, Point(72, 38)); TestCreateDungeon(13, 594689775, ENTRY_PREV); EXPECT_EQ(ViewPosition, Point(32, 40)); - TestCreateDungeon(13, 594689775, ENTRY_TWARPUP); + TestCreateDungeon(13, 594689775, ENTRY_TWARPDN); EXPECT_EQ(ViewPosition, Point(36, 88)); }