From 6962fcd63ebe69b8843bb5b91c6dd74f67cca03c Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Tue, 7 Jun 2022 00:48:08 +0200 Subject: [PATCH] Clean up PlaceMiniSet() --- Source/drlg_l1.cpp | 118 ++++++++++---------- Source/drlg_l2.cpp | 152 ++++++++++---------------- Source/drlg_l3.cpp | 102 +++++++---------- Source/drlg_l4.cpp | 121 ++++++++------------ Source/gendung.cpp | 2 + Source/gendung.h | 2 + Source/quests.cpp | 60 +++++----- Source/quests.h | 2 +- test/fixtures/diablo/5-68685319.dun | Bin 54404 -> 54404 bytes test/fixtures/diablo/6-1824554527.dun | Bin 54404 -> 54404 bytes test/fixtures/diablo/7-1607627156.dun | Bin 54404 -> 54404 bytes 11 files changed, 239 insertions(+), 320 deletions(-) diff --git a/Source/drlg_l1.cpp b/Source/drlg_l1.cpp index 7d9d6a36b..f8b3ddf5a 100644 --- a/Source/drlg_l1.cpp +++ b/Source/drlg_l1.cpp @@ -732,71 +732,68 @@ void ApplyShadowsPatterns() } } -bool PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview) +bool PlaceMiniSet(const BYTE *miniset, bool setview) { - int sx; - int sy; - int sw = miniset[0]; int sh = miniset[1]; + int sx = GenerateRnd(DMAXX - sw) - 1; + int sy = GenerateRnd(DMAXY - sh); - int numt = 1; - if (tmax - tmin != 0) { - numt = GenerateRnd(tmax - tmin) + tmin; - } - - for (int i = 0; i < numt; i++) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - bool abort = false; - int found = 0; + for (int bailcnt = 0;; bailcnt++) { + if (bailcnt > 4000) + return false; - while (!abort) { - abort = true; - if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { - sx++; - abort = false; - } - if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { - sy++; - abort = false; + sx++; + if (sx == DMAXX - sw) { + sx = 0; + sy++; + if (sy == DMAXY - sh) { + sy = 0; } + } - int ii = 2; + if (SetPiecesRoom.Contains({ sx, sy })) { + continue; + } - for (int yy = 0; yy < sh && abort; yy++) { - for (int xx = 0; xx < sw && abort; xx++) { - if (miniset[ii] != 0 && dungeon[xx + sx][sy + yy] != miniset[ii]) - abort = false; - if (Protected[xx + sx][sy + yy]) - abort = false; - ii++; - } - } + // Limit the position of SetPieces for compatibility with Diablo bug + bool valid = true; + if (sx <= 12) { + sx++; + valid = false; + } + if (sy <= 12) { + sy++; + valid = false; + } + if (!valid) { + continue; + } - if (!abort) { - sx++; - if (sx == DMAXX - sw) { - sx = 0; - sy++; - if (sy == DMAXY - sh) { - sy = 0; - } - } - if (++found > 4000) - return false; + int ii = 2; + + bool success = true; + for (int yy = 0; yy < sh && success; yy++) { + for (int xx = 0; xx < sw && success; xx++) { + if (miniset[ii] != 0 && dungeon[xx + sx][sy + yy] != miniset[ii]) + success = false; + if (Protected[xx + sx][sy + yy]) + success = false; + ii++; } } + if (success) + break; + } - int ii = sw * sh + 2; + int ii = sw * sh + 2; - for (int yy = 0; yy < sh; yy++) { - for (int xx = 0; xx < sw; xx++) { - if (miniset[ii] != 0) { - dungeon[xx + sx][sy + yy] = miniset[ii]; - } - ii++; + for (int yy = 0; yy < sh; yy++) { + for (int xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) { + dungeon[xx + sx][sy + yy] = miniset[ii]; } + ii++; } } @@ -2100,21 +2097,21 @@ bool PlaceCathedralStairs(lvl_entry entry) // Place poison water entrance if (Quests[Q_PWATER].IsAvailable()) { - if (!PlaceMiniSet(PWATERIN, 1, 1, 0, 0, entry == ENTRY_RTNLVL)) + if (!PlaceMiniSet(PWATERIN, entry == ENTRY_RTNLVL)) 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)) { + if (!PlaceMiniSet(MyPlayer->pOriginalCathedral ? L5STAIRSUP : STAIRSUP, entry == ENTRY_MAIN)) { if (MyPlayer->pOriginalCathedral) return false; success = false; } // Place stairs down - if (!Quests[Q_LTBANNER].IsAvailable() && !PlaceMiniSet(STAIRSDOWN, 1, 1, 0, 0, entry == ENTRY_PREV)) + if (!Quests[Q_LTBANNER].IsAvailable() && !PlaceMiniSet(STAIRSDOWN, entry == ENTRY_PREV)) success = false; if (entry == ENTRY_PREV) { if (Quests[Q_LTBANNER].IsAvailable()) @@ -2132,14 +2129,14 @@ bool PlaceCryptStairs(lvl_entry entry) // Place stairs up bool enteringFromAbove = entry == ENTRY_MAIN || entry == ENTRY_TWARPDN; - if (!PlaceMiniSet(currlevel != 21 ? L5STAIRSUPHF : L5STAIRSTOWN, 1, 1, 0, 0, enteringFromAbove)) + if (!PlaceMiniSet(currlevel != 21 ? L5STAIRSUPHF : L5STAIRSTOWN, enteringFromAbove)) success = false; if (enteringFromAbove) ViewPosition.y++; // Place stairs down if (currlevel != 24) { - if (!PlaceMiniSet(L5STAIRSDOWN, 1, 1, 0, 0, entry == ENTRY_PREV)) + if (!PlaceMiniSet(L5STAIRSDOWN, entry == ENTRY_PREV)) success = false; if (entry == ENTRY_PREV) ViewPosition.y += 3; @@ -2257,7 +2254,12 @@ void GenerateLevel(lvl_entry entry) } else { Substitution(); ApplyShadowsPatterns(); - PlaceMiniSet(LAMPS, 5, 10, 0, 0, false); + + int numt = GenerateRnd(5) + 5; + for (int i = 0; i < numt; i++) { + PlaceMiniSet(LAMPS, false); + } + FillFloor(); } @@ -2268,7 +2270,7 @@ void GenerateLevel(lvl_entry entry) } DRLG_Init_Globals(); - DRLG_CheckQuests(setpc_x, setpc_y); + DRLG_CheckQuests({ setpc_x, setpc_y }); } void Pass3() diff --git a/Source/drlg_l2.cpp b/Source/drlg_l2.cpp index 2a1d6e4a0..2b5ef698b 100644 --- a/Source/drlg_l2.cpp +++ b/Source/drlg_l2.cpp @@ -23,10 +23,6 @@ BYTE predungeon[DMAXX][DMAXY]; namespace { -int nSx1; -int nSy1; -int nSx2; -int nSy2; int nRoomCnt; ROOMNODE RoomList[81]; std::list HallList; @@ -1645,61 +1641,36 @@ void ApplyShadowsPatterns() } } -bool PlaceMiniSet(const Miniset &miniset, int tmin, int tmax, int cx, int cy, bool setview) +bool PlaceMiniSet(const Miniset &miniset, bool setview) { int sw = miniset.size.width; int sh = miniset.size.height; + int sx = GenerateRnd(DMAXX - sw) - 1; + int sy = GenerateRnd(DMAXY - sh); - int numt = 1; - if (tmax - tmin != 0) { - numt = GenerateRnd(tmax - tmin) + tmin; - } - - int sx = 0; - int sy = 0; - for (int i = 0; i < numt; i++) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - bool abort = false; - int bailcnt; - - for (bailcnt = 0; !abort && bailcnt < 200; bailcnt++) { - abort = true; - if (sx >= nSx1 && sx <= nSx2 && sy >= nSy1 && sy <= nSy2) { - abort = false; - } - if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - - if (abort) - abort = miniset.matches({ sx, sy }); - - if (!abort) { - sx++; - if (sx == DMAXX - sw) { - sx = 0; - sy++; - if (sy == DMAXY - sh) { - sy = 0; - } - } + for (int bailcnt = 0;; bailcnt++) { + if (bailcnt > 198) + return false; + + sx++; + if (sx == DMAXX - sw) { + sx = 0; + sy++; + if (sy == DMAXY - sh) { + sy = 0; } } - if (bailcnt >= 200) { - return false; + + if (SetPiecesRoom.Contains({ sx, sy })) { + continue; } - miniset.place({ sx, sy }); + if (miniset.matches({ sx, sy })) + break; } + miniset.place({ sx, sy }); + if (setview) { ViewPosition = Point { 21, 22 } + Displacement { sx, sy } * 2; } @@ -1714,7 +1685,7 @@ void PlaceMiniSetRandom(const Miniset &miniset, int rndper) for (int sy = 0; sy < DMAXY - sh; sy++) { for (int sx = 0; sx < DMAXX - sw; sx++) { - if (sx >= nSx1 && sx <= nSx2 && sy >= nSy1 && sy <= nSy2) + if (SetPiecesRoom.Contains({ sx, sy })) continue; if (!miniset.matches({ sx, sy })) continue; @@ -1958,10 +1929,7 @@ void CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, bool DefineRoom(nRx1, nRy1, nRx2, nRy2, forceHW); if (forceHW) { - nSx1 = nRx1 + 2; - nSy1 = nRy1 + 2; - nSx2 = nRx2; - nSy2 = nRy2; + SetPiecesRoom = { { nRx1 + 2, nRy1 + 2 }, { nRx2 - nRx1 - 1, nRy2 - nRy1 - 1 } }; } int nRid = nRoomCnt; @@ -2265,46 +2233,49 @@ void Substitution() { for (int y = 0; y < DMAXY; y++) { for (int x = 0; x < DMAXX; x++) { - if ((x < nSx1 || x > nSx2) && (y < nSy1 || y > nSy2) && GenerateRnd(4) == 0) { - uint8_t c = BTYPESL2[dungeon[x][y]]; - if (c != 0) { - int rv = GenerateRnd(16); - int i = -1; - while (rv >= 0) { - i++; - if (i == sizeof(BTYPESL2)) { - i = 0; - } - if (c == BTYPESL2[i]) { - rv--; - } + if (SetPiecesRoom.Contains({ x, y })) + continue; + if (GenerateRnd(4) != 0) + continue; + + uint8_t c = BTYPESL2[dungeon[x][y]]; + if (c != 0) { + int rv = GenerateRnd(16); + int i = -1; + while (rv >= 0) { + i++; + if (i == sizeof(BTYPESL2)) { + i = 0; } + if (c == BTYPESL2[i]) { + rv--; + } + } - int j; - for (j = y - 2; j < y + 2; j++) { - for (int k = x - 2; k < x + 2; k++) { - if (dungeon[k][j] == i) { - j = y + 3; - k = x + 2; - } + int j; + for (j = y - 2; j < y + 2; j++) { + for (int k = x - 2; k < x + 2; k++) { + if (dungeon[k][j] == i) { + j = y + 3; + k = x + 2; } } - if (j < y + 3) { - dungeon[x][y] = i; - } + } + if (j < y + 3) { + dungeon[x][y] = i; } } } } } -void SetRoom(int rx1, int ry1) +void SetRoom(Point position) { int width = SDL_SwapLE16(pSetPiece[0]); int height = SDL_SwapLE16(pSetPiece[1]); - setpc_x = rx1; - setpc_y = ry1; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -2314,10 +2285,10 @@ void SetRoom(int rx1, int ry1) for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); if (tileId != 0) { - dungeon[rx1 + i][ry1 + j] = tileId; - Protected[rx1 + i][ry1 + j] = true; + dungeon[position.x + i][position.y + j] = tileId; + Protected[position.x + i][position.y + j] = true; } else { - dungeon[rx1 + i][ry1 + j] = 3; + dungeon[position.x + i][position.y + j] = 3; } } } @@ -2867,20 +2838,20 @@ void FixDoors() bool PlaceStairs(lvl_entry entry) { // Place stairs up - if (!PlaceMiniSet(USTAIRS, 1, 1, -1, -1, entry == ENTRY_MAIN)) + if (!PlaceMiniSet(USTAIRS, 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)) + if (!PlaceMiniSet(DSTAIRS, 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)) + if (!PlaceMiniSet(WARPSTAIRS, entry == ENTRY_TWARPDN)) return false; if (entry == ENTRY_TWARPDN) ViewPosition.y -= 2; @@ -2900,7 +2871,7 @@ void GenerateLevel(lvl_entry entry) } FixTilesPatterns(); if (setloadflag) { - SetRoom(nSx1, nSy1); + SetRoom(SetPiecesRoom.position); } FloodTransparencyValues(3); FixTransparency(); @@ -3031,7 +3002,7 @@ void GenerateLevel(lvl_entry entry) } DRLG_Init_Globals(); - DRLG_CheckQuests(nSx1, nSy1); + DRLG_CheckQuests(SetPiecesRoom.position); } void LoadDungeonData(const uint16_t *dunData) @@ -3113,11 +3084,6 @@ void LoadPreL2Dungeon(const char *path) void CreateL2Dungeon(uint32_t rseed, lvl_entry entry) { - nSx1 = -1; - nSy1 = -1; - nSx2 = -1; - nSy2 = -1; - SetRndSeed(rseed); dminPosition = { 16, 16 }; diff --git a/Source/drlg_l3.cpp b/Source/drlg_l3.cpp index 46fa5dd2f..d877c3438 100644 --- a/Source/drlg_l3.cpp +++ b/Source/drlg_l3.cpp @@ -1674,73 +1674,55 @@ void PoolFix() } } -bool PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview) +bool PlaceMiniSet(const BYTE *miniset, bool setview) { int sw = miniset[0]; int sh = miniset[1]; + int sx = GenerateRnd(DMAXX - sw) - 1; + int sy = GenerateRnd(DMAXY - sh); - int numt = 1; - if (tmax - tmin != 0) { - numt = GenerateRnd(tmax - tmin) + tmin; - } - - int sx = 0; - int sy = 0; - for (int i = 0; i < numt; i++) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - bool abort = false; - int bailcnt; - - for (bailcnt = 0; !abort && bailcnt < 200;) { - bailcnt++; - abort = true; - if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - int ii = 2; - - for (int yy = 0; yy < sh && abort; yy++) { - for (int xx = 0; xx < sw && abort; xx++) { - if (miniset[ii] != 0 && dungeon[xx + sx][yy + sy] != miniset[ii]) - abort = false; - if (Protected[xx + sx][yy + sy]) - abort = false; - ii++; - } - } + for (int bailcnt = 0;; bailcnt++) { + if (bailcnt > 198) + return false; - if (!abort) { - sx++; - if (sx == DMAXX - sw) { - sx = 0; - sy++; - if (sy == DMAXY - sh) { - sy = 0; - } - } + sx++; + if (sx == DMAXX - sw) { + sx = 0; + sy++; + if (sy == DMAXY - sh) { + sy = 0; } } - if (bailcnt >= 200) { - return false; + + if (SetPiecesRoom.Contains({ sx, sy })) { + continue; } - int ii = sw * sh + 2; - for (int yy = 0; yy < sh; yy++) { - for (int xx = 0; xx < sw; xx++) { - if (miniset[ii] != 0) { - dungeon[xx + sx][yy + sy] = miniset[ii]; - } + int ii = 2; + + bool success = true; + for (int yy = 0; yy < sh && success; yy++) { + for (int xx = 0; xx < sw && success; xx++) { + if (miniset[ii] != 0 && dungeon[xx + sx][sy + yy] != miniset[ii]) + success = false; + if (Protected[xx + sx][sy + yy]) + success = false; ii++; } } + if (success) + break; + } + + int ii = sw * sh + 2; + + for (int yy = 0; yy < sh; yy++) { + for (int xx = 0; xx < sw; xx++) { + if (miniset[ii] != 0) { + dungeon[xx + sx][sy + yy] = miniset[ii]; + } + ii++; + } } if (setview) { @@ -2242,17 +2224,17 @@ bool Lockout() bool PlaceCaveStairs(lvl_entry entry) { // Place stairs up - if (!PlaceMiniSet(L3UP, 1, 1, -1, -1, entry == ENTRY_MAIN)) + if (!PlaceMiniSet(L3UP, entry == ENTRY_MAIN)) return false; // Place stairs down - if (!PlaceMiniSet(L3DOWN, 1, 1, -1, -1, entry == ENTRY_PREV)) + if (!PlaceMiniSet(L3DOWN, 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)) + if (currlevel == 9 && !PlaceMiniSet(L3HOLDWARP, entry == ENTRY_TWARPDN)) return false; return true; @@ -2261,12 +2243,12 @@ bool PlaceCaveStairs(lvl_entry entry) bool PlaceNestStairs(lvl_entry entry) { // Place stairs up - if (!PlaceMiniSet(currlevel != 17 ? L6UP : L6HOLDWARP, 1, 1, -1, -1, entry == ENTRY_MAIN || entry == ENTRY_TWARPDN)) + if (!PlaceMiniSet(currlevel != 17 ? L6UP : L6HOLDWARP, entry == ENTRY_MAIN || entry == ENTRY_TWARPDN)) return false; // Place stairs down if (currlevel != 20) { - if (!PlaceMiniSet(L6DOWN, 1, 1, -1, -1, entry == ENTRY_PREV)) + if (!PlaceMiniSet(L6DOWN, entry == ENTRY_PREV)) return false; if (entry == ENTRY_PREV) ViewPosition += { 2, -2 }; diff --git a/Source/drlg_l4.cpp b/Source/drlg_l4.cpp index 4d18ff8cf..bd03f6e12 100644 --- a/Source/drlg_l4.cpp +++ b/Source/drlg_l4.cpp @@ -28,10 +28,6 @@ namespace { bool hallok[20]; int l4holdx; int l4holdy; -int SP4x1; -int SP4y1; -int SP4x2; -int SP4y2; BYTE L4dungeon[80][80]; BYTE dung[20][20]; // int dword_52A4DC; @@ -168,61 +164,36 @@ void ApplyShadowsPatterns() } } -bool PlaceMiniSet(const Miniset &miniset, int tmin, int tmax, int cx, int cy, bool setview) +bool PlaceMiniSet(const Miniset &miniset, bool setview) { - int sx; - int sy; - int sw = miniset.size.width; int sh = miniset.size.height; + int sx = GenerateRnd(DMAXX - sw) - 1; + int sy = GenerateRnd(DMAXY - sh); - int numt = 1; - if (tmax - tmin != 0) { - numt = GenerateRnd(tmax - tmin) + tmin; - } - - for (int i = 0; i < numt; i++) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - bool abort = false; - int bailcnt; - for (bailcnt = 0; !abort && bailcnt < 200; bailcnt++) { - abort = true; - if (sx >= SP4x1 && sx <= SP4x2 && sy >= SP4y1 && sy <= SP4y2) { - abort = false; - } - if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - abort = false; - } - - if (abort) - abort = miniset.matches({ sx, sy }); + for (int bailcnt = 0;; bailcnt++) { + if (bailcnt > 198) + return false; - if (!abort) { - sx++; - if (sx == DMAXX - sw) { - sx = 0; - sy++; - if (sy == DMAXY - sh) { - sy = 0; - } - } + sx++; + if (sx == DMAXX - sw) { + sx = 0; + sy++; + if (sy == DMAXY - sh) { + sy = 0; } } - if (bailcnt >= 200) { - return false; + + if (SetPiecesRoom.Contains({ sx, sy })) { + continue; } - miniset.place({ sx, sy }, true); + if (miniset.matches({ sx, sy })) + break; } + miniset.place({ sx, sy }, true); + if (currlevel == 15 && Quests[Q_BETRAYER]._qactive >= QUEST_ACTIVE) { /// Lazarus staff skip bug fixed Quests[Q_BETRAYER].position = { sx + 1, sy + 1 }; } @@ -264,7 +235,7 @@ void InitDungeonFlags() } } -void SetRoom(const uint16_t *dunData, int rx1, int ry1) +void SetRoom(const uint16_t *dunData, Point position) { int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); @@ -275,10 +246,10 @@ void SetRoom(const uint16_t *dunData, int rx1, int ry1) for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); if (tileId != 0) { - dungeon[i + rx1][j + ry1] = tileId; - Protected[i + rx1][j + ry1] = true; + dungeon[position.x + i][position.y + j] = tileId; + Protected[position.x + i][position.y + j] = true; } else { - dungeon[i + rx1][j + ry1] = 6; + dungeon[position.x + i][position.y + j] = 6; } } } @@ -402,29 +373,23 @@ void FirstRoom() l4holdy = y; } if (Quests[Q_WARLORD].IsAvailable() || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) { - SP4x1 = x + 1; - SP4y1 = y + 1; - SP4x2 = SP4x1 + w; - SP4y2 = SP4y1 + h; + SetPiecesRoom = { { x + 1, y + 1 }, { w + 1, h + 1 } }; } else { - SP4x1 = 0; - SP4y1 = 0; - SP4x2 = 0; - SP4y2 = 0; + SetPiecesRoom = {}; } MapRoom(x, y, w, h); GenerateRoom(x, y, w, h, GenerateRnd(2)); } -void SetSetPiecesRoom(int rx1, int ry1) +void SetSetPiecesRoom(Point position) { - setpc_x = rx1; - setpc_y = ry1; + setpc_x = position.x; + setpc_y = position.y; setpc_w = SDL_SwapLE16(pSetPiece[0]); setpc_h = SDL_SwapLE16(pSetPiece[1]); - SetRoom(pSetPiece.get(), rx1, ry1); + SetRoom(pSetPiece.get(), position); } void MakeDungeon() @@ -1145,25 +1110,25 @@ void LoadDiabQuads(bool preflag) auto dunData = LoadFileInMem("Levels\\L4Data\\diab1.DUN"); diabquad1x = 4 + l4holdx; diabquad1y = 4 + l4holdy; - SetRoom(dunData.get(), diabquad1x, diabquad1y); + SetRoom(dunData.get(), { diabquad1x, diabquad1y }); } { auto dunData = LoadFileInMem(preflag ? "Levels\\L4Data\\diab2b.DUN" : "Levels\\L4Data\\diab2a.DUN"); diabquad2x = 27 - l4holdx; diabquad2y = 1 + l4holdy; - SetRoom(dunData.get(), diabquad2x, diabquad2y); + SetRoom(dunData.get(), { diabquad2x, diabquad2y }); } { auto dunData = LoadFileInMem(preflag ? "Levels\\L4Data\\diab3b.DUN" : "Levels\\L4Data\\diab3a.DUN"); diabquad3x = 1 + l4holdx; diabquad3y = 27 - l4holdy; - SetRoom(dunData.get(), diabquad3x, diabquad3y); + SetRoom(dunData.get(), { diabquad3x, diabquad3y }); } { auto dunData = LoadFileInMem(preflag ? "Levels\\L4Data\\diab4b.DUN" : "Levels\\L4Data\\diab4a.DUN"); diabquad4x = 28 - l4holdx; diabquad4y = 28 - l4holdy; - SetRoom(dunData.get(), diabquad4x, diabquad4y); + SetRoom(dunData.get(), { diabquad4x, diabquad4y }); } } @@ -1286,7 +1251,7 @@ void GeneralFix() bool PlaceStairs(lvl_entry entry) { // Place stairs up - if (!PlaceMiniSet(L4USTAIRS, 1, 1, -1, -1, entry == ENTRY_MAIN)) + if (!PlaceMiniSet(L4USTAIRS, entry == ENTRY_MAIN)) return false; if (entry == ENTRY_MAIN) ViewPosition.x++; @@ -1294,13 +1259,13 @@ bool PlaceStairs(lvl_entry entry) if (currlevel != 15) { // Place stairs down if (currlevel != 16 && !Quests[Q_WARLORD].IsAvailable()) { - if (!PlaceMiniSet(L4DSTAIRS, 1, 1, -1, -1, entry == ENTRY_PREV)) + if (!PlaceMiniSet(L4DSTAIRS, entry == ENTRY_PREV)) return false; } // Place town warp stairs if (currlevel == 13) { - if (!PlaceMiniSet(L4TWARP, 1, 1, -1, -1, entry == ENTRY_TWARPDN)) + if (!PlaceMiniSet(L4TWARP, entry == ENTRY_TWARPDN)) return false; if (entry == ENTRY_TWARPDN) ViewPosition.x++; @@ -1308,7 +1273,7 @@ bool PlaceStairs(lvl_entry entry) } 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)) + if (!PlaceMiniSet(isGateOpen ? L4PENTA2 : L4PENTA, entry == ENTRY_PREV)) return false; } @@ -1346,8 +1311,8 @@ void GenerateLevel(lvl_entry entry) SaveQuads(); } if (Quests[Q_WARLORD].IsAvailable() || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) { - for (int spi = SP4x1; spi < SP4x2; spi++) { - for (int spj = SP4y1; spj < SP4y2; spj++) { + for (int spi = SetPiecesRoom.position.x; spi < SetPiecesRoom.position.x + SetPiecesRoom.size.width - 1; spi++) { + for (int spj = SetPiecesRoom.position.y; spj < SetPiecesRoom.position.y + SetPiecesRoom.size.height - 1; spj++) { Protected[spi][spj] = true; } } @@ -1356,7 +1321,7 @@ void GenerateLevel(lvl_entry entry) FloodTransparencyValues(6); FixTransparency(); if (setloadflag) { - SetSetPiecesRoom(SP4x1, SP4y1); + SetSetPiecesRoom(SetPiecesRoom.position); } if (currlevel == 16) { LoadDiabQuads(true); @@ -1384,7 +1349,7 @@ void GenerateLevel(lvl_entry entry) } } - DRLG_CheckQuests(SP4x1, SP4y1); + DRLG_CheckQuests(SetPiecesRoom.position); if (currlevel == 15) { for (int j = 0; j < DMAXY; j++) { @@ -1442,7 +1407,7 @@ void LoadL4Dungeon(const char *path, int vx, int vy) auto dunData = LoadFileInMem(path); - SetRoom(dunData.get(), 0, 0); + SetRoom(dunData.get(), { 0, 0 }); ViewPosition = { vx, vy }; @@ -1462,7 +1427,7 @@ void LoadPreL4Dungeon(const char *path) auto dunData = LoadFileInMem(path); - SetRoom(dunData.get(), 0, 0); + SetRoom(dunData.get(), { 0, 0 }); } } // namespace devilution diff --git a/Source/gendung.cpp b/Source/gendung.cpp index 099206138..4447dc077 100644 --- a/Source/gendung.cpp +++ b/Source/gendung.cpp @@ -23,6 +23,7 @@ namespace devilution { uint8_t dungeon[DMAXX][DMAXY]; uint8_t pdungeon[DMAXX][DMAXY]; bool Protected[DMAXX][DMAXY]; +Rectangle SetPiecesRoom; int setpc_x; int setpc_y; int setpc_w; @@ -527,6 +528,7 @@ void DRLG_AreaTrans(int num, BYTE *list) void DRLG_InitSetPC() { + SetPiecesRoom = { { -1, -1 }, { -1, -1 } }; setpc_x = 0; setpc_y = 0; setpc_w = 0; diff --git a/Source/gendung.h b/Source/gendung.h index 3c87434d4..b66381b7c 100644 --- a/Source/gendung.h +++ b/Source/gendung.h @@ -11,6 +11,7 @@ #include "engine.h" #include "engine/cel_sprite.hpp" #include "engine/point.hpp" +#include "engine/rectangle.hpp" #include "scrollrt.h" #include "utils/attributes.h" #include "utils/enum_traits.h" @@ -130,6 +131,7 @@ extern DVL_API_FOR_TEST uint8_t dungeon[DMAXX][DMAXY]; extern uint8_t pdungeon[DMAXX][DMAXY]; /** Tile that may not be overwritten by the level generator */ extern bool Protected[DMAXX][DMAXY]; +extern Rectangle SetPiecesRoom; /** Specifies the active set level X-coordinate of the map. */ extern int setpc_x; /** Specifies the active set level Y-coordinate of the map. */ diff --git a/Source/quests.cpp b/Source/quests.cpp index 60c4ee6e4..a5d18b146 100644 --- a/Source/quests.cpp +++ b/Source/quests.cpp @@ -131,20 +131,20 @@ void DrawButcher() DRLG_RectTrans(x + 3, y + 3, x + 10, y + 10); } -void DrawSkelKing(quest_id q, int x, int y) +void DrawSkelKing(quest_id q, Point position) { - Quests[q].position = { 2 * x + 28, 2 * y + 23 }; + Quests[q].position = { 2 * position.x + 28, 2 * position.y + 23 }; } -void DrawWarLord(int x, int y) +void DrawWarLord(Point position) { auto dunData = LoadFileInMem("Levels\\L4Data\\Warlord2.DUN"); int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); - setpc_x = x; - setpc_y = y; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -153,20 +153,20 @@ void DrawWarLord(int x, int y) for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); - dungeon[x + i][y + j] = (tileId != 0) ? tileId : 6; + dungeon[position.x + i][position.y + j] = (tileId != 0) ? tileId : 6; } } } -void DrawSChamber(quest_id q, int x, int y) +void DrawSChamber(quest_id q, Point position) { auto dunData = LoadFileInMem("Levels\\L2Data\\Bonestr1.DUN"); int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); - setpc_x = x; - setpc_y = y; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -175,22 +175,22 @@ void DrawSChamber(quest_id q, int x, int y) for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); - dungeon[x + i][y + j] = (tileId != 0) ? tileId : 3; + dungeon[position.x + i][position.y + j] = (tileId != 0) ? tileId : 3; } } - Quests[q].position = { 2 * x + 22, 2 * y + 23 }; + Quests[q].position = { 2 * position.x + 22, 2 * position.y + 23 }; } -void DrawLTBanner(int x, int y) +void DrawLTBanner(Point position) { auto dunData = LoadFileInMem("Levels\\L1Data\\Banner1.DUN"); int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); - setpc_x = x; - setpc_y = y; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -200,21 +200,21 @@ void DrawLTBanner(int x, int y) for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); if (tileId != 0) { - pdungeon[x + i][y + j] = tileId; + pdungeon[position.x + i][position.y + j] = tileId; } } } } -void DrawBlind(int x, int y) +void DrawBlind(Point position) { auto dunData = LoadFileInMem("Levels\\L2Data\\Blind1.DUN"); int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); - setpc_x = x; - setpc_y = y; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -224,21 +224,21 @@ void DrawBlind(int x, int y) for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); if (tileId != 0) { - pdungeon[x + i][y + j] = tileId; + pdungeon[position.x + i][position.y + j] = tileId; } } } } -void DrawBlood(int x, int y) +void DrawBlood(Point position) { auto dunData = LoadFileInMem("Levels\\L2Data\\Blood2.DUN"); int width = SDL_SwapLE16(dunData[0]); int height = SDL_SwapLE16(dunData[1]); - setpc_x = x; - setpc_y = y; + setpc_x = position.x; + setpc_y = position.y; setpc_w = width; setpc_h = height; @@ -248,7 +248,7 @@ void DrawBlood(int x, int y) for (int i = 0; i < width; i++) { auto tileId = static_cast(SDL_SwapLE16(tileLayer[j * width + i])); if (tileId != 0) { - dungeon[x + i][y + j] = tileId; + dungeon[position.x + i][position.y + j] = tileId; } } } @@ -522,7 +522,7 @@ void CheckQuestKill(const Monster &monster, bool sendmsg) } } -void DRLG_CheckQuests(int x, int y) +void DRLG_CheckQuests(Point position) { for (auto &quest : Quests) { if (quest.IsAvailable()) { @@ -531,22 +531,22 @@ void DRLG_CheckQuests(int x, int y) DrawButcher(); break; case Q_LTBANNER: - DrawLTBanner(x, y); + DrawLTBanner(position); break; case Q_BLIND: - DrawBlind(x, y); + DrawBlind(position); break; case Q_BLOOD: - DrawBlood(x, y); + DrawBlood(position); break; case Q_WARLORD: - DrawWarLord(x, y); + DrawWarLord(position); break; case Q_SKELKING: - DrawSkelKing(quest._qidx, x, y); + DrawSkelKing(quest._qidx, position); break; case Q_SCHAMB: - DrawSChamber(quest._qidx, x, y); + DrawSChamber(quest._qidx, position); break; default: break; diff --git a/Source/quests.h b/Source/quests.h index b70916670..ffcdb8355 100644 --- a/Source/quests.h +++ b/Source/quests.h @@ -91,7 +91,7 @@ void InitialiseQuestPools(uint32_t seed, Quest quests[]); void CheckQuests(); bool ForceQuests(); void CheckQuestKill(const Monster &monster, bool sendmsg); -void DRLG_CheckQuests(int x, int y); +void DRLG_CheckQuests(Point position); void SetReturnLvlPos(); void GetReturnLvlPos(); void LoadPWaterPalette(); diff --git a/test/fixtures/diablo/5-68685319.dun b/test/fixtures/diablo/5-68685319.dun index cb4297e614a38f359573a963baabacfeec6b7071..b8354b3d375c281307f51f403991bf58ee6e7c65 100644 GIT binary patch delta 1988 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 diff --git a/test/fixtures/diablo/7-1607627156.dun b/test/fixtures/diablo/7-1607627156.dun index f79c22c51aa148be4a827c9a58387812b3c3c905..a105745a778625446abe16a826bf3da7b6cf14a3 100644 GIT binary patch delta 1790 zcmaJ6h3d>o8LYNKQk0c86a&D$3ZBgFt$yDBGW>l@;l5h?F0;|1IG{zgfZ$7l$qDT$d&MB*$&#&PlpL(~|AuRoh`+Ry}zpH>qHh z_0_*g<8+i>1_QzG2f70;$xG0f1+Zo@Qt1-cE7ivb5mifdh?KY;0;Zg&MP#D5LC^F{ z9kGv@T!#0#LYH^bV(3JrN&FY+LyA!YtxyjvQp8+hS7}Asc&a{9I`|WIr_$-mG4xF`l*`a<`$DOaW;X#dGwo0isbo1)(VjeqygL zwi)R*+=mpL#kdn(=%_p*H>Q$?Eu=m0nJa?R&b3eSfFrbDHLhtd;w?lBl8^5@Dtt12 znYr2IibOLjWWjD;8}OC63;zxp9<%)`mk*+s`I_*IA`_n zT2$l5{Tja=DdLk!oi9a}V0Nh?3h_u}P9jqghls6s3Z4=pYW;i>bd9HC8;}l8b~!lK zdXe?60;iwk3-LegWn6Vi<3~dt-hSg4d;#o6*seh4^AE|QTvm@d6+bVWX-AouRpy>0 zi%jqt1pM0`LO_zY`T|D&R$qzf%*Szc7bY;g4Bf$<1Nq$BD!Ku$1h}#-gOiKHr)$i_ zAUNp!<$0-BfPL6B-vW$osu!(J{OF_^=5zeGQ|JEHR}ejnt#fCW6zt~Gp?prZo`5Zi zz0>hQAb7C@yxJbNV(#X$`jRpJRK#je5I1oPg;iuOf|Omw3-4sO<${O*9xXu7L$omx zISz!Au+~1uSMG2I*2dgaY*Rt7i=T~ZN)`VxiU$x|glipp8yB_?N-lPtTgO;O5*ZNc zRA6d>61G{&M-I+j3*n{U6<%OK;`}{{w(rye|L% delta 1719 zcmaJ<-%p!W7=BN`ukF|JrD0IYHl-^YBc$V(U#x#)FXJYY!tl;x+kC6-uj6StlJOg9hms&Co0jkPFMpzo~RX2;W9p zq@IGvxb`nfM;peva`9(oA8)8g+8x;=(_ylmgcfY+2lFC>Uv#$^P~{8m13pDVP#l&L zDoUs6J(AQWHBc>1)XGoX4W*TuKHvymmhti~&%T3-jyvc$$sGMimRr(eZXwPCp5}7F zAxQyZ7-M$vSDuP8LCV;3j76v9A^zRdb3ior!Y}O?a>usEP|EGzx`DHZb~}y4F`|4G z-C*V_8KY@DR$if++|DRu9Qozjw&Z#7B4qI|-hD;m+pHjeS5(0PD}p~$gVjM|l|;ZlKp8}|&)bc~@alb?={ih>HFbDgRrarIz#W-iM<&<~GpZ9RThAq;|BX=YU z=`9~;J}}h_{C290yHi29EX5Ov5-@A{?@vZ~efkJ&8}=$Elkan4sv4lbTmbo1AI~Nn z9w2M{=8Z3Ko(D87TKvY1fchBoK9o%+8(m;O5(wBKgA=LSFwmI*Gj^BOeX4kKzC=4W zbVW_#>;h_yi$Bls#EPx&9lUYf-gLfQUQ}+V3{{gGN%~${c