OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / src / dungeon.c
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. */
5
6 #include "hack.h"
7 #include "dgn_file.h"
8 #include "dlb.h"
9 #include "lev.h"
10
11 #define DUNGEON_FILE "dungeon"
12
13 #define X_START "x-strt"
14 #define X_LOCATE "x-loca"
15 #define X_GOAL "x-goal"
16
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];
22
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 */
26 };
27
28 int n_dgns;     /* number of dungeons (also used in mklev.c and do.c) */
29 static branch *branches = (branch *) 0;        /* dungeon branch list */
30
31 mapseen *mapseenchn = (struct mapseen *) 0; /*DUNGEON_OVERVIEW*/
32
33 struct lchoice {
34     int idx;
35     schar lev[MAXLINFO];
36     schar playerlev[MAXLINFO];
37     xchar dgn[MAXLINFO];
38     char menuletter;
39 };
40
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 *,
59                                    BOOLEAN_P));
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,
63                                      struct lchoice *));
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,
71                                             int, int, int *));
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 *));
77
78 #ifdef DEBUG
79 #define DD dungeons[i]
80 STATIC_DCL void NDECL(dumpit);
81
82 STATIC_OVL void
83 dumpit()
84 {
85     int i;
86     s_level *x;
87     branch *br;
88
89     if (!explicitdebug(__FILE__))
90         return;
91
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" : "");
102         getchar();
103     }
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" : "");
113         getchar();
114     }
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,
118                 br->type == BR_STAIR
119                     ? "stair"
120                     : br->type == BR_NO_END1
121                         ? "no end1"
122                         : br->type == BR_NO_END2
123                             ? "no end2"
124                             : br->type == BR_PORTAL
125                                 ? "portal"
126                                 : "unknown",
127                 br->end1.dnum, br->end1.dlevel, br->end2.dnum,
128                 br->end2.dlevel, br->end1_up ? "end1 up" : "end1 down");
129     }
130     getchar();
131     fprintf(stderr, "\nDone\n");
132     getchar();
133 }
134 #endif
135
136 /* Save the dungeon structures. */
137 void
138 save_dungeon(fd, perform_write, free_data)
139 int fd;
140 boolean perform_write, free_data;
141 {
142     branch *curr, *next;
143     mapseen *curr_ms, *next_ms;
144     int count;
145
146     if (perform_write) {
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);
152
153         for (count = 0, curr = branches; curr; curr = curr->next)
154             count++;
155         bwrite(fd, (genericptr_t) &count, sizeof(count));
156
157         for (curr = branches; curr; curr = curr->next)
158             bwrite(fd, (genericptr_t) curr, sizeof(branch));
159
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);
165
166         for (count = 0, curr_ms = mapseenchn; curr_ms;
167              curr_ms = curr_ms->next)
168             count++;
169         bwrite(fd, (genericptr_t) &count, sizeof(count));
170
171         for (curr_ms = mapseenchn; curr_ms; curr_ms = curr_ms->next)
172             save_mapseen(fd, curr_ms);
173     }
174
175     if (free_data) {
176         for (curr = branches; curr; curr = next) {
177             next = curr->next;
178             free((genericptr_t) curr);
179         }
180         branches = 0;
181         for (curr_ms = mapseenchn; curr_ms; curr_ms = next_ms) {
182             next_ms = curr_ms->next;
183             if (curr_ms->custom)
184                 free((genericptr_t) curr_ms->custom);
185             free((genericptr_t) curr_ms);
186         }
187         mapseenchn = 0;
188     }
189 }
190
191 /* Restore the dungeon structures. */
192 void
193 restore_dungeon(fd)
194 int fd;
195 {
196     branch *curr, *last;
197     int count, i;
198     mapseen *curr_ms, *last_ms;
199
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);
204
205     last = branches = (branch *) 0;
206
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;
212         if (last)
213             last->next = curr;
214         else
215             branches = curr;
216         last = curr;
217     }
218
219     mread(fd, (genericptr_t) &count, sizeof(count));
220     if (count >= MAXLINFO)
221         panic("level information count larger (%d) than allocated size",
222               count);
223     mread(fd, (genericptr_t) level_info,
224           (unsigned) count * sizeof(struct linfo));
225     mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos);
226
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;
232         if (last_ms)
233             last_ms->next = curr_ms;
234         else
235             mapseenchn = curr_ms;
236         last_ms = curr_ms;
237     }
238 }
239
240 static void
241 Fread(ptr, size, nitems, stream)
242 genericptr_t ptr;
243 int size, nitems;
244 dlb *stream;
245 {
246     int cnt;
247
248     if ((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) {
249         panic(
250   "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.",
251               (size * nitems), (size * cnt));
252         nh_terminate(EXIT_FAILURE);
253     }
254 }
255
256 STATIC_OVL xchar
257 dname_to_dnum(s)
258 const char *s;
259 {
260     xchar i;
261
262     for (i = 0; i < n_dgns; i++)
263         if (!strcmp(dungeons[i].dname, s))
264             return i;
265
266     panic("Couldn't resolve dungeon number for name \"%s\".", s);
267     /*NOT REACHED*/
268     return (xchar) 0;
269 }
270
271 s_level *
272 find_level(s)
273 const char *s;
274 {
275     s_level *curr;
276     for (curr = sp_levchn; curr; curr = curr->next)
277         if (!strcmpi(s, curr->proto))
278             break;
279     return curr;
280 }
281
282 /* Find the branch that links the named dungeon. */
283 STATIC_OVL int
284 find_branch(s, pd)
285 const char *s; /* dungeon name */
286 struct proto_dungeon *pd;
287 {
288     int i;
289
290     if (pd) {
291         for (i = 0; i < pd->n_brs; i++)
292             if (!strcmp(pd->tmpbranch[i].name, s))
293                 break;
294         if (i == pd->n_brs)
295             panic("find_branch: can't find %s", s);
296     } else {
297         /* support for level tport by name */
298         branch *br;
299         const char *dnam;
300
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)))
305                 break;
306         }
307         i = br ? ((ledger_no(&br->end1) << 8) | ledger_no(&br->end2)) : -1;
308     }
309     return i;
310 }
311
312 /*
313  * Find the "parent" by searching the prototype branch list for the branch
314  * listing, then figuring out to which dungeon it belongs.
315  */
316 STATIC_OVL xchar
317 parent_dnum(s, pd)
318 const char *s; /* dungeon name */
319 struct proto_dungeon *pd;
320 {
321     int i;
322     xchar pdnum;
323
324     i = find_branch(s, pd);
325     /*
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).
328      */
329     for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++)
330         if ((i -= pd->tmpdungeon[pdnum].branches) < 0)
331             return pdnum;
332
333     panic("parent_dnum: couldn't resolve branch.");
334     /*NOT REACHED*/
335     return (xchar) 0;
336 }
337
338 /*
339  * Return a starting point and number of successive positions a level
340  * or dungeon entrance can occupy.
341  *
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.
347  */
348 STATIC_OVL int
349 level_range(dgn, base, randc, chain, pd, adjusted_base)
350 xchar dgn;
351 int base, randc, chain;
352 struct proto_dungeon *pd;
353 int *adjusted_base;
354 {
355     int lmax = dungeons[dgn].num_dunlevs;
356
357     if (chain >= 0) { /* relative to a special level */
358         s_level *levtmp = pd->final_lev[chain];
359         if (!levtmp)
360             panic("level_range: empty chain level!");
361
362         base += levtmp->dlevel.dlevel;
363     } else { /* absolute in the dungeon */
364         /* from end of dungeon */
365         if (base < 0)
366             base = (lmax + base + 1);
367     }
368
369     if (base < 1 || base > lmax)
370         panic("level_range: base value out of range");
371
372     *adjusted_base = base;
373
374     if (randc == -1) { /* from base to end of dungeon */
375         return (lmax - base + 1);
376     } else if (randc) {
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 */
380     return 1;
381 }
382
383 STATIC_OVL xchar
384 parent_dlevel(s, pd)
385 const char *s;
386 struct proto_dungeon *pd;
387 {
388     int i, j, num, base, dnum = parent_dnum(s, pd);
389     branch *curr;
390
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,
394                       &base);
395
396     /* KMH -- Try our best to find a level without an existing branch */
397     i = j = rn2(num);
398     do {
399         if (++i >= num)
400             i = 0;
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))
404                 break;
405     } while (curr && i != j);
406     return (base + i);
407 }
408
409 /* Convert from the temporary branch type to the dungeon branch type. */
410 STATIC_OVL int
411 correct_branch_type(tbr)
412 struct tmpbranch *tbr;
413 {
414     switch (tbr->type) {
415     case TBR_STAIR:
416         return BR_STAIR;
417     case TBR_NO_UP:
418         return tbr->up ? BR_NO_END1 : BR_NO_END2;
419     case TBR_NO_DOWN:
420         return tbr->up ? BR_NO_END2 : BR_NO_END1;
421     case TBR_PORTAL:
422         return BR_PORTAL;
423     }
424     impossible("correct_branch_type: unknown branch type");
425     return BR_STAIR;
426 }
427
428 /*
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.
433  */
434 void
435 insert_branch(new_branch, extract_first)
436 branch *new_branch;
437 boolean extract_first;
438 {
439     branch *curr, *prev;
440     long new_val, curr_val, prev_val;
441
442     if (extract_first) {
443         for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next)
444             if (curr == new_branch)
445                 break;
446
447         if (!curr)
448             panic("insert_branch: not found");
449         if (prev)
450             prev->next = curr->next;
451         else
452             branches = curr->next;
453     }
454     new_branch->next = (branch *) 0;
455
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))
461
462     /*
463      * Insert the new branch into the correct place in the branch list.
464      */
465     prev = (branch *) 0;
466     prev_val = -1;
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)
472             break;
473     }
474     if (prev) {
475         new_branch->next = curr;
476         prev->next = new_branch;
477     } else {
478         new_branch->next = branches;
479         branches = new_branch;
480     }
481 }
482
483 /* Add a dungeon branch to the branch list. */
484 STATIC_OVL branch *
485 add_branch(dgn, child_entry_level, pd)
486 int dgn;
487 int child_entry_level;
488 struct proto_dungeon *pd;
489 {
490     static int branch_id = 0;
491     int branch_num;
492     branch *new_branch;
493
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;
505
506     insert_branch(new_branch, FALSE);
507     return new_branch;
508 }
509
510 /*
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
514  * last entry.
515  */
516 STATIC_OVL void
517 add_level(new_lev)
518 s_level *new_lev;
519 {
520     s_level *prev, *curr;
521
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)
526             break;
527         prev = curr;
528     }
529     if (!prev) {
530         new_lev->next = sp_levchn;
531         sp_levchn = new_lev;
532     } else {
533         new_lev->next = curr;
534         prev->next = new_lev;
535     }
536 }
537
538 STATIC_OVL void
539 init_level(dgn, proto_index, pd)
540 int dgn, proto_index;
541 struct proto_dungeon *pd;
542 {
543     s_level *new_level;
544     struct tmplevel *tlevel = &pd->tmplevel[proto_index];
545
546     pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */
547     if (!wizard && tlevel->chance <= rn2(100))
548         return;
549
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 */
558
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);
567
568     new_level->rndlevs = tlevel->rndlevs;
569     new_level->next = (s_level *) 0;
570 }
571
572 STATIC_OVL int
573 possible_places(idx, map, pd)
574 int idx;      /* prototype index */
575 boolean *map; /* array MAXLEVEL+1 in length */
576 struct proto_dungeon *pd;
577 {
578     int i, start, count;
579     s_level *lev = pd->final_lev[idx];
580
581     /* init level possibilities */
582     for (i = 0; i <= MAXLEVEL; i++)
583         map[i] = FALSE;
584
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,
588                         pd, &start);
589     for (i = start; i < start + count; i++)
590         map[i] = TRUE;
591
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;
596             --count;
597         }
598     }
599
600     return count;
601 }
602
603 /* Pick the nth TRUE entry in the given boolean array. */
604 STATIC_OVL xchar
605 pick_level(map, nth)
606 boolean *map; /* an array MAXLEVEL+1 in size */
607 int nth;
608 {
609     int i;
610     for (i = 1; i <= MAXLEVEL; i++)
611         if (map[i] && !nth--)
612             return (xchar) i;
613     panic("pick_level:  ran out of valid levels");
614     return 0;
615 }
616
617 #ifdef DDEBUG
618 static void FDECL(indent, (int));
619
620 static void
621 indent(d)
622 int d;
623 {
624     while (d-- > 0)
625         fputs("    ", stderr);
626 }
627 #endif
628
629 /*
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.
635  */
636 STATIC_OVL boolean
637 place_level(proto_index, pd)
638 int proto_index;
639 struct proto_dungeon *pd;
640 {
641     boolean map[MAXLEVEL + 1]; /* valid levels are 1..MAXLEVEL inclusive */
642     s_level *lev;
643     int npossible;
644 #ifdef DDEBUG
645     int i;
646 #endif
647
648     if (proto_index == pd->n_levs)
649         return TRUE; /* at end of proto levels */
650
651     lev = pd->final_lev[proto_index];
652
653     /* No level created for this prototype, goto next. */
654     if (!lev)
655         return place_level(proto_index + 1, pd);
656
657     npossible = possible_places(proto_index, map, pd);
658
659     for (; npossible; --npossible) {
660         lev->dlevel.dlevel = pick_level(map, rn2(npossible));
661 #ifdef DDEBUG
662         indent(proto_index - pd->start);
663         fprintf(stderr, "%s: trying %d [ ", lev->proto, lev->dlevel.dlevel);
664         for (i = 1; i <= MAXLEVEL; i++)
665             if (map[i])
666                 fprintf(stderr, "%d ", i);
667         fprintf(stderr, "]\n");
668 #endif
669         if (place_level(proto_index + 1, pd))
670             return TRUE;
671         map[lev->dlevel.dlevel] = FALSE; /* this choice didn't work */
672     }
673 #ifdef DDEBUG
674     indent(proto_index - pd->start);
675     fprintf(stderr, "%s: failed\n", lev->proto);
676 #endif
677     return FALSE;
678 }
679
680 struct level_map {
681     const char *lev_name;
682     d_level *lev_spec;
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 } };
710
711 /* initialize the "dungeon" structs */
712 void
713 init_dungeons()
714 {
715     dlb *dgn_file;
716     register int i, cl = 0, cb = 0;
717     register s_level *x;
718     struct proto_dungeon pd;
719     struct level_map *lev_map;
720     struct version_info vers_info;
721
722     pd.n_levs = pd.n_brs = 0;
723
724     dgn_file = dlb_fopen(DUNGEON_FILE, RDBMODE);
725     if (!dgn_file) {
726         char tbuf[BUFSZ];
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 */
731 #if defined(DLB)
732         Strcat(tbuf, "\" from ");
733 #ifdef PREFIXES_IN_USE
734         Strcat(tbuf, "\n\"");
735         if (fqn_prefix[DATAPREFIX])
736             Strcat(tbuf, fqn_prefix[DATAPREFIX]);
737 #else
738         Strcat(tbuf, "\"");
739 #endif
740         Strcat(tbuf, DLBFILE);
741 #endif
742         Strcat(tbuf, "\" file!");
743 #endif
744 #ifdef WIN32
745         interject_assistance(1, INTERJECT_PANIC, (genericptr_t) tbuf,
746                              (genericptr_t) fqn_prefix[DATAPREFIX]);
747 #endif
748         panic1(tbuf);
749     }
750
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
756      */
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.");
761
762     /*
763      * Read in each dungeon and transfer the results to the internal
764      * dungeon arrays.
765      */
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");
770
771     for (i = 0; i < n_dgns; i++) {
772         Fread((genericptr_t) &pd.tmpdungeon[i], sizeof(struct tmpdungeon), 1,
773               dgn_file);
774         if (!wizard && pd.tmpdungeon[i].chance
775             && (pd.tmpdungeon[i].chance <= rn2(100))) {
776             int j;
777
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);
782
783             for (j = 0; j < pd.tmpdungeon[i].branches; j++)
784                 Fread((genericptr_t) &pd.tmpbranch[cb],
785                       sizeof(struct tmpbranch), 1, dgn_file);
786             n_dgns--;
787             i--;
788             continue;
789         }
790
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;
794
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);
798         else
799             dungeons[i].num_dunlevs = (xchar) pd.tmpdungeon[i].lev.base;
800
801         if (!i) {
802             dungeons[i].ledger_start = 0;
803             dungeons[i].depth_start = 1;
804             dungeons[i].dunlev_ureached = 1;
805         } else {
806             dungeons[i].ledger_start =
807                 dungeons[i - 1].ledger_start + dungeons[i - 1].num_dunlevs;
808             dungeons[i].dunlev_ureached = 0;
809         }
810
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);
816         /*
817          * Set the entry level for this dungeon.  The pd.tmpdungeon entry
818          * value means:
819          *              < 0     from bottom (-1 == bottom level)
820          *                0     default (top)
821          *              > 0     actual level (1 = top)
822          *
823          * Note that the entry_lev field in the dungeon structure is
824          * redundant.  It is used only here and in print_dungeon().
825          */
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 */
837         }
838
839         if (i) { /* set depth */
840             branch *br;
841             schar from_depth;
842             boolean from_up;
843
844             br = add_branch(i, dungeons[i].entry_lev, &pd);
845
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;
850             } else {
851                 from_depth = depth(&br->end1);
852                 from_up = br->end1_up;
853             }
854
855             /*
856              * Calculate the depth of the top of the dungeon via
857              * its branch.  First, the depth of the entry point:
858              *
859              *  depth of branch from "parent" dungeon
860              *  + -1 or 1 depending on an up or down stair or
861              *    0 if portal
862              *
863              * Followed by the depth of the top of the dungeon:
864              *
865              *  - (entry depth - 1)
866              *
867              * We'll say that portals stay on the same depth.
868              */
869             dungeons[i].depth_start =
870                 from_depth + (br->type == BR_PORTAL ? 0 : (from_up ? -1 : 1))
871                 - (dungeons[i].entry_lev - 1);
872         }
873
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;
877
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");
882         /*
883          * Read in the prototype special levels.  Don't add generated
884          * special levels until they are all placed.
885          */
886         for (; cl < pd.n_levs; cl++) {
887             Fread((genericptr_t) &pd.tmplevel[cl], sizeof(struct tmplevel), 1,
888                   dgn_file);
889             init_level(i, cl, &pd);
890         }
891         /*
892          * Recursively place the generated levels for this dungeon.  This
893          * routine will attempt all possible combinations before giving
894          * up.
895          */
896         if (!place_level(pd.start, &pd))
897             panic("init_dungeon:  couldn't place levels");
898 #ifdef DDEBUG
899         fprintf(stderr, "--- end of dungeon %d ---\n", i);
900         fflush(stderr);
901         getchar();
902 #endif
903         for (; pd.start < pd.n_levs; pd.start++)
904             if (pd.final_lev[pd.start])
905                 add_level(pd.final_lev[pd.start]);
906
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),
912                   1, dgn_file);
913     }
914     (void) dlb_fclose(dgn_file);
915
916     for (i = 0; i < 5; i++)
917         tune[i] = 'A' + rn2(7);
918     tune[5] = 0;
919
920     /*
921      * Find most of the special levels and dungeons so we can access their
922      * locations quickly.
923      */
924     for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) {
925         x = find_level(lev_map->lev_name);
926         if (x) {
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.
931                  */
932                 Sprintf(x->proto, "%s%s", urole.filecode,
933                         &lev_map->lev_name[1]);
934             } else if (lev_map->lev_spec == &knox_level) {
935                 branch *br;
936                 /*
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
940                  * n_dgns.
941                  */
942                 for (br = branches; br; br = br->next)
943                     if (on_level(&br->end2, &knox_level))
944                         break;
945
946                 if (br)
947                     br->end1.dnum = n_dgns;
948                 /* adjust the branch's position on the list */
949                 insert_branch(br, TRUE);
950             }
951         }
952     }
953     /*
954      *  I hate hardwiring these names. :-(
955      */
956 /*JP
957     quest_dnum = dname_to_dnum("The Quest");
958 */
959     quest_dnum = dname_to_dnum("\83N\83G\83X\83g");
960 /*JP
961     sokoban_dnum = dname_to_dnum("Sokoban");
962 */
963     sokoban_dnum = dname_to_dnum("\91q\8cÉ\94Ô");
964 /*JP
965     mines_dnum = dname_to_dnum("The Gnomish Mines");
966 */
967     mines_dnum = dname_to_dnum("\83m\81[\83\80\82Ì\8dz\8eR");
968 /*JP
969     tower_dnum = dname_to_dnum("Vlad's Tower");
970 */
971     tower_dnum = dname_to_dnum("\83\94\83\89\83h\8cò\82Ì\93\83");
972
973     /* one special fixup for dummy surface level */
974     if ((x = find_level("dummy")) != 0) {
975         i = x->dlevel.dnum;
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. */
984     }
985
986 #ifdef DEBUG
987     dumpit();
988 #endif
989 }
990
991 /* return the level number for lev in *this* dungeon */
992 xchar
993 dunlev(lev)
994 d_level *lev;
995 {
996     return lev->dlevel;
997 }
998
999 /* return the lowest level number for *this* dungeon */
1000 xchar
1001 dunlevs_in_dungeon(lev)
1002 d_level *lev;
1003 {
1004     return dungeons[lev->dnum].num_dunlevs;
1005 }
1006
1007 /* return the lowest level explored in the game*/
1008 xchar
1009 deepest_lev_reached(noquest)
1010 boolean noquest;
1011 {
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.
1017      *
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.
1026      */
1027     register int i;
1028     d_level tmp;
1029     register schar ret = 0;
1030
1031     for (i = 0; i < n_dgns; i++) {
1032         if (noquest && i == quest_dnum)
1033             continue;
1034         tmp.dlevel = dungeons[i].dunlev_ureached;
1035         if (tmp.dlevel == 0)
1036             continue;
1037         tmp.dnum = i;
1038         if (depth(&tmp) > ret)
1039             ret = depth(&tmp);
1040     }
1041     return (xchar) ret;
1042 }
1043
1044 /* return a bookkeeping level number for purpose of comparisons and
1045    save/restore */
1046 xchar
1047 ledger_no(lev)
1048 d_level *lev;
1049 {
1050     return (xchar) (lev->dlevel + dungeons[lev->dnum].ledger_start);
1051 }
1052
1053 /*
1054  * The last level in the bookkeeping list of level is the bottom of the last
1055  * dungeon in the dungeons[] array.
1056  *
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.
1062  */
1063 xchar
1064 maxledgerno()
1065 {
1066     return (xchar) (dungeons[n_dgns - 1].ledger_start
1067                     + dungeons[n_dgns - 1].num_dunlevs);
1068 }
1069
1070 /* return the dungeon that this ledgerno exists in */
1071 xchar
1072 ledger_to_dnum(ledgerno)
1073 xchar ledgerno;
1074 {
1075     register int i;
1076
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)
1081             return (xchar) i;
1082
1083     panic("level number out of range [ledger_to_dnum(%d)]", (int) ledgerno);
1084     /*NOT REACHED*/
1085     return (xchar) 0;
1086 }
1087
1088 /* return the level of the dungeon this ledgerno exists in */
1089 xchar
1090 ledger_to_dlev(ledgerno)
1091 xchar ledgerno;
1092 {
1093     return (xchar) (ledgerno
1094                     - dungeons[ledger_to_dnum(ledgerno)].ledger_start);
1095 }
1096
1097 /* returns the depth of a level, in floors below the surface
1098    (note levels in different dungeons can have the same depth) */
1099 schar
1100 depth(lev)
1101 d_level *lev;
1102 {
1103     return (schar) (dungeons[lev->dnum].depth_start + lev->dlevel - 1);
1104 }
1105
1106 /* are "lev1" and "lev2" actually the same? */
1107 boolean
1108 on_level(lev1, lev2)
1109 d_level *lev1, *lev2;
1110 {
1111     return (boolean) (lev1->dnum == lev2->dnum
1112                       && lev1->dlevel == lev2->dlevel);
1113 }
1114
1115 /* is this level referenced in the special level chain? */
1116 s_level *
1117 Is_special(lev)
1118 d_level *lev;
1119 {
1120     s_level *levtmp;
1121
1122     for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next)
1123         if (on_level(lev, &levtmp->dlevel))
1124             return levtmp;
1125
1126     return (s_level *) 0;
1127 }
1128
1129 /*
1130  * Is this a multi-dungeon branch level?  If so, return a pointer to the
1131  * branch.  Otherwise, return null.
1132  */
1133 branch *
1134 Is_branchlev(lev)
1135 d_level *lev;
1136 {
1137     branch *curr;
1138
1139     for (curr = branches; curr; curr = curr->next) {
1140         if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2))
1141             return curr;
1142     }
1143     return (branch *) 0;
1144 }
1145
1146 /* returns True iff the branch 'lev' is in a branch which builds up */
1147 boolean
1148 builds_up(lev)
1149 d_level *lev;
1150 {
1151     dungeon *dptr = &dungeons[lev->dnum];
1152     /*
1153      * FIXME:  this misclassifies a single level branch reached via stairs
1154      * from below.  Saving grace is that no such branches currently exist.
1155      */
1156     return (boolean) (dptr->num_dunlevs > 1
1157                       && dptr->entry_lev == dptr->num_dunlevs);
1158 }
1159
1160 /* goto the next level (or appropriate dungeon) */
1161 void
1162 next_level(at_stairs)
1163 boolean at_stairs;
1164 {
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);
1168     } else {
1169         /* Going down a stairs or jump in a trap door. */
1170         d_level newlevel;
1171
1172         newlevel.dnum = u.uz.dnum;
1173         newlevel.dlevel = u.uz.dlevel + 1;
1174         goto_level(&newlevel, at_stairs, !at_stairs, FALSE);
1175     }
1176 }
1177
1178 /* goto the previous level (or appropriate dungeon) */
1179 void
1180 prev_level(at_stairs)
1181 boolean at_stairs;
1182 {
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)
1188             done(ESCAPED);
1189         else
1190             goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
1191     } else {
1192         /* Going up a stairs or rising through the ceiling. */
1193         d_level newlevel;
1194         newlevel.dnum = u.uz.dnum;
1195         newlevel.dlevel = u.uz.dlevel - 1;
1196         goto_level(&newlevel, at_stairs, FALSE, FALSE);
1197     }
1198 }
1199
1200 void
1201 u_on_newpos(x, y)
1202 int x, y;
1203 {
1204     u.ux = x;
1205     u.uy = y;
1206 #ifdef CLIPPING
1207     cliparound(u.ux, u.uy);
1208 #endif
1209     /* ridden steed always shares hero's location */
1210     if (u.usteed)
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;
1216 }
1217
1218 /* place you on a random location */
1219 void
1220 u_on_rndspot(upflag)
1221 int upflag;
1222 {
1223     int up = (upflag & 1), was_in_W_tower = (upflag & 2);
1224
1225     /*
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.
1229      */
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);
1238     else if (up)
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);
1242     else
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);
1246 }
1247
1248 /* place you on the special staircase */
1249 void
1250 u_on_sstairs(upflag)
1251 int upflag;
1252 {
1253     if (sstairs.sx)
1254         u_on_newpos(sstairs.sx, sstairs.sy);
1255     else
1256         u_on_rndspot(upflag);
1257 }
1258
1259 /* place you on upstairs (or special equivalent) */
1260 void
1261 u_on_upstairs()
1262 {
1263     if (xupstair)
1264         u_on_newpos(xupstair, yupstair);
1265     else
1266         u_on_sstairs(0); /* destination upstairs implies moving down */
1267 }
1268
1269 /* place you on dnstairs (or special equivalent) */
1270 void
1271 u_on_dnstairs()
1272 {
1273     if (xdnstair)
1274         u_on_newpos(xdnstair, ydnstair);
1275     else
1276         u_on_sstairs(1); /* destination dnstairs implies moving up */
1277 }
1278
1279 boolean
1280 On_stairs(x, y)
1281 xchar x, y;
1282 {
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));
1288 }
1289
1290 boolean
1291 Is_botlevel(lev)
1292 d_level *lev;
1293 {
1294     return (boolean) (lev->dlevel == dungeons[lev->dnum].num_dunlevs);
1295 }
1296
1297 boolean
1298 Can_dig_down(lev)
1299 d_level *lev;
1300 {
1301     return (boolean) (!level.flags.hardfloor
1302                       && !Is_botlevel(lev)
1303                       && !Invocation_lev(lev));
1304 }
1305
1306 /*
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.
1310  */
1311 boolean
1312 Can_fall_thru(lev)
1313 d_level *lev;
1314 {
1315     return (boolean) (Can_dig_down(lev) || Is_stronghold(lev));
1316 }
1317
1318 /*
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.
1323  */
1324 boolean
1325 Can_rise_up(x, y, lev)
1326 int x, y;
1327 d_level *lev;
1328 {
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)))
1333         return FALSE;
1334     return (boolean) (lev->dlevel > 1
1335                       || (dungeons[lev->dnum].entry_lev == 1
1336                           && ledger_no(lev) != 1
1337                           && sstairs.sx && sstairs.up));
1338 }
1339
1340 boolean
1341 has_ceiling(lev)
1342 d_level *lev;
1343 {
1344     /* [what about level 1 of the quest?] */
1345     return (boolean) (!Is_airlevel(lev) && !Is_waterlevel(lev));
1346 }
1347
1348 /*
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.
1358  */
1359 void
1360 get_level(newlevel, levnum)
1361 d_level *newlevel;
1362 int levnum;
1363 {
1364     branch *br;
1365     xchar dgn = u.uz.dnum;
1366
1367     if (levnum <= 0) {
1368         /* can only currently happen in endgame */
1369         levnum = u.uz.dlevel;
1370     } else if (levnum
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;
1374     } else {
1375         /* The desired level is in this dungeon or a "higher" one. */
1376
1377         /*
1378          * Branch up the tree until we reach a dungeon that contains the
1379          * levnum.
1380          */
1381         if (levnum < dungeons[dgn].depth_start) {
1382             do {
1383                 /*
1384                  * Find the parent dungeon of this dungeon.
1385                  *
1386                  * This assumes that end2 is always the "child" and it is
1387                  * unique.
1388                  */
1389                 for (br = branches; br; br = br->next)
1390                     if (br->end2.dnum == dgn)
1391                         break;
1392                 if (!br)
1393                     panic("get_level: can't find parent dungeon");
1394
1395                 dgn = br->end1.dnum;
1396             } while (levnum < dungeons[dgn].depth_start);
1397         }
1398
1399         /* We're within the same dungeon; calculate the level. */
1400         levnum = levnum - dungeons[dgn].depth_start + 1;
1401     }
1402
1403     newlevel->dnum = dgn;
1404     newlevel->dlevel = levnum;
1405 }
1406
1407 /* are you in the quest dungeon? */
1408 boolean
1409 In_quest(lev)
1410 d_level *lev;
1411 {
1412     return (boolean) (lev->dnum == quest_dnum);
1413 }
1414
1415 /* are you in the mines dungeon? */
1416 boolean
1417 In_mines(lev)
1418 d_level *lev;
1419 {
1420     return (boolean) (lev->dnum == mines_dnum);
1421 }
1422
1423 /*
1424  * Return the branch for the given dungeon.
1425  *
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.
1430  */
1431 branch *
1432 dungeon_branch(s)
1433 const char *s;
1434 {
1435     branch *br;
1436     xchar dnum;
1437
1438     dnum = dname_to_dnum(s);
1439
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)
1443             break;
1444
1445     if (!br)
1446         panic("dgn_entrance: can't find entrance to %s", s);
1447
1448     return br;
1449 }
1450
1451 /*
1452  * This returns true if the hero is on the same level as the entrance to
1453  * the named dungeon.
1454  *
1455  * Called from do.c and mklev.c.
1456  *
1457  * Assumes that end1 is always the "parent".
1458  */
1459 boolean
1460 at_dgn_entrance(s)
1461 const char *s;
1462 {
1463     branch *br;
1464
1465     br = dungeon_branch(s);
1466     return on_level(&u.uz, &br->end1) ? TRUE : FALSE;
1467 }
1468
1469 /* is `lev' part of Vlad's tower? */
1470 boolean
1471 In_V_tower(lev)
1472 d_level *lev;
1473 {
1474     return (boolean) (lev->dnum == tower_dnum);
1475 }
1476
1477 /* is `lev' a level containing the Wizard's tower? */
1478 boolean
1479 On_W_tower_level(lev)
1480 d_level *lev;
1481 {
1482     return (boolean) (Is_wiz1_level(lev)
1483                       || Is_wiz2_level(lev)
1484                       || Is_wiz3_level(lev));
1485 }
1486
1487 /* is <x,y> of `lev' inside the Wizard's tower? */
1488 boolean
1489 In_W_tower(x, y, lev)
1490 int x, y;
1491 d_level *lev;
1492 {
1493     if (!On_W_tower_level(lev))
1494         return FALSE;
1495     /*
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} );
1499      */
1500     if (dndest.nlx > 0)
1501         return (boolean) within_bounded_area(x, y, dndest.nlx, dndest.nly,
1502                                              dndest.nhx, dndest.nhy);
1503     else
1504         impossible("No boundary for Wizard's Tower?");
1505     return FALSE;
1506 }
1507
1508 /* are you in one of the Hell levels? */
1509 boolean
1510 In_hell(lev)
1511 d_level *lev;
1512 {
1513     return (boolean) (dungeons[lev->dnum].flags.hellish);
1514 }
1515
1516 /* sets *lev to be the gateway to Gehennom... */
1517 void
1518 find_hell(lev)
1519 d_level *lev;
1520 {
1521     lev->dnum = valley_level.dnum;
1522     lev->dlevel = 1;
1523 }
1524
1525 /* go directly to hell... */
1526 void
1527 goto_hell(at_stairs, falling)
1528 boolean at_stairs, falling;
1529 {
1530     d_level lev;
1531
1532     find_hell(&lev);
1533     goto_level(&lev, at_stairs, falling, FALSE);
1534 }
1535
1536 /* equivalent to dest = source */
1537 void
1538 assign_level(dest, src)
1539 d_level *dest, *src;
1540 {
1541     dest->dnum = src->dnum;
1542     dest->dlevel = src->dlevel;
1543 }
1544
1545 /* dest = src + rn1(range) */
1546 void
1547 assign_rnd_level(dest, src, range)
1548 d_level *dest, *src;
1549 int range;
1550 {
1551     dest->dnum = src->dnum;
1552     dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range));
1553
1554     if (dest->dlevel > dunlevs_in_dungeon(dest))
1555         dest->dlevel = dunlevs_in_dungeon(dest);
1556     else if (dest->dlevel < 1)
1557         dest->dlevel = 1;
1558 }
1559
1560 int
1561 induced_align(pct)
1562 int pct;
1563 {
1564     s_level *lev = Is_special(&u.uz);
1565     aligntyp al;
1566
1567     if (lev && lev->flags.align)
1568         if (rn2(100) < pct)
1569             return lev->flags.align;
1570
1571     if (dungeons[u.uz.dnum].flags.align)
1572         if (rn2(100) < pct)
1573             return dungeons[u.uz.dnum].flags.align;
1574
1575     al = rn2(3) - 1;
1576     return Align2amask(al);
1577 }
1578
1579 boolean
1580 Invocation_lev(lev)
1581 d_level *lev;
1582 {
1583     return (boolean) (In_hell(lev)
1584                       && lev->dlevel == dungeons[lev->dnum].num_dunlevs - 1);
1585 }
1586
1587 /* use instead of depth() wherever a degree of difficulty is made
1588  * dependent on the location in the dungeon (eg. monster creation).
1589  */
1590 xchar
1591 level_difficulty()
1592 {
1593     int res;
1594
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);
1599     } else {
1600         res = depth(&u.uz);
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);
1608             /*
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.
1623              */
1624 #if 0
1625         /*
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.
1629          */
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);
1632             /*
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
1640              * posed by W_tower.
1641              */
1642 #endif /*0*/
1643     }
1644     return (xchar) res;
1645 }
1646
1647 /* Take one word and try to match it to a level.
1648  * Recognized levels are as shown by print_dungeon().
1649  */
1650 schar
1651 lev_by_name(nam)
1652 const char *nam;
1653 {
1654     schar lev = 0;
1655     s_level *slev = (s_level *)0;
1656     d_level dlev;
1657     const char *p;
1658     int idx, idxtoo;
1659     char buf[BUFSZ];
1660     mapseen *mseen;
1661
1662     /* look at the player's custom level annotations first */
1663     if ((mseen = find_mapseen_by_str(nam)) != 0) {
1664         dlev = mseen->lev;
1665     } else {
1666         /* no matching annotation, check whether they used a name we know */
1667
1668         /* allow strings like "the oracle level" to find "oracle" */
1669         if (!strncmpi(nam, "the ", 4))
1670             nam += 4;
1671         if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
1672             nam = strcpy(buf, nam);
1673             *(eos(buf) - 6) = '\0';
1674         }
1675         /* hell is the old name, and wouldn't match; gehennom would match its
1676            branch, yielding the castle level instead of the valley of the dead */
1677         if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
1678             if (In_V_tower(&u.uz))
1679                 nam = " to Vlad's tower"; /* branch to... */
1680             else
1681                 nam = "valley";
1682         }
1683
1684         if ((slev = find_level(nam)) != 0)
1685             dlev = slev->dlevel;
1686     }
1687
1688     if (mseen || slev) {
1689         idx = ledger_no(&dlev);
1690         if ((dlev.dnum == u.uz.dnum
1691              /* within same branch, or else main dungeon <-> gehennom */
1692              || (u.uz.dnum == valley_level.dnum
1693                  && dlev.dnum == medusa_level.dnum)
1694              || (u.uz.dnum == medusa_level.dnum
1695                  && dlev.dnum == valley_level.dnum))
1696             && (/* either wizard mode or else seen and not forgotten */
1697                 wizard
1698                 || (level_info[idx].flags & (FORGOTTEN | VISITED))
1699                        == VISITED)) {
1700             lev = depth(&dlev);
1701         }
1702     } else { /* not a specific level; try branch names */
1703         idx = find_branch(nam, (struct proto_dungeon *) 0);
1704         /* "<branch> to Xyzzy" */
1705         if (idx < 0 && (p = strstri(nam, " to ")) != 0)
1706             idx = find_branch(p + 4, (struct proto_dungeon *) 0);
1707
1708         if (idx >= 0) {
1709             idxtoo = (idx >> 8) & 0x00FF;
1710             idx &= 0x00FF;
1711             if (/* either wizard mode, or else _both_ sides of branch seen */
1712                 wizard
1713                 || ((level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED
1714                     && (level_info[idxtoo].flags & (FORGOTTEN | VISITED))
1715                            == VISITED)) {
1716                 if (ledger_to_dnum(idxtoo) == u.uz.dnum)
1717                     idx = idxtoo;
1718                 dlev.dnum = ledger_to_dnum(idx);
1719                 dlev.dlevel = ledger_to_dlev(idx);
1720                 lev = depth(&dlev);
1721             }
1722         }
1723     }
1724     return lev;
1725 }
1726
1727 STATIC_OVL boolean
1728 unplaced_floater(dptr)
1729 struct dungeon *dptr;
1730 {
1731     branch *br;
1732     int idx = (int) (dptr - dungeons);
1733
1734     /* if other floating branches are added, this will need to change */
1735     if (idx != knox_level.dnum)
1736         return FALSE;
1737     for (br = branches; br; br = br->next)
1738         if (br->end1.dnum == n_dgns && br->end2.dnum == idx)
1739             return TRUE;
1740     return FALSE;
1741 }
1742
1743 STATIC_OVL boolean
1744 unreachable_level(lvl_p, unplaced)
1745 d_level *lvl_p;
1746 boolean unplaced;
1747 {
1748     s_level *dummy;
1749
1750     if (unplaced)
1751         return TRUE;
1752     if (In_endgame(&u.uz) && !In_endgame(lvl_p))
1753         return TRUE;
1754     if ((dummy = find_level("dummy")) != 0 && on_level(lvl_p, &dummy->dlevel))
1755         return TRUE;
1756     return FALSE;
1757 }
1758
1759 static void
1760 tport_menu(win, entry, lchoices, lvl_p, unreachable)
1761 winid win;
1762 char *entry;
1763 struct lchoice *lchoices;
1764 d_level *lvl_p;
1765 boolean unreachable;
1766 {
1767     char tmpbuf[BUFSZ];
1768     anything any;
1769
1770     lchoices->lev[lchoices->idx] = lvl_p->dlevel;
1771     lchoices->dgn[lchoices->idx] = lvl_p->dnum;
1772     lchoices->playerlev[lchoices->idx] = depth(lvl_p);
1773     any = zeroany;
1774     if (unreachable) {
1775         /* not selectable, but still consumes next menuletter;
1776            prepend padding in place of missing menu selector */
1777         Sprintf(tmpbuf, "    %s", entry);
1778         entry = tmpbuf;
1779     } else {
1780         any.a_int = lchoices->idx + 1;
1781     }
1782     add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 0, ATR_NONE, entry,
1783              MENU_UNSELECTED);
1784     /* this assumes there are at most 52 interesting levels */
1785     if (lchoices->menuletter == 'z')
1786         lchoices->menuletter = 'A';
1787     else
1788         lchoices->menuletter++;
1789     lchoices->idx++;
1790     return;
1791 }
1792
1793 /* Convert a branch type to a string usable by print_dungeon(). */
1794 STATIC_OVL const char *
1795 br_string(type)
1796 int type;
1797 {
1798     switch (type) {
1799     case BR_PORTAL:
1800         return "Portal";
1801     case BR_NO_END1:
1802 /*JP
1803         return "Connection";
1804 */
1805         return "\90Ú\91±\95\94";
1806     case BR_NO_END2:
1807         return "One way stair";
1808     case BR_STAIR:
1809         return "Stair";
1810     }
1811     return " (unknown)";
1812 }
1813
1814 STATIC_OVL char
1815 chr_u_on_lvl(dlev)
1816 d_level *dlev;
1817 {
1818     return u.uz.dnum == dlev->dnum && u.uz.dlevel == dlev->dlevel ? '*' : ' ';
1819 }
1820
1821 /* Print all child branches between the lower and upper bounds. */
1822 STATIC_OVL void
1823 print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices_p)
1824 winid win;
1825 int dnum;
1826 int lower_bound;
1827 int upper_bound;
1828 boolean bymenu;
1829 struct lchoice *lchoices_p;
1830 {
1831     branch *br;
1832     char buf[BUFSZ];
1833
1834     /* This assumes that end1 is the "parent". */
1835     for (br = branches; br; br = br->next) {
1836         if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel
1837             && br->end1.dlevel <= upper_bound) {
1838             Sprintf(buf, "%c %s to %s: %d",
1839                     bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1840                     br_string(br->type),
1841                     dungeons[br->end2.dnum].dname, depth(&br->end1));
1842             if (bymenu)
1843                 tport_menu(win, buf, lchoices_p, &br->end1,
1844                            unreachable_level(&br->end1, FALSE));
1845             else
1846                 putstr(win, 0, buf);
1847         }
1848     }
1849 }
1850
1851 /* Print available dungeon information. */
1852 schar
1853 print_dungeon(bymenu, rlev, rdgn)
1854 boolean bymenu;
1855 schar *rlev;
1856 xchar *rdgn;
1857 {
1858     int i, last_level, nlev;
1859     char buf[BUFSZ];
1860     const char *descr;
1861     boolean first, unplaced;
1862     s_level *slev;
1863     dungeon *dptr;
1864     branch *br;
1865     anything any;
1866     struct lchoice lchoices;
1867     winid win = create_nhwindow(NHW_MENU);
1868
1869     if (bymenu) {
1870         start_menu(win);
1871         lchoices.idx = 0;
1872         lchoices.menuletter = 'a';
1873     }
1874
1875     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
1876         if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum)
1877             continue;
1878         unplaced = unplaced_floater(dptr);
1879         descr = unplaced ? "depth" : "level";
1880         nlev = dptr->num_dunlevs;
1881         if (nlev > 1)
1882             Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr),
1883                     dptr->depth_start, dptr->depth_start + nlev - 1);
1884         else
1885             Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start);
1886
1887         /* Most entrances are uninteresting. */
1888         if (dptr->entry_lev != 1) {
1889             if (dptr->entry_lev == nlev)
1890                 Strcat(buf, ", entrance from below");
1891             else
1892                 Sprintf(eos(buf), ", entrance on %d",
1893                         dptr->depth_start + dptr->entry_lev - 1);
1894         }
1895         if (bymenu) {
1896             any = zeroany;
1897             add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1898                      MENU_UNSELECTED);
1899         } else
1900             putstr(win, 0, buf);
1901
1902         /*
1903          * Circle through the special levels to find levels that are in
1904          * this dungeon.
1905          */
1906         for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
1907             if (slev->dlevel.dnum != i)
1908                 continue;
1909
1910             /* print any branches before this level */
1911             print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu,
1912                          &lchoices);
1913
1914             Sprintf(buf, "%c %s: %d",
1915                     chr_u_on_lvl(&slev->dlevel),
1916                     slev->proto, depth(&slev->dlevel));
1917             if (Is_stronghold(&slev->dlevel))
1918                 Sprintf(eos(buf), " (tune %s)", tune);
1919             if (bymenu)
1920                 tport_menu(win, buf, &lchoices, &slev->dlevel,
1921                            unreachable_level(&slev->dlevel, unplaced));
1922             else
1923                 putstr(win, 0, buf);
1924
1925             last_level = slev->dlevel.dlevel;
1926         }
1927         /* print branches after the last special level */
1928         print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices);
1929     }
1930
1931     if (bymenu) {
1932         int n;
1933         menu_item *selected;
1934         int idx;
1935
1936         end_menu(win, "Level teleport to where:");
1937         n = select_menu(win, PICK_ONE, &selected);
1938         destroy_nhwindow(win);
1939         if (n > 0) {
1940             idx = selected[0].item.a_int - 1;
1941             free((genericptr_t) selected);
1942             if (rlev && rdgn) {
1943                 *rlev = lchoices.lev[idx];
1944                 *rdgn = lchoices.dgn[idx];
1945                 return lchoices.playerlev[idx];
1946             }
1947         }
1948         return 0;
1949     }
1950
1951     /* Print out floating branches (if any). */
1952     for (first = TRUE, br = branches; br; br = br->next) {
1953         if (br->end1.dnum == n_dgns) {
1954             if (first) {
1955                 putstr(win, 0, "");
1956                 putstr(win, 0, "Floating branches");
1957                 first = FALSE;
1958             }
1959             Sprintf(buf, "   %s to %s", br_string(br->type),
1960                     dungeons[br->end2.dnum].dname);
1961             putstr(win, 0, buf);
1962         }
1963     }
1964
1965     /* I hate searching for the invocation pos while debugging. -dean */
1966     if (Invocation_lev(&u.uz)) {
1967         putstr(win, 0, "");
1968         Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
1969                 inv_pos.x, inv_pos.y, u.ux, u.uy);
1970         putstr(win, 0, buf);
1971     } else {
1972         struct trap *trap;
1973
1974         /* if current level has a magic portal, report its location;
1975            this assumes that there is at most one magic portal on any
1976            given level; quest and ft.ludios have pairs (one in main
1977            dungeon matched with one in the corresponding branch), the
1978            elemental planes have singletons (connection to next plane) */
1979         *buf = '\0';
1980         for (trap = ftrap; trap; trap = trap->ntrap)
1981             if (trap->ttyp == MAGIC_PORTAL)
1982                 break;
1983
1984         if (trap)
1985             Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
1986                     trap->tx, trap->ty, u.ux, u.uy);
1987
1988         /* only report "no portal found" when actually expecting a portal */
1989         else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
1990                  || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
1991                  || Is_qstart(&u.uz) || at_dgn_entrance("The Quest")
1992                  || Is_knox(&u.uz))
1993             Strcpy(buf, "No portal found.");
1994
1995         /* only give output if we found a portal or expected one and didn't */
1996         if (*buf) {
1997             putstr(win, 0, "");
1998             putstr(win, 0, buf);
1999         }
2000     }
2001
2002     display_nhwindow(win, TRUE);
2003     destroy_nhwindow(win);
2004     return 0;
2005 }
2006
2007 /* Record that the player knows about a branch from a level. This function
2008  * will determine whether or not it was a "real" branch that was taken.
2009  * This function should not be called for a transition done via level
2010  * teleport or via the Eye.
2011  */
2012 void
2013 recbranch_mapseen(source, dest)
2014 d_level *source;
2015 d_level *dest;
2016 {
2017     mapseen *mptr;
2018     branch *br;
2019
2020     /* not a branch */
2021     if (source->dnum == dest->dnum)
2022         return;
2023
2024     /* we only care about forward branches */
2025     for (br = branches; br; br = br->next) {
2026         if (on_level(source, &br->end1) && on_level(dest, &br->end2))
2027             break;
2028         if (on_level(source, &br->end2) && on_level(dest, &br->end1))
2029             return;
2030     }
2031
2032     /* branch not found, so not a real branch. */
2033     if (!br)
2034         return;
2035
2036     if ((mptr = find_mapseen(source)) != 0) {
2037         if (mptr->br && br != mptr->br)
2038             impossible("Two branches on the same level?");
2039         mptr->br = br;
2040     } else {
2041         impossible("Can't note branch for unseen level (%d, %d)",
2042                    source->dnum, source->dlevel);
2043     }
2044 }
2045
2046 char *
2047 get_annotation(lev)
2048 d_level *lev;
2049 {
2050     mapseen *mptr;
2051
2052     if ((mptr = find_mapseen(lev)))
2053         return mptr->custom;
2054     return NULL;
2055 }
2056
2057 /* #annotate command - add a custom name to the current level */
2058 int
2059 donamelevel()
2060 {
2061     mapseen *mptr;
2062     char nbuf[BUFSZ]; /* Buffer for response */
2063
2064     if (!(mptr = find_mapseen(&u.uz)))
2065         return 0;
2066
2067     nbuf[0] = '\0';
2068 #ifdef EDIT_GETLIN
2069     if (mptr->custom) {
2070         (void) strncpy(nbuf, mptr->custom, BUFSZ);
2071         nbuf[BUFSZ - 1] = '\0';
2072     }
2073 #else
2074     if (mptr->custom) {
2075         char tmpbuf[BUFSZ];
2076
2077 #if 0 /*JP*/
2078         Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?", mptr->custom,
2079                 (strlen(mptr->custom) > 30) ? "..." : "");
2080 #else
2081         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,
2082                 strlen(mptr->custom) > 30 ? "..." : "");
2083 #endif
2084         getlin(tmpbuf, nbuf);
2085     } else
2086 #endif
2087 /*JP
2088         getlin("What do you want to call this dungeon level?", nbuf);
2089 */
2090         getlin("\82±\82Ì\8aK\82ð\89½\82Æ\8cÄ\82Ô\81H", nbuf);
2091
2092     /* empty input or ESC means don't add or change annotation;
2093        space-only means discard current annotation without adding new one */
2094     if (!*nbuf || *nbuf == '\033')
2095         return 0;
2096     /* strip leading and trailing spaces, compress out consecutive spaces */
2097     (void) mungspaces(nbuf);
2098
2099     /* discard old annotation, if any */
2100     if (mptr->custom) {
2101         free((genericptr_t) mptr->custom);
2102         mptr->custom = (char *) 0;
2103         mptr->custom_lth = 0;
2104     }
2105     /* add new annotation, unless it's all spaces (which will be an
2106        empty string after mungspaces() above) */
2107     if (*nbuf && strcmp(nbuf, " ")) {
2108         mptr->custom = dupstr(nbuf);
2109         mptr->custom_lth = strlen(mptr->custom);
2110     }
2111     return 0;
2112 }
2113
2114 /* find the particular mapseen object in the chain; may return null */
2115 STATIC_OVL mapseen *
2116 find_mapseen(lev)
2117 d_level *lev;
2118 {
2119     mapseen *mptr;
2120
2121     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2122         if (on_level(&(mptr->lev), lev))
2123             break;
2124
2125     return mptr;
2126 }
2127
2128 STATIC_OVL mapseen *
2129 find_mapseen_by_str(s)
2130 const char *s;
2131 {
2132     mapseen *mptr;
2133
2134     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2135         if (mptr->custom && !strcmpi(s, mptr->custom))
2136             break;
2137
2138     return mptr;
2139 }
2140
2141
2142 void
2143 forget_mapseen(ledger_num)
2144 int ledger_num;
2145 {
2146     mapseen *mptr;
2147     struct cemetery *bp;
2148
2149     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2150         if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel
2151             == ledger_num)
2152             break;
2153
2154     /* if not found, then nothing to forget */
2155     if (mptr) {
2156         mptr->flags.forgot = 1;
2157         mptr->br = (branch *) 0;
2158
2159         /* custom names are erased, not just forgotten until revisited */
2160         if (mptr->custom) {
2161             mptr->custom_lth = 0;
2162             free((genericptr_t) mptr->custom);
2163             mptr->custom = (char *) 0;
2164         }
2165         (void) memset((genericptr_t) mptr->msrooms, 0, sizeof mptr->msrooms);
2166         for (bp = mptr->final_resting_place; bp; bp = bp->next)
2167             bp->bonesknown = FALSE;
2168     }
2169 }
2170
2171 void
2172 rm_mapseen(ledger_num)
2173 int ledger_num;
2174 {
2175     mapseen *mptr, *mprev = (mapseen *)0;
2176     struct cemetery *bp, *bpnext;
2177
2178     for (mptr = mapseenchn; mptr; mprev = mptr, mptr = mptr->next)
2179         if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num)
2180             break;
2181
2182     if (!mptr)
2183         return;
2184
2185     if (mptr->custom)
2186         free((genericptr_t) mptr->custom);
2187
2188     bp = mptr->final_resting_place;
2189     while (bp) {
2190         bpnext = bp->next;
2191         free(bp);
2192         bp = bpnext;
2193     }
2194
2195     if (mprev) {
2196         mprev->next = mptr->next;
2197         free(mptr);
2198     } else {
2199         mapseenchn = mptr->next;
2200         free(mptr);
2201     }
2202 }
2203
2204 STATIC_OVL void
2205 save_mapseen(fd, mptr)
2206 int fd;
2207 mapseen *mptr;
2208 {
2209     branch *curr;
2210     int brindx;
2211
2212     for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2213         if (curr == mptr->br)
2214             break;
2215     bwrite(fd, (genericptr_t) &brindx, sizeof brindx);
2216
2217     bwrite(fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
2218     bwrite(fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
2219     bwrite(fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
2220     bwrite(fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
2221     if (mptr->custom_lth)
2222         bwrite(fd, (genericptr_t) mptr->custom, mptr->custom_lth);
2223     bwrite(fd, (genericptr_t) &mptr->msrooms, sizeof mptr->msrooms);
2224     savecemetery(fd, WRITE_SAVE, &mptr->final_resting_place);
2225 }
2226
2227 STATIC_OVL mapseen *
2228 load_mapseen(fd)
2229 int fd;
2230 {
2231     int branchnum, brindx;
2232     mapseen *load;
2233     branch *curr;
2234
2235     load = (mapseen *) alloc(sizeof *load);
2236
2237     mread(fd, (genericptr_t) &branchnum, sizeof branchnum);
2238     for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2239         if (brindx == branchnum)
2240             break;
2241     load->br = curr;
2242
2243     mread(fd, (genericptr_t) &load->lev, sizeof load->lev);
2244     mread(fd, (genericptr_t) &load->feat, sizeof load->feat);
2245     mread(fd, (genericptr_t) &load->flags, sizeof load->flags);
2246     mread(fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
2247     if (load->custom_lth) {
2248         /* length doesn't include terminator (which isn't saved & restored) */
2249         load->custom = (char *) alloc(load->custom_lth + 1);
2250         mread(fd, (genericptr_t) load->custom, load->custom_lth);
2251         load->custom[load->custom_lth] = '\0';
2252     } else
2253         load->custom = 0;
2254     mread(fd, (genericptr_t) &load->msrooms, sizeof load->msrooms);
2255     restcemetery(fd, &load->final_resting_place);
2256
2257     return load;
2258 }
2259
2260 /* to support '#stats' wizard-mode command */
2261 void
2262 overview_stats(win, statsfmt, total_count, total_size)
2263 winid win;
2264 const char *statsfmt;
2265 long *total_count, *total_size;
2266 {
2267     char buf[BUFSZ], hdrbuf[QBUFSZ];
2268     long ocount, osize, bcount, bsize, acount, asize;
2269     struct cemetery *ce;
2270     mapseen *mptr = find_mapseen(&u.uz);
2271
2272     ocount = bcount = acount = osize = bsize = asize = 0L;
2273     for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2274         ++ocount;
2275         osize += (long) sizeof *mptr;
2276         for (ce = mptr->final_resting_place; ce; ce = ce->next) {
2277             ++bcount;
2278             bsize += (long) sizeof *ce;
2279         }
2280         if (mptr->custom_lth) {
2281             ++acount;
2282             asize += (long) (mptr->custom_lth + 1);
2283         }
2284     }
2285
2286     Sprintf(hdrbuf, "general, size %ld", (long) sizeof (mapseen));
2287     Sprintf(buf, statsfmt, hdrbuf, ocount, osize);
2288     putstr(win, 0, buf);
2289     if (bcount) {
2290         Sprintf(hdrbuf, "cemetery, size %ld",
2291                 (long) sizeof (struct cemetery));
2292         Sprintf(buf, statsfmt, hdrbuf, bcount, bsize);
2293         putstr(win, 0, buf);
2294     }
2295     if (acount) {
2296         Sprintf(hdrbuf, "annotations, text");
2297         Sprintf(buf, statsfmt, hdrbuf, acount, asize);
2298         putstr(win, 0, buf);
2299     }
2300     *total_count += ocount + bcount + acount;
2301     *total_size += osize + bsize + asize;
2302 }
2303
2304 /* Remove all mapseen objects for a particular dnum.
2305  * Useful during quest expulsion to remove quest levels.
2306  * [No longer deleted, just marked as unreachable.  #overview will
2307  * ignore such levels, end of game disclosure will include them.]
2308  */
2309 void
2310 remdun_mapseen(dnum)
2311 int dnum;
2312 {
2313     mapseen *mptr, **mptraddr;
2314
2315     mptraddr = &mapseenchn;
2316     while ((mptr = *mptraddr) != 0) {
2317         if (mptr->lev.dnum == dnum) {
2318 #if 1 /* use this... */
2319             mptr->flags.unreachable = 1;
2320         }
2321 #else /* old deletion code */
2322             *mptraddr = mptr->next;
2323             if (mptr->custom)
2324                 free((genericptr_t) mptr->custom);
2325             if (mptr->final_resting_place)
2326                 savecemetery(-1, FREE_SAVE, &mptr->final_resting_place);
2327             free((genericptr_t) mptr);
2328         } else
2329 #endif
2330         mptraddr = &mptr->next;
2331     }
2332 }
2333
2334 void
2335 init_mapseen(lev)
2336 d_level *lev;
2337 {
2338     /* Create a level and insert in "sorted" order.  This is an insertion
2339      * sort first by dungeon (in order of discovery) and then by level number.
2340      */
2341     mapseen *mptr, *init, *prev;
2342
2343     init = (mapseen *) alloc(sizeof *init);
2344     (void) memset((genericptr_t) init, 0, sizeof *init);
2345     /* memset is fine for feature bits, flags, and rooms array;
2346        explicitly initialize pointers to null */
2347     init->next = 0, init->br = 0, init->custom = 0;
2348     init->final_resting_place = 0;
2349     /* lastseentyp[][] is reused for each level, so get rid of
2350        previous level's data */
2351     (void) memset((genericptr_t) lastseentyp, 0, sizeof lastseentyp);
2352
2353     init->lev.dnum = lev->dnum;
2354     init->lev.dlevel = lev->dlevel;
2355
2356     /* walk until we get to the place where we should insert init */
2357     for (mptr = mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next)
2358         if (mptr->lev.dnum > init->lev.dnum
2359             || (mptr->lev.dnum == init->lev.dnum
2360                 && mptr->lev.dlevel > init->lev.dlevel))
2361             break;
2362     if (!prev) {
2363         init->next = mapseenchn;
2364         mapseenchn = init;
2365     } else {
2366         mptr = prev->next;
2367         prev->next = init;
2368         init->next = mptr;
2369     }
2370 }
2371
2372 #define INTEREST(feat)                                                \
2373     ((feat).nfount || (feat).nsink || (feat).nthrone || (feat).naltar \
2374      || (feat).ngrave || (feat).ntree || (feat).nshop || (feat).ntemple)
2375   /* || (feat).water || (feat).ice || (feat).lava */
2376
2377 /* returns true if this level has something interesting to print out */
2378 STATIC_OVL boolean
2379 interest_mapseen(mptr)
2380 mapseen *mptr;
2381 {
2382     if (on_level(&u.uz, &mptr->lev))
2383         return TRUE;
2384     if (mptr->flags.unreachable || mptr->flags.forgot)
2385         return FALSE;
2386     /* level is of interest if it has an auto-generated annotation */
2387     if (mptr->flags.oracle || mptr->flags.bigroom || mptr->flags.roguelevel
2388         || mptr->flags.castle || mptr->flags.valley || mptr->flags.msanctum
2389         || mptr->flags.quest_summons || mptr->flags.questing)
2390         return TRUE;
2391     /* when in Sokoban, list all sokoban levels visited; when not in it,
2392        list any visited Sokoban level which remains unsolved (will usually
2393        only be furthest one reached, but it's possible to enter pits and
2394        climb out on the far side on the first Sokoban level; also, wizard
2395        mode overrides teleport restrictions) */
2396     if (In_sokoban(&mptr->lev)
2397         && (In_sokoban(&u.uz) || !mptr->flags.sokosolved))
2398         return TRUE;
2399     /* when in the endgame, list all endgame levels visited, whether they
2400        have annotations or not, so that #overview doesn't become extremely
2401        sparse once the rest of the dungeon has been flagged as unreachable */
2402     if (In_endgame(&u.uz))
2403         return (boolean) In_endgame(&mptr->lev);
2404     /* level is of interest if it has non-zero feature count or known bones
2405        or user annotation or known connection to another dungeon branch
2406        or is the furthest level reached in its branch */
2407     return (boolean) (INTEREST(mptr->feat)
2408                       || (mptr->final_resting_place
2409                           && (mptr->flags.knownbones || wizard))
2410                       || mptr->custom || mptr->br
2411                       || (mptr->lev.dlevel
2412                           == dungeons[mptr->lev.dnum].dunlev_ureached));
2413 }
2414
2415 /* recalculate mapseen for the current level */
2416 void
2417 recalc_mapseen()
2418 {
2419     mapseen *mptr;
2420     struct monst *mtmp;
2421     struct cemetery *bp, **bonesaddr;
2422     unsigned i, ridx;
2423     int x, y, ltyp, count, atmp;
2424
2425     /* Should not happen in general, but possible if in the process
2426      * of being booted from the quest.  The mapseen object gets
2427      * removed during the expulsion but prior to leaving the level
2428      * [Since quest expulsion no longer deletes quest mapseen data,
2429      * null return from find_mapseen() should now be impossible.]
2430      */
2431     if (!(mptr = find_mapseen(&u.uz)))
2432         return;
2433
2434     /* reset all features; mptr->feat.* = 0; */
2435     (void) memset((genericptr_t) &mptr->feat, 0, sizeof mptr->feat);
2436     /* reset most flags; some level-specific ones are left as-is */
2437     if (mptr->flags.unreachable) {
2438         mptr->flags.unreachable = 0; /* reached it; Eye of the Aethiopica? */
2439         if (In_quest(&u.uz)) {
2440             mapseen *mptrtmp = mapseenchn;
2441
2442             /* when quest was unreachable due to ejection and portal removal,
2443                getting back to it via arti-invoke should revive annotation
2444                data for all quest levels, not just the one we're on now */
2445             do {
2446                 if (mptrtmp->lev.dnum == mptr->lev.dnum)
2447                     mptrtmp->flags.unreachable = 0;
2448                 mptrtmp = mptrtmp->next;
2449             } while (mptrtmp);
2450         }
2451     }
2452     mptr->flags.knownbones = 0;
2453     mptr->flags.sokosolved = In_sokoban(&u.uz) && !Sokoban;
2454     /* mptr->flags.bigroom retains previous value when hero can't see */
2455     if (!Blind)
2456         mptr->flags.bigroom = Is_bigroom(&u.uz);
2457     else if (mptr->flags.forgot)
2458         mptr->flags.bigroom = 0;
2459     mptr->flags.roguelevel = Is_rogue_level(&u.uz);
2460     mptr->flags.oracle = 0; /* recalculated during room traversal below */
2461     mptr->flags.castletune = 0;
2462     /* flags.castle, flags.valley, flags.msanctum retain previous value */
2463     mptr->flags.forgot = 0;
2464     /* flags.quest_summons disabled once quest finished */
2465 /*JP
2466     mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
2467 */
2468     mptr->flags.quest_summons = (at_dgn_entrance("\83N\83G\83X\83g")
2469                                  && u.uevent.qcalled
2470                                  && !(u.uevent.qcompleted
2471                                       || u.uevent.qexpelled
2472                                       || quest_status.leader_is_dead));
2473     mptr->flags.questing = (on_level(&u.uz, &qstart_level)
2474                             && quest_status.got_quest);
2475
2476     /* track rooms the hero is in */
2477     for (i = 0; i < SIZE(u.urooms); ++i) {
2478         if (!u.urooms[i])
2479             continue;
2480
2481         ridx = u.urooms[i] - ROOMOFFSET;
2482         mptr->msrooms[ridx].seen = 1;
2483         mptr->msrooms[ridx].untended =
2484             (rooms[ridx].rtype >= SHOPBASE)
2485                 ? (!(mtmp = shop_keeper(u.urooms[i])) || !inhishop(mtmp))
2486                 : (rooms[ridx].rtype == TEMPLE)
2487                       ? (!(mtmp = findpriest(u.urooms[i]))
2488                          || !inhistemple(mtmp))
2489                       : 0;
2490     }
2491
2492     /* recalculate room knowledge: for now, just shops and temples
2493      * this could be extended to an array of 0..SHOPBASE
2494      */
2495     for (i = 0; i < SIZE(mptr->msrooms); ++i) {
2496         if (mptr->msrooms[i].seen) {
2497             if (rooms[i].rtype >= SHOPBASE) {
2498                 if (mptr->msrooms[i].untended)
2499                     mptr->feat.shoptype = SHOPBASE - 1;
2500                 else if (!mptr->feat.nshop)
2501                     mptr->feat.shoptype = rooms[i].rtype;
2502                 else if (mptr->feat.shoptype != (unsigned) rooms[i].rtype)
2503                     mptr->feat.shoptype = 0;
2504                 count = mptr->feat.nshop + 1;
2505                 if (count <= 3)
2506                     mptr->feat.nshop = count;
2507             } else if (rooms[i].rtype == TEMPLE) {
2508                 /* altar and temple alignment handled below */
2509                 count = mptr->feat.ntemple + 1;
2510                 if (count <= 3)
2511                     mptr->feat.ntemple = count;
2512             } else if (rooms[i].orig_rtype == DELPHI) {
2513                 mptr->flags.oracle = 1;
2514             }
2515         }
2516     }
2517
2518     /* Update lastseentyp with typ if and only if it is in sight or the
2519      * hero can feel it on their current location (i.e. not levitating).
2520      * This *should* give the "last known typ" for each dungeon location.
2521      * (At the very least, it's a better assumption than determining what
2522      * the player knows from the glyph and the typ (which is isn't quite
2523      * enough information in some cases)).
2524      *
2525      * It was reluctantly added to struct rm to track.  Alternatively
2526      * we could track "features" and then update them all here, and keep
2527      * track of when new features are created or destroyed, but this
2528      * seemed the most elegant, despite adding more data to struct rm.
2529      * [3.6.0: we're using lastseentyp[][] rather than level.locations
2530      * to track the features seen.]
2531      *
2532      * Although no current windowing systems (can) do this, this would add
2533      * the ability to have non-dungeon glyphs float above the last known
2534      * dungeon glyph (i.e. items on fountains).
2535      */
2536     for (x = 1; x < COLNO; x++) {
2537         for (y = 0; y < ROWNO; y++) {
2538             if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
2539                 ltyp = levl[x][y].typ;
2540                 if (ltyp == DRAWBRIDGE_UP)
2541                     ltyp = db_under_typ(levl[x][y].drawbridgemask);
2542                 if ((mtmp = m_at(x, y)) != 0
2543                     && mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp))
2544                     ltyp = cmap_to_type(mtmp->mappearance);
2545                 lastseentyp[x][y] = ltyp;
2546             }
2547
2548             switch (lastseentyp[x][y]) {
2549 #if 0
2550             case ICE:
2551                 count = mptr->feat.ice + 1;
2552                 if (count <= 3)
2553                     mptr->feat.ice = count;
2554                 break;
2555             case POOL:
2556             case MOAT:
2557             case WATER:
2558                 count = mptr->feat.water + 1;
2559                 if (count <= 3)
2560                     mptr->feat.water = count;
2561                 break;
2562             case LAVAPOOL:
2563                 count = mptr->feat.lava + 1;
2564                 if (count <= 3)
2565                     mptr->feat.lava = count;
2566                 break;
2567 #endif
2568             case TREE:
2569                 count = mptr->feat.ntree + 1;
2570                 if (count <= 3)
2571                     mptr->feat.ntree = count;
2572                 break;
2573             case FOUNTAIN:
2574                 count = mptr->feat.nfount + 1;
2575                 if (count <= 3)
2576                     mptr->feat.nfount = count;
2577                 break;
2578             case THRONE:
2579                 count = mptr->feat.nthrone + 1;
2580                 if (count <= 3)
2581                     mptr->feat.nthrone = count;
2582                 break;
2583             case SINK:
2584                 count = mptr->feat.nsink + 1;
2585                 if (count <= 3)
2586                     mptr->feat.nsink = count;
2587                 break;
2588             case GRAVE:
2589                 count = mptr->feat.ngrave + 1;
2590                 if (count <= 3)
2591                     mptr->feat.ngrave = count;
2592                 break;
2593             case ALTAR:
2594                 atmp = (Is_astralevel(&u.uz)
2595                         && (levl[x][y].seenv & SVALL) != SVALL)
2596                          ? MSA_NONE
2597                          : Amask2msa(levl[x][y].altarmask);
2598                 if (!mptr->feat.naltar)
2599                     mptr->feat.msalign = atmp;
2600                 else if (mptr->feat.msalign != atmp)
2601                     mptr->feat.msalign = MSA_NONE;
2602                 count = mptr->feat.naltar + 1;
2603                 if (count <= 3)
2604                     mptr->feat.naltar = count;
2605                 break;
2606             /*  An automatic annotation is added to the Castle and
2607              *  to Fort Ludios once their structure's main entrance
2608              *  has been seen (in person or via magic mapping).
2609              *  For the Fort, that entrance is just a secret door
2610              *  which will be converted into a regular one when
2611              *  located (or destroyed).
2612              * DOOR: possibly a lowered drawbridge's open portcullis;
2613              * DBWALL: a raised drawbridge's "closed door";
2614              * DRAWBRIDGE_DOWN: the span provided by lowered bridge,
2615              *  with moat or other terrain hidden underneath;
2616              * DRAWBRIDGE_UP: moat in front of a raised drawbridge,
2617              *  not recognizable as a bridge location unless/until
2618              *  the adjacent DBWALL has been seen.
2619              */
2620             case DOOR:
2621                 if (Is_knox(&u.uz)) {
2622                     int ty, tx = x - 4;
2623
2624                     /* Throne is four columns left, either directly in
2625                      * line or one row higher or lower, and doesn't have
2626                      * to have been seen yet.
2627                      *   ......|}}}.
2628                      *   ..\...S}...
2629                      *   ..\...S}...
2630                      *   ......|}}}.
2631                      * For 3.6.0 and earlier, it was always in direct line:
2632                      * both throne and door on the lower of the two rows.
2633                      */
2634                     for (ty = y - 1; ty <= y + 1; ++ty)
2635                         if (isok(tx, ty) && IS_THRONE(levl[tx][ty].typ)) {
2636                             mptr->flags.ludios = 1;
2637                             break;
2638                         }
2639                     break;
2640                 }
2641                 if (is_drawbridge_wall(x, y) < 0)
2642                     break;
2643                 /*FALLTHRU*/
2644             case DBWALL:
2645             case DRAWBRIDGE_DOWN:
2646                 if (Is_stronghold(&u.uz))
2647                     mptr->flags.castle = 1, mptr->flags.castletune = 1;
2648                 break;
2649             default:
2650                 break;
2651             }
2652         }
2653     }
2654
2655     if (level.bonesinfo && !mptr->final_resting_place) {
2656         /* clone the bonesinfo so we aren't dependent upon this
2657            level being in memory */
2658         bonesaddr = &mptr->final_resting_place;
2659         bp = level.bonesinfo;
2660         do {
2661             *bonesaddr = (struct cemetery *) alloc(sizeof **bonesaddr);
2662             **bonesaddr = *bp;
2663             bp = bp->next;
2664             bonesaddr = &(*bonesaddr)->next;
2665         } while (bp);
2666         *bonesaddr = 0;
2667     }
2668     /* decide which past hero deaths have become known; there's no
2669        guarantee of either a grave or a ghost, so we go by whether the
2670        current hero has seen the map location where each old one died */
2671     for (bp = mptr->final_resting_place; bp; bp = bp->next)
2672         if (lastseentyp[bp->frpx][bp->frpy]) {
2673             bp->bonesknown = TRUE;
2674             mptr->flags.knownbones = 1;
2675         }
2676 }
2677
2678 /*ARGUSED*/
2679 /* valley and sanctum levels get automatic annotation once temple is entered
2680  */
2681 void
2682 mapseen_temple(priest)
2683 struct monst *priest UNUSED; /* currently unused; might be useful someday */
2684 {
2685     mapseen *mptr = find_mapseen(&u.uz);
2686
2687     if (Is_valley(&u.uz))
2688         mptr->flags.valley = 1;
2689     else if (Is_sanctum(&u.uz))
2690         mptr->flags.msanctum = 1;
2691 }
2692
2693 /* room entry message has just been delivered so learn room even if blind */
2694 void
2695 room_discovered(roomno)
2696 int roomno;
2697 {
2698     mapseen *mptr = find_mapseen(&u.uz);
2699
2700     mptr->msrooms[roomno].seen = 1;
2701 }
2702
2703 /* #overview command */
2704 int
2705 dooverview()
2706 {
2707     show_overview(0, 0);
2708     return 0;
2709 }
2710
2711 /* called for #overview or for end of game disclosure */
2712 void
2713 show_overview(why, reason)
2714 int why;    /* 0 => #overview command,
2715                1 or 2 => final disclosure (1: hero lived, 2: hero died) */
2716 int reason; /* how hero died; used when disclosing end-of-game level */
2717 {
2718     winid win;
2719     int lastdun = -1;
2720
2721     /* lazy initialization */
2722     (void) recalc_mapseen();
2723
2724     win = create_nhwindow(NHW_MENU);
2725     /* show the endgame levels before the rest of the dungeon,
2726        so that the Planes (dnum 5-ish) come out above main dungeon (dnum 0) */
2727     if (In_endgame(&u.uz))
2728         traverse_mapseenchn(TRUE, win, why, reason, &lastdun);
2729     /* if game is over or we're not in the endgame yet, show the dungeon */
2730     if (why > 0 || !In_endgame(&u.uz))
2731         traverse_mapseenchn(FALSE, win, why, reason, &lastdun);
2732     display_nhwindow(win, TRUE);
2733     destroy_nhwindow(win);
2734 }
2735
2736 /* display endgame levels or non-endgame levels, not both */
2737 STATIC_OVL void
2738 traverse_mapseenchn(viewendgame, win, why, reason, lastdun_p)
2739 boolean viewendgame;
2740 winid win;
2741 int why, reason, *lastdun_p;
2742 {
2743     mapseen *mptr;
2744     boolean showheader;
2745
2746     for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2747         if (viewendgame ^ In_endgame(&mptr->lev))
2748             continue;
2749
2750         /* only print out info for a level or a dungeon if interest */
2751         if (why > 0 || interest_mapseen(mptr)) {
2752             showheader = (boolean) (mptr->lev.dnum != *lastdun_p);
2753             print_mapseen(win, mptr, why, reason, showheader);
2754             *lastdun_p = mptr->lev.dnum;
2755         }
2756     }
2757 }
2758
2759 STATIC_OVL const char *
2760 seen_string(x, obj)
2761 xchar x;
2762 const char *obj;
2763 {
2764     /* players are computer scientists: 0, 1, 2, n */
2765     switch (x) {
2766     case 0:
2767 /*JP:\82±\82±\82É\82Í\97\88\82È\82¢\82Í\82¸*/
2768         return "no";
2769     /* an() returns too much.  index is ok in this case */
2770     case 1:
2771 /*JP
2772         return index(vowels, *obj) ? "an" : "a";
2773 */
2774         return "";
2775     case 2:
2776 /*JP
2777         return "some";
2778 */
2779         return "\93ñ\82Â\82Ì";
2780     case 3:
2781 /*JP
2782         return "many";
2783 */
2784         return "\91½\82­\82Ì";
2785     }
2786
2787     return "(unknown)";
2788 }
2789
2790 /* better br_string */
2791 STATIC_OVL const char *
2792 br_string2(br)
2793 branch *br;
2794 {
2795     /* Special case: quest portal says closed if kicked from quest */
2796     boolean closed_portal = (br->end2.dnum == quest_dnum
2797                              && u.uevent.qexpelled);
2798
2799     switch (br->type) {
2800     case BR_PORTAL:
2801 /*JP
2802         return closed_portal ? "Sealed portal" : "Portal";
2803 */
2804         return closed_portal ? "\95\95\88ó\82³\82ê\82½\96\82\96@\82Ì\93ü\8cû" : "\96\82\96@\82Ì\93ü\8cû";
2805     case BR_NO_END1:
2806         return "Connection";
2807     case BR_NO_END2:
2808 /*JP
2809         return br->end1_up ? "One way stairs up" : "One way stairs down";
2810 */
2811         return br->end1_up ? "\8fã\82è\95Ð\93¹\8aK\92i" : "\89º\82è\95Ð\93¹\8aK\92i";
2812     case BR_STAIR:
2813 /*JP
2814         return br->end1_up ? "Stairs up" : "Stairs down";
2815 */
2816         return br->end1_up ? "\8fã\82è\8aK\92i" : "\89º\82è\8aK\92i";
2817     }
2818
2819     return "(unknown)";
2820 }
2821
2822 /* get the name of an endgame level; topten.c does something similar */
2823 STATIC_OVL const char *
2824 endgamelevelname(outbuf, indx)
2825 char *outbuf;
2826 int indx;
2827 {
2828     const char *planename = 0;
2829
2830     *outbuf = '\0';
2831     switch (indx) {
2832     case -5:
2833 /*JP
2834         Strcpy(outbuf, "Astral Plane");
2835 */
2836         Strcpy(outbuf, "\93V\8fã\8aE");
2837         break;
2838     case -4:
2839 /*JP
2840         planename = "Water";
2841 */
2842         planename = "\90\85";
2843         break;
2844     case -3:
2845 /*JP
2846         planename = "Fire";
2847 */
2848         planename = "\89Î";
2849         break;
2850     case -2:
2851 /*JP
2852         planename = "Air";
2853 */
2854         planename = "\95\97";
2855         break;
2856     case -1:
2857 /*JP
2858         planename = "Earth";
2859 */
2860         planename = "\93y";
2861         break;
2862     }
2863     if (planename)
2864 /*JP
2865         Sprintf(outbuf, "Plane of %s", planename);
2866 */
2867         Sprintf(outbuf, "%s\82Ì\90¸\97ì\8aE", planename);
2868     else if (!*outbuf)
2869         Sprintf(outbuf, "unknown plane #%d", indx);
2870     return outbuf;
2871 }
2872
2873 STATIC_OVL const char *
2874 shop_string(rtype)
2875 int rtype;
2876 {
2877 #if 0 /*JP*/
2878     const char *str = "shop"; /* catchall */
2879 #else
2880     const char *str = "\93X"; /* catchall */
2881 #endif
2882
2883     /* Yuck, redundancy...but shclass.name doesn't cut it as a noun */
2884     switch (rtype) {
2885     case SHOPBASE - 1:
2886 /*JP
2887         str = "untended shop";
2888 */
2889         str = "\95ú\8aü\82³\82ê\82½\93X";
2890         break; /* see recalc_mapseen */
2891     case SHOPBASE:
2892 /*JP
2893         str = "general store";
2894 */
2895         str = "\8eG\89Ý\93X";
2896         break;
2897     case ARMORSHOP:
2898 /*JP
2899         str = "armor shop";
2900 */
2901         str = "\96h\8bï\93X";
2902         break;
2903     case SCROLLSHOP:
2904 /*JP
2905         str = "scroll shop";
2906 */
2907         str = "\8aª\95¨\93X";
2908         break;
2909     case POTIONSHOP:
2910 /*JP
2911         str = "potion shop";
2912 */
2913         str = "\96ò\93X";
2914         break;
2915     case WEAPONSHOP:
2916 /*JP
2917         str = "weapon shop";
2918 */
2919         str = "\95\90\8aí\93X";
2920         break;
2921     case FOODSHOP:
2922 /*JP
2923         str = "delicatessen";
2924 */
2925         str = "\90H\97¿\95i\93X";
2926         break;
2927     case RINGSHOP:
2928 /*JP
2929         str = "jewelers";
2930 */
2931         str = "\95ó\90Î\93X";
2932         break;
2933     case WANDSHOP:
2934 /*JP
2935         str = "wand shop";
2936 */
2937         str = "\8fñ\93X";
2938         break;
2939     case BOOKSHOP:
2940 /*JP
2941         str = "bookstore";
2942 */
2943         str = "\8f\91\93X";
2944         break;
2945     case FODDERSHOP:
2946 /*JP
2947         str = "health food store";
2948 */
2949         str = "\8c\92\8dN\90H\95i\93X";
2950         break;
2951     case CANDLESHOP:
2952 /*JP
2953         str = "lighting shop";
2954 */
2955         str = "\8fÆ\96¾\93X";
2956         break;
2957     default:
2958         break;
2959     }
2960     return str;
2961 }
2962
2963 /* if player knows about the mastermind tune, append it to Castle annotation;
2964    if drawbridge has been destroyed, flags.castletune will be zero */
2965 STATIC_OVL char *
2966 tunesuffix(mptr, outbuf)
2967 mapseen *mptr;
2968 char *outbuf;
2969 {
2970     *outbuf = '\0';
2971     if (mptr->flags.castletune && u.uevent.uheard_tune) {
2972         char tmp[BUFSZ];
2973
2974         if (u.uevent.uheard_tune == 2)
2975             Sprintf(tmp, "notes \"%s\"", tune);
2976         else
2977             Strcpy(tmp, "5-note tune");
2978         Sprintf(outbuf, " (play %s to open or close drawbridge)", tmp);
2979     }
2980     return outbuf;
2981 }
2982
2983 /* some utility macros for print_mapseen */
2984 #define TAB "   " /* three spaces */
2985 #if 0
2986 #define BULLET "" /* empty; otherwise output becomes cluttered */
2987 #define PREFIX TAB TAB BULLET
2988 #else                   /*!0*/
2989 /* K&R: don't require support for concatenation of adjacent string literals */
2990 #define PREFIX "      " /* two TABs + empty BULLET: six spaces */
2991 #endif
2992 #define COMMA (i++ > 0 ? ", " : PREFIX)
2993 /* "iterate" once; safe to use as ``if (cond) ADDTOBUF(); else whatever;'' */
2994 #if 0 /*JP*/
2995 #define ADDNTOBUF(nam, var)                                                  \
2996     do {                                                                     \
2997         if (var)                                                             \
2998             Sprintf(eos(buf), "%s%s %s%s", COMMA, seen_string((var), (nam)), \
2999                     (nam), plur(var));                                       \
3000     } while (0)
3001 #else
3002 #define ADDNTOBUF(nam, var)                                                  \
3003     do {                                                                     \
3004         if (var)                                                             \
3005             Sprintf(eos(buf), "%s%s%s", COMMA, seen_string((var), (nam)),    \
3006                     (nam));                                                  \
3007     } while (0)
3008 #endif
3009 #define ADDTOBUF(nam, var)                           \
3010     do {                                             \
3011         if (var)                                     \
3012             Sprintf(eos(buf), "%s%s", COMMA, (nam)); \
3013     } while (0)
3014
3015 STATIC_OVL void
3016 print_mapseen(win, mptr, final, how, printdun)
3017 winid win;
3018 mapseen *mptr;
3019 int final; /* 0: not final; 1: game over, alive; 2: game over, dead */
3020 int how;   /* cause of death; only used if final==2 and mptr->lev==u.uz */
3021 boolean printdun;
3022 {
3023     char buf[BUFSZ], tmpbuf[BUFSZ];
3024     int i, depthstart, dnum;
3025     boolean died_here = (final == 2 && on_level(&u.uz, &mptr->lev));
3026
3027     /* Damnable special cases */
3028     /* The quest and knox should appear to be level 1 to match
3029      * other text.
3030      */
3031     dnum = mptr->lev.dnum;
3032     if (dnum == quest_dnum || dnum == knox_level.dnum)
3033         depthstart = 1;
3034     else
3035         depthstart = dungeons[dnum].depth_start;
3036
3037     if (printdun) {
3038         if (dungeons[dnum].dunlev_ureached == dungeons[dnum].entry_lev
3039             /* suppress the negative numbers in the endgame */
3040             || In_endgame(&mptr->lev))
3041             Sprintf(buf, "%s:", dungeons[dnum].dname);
3042         else if (builds_up(&mptr->lev))
3043 /*JP
3044             Sprintf(buf, "%s: levels %d up to %d",
3045 */
3046             Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
3047                     dungeons[dnum].dname,
3048                     depthstart + dungeons[dnum].entry_lev - 1,
3049                     depthstart + dungeons[dnum].dunlev_ureached - 1);
3050         else
3051 /*JP
3052             Sprintf(buf, "%s: levels %d to %d",
3053 */
3054             Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
3055                     dungeons[dnum].dname, depthstart,
3056                     depthstart + dungeons[dnum].dunlev_ureached - 1);
3057         putstr(win, !final ? ATR_INVERSE : 0, buf);
3058     }
3059
3060     /* calculate level number */
3061     i = depthstart + mptr->lev.dlevel - 1;
3062     if (In_endgame(&mptr->lev))
3063         Sprintf(buf, "%s%s:", TAB, endgamelevelname(tmpbuf, i));
3064     else
3065 /*JP
3066         Sprintf(buf, "%sLevel %d:", TAB, i);
3067 */
3068         Sprintf(buf, "%s%d\8aK:", TAB, i);
3069
3070     /* wizmode prints out proto dungeon names for clarity */
3071     if (wizard) {
3072         s_level *slev;
3073
3074         if ((slev = Is_special(&mptr->lev)) != 0)
3075             Sprintf(eos(buf), " [%s]", slev->proto);
3076     }
3077     /* [perhaps print custom annotation on its own line when it's long] */
3078     if (mptr->custom)
3079         Sprintf(eos(buf), " \"%s\"", mptr->custom);
3080     if (on_level(&u.uz, &mptr->lev))
3081 #if 0 /*JP*/
3082         Sprintf(eos(buf), " <- You %s here.",
3083                 (!final || (final == 1 && how == ASCENDED)) ? "are"
3084                   : (final == 1 && how == ESCAPED) ? "left from"
3085                     : "were");
3086 #else
3087         Sprintf(eos(buf), " <- \82±\82±%s\81D",
3088                 (!final || (final == 1 && how == ASCENDED)) ? "\82É\82¢\82é"
3089                   : (final == 1 && how == ESCAPED) ? "\82©\82ç\94²\82¯\82½"
3090                     : "\82É\82¢\82½");
3091 #endif
3092     putstr(win, !final ? ATR_BOLD : 0, buf);
3093
3094     if (mptr->flags.forgot)
3095         return;
3096
3097     if (INTEREST(mptr->feat)) {
3098         buf[0] = 0;
3099
3100         i = 0; /* interest counter */
3101         /* List interests in an order vaguely corresponding to
3102          * how important they are.
3103          */
3104         if (mptr->feat.nshop > 0) {
3105             if (mptr->feat.nshop > 1)
3106 /*JP
3107                 ADDNTOBUF("shop", mptr->feat.nshop);
3108 */
3109                 ADDNTOBUF("\93X", mptr->feat.nshop);
3110             else
3111                 Sprintf(eos(buf), "%s%s", COMMA,
3112                         an(shop_string(mptr->feat.shoptype)));
3113         }
3114         if (mptr->feat.naltar > 0) {
3115             /* Temples + non-temple altars get munged into just "altars" */
3116             if (mptr->feat.ntemple != mptr->feat.naltar)
3117 /*JP
3118                 ADDNTOBUF("altar", mptr->feat.naltar);
3119 */
3120                 ADDNTOBUF("\8dÕ\92d", mptr->feat.naltar);
3121             else
3122 /*JP
3123                 ADDNTOBUF("temple", mptr->feat.ntemple);
3124 */
3125                 ADDNTOBUF("\8e\9b\89@", mptr->feat.ntemple);
3126
3127             /* only print out altar's god if they are all to your god */
3128             if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
3129 /*JP
3130                 Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
3131 */
3132                 Sprintf(eos(buf), "(%s)", align_gname(u.ualign.type));
3133         }
3134 /*JP
3135         ADDNTOBUF("throne", mptr->feat.nthrone);
3136 */
3137         ADDNTOBUF("\8bÊ\8dÀ", mptr->feat.nthrone);
3138 /*JP
3139         ADDNTOBUF("fountain", mptr->feat.nfount);
3140 */
3141         ADDNTOBUF("\90ò", mptr->feat.nfount);
3142 /*JP
3143         ADDNTOBUF("sink", mptr->feat.nsink);
3144 */
3145         ADDNTOBUF("\97¬\82µ\91ä", mptr->feat.nsink);
3146 /*JP
3147         ADDNTOBUF("grave", mptr->feat.ngrave);
3148 */
3149         ADDNTOBUF("\95æ", mptr->feat.ngrave);
3150 /*JP
3151         ADDNTOBUF("tree", mptr->feat.ntree);
3152 */
3153         ADDNTOBUF("\96Ø", mptr->feat.ntree);
3154 #if 0
3155         ADDTOBUF("water", mptr->feat.water);
3156         ADDTOBUF("lava", mptr->feat.lava);
3157         ADDTOBUF("ice", mptr->feat.ice);
3158 #endif
3159         /* capitalize afterwards */
3160         i = strlen(PREFIX);
3161         buf[i] = highc(buf[i]);
3162         /* capitalizing it makes it a sentence; terminate with '.' */
3163         Strcat(buf, ".");
3164         putstr(win, 0, buf);
3165     }
3166
3167     /* we assume that these are mutually exclusive */
3168     *buf = '\0';
3169     if (mptr->flags.oracle) {
3170 /*JP
3171         Sprintf(buf, "%sOracle of Delphi.", PREFIX);
3172 */
3173         Sprintf(buf, "%s\83f\83\8b\83t\83@\83C\82Ì\90_\93a\81D", PREFIX);
3174     } else if (In_sokoban(&mptr->lev)) {
3175 #if 0 /*JP*/
3176         Sprintf(buf, "%s%s.", PREFIX,
3177                 mptr->flags.sokosolved ? "Solved" : "Unsolved");
3178 #else
3179         Sprintf(buf, "%s%s.", PREFIX,
3180                 mptr->flags.sokosolved ? "\83N\83\8a\83A\8dÏ" : "\96¢\83N\83\8a\83A");
3181 #endif
3182     } else if (mptr->flags.bigroom) {
3183 /*JP
3184         Sprintf(buf, "%sA very big room.", PREFIX);
3185 */
3186         Sprintf(buf, "%s\82Æ\82Ä\82à\91å\82«\82¢\95\94\89®\81D", PREFIX);
3187     } else if (mptr->flags.roguelevel) {
3188 /*JP
3189         Sprintf(buf, "%sA primitive area.", PREFIX);
3190 */
3191         Sprintf(buf, "%s\92P\8f\83\82È\95\94\89®\81D", PREFIX);
3192     } else if (on_level(&mptr->lev, &qstart_level)) {
3193 #if 0 /*JP*/
3194         Sprintf(buf, "%sHome%s.", PREFIX,
3195                 mptr->flags.unreachable ? " (no way back...)" : "");
3196 #else
3197         Sprintf(buf, "%s\8cÌ\8b½%s\81D", PREFIX,
3198                 mptr->flags.unreachable ? "(\96ß\82ê\82È\82¢\81D\81D\81D)" : "");
3199 #endif
3200         if (u.uevent.qcompleted)
3201 /*JP
3202             Sprintf(buf, "%sCompleted quest for %s.", PREFIX, ldrname());
3203 */
3204             Sprintf(buf, "%s%s\82Ì\82½\82ß\82É\83N\83G\83X\83g\82ð\8a®\90\8b\82µ\82½\81D", PREFIX, ldrname());
3205         else if (mptr->flags.questing)
3206 /*JP
3207             Sprintf(buf, "%sGiven quest by %s.", PREFIX, ldrname());
3208 */
3209             Sprintf(buf, "%s%s\82©\82ç\83N\83G\83X\83g\82ð\97^\82¦\82ç\82ê\82½\81D", PREFIX, ldrname());
3210     } else if (mptr->flags.ludios) {
3211         /* presence of the ludios branch in #overview output indicates that
3212            the player has made it onto the level; presence of this annotation
3213            indicates that the fort's entrance has been seen (or mapped) */
3214 /*JP
3215         Sprintf(buf, "%sFort Ludios.", PREFIX);
3216 */
3217         Sprintf(buf, "%s\83\8d\81[\83f\83B\83I\83X\8dÔ\81D", PREFIX);
3218     } else if (mptr->flags.castle) {
3219 /*JP
3220         Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
3221 */
3222         Sprintf(buf, "%s\8fé%s\81D", PREFIX, tunesuffix(mptr, tmpbuf));
3223     } else if (mptr->flags.valley) {
3224 /*JP
3225         Sprintf(buf, "%sValley of the Dead.", PREFIX);
3226 */
3227         Sprintf(buf, "%s\8e\80\82Ì\92J\81D", PREFIX);
3228     } else if (mptr->flags.msanctum) {
3229 /*JP
3230         Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
3231 */
3232         Sprintf(buf, "%s\83\82\81[\83\8d\83b\83N\82Ì\90¹\88æ\81D", PREFIX);
3233     }
3234     if (*buf)
3235         putstr(win, 0, buf);
3236     /* quest entrance is not mutually-exclusive with bigroom or rogue level */
3237     if (mptr->flags.quest_summons) {
3238 /*JP
3239         Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
3240 */
3241         Sprintf(buf, "%s%s\82©\82ç\8cÄ\82Ñ\8fo\82³\82ê\82½\81D", PREFIX, ldrname());
3242         putstr(win, 0, buf);
3243     }
3244
3245     /* print out branches */
3246     if (mptr->br) {
3247 #if 0 /*JP*/
3248         Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br),
3249                 dungeons[mptr->br->end2.dnum].dname);
3250 #else
3251         Sprintf(buf, "%s%s\82Ö\82Ì%s", PREFIX, dungeons[mptr->br->end2.dnum].dname,
3252                 br_string2(mptr->br));
3253 #endif
3254
3255         /* Since mapseen objects are printed out in increasing order
3256          * of dlevel, clarify which level this branch is going to
3257          * if the branch goes upwards.  Unless it's the end game.
3258          */
3259         if (mptr->br->end1_up && !In_endgame(&(mptr->br->end2)))
3260 /*JP
3261             Sprintf(eos(buf), ", level %d", depth(&(mptr->br->end2)));
3262 */
3263             Sprintf(eos(buf), ", %d\8aK", depth(&(mptr->br->end2)));
3264         Strcat(buf, ".");
3265         putstr(win, 0, buf);
3266     }
3267
3268     /* maybe print out bones details */
3269     if (mptr->final_resting_place || final) {
3270         struct cemetery *bp;
3271         int kncnt = !died_here ? 0 : 1;
3272
3273         for (bp = mptr->final_resting_place; bp; bp = bp->next)
3274             if (bp->bonesknown || wizard || final)
3275                 ++kncnt;
3276         if (kncnt) {
3277 /*JP
3278             Sprintf(buf, "%s%s", PREFIX, "Final resting place for");
3279 */
3280             Sprintf(buf, "%s%s", PREFIX, "\8dÅ\8aú\82Ì\92n:");
3281             putstr(win, 0, buf);
3282             if (died_here) {
3283                 /* disclosure occurs before bones creation, so listing dead
3284                    hero here doesn't give away whether bones are produced */
3285                 formatkiller(tmpbuf, sizeof tmpbuf, how, TRUE);
3286 #if 0 /*JP*/
3287                 /* rephrase a few death reasons to work with "you" */
3288                 (void) strsubst(tmpbuf, " himself", " yourself");
3289                 (void) strsubst(tmpbuf, " herself", " yourself");
3290                 (void) strsubst(tmpbuf, " his ", " your ");
3291                 (void) strsubst(tmpbuf, " her ", " your ");
3292 #endif
3293 #if 0 /*JP*/
3294                 Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf,
3295                         --kncnt ? ',' : '.');
3296 #else
3297                 Sprintf(buf, "%s%s     %s%c", PREFIX, TAB, tmpbuf,
3298                         --kncnt ? ',' : '.');
3299 #endif
3300                 putstr(win, 0, buf);
3301             }
3302             for (bp = mptr->final_resting_place; bp; bp = bp->next) {
3303                 if (bp->bonesknown || wizard || final) {
3304                     Sprintf(buf, "%s%s%s, %s%c", PREFIX, TAB, bp->who,
3305                             bp->how, --kncnt ? ',' : '.');
3306                     putstr(win, 0, buf);
3307                 }
3308             }
3309         }
3310     }
3311 }
3312
3313 /*dungeon.c*/