end });
end,
+ -- Twin businesses
+ {
+ mindiff = 4; -- arbitrary
+ contents = function()
+ -- Due to the way room connections work in mklev.c, we must guarantee
+ -- that the "aisle" between the shops touches all four walls of the
+ -- larger room. Thus it has an extra width and height.
+ des.room({ type="themed", w=9, h=5, contents = function()
+ -- There are eight possible placements of the two shops, four of
+ -- which have the vertical aisle in the center.
+ southeast = function() return percent(50) and "south" or "east" end
+ northeast = function() return percent(50) and "north" or "east" end
+ northwest = function() return percent(50) and "north" or "west" end
+ southwest = function() return percent(50) and "south" or "west" end
+ placements = {
+ { lx = 1, ly = 1, rx = 4, ry = 1, lwall = "south", rwall = southeast() },
+ { lx = 1, ly = 2, rx = 4, ry = 2, lwall = "north", rwall = northeast() },
+ { lx = 1, ly = 1, rx = 5, ry = 1, lwall = southeast(), rwall = southwest() },
+ { lx = 1, ly = 1, rx = 5, ry = 2, lwall = southeast(), rwall = northwest() },
+ { lx = 1, ly = 2, rx = 5, ry = 1, lwall = northeast(), rwall = southwest() },
+ { lx = 1, ly = 2, rx = 5, ry = 2, lwall = northeast(), rwall = northwest() },
+ { lx = 2, ly = 1, rx = 5, ry = 1, lwall = southwest(), rwall = "south" },
+ { lx = 2, ly = 2, rx = 5, ry = 2, lwall = northwest(), rwall = "north" }
+ }
+ ltype,rtype = "weapon shop","armor shop"
+ if percent(50) then
+ ltype,rtype = rtype,ltype
+ end
+ shopdoorstate = function()
+ if percent(1) then
+ return "locked"
+ elseif percent(50) then
+ return "closed"
+ else
+ return "open"
+ end
+ end
+ p = placements[d(#placements)]
+ des.room({ type=ltype, x=p["lx"], y=p["ly"], w=3, h=3, filled=1, joined=0,
+ contents = function()
+ des.door({ state=shopdoorstate(), wall=p["lwall"] })
+ end
+ });
+ des.room({ type=rtype, x=p["rx"], y=p["ry"], w=3, h=3, filled=1, joined=0,
+ contents = function()
+ des.door({ state=shopdoorstate(), wall=p["rwall"] })
+ end
+ });
+ end
+ });
+ end
+ },
+
};
function is_eligible(room)
int, int, BOOLEAN_P,
SCHAR_P, BOOLEAN_P, BOOLEAN_P));
static void NDECL(makerooms);
+static boolean FDECL(door_into_nonjoined, (XCHAR_P, XCHAR_P));
static void FDECL(finddpos, (coord *, XCHAR_P, XCHAR_P,
XCHAR_P, XCHAR_P));
static void FDECL(mkinvpos, (XCHAR_P, XCHAR_P, int));
#endif /* LINT */
}
+/* Return TRUE if a door placed at (x, y) which otherwise passes okdoor() checks
+ * would be connecting into an area that was declared as joined = 0.
+ * Checking for this in finddpos() enables us to have rooms with sub-areas (such
+ * as shops) that will never randomly generate unwanted doors in order to
+ * connect them up to other areas.
+ */
+static boolean
+door_into_nonjoined(x, y)
+xchar x, y;
+{
+ xchar tx, ty, diridx;
+
+ for (diridx = 0; diridx <= 6; diridx += 2) {
+ tx = x + xdir[diridx];
+ ty = y + ydir[diridx];
+ if (!isok(tx, ty) || IS_ROCK(levl[tx][ty].typ))
+ continue;
+
+ /* Is this connecting to a room that doesn't want joining? */
+ if (levl[tx][ty].roomno >= ROOMOFFSET &&
+ !g.rooms[levl[tx][ty].roomno - ROOMOFFSET].needjoining) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void
finddpos(cc, xl, yl, xh, yh)
coord *cc;
x = rn1(xh - xl + 1, xl);
y = rn1(yh - yl + 1, yl);
- if (okdoor(x, y))
+ if (okdoor(x, y) && !door_into_nonjoined(x, y))
goto gotit;
for (x = xl; x <= xh; x++)
for (y = yl; y <= yh; y++)
- if (okdoor(x, y))
+ if (okdoor(x, y) && !door_into_nonjoined(x, y))
goto gotit;
for (x = xl; x <= xh; x++)
/* cannot find something reasonable -- strange */
x = xl;
y = yh;
+ impossible("finddpos: couldn't find door pos within (%d,%d,%d,%d)",
+ xl, yl, xh, yh);
gotit:
cc->x = x;
cc->y = y;
int i, trycnt, names_avail;
const char *shname = 0;
struct monst *mtmp;
- int name_wanted;
+ int name_wanted = shk->m_id;
s_level *sptr;
if (nlp == shklight && In_mines(&u.uz)
use ledger_no rather than depth to keep minetown distinct. */
int nseed = (int) ((long) ubirthday / 257L);
- name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5);
+ name_wanted += ledger_no(&u.uz) + (nseed % 13) - (nseed % 5);
if (name_wanted < 0)
name_wanted += (13 + 5);
shk->female = name_wanted & 1;
for (names_avail = 0; nlp[names_avail]; names_avail++)
continue;
+ name_wanted = name_wanted % names_avail;
+
for (trycnt = 0; trycnt < 50; trycnt++) {
if (nlp == shktools) {
shname = shktools[rn2(names_avail)];
continue;
if (strcmp(ESHK(mtmp)->shknam, shname))
continue;
+ name_wanted = names_avail; /* try a random name */
break;
}
if (!mtmp)