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 cb4297e61..b8354b3d3 100644 Binary files a/test/fixtures/diablo/5-68685319.dun and b/test/fixtures/diablo/5-68685319.dun differ diff --git a/test/fixtures/diablo/6-1824554527.dun b/test/fixtures/diablo/6-1824554527.dun index b70115cd9..0cfe85987 100644 Binary files a/test/fixtures/diablo/6-1824554527.dun and b/test/fixtures/diablo/6-1824554527.dun differ diff --git a/test/fixtures/diablo/7-1607627156.dun b/test/fixtures/diablo/7-1607627156.dun index f79c22c51..a105745a7 100644 Binary files a/test/fixtures/diablo/7-1607627156.dun and b/test/fixtures/diablo/7-1607627156.dun differ