From ad4c71fab392dff52ef896592afcc86503f129f6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 13 Apr 2023 18:35:24 +0300 Subject: [PATCH] Avoid placing random niches into subroom walls Wizmode testing shop generation, I encountered impossible "Where is shopdoor" - the room that was being turned into a shop had a subroom sharing the outer south wall with the parent room, with a random niche placed such that it was actually in the subroom wall. The niche door was still added to the parent room, and the shop generation was trying to use that door as the shop entrance. As random niches are only used in room-and-corridor style levels, subrooms aren't that common, so I just opted to skip the niche generation if it was going to be placed without being directly attached to the room it wanted. The niche generation could be changed at a later date to actually add the niche door to the correct room instead, if we ever feel it's necessary to have random niches in subrooms. As an interesting side note, I had no idea random niches were only placed in the south or north walls of rooms, never to east or west. --- src/mklev.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/mklev.c b/src/mklev.c index 02eda196d..f5698f7df 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -25,6 +25,7 @@ static boolean bydoor(coordxy, coordxy); static void mktrap_victim(struct trap *); static struct mkroom *find_branch_room(coord *); static struct mkroom *pos_to_room(coordxy, coordxy); +static boolean cardinal_nextto_room(struct mkroom *, coordxy, coordxy); static boolean place_niche(struct mkroom *, coordxy *, coordxy *, coordxy *); static void makeniche(int); static void make_niches(void); @@ -575,6 +576,28 @@ dosdoor(register coordxy x, register coordxy y, struct mkroom *aroom, int type) add_door(x, y, aroom); } +/* is x,y location such that NEWS direction from it is inside aroom, + excluding subrooms */ +static boolean +cardinal_nextto_room(struct mkroom *aroom, coordxy x, coordxy y) +{ + int rmno = (int) ((aroom - gr.rooms) + ROOMOFFSET); + + if (isok(x - 1, y) && !levl[x - 1][y].edge + && (int) levl[x - 1][y].roomno == rmno) + return TRUE; + if (isok(x + 1, y) && !levl[x + 1][y].edge + && (int) levl[x + 1][y].roomno == rmno) + return TRUE; + if (isok(x, y - 1) && !levl[x][y - 1].edge + && (int) levl[x][y - 1].roomno == rmno) + return TRUE; + if (isok(x, y + 1) && !levl[x][y + 1].edge + && (int) levl[x][y + 1].roomno == rmno) + return TRUE; + return FALSE; +} + static boolean place_niche(register struct mkroom *aroom, coordxy *dy, coordxy *xx, coordxy *yy) { @@ -595,7 +618,8 @@ place_niche(register struct mkroom *aroom, coordxy *dy, coordxy *xx, coordxy *yy && levl[*xx][*yy + *dy].typ == STONE) && (isok(*xx, *yy - *dy) && !IS_POOL(levl[*xx][*yy - *dy].typ) - && !IS_FURNITURE(levl[*xx][*yy - *dy].typ))); + && !IS_FURNITURE(levl[*xx][*yy - *dy].typ)) + && cardinal_nextto_room(aroom, *xx, *yy)); } /* there should be one of these per trap, in the same order as trap.h */