Stock all special rooms at the end of level creation

This unifies the two separate special-room-stocking code paths, one in
the standard dungeon generator and one in the special level generator
(neither of which reacted to themed rooms, which is the reason for this
commit) into the end of makelevel(), placing the special room stocking
as the very last step of level creation.

Under the new system, when a regular or special level decides to create
a special room, it sets that room's rtype, but the room is not stocked
until later. It already worked this way for special levels, so the main
difference here is in the normal level generation, where the mkroom
family of functions identifies and marks a room as a special room, but
stops short of filling it. (I suppose perhaps the mkroom, mkzoo, mkshop
family of functions would be better off changing their names to
"pickroom" and so on.)

This also restructures makelevel() itself a bit, but the only real
change is that the paths that call makemaz don't return immediately
afterward; they continue to the special room stocking code. Also, this
code was lifted from fill_special_rooms, which is now not used
anywhere, so it has been deleted.

I don't really like how fill_ordinary_room is in mklev.c and
fill_special_room is in sp_lev.c; they seem like they'd be better off in
mkroom.c, but in the interest of not making unnecessary code changes,
I'll just recommend it.
This commit is contained in:
copperwater
2020-05-22 00:02:51 -04:00
committed by Pasi Kallinen
parent a35cbf3816
commit 3d03a472f6
3 changed files with 91 additions and 99 deletions

View File

@@ -845,94 +845,87 @@ makelevel()
register struct mkroom *croom;
branch *branchp;
int room_threshold;
register s_level *slev = Is_special(&u.uz);
int i;
if (wiz1_level.dlevel == 0)
init_dungeons();
oinit(); /* assign level dependent obj probabilities */
clear_level_structures();
{
register s_level *slev = Is_special(&u.uz);
/* check for special levels */
if (slev && !Is_rogue_level(&u.uz)) {
makemaz(slev->proto);
} else if (g.dungeons[u.uz.dnum].proto[0]) {
makemaz("");
} else if (g.dungeons[u.uz.dnum].fill_lvl[0]) {
makemaz(g.dungeons[u.uz.dnum].fill_lvl);
} else if (In_quest(&u.uz)) {
char fillname[9];
s_level *loc_lev;
/* check for special levels */
if (slev && !Is_rogue_level(&u.uz)) {
makemaz(slev->proto);
return;
} else if (g.dungeons[u.uz.dnum].proto[0]) {
makemaz("");
return;
} else if (g.dungeons[u.uz.dnum].fill_lvl[0]) {
makemaz(g.dungeons[u.uz.dnum].fill_lvl);
return;
} else if (In_quest(&u.uz)) {
char fillname[9];
s_level *loc_lev;
Sprintf(fillname, "%s-loca", g.urole.filecode);
loc_lev = find_level(fillname);
Sprintf(fillname, "%s-loca", g.urole.filecode);
loc_lev = find_level(fillname);
Sprintf(fillname, "%s-fil", g.urole.filecode);
Strcat(fillname,
(u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
makemaz(fillname);
return;
} else if (In_hell(&u.uz)
|| (rn2(5) && u.uz.dnum == medusa_level.dnum
&& depth(&u.uz) > depth(&medusa_level))) {
makemaz("");
return;
}
}
/* otherwise, fall through - it's a "regular" level. */
if (Is_rogue_level(&u.uz)) {
makeroguerooms();
makerogueghost();
} else
makerooms();
sort_rooms();
generate_stairs(); /* up and down stairs */
branchp = Is_branchlev(&u.uz); /* possible dungeon branch */
room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
to allow a random special room */
if (Is_rogue_level(&u.uz))
goto skip0;
makecorridors();
make_niches();
/* make a secret treasure vault, not connected to the rest */
if (do_vault()) {
xchar w, h;
debugpline0("trying to make a vault...");
w = 1;
h = 1;
if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) {
fill_vault:
add_room(g.vault_x, g.vault_y, g.vault_x + w, g.vault_y + h,
TRUE, VAULT, FALSE);
g.level.flags.has_vault = 1;
++room_threshold;
fill_special_room(&g.rooms[g.nroom - 1]);
mk_knox_portal(g.vault_x + w, g.vault_y + h);
if (!g.level.flags.noteleport && !rn2(3))
makevtele();
} else if (rnd_rect() && create_vault()) {
g.vault_x = g.rooms[g.nroom].lx;
g.vault_y = g.rooms[g.nroom].ly;
if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE))
goto fill_vault;
else
g.rooms[g.nroom].hx = -1;
}
}
{
Sprintf(fillname, "%s-fil", g.urole.filecode);
Strcat(fillname,
(u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
makemaz(fillname);
} else if (In_hell(&u.uz)
|| (rn2(5) && u.uz.dnum == medusa_level.dnum
&& depth(&u.uz) > depth(&medusa_level))) {
makemaz("");
} else {
/* otherwise, fall through - it's a "regular" level. */
register int u_depth = depth(&u.uz);
if (Is_rogue_level(&u.uz)) {
makeroguerooms();
makerogueghost();
} else
makerooms();
sort_rooms();
generate_stairs(); /* up and down stairs */
branchp = Is_branchlev(&u.uz); /* possible dungeon branch */
room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
to allow a random special room */
if (Is_rogue_level(&u.uz))
goto skip0;
makecorridors();
make_niches();
/* make a secret treasure vault, not connected to the rest */
if (do_vault()) {
xchar w, h;
debugpline0("trying to make a vault...");
w = 1;
h = 1;
if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) {
fill_vault:
add_room(g.vault_x, g.vault_y, g.vault_x + w, g.vault_y + h,
TRUE, VAULT, FALSE);
g.level.flags.has_vault = 1;
++room_threshold;
fill_special_room(&g.rooms[g.nroom - 1]);
mk_knox_portal(g.vault_x + w, g.vault_y + h);
if (!g.level.flags.noteleport && !rn2(3))
makevtele();
} else if (rnd_rect() && create_vault()) {
g.vault_x = g.rooms[g.nroom].lx;
g.vault_y = g.rooms[g.nroom].ly;
if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE))
goto fill_vault;
else
g.rooms[g.nroom].hx = -1;
}
}
/* make up to 1 special room, with type dependent on depth;
* note that mkroom doesn't guarantee a room gets created, and that this
* step only sets the room's rtype - it doesn't fill it yet. */
if (wizard && nh_getenv("SHOPTYPE"))
mkroom(SHOPBASE);
else if (u_depth > 1 && u_depth < depth(&medusa_level)
@@ -962,15 +955,20 @@ makelevel()
else if (u_depth > 16 && !rn2(8)
&& !(g.mvitals[PM_COCKATRICE].mvflags & G_GONE))
mkroom(COCKNEST);
}
skip0:
/* Place multi-dungeon branch. */
place_branch(branchp, 0, 0);
/* Place multi-dungeon branch. */
place_branch(branchp, 0, 0);
/* for each room: put things inside */
for (croom = g.rooms; croom->hx > 0; croom++) {
fill_ordinary_room(croom);
/* for each room: put things inside */
for (croom = g.rooms; croom->hx > 0; croom++) {
fill_ordinary_room(croom);
}
}
/* Fill all special rooms now, regardless of whether this is a special
* level, proto level, or ordinary level. */
for (i = 0; i < g.nroom; ++i) {
fill_special_room(&g.rooms[i]);
}
}

