diff --git a/Source/drlg_l1.cpp b/Source/drlg_l1.cpp index 4c24f374b..edc3f06d5 100644 --- a/Source/drlg_l1.cpp +++ b/Source/drlg_l1.cpp @@ -863,6 +863,61 @@ int PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool s return 3; } +void CryptRandomSet(const BYTE *miniset, int rndper) +{ + int sw = miniset[0]; + int sh = miniset[1]; + + for (int sy = 0; sy < DMAXY - sh; sy++) { + for (int sx = 0; sx < DMAXX - 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 (miniset[kk] >= 84 && miniset[kk] <= 100 && found) { + // BUGFIX: accesses to dungeon can go out of bounds (fixed) + // BUGFIX: Comparisons vs 100 should use same tile as comparisons vs 84 - NOT A BUG - "fixing" this breaks crypt + + constexpr auto ComparisonWithBoundsCheck = [](Point p1, Point p2) { + return (p1.x >= 0 && p1.x < DMAXX && p1.y >= 0 && p1.y < DMAXY) && (p2.x >= 0 && p2.x < DMAXX && p2.y >= 0 && p2.y < DMAXY) && (dungeon[p1.x][p1.y] >= 84 && dungeon[p2.x][p2.y] <= 100); + }; + if (ComparisonWithBoundsCheck({ sx - 1, sy }, { sx - 1, sy })) { + found = false; + } + if (ComparisonWithBoundsCheck({ sx + 1, sy }, { sx - 1, sy })) { + found = false; + } + if (ComparisonWithBoundsCheck({ sx, sy + 1 }, { sx - 1, sy })) { + found = false; + } + if (ComparisonWithBoundsCheck({ sx, sy - 1 }, { sx - 1, sy })) { + found = false; + } + } + if (found && GenerateRnd(100) < rndper) { + 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++; + } + } + } + } + } +} + void FillFloor() { for (int j = 0; j < DMAXY; j++) { @@ -879,11 +934,6 @@ void FillFloor() } } -void CathedralPass3() -{ - DRLG_LPass3(22 - 1); -} - void LoadQuestSetPieces() { L5setloadflag = false; @@ -1571,61 +1621,6 @@ void SetCornerRoom(int rx1, int ry1) } } -void CryptRandomSet(const BYTE *miniset, int rndper) -{ - int sw = miniset[0]; - int sh = miniset[1]; - - for (int sy = 0; sy < DMAXY - sh; sy++) { - for (int sx = 0; sx < DMAXX - 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 (miniset[kk] >= 84 && miniset[kk] <= 100 && found) { - // BUGFIX: accesses to dungeon can go out of bounds (fixed) - // BUGFIX: Comparisons vs 100 should use same tile as comparisons vs 84 - NOT A BUG - "fixing" this breaks crypt - - constexpr auto ComparisonWithBoundsCheck = [](Point p1, Point p2) { - return (p1.x >= 0 && p1.x < DMAXX && p1.y >= 0 && p1.y < DMAXY) && (p2.x >= 0 && p2.x < DMAXX && p2.y >= 0 && p2.y < DMAXY) && (dungeon[p1.x][p1.y] >= 84 && dungeon[p2.x][p2.y] <= 100); - }; - if (ComparisonWithBoundsCheck({ sx - 1, sy }, { sx - 1, sy })) { - found = false; - } - if (ComparisonWithBoundsCheck({ sx + 1, sy }, { sx - 1, sy })) { - found = false; - } - if (ComparisonWithBoundsCheck({ sx, sy + 1 }, { sx - 1, sy })) { - found = false; - } - if (ComparisonWithBoundsCheck({ sx, sy - 1 }, { sx - 1, sy })) { - found = false; - } - } - if (found && GenerateRnd(100) < rndper) { - 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++; - } - } - } - } - } -} - void Substitution() { for (int y = 0; y < DMAXY; y++) { @@ -2439,6 +2434,11 @@ void GenerateCathedralLevel(lvl_entry entry) DRLG_CheckQuests(setpc_x, setpc_y); } +void CathedralPass3() +{ + DRLG_LPass3(22 - 1); +} + } // namespace void DRLG_LPass3(int lv) diff --git a/Source/drlg_l2.cpp b/Source/drlg_l2.cpp index dc4e2ba74..be83573da 100644 --- a/Source/drlg_l2.cpp +++ b/Source/drlg_l2.cpp @@ -1610,6 +1610,40 @@ int Patterns[100][10] = { { 0, 0, 0, 0, 255, 0, 0, 0, 0, 0 }, }; +static void DrlgL2Shadows() +{ + uint8_t sd[2][2]; + + for (int y = 1; y < DMAXY; y++) { + for (int x = 1; x < DMAXX; x++) { + sd[0][0] = BSTYPESL2[dungeon[x][y]]; + sd[1][0] = BSTYPESL2[dungeon[x - 1][y]]; + sd[0][1] = BSTYPESL2[dungeon[x][y - 1]]; + sd[1][1] = BSTYPESL2[dungeon[x - 1][y - 1]]; + for (const auto &shadow : SPATSL2) { + if (shadow.strig != sd[0][0]) + continue; + if (shadow.s1 != 0 && shadow.s1 != sd[1][1]) + continue; + if (shadow.s2 != 0 && shadow.s2 != sd[0][1]) + continue; + if (shadow.s3 != 0 && shadow.s3 != sd[1][0]) + continue; + + if (shadow.nv1 != 0) { + dungeon[x - 1][y - 1] = shadow.nv1; + } + if (shadow.nv2 != 0) { + dungeon[x][y - 1] = shadow.nv2; + } + if (shadow.nv3 != 0) { + dungeon[x - 1][y] = shadow.nv3; + } + } + } + } +} + static bool DrlgL2PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview) { int sw = miniset[0]; @@ -1735,86 +1769,6 @@ static void DrlgL2PlaceRndSet(const BYTE *miniset, int rndper) } } -static void DrlgL2Subs() -{ - 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 k = -1; - while (rv >= 0) { - k++; - if (k == sizeof(BTYPESL2)) { - k = 0; - } - if (c == BTYPESL2[k]) { - rv--; - } - } - int j; - for (j = y - 2; j < y + 2; j++) { - for (int i = x - 2; i < x + 2; i++) { - if (dungeon[i][j] == k) { - j = y + 3; - i = x + 2; - } - } - } - if (j < y + 3) { - dungeon[x][y] = k; - } - } - } - } - } -} - -static void DrlgL2Shadows() -{ - uint8_t sd[2][2]; - - for (int y = 1; y < DMAXY; y++) { - for (int x = 1; x < DMAXX; x++) { - sd[0][0] = BSTYPESL2[dungeon[x][y]]; - sd[1][0] = BSTYPESL2[dungeon[x - 1][y]]; - sd[0][1] = BSTYPESL2[dungeon[x][y - 1]]; - sd[1][1] = BSTYPESL2[dungeon[x - 1][y - 1]]; - for (const auto &shadow : SPATSL2) { - if (shadow.strig != sd[0][0]) - continue; - if (shadow.s1 != 0 && shadow.s1 != sd[1][1]) - continue; - if (shadow.s2 != 0 && shadow.s2 != sd[0][1]) - continue; - if (shadow.s3 != 0 && shadow.s3 != sd[1][0]) - continue; - - if (shadow.nv1 != 0) { - dungeon[x - 1][y - 1] = shadow.nv1; - } - if (shadow.nv2 != 0) { - dungeon[x][y - 1] = shadow.nv2; - } - if (shadow.nv3 != 0) { - dungeon[x - 1][y] = shadow.nv3; - } - } - } - } -} - -void InitDungeon() -{ - for (int j = 0; j < DMAXY; j++) { - for (int i = 0; i < DMAXX; i++) { - predungeon[i][j] = 32; - dflags[i][j] = 0; - } - } -} - static void DrlgLoadL2SetPiece() { setloadflag = false; @@ -1838,31 +1792,62 @@ static void DrlgFreeL2SetPiece() pSetPiece = nullptr; } -static void DrlgL2SetRoom(int rx1, int ry1) +static void DrlgInitL2Vals() { - int width = SDL_SwapLE16(pSetPiece[0]); - int height = SDL_SwapLE16(pSetPiece[1]); - - setpc_x = rx1; - setpc_y = ry1; - setpc_w = width; - setpc_h = height; - - uint16_t *tileLayer = &pSetPiece[2]; + int8_t pc; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - uint8_t tileId = SDL_SwapLE16(tileLayer[j * width + i]); - if (tileId != 0) { - dungeon[i + rx1][j + ry1] = tileId; - dflags[i + rx1][j + ry1] |= DLRG_PROTECTED; + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (IsAnyOf(dPiece[i][j], 541, 178, 551)) { + pc = 5; + } else if (IsAnyOf(dPiece[i][j], 542, 553)) { + pc = 6; } else { - dungeon[i + rx1][j + ry1] = 3; + continue; + } + dSpecial[i][j] = pc; + } + } + for (int j = 0; j < MAXDUNY; j++) { + for (int i = 0; i < MAXDUNX; i++) { + if (dPiece[i][j] == 132) { + dSpecial[i][j + 1] = 2; + dSpecial[i][j + 2] = 1; + } else if (dPiece[i][j] == 135 || dPiece[i][j] == 139) { + dSpecial[i + 1][j] = 3; + dSpecial[i + 2][j] = 4; } } } } +void InitDungeon() +{ + for (int j = 0; j < DMAXY; j++) { + for (int i = 0; i < DMAXX; i++) { + predungeon[i][j] = 32; + dflags[i][j] = 0; + } + } +} + +static void DL2DrawRoom(int x1, int y1, int x2, int y2) +{ + for (int jj = y1; jj <= y2; jj++) { + for (int ii = x1; ii <= x2; ii++) { + predungeon[ii][jj] = 46; + } + } + for (int jj = y1; jj <= y2; jj++) { + predungeon[x1][jj] = 35; + predungeon[x2][jj] = 35; + } + for (int ii = x1; ii <= x2; ii++) { + predungeon[ii][y1] = 35; + predungeon[ii][y2] = 35; + } +} + static void DefineRoom(int nX1, int nY1, int nX2, int nY2, bool forceHW) { predungeon[nX1][nY1] = 67; @@ -2312,6 +2297,67 @@ static void L2TileFix() } } +static void DrlgL2Subs() +{ + 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 k = -1; + while (rv >= 0) { + k++; + if (k == sizeof(BTYPESL2)) { + k = 0; + } + if (c == BTYPESL2[k]) { + rv--; + } + } + int j; + for (j = y - 2; j < y + 2; j++) { + for (int i = x - 2; i < x + 2; i++) { + if (dungeon[i][j] == k) { + j = y + 3; + i = x + 2; + } + } + } + if (j < y + 3) { + dungeon[x][y] = k; + } + } + } + } + } +} + +static void DrlgL2SetRoom(int rx1, int ry1) +{ + int width = SDL_SwapLE16(pSetPiece[0]); + int height = SDL_SwapLE16(pSetPiece[1]); + + setpc_x = rx1; + setpc_y = ry1; + setpc_w = width; + setpc_h = height; + + uint16_t *tileLayer = &pSetPiece[2]; + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + uint8_t tileId = SDL_SwapLE16(tileLayer[j * width + i]); + if (tileId != 0) { + dungeon[i + rx1][j + ry1] = tileId; + dflags[i + rx1][j + ry1] |= DLRG_PROTECTED; + } else { + dungeon[i + rx1][j + ry1] = 3; + } + } + } +} + static bool DL2Cont(bool x1f, bool y1f, bool x2f, bool y2f) { if (x1f && x2f && y1f && y2f) { @@ -2341,23 +2387,6 @@ static int DL2NumNoChar() return t; } -static void DL2DrawRoom(int x1, int y1, int x2, int y2) -{ - for (int jj = y1; jj <= y2; jj++) { - for (int ii = x1; ii <= x2; ii++) { - predungeon[ii][jj] = 46; - } - } - for (int jj = y1; jj <= y2; jj++) { - predungeon[x1][jj] = 35; - predungeon[x2][jj] = 35; - } - for (int ii = x1; ii <= x2; ii++) { - predungeon[ii][y1] = 35; - predungeon[ii][y2] = 35; - } -} - static void DL2KnockWalls(int x1, int y1, int x2, int y2) { for (int ii = x1 + 1; ii < x2; ii++) { @@ -2728,7 +2757,7 @@ static bool CreateDungeon() } } - if (!DL2FillVoids()) { + if (!FillVoids()) { return false; } @@ -2741,11 +2770,6 @@ static bool CreateDungeon() return true; } -static void DrlgL2Pass3() -{ - DRLG_LPass3(12 - 1); -} - static void DrlgL2FTransparencyValueR(int i, int j, int x, int y, int d) { if (dTransVal[x][y] != 0 || dungeon[i][j] != 3) { @@ -3118,35 +3142,6 @@ static void DrlgL2(lvl_entry entry) DRLG_CheckQuests(nSx1, nSy1); } -static void DrlgInitL2Vals() -{ - int8_t pc; - - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (IsAnyOf(dPiece[i][j], 541, 178, 551)) { - pc = 5; - } else if (IsAnyOf(dPiece[i][j], 542, 553)) { - pc = 6; - } else { - continue; - } - dSpecial[i][j] = pc; - } - } - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) { - if (dPiece[i][j] == 132) { - dSpecial[i][j + 1] = 2; - dSpecial[i][j + 2] = 1; - } else if (dPiece[i][j] == 135 || dPiece[i][j] == 139) { - dSpecial[i + 1][j] = 3; - dSpecial[i + 2][j] = 4; - } - } - } -} - static void LoadL2DungeonData(const uint16_t *dunData) { InitDungeon(); @@ -3186,6 +3181,11 @@ static void LoadL2DungeonData(const uint16_t *dunData) } } +static void DrlgL2Pass3() +{ + DRLG_LPass3(12 - 1); +} + } // namespace void LoadL2Dungeon(const char *path, int vx, int vy) diff --git a/Source/drlg_l4.cpp b/Source/drlg_l4.cpp index 27532c50f..33871bcba 100644 --- a/Source/drlg_l4.cpp +++ b/Source/drlg_l4.cpp @@ -168,17 +168,86 @@ static void DrlgL4Shadows() } } -static void InitL4Dungeon() +static bool DrlgL4PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview) { - memset(dung, 0, sizeof(dung)); - memset(L4dungeon, 0, sizeof(L4dungeon)); + int sx; + int sy; - for (int j = 0; j < DMAXY; j++) { - for (int i = 0; i < DMAXX; i++) { - dungeon[i][j] = 30; - dflags[i][j] = 0; + int sw = miniset[0]; + int sh = miniset[1]; + + 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 found = false; + int bailcnt; + for (bailcnt = 0; !found && bailcnt < 200; bailcnt++) { + found = true; + if (sx >= SP4x1 && sx <= SP4x2 && sy >= SP4y1 && sy <= SP4y2) { + found = false; + } + if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { + sx = GenerateRnd(DMAXX - sw); + sy = GenerateRnd(DMAXY - sh); + found = false; + } + if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { + sx = GenerateRnd(DMAXX - sw); + sy = GenerateRnd(DMAXY - sh); + found = false; + } + 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++; + } + } + if (!found) { + sx++; + if (sx == DMAXX - sw) { + sx = 0; + sy++; + if (sy == DMAXY - sh) { + sy = 0; + } + } + } + } + if (bailcnt >= 200) { + return false; + } + 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]; + dflags[xx + sx][yy + sy] |= 8; + } + ii++; + } } } + + if (currlevel == 15 && Quests[Q_BETRAYER]._qactive >= QUEST_ACTIVE) { /// Lazarus staff skip bug fixed + Quests[Q_BETRAYER].position = { sx + 1, sy + 1 }; + } + if (setview) { + ViewX = 2 * sx + 21; + ViewY = 2 * sy + 22; + } + + return true; } void DRLG_LoadL4SP() @@ -199,6 +268,19 @@ void DRLG_FreeL4SP() pSetPiece = nullptr; } +static void InitL4Dungeon() +{ + memset(dung, 0, sizeof(dung)); + memset(L4dungeon, 0, sizeof(L4dungeon)); + + for (int j = 0; j < DMAXY; j++) { + for (int i = 0; i < DMAXX; i++) { + dungeon[i][j] = 30; + dflags[i][j] = 0; + } + } +} + void DRLG_L4SetRoom(const uint16_t *dunData, int rx1, int ry1) { int width = SDL_SwapLE16(dunData[0]); @@ -219,6 +301,139 @@ void DRLG_L4SetRoom(const uint16_t *dunData, int rx1, int ry1) } } +static void L4drawRoom(int x, int y, int width, int height) +{ + for (int j = 0; j < height && j + y < 20; j++) { + for (int i = 0; i < width && i + x < 20; i++) { + dung[i + x][j + y] = 1; + } + } +} + +static bool L4checkRoom(int x, int y, int width, int height) +{ + if (x <= 0 || y <= 0) { + return false; + } + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + if (i + x < 0 || i + x >= 20 || j + y < 0 || j + y >= 20) { + return false; + } + if (dung[i + x][j + y] != 0) { + return false; + } + } + } + + return true; +} + +static void L4roomGen(int x, int y, int w, int h, int dir) +{ + bool ran; + int dirProb = GenerateRnd(4); + int num = 0; + + if ((dir == 1 && dirProb == 0) || (dir != 1 && dirProb != 0)) { + int cw; + int ch; + int cx1; + int cy1; + do { + cw = (GenerateRnd(5) + 2) & ~1; + ch = (GenerateRnd(5) + 2) & ~1; + cy1 = h / 2 + y - ch / 2; + cx1 = x - cw; + ran = L4checkRoom(cx1 - 1, cy1 - 1, ch + 2, cw + 1); /// BUGFIX: swap args 3 and 4 ("ch+2" and "cw+1") + num++; + } while (!ran && num < 20); + + if (ran) + L4drawRoom(cx1, cy1, cw, ch); + int cx2 = x + w; + bool ran2 = L4checkRoom(cx2, cy1 - 1, cw + 1, ch + 2); + if (ran2) + L4drawRoom(cx2, cy1, cw, ch); + if (ran) + L4roomGen(cx1, cy1, cw, ch, 1); + if (ran2) + L4roomGen(cx2, cy1, cw, ch, 1); + return; + } + + int width; + int height; + int rx; + int ry; + do { + width = (GenerateRnd(5) + 2) & ~1; + height = (GenerateRnd(5) + 2) & ~1; + rx = w / 2 + x - width / 2; + ry = y - height; + ran = L4checkRoom(rx - 1, ry - 1, width + 2, height + 1); + num++; + } while (!ran && num < 20); + + if (ran) + L4drawRoom(rx, ry, width, height); + int ry2 = y + h; + bool ran2 = L4checkRoom(rx - 1, ry2, width + 2, height + 1); + if (ran2) + L4drawRoom(rx, ry2, width, height); + if (ran) + L4roomGen(rx, ry, width, height, 0); + if (ran2) + L4roomGen(rx, ry2, width, height, 0); +} + +static void L4firstRoom() +{ + int w = 14; + int h = 14; + if (currlevel != 16) { + if (currlevel == Quests[Q_WARLORD]._qlevel && Quests[Q_WARLORD]._qactive != QUEST_NOTAVAIL) { + assert(!gbIsMultiplayer); + w = 11; + h = 11; + } else if (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer) { + w = 11; + h = 11; + } else { + w = GenerateRnd(5) + 2; + h = GenerateRnd(5) + 2; + } + } + + int xmin = (20 - w) / 2; + int xmax = 19 - w; + int x = GenerateRnd(xmax - xmin + 1) + xmin; + + int ymin = (20 - h) / 2; + int ymax = 19 - h; + int y = GenerateRnd(ymax - ymin + 1) + ymin; + + if (currlevel == 16) { + l4holdx = x; + l4holdy = y; + } + if (QuestStatus(Q_WARLORD) || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) { + SP4x1 = x + 1; + SP4y1 = y + 1; + SP4x2 = SP4x1 + w; + SP4y2 = SP4y1 + h; + } else { + SP4x1 = 0; + SP4y1 = 0; + SP4x2 = 0; + SP4y2 = 0; + } + + L4drawRoom(x, y, w, h); + L4roomGen(x, y, w, h, GenerateRnd(2)); +} + void DRLG_L4SetSPRoom(int rx1, int ry1) { setpc_x = rx1; @@ -229,6 +444,50 @@ void DRLG_L4SetSPRoom(int rx1, int ry1) DRLG_L4SetRoom(pSetPiece.get(), rx1, ry1); } +static void L4makeDungeon() +{ + for (int j = 0; j < 20; j++) { + for (int i = 0; i < 20; i++) { + int k = i * 2; + int l = j * 2; + L4dungeon[k][l] = dung[i][j]; + L4dungeon[k][l + 1] = dung[i][j]; + L4dungeon[k + 1][l] = dung[i][j]; + L4dungeon[k + 1][l + 1] = dung[i][j]; + } + } + for (int j = 0; j < 20; j++) { + for (int i = 0; i < 20; i++) { + int k = i * 2; + int l = j * 2; + L4dungeon[k][l + 40] = dung[i][19 - j]; + L4dungeon[k][l + 41] = dung[i][19 - j]; + L4dungeon[k + 1][l + 40] = dung[i][19 - j]; + L4dungeon[k + 1][l + 41] = dung[i][19 - j]; + } + } + for (int j = 0; j < 20; j++) { + for (int i = 0; i < 20; i++) { + int k = i * 2; + int l = j * 2; + L4dungeon[k + 40][l] = dung[19 - i][j]; + L4dungeon[k + 40][l + 1] = dung[19 - i][j]; + L4dungeon[k + 41][l] = dung[19 - i][j]; + L4dungeon[k + 41][l + 1] = dung[19 - i][j]; + } + } + for (int j = 0; j < 20; j++) { + for (int i = 0; i < 20; i++) { + int k = i * 2; + int l = j * 2; + L4dungeon[k + 40][l + 40] = dung[19 - i][19 - j]; + L4dungeon[k + 40][l + 41] = dung[19 - i][19 - j]; + L4dungeon[k + 41][l + 40] = dung[19 - i][19 - j]; + L4dungeon[k + 41][l + 41] = dung[19 - i][19 - j]; + } + } +} + static void L4makeDmt() { int dmty = 1; @@ -739,85 +998,41 @@ static void L4tileFix() } } } - -static void DrlgL4Subs() -{ - for (int y = 0; y < DMAXY; y++) { - for (int x = 0; x < DMAXX; x++) { - int rv = GenerateRnd(3); - if (rv == 0) { - uint8_t c = dungeon[x][y]; - c = L4BTYPES[c]; - if (c != 0 && dflags[x][y] == 0) { - rv = GenerateRnd(16); - int i = -1; - while (rv >= 0) { - i++; - if (i == sizeof(L4BTYPES)) { - i = 0; - } - if (c == L4BTYPES[i]) { - rv--; - } - } - dungeon[x][y] = i; - } - } - } - } - for (int y = 0; y < DMAXY; y++) { - for (int x = 0; x < DMAXX; x++) { - int rv = GenerateRnd(10); - if (rv == 0) { - uint8_t c = dungeon[x][y]; - if (L4BTYPES[c] == 6 && dflags[x][y] == 0) { - dungeon[x][y] = GenerateRnd(3) + 95; - } - } - } - } -} - -static void L4makeDungeon() -{ - for (int j = 0; j < 20; j++) { - for (int i = 0; i < 20; i++) { - int k = i * 2; - int l = j * 2; - L4dungeon[k][l] = dung[i][j]; - L4dungeon[k][l + 1] = dung[i][j]; - L4dungeon[k + 1][l] = dung[i][j]; - L4dungeon[k + 1][l + 1] = dung[i][j]; - } - } - for (int j = 0; j < 20; j++) { - for (int i = 0; i < 20; i++) { - int k = i * 2; - int l = j * 2; - L4dungeon[k][l + 40] = dung[i][19 - j]; - L4dungeon[k][l + 41] = dung[i][19 - j]; - L4dungeon[k + 1][l + 40] = dung[i][19 - j]; - L4dungeon[k + 1][l + 41] = dung[i][19 - j]; - } - } - for (int j = 0; j < 20; j++) { - for (int i = 0; i < 20; i++) { - int k = i * 2; - int l = j * 2; - L4dungeon[k + 40][l] = dung[19 - i][j]; - L4dungeon[k + 40][l + 1] = dung[19 - i][j]; - L4dungeon[k + 41][l] = dung[19 - i][j]; - L4dungeon[k + 41][l + 1] = dung[19 - i][j]; + +static void DrlgL4Subs() +{ + for (int y = 0; y < DMAXY; y++) { + for (int x = 0; x < DMAXX; x++) { + int rv = GenerateRnd(3); + if (rv == 0) { + uint8_t c = dungeon[x][y]; + c = L4BTYPES[c]; + if (c != 0 && dflags[x][y] == 0) { + rv = GenerateRnd(16); + int i = -1; + while (rv >= 0) { + i++; + if (i == sizeof(L4BTYPES)) { + i = 0; + } + if (c == L4BTYPES[i]) { + rv--; + } + } + dungeon[x][y] = i; + } + } } } - for (int j = 0; j < 20; j++) { - for (int i = 0; i < 20; i++) { - int k = i * 2; - int l = j * 2; - L4dungeon[k + 40][l + 40] = dung[19 - i][19 - j]; - L4dungeon[k + 40][l + 41] = dung[19 - i][19 - j]; - L4dungeon[k + 41][l + 40] = dung[19 - i][19 - j]; - L4dungeon[k + 41][l + 41] = dung[19 - i][19 - j]; + for (int y = 0; y < DMAXY; y++) { + for (int x = 0; x < DMAXX; x++) { + int rv = GenerateRnd(10); + if (rv == 0) { + uint8_t c = dungeon[x][y]; + if (L4BTYPES[c] == 6 && dflags[x][y] == 0) { + dungeon[x][y] = GenerateRnd(3) + 95; + } + } } } } @@ -916,139 +1131,6 @@ static int GetArea() return rv; } -static void L4drawRoom(int x, int y, int width, int height) -{ - for (int j = 0; j < height && j + y < 20; j++) { - for (int i = 0; i < width && i + x < 20; i++) { - dung[i + x][j + y] = 1; - } - } -} - -static bool L4checkRoom(int x, int y, int width, int height) -{ - if (x <= 0 || y <= 0) { - return false; - } - - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - if (i + x < 0 || i + x >= 20 || j + y < 0 || j + y >= 20) { - return false; - } - if (dung[i + x][j + y] != 0) { - return false; - } - } - } - - return true; -} - -static void L4roomGen(int x, int y, int w, int h, int dir) -{ - bool ran; - int dirProb = GenerateRnd(4); - int num = 0; - - if ((dir == 1 && dirProb == 0) || (dir != 1 && dirProb != 0)) { - int cw; - int ch; - int cx1; - int cy1; - do { - cw = (GenerateRnd(5) + 2) & ~1; - ch = (GenerateRnd(5) + 2) & ~1; - cy1 = h / 2 + y - ch / 2; - cx1 = x - cw; - ran = L4checkRoom(cx1 - 1, cy1 - 1, ch + 2, cw + 1); /// BUGFIX: swap args 3 and 4 ("ch+2" and "cw+1") - num++; - } while (!ran && num < 20); - - if (ran) - L4drawRoom(cx1, cy1, cw, ch); - int cx2 = x + w; - bool ran2 = L4checkRoom(cx2, cy1 - 1, cw + 1, ch + 2); - if (ran2) - L4drawRoom(cx2, cy1, cw, ch); - if (ran) - L4roomGen(cx1, cy1, cw, ch, 1); - if (ran2) - L4roomGen(cx2, cy1, cw, ch, 1); - return; - } - - int width; - int height; - int rx; - int ry; - do { - width = (GenerateRnd(5) + 2) & ~1; - height = (GenerateRnd(5) + 2) & ~1; - rx = w / 2 + x - width / 2; - ry = y - height; - ran = L4checkRoom(rx - 1, ry - 1, width + 2, height + 1); - num++; - } while (!ran && num < 20); - - if (ran) - L4drawRoom(rx, ry, width, height); - int ry2 = y + h; - bool ran2 = L4checkRoom(rx - 1, ry2, width + 2, height + 1); - if (ran2) - L4drawRoom(rx, ry2, width, height); - if (ran) - L4roomGen(rx, ry, width, height, 0); - if (ran2) - L4roomGen(rx, ry2, width, height, 0); -} - -static void L4firstRoom() -{ - int w = 14; - int h = 14; - if (currlevel != 16) { - if (currlevel == Quests[Q_WARLORD]._qlevel && Quests[Q_WARLORD]._qactive != QUEST_NOTAVAIL) { - assert(!gbIsMultiplayer); - w = 11; - h = 11; - } else if (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer) { - w = 11; - h = 11; - } else { - w = GenerateRnd(5) + 2; - h = GenerateRnd(5) + 2; - } - } - - int xmin = (20 - w) / 2; - int xmax = 19 - w; - int x = GenerateRnd(xmax - xmin + 1) + xmin; - - int ymin = (20 - h) / 2; - int ymax = 19 - h; - int y = GenerateRnd(ymax - ymin + 1) + ymin; - - if (currlevel == 16) { - l4holdx = x; - l4holdy = y; - } - if (QuestStatus(Q_WARLORD) || (currlevel == Quests[Q_BETRAYER]._qlevel && gbIsMultiplayer)) { - SP4x1 = x + 1; - SP4y1 = y + 1; - SP4x2 = SP4x1 + w; - SP4y2 = SP4y1 + h; - } else { - SP4x1 = 0; - SP4y1 = 0; - SP4x2 = 0; - SP4y2 = 0; - } - - L4drawRoom(x, y, w, h); - L4roomGen(x, y, w, h, GenerateRnd(2)); -} - void L4SaveQuads() { int x = l4holdx; @@ -1092,88 +1174,6 @@ void DRLG_LoadDiabQuads(bool preflag) } } -static bool DrlgL4PlaceMiniSet(const BYTE *miniset, int tmin, int tmax, int cx, int cy, bool setview) -{ - int sx; - int sy; - - int sw = miniset[0]; - int sh = miniset[1]; - - 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 found = false; - int bailcnt; - for (bailcnt = 0; !found && bailcnt < 200; bailcnt++) { - found = true; - if (sx >= SP4x1 && sx <= SP4x2 && sy >= SP4y1 && sy <= SP4y2) { - found = false; - } - if (cx != -1 && sx >= cx - sw && sx <= cx + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - found = false; - } - if (cy != -1 && sy >= cy - sh && sy <= cy + 12) { - sx = GenerateRnd(DMAXX - sw); - sy = GenerateRnd(DMAXY - sh); - found = false; - } - 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++; - } - } - if (!found) { - sx++; - if (sx == DMAXX - sw) { - sx = 0; - sy++; - if (sy == DMAXY - sh) { - sy = 0; - } - } - } - } - if (bailcnt >= 200) { - return false; - } - 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]; - dflags[xx + sx][yy + sy] |= 8; - } - ii++; - } - } - } - - if (currlevel == 15 && Quests[Q_BETRAYER]._qactive >= QUEST_ACTIVE) { /// Lazarus staff skip bug fixed - Quests[Q_BETRAYER].position = { sx + 1, sy + 1 }; - } - if (setview) { - ViewX = 2 * sx + 21; - ViewY = 2 * sy + 22; - } - - return true; -} - #if defined(__3DS__) #pragma GCC push_options #pragma GCC optimize("O0")