]> granicus.if.org Git - nethack/commitdiff
Stock all special rooms at the end of level creation
authorcopperwater <aosdict@gmail.com>
Fri, 22 May 2020 04:02:51 +0000 (00:02 -0400)
committerPasi Kallinen <paxed@alt.org>
Sun, 27 Sep 2020 15:54:15 +0000 (18:54 +0300)
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.

src/mklev.c
src/mkroom.c
src/sp_lev.c

index 670f8760aca5d47dd91f3c437f72cd52a9be1429..8a6e5f4c7d2322e3ff6923912d5acbca810c4b90 100644 (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);
-            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-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. */
+    /* 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;
+
+        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);
+    } 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();
+        if (Is_rogue_level(&u.uz)) {
+            makeroguerooms();
+            makerogueghost();
+        } else
+            makerooms();
+        sort_rooms();
 
-    generate_stairs(); /* up and down stairs */
+        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)) {
+        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;
+                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;
+            }
         }
-    }
-
-    {
-        register int u_depth = depth(&u.uz);
 
+        /* 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]);
     }
 }
 
index 7fb8874fe95e9d16935b825de9a67df06829aecd..b8df0ffa5b81ae1a57004ee024b3c37c6338aa15 100644 (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:
index 39e2e037dfef51c80b00cc1ab760500b61258645..446e782581dd70c742643a1d2b6a685cba82bff5 100755 (executable)
@@ -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 */