|
|
|
@ -17,122 +17,177 @@ 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) {
|
|
|
|
|
// 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
|
|
|
|
|
} else {
|
|
|
|
|
impossible("corridor in direction %d?", dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -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*/
|
|
|
|
|