1 /* NetHack 3.6 dungeon.c $NHDT-Date: 1523308357 2018/04/09 21:12:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.87 $ */
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(endgamelevelname, (char *, int));
75 STATIC_DCL const char *FDECL(shop_string, (int));
76 STATIC_DCL char *FDECL(tunesuffix, (mapseen *, char *));
79 #define DD dungeons[i]
80 STATIC_DCL void NDECL(dumpit);
89 if (!explicitdebug(__FILE__))
92 for (i = 0; i < n_dgns; i++) {
93 fprintf(stderr, "\n#%d \"%s\" (%s):\n", i, DD.dname, DD.proto);
94 fprintf(stderr, " num_dunlevs %d, dunlev_ureached %d\n",
95 DD.num_dunlevs, DD.dunlev_ureached);
96 fprintf(stderr, " depth_start %d, ledger_start %d\n",
97 DD.depth_start, DD.ledger_start);
98 fprintf(stderr, " flags:%s%s%s\n",
99 DD.flags.rogue_like ? " rogue_like" : "",
100 DD.flags.maze_like ? " maze_like" : "",
101 DD.flags.hellish ? " hellish" : "");
104 fprintf(stderr, "\nSpecial levels:\n");
105 for (x = sp_levchn; x; x = x->next) {
106 fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs);
107 fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel);
108 fprintf(stderr, "flags:%s%s%s%s\n",
109 x->flags.rogue_like ? " rogue_like" : "",
110 x->flags.maze_like ? " maze_like" : "",
111 x->flags.hellish ? " hellish" : "",
112 x->flags.town ? " town" : "");
115 fprintf(stderr, "\nBranches:\n");
116 for (br = branches; br; br = br->next) {
117 fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n", br->id,
120 : br->type == BR_NO_END1
122 : br->type == BR_NO_END2
124 : br->type == BR_PORTAL
127 br->end1.dnum, br->end1.dlevel, br->end2.dnum,
128 br->end2.dlevel, br->end1_up ? "end1 up" : "end1 down");
131 fprintf(stderr, "\nDone\n");
136 /* Save the dungeon structures. */
138 save_dungeon(fd, perform_write, free_data)
140 boolean perform_write, free_data;
143 mapseen *curr_ms, *next_ms;
147 bwrite(fd, (genericptr_t) &n_dgns, sizeof n_dgns);
148 bwrite(fd, (genericptr_t) dungeons,
149 sizeof(dungeon) * (unsigned) n_dgns);
150 bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
151 bwrite(fd, (genericptr_t) tune, sizeof tune);
153 for (count = 0, curr = branches; curr; curr = curr->next)
155 bwrite(fd, (genericptr_t) &count, sizeof(count));
157 for (curr = branches; curr; curr = curr->next)
158 bwrite(fd, (genericptr_t) curr, sizeof(branch));
160 count = maxledgerno();
161 bwrite(fd, (genericptr_t) &count, sizeof count);
162 bwrite(fd, (genericptr_t) level_info,
163 (unsigned) count * sizeof(struct linfo));
164 bwrite(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
166 for (count = 0, curr_ms = mapseenchn; curr_ms;
167 curr_ms = curr_ms->next)
169 bwrite(fd, (genericptr_t) &count, sizeof(count));
171 for (curr_ms = mapseenchn; curr_ms; curr_ms = curr_ms->next)
172 save_mapseen(fd, curr_ms);
176 for (curr = branches; curr; curr = next) {
178 free((genericptr_t) curr);
181 for (curr_ms = mapseenchn; curr_ms; curr_ms = next_ms) {
182 next_ms = curr_ms->next;
184 free((genericptr_t) curr_ms->custom);
185 free((genericptr_t) curr_ms);
191 /* Restore the dungeon structures. */
198 mapseen *curr_ms, *last_ms;
200 mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
201 mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned) n_dgns);
202 mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
203 mread(fd, (genericptr_t) tune, sizeof tune);
205 last = branches = (branch *) 0;
207 mread(fd, (genericptr_t) &count, sizeof(count));
208 for (i = 0; i < count; i++) {
209 curr = (branch *) alloc(sizeof(branch));
210 mread(fd, (genericptr_t) curr, sizeof(branch));
211 curr->next = (branch *) 0;
219 mread(fd, (genericptr_t) &count, sizeof(count));
220 if (count >= MAXLINFO)
221 panic("level information count larger (%d) than allocated size",
223 mread(fd, (genericptr_t) level_info,
224 (unsigned) count * sizeof(struct linfo));
225 mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
227 mread(fd, (genericptr_t) &count, sizeof(count));
228 last_ms = (mapseen *) 0;
229 for (i = 0; i < count; i++) {
230 curr_ms = load_mapseen(fd);
231 curr_ms->next = (mapseen *) 0;
233 last_ms->next = curr_ms;
235 mapseenchn = curr_ms;
241 Fread(ptr, size, nitems, stream)
248 if ((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) {
250 "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.",
251 (size * nitems), (size * cnt));
252 nh_terminate(EXIT_FAILURE);
262 for (i = 0; i < n_dgns; i++)
263 if (!strcmp(dungeons[i].dname, s))
266 panic("Couldn't resolve dungeon number for name \"%s\".", s);
276 for (curr = sp_levchn; curr; curr = curr->next)
277 if (!strcmpi(s, curr->proto))
282 /* Find the branch that links the named dungeon. */
285 const char *s; /* dungeon name */
286 struct proto_dungeon *pd;
291 for (i = 0; i < pd->n_brs; i++)
292 if (!strcmp(pd->tmpbranch[i].name, s))
295 panic("find_branch: can't find %s", s);
297 /* support for level tport by name */
301 for (br = branches; br; br = br->next) {
302 dnam = dungeons[br->end2.dnum].dname;
303 if (!strcmpi(dnam, s)
304 || (!strncmpi(dnam, "The ", 4) && !strcmpi(dnam + 4, s)))
307 i = br ? ((ledger_no(&br->end1) << 8) | ledger_no(&br->end2)) : -1;
313 * Find the "parent" by searching the prototype branch list for the branch
314 * listing, then figuring out to which dungeon it belongs.
318 const char *s; /* dungeon name */
319 struct proto_dungeon *pd;
324 i = find_branch(s, pd);
326 * Got branch, now find parent dungeon. Stop if we have reached
327 * "this" dungeon (if we haven't found it by now it is an error).
329 for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++)
330 if ((i -= pd->tmpdungeon[pdnum].branches) < 0)
333 panic("parent_dnum: couldn't resolve branch.");
339 * Return a starting point and number of successive positions a level
340 * or dungeon entrance can occupy.
342 * Note: This follows the acouple (instead of the rcouple) rules for a
343 * negative random component (randc < 0). These rules are found
344 * in dgn_comp.y. The acouple [absolute couple] section says that
345 * a negative random component means from the (adjusted) base to the
346 * end of the dungeon.
349 level_range(dgn, base, randc, chain, pd, adjusted_base)
351 int base, randc, chain;
352 struct proto_dungeon *pd;
355 int lmax = dungeons[dgn].num_dunlevs;
357 if (chain >= 0) { /* relative to a special level */
358 s_level *levtmp = pd->final_lev[chain];
360 panic("level_range: empty chain level!");
362 base += levtmp->dlevel.dlevel;
363 } else { /* absolute in the dungeon */
364 /* from end of dungeon */
366 base = (lmax + base + 1);
369 if (base < 1 || base > lmax)
370 panic("level_range: base value out of range");
372 *adjusted_base = base;
374 if (randc == -1) { /* from base to end of dungeon */
375 return (lmax - base + 1);
377 /* make sure we don't run off the end of the dungeon */
378 return (((base + randc - 1) > lmax) ? lmax - base + 1 : randc);
379 } /* else only one choice */
386 struct proto_dungeon *pd;
388 int i, j, num, base, dnum = parent_dnum(s, pd);
391 i = find_branch(s, pd);
392 num = level_range(dnum, pd->tmpbranch[i].lev.base,
393 pd->tmpbranch[i].lev.rand, pd->tmpbranch[i].chain, pd,
396 /* KMH -- Try our best to find a level without an existing branch */
401 for (curr = branches; curr; curr = curr->next)
402 if ((curr->end1.dnum == dnum && curr->end1.dlevel == base + i)
403 || (curr->end2.dnum == dnum && curr->end2.dlevel == base + i))
405 } while (curr && i != j);
409 /* Convert from the temporary branch type to the dungeon branch type. */
411 correct_branch_type(tbr)
412 struct tmpbranch *tbr;
418 return tbr->up ? BR_NO_END1 : BR_NO_END2;
420 return tbr->up ? BR_NO_END2 : BR_NO_END1;
424 impossible("correct_branch_type: unknown branch type");
429 * Add the given branch to the branch list. The branch list is ordered
430 * by end1 dungeon and level followed by end2 dungeon and level. If
431 * extract_first is true, then the branch is already part of the list
432 * but needs to be repositioned.
435 insert_branch(new_branch, extract_first)
437 boolean extract_first;
440 long new_val, curr_val, prev_val;
443 for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next)
444 if (curr == new_branch)
448 panic("insert_branch: not found");
450 prev->next = curr->next;
452 branches = curr->next;
454 new_branch->next = (branch *) 0;
456 /* Convert the branch into a unique number so we can sort them. */
457 #define branch_val(bp) \
458 ((((long) (bp)->end1.dnum * (MAXLEVEL + 1) + (long) (bp)->end1.dlevel) \
459 * (MAXDUNGEON + 1) * (MAXLEVEL + 1)) \
460 + ((long) (bp)->end2.dnum * (MAXLEVEL + 1) + (long) (bp)->end2.dlevel))
463 * Insert the new branch into the correct place in the branch list.
467 new_val = branch_val(new_branch);
468 for (curr = branches; curr;
469 prev_val = curr_val, prev = curr, curr = curr->next) {
470 curr_val = branch_val(curr);
471 if (prev_val < new_val && new_val <= curr_val)
475 new_branch->next = curr;
476 prev->next = new_branch;
478 new_branch->next = branches;
479 branches = new_branch;
483 /* Add a dungeon branch to the branch list. */
485 add_branch(dgn, child_entry_level, pd)
487 int child_entry_level;
488 struct proto_dungeon *pd;
490 static int branch_id = 0;
494 branch_num = find_branch(dungeons[dgn].dname, pd);
495 new_branch = (branch *) alloc(sizeof(branch));
496 (void) memset((genericptr_t)new_branch, 0, sizeof(branch));
497 new_branch->next = (branch *) 0;
498 new_branch->id = branch_id++;
499 new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]);
500 new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd);
501 new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd);
502 new_branch->end2.dnum = dgn;
503 new_branch->end2.dlevel = child_entry_level;
504 new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE;
506 insert_branch(new_branch, FALSE);
511 * Add new level to special level chain. Insert it in level order with the
512 * other levels in this dungeon. This assumes that we are never given a
513 * level that has a dungeon number less than the dungeon number of the
520 s_level *prev, *curr;
522 prev = (s_level *) 0;
523 for (curr = sp_levchn; curr; curr = curr->next) {
524 if (curr->dlevel.dnum == new_lev->dlevel.dnum
525 && curr->dlevel.dlevel > new_lev->dlevel.dlevel)
530 new_lev->next = sp_levchn;
533 new_lev->next = curr;
534 prev->next = new_lev;
539 init_level(dgn, proto_index, pd)
540 int dgn, proto_index;
541 struct proto_dungeon *pd;
544 struct tmplevel *tlevel = &pd->tmplevel[proto_index];
546 pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */
547 if (!wizard && tlevel->chance <= rn2(100))
550 pd->final_lev[proto_index] = new_level =
551 (s_level *) alloc(sizeof(s_level));
552 (void) memset((genericptr_t)new_level, 0, sizeof(s_level));
553 /* load new level with data */
554 Strcpy(new_level->proto, tlevel->name);
555 new_level->boneid = tlevel->boneschar;
556 new_level->dlevel.dnum = dgn;
557 new_level->dlevel.dlevel = 0; /* for now */
559 new_level->flags.town = !!(tlevel->flags & TOWN);
560 new_level->flags.hellish = !!(tlevel->flags & HELLISH);
561 new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE);
562 new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE);
563 new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4);
564 if (!new_level->flags.align)
565 new_level->flags.align =
566 ((pd->tmpdungeon[dgn].flags & D_ALIGN_MASK) >> 4);
568 new_level->rndlevs = tlevel->rndlevs;
569 new_level->next = (s_level *) 0;
573 possible_places(idx, map, pd)
574 int idx; /* prototype index */
575 boolean *map; /* array MAXLEVEL+1 in length */
576 struct proto_dungeon *pd;
579 s_level *lev = pd->final_lev[idx];
581 /* init level possibilities */
582 for (i = 0; i <= MAXLEVEL; i++)
585 /* get base and range and set those entries to true */
586 count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,
587 pd->tmplevel[idx].lev.rand, pd->tmplevel[idx].chain,
589 for (i = start; i < start + count; i++)
592 /* mark off already placed levels */
593 for (i = pd->start; i < idx; i++) {
594 if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) {
595 map[pd->final_lev[i]->dlevel.dlevel] = FALSE;
603 /* Pick the nth TRUE entry in the given boolean array. */
606 boolean *map; /* an array MAXLEVEL+1 in size */
610 for (i = 1; i <= MAXLEVEL; i++)
611 if (map[i] && !nth--)
613 panic("pick_level: ran out of valid levels");
618 static void FDECL(indent, (int));
630 * Place a level. First, find the possible places on a dungeon map
631 * template. Next pick one. Then try to place the next level. If
632 * successful, we're done. Otherwise, try another (and another) until
633 * all possible places have been tried. If all possible places have
634 * been exhausted, return false.
637 place_level(proto_index, pd)
639 struct proto_dungeon *pd;
641 boolean map[MAXLEVEL + 1]; /* valid levels are 1..MAXLEVEL inclusive */
648 if (proto_index == pd->n_levs)
649 return TRUE; /* at end of proto levels */
651 lev = pd->final_lev[proto_index];
653 /* No level created for this prototype, goto next. */
655 return place_level(proto_index + 1, pd);
657 npossible = possible_places(proto_index, map, pd);
659 for (; npossible; --npossible) {
660 lev->dlevel.dlevel = pick_level(map, rn2(npossible));
662 indent(proto_index - pd->start);
663 fprintf(stderr, "%s: trying %d [ ", lev->proto, lev->dlevel.dlevel);
664 for (i = 1; i <= MAXLEVEL; i++)
666 fprintf(stderr, "%d ", i);
667 fprintf(stderr, "]\n");
669 if (place_level(proto_index + 1, pd))
671 map[lev->dlevel.dlevel] = FALSE; /* this choice didn't work */
674 indent(proto_index - pd->start);
675 fprintf(stderr, "%s: failed\n", lev->proto);
681 const char *lev_name;
683 } level_map[] = { { "air", &air_level },
684 { "asmodeus", &asmodeus_level },
685 { "astral", &astral_level },
686 { "baalz", &baalzebub_level },
687 { "bigrm", &bigroom_level },
688 { "castle", &stronghold_level },
689 { "earth", &earth_level },
690 { "fakewiz1", &portal_level },
691 { "fire", &fire_level },
692 { "juiblex", &juiblex_level },
693 { "knox", &knox_level },
694 { "medusa", &medusa_level },
695 { "oracle", &oracle_level },
696 { "orcus", &orcus_level },
697 { "rogue", &rogue_level },
698 { "sanctum", &sanctum_level },
699 { "valley", &valley_level },
700 { "water", &water_level },
701 { "wizard1", &wiz1_level },
702 { "wizard2", &wiz2_level },
703 { "wizard3", &wiz3_level },
704 { "minend", &mineend_level },
705 { "soko1", &sokoend_level },
706 { X_START, &qstart_level },
707 { X_LOCATE, &qlocate_level },
708 { X_GOAL, &nemesis_level },
709 { "", (d_level *) 0 } };
711 /* initialize the "dungeon" structs */
716 register int i, cl = 0, cb = 0;
718 struct proto_dungeon pd;
719 struct level_map *lev_map;
720 struct version_info vers_info;
722 pd.n_levs = pd.n_brs = 0;
724 dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE);
727 Sprintf(tbuf, "Cannot open dungeon description - \"%s", DUNGEON_FILE);
728 #ifdef DLBRSRC /* using a resource from the executable */
729 Strcat(tbuf, "\" resource!");
730 #else /* using a file or DLB file */
732 Strcat(tbuf, "\" from ");
733 #ifdef PREFIXES_IN_USE
734 Strcat(tbuf, "\n\"");
735 if (fqn_prefix[DATAPREFIX])
736 Strcat(tbuf, fqn_prefix[DATAPREFIX]);
740 Strcat(tbuf, DLBFILE);
742 Strcat(tbuf, "\" file!");
745 interject_assistance(1, INTERJECT_PANIC, (genericptr_t) tbuf,
746 (genericptr_t) fqn_prefix[DATAPREFIX]);
751 /* validate the data's version against the program's version */
752 Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file);
753 /* we'd better clear the screen now, since when error messages come from
754 * check_version() they will be printed using pline(), which doesn't
755 * mix with the raw messages that might be already on the screen
757 if (iflags.window_inited)
758 clear_nhwindow(WIN_MAP);
759 if (!check_version(&vers_info, DUNGEON_FILE, TRUE))
760 panic("Dungeon description not valid.");
763 * Read in each dungeon and transfer the results to the internal
766 sp_levchn = (s_level *) 0;
767 Fread((genericptr_t) &n_dgns, sizeof(int), 1, dgn_file);
768 if (n_dgns >= MAXDUNGEON)
769 panic("init_dungeons: too many dungeons");
771 for (i = 0; i < n_dgns; i++) {
772 Fread((genericptr_t) &pd.tmpdungeon[i], sizeof(struct tmpdungeon), 1,
774 if (!wizard && pd.tmpdungeon[i].chance
775 && (pd.tmpdungeon[i].chance <= rn2(100))) {
778 /* skip over any levels or branches */
779 for (j = 0; j < pd.tmpdungeon[i].levels; j++)
780 Fread((genericptr_t) &pd.tmplevel[cl],
781 sizeof(struct tmplevel), 1, dgn_file);
783 for (j = 0; j < pd.tmpdungeon[i].branches; j++)
784 Fread((genericptr_t) &pd.tmpbranch[cb],
785 sizeof(struct tmpbranch), 1, dgn_file);
791 Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name);
792 Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname);
793 dungeons[i].boneid = pd.tmpdungeon[i].boneschar;
795 if (pd.tmpdungeon[i].lev.rand)
796 dungeons[i].num_dunlevs = (xchar) rn1(pd.tmpdungeon[i].lev.rand,
797 pd.tmpdungeon[i].lev.base);
799 dungeons[i].num_dunlevs = (xchar) pd.tmpdungeon[i].lev.base;
802 dungeons[i].ledger_start = 0;
803 dungeons[i].depth_start = 1;
804 dungeons[i].dunlev_ureached = 1;
806 dungeons[i].ledger_start =
807 dungeons[i - 1].ledger_start + dungeons[i - 1].num_dunlevs;
808 dungeons[i].dunlev_ureached = 0;
811 dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH);
812 dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE);
813 dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE);
814 dungeons[i].flags.align =
815 ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4);
817 * Set the entry level for this dungeon. The pd.tmpdungeon entry
819 * < 0 from bottom (-1 == bottom level)
821 * > 0 actual level (1 = top)
823 * Note that the entry_lev field in the dungeon structure is
824 * redundant. It is used only here and in print_dungeon().
826 if (pd.tmpdungeon[i].entry_lev < 0) {
827 dungeons[i].entry_lev =
828 dungeons[i].num_dunlevs + pd.tmpdungeon[i].entry_lev + 1;
829 if (dungeons[i].entry_lev <= 0)
830 dungeons[i].entry_lev = 1;
831 } else if (pd.tmpdungeon[i].entry_lev > 0) {
832 dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
833 if (dungeons[i].entry_lev > dungeons[i].num_dunlevs)
834 dungeons[i].entry_lev = dungeons[i].num_dunlevs;
835 } else { /* default */
836 dungeons[i].entry_lev = 1; /* defaults to top level */
839 if (i) { /* set depth */
844 br = add_branch(i, dungeons[i].entry_lev, &pd);
846 /* Get the depth of the connecting end. */
847 if (br->end1.dnum == i) {
848 from_depth = depth(&br->end2);
849 from_up = !br->end1_up;
851 from_depth = depth(&br->end1);
852 from_up = br->end1_up;
856 * Calculate the depth of the top of the dungeon via
857 * its branch. First, the depth of the entry point:
859 * depth of branch from "parent" dungeon
860 * + -1 or 1 depending on an up or down stair or
863 * Followed by the depth of the top of the dungeon:
865 * - (entry depth - 1)
867 * We'll say that portals stay on the same depth.
869 dungeons[i].depth_start =
870 from_depth + (br->type == BR_PORTAL ? 0 : (from_up ? -1 : 1))
871 - (dungeons[i].entry_lev - 1);
874 /* this is redundant - it should have been flagged by dgn_comp */
875 if (dungeons[i].num_dunlevs > MAXLEVEL)
876 dungeons[i].num_dunlevs = MAXLEVEL;
878 pd.start = pd.n_levs; /* save starting point */
879 pd.n_levs += pd.tmpdungeon[i].levels;
880 if (pd.n_levs > LEV_LIMIT)
881 panic("init_dungeon: too many special levels");
883 * Read in the prototype special levels. Don't add generated
884 * special levels until they are all placed.
886 for (; cl < pd.n_levs; cl++) {
887 Fread((genericptr_t) &pd.tmplevel[cl], sizeof(struct tmplevel), 1,
889 init_level(i, cl, &pd);
892 * Recursively place the generated levels for this dungeon. This
893 * routine will attempt all possible combinations before giving
896 if (!place_level(pd.start, &pd))
897 panic("init_dungeon: couldn't place levels");
899 fprintf(stderr, "--- end of dungeon %d ---\n", i);
903 for (; pd.start < pd.n_levs; pd.start++)
904 if (pd.final_lev[pd.start])
905 add_level(pd.final_lev[pd.start]);
907 pd.n_brs += pd.tmpdungeon[i].branches;
908 if (pd.n_brs > BRANCH_LIMIT)
909 panic("init_dungeon: too many branches");
910 for (; cb < pd.n_brs; cb++)
911 Fread((genericptr_t) &pd.tmpbranch[cb], sizeof(struct tmpbranch),
914 (void) dlb_fclose(dgn_file);
916 for (i = 0; i < 5; i++)
917 tune[i] = 'A' + rn2(7);
921 * Find most of the special levels and dungeons so we can access their
924 for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) {
925 x = find_level(lev_map->lev_name);
927 assign_level(lev_map->lev_spec, &x->dlevel);
928 if (!strncmp(lev_map->lev_name, "x-", 2)) {
929 /* This is where the name substitution on the
930 * levels of the quest dungeon occur.
932 Sprintf(x->proto, "%s%s", urole.filecode,
933 &lev_map->lev_name[1]);
934 } else if (lev_map->lev_spec == &knox_level) {
937 * Kludge to allow floating Knox entrance. We
938 * specify a floating entrance by the fact that
939 * its entrance (end1) has a bogus dnum, namely
942 for (br = branches; br; br = br->next)
943 if (on_level(&br->end2, &knox_level))
947 br->end1.dnum = n_dgns;
948 /* adjust the branch's position on the list */
949 insert_branch(br, TRUE);
954 * I hate hardwiring these names. :-(
957 quest_dnum = dname_to_dnum("The Quest");
959 quest_dnum = dname_to_dnum("
\83N
\83G
\83X
\83g");
961 sokoban_dnum = dname_to_dnum("Sokoban");
963 sokoban_dnum = dname_to_dnum("
\91q
\8cÉ
\94Ô");
965 mines_dnum = dname_to_dnum("The Gnomish Mines");
967 mines_dnum = dname_to_dnum("
\83m
\81[
\83\80\82Ì
\8dz
\8eR");
969 tower_dnum = dname_to_dnum("Vlad's Tower");
971 tower_dnum = dname_to_dnum("
\83\94\83\89\83h
\8cò
\82Ì
\93\83");
973 /* one special fixup for dummy surface level */
974 if ((x = find_level("dummy")) != 0) {
976 /* the code above puts earth one level above dungeon level #1,
977 making the dummy level overlay level 1; but the whole reason
978 for having the dummy level is to make earth have depth -1
979 instead of 0, so adjust the start point to shift endgame up */
980 if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start)
981 dungeons[i].depth_start -= 1;
982 /* TODO: strip "dummy" out all the way here,
983 so that it's hidden from <ctrl/O> feedback. */
991 /* return the level number for lev in *this* dungeon */
999 /* return the lowest level number for *this* dungeon */
1001 dunlevs_in_dungeon(lev)
1004 return dungeons[lev->dnum].num_dunlevs;
1007 /* return the lowest level explored in the game*/
1009 deepest_lev_reached(noquest)
1012 /* this function is used for three purposes: to provide a factor
1013 * of difficulty in monster generation; to provide a factor of
1014 * difficulty in experience calculations (botl.c and end.c); and
1015 * to insert the deepest level reached in the game in the topten
1016 * display. the 'noquest' arg switch is required for the latter.
1018 * from the player's point of view, going into the Quest is _not_
1019 * going deeper into the dungeon -- it is going back "home", where
1020 * the dungeon starts at level 1. given the setup in dungeon.def,
1021 * the depth of the Quest (thought of as starting at level 1) is
1022 * never lower than the level of entry into the Quest, so we exclude
1023 * the Quest from the topten "deepest level reached" display
1024 * calculation. _However_ the Quest is a difficult dungeon, so we
1025 * include it in the factor of difficulty calculations.
1029 register schar ret = 0;
1031 for (i = 0; i < n_dgns; i++) {
1032 if (noquest && i == quest_dnum)
1034 tmp.dlevel = dungeons[i].dunlev_ureached;
1035 if (tmp.dlevel == 0)
1038 if (depth(&tmp) > ret)
1044 /* return a bookkeeping level number for purpose of comparisons and
1050 return (xchar) (lev->dlevel + dungeons[lev->dnum].ledger_start);
1054 * The last level in the bookkeeping list of level is the bottom of the last
1055 * dungeon in the dungeons[] array.
1057 * Maxledgerno() -- which is the max number of levels in the bookkeeping
1058 * list, should not be confused with dunlevs_in_dungeon(lev) -- which
1059 * returns the max number of levels in lev's dungeon, and both should
1060 * not be confused with deepest_lev_reached() -- which returns the lowest
1061 * depth visited by the player.
1066 return (xchar) (dungeons[n_dgns - 1].ledger_start
1067 + dungeons[n_dgns - 1].num_dunlevs);
1070 /* return the dungeon that this ledgerno exists in */
1072 ledger_to_dnum(ledgerno)
1077 /* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */
1078 for (i = 0; i < n_dgns; i++)
1079 if (dungeons[i].ledger_start < ledgerno
1080 && ledgerno <= dungeons[i].ledger_start + dungeons[i].num_dunlevs)
1083 panic("level number out of range [ledger_to_dnum(%d)]", (int) ledgerno);
1088 /* return the level of the dungeon this ledgerno exists in */
1090 ledger_to_dlev(ledgerno)
1093 return (xchar) (ledgerno
1094 - dungeons[ledger_to_dnum(ledgerno)].ledger_start);
1097 /* returns the depth of a level, in floors below the surface
1098 (note levels in different dungeons can have the same depth) */
1103 return (schar) (dungeons[lev->dnum].depth_start + lev->dlevel - 1);
1106 /* are "lev1" and "lev2" actually the same? */
1108 on_level(lev1, lev2)
1109 d_level *lev1, *lev2;
1111 return (boolean) (lev1->dnum == lev2->dnum
1112 && lev1->dlevel == lev2->dlevel);
1115 /* is this level referenced in the special level chain? */
1122 for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next)
1123 if (on_level(lev, &levtmp->dlevel))
1126 return (s_level *) 0;
1130 * Is this a multi-dungeon branch level? If so, return a pointer to the
1131 * branch. Otherwise, return null.
1139 for (curr = branches; curr; curr = curr->next) {
1140 if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2))
1143 return (branch *) 0;
1146 /* returns True iff the branch 'lev' is in a branch which builds up */
1151 dungeon *dptr = &dungeons[lev->dnum];
1153 * FIXME: this misclassifies a single level branch reached via stairs
1154 * from below. Saving grace is that no such branches currently exist.
1156 return (boolean) (dptr->num_dunlevs > 1
1157 && dptr->entry_lev == dptr->num_dunlevs);
1160 /* goto the next level (or appropriate dungeon) */
1162 next_level(at_stairs)
1165 if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
1166 /* Taking a down dungeon branch. */
1167 goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
1169 /* Going down a stairs or jump in a trap door. */
1172 newlevel.dnum = u.uz.dnum;
1173 newlevel.dlevel = u.uz.dlevel + 1;
1174 goto_level(&newlevel, at_stairs, !at_stairs, FALSE);
1178 /* goto the previous level (or appropriate dungeon) */
1180 prev_level(at_stairs)
1183 if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
1184 /* Taking an up dungeon branch. */
1185 /* KMH -- Upwards branches are okay if not level 1 */
1186 /* (Just make sure it doesn't go above depth 1) */
1187 if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
1190 goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
1192 /* Going up a stairs or rising through the ceiling. */
1194 newlevel.dnum = u.uz.dnum;
1195 newlevel.dlevel = u.uz.dlevel - 1;
1196 goto_level(&newlevel, at_stairs, FALSE, FALSE);
1207 cliparound(u.ux, u.uy);
1209 /* ridden steed always shares hero's location */
1211 u.usteed->mx = u.ux, u.usteed->my = u.uy;
1212 /* when changing levels, don't leave old position set with
1213 stale values from previous level */
1214 if (!on_level(&u.uz, &u.uz0))
1215 u.ux0 = u.ux, u.uy0 = u.uy;
1218 /* place you on a random location */
1220 u_on_rndspot(upflag)
1223 int up = (upflag & 1), was_in_W_tower = (upflag & 2);
1226 * Place the hero at a random location within the relevant region.
1227 * place_lregion(xTELE) -> put_lregion_here(xTELE) -> u_on_newpos()
1228 * Unspecified region (.lx == 0) defaults to entire level.
1230 if (was_in_W_tower && On_W_tower_level(&u.uz))
1231 /* Stay inside the Wizard's tower when feasible.
1232 We use the W Tower's exclusion region for the
1233 destination instead of its enclosing region.
1234 Note: up vs down doesn't matter in this case
1235 because both specify the same exclusion area. */
1236 place_lregion(dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
1237 0, 0, 0, 0, LR_DOWNTELE, (d_level *) 0);
1239 place_lregion(updest.lx, updest.ly, updest.hx, updest.hy,
1240 updest.nlx, updest.nly, updest.nhx, updest.nhy,
1241 LR_UPTELE, (d_level *) 0);
1243 place_lregion(dndest.lx, dndest.ly, dndest.hx, dndest.hy,
1244 dndest.nlx, dndest.nly, dndest.nhx, dndest.nhy,
1245 LR_DOWNTELE, (d_level *) 0);
1248 /* place you on the special staircase */
1250 u_on_sstairs(upflag)
1254 u_on_newpos(sstairs.sx, sstairs.sy);
1256 u_on_rndspot(upflag);
1259 /* place you on upstairs (or special equivalent) */
1264 u_on_newpos(xupstair, yupstair);
1266 u_on_sstairs(0); /* destination upstairs implies moving down */
1269 /* place you on dnstairs (or special equivalent) */
1274 u_on_newpos(xdnstair, ydnstair);
1276 u_on_sstairs(1); /* destination dnstairs implies moving up */
1283 return (boolean) ((x == xupstair && y == yupstair)
1284 || (x == xdnstair && y == ydnstair)
1285 || (x == xdnladder && y == ydnladder)
1286 || (x == xupladder && y == yupladder)
1287 || (x == sstairs.sx && y == sstairs.sy));
1294 return (boolean) (lev->dlevel == dungeons[lev->dnum].num_dunlevs);
1301 return (boolean) (!level.flags.hardfloor
1302 && !Is_botlevel(lev)
1303 && !Invocation_lev(lev));
1307 * Like Can_dig_down (above), but also allows falling through on the
1308 * stronghold level. Normally, the bottom level of a dungeon resists
1309 * both digging and falling.
1315 return (boolean) (Can_dig_down(lev) || Is_stronghold(lev));
1319 * True if one can rise up a level (e.g. cursed gain level).
1320 * This happens on intermediate dungeon levels or on any top dungeon
1321 * level that has a stairwell style branch to the next higher dungeon.
1322 * Checks for amulets and such must be done elsewhere.
1325 Can_rise_up(x, y, lev)
1329 /* can't rise up from inside the top of the Wizard's tower */
1330 /* KMH -- or in sokoban */
1331 if (In_endgame(lev) || In_sokoban(lev)
1332 || (Is_wiz1_level(lev) && In_W_tower(x, y, lev)))
1334 return (boolean) (lev->dlevel > 1
1335 || (dungeons[lev->dnum].entry_lev == 1
1336 && ledger_no(lev) != 1
1337 && sstairs.sx && sstairs.up));
1344 /* [what about level 1 of the quest?] */
1345 return (boolean) (!Is_airlevel(lev) && !Is_waterlevel(lev));
1349 * It is expected that the second argument of get_level is a depth value,
1350 * either supplied by the user (teleport control) or randomly generated.
1351 * But more than one level can be at the same depth. If the target level
1352 * is "above" the present depth location, get_level must trace "up" from
1353 * the player's location (through the ancestors dungeons) the dungeon
1354 * within which the target level is located. With only one exception
1355 * which does not pass through this routine (see level_tele), teleporting
1356 * "down" is confined to the current dungeon. At present, level teleport
1357 * in dungeons that build up is confined within them.
1360 get_level(newlevel, levnum)
1365 xchar dgn = u.uz.dnum;
1368 /* can only currently happen in endgame */
1369 levnum = u.uz.dlevel;
1371 > dungeons[dgn].depth_start + dungeons[dgn].num_dunlevs - 1) {
1372 /* beyond end of dungeon, jump to last level */
1373 levnum = dungeons[dgn].num_dunlevs;
1375 /* The desired level is in this dungeon or a "higher" one. */
1378 * Branch up the tree until we reach a dungeon that contains the
1381 if (levnum < dungeons[dgn].depth_start) {
1384 * Find the parent dungeon of this dungeon.
1386 * This assumes that end2 is always the "child" and it is
1389 for (br = branches; br; br = br->next)
1390 if (br->end2.dnum == dgn)
1393 panic("get_level: can't find parent dungeon");
1395 dgn = br->end1.dnum;
1396 } while (levnum < dungeons[dgn].depth_start);
1399 /* We're within the same dungeon; calculate the level. */
1400 levnum = levnum - dungeons[dgn].depth_start + 1;
1403 newlevel->dnum = dgn;
1404 newlevel->dlevel = levnum;
1407 /* are you in the quest dungeon? */
1412 return (boolean) (lev->dnum == quest_dnum);
1415 /* are you in the mines dungeon? */
1420 return (boolean) (lev->dnum == mines_dnum);
1424 * Return the branch for the given dungeon.
1426 * This function assumes:
1427 * + This is not called with "Dungeons of Doom".
1428 * + There is only _one_ branch to a given dungeon.
1429 * + Field end2 is the "child" dungeon.
1438 dnum = dname_to_dnum(s);
1440 /* Find the branch that connects to dungeon i's branch. */
1441 for (br = branches; br; br = br->next)
1442 if (br->end2.dnum == dnum)
1446 panic("dgn_entrance: can't find entrance to %s", s);
1452 * This returns true if the hero is on the same level as the entrance to
1453 * the named dungeon.
1455 * Called from do.c and mklev.c.
1457 * Assumes that end1 is always the "parent".
1465 br = dungeon_branch(s);
1466 return on_level(&u.uz, &br->end1) ? TRUE : FALSE;
1469 /* is `lev' part of Vlad's tower? */
1474 return (boolean) (lev->dnum == tower_dnum);
1477 /* is `lev' a level containing the Wizard's tower? */
1479 On_W_tower_level(lev)
1482 return (boolean) (Is_wiz1_level(lev)
1483 || Is_wiz2_level(lev)
1484 || Is_wiz3_level(lev));
1487 /* is <x,y> of `lev' inside the Wizard's tower? */
1489 In_W_tower(x, y, lev)
1493 if (!On_W_tower_level(lev))
1496 * Both of the exclusion regions for arriving via level teleport
1497 * (from above or below) define the tower's boundary.
1498 * assert( updest.nIJ == dndest.nIJ for I={l|h},J={x|y} );
1501 return (boolean) within_bounded_area(x, y, dndest.nlx, dndest.nly,
1502 dndest.nhx, dndest.nhy);
1504 impossible("No boundary for Wizard's Tower?");
1508 /* are you in one of the Hell levels? */
1513 return (boolean) (dungeons[lev->dnum].flags.hellish);
1516 /* sets *lev to be the gateway to Gehennom... */
1521 lev->dnum = valley_level.dnum;
1525 /* go directly to hell... */
1527 goto_hell(at_stairs, falling)
1528 boolean at_stairs, falling;
1533 goto_level(&lev, at_stairs, falling, FALSE);
1536 /* equivalent to dest = source */
1538 assign_level(dest, src)
1539 d_level *dest, *src;
1541 dest->dnum = src->dnum;
1542 dest->dlevel = src->dlevel;
1545 /* dest = src + rn1(range) */
1547 assign_rnd_level(dest, src, range)
1548 d_level *dest, *src;
1551 dest->dnum = src->dnum;
1552 dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range));
1554 if (dest->dlevel > dunlevs_in_dungeon(dest))
1555 dest->dlevel = dunlevs_in_dungeon(dest);
1556 else if (dest->dlevel < 1)
1564 s_level *lev = Is_special(&u.uz);
1567 if (lev && lev->flags.align)
1569 return lev->flags.align;
1571 if (dungeons[u.uz.dnum].flags.align)
1573 return dungeons[u.uz.dnum].flags.align;
1576 return Align2amask(al);
1583 return (boolean) (In_hell(lev)
1584 && lev->dlevel == dungeons[lev->dnum].num_dunlevs - 1);
1587 /* use instead of depth() wherever a degree of difficulty is made
1588 * dependent on the location in the dungeon (eg. monster creation).
1595 if (In_endgame(&u.uz)) {
1596 res = depth(&sanctum_level) + u.ulevel / 2;
1597 } else if (u.uhave.amulet) {
1598 res = deepest_lev_reached(FALSE);
1601 /* depth() is the number of elevation units (levels) below
1602 the theoretical surface; in a builds-up branch, that value
1603 ends up making the harder to reach levels be treated as if
1604 they were easier; adjust for the extra effort involved in
1605 going down to the entrance and then up to the location */
1606 if (builds_up(&u.uz))
1607 res += 2 * (dungeons[u.uz.dnum].entry_lev - u.uz.dlevel + 1);
1609 * 'Proof' by example: suppose the entrance to sokoban is
1610 * on dungeon level 9, leading up to bottom sokoban level
1611 * of 8 [entry_lev]. When the hero is on sokoban level 8
1612 * [uz.dlevel], depth() yields eight but he has ventured
1613 * one level beyond 9, so difficulty depth should be 10:
1614 * 8 + 2 * (8 - 8 + 1) => 10.
1615 * Going up to 7, depth is 7 but hero will be two beyond 9:
1616 * 7 + 2 * (8 - 7 + 1) => 11.
1617 * When he goes up to level 6, three levels beyond 9:
1618 * 6 + 2 * (8 - 6 + 1) => 12.
1619 * And the top level of sokoban at 5, four levels beyond 9:
1620 * 5 + 2 * (8 - 5 + 1) => 13.
1621 * The same applies to Vlad's Tower, although the increment
1622 * there is inconsequential compared to overall depth.
1626 * The inside of the Wizard's Tower is also effectively a
1627 * builds-up area, reached from a portal an arbitrary distance
1628 * below rather than stairs 1 level beneath the entry level.
1630 else if (On_W_tower_level(&u.uz) && In_W_tower(some_X, some_Y, &u.uz))
1631 res += (fakewiz1.dlev - u.uz.dlev);
1633 * Handling this properly would need more information here:
1634 * an inside/outside flag, or coordinates to calculate it.
1635 * Unfortunately level difficulty may be wanted before
1636 * coordinates have been chosen so simply extending this
1637 * routine to take extra arguments is not sufficient to cope.
1638 * The difference beyond naive depth-from-surface is small
1639 * relative to the overall depth, so just ignore complications
1647 /* Take one word and try to match it to a level.
1648 * Recognized levels are as shown by print_dungeon().
1655 s_level *slev = (s_level *)0;
1662 /* look at the player's custom level annotations first */
1663 if ((mseen = find_mapseen_by_str(nam)) != 0) {
1666 /* no matching annotation, check whether they used a name we know */
1668 #if 0 /*JP*//*
\93ú
\96{
\8cê
\82Å
\82Í
\8f\88\97\9d\82µ
\82È
\82¢*/
1669 /* allow strings like "the oracle level" to find "oracle" */
1670 if (!strncmpi(nam, "the ", 4))
1672 if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
1673 nam = strcpy(buf, nam);
1674 *(eos(buf) - 6) = '\0';
1676 /* hell is the old name, and wouldn't match; gehennom would match its
1677 branch, yielding the castle level instead of the valley of the dead */
1678 if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
1679 if (In_V_tower(&u.uz))
1680 nam = " to Vlad's tower"; /* branch to... */
1686 if ((slev = find_level(nam)) != 0)
1687 dlev = slev->dlevel;
1690 if (mseen || slev) {
1691 idx = ledger_no(&dlev);
1692 if ((dlev.dnum == u.uz.dnum
1693 /* within same branch, or else main dungeon <-> gehennom */
1694 || (u.uz.dnum == valley_level.dnum
1695 && dlev.dnum == medusa_level.dnum)
1696 || (u.uz.dnum == medusa_level.dnum
1697 && dlev.dnum == valley_level.dnum))
1698 && (/* either wizard mode or else seen and not forgotten */
1700 || (level_info[idx].flags & (FORGOTTEN | VISITED))
1704 } else { /* not a specific level; try branch names */
1705 idx = find_branch(nam, (struct proto_dungeon *) 0);
1706 /* "<branch> to Xyzzy" */
1707 if (idx < 0 && (p = strstri(nam, " to ")) != 0)
1708 idx = find_branch(p + 4, (struct proto_dungeon *) 0);
1711 idxtoo = (idx >> 8) & 0x00FF;
1713 if (/* either wizard mode, or else _both_ sides of branch seen */
1715 || ((level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED
1716 && (level_info[idxtoo].flags & (FORGOTTEN | VISITED))
1718 if (ledger_to_dnum(idxtoo) == u.uz.dnum)
1720 dlev.dnum = ledger_to_dnum(idx);
1721 dlev.dlevel = ledger_to_dlev(idx);
1730 unplaced_floater(dptr)
1731 struct dungeon *dptr;
1734 int idx = (int) (dptr - dungeons);
1736 /* if other floating branches are added, this will need to change */
1737 if (idx != knox_level.dnum)
1739 for (br = branches; br; br = br->next)
1740 if (br->end1.dnum == n_dgns && br->end2.dnum == idx)
1746 unreachable_level(lvl_p, unplaced)
1754 if (In_endgame(&u.uz) && !In_endgame(lvl_p))
1756 if ((dummy = find_level("dummy")) != 0 && on_level(lvl_p, &dummy->dlevel))
1762 tport_menu(win, entry, lchoices, lvl_p, unreachable)
1765 struct lchoice *lchoices;
1767 boolean unreachable;
1772 lchoices->lev[lchoices->idx] = lvl_p->dlevel;
1773 lchoices->dgn[lchoices->idx] = lvl_p->dnum;
1774 lchoices->playerlev[lchoices->idx] = depth(lvl_p);
1777 /* not selectable, but still consumes next menuletter;
1778 prepend padding in place of missing menu selector */
1779 Sprintf(tmpbuf, " %s", entry);
1782 any.a_int = lchoices->idx + 1;
1784 add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 0, ATR_NONE, entry,
1786 /* this assumes there are at most 52 interesting levels */
1787 if (lchoices->menuletter == 'z')
1788 lchoices->menuletter = 'A';
1790 lchoices->menuletter++;
1795 /* Convert a branch type to a string usable by print_dungeon(). */
1796 STATIC_OVL const char *
1805 return "
\96\82\96@
\82Ì
\93ü
\82è
\8cû";
1808 return "Connection";
1810 return "
\90Ú
\91±
\95\94";
1813 return "One way stair";
1815 return "
\88ê
\95û
\92Ê
\8ds
\82Ì
\8aK
\92i";
1823 return " (unknown)";
1825 return " (
\95s
\96¾)";
1832 return u.uz.dnum == dlev->dnum && u.uz.dlevel == dlev->dlevel ? '*' : ' ';
1835 /* Print all child branches between the lower and upper bounds. */
1837 print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices_p)
1843 struct lchoice *lchoices_p;
1848 /* This assumes that end1 is the "parent". */
1849 for (br = branches; br; br = br->next) {
1850 if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel
1851 && br->end1.dlevel <= upper_bound) {
1853 Sprintf(buf, "%c %s to %s: %d",
1854 bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1855 br_string(br->type),
1856 dungeons[br->end2.dnum].dname, depth(&br->end1));
1858 Sprintf(buf, "%c %s
\82©
\82ç%s: %d",
1859 bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1860 br_string(br->type),
1861 dungeons[br->end2.dnum].dname, depth(&br->end1));
1864 tport_menu(win, buf, lchoices_p, &br->end1,
1865 unreachable_level(&br->end1, FALSE));
1867 putstr(win, 0, buf);
1872 /* Print available dungeon information. */
1874 print_dungeon(bymenu, rlev, rdgn)
1879 int i, last_level, nlev;
1882 boolean first, unplaced;
1887 struct lchoice lchoices;
1888 winid win = create_nhwindow(NHW_MENU);
1893 lchoices.menuletter = 'a';
1896 for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
1897 if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum)
1899 unplaced = unplaced_floater(dptr);
1901 descr = unplaced ? "depth" : "level";
1903 descr = unplaced ? "
\92n
\89º" : "
\83\8c\83x
\83\8b";
1904 nlev = dptr->num_dunlevs;
1907 Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr),
1908 dptr->depth_start, dptr->depth_start + nlev - 1);
1910 Sprintf(buf, "%s: %s%d
\82©
\82ç%d", dptr->dname, descr,
1911 dptr->depth_start, dptr->depth_start + nlev - 1);
1914 Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start);
1916 /* Most entrances are uninteresting. */
1917 if (dptr->entry_lev != 1) {
1918 if (dptr->entry_lev == nlev)
1920 Strcat(buf, ", entrance from below");
1922 Strcat(buf, ",
\89º
\82©
\82ç
\82Ì
\93ü
\82è
\8cû");
1925 Sprintf(eos(buf), ", entrance on %d",
1926 dptr->depth_start + dptr->entry_lev - 1);
1928 Sprintf(eos(buf), ", %d
\82Ì
\93ü
\82è
\8cû",
1929 dptr->depth_start + dptr->entry_lev - 1);
1934 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1937 putstr(win, 0, buf);
1940 * Circle through the special levels to find levels that are in
1943 for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
1944 if (slev->dlevel.dnum != i)
1947 /* print any branches before this level */
1948 print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu,
1951 Sprintf(buf, "%c %s: %d",
1952 chr_u_on_lvl(&slev->dlevel),
1953 slev->proto, depth(&slev->dlevel));
1954 if (Is_stronghold(&slev->dlevel))
1955 Sprintf(eos(buf), " (tune %s)", tune);
1957 tport_menu(win, buf, &lchoices, &slev->dlevel,
1958 unreachable_level(&slev->dlevel, unplaced));
1960 putstr(win, 0, buf);
1962 last_level = slev->dlevel.dlevel;
1964 /* print branches after the last special level */
1965 print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices);
1970 menu_item *selected;
1974 end_menu(win, "Level teleport to where:");
1976 end_menu(win, "
\82Ç
\82±
\82É
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é
\81F");
1977 n = select_menu(win, PICK_ONE, &selected);
1978 destroy_nhwindow(win);
1980 idx = selected[0].item.a_int - 1;
1981 free((genericptr_t) selected);
1983 *rlev = lchoices.lev[idx];
1984 *rdgn = lchoices.dgn[idx];
1985 return lchoices.playerlev[idx];
1991 /* Print out floating branches (if any). */
1992 for (first = TRUE, br = branches; br; br = br->next) {
1993 if (br->end1.dnum == n_dgns) {
1997 putstr(win, 0, "Floating branches");
1999 putstr(win, 0, "
\95\82\93®
\95ª
\8aò");
2003 Sprintf(buf, " %s to %s", br_string(br->type),
2004 dungeons[br->end2.dnum].dname);
2006 Sprintf(buf, " %s
\82©
\82ç%s", br_string(br->type),
2007 dungeons[br->end2.dnum].dname);
2009 putstr(win, 0, buf);
2013 /* I hate searching for the invocation pos while debugging. -dean */
2014 if (Invocation_lev(&u.uz)) {
2017 Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
2018 inv_pos.x, inv_pos.y, u.ux, u.uy);
2020 Sprintf(buf, "
\94
\93®
\88Ê
\92u @ (%d,%d),
\83v
\83\8c\83C
\83\84\81[ @ (%d,%d)",
2021 inv_pos.x, inv_pos.y, u.ux, u.uy);
2023 putstr(win, 0, buf);
2027 /* if current level has a magic portal, report its location;
2028 this assumes that there is at most one magic portal on any
2029 given level; quest and ft.ludios have pairs (one in main
2030 dungeon matched with one in the corresponding branch), the
2031 elemental planes have singletons (connection to next plane) */
2033 for (trap = ftrap; trap; trap = trap->ntrap)
2034 if (trap->ttyp == MAGIC_PORTAL)
2038 Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
2039 trap->tx, trap->ty, u.ux, u.uy);
2041 /* only report "no portal found" when actually expecting a portal */
2043 else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2044 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2045 || Is_qstart(&u.uz) || at_dgn_entrance("The Quest")
2048 else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2049 || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2050 || Is_qstart(&u.uz) || at_dgn_entrance("
\83N
\83G
\83X
\83g")
2053 Strcpy(buf, "No portal found.");
2055 /* only give output if we found a portal or expected one and didn't */
2058 putstr(win, 0, buf);
2062 display_nhwindow(win, TRUE);
2063 destroy_nhwindow(win);
2067 /* Record that the player knows about a branch from a level. This function
2068 * will determine whether or not it was a "real" branch that was taken.
2069 * This function should not be called for a transition done via level
2070 * teleport or via the Eye.
2073 recbranch_mapseen(source, dest)
2081 if (source->dnum == dest->dnum)
2084 /* we only care about forward branches */
2085 for (br = branches; br; br = br->next) {
2086 if (on_level(source, &br->end1) && on_level(dest, &br->end2))
2088 if (on_level(source, &br->end2) && on_level(dest, &br->end1))
2092 /* branch not found, so not a real branch. */
2096 if ((mptr = find_mapseen(source)) != 0) {
2097 if (mptr->br && br != mptr->br)
2098 impossible("Two branches on the same level?");
2101 impossible("Can't note branch for unseen level (%d, %d)",
2102 source->dnum, source->dlevel);
2112 if ((mptr = find_mapseen(lev)))
2113 return mptr->custom;
2117 /* #annotate command - add a custom name to the current level */
2122 char nbuf[BUFSZ]; /* Buffer for response */
2124 if (!(mptr = find_mapseen(&u.uz)))
2130 (void) strncpy(nbuf, mptr->custom, BUFSZ);
2131 nbuf[BUFSZ - 1] = '\0';
2138 Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?", mptr->custom,
2139 (strlen(mptr->custom) > 30) ? "..." : "");
2141 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,
2142 strlen(mptr->custom) > 30 ? "..." : "");
2144 getlin(tmpbuf, nbuf);
2148 getlin("What do you want to call this dungeon level?", nbuf);
2150 getlin("
\82±
\82Ì
\8aK
\82ð
\89½
\82Æ
\8cÄ
\82Ô
\81H", nbuf);
2152 /* empty input or ESC means don't add or change annotation;
2153 space-only means discard current annotation without adding new one */
2154 if (!*nbuf || *nbuf == '\033')
2156 /* strip leading and trailing spaces, compress out consecutive spaces */
2157 (void) mungspaces(nbuf);
2159 /* discard old annotation, if any */
2161 free((genericptr_t) mptr->custom);
2162 mptr->custom = (char *) 0;
2163 mptr->custom_lth = 0;
2165 /* add new annotation, unless it's all spaces (which will be an
2166 empty string after mungspaces() above) */
2167 if (*nbuf && strcmp(nbuf, " ")) {
2168 mptr->custom = dupstr(nbuf);
2169 mptr->custom_lth = strlen(mptr->custom);
2174 /* find the particular mapseen object in the chain; may return null */
2175 STATIC_OVL mapseen *
2181 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2182 if (on_level(&(mptr->lev), lev))
2188 STATIC_OVL mapseen *
2189 find_mapseen_by_str(s)
2194 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2195 if (mptr->custom && !strcmpi(s, mptr->custom))
2203 forget_mapseen(ledger_num)
2207 struct cemetery *bp;
2209 for (mptr = mapseenchn; mptr; mptr = mptr->next)
2210 if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel
2214 /* if not found, then nothing to forget */
2216 mptr->flags.forgot = 1;
2217 mptr->br = (branch *) 0;
2219 /* custom names are erased, not just forgotten until revisited */
2221 mptr->custom_lth = 0;
2222 free((genericptr_t) mptr->custom);
2223 mptr->custom = (char *) 0;
2225 (void) memset((genericptr_t) mptr->msrooms, 0, sizeof mptr->msrooms);
2226 for (bp = mptr->final_resting_place; bp; bp = bp->next)
2227 bp->bonesknown = FALSE;
2232 rm_mapseen(ledger_num)
2235 mapseen *mptr, *mprev = (mapseen *)0;
2236 struct cemetery *bp, *bpnext;
2238 for (mptr = mapseenchn; mptr; mprev = mptr, mptr = mptr->next)
2239 if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num)
2246 free((genericptr_t) mptr->custom);
2248 bp = mptr->final_resting_place;
2256 mprev->next = mptr->next;
2259 mapseenchn = mptr->next;
2265 save_mapseen(fd, mptr)
2272 for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2273 if (curr == mptr->br)
2275 bwrite(fd, (genericptr_t) &brindx, sizeof brindx);
2277 bwrite(fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
2278 bwrite(fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
2279 bwrite(fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
2280 bwrite(fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
2281 if (mptr->custom_lth)
2282 bwrite(fd, (genericptr_t) mptr->custom, mptr->custom_lth);
2283 bwrite(fd, (genericptr_t) &mptr->msrooms, sizeof mptr->msrooms);
2284 savecemetery(fd, WRITE_SAVE, &mptr->final_resting_place);
2287 STATIC_OVL mapseen *
2291 int branchnum, brindx;
2295 load = (mapseen *) alloc(sizeof *load);
2297 mread(fd, (genericptr_t) &branchnum, sizeof branchnum);
2298 for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2299 if (brindx == branchnum)
2303 mread(fd, (genericptr_t) &load->lev, sizeof load->lev);
2304 mread(fd, (genericptr_t) &load->feat, sizeof load->feat);
2305 mread(fd, (genericptr_t) &load->flags, sizeof load->flags);
2306 mread(fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
2307 if (load->custom_lth) {
2308 /* length doesn't include terminator (which isn't saved & restored) */
2309 load->custom = (char *) alloc(load->custom_lth + 1);
2310 mread(fd, (genericptr_t) load->custom, load->custom_lth);
2311 load->custom[load->custom_lth] = '\0';
2314 mread(fd, (genericptr_t) &load->msrooms, sizeof load->msrooms);
2315 restcemetery(fd, &load->final_resting_place);
2320 /* to support '#stats' wizard-mode command */
2322 overview_stats(win, statsfmt, total_count, total_size)
2324 const char *statsfmt;
2325 long *total_count, *total_size;
2327 char buf[BUFSZ], hdrbuf[QBUFSZ];
2328 long ocount, osize, bcount, bsize, acount, asize;
2329 struct cemetery *ce;
2330 mapseen *mptr = find_mapseen(&u.uz);
2332 ocount = bcount = acount = osize = bsize = asize = 0L;
2333 for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2335 osize += (long) sizeof *mptr;
2336 for (ce = mptr->final_resting_place; ce; ce = ce->next) {
2338 bsize += (long) sizeof *ce;
2340 if (mptr->custom_lth) {
2342 asize += (long) (mptr->custom_lth + 1);
2346 Sprintf(hdrbuf, "general, size %ld", (long) sizeof (mapseen));
2347 Sprintf(buf, statsfmt, hdrbuf, ocount, osize);
2348 putstr(win, 0, buf);
2350 Sprintf(hdrbuf, "cemetery, size %ld",
2351 (long) sizeof (struct cemetery));
2352 Sprintf(buf, statsfmt, hdrbuf, bcount, bsize);
2353 putstr(win, 0, buf);
2356 Sprintf(hdrbuf, "annotations, text");
2357 Sprintf(buf, statsfmt, hdrbuf, acount, asize);
2358 putstr(win, 0, buf);
2360 *total_count += ocount + bcount + acount;
2361 *total_size += osize + bsize + asize;
2364 /* Remove all mapseen objects for a particular dnum.
2365 * Useful during quest expulsion to remove quest levels.
2366 * [No longer deleted, just marked as unreachable. #overview will
2367 * ignore such levels, end of game disclosure will include them.]
2370 remdun_mapseen(dnum)
2373 mapseen *mptr, **mptraddr;
2375 mptraddr = &mapseenchn;
2376 while ((mptr = *mptraddr) != 0) {
2377 if (mptr->lev.dnum == dnum) {
2378 #if 1 /* use this... */
2379 mptr->flags.unreachable = 1;
2381 #else /* old deletion code */
2382 *mptraddr = mptr->next;
2384 free((genericptr_t) mptr->custom);
2385 if (mptr->final_resting_place)
2386 savecemetery(-1, FREE_SAVE, &mptr->final_resting_place);
2387 free((genericptr_t) mptr);
2390 mptraddr = &mptr->next;
2398 /* Create a level and insert in "sorted" order. This is an insertion
2399 * sort first by dungeon (in order of discovery) and then by level number.
2401 mapseen *mptr, *init, *prev;
2403 init = (mapseen *) alloc(sizeof *init);
2404 (void) memset((genericptr_t) init, 0, sizeof *init);
2405 /* memset is fine for feature bits, flags, and rooms array;
2406 explicitly initialize pointers to null */
2407 init->next = 0, init->br = 0, init->custom = 0;
2408 init->final_resting_place = 0;
2409 /* lastseentyp[][] is reused for each level, so get rid of
2410 previous level's data */
2411 (void) memset((genericptr_t) lastseentyp, 0, sizeof lastseentyp);
2413 init->lev.dnum = lev->dnum;
2414 init->lev.dlevel = lev->dlevel;
2416 /* walk until we get to the place where we should insert init */
2417 for (mptr = mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next)
2418 if (mptr->lev.dnum > init->lev.dnum
2419 || (mptr->lev.dnum == init->lev.dnum
2420 && mptr->lev.dlevel > init->lev.dlevel))
2423 init->next = mapseenchn;
2432 #define INTEREST(feat) \
2433 ((feat).nfount || (feat).nsink || (feat).nthrone || (feat).naltar \
2434 || (feat).ngrave || (feat).ntree || (feat).nshop || (feat).ntemple)
2435 /* || (feat).water || (feat).ice || (feat).lava */
2437 /* returns true if this level has something interesting to print out */
2439 interest_mapseen(mptr)
2442 if (on_level(&u.uz, &mptr->lev))
2444 if (mptr->flags.unreachable || mptr->flags.forgot)
2446 /* level is of interest if it has an auto-generated annotation */
2447 if (mptr->flags.oracle || mptr->flags.bigroom || mptr->flags.roguelevel
2448 || mptr->flags.castle || mptr->flags.valley || mptr->flags.msanctum
2449 || mptr->flags.quest_summons || mptr->flags.questing)
2451 /* when in Sokoban, list all sokoban levels visited; when not in it,
2452 list any visited Sokoban level which remains unsolved (will usually
2453 only be furthest one reached, but it's possible to enter pits and
2454 climb out on the far side on the first Sokoban level; also, wizard
2455 mode overrides teleport restrictions) */
2456 if (In_sokoban(&mptr->lev)
2457 && (In_sokoban(&u.uz) || !mptr->flags.sokosolved))
2459 /* when in the endgame, list all endgame levels visited, whether they
2460 have annotations or not, so that #overview doesn't become extremely
2461 sparse once the rest of the dungeon has been flagged as unreachable */
2462 if (In_endgame(&u.uz))
2463 return (boolean) In_endgame(&mptr->lev);
2464 /* level is of interest if it has non-zero feature count or known bones
2465 or user annotation or known connection to another dungeon branch
2466 or is the furthest level reached in its branch */
2467 return (boolean) (INTEREST(mptr->feat)
2468 || (mptr->final_resting_place
2469 && (mptr->flags.knownbones || wizard))
2470 || mptr->custom || mptr->br
2471 || (mptr->lev.dlevel
2472 == dungeons[mptr->lev.dnum].dunlev_ureached));
2475 /* recalculate mapseen for the current level */
2481 struct cemetery *bp, **bonesaddr;
2483 int x, y, ltyp, count, atmp;
2485 /* Should not happen in general, but possible if in the process
2486 * of being booted from the quest. The mapseen object gets
2487 * removed during the expulsion but prior to leaving the level
2488 * [Since quest expulsion no longer deletes quest mapseen data,
2489 * null return from find_mapseen() should now be impossible.]
2491 if (!(mptr = find_mapseen(&u.uz)))
2494 /* reset all features; mptr->feat.* = 0; */
2495 (void) memset((genericptr_t) &mptr->feat, 0, sizeof mptr->feat);
2496 /* reset most flags; some level-specific ones are left as-is */
2497 if (mptr->flags.unreachable) {
2498 mptr->flags.unreachable = 0; /* reached it; Eye of the Aethiopica? */
2499 if (In_quest(&u.uz)) {
2500 mapseen *mptrtmp = mapseenchn;
2502 /* when quest was unreachable due to ejection and portal removal,
2503 getting back to it via arti-invoke should revive annotation
2504 data for all quest levels, not just the one we're on now */
2506 if (mptrtmp->lev.dnum == mptr->lev.dnum)
2507 mptrtmp->flags.unreachable = 0;
2508 mptrtmp = mptrtmp->next;
2512 mptr->flags.knownbones = 0;
2513 mptr->flags.sokosolved = In_sokoban(&u.uz) && !Sokoban;
2514 /* mptr->flags.bigroom retains previous value when hero can't see */
2516 mptr->flags.bigroom = Is_bigroom(&u.uz);
2517 else if (mptr->flags.forgot)
2518 mptr->flags.bigroom = 0;
2519 mptr->flags.roguelevel = Is_rogue_level(&u.uz);
2520 mptr->flags.oracle = 0; /* recalculated during room traversal below */
2521 mptr->flags.castletune = 0;
2522 /* flags.castle, flags.valley, flags.msanctum retain previous value */
2523 mptr->flags.forgot = 0;
2524 /* flags.quest_summons disabled once quest finished */
2526 mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
2528 mptr->flags.quest_summons = (at_dgn_entrance("
\83N
\83G
\83X
\83g")
2530 && !(u.uevent.qcompleted
2531 || u.uevent.qexpelled
2532 || quest_status.leader_is_dead));
2533 mptr->flags.questing = (on_level(&u.uz, &qstart_level)
2534 && quest_status.got_quest);
2536 /* track rooms the hero is in */
2537 for (i = 0; i < SIZE(u.urooms); ++i) {
2541 ridx = u.urooms[i] - ROOMOFFSET;
2542 mptr->msrooms[ridx].seen = 1;
2543 mptr->msrooms[ridx].untended =
2544 (rooms[ridx].rtype >= SHOPBASE)
2545 ? (!(mtmp = shop_keeper(u.urooms[i])) || !inhishop(mtmp))
2546 : (rooms[ridx].rtype == TEMPLE)
2547 ? (!(mtmp = findpriest(u.urooms[i]))
2548 || !inhistemple(mtmp))
2552 /* recalculate room knowledge: for now, just shops and temples
2553 * this could be extended to an array of 0..SHOPBASE
2555 for (i = 0; i < SIZE(mptr->msrooms); ++i) {
2556 if (mptr->msrooms[i].seen) {
2557 if (rooms[i].rtype >= SHOPBASE) {
2558 if (mptr->msrooms[i].untended)
2559 mptr->feat.shoptype = SHOPBASE - 1;
2560 else if (!mptr->feat.nshop)
2561 mptr->feat.shoptype = rooms[i].rtype;
2562 else if (mptr->feat.shoptype != (unsigned) rooms[i].rtype)
2563 mptr->feat.shoptype = 0;
2564 count = mptr->feat.nshop + 1;
2566 mptr->feat.nshop = count;
2567 } else if (rooms[i].rtype == TEMPLE) {
2568 /* altar and temple alignment handled below */
2569 count = mptr->feat.ntemple + 1;
2571 mptr->feat.ntemple = count;
2572 } else if (rooms[i].orig_rtype == DELPHI) {
2573 mptr->flags.oracle = 1;
2578 /* Update lastseentyp with typ if and only if it is in sight or the
2579 * hero can feel it on their current location (i.e. not levitating).
2580 * This *should* give the "last known typ" for each dungeon location.
2581 * (At the very least, it's a better assumption than determining what
2582 * the player knows from the glyph and the typ (which is isn't quite
2583 * enough information in some cases)).
2585 * It was reluctantly added to struct rm to track. Alternatively
2586 * we could track "features" and then update them all here, and keep
2587 * track of when new features are created or destroyed, but this
2588 * seemed the most elegant, despite adding more data to struct rm.
2589 * [3.6.0: we're using lastseentyp[][] rather than level.locations
2590 * to track the features seen.]
2592 * Although no current windowing systems (can) do this, this would add
2593 * the ability to have non-dungeon glyphs float above the last known
2594 * dungeon glyph (i.e. items on fountains).
2596 for (x = 1; x < COLNO; x++) {
2597 for (y = 0; y < ROWNO; y++) {
2598 if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
2599 ltyp = levl[x][y].typ;
2600 if (ltyp == DRAWBRIDGE_UP)
2601 ltyp = db_under_typ(levl[x][y].drawbridgemask);
2602 if ((mtmp = m_at(x, y)) != 0
2603 && mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp))
2604 ltyp = cmap_to_type(mtmp->mappearance);
2605 lastseentyp[x][y] = ltyp;
2608 switch (lastseentyp[x][y]) {
2611 count = mptr->feat.ice + 1;
2613 mptr->feat.ice = count;
2618 count = mptr->feat.water + 1;
2620 mptr->feat.water = count;
2623 count = mptr->feat.lava + 1;
2625 mptr->feat.lava = count;
2629 count = mptr->feat.ntree + 1;
2631 mptr->feat.ntree = count;
2634 count = mptr->feat.nfount + 1;
2636 mptr->feat.nfount = count;
2639 count = mptr->feat.nthrone + 1;
2641 mptr->feat.nthrone = count;
2644 count = mptr->feat.nsink + 1;
2646 mptr->feat.nsink = count;
2649 count = mptr->feat.ngrave + 1;
2651 mptr->feat.ngrave = count;
2654 atmp = (Is_astralevel(&u.uz)
2655 && (levl[x][y].seenv & SVALL) != SVALL)
2657 : Amask2msa(levl[x][y].altarmask);
2658 if (!mptr->feat.naltar)
2659 mptr->feat.msalign = atmp;
2660 else if (mptr->feat.msalign != atmp)
2661 mptr->feat.msalign = MSA_NONE;
2662 count = mptr->feat.naltar + 1;
2664 mptr->feat.naltar = count;
2666 /* An automatic annotation is added to the Castle and
2667 * to Fort Ludios once their structure's main entrance
2668 * has been seen (in person or via magic mapping).
2669 * For the Fort, that entrance is just a secret door
2670 * which will be converted into a regular one when
2671 * located (or destroyed).
2672 * DOOR: possibly a lowered drawbridge's open portcullis;
2673 * DBWALL: a raised drawbridge's "closed door";
2674 * DRAWBRIDGE_DOWN: the span provided by lowered bridge,
2675 * with moat or other terrain hidden underneath;
2676 * DRAWBRIDGE_UP: moat in front of a raised drawbridge,
2677 * not recognizable as a bridge location unless/until
2678 * the adjacent DBWALL has been seen.
2681 if (Is_knox(&u.uz)) {
2684 /* Throne is four columns left, either directly in
2685 * line or one row higher or lower, and doesn't have
2686 * to have been seen yet.
2691 * For 3.6.0 and earlier, it was always in direct line:
2692 * both throne and door on the lower of the two rows.
2694 for (ty = y - 1; ty <= y + 1; ++ty)
2695 if (isok(tx, ty) && IS_THRONE(levl[tx][ty].typ)) {
2696 mptr->flags.ludios = 1;
2701 if (is_drawbridge_wall(x, y) < 0)
2705 case DRAWBRIDGE_DOWN:
2706 if (Is_stronghold(&u.uz))
2707 mptr->flags.castle = 1, mptr->flags.castletune = 1;
2715 if (level.bonesinfo && !mptr->final_resting_place) {
2716 /* clone the bonesinfo so we aren't dependent upon this
2717 level being in memory */
2718 bonesaddr = &mptr->final_resting_place;
2719 bp = level.bonesinfo;
2721 *bonesaddr = (struct cemetery *) alloc(sizeof **bonesaddr);
2724 bonesaddr = &(*bonesaddr)->next;
2728 /* decide which past hero deaths have become known; there's no
2729 guarantee of either a grave or a ghost, so we go by whether the
2730 current hero has seen the map location where each old one died */
2731 for (bp = mptr->final_resting_place; bp; bp = bp->next)
2732 if (lastseentyp[bp->frpx][bp->frpy]) {
2733 bp->bonesknown = TRUE;
2734 mptr->flags.knownbones = 1;
2739 /* valley and sanctum levels get automatic annotation once temple is entered
2742 mapseen_temple(priest)
2743 struct monst *priest UNUSED; /* currently unused; might be useful someday */
2745 mapseen *mptr = find_mapseen(&u.uz);
2747 if (Is_valley(&u.uz))
2748 mptr->flags.valley = 1;
2749 else if (Is_sanctum(&u.uz))
2750 mptr->flags.msanctum = 1;
2753 /* room entry message has just been delivered so learn room even if blind */
2755 room_discovered(roomno)
2758 mapseen *mptr = find_mapseen(&u.uz);
2760 mptr->msrooms[roomno].seen = 1;
2763 /* #overview command */
2767 show_overview(0, 0);
2771 /* called for #overview or for end of game disclosure */
2773 show_overview(why, reason)
2774 int why; /* 0 => #overview command,
2775 1 or 2 => final disclosure (1: hero lived, 2: hero died) */
2776 int reason; /* how hero died; used when disclosing end-of-game level */
2781 /* lazy initialization */
2782 (void) recalc_mapseen();
2784 win = create_nhwindow(NHW_MENU);
2785 /* show the endgame levels before the rest of the dungeon,
2786 so that the Planes (dnum 5-ish) come out above main dungeon (dnum 0) */
2787 if (In_endgame(&u.uz))
2788 traverse_mapseenchn(TRUE, win, why, reason, &lastdun);
2789 /* if game is over or we're not in the endgame yet, show the dungeon */
2790 if (why > 0 || !In_endgame(&u.uz))
2791 traverse_mapseenchn(FALSE, win, why, reason, &lastdun);
2792 display_nhwindow(win, TRUE);
2793 destroy_nhwindow(win);
2796 /* display endgame levels or non-endgame levels, not both */
2798 traverse_mapseenchn(viewendgame, win, why, reason, lastdun_p)
2799 boolean viewendgame;
2801 int why, reason, *lastdun_p;
2806 for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2807 if (viewendgame ^ In_endgame(&mptr->lev))
2810 /* only print out info for a level or a dungeon if interest */
2811 if (why > 0 || interest_mapseen(mptr)) {
2812 showheader = (boolean) (mptr->lev.dnum != *lastdun_p);
2813 print_mapseen(win, mptr, why, reason, showheader);
2814 *lastdun_p = mptr->lev.dnum;
2819 STATIC_OVL const char *
2824 /* players are computer scientists: 0, 1, 2, n */
2827 /*JP:
\82±
\82±
\82É
\82Í
\97\88\82È
\82¢
\82Í
\82¸*/
2829 /* an() returns too much. index is ok in this case */
2832 return index(vowels, *obj) ? "an" : "a";
2839 return "
\93ñ
\82Â
\82Ì";
2844 return "
\91½
\82
\82Ì";
2850 /* better br_string */
2851 STATIC_OVL const char *
2855 /* Special case: quest portal says closed if kicked from quest */
2856 boolean closed_portal = (br->end2.dnum == quest_dnum
2857 && u.uevent.qexpelled);
2862 return closed_portal ? "Sealed portal" : "Portal";
2864 return closed_portal ? "
\95\95\88ó
\82³
\82ê
\82½
\96\82\96@
\82Ì
\93ü
\8cû" : "
\96\82\96@
\82Ì
\93ü
\8cû";
2866 return "Connection";
2869 return br->end1_up ? "One way stairs up" : "One way stairs down";
2871 return br->end1_up ? "
\8fã
\82è
\95Ð
\93¹
\8aK
\92i" : "
\89º
\82è
\95Ð
\93¹
\8aK
\92i";
2874 return br->end1_up ? "Stairs up" : "Stairs down";
2876 return br->end1_up ? "
\8fã
\82è
\8aK
\92i" : "
\89º
\82è
\8aK
\92i";
2882 /* get the name of an endgame level; topten.c does something similar */
2883 STATIC_OVL const char *
2884 endgamelevelname(outbuf, indx)
2888 const char *planename = 0;
2894 Strcpy(outbuf, "Astral Plane");
2896 Strcpy(outbuf, "
\93V
\8fã
\8aE");
2900 planename = "Water";
2902 planename = "
\90\85";
2914 planename = "
\95\97";
2918 planename = "Earth";
2925 Sprintf(outbuf, "Plane of %s", planename);
2927 Sprintf(outbuf, "%s
\82Ì
\90¸
\97ì
\8aE", planename);
2929 Sprintf(outbuf, "unknown plane #%d", indx);
2933 STATIC_OVL const char *
2938 const char *str = "shop"; /* catchall */
2940 const char *str = "
\93X"; /* catchall */
2943 /* Yuck, redundancy...but shclass.name doesn't cut it as a noun */
2947 str = "untended shop";
2949 str = "
\95ú
\8aü
\82³
\82ê
\82½
\93X";
2950 break; /* see recalc_mapseen */
2953 str = "general store";
2955 str = "
\8eG
\89Ý
\93X";
2961 str = "
\96h
\8bï
\93X";
2965 str = "scroll shop";
2967 str = "
\8aª
\95¨
\93X";
2971 str = "potion shop";
2977 str = "weapon shop";
2979 str = "
\95\90\8aí
\93X";
2983 str = "delicatessen";
2985 str = "
\90H
\97¿
\95i
\93X";
2991 str = "
\95ó
\90Î
\93X";
3007 str = "health food store";
3009 str = "
\8c\92\8dN
\90H
\95i
\93X";
3013 str = "lighting shop";
3015 str = "
\8fÆ
\96¾
\93X";
3023 /* if player knows about the mastermind tune, append it to Castle annotation;
3024 if drawbridge has been destroyed, flags.castletune will be zero */
3026 tunesuffix(mptr, outbuf)
3031 if (mptr->flags.castletune && u.uevent.uheard_tune) {
3034 if (u.uevent.uheard_tune == 2)
3035 Sprintf(tmp, "notes \"%s\"", tune);
3037 Strcpy(tmp, "5-note tune");
3038 Sprintf(outbuf, " (play %s to open or close drawbridge)", tmp);
3043 /* some utility macros for print_mapseen */
3044 #define TAB " " /* three spaces */
3046 #define BULLET "" /* empty; otherwise output becomes cluttered */
3047 #define PREFIX TAB TAB BULLET
3049 /* K&R: don't require support for concatenation of adjacent string literals */
3050 #define PREFIX " " /* two TABs + empty BULLET: six spaces */
3052 #define COMMA (i++ > 0 ? ", " : PREFIX)
3053 /* "iterate" once; safe to use as ``if (cond) ADDTOBUF(); else whatever;'' */
3055 #define ADDNTOBUF(nam, var) \
3058 Sprintf(eos(buf), "%s%s %s%s", COMMA, seen_string((var), (nam)), \
3059 (nam), plur(var)); \
3062 #define ADDNTOBUF(nam, var) \
3065 Sprintf(eos(buf), "%s%s%s", COMMA, seen_string((var), (nam)), \
3069 #define ADDTOBUF(nam, var) \
3072 Sprintf(eos(buf), "%s%s", COMMA, (nam)); \
3076 print_mapseen(win, mptr, final, how, printdun)
3079 int final; /* 0: not final; 1: game over, alive; 2: game over, dead */
3080 int how; /* cause of death; only used if final==2 and mptr->lev==u.uz */
3083 char buf[BUFSZ], tmpbuf[BUFSZ];
3084 int i, depthstart, dnum;
3085 boolean died_here = (final == 2 && on_level(&u.uz, &mptr->lev));
3087 /* Damnable special cases */
3088 /* The quest and knox should appear to be level 1 to match
3091 dnum = mptr->lev.dnum;
3092 if (dnum == quest_dnum || dnum == knox_level.dnum)
3095 depthstart = dungeons[dnum].depth_start;
3098 if (dungeons[dnum].dunlev_ureached == dungeons[dnum].entry_lev
3099 /* suppress the negative numbers in the endgame */
3100 || In_endgame(&mptr->lev))
3101 Sprintf(buf, "%s:", dungeons[dnum].dname);
3102 else if (builds_up(&mptr->lev))
3104 Sprintf(buf, "%s: levels %d up to %d",
3106 Sprintf(buf, "%s: %d
\8aK
\82©
\82ç%d
\8aK",
3107 dungeons[dnum].dname,
3108 depthstart + dungeons[dnum].entry_lev - 1,
3109 depthstart + dungeons[dnum].dunlev_ureached - 1);
3112 Sprintf(buf, "%s: levels %d to %d",
3114 Sprintf(buf, "%s: %d
\8aK
\82©
\82ç%d
\8aK",
3115 dungeons[dnum].dname, depthstart,
3116 depthstart + dungeons[dnum].dunlev_ureached - 1);
3117 putstr(win, !final ? ATR_INVERSE : 0, buf);
3120 /* calculate level number */
3121 i = depthstart + mptr->lev.dlevel - 1;
3122 if (In_endgame(&mptr->lev))
3123 Sprintf(buf, "%s%s:", TAB, endgamelevelname(tmpbuf, i));
3126 Sprintf(buf, "%sLevel %d:", TAB, i);
3128 Sprintf(buf, "%s%d
\8aK:", TAB, i);
3130 /* wizmode prints out proto dungeon names for clarity */
3134 if ((slev = Is_special(&mptr->lev)) != 0)
3135 Sprintf(eos(buf), " [%s]", slev->proto);
3137 /* [perhaps print custom annotation on its own line when it's long] */
3139 Sprintf(eos(buf), " \"%s\"", mptr->custom);
3140 if (on_level(&u.uz, &mptr->lev))
3142 Sprintf(eos(buf), " <- You %s here.",
3143 (!final || (final == 1 && how == ASCENDED)) ? "are"
3144 : (final == 1 && how == ESCAPED) ? "left from"
3147 Sprintf(eos(buf), " <-
\82±
\82±%s
\81D",
3148 (!final || (final == 1 && how == ASCENDED)) ? "
\82É
\82¢
\82é"
3149 : (final == 1 && how == ESCAPED) ? "
\82©
\82ç
\94²
\82¯
\82½"
3152 putstr(win, !final ? ATR_BOLD : 0, buf);
3154 if (mptr->flags.forgot)
3157 if (INTEREST(mptr->feat)) {
3160 i = 0; /* interest counter */
3161 /* List interests in an order vaguely corresponding to
3162 * how important they are.
3164 if (mptr->feat.nshop > 0) {
3165 if (mptr->feat.nshop > 1)
3167 ADDNTOBUF("shop", mptr->feat.nshop);
3169 ADDNTOBUF("
\93X", mptr->feat.nshop);
3171 Sprintf(eos(buf), "%s%s", COMMA,
3172 an(shop_string(mptr->feat.shoptype)));
3174 if (mptr->feat.naltar > 0) {
3175 /* Temples + non-temple altars get munged into just "altars" */
3176 if (mptr->feat.ntemple != mptr->feat.naltar)
3178 ADDNTOBUF("altar", mptr->feat.naltar);
3180 ADDNTOBUF("
\8dÕ
\92d", mptr->feat.naltar);
3183 ADDNTOBUF("temple", mptr->feat.ntemple);
3185 ADDNTOBUF("
\8e\9b\89@", mptr->feat.ntemple);
3187 /* only print out altar's god if they are all to your god */
3188 if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
3190 Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
3192 Sprintf(eos(buf), "(%s)", align_gname(u.ualign.type));
3195 ADDNTOBUF("throne", mptr->feat.nthrone);
3197 ADDNTOBUF("
\8bÊ
\8dÀ", mptr->feat.nthrone);
3199 ADDNTOBUF("fountain", mptr->feat.nfount);
3201 ADDNTOBUF("
\90ò", mptr->feat.nfount);
3203 ADDNTOBUF("sink", mptr->feat.nsink);
3205 ADDNTOBUF("
\97¬
\82µ
\91ä", mptr->feat.nsink);
3207 ADDNTOBUF("grave", mptr->feat.ngrave);
3209 ADDNTOBUF("
\95æ", mptr->feat.ngrave);
3211 ADDNTOBUF("tree", mptr->feat.ntree);
3213 ADDNTOBUF("
\96Ø", mptr->feat.ntree);
3215 ADDTOBUF("water", mptr->feat.water);
3216 ADDTOBUF("lava", mptr->feat.lava);
3217 ADDTOBUF("ice", mptr->feat.ice);
3219 /* capitalize afterwards */
3221 buf[i] = highc(buf[i]);
3222 /* capitalizing it makes it a sentence; terminate with '.' */
3224 putstr(win, 0, buf);
3227 /* we assume that these are mutually exclusive */
3229 if (mptr->flags.oracle) {
3231 Sprintf(buf, "%sOracle of Delphi.", PREFIX);
3233 Sprintf(buf, "%s
\83f
\83\8b\83t
\83@
\83C
\82Ì
\90_
\93a
\81D", PREFIX);
3234 } else if (In_sokoban(&mptr->lev)) {
3236 Sprintf(buf, "%s%s.", PREFIX,
3237 mptr->flags.sokosolved ? "Solved" : "Unsolved");
3239 Sprintf(buf, "%s%s.", PREFIX,
3240 mptr->flags.sokosolved ? "
\83N
\83\8a\83A
\8dÏ" : "
\96¢
\83N
\83\8a\83A");
3242 } else if (mptr->flags.bigroom) {
3244 Sprintf(buf, "%sA very big room.", PREFIX);
3246 Sprintf(buf, "%s
\82Æ
\82Ä
\82à
\91å
\82«
\82¢
\95\94\89®
\81D", PREFIX);
3247 } else if (mptr->flags.roguelevel) {
3249 Sprintf(buf, "%sA primitive area.", PREFIX);
3251 Sprintf(buf, "%s
\92P
\8f\83\82È
\95\94\89®
\81D", PREFIX);
3252 } else if (on_level(&mptr->lev, &qstart_level)) {
3254 Sprintf(buf, "%sHome%s.", PREFIX,
3255 mptr->flags.unreachable ? " (no way back...)" : "");
3257 Sprintf(buf, "%s
\8cÌ
\8b½%s
\81D", PREFIX,
3258 mptr->flags.unreachable ? "(
\96ß
\82ê
\82È
\82¢
\81D
\81D
\81D)" : "");
3260 if (u.uevent.qcompleted)
3262 Sprintf(buf, "%sCompleted quest for %s.", PREFIX, ldrname());
3264 Sprintf(buf, "%s%s
\82Ì
\82½
\82ß
\82É
\83N
\83G
\83X
\83g
\82ð
\8a®
\90\8b\82µ
\82½
\81D", PREFIX, ldrname());
3265 else if (mptr->flags.questing)
3267 Sprintf(buf, "%sGiven quest by %s.", PREFIX, ldrname());
3269 Sprintf(buf, "%s%s
\82©
\82ç
\83N
\83G
\83X
\83g
\82ð
\97^
\82¦
\82ç
\82ê
\82½
\81D", PREFIX, ldrname());
3270 } else if (mptr->flags.ludios) {
3271 /* presence of the ludios branch in #overview output indicates that
3272 the player has made it onto the level; presence of this annotation
3273 indicates that the fort's entrance has been seen (or mapped) */
3275 Sprintf(buf, "%sFort Ludios.", PREFIX);
3277 Sprintf(buf, "%s
\83\8d\81[
\83f
\83B
\83I
\83X
\8dÔ
\81D", PREFIX);
3278 } else if (mptr->flags.castle) {
3280 Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
3282 Sprintf(buf, "%s
\8fé%s
\81D", PREFIX, tunesuffix(mptr, tmpbuf));
3283 } else if (mptr->flags.valley) {
3285 Sprintf(buf, "%sValley of the Dead.", PREFIX);
3287 Sprintf(buf, "%s
\8e\80\82Ì
\92J
\81D", PREFIX);
3288 } else if (mptr->flags.msanctum) {
3290 Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
3292 Sprintf(buf, "%s
\83\82\81[
\83\8d\83b
\83N
\82Ì
\90¹
\88æ
\81D", PREFIX);
3295 putstr(win, 0, buf);
3296 /* quest entrance is not mutually-exclusive with bigroom or rogue level */
3297 if (mptr->flags.quest_summons) {
3299 Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
3301 Sprintf(buf, "%s%s
\82©
\82ç
\8cÄ
\82Ñ
\8fo
\82³
\82ê
\82½
\81D", PREFIX, ldrname());
3302 putstr(win, 0, buf);
3305 /* print out branches */
3308 Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br),
3309 dungeons[mptr->br->end2.dnum].dname);
3311 Sprintf(buf, "%s%s
\82Ö
\82Ì%s", PREFIX, dungeons[mptr->br->end2.dnum].dname,
3312 br_string2(mptr->br));
3315 /* Since mapseen objects are printed out in increasing order
3316 * of dlevel, clarify which level this branch is going to
3317 * if the branch goes upwards. Unless it's the end game.
3319 if (mptr->br->end1_up && !In_endgame(&(mptr->br->end2)))
3321 Sprintf(eos(buf), ", level %d", depth(&(mptr->br->end2)));
3323 Sprintf(eos(buf), ", %d
\8aK", depth(&(mptr->br->end2)));
3325 putstr(win, 0, buf);
3328 /* maybe print out bones details */
3329 if (mptr->final_resting_place || final) {
3330 struct cemetery *bp;
3331 int kncnt = !died_here ? 0 : 1;
3333 for (bp = mptr->final_resting_place; bp; bp = bp->next)
3334 if (bp->bonesknown || wizard || final)
3338 Sprintf(buf, "%s%s", PREFIX, "Final resting place for");
3340 Sprintf(buf, "%s%s", PREFIX, "
\8dÅ
\8aú
\82Ì
\92n:");
3341 putstr(win, 0, buf);
3343 /* disclosure occurs before bones creation, so listing dead
3344 hero here doesn't give away whether bones are produced */
3345 formatkiller(tmpbuf, sizeof tmpbuf, how, TRUE);
3347 /* rephrase a few death reasons to work with "you" */
3348 (void) strsubst(tmpbuf, " himself", " yourself");
3349 (void) strsubst(tmpbuf, " herself", " yourself");
3350 (void) strsubst(tmpbuf, " his ", " your ");
3351 (void) strsubst(tmpbuf, " her ", " your ");
3354 Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf,
3355 --kncnt ? ',' : '.');
3357 Sprintf(buf, "%s%s %s%c", PREFIX, TAB, tmpbuf,
3358 --kncnt ? ',' : '.');
3360 putstr(win, 0, buf);
3362 for (bp = mptr->final_resting_place; bp; bp = bp->next) {
3363 if (bp->bonesknown || wizard || final) {
3364 Sprintf(buf, "%s%s%s, %s%c", PREFIX, TAB, bp->who,
3365 bp->how, --kncnt ? ',' : '.');
3366 putstr(win, 0, buf);