1 /* NetHack 3.6 dungeon.c $NHDT-Date: 1554341477 2019/04/04 01:31:17 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.92 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2012. */
4 /* NetHack may be freely redistributed. See license for details. */
11 #define DUNGEON_FILE "dungeon"
13 #define X_START "x-strt"
14 #define X_LOCATE "x-loca"
15 #define X_GOAL "x-goal"
17 struct proto_dungeon {
18 struct tmpdungeon tmpdungeon[MAXDUNGEON];
19 struct tmplevel tmplevel[LEV_LIMIT];
20 s_level *final_lev[LEV_LIMIT]; /* corresponding level pointers */
21 struct tmpbranch tmpbranch[BRANCH_LIMIT];
23 int start; /* starting index of current dungeon sp levels */
24 int n_levs; /* number of tmplevel entries */
25 int n_brs; /* number of tmpbranch entries */
28 int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */
29 static branch *branches = (branch *) 0; /* dungeon branch list */
31 mapseen *mapseenchn = (struct mapseen *) 0; /*DUNGEON_OVERVIEW*/
36 schar playerlev[MAXLINFO];
41 static void FDECL(Fread, (genericptr_t, int, int, dlb *));
42 STATIC_DCL xchar FDECL(dname_to_dnum, (const char *));
43 STATIC_DCL int FDECL(find_branch, (const char *, struct proto_dungeon *));
44 STATIC_DCL xchar FDECL(parent_dnum, (const char *, struct proto_dungeon *));
45 STATIC_DCL int FDECL(level_range, (XCHAR_P, int, int, int,
46 struct proto_dungeon *, int *));
47 STATIC_DCL xchar FDECL(parent_dlevel, (const char *, struct proto_dungeon *));
48 STATIC_DCL int FDECL(correct_branch_type, (struct tmpbranch *));
49 STATIC_DCL branch *FDECL(add_branch, (int, int, struct proto_dungeon *));
50 STATIC_DCL void FDECL(add_level, (s_level *));
51 STATIC_DCL void FDECL(init_level, (int, int, struct proto_dungeon *));
52 STATIC_DCL int FDECL(possible_places, (int, boolean *,
53 struct proto_dungeon *));
54 STATIC_DCL xchar FDECL(pick_level, (boolean *, int));
55 STATIC_DCL boolean FDECL(place_level, (int, struct proto_dungeon *));
56 STATIC_DCL boolean FDECL(unplaced_floater, (struct dungeon *));
57 STATIC_DCL boolean FDECL(unreachable_level, (d_level *, BOOLEAN_P));
58 STATIC_DCL void FDECL(tport_menu, (winid, char *, struct lchoice *, d_level *,
60 STATIC_DCL const char *FDECL(br_string, (int));
61 STATIC_DCL char FDECL(chr_u_on_lvl, (d_level *));
62 STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P,
64 STATIC_DCL mapseen *FDECL(load_mapseen, (int));
65 STATIC_DCL void FDECL(save_mapseen, (int, mapseen *));
66 STATIC_DCL mapseen *FDECL(find_mapseen, (d_level *));
67 STATIC_DCL mapseen *FDECL(find_mapseen_by_str, (const char *));
68 STATIC_DCL void FDECL(print_mapseen, (winid, mapseen *, int, int, BOOLEAN_P));
69 STATIC_DCL boolean FDECL(interest_mapseen, (mapseen *));
70 STATIC_DCL void FDECL(traverse_mapseenchn, (BOOLEAN_P, winid,
72 STATIC_DCL const char *FDECL(seen_string, (XCHAR_P, const char *));
73 STATIC_DCL const char *FDECL(br_string2, (branch *));
74 STATIC_DCL const char *FDECL(shop_string, (int));
75 STATIC_DCL char *FDECL(tunesuffix, (mapseen *, char *));
78 #define DD dungeons[i]
79 STATIC_DCL void NDECL(dumpit);
88 if (!explicitdebug(__FILE__))
91 for (i = 0; i < n_dgns; i++) {
92 fprintf(stderr, "\n#%d \"%s\" (%s):\n", i, DD.dname, DD.proto);
93 fprintf(stderr, " num_dunlevs %d, dunlev_ureached %d\n",
94 DD.num_dunlevs, DD.dunlev_ureached);
95 fprintf(stderr, " depth_start %d, ledger_start %d\n",
96 DD.depth_start, DD.ledger_start);
97 fprintf(stderr, " flags:%s%s%s\n",
98 DD.flags.rogue_like ? " rogue_like" : "",
99 DD.flags.maze_like ? " maze_like" : "",
100 DD.flags.hellish ? " hellish" : "");
103 fprintf(stderr, "\nSpecial levels:\n");
104 for (x = sp_levchn; x; x = x->next) {
105 fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs);
106 fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel);
107 fprintf(stderr, "flags:%s%s%s%s\n",
108 x->flags.rogue_like ? " rogue_like" : "",
109 x->flags.maze_like ? " maze_like" : "",
110 x->flags.hellish ? " hellish" : "",
111 x->flags.town ? " town" : "");
114 fprintf(stderr, "\nBranches:\n");
115 for (br = branches; br; br = br->next) {
116 fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n", br->id,
119 : br->type == BR_NO_END1
121 : br->type == BR_NO_END2
123 : br->type == BR_PORTAL
126 br->end1.dnum, br->end1.dlevel, br->end2.dnum,
127 br->end2.dlevel, br->end1_up ? "end1 up" : "end1 down");
130 fprintf(stderr, "\nDone\n");
135 /* Save the dungeon structures. */
137 save_dungeon(fd, perform_write, free_data)
139 boolean perform_write, free_data;
142 mapseen *curr_ms, *next_ms;
146 bwrite(fd, (genericptr_t) &n_dgns, sizeof n_dgns);
147 bwrite(fd, (genericptr_t) dungeons,
148 sizeof(dungeon) * (unsigned) n_dgns);
149 bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
150 bwrite(fd, (genericptr_t) tune, sizeof tune);
152 for (count = 0, curr = branches; curr; curr = curr->next)
154 bwrite(fd, (genericptr_t) &count, sizeof(count));
156 for (curr = branches; curr; curr = curr->next)
157 bwrite(fd, (genericptr_t) curr, sizeof(branch));
159 count = maxledgerno();
160 bwrite(fd, (genericptr_t) &count, sizeof count);
161 bwrite(fd, (genericptr_t) level_info,
162 (unsigned) count * sizeof(struct linfo));
163 bwrite(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
165 for (count = 0, curr_ms = mapseenchn; curr_ms;
166 curr_ms = curr_ms->next)
168 bwrite(fd, (genericptr_t) &count, sizeof(count));
170 for (curr_ms = mapseenchn; curr_ms; curr_ms = curr_ms->next)
171 save_mapseen(fd, curr_ms);
175 for (curr = branches; curr; curr = next) {
177 free((genericptr_t) curr);
180 for (curr_ms = mapseenchn; curr_ms; curr_ms = next_ms) {
181 next_ms = curr_ms->next;
183 free((genericptr_t) curr_ms->custom);
184 free((genericptr_t) curr_ms);
190 /* Restore the dungeon structures. */
197 mapseen *curr_ms, *last_ms;
199 mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
200 mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned) n_dgns);
201 mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
202 mread(fd, (genericptr_t) tune, sizeof tune);
204 last = branches = (branch *) 0;
206 mread(fd, (genericptr_t) &count, sizeof(count));
207 for (i = 0; i < count; i++) {
208 curr = (branch *) alloc(sizeof(branch));
209 mread(fd, (genericptr_t) curr, sizeof(branch));
210 curr->next = (branch *) 0;
218 mread(fd, (genericptr_t) &count, sizeof(count));
219 if (count >= MAXLINFO)
220 panic("level information count larger (%d) than allocated size",
222 mread(fd, (genericptr_t) level_info,
223 (unsigned) count * sizeof(struct linfo));
224 mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
226 mread(fd, (genericptr_t) &count, sizeof(count));
227 last_ms = (mapseen *) 0;
228 for (i = 0; i < count; i++) {
229 curr_ms = load_mapseen(fd);
230 curr_ms->next = (mapseen *) 0;
232 last_ms->next = curr_ms;
234 mapseenchn = curr_ms;
240 Fread(ptr, size, nitems, stream)
247 if ((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) {
249 "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.",
250 (size * nitems), (size * cnt));
251 nh_terminate(EXIT_FAILURE);
261 for (i = 0; i < n_dgns; i++)
262 if (!strcmp(dungeons[i].dname, s))
265 panic("Couldn't resolve dungeon number for name \"%s\".", s);
275 for (curr = sp_levchn; curr; curr = curr->next)
276 if (!strcmpi(s, curr->proto))
281 /* Find the branch that links the named dungeon. */
284 const char *s; /* dungeon name */
285 struct proto_dungeon *pd;
290 for (i = 0; i < pd->n_brs; i++)
291 if (!strcmp(pd->tmpbranch[i].name, s))
294 panic("find_branch: can't find %s", s);
296 /* support for level tport by name */
300 for (br = branches; br; br = br->next) {
301 dnam = dungeons[br->end2.dnum].dname;
302 if (!strcmpi(dnam, s)
303 || (!strncmpi(dnam, "The ", 4) && !strcmpi(dnam + 4, s)))
306 i = br ? ((ledger_no(&br->end1) << 8) | ledger_no(&br->end2)) : -1;
312 * Find the "parent" by searching the prototype branch list for the branch
313 * listing, then figuring out to which dungeon it belongs.
317 const char *s; /* dungeon name */
318 struct proto_dungeon *pd;
323 i = find_branch(s, pd);
325 * Got branch, now find parent dungeon. Stop if we have reached
326 * "this" dungeon (if we haven't found it by now it is an error).
328 for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++)
329 if ((i -= pd->tmpdungeon[pdnum].branches) < 0)
332 panic("parent_dnum: couldn't resolve branch.");
338 * Return a starting point and number of successive positions a level
339 * or dungeon entrance can occupy.
341 * Note: This follows the acouple (instead of the rcouple) rules for a
342 * negative random component (randc < 0). These rules are found
343 * in dgn_comp.y. The acouple [absolute couple] section says that
344 * a negative random component means from the (adjusted) base to the
345 * end of the dungeon.
348 level_range(dgn, base, randc, chain, pd, adjusted_base)
350 int base, randc, chain;
351 struct proto_dungeon *pd;
354 int lmax = dungeons[dgn].num_dunlevs;
356 if (chain >= 0) { /* relative to a special level */
357 s_level *levtmp = pd->final_lev[chain];
359 panic("level_range: empty chain level!");
361 base += levtmp->dlevel.dlevel;
362 } else { /* absolute in the dungeon */
363 /* from end of dungeon */
365 base = (lmax + base + 1);
368 if (base < 1 || base > lmax)
369 panic("level_range: base value out of range");
371 *adjusted_base = base;
373 if (randc == -1) { /* from base to end of dungeon */
374 return (lmax - base + 1);
376 /* make sure we don't run off the end of the dungeon */
377 return (((base + randc - 1) > lmax) ? lmax - base + 1 : randc);
378 } /* else only one choice */
385 struct proto_dungeon *pd;
387 int i, j, num, base, dnum = parent_dnum(s, pd);
390 i = find_branch(s, pd);
391 num = level_range(dnum, pd->tmpbranch[i].lev.base,
392 pd->tmpbranch[i].lev.rand, pd->tmpbranch[i].chain, pd,
395 /* KMH -- Try our best to find a level without an existing branch */
400 for (curr = branches; curr; curr = curr->next)
401 if ((curr->end1.dnum == dnum && curr->end1.dlevel == base + i)
402 || (curr->end2.dnum == dnum && curr->end2.dlevel == base + i))
404 } while (curr && i != j);
408 /* Convert from the temporary branch type to the dungeon branch type. */
410 correct_branch_type(tbr)
411 struct tmpbranch *tbr;
417 return tbr->up ? BR_NO_END1 : BR_NO_END2;
419 return tbr->up ? BR_NO_END2 : BR_NO_END1;
423 impossible("correct_branch_type: unknown branch type");
428 * Add the given branch to the branch list. The branch list is ordered
429 * by end1 dungeon and level followed by end2 dungeon and level. If
430 * extract_first is true, then the branch is already part of the list
431 * but needs to be repositioned.
434 insert_branch(new_branch, extract_first)
436 boolean extract_first;
439 long new_val, curr_val, prev_val;
442 for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next)
443 if (curr == new_branch)
447 panic("insert_branch: not found");
449 prev->next = curr->next;
451 branches = curr->next;
453 new_branch->next = (branch *) 0;
455 /* Convert the branch into a unique number so we can sort them. */
456 #define branch_val(bp) \
457 ((((long) (bp)->end1.dnum * (MAXLEVEL + 1) + (long) (bp)->end1.dlevel) \
458 * (MAXDUNGEON + 1) * (MAXLEVEL + 1)) \
459 + ((long) (bp)->end2.dnum * (MAXLEVEL + 1) + (long) (bp)->end2.dlevel))
462 * Insert the new branch into the correct place in the branch list.
466 new_val = branch_val(new_branch);
467 for (curr = branches; curr;
468 prev_val = curr_val, prev = curr, curr = curr->next) {
469 curr_val = branch_val(curr);
470 if (prev_val < new_val && new_val <= curr_val)
474 new_branch->next = curr;
475 prev->next = new_branch;
477 new_branch->next = branches;
478 branches = new_branch;
482 /* Add a dungeon branch to the branch list. */
484 add_branch(dgn, child_entry_level, pd)
486 int child_entry_level;
487 struct proto_dungeon *pd;
489 static int branch_id = 0;
493 branch_num = find_branch(dungeons[dgn].dname, pd);
494 new_branch = (branch *) alloc(sizeof(branch));
495 (void) memset((genericptr_t)new_branch, 0, sizeof(branch));
496 new_branch->next = (branch *) 0;
497 new_branch->id = branch_id++;
498 new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]);
499 new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd);
500 new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd);
501 new_branch->end2.dnum = dgn;
502 new_branch->end2.dlevel = child_entry_level;
503 new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE;
505 insert_branch(new_branch, FALSE);
510 * Add new level to special level chain. Insert it in level order with the
511 * other levels in this dungeon. This assumes that we are never given a
512 * level that has a dungeon number less than the dungeon number of the
519 s_level *prev, *curr;
521 prev = (s_level *) 0;
522 for (curr = sp_levchn; curr; curr = curr->next) {
523 if (curr->dlevel.dnum == new_lev->dlevel.dnum
524 && curr->dlevel.dlevel > new_lev->dlevel.dlevel)
529 new_lev->next = sp_levchn;
532 new_lev->next = curr;
533 prev->next = new_lev;
538 init_level(dgn, proto_index, pd)
539 int dgn, proto_index;
540 struct proto_dungeon *pd;
543 struct tmplevel *tlevel = &pd->tmplevel[proto_index];
545 pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */
546 if (!wizard && tlevel->chance <= rn2(100))
549 pd->final_lev[proto_index] = new_level =
550 (s_level *) alloc(sizeof(s_level));
551 (void) memset((genericptr_t)new_level, 0, sizeof(s_level));
552 /* load new level with data */
553 Strcpy(new_level->proto, tlevel->name);
554 new_level->boneid = tlevel->boneschar;
555 new_level->dlevel.dnum = dgn;
556 new_level->dlevel.dlevel = 0; /* for now */
558 new_level->flags.town = !!(tlevel->flags & TOWN);
559 new_level->flags.hellish = !!(tlevel->flags & HELLISH);
560 new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE);
561 new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE);
562 new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4);
563 if (!new_level->flags.align)
564 new_level->flags.align =
565 ((pd->tmpdungeon[dgn].flags & D_ALIGN_MASK) >> 4);
567 new_level->rndlevs = tlevel->rndlevs;
568 new_level->next = (s_level *) 0;
572 possible_places(idx, map, pd)
573 int idx; /* prototype index */
574 boolean *map; /* array MAXLEVEL+1 in length */
575 struct proto_dungeon *pd;
578 s_level *lev = pd->final_lev[idx];
580 /* init level possibilities */
581 for (i = 0; i <= MAXLEVEL; i++)
584 /* get base and range and set those entries to true */
585 count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,
586 pd->tmplevel[idx].lev.rand, pd->tmplevel[idx].chain,
588 for (i = start; i < start + count; i++)
591 /* mark off already placed levels */
592 for (i = pd->start; i < idx; i++) {
593 if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) {
594 map[pd->final_lev[i]->dlevel.dlevel] = FALSE;
602 /* Pick the nth TRUE entry in the given boolean array. */
605 boolean *map; /* an array MAXLEVEL+1 in size */
609 for (i = 1; i <= MAXLEVEL; i++)
610 if (map[i] && !nth--)
612 panic("pick_level: ran out of valid levels");
617 static void FDECL(indent, (int));
629 * Place a level. First, find the possible places on a dungeon map
630 * template. Next pick one. Then try to place the next level. If
631 * successful, we're done. Otherwise, try another (and another) until
632 * all possible places have been tried. If all possible places have
633 * been exhausted, return false.
636 place_level(proto_index, pd)
638 struct proto_dungeon *pd;
640 boolean map[MAXLEVEL + 1]; /* valid levels are 1..MAXLEVEL inclusive */
647 if (proto_index == pd->n_levs)
648 return TRUE; /* at end of proto levels */
650 lev = pd->final_lev[proto_index];
652 /* No level created for this prototype, goto next. */
654 return place_level(proto_index + 1, pd);
656 npossible = possible_places(proto_index, map, pd);
658 for (; npossible; --npossible) {
659 lev->dlevel.dlevel = pick_level(map, rn2(npossible));
661 indent(proto_index - pd->start);
662 fprintf(stderr, "%s: trying %d [ ", lev->proto, lev->dlevel.dlevel);
663 for (i = 1; i <= MAXLEVEL; i++)
665 fprintf(stderr, "%d ", i);
666 fprintf(stderr, "]\n");
668 if (place_level(proto_index + 1, pd))
670 map[lev->dlevel.dlevel] = FALSE; /* this choice didn't work */
673 indent(proto_index - pd->start);
674 fprintf(stderr, "%s: failed\n", lev->proto);
680 const char *lev_name;
682 } level_map[] = { { "air", &air_level },
683 { "asmodeus", &asmodeus_level },
684 { "astral", &astral_level },
685 { "baalz", &baalzebub_level },
686 { "bigrm", &bigroom_level },
687 { "castle", &stronghold_level },
688 { "earth", &earth_level },
689 { "fakewiz1", &portal_level },
690 { "fire", &fire_level },
691 { "juiblex", &juiblex_level },
692 { "knox", &knox_level },
693 { "medusa", &medusa_level },
694 { "oracle", &oracle_level },
695 { "orcus", &orcus_level },
696 { "rogue", &rogue_level },
697 { "sanctum", &sanctum_level },
698 { "valley", &valley_level },
699 { "water", &water_level },
700 { "wizard1", &wiz1_level },
701 { "wizard2", &wiz2_level },
702 { "wizard3", &wiz3_level },
703 { "minend", &mineend_level },
704 { "soko1", &sokoend_level },
705 { X_START, &qstart_level },
706 { X_LOCATE, &qlocate_level },
707 { X_GOAL, &nemesis_level },
708 { "", (d_level *) 0 } };
710 /* initialize the "dungeon" structs */
715 register int i, cl = 0, cb = 0;
717 struct proto_dungeon pd;
718 struct level_map *lev_map;
719 struct version_info vers_info;
721 pd.n_levs = pd.n_brs = 0;
723 dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE);
726 Sprintf(tbuf, "Cannot open dungeon description - \"%s", DUNGEON_FILE);
727 #ifdef DLBRSRC /* using a resource from the executable */
728 Strcat(tbuf, "\" resource!");
729 #else /* using a file or DLB file */
731 Strcat(tbuf, "\" from ");
732 #ifdef PREFIXES_IN_USE
733 Strcat(tbuf, "\n\"");
734 if (fqn_prefix[DATAPREFIX])
735 Strcat(tbuf, fqn_prefix[DATAPREFIX]);
739 Strcat(tbuf, DLBFILE);
741 Strcat(tbuf, "\" file!");
744 interject_assistance(1, INTERJECT_PANIC, (genericptr_t) tbuf,
745 (genericptr_t) fqn_prefix[DATAPREFIX]);
750 /* validate the data's version against the program's version */
751 Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file);
752 /* we'd better clear the screen now, since when error messages come from
753 * check_version() they will be printed using pline(), which doesn't
754 * mix with the raw messages that might be already on the screen
756 if (iflags.window_inited)
757 clear_nhwindow(WIN_MAP);
758 if (!check_version(&vers_info, DUNGEON_FILE, TRUE))
759 panic("Dungeon description not valid.");
762 * Read in each dungeon and transfer the results to the internal
765 sp_levchn = (s_level *) 0;
766 Fread((genericptr_t) &n_dgns, sizeof(int), 1, dgn_file);
767 if (n_dgns >= MAXDUNGEON)
768 panic("init_dungeons: too many dungeons");
770 for (i = 0; i < n_dgns; i++) {
771 Fread((genericptr_t) &pd.tmpdungeon[i], sizeof(struct tmpdungeon), 1,
773 if (!wizard && pd.tmpdungeon[i].chance
774 && (pd.tmpdungeon[i].chance <= rn2(100))) {
777 /* skip over any levels or branches */
778 for (j = 0; j < pd.tmpdungeon[i].levels; j++)
779 Fread((genericptr_t) &pd.tmplevel[cl],
780 sizeof(struct tmplevel), 1, dgn_file);
782 for (j = 0; j < pd.tmpdungeon[i].branches; j++)
783 Fread((genericptr_t) &pd.tmpbranch[cb],
784 sizeof(struct tmpbranch), 1, dgn_file);
790 Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name);
791 Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname);
792 dungeons[i].boneid = pd.tmpdungeon[i].boneschar;
794 if (pd.tmpdungeon[i].lev.rand)
795 dungeons[i].num_dunlevs = (xchar) rn1(pd.tmpdungeon[i].lev.rand,
796 pd.tmpdungeon[i].lev.base);
798 dungeons[i].num_dunlevs = (xchar) pd.tmpdungeon[i].lev.base;
801 dungeons[i].ledger_start = 0;
802 dungeons[i].depth_start = 1;
803 dungeons[i].dunlev_ureached = 1;
805 dungeons[i].ledger_start =
806 dungeons[i - 1].ledger_start + dungeons[i - 1].num_dunlevs;
807 dungeons[i].dunlev_ureached = 0;
810 dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH);
811 dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE);
812 dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE);
813 dungeons[i].flags.align =
814 ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4);
816 * Set the entry level for this dungeon. The pd.tmpdungeon entry
818 * < 0 from bottom (-1 == bottom level)
820 * > 0 actual level (1 = top)
822 * Note that the entry_lev field in the dungeon structure is
823 * redundant. It is used only here and in print_dungeon().
825 if (pd.tmpdungeon[i].entry_lev < 0) {
826 dungeons[i].entry_lev =
827 dungeons[i].num_dunlevs + pd.tmpdungeon[i].entry_lev + 1;
828 if (dungeons[i].entry_lev <= 0)
829 dungeons[i].entry_lev = 1;
830 } else if (pd.tmpdungeon[i].entry_lev > 0) {
831 dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
832 if (dungeons[i].entry_lev > dungeons[i].num_dunlevs)
833 dungeons[i].entry_lev = dungeons[i].num_dunlevs;
834 } else { /* default */
835 dungeons[i].entry_lev = 1; /* defaults to top level */
838 if (i) { /* set depth */
843 br = add_branch(i, dungeons[i].entry_lev, &pd);
845 /* Get the depth of the connecting end. */
846 if (br->end1.dnum == i) {
847 from_depth = depth(&br->end2);
848 from_up = !br->end1_up;
850 from_depth = depth(&br->end1);
851 from_up = br->end1_up;
855 * Calculate the depth of the top of the dungeon via
856 * its branch. First, the depth of the entry point:
858 * depth of branch from "parent" dungeon
859 * + -1 or 1 depending on an up or down stair or
862 * Followed by the depth of the top of the dungeon:
864 * - (entry depth - 1)
866 * We'll say that portals stay on the same depth.
868 dungeons[i].depth_start =
869 from_depth + (br->type == BR_PORTAL ? 0 : (from_up ? -1 : 1))
870 - (dungeons[i].entry_lev - 1);
873 /* this is redundant - it should have been flagged by dgn_comp */
874 if (dungeons[i].num_dunlevs > MAXLEVEL)
875 dungeons[i].num_dunlevs = MAXLEVEL;
877 pd.start = pd.n_levs; /* save starting point */
878 pd.n_levs += pd.tmpdungeon[i].levels;
879 if (pd.n_levs > LEV_LIMIT)
880 panic("init_dungeon: too many special levels");
882 * Read in the prototype special levels. Don't add generated
883 * special levels until they are all placed.
885 for (; cl < pd.n_levs; cl++) {
886 Fread((genericptr_t) &pd.tmplevel[cl], sizeof(struct tmplevel), 1,
888 init_level(i, cl, &pd);
891 * Recursively place the generated levels for this dungeon. This
892 * routine will attempt all possible combinations before giving
895 if (!place_level(pd.start, &pd))
896 panic("init_dungeon: couldn't place levels");
898 fprintf(stderr, "--- end of dungeon %d ---\n", i);
902 for (; pd.start < pd.n_levs; pd.start++)
903 if (pd.final_lev[pd.start])
904 add_level(pd.final_lev[pd.start]);
906 pd.n_brs += pd.tmpdungeon[i].branches;
907 if (pd.n_brs > BRANCH_LIMIT)
908 panic("init_dungeon: too many branches");
909 for (; cb < pd.n_brs; cb++)
910 Fread((genericptr_t) &pd.tmpbranch[cb], sizeof(struct tmpbranch),
913 (void) dlb_fclose(dgn_file);
915 for (i = 0; i < 5; i++)
916 tune[i] = 'A' + rn2(7);
920 * Find most of the special levels and dungeons so we can access their
923 for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) {
924 x = find_level(lev_map->lev_name);
926 assign_level(lev_map->lev_spec, &x->dlevel);
927 if (!strncmp(lev_map->lev_name, "x-", 2)) {
928 /* This is where the name substitution on the
929 * levels of the quest dungeon occur.
931 Sprintf(x->proto, "%s%s", urole.filecode,
932 &lev_map->lev_name[1]);
933 } else if (lev_map->lev_spec == &knox_level) {
936 * Kludge to allow floating Knox entrance. We
937 * specify a floating entrance by the fact that
938 * its entrance (end1) has a bogus dnum, namely
941 for (br = branches; br; br = br->next)
942 if (on_level(&br->end2, &knox_level))
946 br->end1.dnum = n_dgns;
947 /* adjust the branch's position on the list */
948 insert_branch(br, TRUE);
953 * I hate hardwiring these names. :-(
956 quest_dnum = dname_to_dnum("The Quest");
958 quest_dnum = dname_to_dnum("
\83N
\83G
\83X
\83g");
960 sokoban_dnum = dname_to_dnum("Sokoban");
962 sokoban_dnum = dname_to_dnum("
\91q
\8cÉ
\94Ô");
964 mines_dnum = dname_to_dnum("The Gnomish Mines");
966 mines_dnum = dname_to_dnum("
\83m
\81[
\83\80\82Ì
\8dz
\8eR");
968 tower_dnum = dname_to_dnum("Vlad's Tower");
970 tower_dnum = dname_to_dnum("
\83\94\83\89\83h
\8cò
\82Ì
\93\83");
972 /* one special fixup for dummy surface level */
973 if ((x = find_level("dummy")) != 0) {
975 /* the code above puts earth one level above dungeon level #1,
976 making the dummy level overlay level 1; but the whole reason
977 for having the dummy level is to make earth have depth -1
978 instead of 0, so adjust the start point to shift endgame up */
979 if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start)
980 dungeons[i].depth_start -= 1;
981 /* TODO: strip "dummy" out all the way here,
982 so that it's hidden from '#wizwhere' feedback. */
990 /* return the level number for lev in *this* dungeon */
998 /* return the lowest level number for *this* dungeon */
1000 dunlevs_in_dungeon(lev)
1003 return dungeons[lev->dnum].num_dunlevs;
1006 /* return the lowest level explored in the game*/
1008 deepest_lev_reached(noquest)
1011 /* this function is used for three purposes: to provide a factor
1012 * of difficulty in monster generation; to provide a factor of
1013 * difficulty in experience calculations (botl.c and end.c); and
1014 * to insert the deepest level reached in the game in the topten
1015 * display. the 'noquest' arg switch is required for the latter.
1017 * from the player's point of view, going into the Quest is _not_
1018 * going deeper into the dungeon -- it is going back "home", where
1019 * the dungeon starts at level 1. given the setup in dungeon.def,
1020 * the depth of the Quest (thought of as starting at level 1) is
1021 * never lower than the level of entry into the Quest, so we exclude
1022 * the Quest from the topten "deepest level reached" display
1023 * calculation. _However_ the Quest is a difficult dungeon, so we
1024 * include it in the factor of difficulty calculations.
1028 register schar ret = 0;
1030 for (i = 0; i < n_dgns; i++) {
1031 if (noquest && i == quest_dnum)
1033 tmp.dlevel = dungeons[i].dunlev_ureached;
1034 if (tmp.dlevel == 0)
1037 if (depth(&tmp) > ret)
1043 /* return a bookkeeping level number for purpose of comparisons and
1049 return (xchar) (lev->dlevel + dungeons[lev->dnum].ledger_start);
1053 * The last level in the bookkeeping list of level is the bottom of the last
1054 * dungeon in the dungeons[] array.
1056 * Maxledgerno() -- which is the max number of levels in the bookkeeping
1057 * list, should not be confused with dunlevs_in_dungeon(lev) -- which
1058 * returns the max number of levels in lev's dungeon, and both should
1059 * not be confused with deepest_lev_reached() -- which returns the lowest
1060 * depth visited by the player.
1065 return (xchar) (dungeons[n_dgns - 1].ledger_start
1066 + dungeons[n_dgns - 1].num_dunlevs);
1069 /* return the dungeon that this ledgerno exists in */
1071 ledger_to_dnum(ledgerno)
1076 /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */
1077 for (i = 0; i < n_dgns; i++)
1078 if (dungeons[i].ledger_start < ledgerno
1079 && ledgerno <= dungeons[i].ledger_start + dungeons[i].num_dunlevs)
1082 panic("level number out of range [ledger_to_dnum(%d)]", (int) ledgerno);
1087 /* return the level of the dungeon this ledgerno exists in */
1089 ledger_to_dlev(ledgerno)
1092 return (xchar) (ledgerno
1093 - dungeons[ledger_to_dnum(ledgerno)].ledger_start);
1096 /* returns the depth of a level, in floors below the surface
1097 (note levels in different dungeons can have the same depth) */
1102 return (schar) (dungeons[lev->dnum].depth_start + lev->dlevel - 1);
1105 /* are "lev1" and "lev2" actually the same? */
1107 on_level(lev1, lev2)
1108 d_level *lev1, *lev2;
1110 return (boolean) (lev1->dnum == lev2->dnum
1111 && lev1->dlevel == lev2->dlevel);
1114 /* is this level referenced in the special level chain? */
1121 for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next)
1122 if (on_level(lev, &levtmp->dlevel))
1125 return (s_level *) 0;
1129 * Is this a multi-dungeon branch level? If so, return a pointer to the
1130 * branch. Otherwise, return null.
1138 for (curr = branches; curr; curr = curr->next) {
1139 if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2))
1142 return (branch *) 0;
1145 /* returns True iff the branch 'lev' is in a branch which builds up */
1150 dungeon *dptr = &dungeons[lev->dnum];
1152 * FIXME: this misclassifies a single level branch reached via stairs
1153 * from below. Saving grace is that no such branches currently exist.
1155 return (boolean) (dptr->num_dunlevs > 1
1156 && dptr->entry_lev == dptr->num_dunlevs);
1159 /* goto the next level (or appropriate dungeon) */
1161 next_level(at_stairs)
1164 if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
1165 /* Taking a down dungeon branch. */
1166 goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
1168 /* Going down a stairs or jump in a trap door. */
1171 newlevel.dnum = u.uz.dnum;
1172 newlevel.dlevel = u.uz.dlevel + 1;
1173 goto_level(&newlevel, at_stairs, !at_stairs, FALSE);
1177 /* goto the previous level (or appropriate dungeon) */
1179 prev_level(at_stairs)
1182 if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
1183 /* Taking an up dungeon branch. */
1184 /* KMH -- Upwards branches are okay if not level 1 */
1185 /* (Just make sure it doesn't go above depth 1) */
1186 if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
1189 goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
1191 /* Going up a stairs or rising through the ceiling. */
1193 newlevel.dnum = u.uz.dnum;
1194 newlevel.dlevel = u.uz.dlevel - 1;
1195 goto_level(&newlevel, at_stairs, FALSE, FALSE);
1206 cliparound(u.ux, u.uy);
1208 /* ridden steed always shares hero's location */
1210 u.usteed->mx = u.ux, u.usteed->my = u.uy;
1211 /* when changing levels, don't leave old position set with
1212 stale values from previous level */
1213 if (!on_level(&u.uz, &u.uz0))
1214 u.ux0 = u.ux, u.uy0 = u.uy;
1217 /* place you on a random location when arriving on a level */
1219 u_on_rndspot(upflag)
1222 int up = (upflag & 1), was_in_W_tower = (upflag & 2);
1225 * Place the hero at a random location within the relevant region.
1226 * place_lregion(xTELE) -> put_lregion_here(xTELE) -> u_on_newpos()
1227 * Unspecified region (.lx == 0) defaults to entire level.
1229 if (was_in_W_tower && On_W_tower_level(&u.uz))
1230 /* Stay inside the Wizard's tower when feasible.
1231 We use the W Tower's exclusion region for the
1232 destination instead of its enclosing region.
1233 Note: up vs down doesn't matter in this case
1234 because both specify the same exclusion area. */
1235 place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
1236 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0);
1238 place_lregion(updest.lx, updest.ly, updest.hx, updest.hy,
1239 updest.nlx, updest.nly, updest.nhx, updest.nhy,
1240 LR_UPTELE, (d_level *) 0);
1242 place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy,
1243 dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
1244 LR_DOWNTELE, (d_level *) 0);
1246 /* might have just left solid rock and unblocked levitation */
1250 /* place you on the special staircase */
1252 u_on_sstairs(upflag)
1256 u_on_newpos(sstairs.sx, sstairs.sy);
1258 u_on_rndspot(upflag);
1261 /* place you on upstairs (or special equivalent) */
1266 u_on_newpos(xupstair, yupstair);
1268 u_on_sstairs(0); /* destination upstairs implies moving down */
1271 /* place you on dnstairs (or special equivalent) */
1276 u_on_newpos(xdnstair, ydnstair);
1278 u_on_sstairs(1); /* destination dnstairs implies moving up */
1285 return (boolean) ((x == xupstair && y == yupstair)
1286 || (x == xdnstair && y == ydnstair)
1287 || (x == xdnladder && y == ydnladder)
1288 || (x == xupladder && y == yupladder)
1289 || (x == sstairs.sx && y == sstairs.sy));
1296 return (boolean) (lev->dlevel == dungeons[lev->dnum].num_dunlevs);
1303 return (boolean) (!level.flags.hardfloor
1304 && !Is_botlevel(lev)
1305 && !Invocation_lev(lev));
1309 * Like Can_dig_down (above), but also allows falling through on the
1310 * stronghold level. Normally, the bottom level of a dungeon resists
1311 * both digging and falling.
1317 return (boolean) (Can_dig_down(lev) || Is_stronghold(lev));
1321 * True if one can rise up a level (e.g. cursed gain level).
1322 * This happens on intermediate dungeon levels or on any top dungeon
1323 * level that has a stairwell style branch to the next higher dungeon.
1324 * Checks for amulets and such must be done elsewhere.
1327 Can_rise_up(x, y, lev)
1331 /* can't rise up from inside the top of the Wizard's tower */
1332 /* KMH -- or in sokoban */
1333 if (In_endgame(lev) || In_sokoban(lev)
1334 || (Is_wiz1_level(lev) && In_W_tower(x, y, lev)))
1336 return (boolean) (lev->dlevel > 1
1337 || (dungeons[lev->dnum].entry_lev == 1
1338 && ledger_no(lev) != 1
1339 && sstairs.sx && sstairs.up));
1346 /* [what about level 1 of the quest?] */
1347 return (boolean) (!Is_airlevel(lev) && !Is_waterlevel(lev));
1351 * It is expected that the second argument of get_level is a depth value,
1352 * either supplied by the user (teleport control) or randomly generated.
1353 * But more than one level can be at the same depth. If the target level
1354 * is "above" the present depth location, get_level must trace "up" from
1355 * the player's location (through the ancestors dungeons) the dungeon
1356 * within which the target level is located. With only one exception
1357 * which does not pass through this routine (see level_tele), teleporting
1358 * "down" is confined to the current dungeon. At present, level teleport
1359 * in dungeons that build up is confined within them.
1362 get_level(newlevel, levnum)
1367 xchar dgn = u.uz.dnum;
1370 /* can only currently happen in endgame */
1371 levnum = u.uz.dlevel;
1373 > dungeons[dgn].depth_start + dungeons[dgn].num_dunlevs - 1) {
1374 /* beyond end of dungeon, jump to last level */
1375 levnum = dungeons[dgn].num_dunlevs;
1377 /* The desired level is in this dungeon or a "higher" one. */
1380 * Branch up the tree until we reach a dungeon that contains the
1383 if (levnum < dungeons[dgn].depth_start) {
1386 * Find the parent dungeon of this dungeon.
1388 * This assumes that end2 is always the "child" and it is
1391 for (br = branches; br; br = br->next)
1392 if (br->end2.dnum == dgn)
1395 panic("get_level: can't find parent dungeon");
1397 dgn = br->end1.dnum;
1398 } while (levnum < dungeons[dgn].depth_start);
1401 /* We're within the same dungeon; calculate the level. */
1402 levnum = levnum - dungeons[dgn].depth_start + 1;
1405 newlevel->dnum = dgn;
1406 newlevel->dlevel = levnum;
1409 /* are you in the quest dungeon? */
1414 return (boolean) (lev->dnum == quest_dnum);
1417 /* are you in the mines dungeon? */
1422 return (boolean) (lev->dnum == mines_dnum);
1426 * Return the branch for the given dungeon.
1428 * This function assumes:
1429 * + This is not called with "Dungeons of Doom".
1430 * + There is only _one_ branch to a given dungeon.
1431 * + Field end2 is the "child" dungeon.
1440 dnum = dname_to_dnum(s);
1442 /* Find the branch that connects to dungeon i's branch. */
1443 for (br = branches; br; br = br->next)
1444 if (br->end2.dnum == dnum)
1448 panic("dgn_entrance: can't find entrance to %s", s);
1454 * This returns true if the hero is on the same level as the entrance to
1455 * the named dungeon.
1457 * Called from do.c and mklev.c.
1459 * Assumes that end1 is always the "parent".
1467 br = dungeon_branch(s);
1468 return on_level(&u.uz, &br->end1) ? TRUE : FALSE;
1471 /* is `lev' part of Vlad's tower? */
1476 return (boolean) (lev->dnum == tower_dnum);
1479 /* is `lev' a level containing the Wizard's tower? */
1481 On_W_tower_level(lev)
1484 return (boolean) (Is_wiz1_level(lev)
1485 || Is_wiz2_level(lev)
1486 || Is_wiz3_level(lev));
1489 /* is <x,y> of `lev' inside the Wizard's tower? */
1491 In_W_tower(x, y, lev)
1495 if (!On_W_tower_level(lev))
1498 * Both of the exclusion regions for arriving via level teleport
1499 * (from above or below) define the tower's boundary.
1500 * assert( updest.nIJ == dndest.nIJ for I={l|h},J={x|y} );
1503 return (boolean) within_bounded_area(x, y, dndest.nlx, dndest.nly,
1504 dndest.nhx, dndest.nhy);
1506 impossible("No boundary for Wizard's Tower?");
1510 /* are you in one of the Hell levels? */
1515 return (boolean) (dungeons[lev->dnum].flags.hellish);
1518 /* sets *lev to be the gateway to Gehennom... */
1523 lev->dnum = valley_level.dnum;
1527 /* go directly to hell... */
1529 goto_hell(at_stairs, falling)
1530 boolean at_stairs, falling;
1535 goto_level(&lev, at_stairs, falling, FALSE);
1538 /* equivalent to dest = source */
1540 assign_level(dest, src)
1541 d_level *dest, *src;
1543 dest->dnum = src->dnum;
1544 dest->dlevel = src->dlevel;
1547 /* dest = src + rn1(range) */
1549 assign_rnd_level(dest, src, range)
1550 d_level *dest, *src;
1553 dest->dnum = src->dnum;
1554 dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range));
1556 if (dest->dlevel > dunlevs_in_dungeon(dest))
1557 dest->dlevel = dunlevs_in_dungeon(dest);
1558 else if (dest->dlevel < 1)
1566 s_level *lev = Is_special(&u.uz);
1569 if (lev && lev->flags.align)
1571 return lev->flags.align;
1573 if (dungeons[u.uz.dnum].flags.align)
1575 return dungeons[u.uz.dnum].flags.align;
1578 return Align2amask(al);
1585 return (boolean) (In_hell(lev)
1586 && lev->dlevel == dungeons[lev->dnum].num_dunlevs - 1);
1589 /* use instead of depth() wherever a degree of difficulty is made
1590 * dependent on the location in the dungeon (eg. monster creation).
1597 if (In_endgame(&u.uz)) {
1598 res = depth(&sanctum_level) + u.ulevel / 2;
1599 } else if (u.uhave.amulet) {
1600 res = deepest_lev_reached(FALSE);
1603 /* depth() is the number of elevation units (levels) below
1604 the theoretical surface; in a builds-up branch, that value
1605 ends up making the harder to reach levels be treated as if
1606 they were easier; adjust for the extra effort involved in
1607 going down to the entrance and then up to the location */
1608 if (builds_up(&u.uz))
1609 res += 2 * (dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1);
1611 * 'Proof' by example: suppose the entrance to sokoban is
1612 * on dungeon level 9, leading up to bottom sokoban level
1613 * of 8 [entry_lev]. When the hero is on sokoban level 8
1614 * [uz.dlevel], depth() yields eight but he has ventured
1615 * one level beyond 9, so difficulty depth should be 10:
1616 * 8 + 2 * (8 - 8 + 1) => 10.
1617 * Going up to 7, depth is 7 but hero will be two beyond 9:
1618 * 7 + 2 * (8 - 7 + 1) => 11.
1619 * When he goes up to level 6, three levels beyond 9:
1620 * 6 + 2 * (8 - 6 + 1) => 12.
1621 * And the top level of sokoban at 5, four levels beyond 9:
1622 * 5 + 2 * (8 - 5 + 1) => 13.
1623 * The same applies to Vlad's Tower, although the increment
1624 * there is inconsequential compared to overall depth.
1628 * The inside of the Wizard's Tower is also effectively a
1629 * builds-up area, reached from a portal an arbitrary distance
1630 * below rather than stairs 1 level beneath the entry level.
1632 else if (On_W_tower_level(&u.uz) && In_W_tower(some_X, some_Y, &u.uz))
1633 res += (fakewiz1.dlev - u.uz.dlev);
1635 * Handling this properly would need more information here:
1636 * an inside/outside flag, or coordinates to calculate it.
1637 * Unfortunately level difficulty may be wanted before
1638 * coordinates have been chosen so simply extending this
1639 * routine to take extra arguments is not sufficient to cope.
1640 * The difference beyond naive depth-from-surface is small
1641 * relative to the overall depth, so just ignore complications
1649 /* Take one word and try to match it to a level.
1650 * Recognized levels are as shown by print_dungeon().
1657 s_level *slev = (s_level *)0;
1666 /* look at the player's custom level annotations first */
1667 if ((mseen = find_mapseen_by_str(nam)) != 0) {
1670 /* no matching annotation, check whether they used a name we know */
1672 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
1673 /* allow strings like "the oracle level" to find "oracle" */
1674 if (!strncmpi(nam, "the ", 4))
1676 if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
1677 nam = strcpy(buf, nam);
1678 *(eos(buf) - 6) = '\0';
1680 /* hell is the old name, and wouldn't match; gehennom would match its
1681 branch, yielding the castle level instead of valley of the dead */
1682 if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
1683 if (In_V_tower(&u.uz))
1684 nam = " to Vlad's tower"; /* branch to... */
1690 if ((slev = find_level(nam)) != 0)
1691 dlev = slev->dlevel;
1694 if (mseen || slev) {
1695 idx = ledger_no(&dlev);
1696 if ((dlev.dnum == u.uz.dnum
1697 /* within same branch, or else main dungeon <-> gehennom */
1698 || (u.uz.dnum == valley_level.dnum
1699 && dlev.dnum == medusa_level.dnum)
1700 || (u.uz.dnum == medusa_level.dnum
1701 && dlev.dnum == valley_level.dnum))
1702 && (/* either wizard mode or else seen and not forgotten */
1704 || (level_info[idx].flags & (FORGOTTEN | VISITED))
1708 } else { /* not a specific level; try branch names */
1709 idx = find_branch(nam, (struct proto_dungeon *) 0);
1710 /* "<branch> to Xyzzy" */
1711 if (idx < 0 && (p = strstri(nam, " to ")) != 0)
1712 idx = find_branch(p + 4, (struct proto_dungeon *) 0);
1715 idxtoo = (idx >> 8) & 0x00FF;
1717 if (/* either wizard mode, or else _both_ sides of branch seen */
1719 || ((level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED
1720 && (level_info[idxtoo].flags & (FORGOTTEN | VISITED))
1722 if (ledger_to_dnum(idxtoo) == u.uz.dnum)
1724 dlev.dnum = ledger_to_dnum(idx);
1725 dlev.dlevel = ledger_to_dlev(idx);
1734 unplaced_floater(dptr)
1735 struct dungeon *dptr;
1738 int idx = (int) (dptr - dungeons);
1740 /* if other floating branches are added, this will need to change */
1741 if (idx != knox_level.dnum)
1743 for (br = branches; br; br = br->next)
1744 if (br->end1.dnum == n_dgns && br->end2.dnum == idx)
1750 unreachable_level(lvl_p, unplaced)
1758 if (In_endgame(&u.uz) && !In_endgame(lvl_p))
1760 if ((dummy = find_level("dummy")) != 0 && on_level(lvl_p, &dummy->dlevel))
1766 tport_menu(win, entry, lchoices, lvl_p, unreachable)
1769 struct lchoice *lchoices;
1771 boolean unreachable;
1776 lchoices->lev[lchoices->idx] = lvl_p->dlevel;
1777 lchoices->dgn[lchoices->idx] = lvl_p->dnum;
1778 lchoices->playerlev[lchoices->idx] = depth(lvl_p);
1781 /* not selectable, but still consumes next menuletter;
1782 prepend padding in place of missing menu selector */
1783 Sprintf(tmpbuf, " %s", entry);
1786 any.a_int = lchoices->idx + 1;
1788 add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 0, ATR_NONE, entry,
1790 /* this assumes there are at most 52 interesting levels */
1791 if (lchoices->menuletter == 'z')
1792 lchoices->menuletter = 'A';
1794 lchoices->menuletter++;
1799 /* Convert a branch type to a string usable by print_dungeon(). */
1800 STATIC_OVL const char *
1809 return "
\96\82\96@
\82Ì
\93ü
\82è
\8cû";
1812 return "Connection";
1814 return "
\90Ú
\91±
\95\94";
1817 return "One way stair";
1819 return "
\88ê
\95û
\92Ê
\8ds
\82Ì
\8aK
\92i";
1827 return " (unknown)";
1829 return " (
\95s
\96¾)";
1836 return u.uz.dnum == dlev->dnum && u.uz.dlevel == dlev->dlevel ? '*' : ' ';
1839 /* Print all child branches between the lower and upper bounds. */
1841 print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices_p)
1847 struct lchoice *lchoices_p;
1852 /* This assumes that end1 is the "parent". */
1853 for (br = branches; br; br = br->next) {
1854 if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel
1855 && br->end1.dlevel <= upper_bound) {
1857 Sprintf(buf, "%c %s to %s: %d",
1858 bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1859 br_string(br->type),
1860 dungeons[br->end2.dnum].dname, depth(&br->end1));
1862 Sprintf(buf, "%c %s
\82©
\82ç%s: %d",
1863 bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1864 br_string(br->type),
1865 dungeons[br->end2.dnum].dname, depth(&br->end1));
1868 tport_menu(win, buf, lchoices_p, &br->end1,
1869 unreachable_level(&br->end1, FALSE));
1871 putstr(win, 0, buf);
1876 /* Print available dungeon information. */
1878 print_dungeon(bymenu, rlev, rdgn)
1883 int i, last_level, nlev;
1886 boolean first, unplaced;
1891 struct lchoice lchoices;
1892 winid win = create_nhwindow(NHW_MENU);
1897 lchoices.menuletter = 'a';
1900 for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
1901 if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum)
1903 unplaced = unplaced_floater(dptr);
1905 descr = unplaced ? "depth" : "level";
1907 descr = unplaced ? "
\92n
\89º" : "
\83\8c\83x
\83\8b";
1908 nlev = dptr->num_dunlevs;
1911 Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr),
1912 dptr->depth_start, dptr->depth_start + nlev - 1);
1914 Sprintf(buf, "%s: %s%d
\82©
\82ç%d", dptr->dname, descr,
1915 dptr->depth_start, dptr->depth_start + nlev - 1);
1918 Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start);
1920 /* Most entrances are uninteresting. */
1921 if (dptr->entry_lev != 1) {
1922 if (dptr->entry_lev == nlev)
1924 Strcat(buf, ", entrance from below");
1926 Strcat(buf, ",
\89º
\82©
\82ç
\82Ì
\93ü
\82è
\8cû");
1929 Sprintf(eos(buf), ", entrance on %d",
1930 dptr->depth_start + dptr->entry_lev - 1);
1932 Sprintf(eos(buf), ", %d
\82Ì
\93ü
\82è
\8cû",
1933 dptr->depth_start + dptr->entry_lev - 1);
1938 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1941 putstr(win, 0, buf);
1944 * Circle through the special levels to find levels that are in
1947 for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
1948 if (slev->dlevel.dnum != i)
1951 /* print any branches before this level */
1952 print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu,
1955 Sprintf(buf, "%c %s: %d",
1956 chr_u_on_lvl(&slev->dlevel),
1957 slev->proto, depth(&slev->dlevel));
1958 if (Is_stronghold(&slev->dlevel))
1959 Sprintf(eos(buf), " (tune %s)", tune);
1961 tport_menu(win, buf, &lchoices, &slev->dlevel,
1962 unreachable_level(&slev->dlevel, unplaced));
1964 putstr(win, 0, buf);
1966 last_level = slev->dlevel.dlevel;
1968 /* print branches after the last special level */
1969 print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices);
1974 menu_item *selected;
1978 end_menu(win, "Level teleport to where:");
1980 end_menu(win, "
\82Ç
\82±
\82É
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é
\81F");
1981 n = select_menu(win, PICK_ONE, &selected);
1982 destroy_nhwindow(win);
1984 idx = selected[0].item.a_int - 1;
1985 free((genericptr_t) selected);
1987 *rlev = lchoices.lev[idx];
1988 *rdgn = lchoices.dgn[idx];
1989 return lchoices.playerlev[idx];
1995 /* Print out floating branches (if any). */
1996 for (first = TRUE, br = branches; br; br = br->next) {
1997 if (br->end1.dnum == n_dgns) {
2001 putstr(win, 0, "Floating branches");
2003 putstr(win, 0, "
\95\82\93®
\95ª
\8aò");
2007 Sprintf(buf, " %s to %s", br_string(br->type),
2008 dungeons[br->end2.dnum].dname);
2010 Sprintf(buf, " %s
\82©
\82ç%s", br_string(br->type),
2011 dungeons[br->end2.dnum].dname);
2013 putstr(win, 0, buf);
2017 /* I hate searching for the invocation pos while debugging. -dean */
2018 if (Invocation_lev(&u.uz)) {
2021 Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
2022 inv_pos.x, inv_pos.y, u.ux, u.uy);
2024 Sprintf(buf, "
\94
\93®
\88Ê
\92u @ (%d,%d),
\83v
\83\8c\83C
\83\84\81[ @ (%d,%d)",
2025 inv_pos.x, inv_pos.y, u.ux, u.uy);
2027 putstr(win, 0, buf);
2031 /* if current level has a magic portal, report its location;
2032 this assumes that there is at most one magic portal on any
2033 given level; quest and ft.ludios have pairs (one in main
2034 dungeon matched with one in the corresponding branch), the
2035 elemental planes have singletons (connection to next plane) */
2037 for (trap = ftrap; trap; trap = trap->ntrap)
2038 if (trap->ttyp == MAGIC_PORTAL)
2042 Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
2043 trap->tx, trap->ty, u.ux, u.uy);
2045 /* only report "no portal found" when actually expecting a portal */
2047 else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2048 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2049 || Is_qstart(&u.uz) || at_dgn_entrance("The Quest")
2052 else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2053 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2054 || Is_qstart(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g")
2057 Strcpy(buf, "No portal found.");
2059 /* only give output if we found a portal or expected one and didn't */
2062 putstr(win, 0, buf);
2066 display_nhwindow(win, TRUE);
2067 destroy_nhwindow(win);
2071 /* Record that the player knows about a branch from a level. This function
2072 * will determine whether or not it was a "real" branch that was taken.
2073 * This function should not be called for a transition done via level
2074 * teleport or via the Eye.
2077 recbranch_mapseen(source, dest)
2085 if (source->dnum == dest->dnum)
2088 /* we only care about forward branches */
2089 for (br = branches; br; br = br->next) {
2090 if (on_level(source, &br->end1) && on_level(dest, &br->end2))
2092 if (on_level(source, &br->end2) && on_level(dest, &br->end1))
2096 /* branch not found, so not a real branch. */
2100 if ((mptr = find_mapseen(source)) != 0) {
2101 if (mptr->br && br != mptr->br)
2102 impossible("Two branches on the same level?");
2105 impossible("Can't note branch for unseen level (%d, %d)",
2106 source->dnum, source->dlevel);
2116 if ((mptr = find_mapseen(lev)))
2117 return mptr->custom;
2121 /* #annotate command - add a custom name to the current level */
2126 char nbuf[BUFSZ]; /* Buffer for response */
2128 if (!(mptr = find_mapseen(&u.uz)))
2134 (void) strncpy(nbuf, mptr->custom, BUFSZ);
2135 nbuf[BUFSZ - 1] = '\0';
2142 Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?", mptr->custom,
2143 (strlen(mptr->custom) > 30) ? "..." : "");
2145 Sprintf(tmpbuf, "
\8c»
\8dÝ
\82Ì
\83\81\83\82\81u%.30s%s
\81v
\82ð
\89½
\82É
\8f\91\82«
\8a·
\82¦
\82é
\81H", mptr->custom,
2146 strlen(mptr->custom) > 30 ? "..." : "");
2148 getlin(tmpbuf, nbuf);
2152 getlin("What do you want to call this dungeon level?", nbuf);
2154 getlin("
\82±
\82Ì
\8aK
\82ð
\89½
\82Æ
\8cÄ
\82Ô
\81H", nbuf);
2156 /* empty input or ESC means don't add or change annotation;
2157 space-only means discard current annotation without adding new one */
2158 if (!*nbuf || *nbuf == '\033')
2160 /* strip leading and trailing spaces, compress out consecutive spaces */
2161 (void) mungspaces(nbuf);
2163 /* discard old annotation, if any */
2165 free((genericptr_t) mptr->custom);
2166 mptr->custom = (char *) 0;
2167 mptr->custom_lth = 0;
2169 /* add new annotation, unless it's all spaces (which will be an
2170 empty string after mungspaces() above) */
2171 if (*nbuf && strcmp(nbuf, " ")) {
2172 mptr->custom = dupstr(nbuf);
2173 mptr->custom_lth = strlen(mptr->custom);
2178 /* find the particular mapseen object in the chain; may return null */
2179 STATIC_OVL mapseen *
2185 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2186 if (on_level(&(mptr->lev), lev))
2192 STATIC_OVL mapseen *
2193 find_mapseen_by_str(s)
2198 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2199 if (mptr->custom && !strcmpi(s, mptr->custom))
2207 forget_mapseen(ledger_num)
2211 struct cemetery *bp;
2213 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2214 if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel
2218 /* if not found, then nothing to forget */
2220 mptr->flags.forgot = 1;
2221 mptr->br = (branch *) 0;
2223 /* custom names are erased, not just forgotten until revisited */
2225 mptr->custom_lth = 0;
2226 free((genericptr_t) mptr->custom);
2227 mptr->custom = (char *) 0;
2229 (void) memset((genericptr_t) mptr->msrooms, 0, sizeof mptr->msrooms);
2230 for (bp = mptr->final_resting_place; bp; bp = bp->next)
2231 bp->bonesknown = FALSE;
2236 rm_mapseen(ledger_num)
2239 mapseen *mptr, *mprev = (mapseen *)0;
2240 struct cemetery *bp, *bpnext;
2242 for (mptr = mapseenchn; mptr; mprev = mptr, mptr = mptr->next)
2243 if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num)
2250 free((genericptr_t) mptr->custom);
2252 bp = mptr->final_resting_place;
2260 mprev->next = mptr->next;
2263 mapseenchn = mptr->next;
2269 save_mapseen(fd, mptr)
2276 for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2277 if (curr == mptr->br)
2279 bwrite(fd, (genericptr_t) &brindx, sizeof brindx);
2281 bwrite(fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
2282 bwrite(fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
2283 bwrite(fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
2284 bwrite(fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
2285 if (mptr->custom_lth)
2286 bwrite(fd, (genericptr_t) mptr->custom, mptr->custom_lth);
2287 bwrite(fd, (genericptr_t) mptr->msrooms, sizeof mptr->msrooms);
2288 savecemetery(fd, WRITE_SAVE, &mptr->final_resting_place);
2291 STATIC_OVL mapseen *
2295 int branchnum, brindx;
2299 load = (mapseen *) alloc(sizeof *load);
2301 mread(fd, (genericptr_t) &branchnum, sizeof branchnum);
2302 for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2303 if (brindx == branchnum)
2307 mread(fd, (genericptr_t) &load->lev, sizeof load->lev);
2308 mread(fd, (genericptr_t) &load->feat, sizeof load->feat);
2309 mread(fd, (genericptr_t) &load->flags, sizeof load->flags);
2310 mread(fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
2311 if (load->custom_lth) {
2312 /* length doesn't include terminator (which isn't saved & restored) */
2313 load->custom = (char *) alloc(load->custom_lth + 1);
2314 mread(fd, (genericptr_t) load->custom, load->custom_lth);
2315 load->custom[load->custom_lth] = '\0';
2318 mread(fd, (genericptr_t) load->msrooms, sizeof load->msrooms);
2319 restcemetery(fd, &load->final_resting_place);
2324 /* to support '#stats' wizard-mode command */
2326 overview_stats(win, statsfmt, total_count, total_size)
2328 const char *statsfmt;
2329 long *total_count, *total_size;
2331 char buf[BUFSZ], hdrbuf[QBUFSZ];
2332 long ocount, osize, bcount, bsize, acount, asize;
2333 struct cemetery *ce;
2334 mapseen *mptr = find_mapseen(&u.uz);
2336 ocount = bcount = acount = osize = bsize = asize = 0L;
2337 for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2339 osize += (long) sizeof *mptr;
2340 for (ce = mptr->final_resting_place; ce; ce = ce->next) {
2342 bsize += (long) sizeof *ce;
2344 if (mptr->custom_lth) {
2346 asize += (long) (mptr->custom_lth + 1);
2350 Sprintf(hdrbuf, "general, size %ld", (long) sizeof (mapseen));
2351 Sprintf(buf, statsfmt, hdrbuf, ocount, osize);
2352 putstr(win, 0, buf);
2354 Sprintf(hdrbuf, "cemetery, size %ld",
2355 (long) sizeof (struct cemetery));
2356 Sprintf(buf, statsfmt, hdrbuf, bcount, bsize);
2357 putstr(win, 0, buf);
2360 Sprintf(hdrbuf, "annotations, text");
2361 Sprintf(buf, statsfmt, hdrbuf, acount, asize);
2362 putstr(win, 0, buf);
2364 *total_count += ocount + bcount + acount;
2365 *total_size += osize + bsize + asize;
2368 /* Remove all mapseen objects for a particular dnum.
2369 * Useful during quest expulsion to remove quest levels.
2370 * [No longer deleted, just marked as unreachable. #overview will
2371 * ignore such levels, end of game disclosure will include them.]
2374 remdun_mapseen(dnum)
2377 mapseen *mptr, **mptraddr;
2379 mptraddr = &mapseenchn;
2380 while ((mptr = *mptraddr) != 0) {
2381 if (mptr->lev.dnum == dnum) {
2382 #if 1 /* use this... */
2383 mptr->flags.unreachable = 1;
2385 #else /* old deletion code */
2386 *mptraddr = mptr->next;
2388 free((genericptr_t) mptr->custom);
2389 if (mptr->final_resting_place)
2390 savecemetery(-1, FREE_SAVE, &mptr->final_resting_place);
2391 free((genericptr_t) mptr);
2394 mptraddr = &mptr->next;
2402 /* Create a level and insert in "sorted" order. This is an insertion
2403 * sort first by dungeon (in order of discovery) and then by level number.
2405 mapseen *mptr, *init, *prev;
2407 init = (mapseen *) alloc(sizeof *init);
2408 (void) memset((genericptr_t) init, 0, sizeof *init);
2409 /* memset is fine for feature bits, flags, and rooms array;
2410 explicitly initialize pointers to null */
2411 init->next = 0, init->br = 0, init->custom = 0;
2412 init->final_resting_place = 0;
2413 /* lastseentyp[][] is reused for each level, so get rid of
2414 previous level's data */
2415 (void) memset((genericptr_t) lastseentyp, 0, sizeof lastseentyp);
2417 init->lev.dnum = lev->dnum;
2418 init->lev.dlevel = lev->dlevel;
2420 /* walk until we get to the place where we should insert init */
2421 for (mptr = mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next)
2422 if (mptr->lev.dnum > init->lev.dnum
2423 || (mptr->lev.dnum == init->lev.dnum
2424 && mptr->lev.dlevel > init->lev.dlevel))
2427 init->next = mapseenchn;
2436 #define INTEREST(feat) \
2437 ((feat).nfount || (feat).nsink || (feat).nthrone || (feat).naltar \
2438 || (feat).ngrave || (feat).ntree || (feat).nshop || (feat).ntemple)
2439 /* || (feat).water || (feat).ice || (feat).lava */
2441 /* returns true if this level has something interesting to print out */
2443 interest_mapseen(mptr)
2446 if (on_level(&u.uz, &mptr->lev))
2448 if (mptr->flags.unreachable || mptr->flags.forgot)
2450 /* level is of interest if it has an auto-generated annotation */
2451 if (mptr->flags.oracle || mptr->flags.bigroom || mptr->flags.roguelevel
2452 || mptr->flags.castle || mptr->flags.valley || mptr->flags.msanctum
2453 || mptr->flags.quest_summons || mptr->flags.questing)
2455 /* when in Sokoban, list all sokoban levels visited; when not in it,
2456 list any visited Sokoban level which remains unsolved (will usually
2457 only be furthest one reached, but it's possible to enter pits and
2458 climb out on the far side on the first Sokoban level; also, wizard
2459 mode overrides teleport restrictions) */
2460 if (In_sokoban(&mptr->lev)
2461 && (In_sokoban(&u.uz) || !mptr->flags.sokosolved))
2463 /* when in the endgame, list all endgame levels visited, whether they
2464 have annotations or not, so that #overview doesn't become extremely
2465 sparse once the rest of the dungeon has been flagged as unreachable */
2466 if (In_endgame(&u.uz))
2467 return (boolean) In_endgame(&mptr->lev);
2468 /* level is of interest if it has non-zero feature count or known bones
2469 or user annotation or known connection to another dungeon branch
2470 or is the furthest level reached in its branch */
2471 return (boolean) (INTEREST(mptr->feat)
2472 || (mptr->final_resting_place
2473 && (mptr->flags.knownbones || wizard))
2474 || mptr->custom || mptr->br
2475 || (mptr->lev.dlevel
2476 == dungeons[mptr->lev.dnum].dunlev_ureached));
2479 /* recalculate mapseen for the current level */
2485 struct cemetery *bp, **bonesaddr;
2487 int x, y, ltyp, count, atmp;
2489 /* Should not happen in general, but possible if in the process
2490 * of being booted from the quest. The mapseen object gets
2491 * removed during the expulsion but prior to leaving the level
2492 * [Since quest expulsion no longer deletes quest mapseen data,
2493 * null return from find_mapseen() should now be impossible.]
2495 if (!(mptr = find_mapseen(&u.uz)))
2498 /* reset all features; mptr->feat.* = 0; */
2499 (void) memset((genericptr_t) &mptr->feat, 0, sizeof mptr->feat);
2500 /* reset most flags; some level-specific ones are left as-is */
2501 if (mptr->flags.unreachable) {
2502 mptr->flags.unreachable = 0; /* reached it; Eye of the Aethiopica? */
2503 if (In_quest(&u.uz)) {
2504 mapseen *mptrtmp = mapseenchn;
2506 /* when quest was unreachable due to ejection and portal removal,
2507 getting back to it via arti-invoke should revive annotation
2508 data for all quest levels, not just the one we're on now */
2510 if (mptrtmp->lev.dnum == mptr->lev.dnum)
2511 mptrtmp->flags.unreachable = 0;
2512 mptrtmp = mptrtmp->next;
2516 mptr->flags.knownbones = 0;
2517 mptr->flags.sokosolved = In_sokoban(&u.uz) && !Sokoban;
2518 /* mptr->flags.bigroom retains previous value when hero can't see */
2520 mptr->flags.bigroom = Is_bigroom(&u.uz);
2521 else if (mptr->flags.forgot)
2522 mptr->flags.bigroom = 0;
2523 mptr->flags.roguelevel = Is_rogue_level(&u.uz);
2524 mptr->flags.oracle = 0; /* recalculated during room traversal below */
2525 mptr->flags.castletune = 0;
2526 /* flags.castle, flags.valley, flags.msanctum retain previous value */
2527 mptr->flags.forgot = 0;
2528 /* flags.quest_summons disabled once quest finished */
2530 mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
2532 mptr->flags.quest_summons = (at_dgn_entrance("
\83N
\83G
\83X
\83g")
2534 && !(u.uevent.qcompleted
2535 || u.uevent.qexpelled
2536 || quest_status.leader_is_dead));
2537 mptr->flags.questing = (on_level(&u.uz, &qstart_level)
2538 && quest_status.got_quest);
2540 /* track rooms the hero is in */
2541 for (i = 0; i < SIZE(u.urooms); ++i) {
2545 ridx = u.urooms[i] - ROOMOFFSET;
2546 mptr->msrooms[ridx].seen = 1;
2547 mptr->msrooms[ridx].untended =
2548 (rooms[ridx].rtype >= SHOPBASE)
2549 ? (!(mtmp = shop_keeper(u.urooms[i])) || !inhishop(mtmp))
2550 : (rooms[ridx].rtype == TEMPLE)
2551 ? (!(mtmp = findpriest(u.urooms[i]))
2552 || !inhistemple(mtmp))
2556 /* recalculate room knowledge: for now, just shops and temples
2557 * this could be extended to an array of 0..SHOPBASE
2559 for (i = 0; i < SIZE(mptr->msrooms); ++i) {
2560 if (mptr->msrooms[i].seen) {
2561 if (rooms[i].rtype >= SHOPBASE) {
2562 if (mptr->msrooms[i].untended)
2563 mptr->feat.shoptype = SHOPBASE - 1;
2564 else if (!mptr->feat.nshop)
2565 mptr->feat.shoptype = rooms[i].rtype;
2566 else if (mptr->feat.shoptype != (unsigned) rooms[i].rtype)
2567 mptr->feat.shoptype = 0;
2568 count = mptr->feat.nshop + 1;
2570 mptr->feat.nshop = count;
2571 } else if (rooms[i].rtype == TEMPLE) {
2572 /* altar and temple alignment handled below */
2573 count = mptr->feat.ntemple + 1;
2575 mptr->feat.ntemple = count;
2576 } else if (rooms[i].orig_rtype == DELPHI) {
2577 mptr->flags.oracle = 1;
2582 /* Update lastseentyp with typ if and only if it is in sight or the
2583 * hero can feel it on their current location (i.e. not levitating).
2584 * This *should* give the "last known typ" for each dungeon location.
2585 * (At the very least, it's a better assumption than determining what
2586 * the player knows from the glyph and the typ (which is isn't quite
2587 * enough information in some cases)).
2589 * It was reluctantly added to struct rm to track. Alternatively
2590 * we could track "features" and then update them all here, and keep
2591 * track of when new features are created or destroyed, but this
2592 * seemed the most elegant, despite adding more data to struct rm.
2593 * [3.6.0: we're using lastseentyp[][] rather than level.locations
2594 * to track the features seen.]
2596 * Although no current windowing systems (can) do this, this would add
2597 * the ability to have non-dungeon glyphs float above the last known
2598 * dungeon glyph (i.e. items on fountains).
2600 for (x = 1; x < COLNO; x++) {
2601 for (y = 0; y < ROWNO; y++) {
2602 if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
2603 ltyp = levl[x][y].typ;
2604 if (ltyp == DRAWBRIDGE_UP)
2605 ltyp = db_under_typ(levl[x][y].drawbridgemask);
2606 if ((mtmp = m_at(x, y)) != 0
2607 && M_AP_TYPE(mtmp) == M_AP_FURNITURE && canseemon(mtmp))
2608 ltyp = cmap_to_type(mtmp->mappearance);
2609 lastseentyp[x][y] = ltyp;
2612 switch (lastseentyp[x][y]) {
2615 count = mptr->feat.ice + 1;
2617 mptr->feat.ice = count;
2622 count = mptr->feat.water + 1;
2624 mptr->feat.water = count;
2627 count = mptr->feat.lava + 1;
2629 mptr->feat.lava = count;
2633 count = mptr->feat.ntree + 1;
2635 mptr->feat.ntree = count;
2638 count = mptr->feat.nfount + 1;
2640 mptr->feat.nfount = count;
2643 count = mptr->feat.nthrone + 1;
2645 mptr->feat.nthrone = count;
2648 count = mptr->feat.nsink + 1;
2650 mptr->feat.nsink = count;
2653 count = mptr->feat.ngrave + 1;
2655 mptr->feat.ngrave = count;
2658 atmp = (Is_astralevel(&u.uz)
2659 && (levl[x][y].seenv & SVALL) != SVALL)
2661 : Amask2msa(levl[x][y].altarmask);
2662 if (!mptr->feat.naltar)
2663 mptr->feat.msalign = atmp;
2664 else if (mptr->feat.msalign != atmp)
2665 mptr->feat.msalign = MSA_NONE;
2666 count = mptr->feat.naltar + 1;
2668 mptr->feat.naltar = count;
2670 /* An automatic annotation is added to the Castle and
2671 * to Fort Ludios once their structure's main entrance
2672 * has been seen (in person or via magic mapping).
2673 * For the Fort, that entrance is just a secret door
2674 * which will be converted into a regular one when
2675 * located (or destroyed).
2676 * DOOR: possibly a lowered drawbridge's open portcullis;
2677 * DBWALL: a raised drawbridge's "closed door";
2678 * DRAWBRIDGE_DOWN: the span provided by lowered bridge,
2679 * with moat or other terrain hidden underneath;
2680 * DRAWBRIDGE_UP: moat in front of a raised drawbridge,
2681 * not recognizable as a bridge location unless/until
2682 * the adjacent DBWALL has been seen.
2685 if (Is_knox(&u.uz)) {
2688 /* Throne is four columns left, either directly in
2689 * line or one row higher or lower, and doesn't have
2690 * to have been seen yet.
2695 * For 3.6.0 and earlier, it was always in direct line:
2696 * both throne and door on the lower of the two rows.
2698 for (ty = y - 1; ty <= y + 1; ++ty)
2699 if (isok(tx, ty) && IS_THRONE(levl[tx][ty].typ)) {
2700 mptr->flags.ludios = 1;
2705 if (is_drawbridge_wall(x, y) < 0)
2709 case DRAWBRIDGE_DOWN:
2710 if (Is_stronghold(&u.uz))
2711 mptr->flags.castle = 1, mptr->flags.castletune = 1;
2719 if (level.bonesinfo && !mptr->final_resting_place) {
2720 /* clone the bonesinfo so we aren't dependent upon this
2721 level being in memory */
2722 bonesaddr = &mptr->final_resting_place;
2723 bp = level.bonesinfo;
2725 *bonesaddr = (struct cemetery *) alloc(sizeof **bonesaddr);
2728 bonesaddr = &(*bonesaddr)->next;
2732 /* decide which past hero deaths have become known; there's no
2733 guarantee of either a grave or a ghost, so we go by whether the
2734 current hero has seen the map location where each old one died */
2735 for (bp = mptr->final_resting_place; bp; bp = bp->next)
2736 if (lastseentyp[bp->frpx][bp->frpy]) {
2737 bp->bonesknown = TRUE;
2738 mptr->flags.knownbones = 1;
2743 /* valley and sanctum levels get automatic annotation once temple is entered
2746 mapseen_temple(priest)
2747 struct monst *priest UNUSED; /* currently unused; might be useful someday */
2749 mapseen *mptr = find_mapseen(&u.uz);
2751 if (Is_valley(&u.uz))
2752 mptr->flags.valley = 1;
2753 else if (Is_sanctum(&u.uz))
2754 mptr->flags.msanctum = 1;
2757 /* room entry message has just been delivered so learn room even if blind */
2759 room_discovered(roomno)
2762 mapseen *mptr = find_mapseen(&u.uz);
2764 mptr->msrooms[roomno].seen = 1;
2767 /* #overview command */
2771 show_overview(0, 0);
2775 /* called for #overview or for end of game disclosure */
2777 show_overview(why, reason)
2778 int why; /* 0 => #overview command,
2779 1 or 2 => final disclosure (1: hero lived, 2: hero died) */
2780 int reason; /* how hero died; used when disclosing end-of-game level */
2785 /* lazy initialization */
2786 (void) recalc_mapseen();
2788 win = create_nhwindow(NHW_MENU);
2789 /* show the endgame levels before the rest of the dungeon,
2790 so that the Planes (dnum 5-ish) come out above main dungeon (dnum 0) */
2791 if (In_endgame(&u.uz))
2792 traverse_mapseenchn(TRUE, win, why, reason, &lastdun);
2793 /* if game is over or we're not in the endgame yet, show the dungeon */
2794 if (why > 0 || !In_endgame(&u.uz))
2795 traverse_mapseenchn(FALSE, win, why, reason, &lastdun);
2796 display_nhwindow(win, TRUE);
2797 destroy_nhwindow(win);
2800 /* display endgame levels or non-endgame levels, not both */
2802 traverse_mapseenchn(viewendgame, win, why, reason, lastdun_p)
2803 boolean viewendgame;
2805 int why, reason, *lastdun_p;
2810 for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2811 if (viewendgame ^ In_endgame(&mptr->lev))
2814 /* only print out info for a level or a dungeon if interest */
2815 if (why > 0 || interest_mapseen(mptr)) {
2816 showheader = (boolean) (mptr->lev.dnum != *lastdun_p);
2817 print_mapseen(win, mptr, why, reason, showheader);
2818 *lastdun_p = mptr->lev.dnum;
2823 STATIC_OVL const char *
2828 /* players are computer scientists: 0, 1, 2, n */
2831 /*JP:
\82±
\82±
\82É
\82Í
\97\88\82È
\82¢
\82Í
\82¸*/
2833 /* an() returns too much. index is ok in this case */
2836 return index(vowels, *obj) ? "an" : "a";
2843 return "
\93ñ
\82Â
\82Ì";
2848 return "
\91½
\82
\82Ì";
2854 /* better br_string */
2855 STATIC_OVL const char *
2859 /* Special case: quest portal says closed if kicked from quest */
2860 boolean closed_portal = (br->end2.dnum == quest_dnum
2861 && u.uevent.qexpelled);
2866 return closed_portal ? "Sealed portal" : "Portal";
2868 return closed_portal ? "
\95\95\88ó
\82³
\82ê
\82½
\96\82\96@
\82Ì
\93ü
\8cû" : "
\96\82\96@
\82Ì
\93ü
\8cû";
2870 return "Connection";
2873 return br->end1_up ? "One way stairs up" : "One way stairs down";
2875 return br->end1_up ? "
\8fã
\82è
\95Ð
\93¹
\8aK
\92i" : "
\89º
\82è
\95Ð
\93¹
\8aK
\92i";
2878 return br->end1_up ? "Stairs up" : "Stairs down";
2880 return br->end1_up ? "
\8fã
\82è
\8aK
\92i" : "
\89º
\82è
\8aK
\92i";
2886 /* get the name of an endgame level; topten.c does something similar */
2888 endgamelevelname(outbuf, indx)
2892 const char *planename = 0;
2898 Strcpy(outbuf, "Astral Plane");
2900 Strcpy(outbuf, "
\93V
\8fã
\8aE");
2904 planename = "Water";
2906 planename = "
\90\85";
2918 planename = "
\95\97";
2922 planename = "Earth";
2929 Sprintf(outbuf, "Plane of %s", planename);
2931 Sprintf(outbuf, "%s
\82Ì
\90¸
\97ì
\8aE", planename);
2933 Sprintf(outbuf, "unknown plane #%d", indx);
2937 STATIC_OVL const char *
2942 const char *str = "shop"; /* catchall */
2944 const char *str = "
\93X"; /* catchall */
2947 /* Yuck, redundancy...but shclass.name doesn't cut it as a noun */
2951 str = "untended shop";
2953 str = "
\95ú
\8aü
\82³
\82ê
\82½
\93X";
2954 break; /* see recalc_mapseen */
2957 str = "general store";
2959 str = "
\8eG
\89Ý
\93X";
2965 str = "
\96h
\8bï
\93X";
2969 str = "scroll shop";
2971 str = "
\8aª
\95¨
\93X";
2975 str = "potion shop";
2981 str = "weapon shop";
2983 str = "
\95\90\8aí
\93X";
2987 str = "delicatessen";
2989 str = "
\90H
\97¿
\95i
\93X";
2995 str = "
\95ó
\90Î
\93X";
3011 str = "health food store";
3013 str = "
\8c\92\8dN
\90H
\95i
\93X";
3017 str = "lighting shop";
3019 str = "
\8fÆ
\96¾
\93X";
3027 /* if player knows about the mastermind tune, append it to Castle annotation;
3028 if drawbridge has been destroyed, flags.castletune will be zero */
3030 tunesuffix(mptr, outbuf)
3035 if (mptr->flags.castletune && u.uevent.uheard_tune) {
3038 if (u.uevent.uheard_tune == 2)
3039 Sprintf(tmp, "notes \"%s\"", tune);
3041 Strcpy(tmp, "5-note tune");
3042 Sprintf(outbuf, " (play %s to open or close drawbridge)", tmp);
3047 /* some utility macros for print_mapseen */
3048 #define TAB " " /* three spaces */
3050 #define BULLET "" /* empty; otherwise output becomes cluttered */
3051 #define PREFIX TAB TAB BULLET
3053 /* K&R: don't require support for concatenation of adjacent string literals */
3054 #define PREFIX " " /* two TABs + empty BULLET: six spaces */
3056 #define COMMA (i++ > 0 ? ", " : PREFIX)
3057 /* "iterate" once; safe to use as ``if (cond) ADDTOBUF(); else whatever;'' */
3059 #define ADDNTOBUF(nam, var) \
3062 Sprintf(eos(buf), "%s%s %s%s", COMMA, seen_string((var), (nam)), \
3063 (nam), plur(var)); \
3066 #define ADDNTOBUF(nam, var) \
3069 Sprintf(eos(buf), "%s%s%s", COMMA, seen_string((var), (nam)), \
3073 #define ADDTOBUF(nam, var) \
3076 Sprintf(eos(buf), "%s%s", COMMA, (nam)); \
3080 print_mapseen(win, mptr, final, how, printdun)
3083 int final; /* 0: not final; 1: game over, alive; 2: game over, dead */
3084 int how; /* cause of death; only used if final==2 and mptr->lev==u.uz */
3087 char buf[BUFSZ], tmpbuf[BUFSZ];
3088 int i, depthstart, dnum;
3089 boolean died_here = (final == 2 && on_level(&u.uz, &mptr->lev));
3091 /* Damnable special cases */
3092 /* The quest and knox should appear to be level 1 to match
3095 dnum = mptr->lev.dnum;
3096 if (dnum == quest_dnum || dnum == knox_level.dnum)
3099 depthstart = dungeons[dnum].depth_start;
3102 if (dungeons[dnum].dunlev_ureached == dungeons[dnum].entry_lev
3103 /* suppress the negative numbers in the endgame */
3104 || In_endgame(&mptr->lev))
3105 Sprintf(buf, "%s:", dungeons[dnum].dname);
3106 else if (builds_up(&mptr->lev))
3108 Sprintf(buf, "%s: levels %d up to %d",
3110 Sprintf(buf, "%s: %d
\8aK
\82©
\82ç%d
\8aK",
3111 dungeons[dnum].dname,
3112 depthstart + dungeons[dnum].entry_lev - 1,
3113 depthstart + dungeons[dnum].dunlev_ureached - 1);
3116 Sprintf(buf, "%s: levels %d to %d",
3118 Sprintf(buf, "%s: %d
\8aK
\82©
\82ç%d
\8aK",
3119 dungeons[dnum].dname, depthstart,
3120 depthstart + dungeons[dnum].dunlev_ureached - 1);
3121 putstr(win, !final ? ATR_INVERSE : 0, buf);
3124 /* calculate level number */
3125 i = depthstart + mptr->lev.dlevel - 1;
3126 if (In_endgame(&mptr->lev))
3127 Sprintf(buf, "%s%s:", TAB, endgamelevelname(tmpbuf, i));
3130 Sprintf(buf, "%sLevel %d:", TAB, i);
3132 Sprintf(buf, "%s%d
\8aK:", TAB, i);
3134 /* wizmode prints out proto dungeon names for clarity */
3138 if ((slev = Is_special(&mptr->lev)) != 0)
3139 Sprintf(eos(buf), " [%s]", slev->proto);
3141 /* [perhaps print custom annotation on its own line when it's long] */
3143 Sprintf(eos(buf), " \"%s\"", mptr->custom);
3144 if (on_level(&u.uz, &mptr->lev))
3146 Sprintf(eos(buf), " <- You %s here.",
3147 (!final || (final == 1 && how == ASCENDED)) ? "are"
3148 : (final == 1 && how == ESCAPED) ? "left from"
3151 Sprintf(eos(buf), " <-
\82±
\82±%s
\81D",
3152 (!final || (final == 1 && how == ASCENDED)) ? "
\82É
\82¢
\82é"
3153 : (final == 1 && how == ESCAPED) ? "
\82©
\82ç
\94²
\82¯
\82½"
3156 putstr(win, !final ? ATR_BOLD : 0, buf);
3158 if (mptr->flags.forgot)
3161 if (INTEREST(mptr->feat)) {
3164 i = 0; /* interest counter */
3165 /* List interests in an order vaguely corresponding to
3166 * how important they are.
3168 if (mptr->feat.nshop > 0) {
3169 if (mptr->feat.nshop > 1)
3171 ADDNTOBUF("shop", mptr->feat.nshop);
3173 ADDNTOBUF("
\93X", mptr->feat.nshop);
3175 Sprintf(eos(buf), "%s%s", COMMA,
3176 an(shop_string(mptr->feat.shoptype)));
3178 if (mptr->feat.naltar > 0) {
3179 /* Temples + non-temple altars get munged into just "altars" */
3180 if (mptr->feat.ntemple != mptr->feat.naltar)
3182 ADDNTOBUF("altar", mptr->feat.naltar);
3184 ADDNTOBUF("
\8dÕ
\92d", mptr->feat.naltar);
3187 ADDNTOBUF("temple", mptr->feat.ntemple);
3189 ADDNTOBUF("
\8e\9b\89@", mptr->feat.ntemple);
3191 /* only print out altar's god if they are all to your god */
3192 if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
3194 Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
3196 Sprintf(eos(buf), "(%s)", align_gname(u.ualign.type));
3199 ADDNTOBUF("throne", mptr->feat.nthrone);
3201 ADDNTOBUF("
\8bÊ
\8dÀ", mptr->feat.nthrone);
3203 ADDNTOBUF("fountain", mptr->feat.nfount);
3205 ADDNTOBUF("
\90ò", mptr->feat.nfount);
3207 ADDNTOBUF("sink", mptr->feat.nsink);
3209 ADDNTOBUF("
\97¬
\82µ
\91ä", mptr->feat.nsink);
3211 ADDNTOBUF("grave", mptr->feat.ngrave);
3213 ADDNTOBUF("
\95æ", mptr->feat.ngrave);
3215 ADDNTOBUF("tree", mptr->feat.ntree);
3217 ADDNTOBUF("
\96Ø", mptr->feat.ntree);
3219 ADDTOBUF("water", mptr->feat.water);
3220 ADDTOBUF("lava", mptr->feat.lava);
3221 ADDTOBUF("ice", mptr->feat.ice);
3223 /* capitalize afterwards */
3225 buf[i] = highc(buf[i]);
3226 /* capitalizing it makes it a sentence; terminate with '.' */
3228 putstr(win, 0, buf);
3231 /* we assume that these are mutually exclusive */
3233 if (mptr->flags.oracle) {
3235 Sprintf(buf, "%sOracle of Delphi.", PREFIX);
3237 Sprintf(buf, "%s
\83f
\83\8b\83t
\83@
\83C
\82Ì
\90_
\93a
\81D", PREFIX);
3238 } else if (In_sokoban(&mptr->lev)) {
3240 Sprintf(buf, "%s%s.", PREFIX,
3241 mptr->flags.sokosolved ? "Solved" : "Unsolved");
3243 Sprintf(buf, "%s%s.", PREFIX,
3244 mptr->flags.sokosolved ? "
\83N
\83\8a\83A
\8dÏ" : "
\96¢
\83N
\83\8a\83A");
3246 } else if (mptr->flags.bigroom) {
3248 Sprintf(buf, "%sA very big room.", PREFIX);
3250 Sprintf(buf, "%s
\82Æ
\82Ä
\82à
\91å
\82«
\82¢
\95\94\89®
\81D", PREFIX);
3251 } else if (mptr->flags.roguelevel) {
3253 Sprintf(buf, "%sA primitive area.", PREFIX);
3255 Sprintf(buf, "%s
\92P
\8f\83\82È
\95\94\89®
\81D", PREFIX);
3256 } else if (on_level(&mptr->lev, &qstart_level)) {
3258 Sprintf(buf, "%sHome%s.", PREFIX,
3259 mptr->flags.unreachable ? " (no way back...)" : "");
3261 Sprintf(buf, "%s
\8cÌ
\8b½%s
\81D", PREFIX,
3262 mptr->flags.unreachable ? "(
\96ß
\82ê
\82È
\82¢
\81D
\81D
\81D)" : "");
3264 if (u.uevent.qcompleted)
3266 Sprintf(buf, "%sCompleted quest for %s.", PREFIX, ldrname());
3268 Sprintf(buf, "%s%s
\82Ì
\82½
\82ß
\82É
\83N
\83G
\83X
\83g
\82ð
\8a®
\90\8b\82µ
\82½
\81D", PREFIX, ldrname());
3269 else if (mptr->flags.questing)
3271 Sprintf(buf, "%sGiven quest by %s.", PREFIX, ldrname());
3273 Sprintf(buf, "%s%s
\82©
\82ç
\83N
\83G
\83X
\83g
\82ð
\97^
\82¦
\82ç
\82ê
\82½
\81D", PREFIX, ldrname());
3274 } else if (mptr->flags.ludios) {
3275 /* presence of the ludios branch in #overview output indicates that
3276 the player has made it onto the level; presence of this annotation
3277 indicates that the fort's entrance has been seen (or mapped) */
3279 Sprintf(buf, "%sFort Ludios.", PREFIX);
3281 Sprintf(buf, "%s
\83\8d\81[
\83f
\83B
\83I
\83X
\8dÔ
\81D", PREFIX);
3282 } else if (mptr->flags.castle) {
3284 Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
3286 Sprintf(buf, "%s
\8fé%s
\81D", PREFIX, tunesuffix(mptr, tmpbuf));
3287 } else if (mptr->flags.valley) {
3289 Sprintf(buf, "%sValley of the Dead.", PREFIX);
3291 Sprintf(buf, "%s
\8e\80\82Ì
\92J
\81D", PREFIX);
3292 } else if (mptr->flags.msanctum) {
3294 Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
3296 Sprintf(buf, "%s
\83\82\81[
\83\8d\83b
\83N
\82Ì
\90¹
\88æ
\81D", PREFIX);
3299 putstr(win, 0, buf);
3300 /* quest entrance is not mutually-exclusive with bigroom or rogue level */
3301 if (mptr->flags.quest_summons) {
3303 Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
3305 Sprintf(buf, "%s%s
\82©
\82ç
\8cÄ
\82Ñ
\8fo
\82³
\82ê
\82½
\81D", PREFIX, ldrname());
3306 putstr(win, 0, buf);
3309 /* print out branches */
3312 Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br),
3313 dungeons[mptr->br->end2.dnum].dname);
3315 Sprintf(buf, "%s%s
\82Ö
\82Ì%s", PREFIX, dungeons[mptr->br->end2.dnum].dname,
3316 br_string2(mptr->br));
3319 /* Since mapseen objects are printed out in increasing order
3320 * of dlevel, clarify which level this branch is going to
3321 * if the branch goes upwards. Unless it's the end game.
3323 if (mptr->br->end1_up && !In_endgame(&(mptr->br->end2)))
3325 Sprintf(eos(buf), ", level %d", depth(&(mptr->br->end2)));
3327 Sprintf(eos(buf), ", %d
\8aK", depth(&(mptr->br->end2)));
3329 putstr(win, 0, buf);
3332 /* maybe print out bones details */
3333 if (mptr->final_resting_place || final) {
3334 struct cemetery *bp;
3335 int kncnt = !died_here ? 0 : 1;
3337 for (bp = mptr->final_resting_place; bp; bp = bp->next)
3338 if (bp->bonesknown || wizard || final)
3342 Sprintf(buf, "%s%s", PREFIX, "Final resting place for");
3344 Sprintf(buf, "%s%s", PREFIX, "
\8dÅ
\8aú
\82Ì
\92n:");
3345 putstr(win, 0, buf);
3347 /* disclosure occurs before bones creation, so listing dead
3348 hero here doesn't give away whether bones are produced */
3349 formatkiller(tmpbuf, sizeof tmpbuf, how, TRUE);
3351 /* rephrase a few death reasons to work with "you" */
3352 (void) strsubst(tmpbuf, " himself", " yourself");
3353 (void) strsubst(tmpbuf, " herself", " yourself");
3354 (void) strsubst(tmpbuf, " his ", " your ");
3355 (void) strsubst(tmpbuf, " her ", " your ");
3358 Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf,
3359 --kncnt ? ',' : '.');
3361 Sprintf(buf, "%s%s %s%c", PREFIX, TAB, tmpbuf,
3362 --kncnt ? ',' : '.');
3364 putstr(win, 0, buf);
3366 for (bp = mptr->final_resting_place; bp; bp = bp->next) {
3367 if (bp->bonesknown || wizard || final) {
3368 Sprintf(buf, "%s%s%s, %s%c", PREFIX, TAB, bp->who,
3369 bp->how, --kncnt ? ',' : '.');
3370 putstr(win, 0, buf);