View File

@@ -199,8 +199,10 @@ gottype:
topologize(sroom);
#endif
/* stock the room with a shopkeeper and artifacts */
stock_room(i, sroom);
/* The shop used to be stocked here, but this no longer happens - all we do
* is set its rtype, and it gets stocked at the end of makelevel() along
* with other special rooms. */
sroom->needfill = FILL_NORMAL;
}
/* pick an unused room, preferably with only one door */
@@ -237,7 +239,9 @@ int type;
if ((sroom = pick_room(FALSE)) != 0) {
sroom->rtype = type;
fill_zoo(sroom);
/* room does not get stocked at this time - it will get stocked at the
* end of makelevel() */
sroom->needfill = FILL_NORMAL;
}
}
@@ -271,6 +275,8 @@ struct mkroom *sroom;
int rmno = (int) ((sroom - g.rooms) + ROOMOFFSET);
coord mm;
/* Note: This doesn't check needfill; it assumes the caller has already done
* that. */
sh = sroom->fdoor;
switch (type) {
case COURT:

View File

@@ -40,7 +40,6 @@ static void NDECL(remove_boundary_syms);
static void FDECL(set_door_orientation, (int, int));
static void FDECL(maybe_add_door, (int, int, struct mkroom *));
static void NDECL(link_doors_rooms);
static void NDECL(fill_special_rooms);
static int NDECL(rnddoor);
static int NDECL(rndtrap);
static void FDECL(get_location, (schar *, schar *, int, struct mkroom *));
@@ -1035,16 +1034,6 @@ link_doors_rooms()
}
}
static void
fill_special_rooms()
{
int tmpi, m;
for (tmpi = 0; tmpi < g.nroom; tmpi++) {
fill_special_room(&g.rooms[tmpi]);
}
}
/*
* Choose randomly the state (nodoor, open, closed or locked) for a door
*/
@@ -6426,7 +6415,6 @@ const char *name;
goto give_up;
link_doors_rooms();
fill_special_rooms();
remove_boundary_syms();
/* TODO: ensure_way_out() needs rewrite */