From e1ed67a1cf94e943e16801c3f80f203971e73237 Mon Sep 17 00:00:00 2001 From: yk <2272757354@qq.com> Date: Mon, 4 Dec 2023 08:57:47 +0800 Subject: [PATCH] yk --- src/NetHack_3.7/src/extralev.c | 169 +++++++++++++++++++++++---------- 1 file changed, 117 insertions(+), 52 deletions(-) diff --git a/src/NetHack_3.7/src/extralev.c b/src/NetHack_3.7/src/extralev.c index 3d7cd0a..36eec4b 100644 --- a/src/NetHack_3.7/src/extralev.c +++ b/src/NetHack_3.7/src/extralev.c @@ -17,123 +17,178 @@ static void roguejoin(coordxy, coordxy, coordxy, coordxy, int); static void roguecorr(coordxy, coordxy, int); static void miniwalk(coordxy, coordxy); -static -void -roguejoin(coordxy x1, coordxy y1, coordxy x2, coordxy y2, int horiz) +static void roguejoin(coordxy x1, coordxy y1, coordxy x2, coordxy y2, int horiz) { register coordxy x, y, middle; if (horiz) { + // Calculate the midpoint for the horizontal corridor middle = x1 + rn2(x2 - x1 + 1); + // Create the first segment of the corridor along the x-axis for (x = min(x1, middle); x <= max(x1, middle); x++) corr(x, y1); + // Create the vertical segment of the corridor for (y = min(y1, y2); y <= max(y1, y2); y++) corr(middle, y); + // Create the second segment of the corridor along the x-axis for (x = min(middle, x2); x <= max(middle, x2); x++) corr(x, y2); } else { + // Calculate the midpoint for the vertical corridor middle = y1 + rn2(y2 - y1 + 1); + // Create the first segment of the corridor along the y-axis for (y = min(y1, middle); y <= max(y1, middle); y++) corr(x1, y); + // Create the horizontal segment of the corridor for (x = min(x1, x2); x <= max(x1, x2); x++) corr(x, middle); + // Create the second segment of the corridor along the y-axis for (y = min(middle, y2); y <= max(middle, y2); y++) corr(x2, y); } } -static -void -roguecorr(coordxy x, coordxy y, int dir) +static void roguecorr(coordxy x, coordxy y, int dir) { register coordxy fromx, fromy, tox, toy; if (dir == XL_DOWN) { + // Disable the down door in the current room gr.r[x][y].doortable &= ~XL_DOWN; + if (!gr.r[x][y].real) { + // If the current room is not a real room, calculate the starting coordinates for the virtual room fromx = gr.r[x][y].rlx; fromy = gr.r[x][y].rly; fromx += 1 + 26 * x; fromy += 7 * y; } else { + // If the current room is a real room, calculate the starting coordinates based on the room size and position fromx = gr.r[x][y].rlx + rn2(gr.r[x][y].dx); fromy = gr.r[x][y].rly + gr.r[x][y].dy; fromx += 1 + 26 * x; fromy += 7 * y; + + // Check if there is a wall at the starting coordinates. If not, output an error message. if (!IS_WALL(levl[fromx][fromy].typ)) impossible("down: no wall at %d,%d?", fromx, fromy); + + // Create a door at the starting coordinates and mark it as no door dodoor(fromx, fromy, &gr.rooms[gr.r[x][y].nroom]); levl[fromx][fromy].doormask = D_NODOOR; + fromy++; } + if (y >= 2) { + // If the current row is greater than or equal to 2, output an error message impossible("down door from %d,%d going nowhere?", x, y); return; } + + // Move to the next row y++; + + // Disable the up door in the next room gr.r[x][y].doortable &= ~XL_UP; + if (!gr.r[x][y].real) { + // If the next room is not a real room, calculate the ending coordinates for the virtual room tox = gr.r[x][y].rlx; toy = gr.r[x][y].rly; tox += 1 + 26 * x; toy += 7 * y; } else { + // If the next room is a real room, calculate the ending coordinates based on the room size and position tox = gr.r[x][y].rlx + rn2(gr.r[x][y].dx); toy = gr.r[x][y].rly - 1; tox += 1 + 26 * x; toy += 7 * y; + + // Check if there is a wall at the ending coordinates. If not, output an error message. if (!IS_WALL(levl[tox][toy].typ)) impossible("up: no wall at %d,%d?", tox, toy); + + // Create a door at the ending coordinates and mark it as no door dodoor(tox, toy, &gr.rooms[gr.r[x][y].nroom]); levl[tox][toy].doormask = D_NODOOR; + toy--; } + + // Call the `roguejoin` function to create a corridor connecting the starting and ending coordinates roguejoin(fromx, fromy, tox, toy, FALSE); return; - } else if (dir == XL_RIGHT) { - gr.r[x][y].doortable &= ~XL_RIGHT; - if (!gr.r[x][y].real) { - fromx = gr.r[x][y].rlx; - fromy = gr.r[x][y].rly; - fromx += 1 + 26 * x; - fromy += 7 * y; - } else { - fromx = gr.r[x][y].rlx + gr.r[x][y].dx; - fromy = gr.r[x][y].rly + rn2(gr.r[x][y].dy); - fromx += 1 + 26 * x; - fromy += 7 * y; - if (!IS_WALL(levl[fromx][fromy].typ)) - impossible("down: no wall at %d,%d?", fromx, fromy); - dodoor(fromx, fromy, &gr.rooms[gr.r[x][y].nroom]); - levl[fromx][fromy].doormask = D_NODOOR; - fromx++; - } - if (x >= 2) { - impossible("right door from %d,%d going nowhere?", x, y); - return; - } - x++; - gr.r[x][y].doortable &= ~XL_LEFT; - if (!gr.r[x][y].real) { - tox = gr.r[x][y].rlx; - toy = gr.r[x][y].rly; - tox += 1 + 26 * x; - toy += 7 * y; - } else { - tox = gr.r[x][y].rlx - 1; - toy = gr.r[x][y].rly + rn2(gr.r[x][y].dy); - tox += 1 + 26 * x; - toy += 7 * y; - if (!IS_WALL(levl[tox][toy].typ)) - impossible("left: no wall at %d,%d?", tox, toy); - dodoor(tox, toy, &gr.rooms[gr.r[x][y].nroom]); - levl[tox][toy].doormask = D_NODOOR; - tox--; - } - roguejoin(fromx, fromy, tox, toy, TRUE); - return; - } else - impossible("corridor in direction %d?", dir); + + + } else if (dir == XL_RIGHT) { + // Disable the right door in the current room + gr.r[x][y].doortable &= ~XL_RIGHT; + + if (!gr.r[x][y].real) { + // If the current room is not a real room, calculate the starting coordinates for the virtual room + fromx = gr.r[x][y].rlx; + fromy = gr.r[x][y].rly; + fromx += 1 + 26 * x; + fromy += 7 * y; + } else { + // If the current room is a real room, calculate the starting coordinates based on the room size and position + fromx = gr.r[x][y].rlx + gr.r[x][y].dx; + fromy = gr.r[x][y].rly + rn2(gr.r[x][y].dy); + fromx += 1 + 26 * x; + fromy += 7 * y; + + // Check if there is a wall at the starting coordinates. If not, output an error message. + if (!IS_WALL(levl[fromx][fromy].typ)) + impossible("down: no wall at %d,%d?", fromx, fromy); + + // Create a door at the starting coordinates and mark it as no door + dodoor(fromx, fromy, &gr.rooms[gr.r[x][y].nroom]); + levl[fromx][fromy].doormask = D_NODOOR; + + fromx++; + } + + if (x >= 2) { + impossible("right door from %d,%d going nowhere?", x, y); + return; + } + + // Move to the next column + x++; + + // Disable the left door in the next room + gr.r[x][y].doortable &= ~XL_LEFT; + + if (!gr.r[x][y].real) { + // If the next room is not a real room, calculate the ending coordinates for the virtual room + tox = gr.r[x][y].rlx; + toy = gr.r[x][y].rly; + tox += 1 + 26 * x; + toy += 7 * y; + } else { + // If the next room is a real room, calculate the ending coordinates based on the room size and position + tox = gr.r[x][y].rlx - 1; + toy = gr.r[x][y].rly + rn2(gr.r[x][y].dy); + tox += 1 + 26 * x; + toy += 7 * y; + + // Check if there is a wall at the ending coordinates. If not, output an error message. + if (!IS_WALL(levl[tox][toy].typ)) + impossible("left: no wall at %d,%d?", tox, toy); + + // Create a door at the ending coordinates and mark it as no door + dodoor(tox, toy, &gr.rooms[gr.r[x][y].nroom]); + levl[tox][toy].doormask = D_NODOOR; + + tox--; + } + + // Call the `roguejoin` function to create a corridor connecting the starting and ending coordinates + roguejoin(fromx, fromy, tox, toy, TRUE); + return; + } else { + impossible("corridor in direction %d?", dir); } /* Modified walkfrom() from mkmaze.c */ @@ -287,9 +342,9 @@ corr(coordxy x, coordxy y) } } -void -makerogueghost(void) +void makerogueghost(void) { + // Declare variables register struct monst *ghost; struct obj *ghostobj; struct mkroom *croom; @@ -297,14 +352,23 @@ makerogueghost(void) if (!gn.nroom) return; /* Should never happen */ + + // Select a random room croom = &gr.rooms[rn2(gn.nroom)]; + + // Select a random coordinate within the room x = somex(croom); y = somey(croom); + + // Create a ghost monster at the selected coordinates if (!(ghost = makemon(&mons[PM_GHOST], x, y, NO_MM_FLAGS))) return; + + // Make the ghost sleep and give it a name ghost->msleeping = 1; ghost = christen_monst(ghost, roguename()); + // Randomly create and place different items near the ghost if (rn2(4)) { ghostobj = mksobj_at(FOOD_RATION, x, y, FALSE, FALSE); ghostobj->quan = (long) rnd(7); @@ -354,4 +418,5 @@ makerogueghost(void) } } + /*extralev.c*/