OSDN Git Service

fix #38569
[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 #if 0 /*JP*//*\93ú\96{\8cê\82Å\82Í\8f\88\97\9d\82µ\82È\82¢*/
1669         /* allow strings like "the oracle level" to find "oracle" */
1670         if (!strncmpi(nam, "the ", 4))
1671             nam += 4;
1672         if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) {
1673             nam = strcpy(buf, nam);
1674             *(eos(buf) - 6) = '\0';
1675         }
1676         /* hell is the old name, and wouldn't match; gehennom would match its
1677            branch, yielding the castle level instead of the valley of the dead */
1678         if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) {
1679             if (In_V_tower(&u.uz))
1680                 nam = " to Vlad's tower"; /* branch to... */
1681             else
1682                 nam = "valley";
1683         }
1684 #endif
1685
1686         if ((slev = find_level(nam)) != 0)
1687             dlev = slev->dlevel;
1688     }
1689
1690     if (mseen || slev) {
1691         idx = ledger_no(&dlev);
1692         if ((dlev.dnum == u.uz.dnum
1693              /* within same branch, or else main dungeon <-> gehennom */
1694              || (u.uz.dnum == valley_level.dnum
1695                  && dlev.dnum == medusa_level.dnum)
1696              || (u.uz.dnum == medusa_level.dnum
1697                  && dlev.dnum == valley_level.dnum))
1698             && (/* either wizard mode or else seen and not forgotten */
1699                 wizard
1700                 || (level_info[idx].flags & (FORGOTTEN | VISITED))
1701                        == VISITED)) {
1702             lev = depth(&dlev);
1703         }
1704     } else { /* not a specific level; try branch names */
1705         idx = find_branch(nam, (struct proto_dungeon *) 0);
1706         /* "<branch> to Xyzzy" */
1707         if (idx < 0 && (p = strstri(nam, " to ")) != 0)
1708             idx = find_branch(p + 4, (struct proto_dungeon *) 0);
1709
1710         if (idx >= 0) {
1711             idxtoo = (idx >> 8) & 0x00FF;
1712             idx &= 0x00FF;
1713             if (/* either wizard mode, or else _both_ sides of branch seen */
1714                 wizard
1715                 || ((level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED
1716                     && (level_info[idxtoo].flags & (FORGOTTEN | VISITED))
1717                            == VISITED)) {
1718                 if (ledger_to_dnum(idxtoo) == u.uz.dnum)
1719                     idx = idxtoo;
1720                 dlev.dnum = ledger_to_dnum(idx);
1721                 dlev.dlevel = ledger_to_dlev(idx);
1722                 lev = depth(&dlev);
1723             }
1724         }
1725     }
1726     return lev;
1727 }
1728
1729 STATIC_OVL boolean
1730 unplaced_floater(dptr)
1731 struct dungeon *dptr;
1732 {
1733     branch *br;
1734     int idx = (int) (dptr - dungeons);
1735
1736     /* if other floating branches are added, this will need to change */
1737     if (idx != knox_level.dnum)
1738         return FALSE;
1739     for (br = branches; br; br = br->next)
1740         if (br->end1.dnum == n_dgns && br->end2.dnum == idx)
1741             return TRUE;
1742     return FALSE;
1743 }
1744
1745 STATIC_OVL boolean
1746 unreachable_level(lvl_p, unplaced)
1747 d_level *lvl_p;
1748 boolean unplaced;
1749 {
1750     s_level *dummy;
1751
1752     if (unplaced)
1753         return TRUE;
1754     if (In_endgame(&u.uz) && !In_endgame(lvl_p))
1755         return TRUE;
1756     if ((dummy = find_level("dummy")) != 0 && on_level(lvl_p, &dummy->dlevel))
1757         return TRUE;
1758     return FALSE;
1759 }
1760
1761 static void
1762 tport_menu(win, entry, lchoices, lvl_p, unreachable)
1763 winid win;
1764 char *entry;
1765 struct lchoice *lchoices;
1766 d_level *lvl_p;
1767 boolean unreachable;
1768 {
1769     char tmpbuf[BUFSZ];
1770     anything any;
1771
1772     lchoices->lev[lchoices->idx] = lvl_p->dlevel;
1773     lchoices->dgn[lchoices->idx] = lvl_p->dnum;
1774     lchoices->playerlev[lchoices->idx] = depth(lvl_p);
1775     any = zeroany;
1776     if (unreachable) {
1777         /* not selectable, but still consumes next menuletter;
1778            prepend padding in place of missing menu selector */
1779         Sprintf(tmpbuf, "    %s", entry);
1780         entry = tmpbuf;
1781     } else {
1782         any.a_int = lchoices->idx + 1;
1783     }
1784     add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 0, ATR_NONE, entry,
1785              MENU_UNSELECTED);
1786     /* this assumes there are at most 52 interesting levels */
1787     if (lchoices->menuletter == 'z')
1788         lchoices->menuletter = 'A';
1789     else
1790         lchoices->menuletter++;
1791     lchoices->idx++;
1792     return;
1793 }
1794
1795 /* Convert a branch type to a string usable by print_dungeon(). */
1796 STATIC_OVL const char *
1797 br_string(type)
1798 int type;
1799 {
1800     switch (type) {
1801     case BR_PORTAL:
1802 /*JP
1803         return "Portal";
1804 */
1805         return "\96\82\96@\82Ì\93ü\82è\8cû";
1806     case BR_NO_END1:
1807 /*JP
1808         return "Connection";
1809 */
1810         return "\90Ú\91±\95\94";
1811     case BR_NO_END2:
1812 /*JP
1813         return "One way stair";
1814 */
1815         return "\88ê\95û\92Ê\8ds\82Ì\8aK\92i";
1816     case BR_STAIR:
1817 /*JP
1818         return "Stair";
1819 */
1820         return "\8aK\92i";
1821     }
1822 /*JP
1823     return " (unknown)";
1824 */
1825     return " (\95s\96¾)";
1826 }
1827
1828 STATIC_OVL char
1829 chr_u_on_lvl(dlev)
1830 d_level *dlev;
1831 {
1832     return u.uz.dnum == dlev->dnum && u.uz.dlevel == dlev->dlevel ? '*' : ' ';
1833 }
1834
1835 /* Print all child branches between the lower and upper bounds. */
1836 STATIC_OVL void
1837 print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices_p)
1838 winid win;
1839 int dnum;
1840 int lower_bound;
1841 int upper_bound;
1842 boolean bymenu;
1843 struct lchoice *lchoices_p;
1844 {
1845     branch *br;
1846     char buf[BUFSZ];
1847
1848     /* This assumes that end1 is the "parent". */
1849     for (br = branches; br; br = br->next) {
1850         if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel
1851             && br->end1.dlevel <= upper_bound) {
1852 #if 0 /*JP*/
1853             Sprintf(buf, "%c %s to %s: %d",
1854                     bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1855                     br_string(br->type),
1856                     dungeons[br->end2.dnum].dname, depth(&br->end1));
1857 #else
1858             Sprintf(buf, "%c %s\82©\82ç%s: %d",
1859                     bymenu ? chr_u_on_lvl(&br->end1) : ' ',
1860                     br_string(br->type),
1861                     dungeons[br->end2.dnum].dname, depth(&br->end1));
1862 #endif
1863             if (bymenu)
1864                 tport_menu(win, buf, lchoices_p, &br->end1,
1865                            unreachable_level(&br->end1, FALSE));
1866             else
1867                 putstr(win, 0, buf);
1868         }
1869     }
1870 }
1871
1872 /* Print available dungeon information. */
1873 schar
1874 print_dungeon(bymenu, rlev, rdgn)
1875 boolean bymenu;
1876 schar *rlev;
1877 xchar *rdgn;
1878 {
1879     int i, last_level, nlev;
1880     char buf[BUFSZ];
1881     const char *descr;
1882     boolean first, unplaced;
1883     s_level *slev;
1884     dungeon *dptr;
1885     branch *br;
1886     anything any;
1887     struct lchoice lchoices;
1888     winid win = create_nhwindow(NHW_MENU);
1889
1890     if (bymenu) {
1891         start_menu(win);
1892         lchoices.idx = 0;
1893         lchoices.menuletter = 'a';
1894     }
1895
1896     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
1897         if (bymenu && In_endgame(&u.uz) && i != astral_level.dnum)
1898             continue;
1899         unplaced = unplaced_floater(dptr);
1900 /*JP
1901         descr = unplaced ? "depth" : "level";
1902 */
1903         descr = unplaced ? "\92n\89º" : "\83\8c\83x\83\8b";
1904         nlev = dptr->num_dunlevs;
1905         if (nlev > 1)
1906 #if 0 /*JP*/
1907             Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr),
1908                     dptr->depth_start, dptr->depth_start + nlev - 1);
1909 #else
1910             Sprintf(buf, "%s: %s%d\82©\82ç%d", dptr->dname, descr,
1911                     dptr->depth_start, dptr->depth_start + nlev - 1);
1912 #endif
1913         else
1914             Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start);
1915
1916         /* Most entrances are uninteresting. */
1917         if (dptr->entry_lev != 1) {
1918             if (dptr->entry_lev == nlev)
1919 /*JP
1920                 Strcat(buf, ", entrance from below");
1921 */
1922                 Strcat(buf, ", \89º\82©\82ç\82Ì\93ü\82è\8cû");
1923             else
1924 #if 0 /*JP*/
1925                 Sprintf(eos(buf), ", entrance on %d",
1926                         dptr->depth_start + dptr->entry_lev - 1);
1927 #else
1928                 Sprintf(eos(buf), ", %d\82Ì\93ü\82è\8cû",
1929                         dptr->depth_start + dptr->entry_lev - 1);
1930 #endif
1931         }
1932         if (bymenu) {
1933             any = zeroany;
1934             add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
1935                      MENU_UNSELECTED);
1936         } else
1937             putstr(win, 0, buf);
1938
1939         /*
1940          * Circle through the special levels to find levels that are in
1941          * this dungeon.
1942          */
1943         for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
1944             if (slev->dlevel.dnum != i)
1945                 continue;
1946
1947             /* print any branches before this level */
1948             print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu,
1949                          &lchoices);
1950
1951             Sprintf(buf, "%c %s: %d",
1952                     chr_u_on_lvl(&slev->dlevel),
1953                     slev->proto, depth(&slev->dlevel));
1954             if (Is_stronghold(&slev->dlevel))
1955                 Sprintf(eos(buf), " (tune %s)", tune);
1956             if (bymenu)
1957                 tport_menu(win, buf, &lchoices, &slev->dlevel,
1958                            unreachable_level(&slev->dlevel, unplaced));
1959             else
1960                 putstr(win, 0, buf);
1961
1962             last_level = slev->dlevel.dlevel;
1963         }
1964         /* print branches after the last special level */
1965         print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices);
1966     }
1967
1968     if (bymenu) {
1969         int n;
1970         menu_item *selected;
1971         int idx;
1972
1973 /*JP
1974         end_menu(win, "Level teleport to where:");
1975 */
1976         end_menu(win, "\82Ç\82±\82É\8fu\8aÔ\88Ú\93®\82·\82é\81F");
1977         n = select_menu(win, PICK_ONE, &selected);
1978         destroy_nhwindow(win);
1979         if (n > 0) {
1980             idx = selected[0].item.a_int - 1;
1981             free((genericptr_t) selected);
1982             if (rlev && rdgn) {
1983                 *rlev = lchoices.lev[idx];
1984                 *rdgn = lchoices.dgn[idx];
1985                 return lchoices.playerlev[idx];
1986             }
1987         }
1988         return 0;
1989     }
1990
1991     /* Print out floating branches (if any). */
1992     for (first = TRUE, br = branches; br; br = br->next) {
1993         if (br->end1.dnum == n_dgns) {
1994             if (first) {
1995                 putstr(win, 0, "");
1996 /*JP
1997                 putstr(win, 0, "Floating branches");
1998 */
1999                 putstr(win, 0, "\95\82\93®\95ª\8aò");
2000                 first = FALSE;
2001             }
2002 #if 0 /*JP*/
2003             Sprintf(buf, "   %s to %s", br_string(br->type),
2004                     dungeons[br->end2.dnum].dname);
2005 #else
2006             Sprintf(buf, "   %s\82©\82ç%s", br_string(br->type),
2007                     dungeons[br->end2.dnum].dname);
2008 #endif
2009             putstr(win, 0, buf);
2010         }
2011     }
2012
2013     /* I hate searching for the invocation pos while debugging. -dean */
2014     if (Invocation_lev(&u.uz)) {
2015         putstr(win, 0, "");
2016 #if 0 /*JP*/
2017         Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
2018                 inv_pos.x, inv_pos.y, u.ux, u.uy);
2019 #else
2020         Sprintf(buf, "\94­\93®\88Ê\92u @ (%d,%d), \83v\83\8c\83C\83\84\81[ @ (%d,%d)",
2021                 inv_pos.x, inv_pos.y, u.ux, u.uy);
2022 #endif
2023         putstr(win, 0, buf);
2024     } else {
2025         struct trap *trap;
2026
2027         /* if current level has a magic portal, report its location;
2028            this assumes that there is at most one magic portal on any
2029            given level; quest and ft.ludios have pairs (one in main
2030            dungeon matched with one in the corresponding branch), the
2031            elemental planes have singletons (connection to next plane) */
2032         *buf = '\0';
2033         for (trap = ftrap; trap; trap = trap->ntrap)
2034             if (trap->ttyp == MAGIC_PORTAL)
2035                 break;
2036
2037         if (trap)
2038             Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
2039                     trap->tx, trap->ty, u.ux, u.uy);
2040
2041         /* only report "no portal found" when actually expecting a portal */
2042 #if 0 /*JP*/
2043         else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2044                  || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2045                  || Is_qstart(&u.uz) || at_dgn_entrance("The Quest")
2046                  || Is_knox(&u.uz))
2047 #else
2048         else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
2049                  || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)
2050                  || Is_qstart(&u.uz) || at_dgn_entrance("\83N\83G\83X\83g")
2051                  || Is_knox(&u.uz))
2052 #endif
2053             Strcpy(buf, "No portal found.");
2054
2055         /* only give output if we found a portal or expected one and didn't */
2056         if (*buf) {
2057             putstr(win, 0, "");
2058             putstr(win, 0, buf);
2059         }
2060     }
2061
2062     display_nhwindow(win, TRUE);
2063     destroy_nhwindow(win);
2064     return 0;
2065 }
2066
2067 /* Record that the player knows about a branch from a level. This function
2068  * will determine whether or not it was a "real" branch that was taken.
2069  * This function should not be called for a transition done via level
2070  * teleport or via the Eye.
2071  */
2072 void
2073 recbranch_mapseen(source, dest)
2074 d_level *source;
2075 d_level *dest;
2076 {
2077     mapseen *mptr;
2078     branch *br;
2079
2080     /* not a branch */
2081     if (source->dnum == dest->dnum)
2082         return;
2083
2084     /* we only care about forward branches */
2085     for (br = branches; br; br = br->next) {
2086         if (on_level(source, &br->end1) && on_level(dest, &br->end2))
2087             break;
2088         if (on_level(source, &br->end2) && on_level(dest, &br->end1))
2089             return;
2090     }
2091
2092     /* branch not found, so not a real branch. */
2093     if (!br)
2094         return;
2095
2096     if ((mptr = find_mapseen(source)) != 0) {
2097         if (mptr->br && br != mptr->br)
2098             impossible("Two branches on the same level?");
2099         mptr->br = br;
2100     } else {
2101         impossible("Can't note branch for unseen level (%d, %d)",
2102                    source->dnum, source->dlevel);
2103     }
2104 }
2105
2106 char *
2107 get_annotation(lev)
2108 d_level *lev;
2109 {
2110     mapseen *mptr;
2111
2112     if ((mptr = find_mapseen(lev)))
2113         return mptr->custom;
2114     return NULL;
2115 }
2116
2117 /* #annotate command - add a custom name to the current level */
2118 int
2119 donamelevel()
2120 {
2121     mapseen *mptr;
2122     char nbuf[BUFSZ]; /* Buffer for response */
2123
2124     if (!(mptr = find_mapseen(&u.uz)))
2125         return 0;
2126
2127     nbuf[0] = '\0';
2128 #ifdef EDIT_GETLIN
2129     if (mptr->custom) {
2130         (void) strncpy(nbuf, mptr->custom, BUFSZ);
2131         nbuf[BUFSZ - 1] = '\0';
2132     }
2133 #else
2134     if (mptr->custom) {
2135         char tmpbuf[BUFSZ];
2136
2137 #if 0 /*JP*/
2138         Sprintf(tmpbuf, "Replace annotation \"%.30s%s\" with?", mptr->custom,
2139                 (strlen(mptr->custom) > 30) ? "..." : "");
2140 #else
2141         Sprintf(tmpbuf, "\8c»\8dÝ\82Ì\83\81\83\82\81u%.30s%s\81v\82ð\89½\82É\8f\91\82«\8a·\82¦\82é\81H", mptr->custom,
2142                 strlen(mptr->custom) > 30 ? "..." : "");
2143 #endif
2144         getlin(tmpbuf, nbuf);
2145     } else
2146 #endif
2147 /*JP
2148         getlin("What do you want to call this dungeon level?", nbuf);
2149 */
2150         getlin("\82±\82Ì\8aK\82ð\89½\82Æ\8cÄ\82Ô\81H", nbuf);
2151
2152     /* empty input or ESC means don't add or change annotation;
2153        space-only means discard current annotation without adding new one */
2154     if (!*nbuf || *nbuf == '\033')
2155         return 0;
2156     /* strip leading and trailing spaces, compress out consecutive spaces */
2157     (void) mungspaces(nbuf);
2158
2159     /* discard old annotation, if any */
2160     if (mptr->custom) {
2161         free((genericptr_t) mptr->custom);
2162         mptr->custom = (char *) 0;
2163         mptr->custom_lth = 0;
2164     }
2165     /* add new annotation, unless it's all spaces (which will be an
2166        empty string after mungspaces() above) */
2167     if (*nbuf && strcmp(nbuf, " ")) {
2168         mptr->custom = dupstr(nbuf);
2169         mptr->custom_lth = strlen(mptr->custom);
2170     }
2171     return 0;
2172 }
2173
2174 /* find the particular mapseen object in the chain; may return null */
2175 STATIC_OVL mapseen *
2176 find_mapseen(lev)
2177 d_level *lev;
2178 {
2179     mapseen *mptr;
2180
2181     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2182         if (on_level(&(mptr->lev), lev))
2183             break;
2184
2185     return mptr;
2186 }
2187
2188 STATIC_OVL mapseen *
2189 find_mapseen_by_str(s)
2190 const char *s;
2191 {
2192     mapseen *mptr;
2193
2194     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2195         if (mptr->custom && !strcmpi(s, mptr->custom))
2196             break;
2197
2198     return mptr;
2199 }
2200
2201
2202 void
2203 forget_mapseen(ledger_num)
2204 int ledger_num;
2205 {
2206     mapseen *mptr;
2207     struct cemetery *bp;
2208
2209     for (mptr = mapseenchn; mptr; mptr = mptr->next)
2210         if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel
2211             == ledger_num)
2212             break;
2213
2214     /* if not found, then nothing to forget */
2215     if (mptr) {
2216         mptr->flags.forgot = 1;
2217         mptr->br = (branch *) 0;
2218
2219         /* custom names are erased, not just forgotten until revisited */
2220         if (mptr->custom) {
2221             mptr->custom_lth = 0;
2222             free((genericptr_t) mptr->custom);
2223             mptr->custom = (char *) 0;
2224         }
2225         (void) memset((genericptr_t) mptr->msrooms, 0, sizeof mptr->msrooms);
2226         for (bp = mptr->final_resting_place; bp; bp = bp->next)
2227             bp->bonesknown = FALSE;
2228     }
2229 }
2230
2231 void
2232 rm_mapseen(ledger_num)
2233 int ledger_num;
2234 {
2235     mapseen *mptr, *mprev = (mapseen *)0;
2236     struct cemetery *bp, *bpnext;
2237
2238     for (mptr = mapseenchn; mptr; mprev = mptr, mptr = mptr->next)
2239         if (dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel == ledger_num)
2240             break;
2241
2242     if (!mptr)
2243         return;
2244
2245     if (mptr->custom)
2246         free((genericptr_t) mptr->custom);
2247
2248     bp = mptr->final_resting_place;
2249     while (bp) {
2250         bpnext = bp->next;
2251         free(bp);
2252         bp = bpnext;
2253     }
2254
2255     if (mprev) {
2256         mprev->next = mptr->next;
2257         free(mptr);
2258     } else {
2259         mapseenchn = mptr->next;
2260         free(mptr);
2261     }
2262 }
2263
2264 STATIC_OVL void
2265 save_mapseen(fd, mptr)
2266 int fd;
2267 mapseen *mptr;
2268 {
2269     branch *curr;
2270     int brindx;
2271
2272     for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2273         if (curr == mptr->br)
2274             break;
2275     bwrite(fd, (genericptr_t) &brindx, sizeof brindx);
2276
2277     bwrite(fd, (genericptr_t) &mptr->lev, sizeof mptr->lev);
2278     bwrite(fd, (genericptr_t) &mptr->feat, sizeof mptr->feat);
2279     bwrite(fd, (genericptr_t) &mptr->flags, sizeof mptr->flags);
2280     bwrite(fd, (genericptr_t) &mptr->custom_lth, sizeof mptr->custom_lth);
2281     if (mptr->custom_lth)
2282         bwrite(fd, (genericptr_t) mptr->custom, mptr->custom_lth);
2283     bwrite(fd, (genericptr_t) &mptr->msrooms, sizeof mptr->msrooms);
2284     savecemetery(fd, WRITE_SAVE, &mptr->final_resting_place);
2285 }
2286
2287 STATIC_OVL mapseen *
2288 load_mapseen(fd)
2289 int fd;
2290 {
2291     int branchnum, brindx;
2292     mapseen *load;
2293     branch *curr;
2294
2295     load = (mapseen *) alloc(sizeof *load);
2296
2297     mread(fd, (genericptr_t) &branchnum, sizeof branchnum);
2298     for (brindx = 0, curr = branches; curr; curr = curr->next, ++brindx)
2299         if (brindx == branchnum)
2300             break;
2301     load->br = curr;
2302
2303     mread(fd, (genericptr_t) &load->lev, sizeof load->lev);
2304     mread(fd, (genericptr_t) &load->feat, sizeof load->feat);
2305     mread(fd, (genericptr_t) &load->flags, sizeof load->flags);
2306     mread(fd, (genericptr_t) &load->custom_lth, sizeof load->custom_lth);
2307     if (load->custom_lth) {
2308         /* length doesn't include terminator (which isn't saved & restored) */
2309         load->custom = (char *) alloc(load->custom_lth + 1);
2310         mread(fd, (genericptr_t) load->custom, load->custom_lth);
2311         load->custom[load->custom_lth] = '\0';
2312     } else
2313         load->custom = 0;
2314     mread(fd, (genericptr_t) &load->msrooms, sizeof load->msrooms);
2315     restcemetery(fd, &load->final_resting_place);
2316
2317     return load;
2318 }
2319
2320 /* to support '#stats' wizard-mode command */
2321 void
2322 overview_stats(win, statsfmt, total_count, total_size)
2323 winid win;
2324 const char *statsfmt;
2325 long *total_count, *total_size;
2326 {
2327     char buf[BUFSZ], hdrbuf[QBUFSZ];
2328     long ocount, osize, bcount, bsize, acount, asize;
2329     struct cemetery *ce;
2330     mapseen *mptr = find_mapseen(&u.uz);
2331
2332     ocount = bcount = acount = osize = bsize = asize = 0L;
2333     for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2334         ++ocount;
2335         osize += (long) sizeof *mptr;
2336         for (ce = mptr->final_resting_place; ce; ce = ce->next) {
2337             ++bcount;
2338             bsize += (long) sizeof *ce;
2339         }
2340         if (mptr->custom_lth) {
2341             ++acount;
2342             asize += (long) (mptr->custom_lth + 1);
2343         }
2344     }
2345
2346     Sprintf(hdrbuf, "general, size %ld", (long) sizeof (mapseen));
2347     Sprintf(buf, statsfmt, hdrbuf, ocount, osize);
2348     putstr(win, 0, buf);
2349     if (bcount) {
2350         Sprintf(hdrbuf, "cemetery, size %ld",
2351                 (long) sizeof (struct cemetery));
2352         Sprintf(buf, statsfmt, hdrbuf, bcount, bsize);
2353         putstr(win, 0, buf);
2354     }
2355     if (acount) {
2356         Sprintf(hdrbuf, "annotations, text");
2357         Sprintf(buf, statsfmt, hdrbuf, acount, asize);
2358         putstr(win, 0, buf);
2359     }
2360     *total_count += ocount + bcount + acount;
2361     *total_size += osize + bsize + asize;
2362 }
2363
2364 /* Remove all mapseen objects for a particular dnum.
2365  * Useful during quest expulsion to remove quest levels.
2366  * [No longer deleted, just marked as unreachable.  #overview will
2367  * ignore such levels, end of game disclosure will include them.]
2368  */
2369 void
2370 remdun_mapseen(dnum)
2371 int dnum;
2372 {
2373     mapseen *mptr, **mptraddr;
2374
2375     mptraddr = &mapseenchn;
2376     while ((mptr = *mptraddr) != 0) {
2377         if (mptr->lev.dnum == dnum) {
2378 #if 1 /* use this... */
2379             mptr->flags.unreachable = 1;
2380         }
2381 #else /* old deletion code */
2382             *mptraddr = mptr->next;
2383             if (mptr->custom)
2384                 free((genericptr_t) mptr->custom);
2385             if (mptr->final_resting_place)
2386                 savecemetery(-1, FREE_SAVE, &mptr->final_resting_place);
2387             free((genericptr_t) mptr);
2388         } else
2389 #endif
2390         mptraddr = &mptr->next;
2391     }
2392 }
2393
2394 void
2395 init_mapseen(lev)
2396 d_level *lev;
2397 {
2398     /* Create a level and insert in "sorted" order.  This is an insertion
2399      * sort first by dungeon (in order of discovery) and then by level number.
2400      */
2401     mapseen *mptr, *init, *prev;
2402
2403     init = (mapseen *) alloc(sizeof *init);
2404     (void) memset((genericptr_t) init, 0, sizeof *init);
2405     /* memset is fine for feature bits, flags, and rooms array;
2406        explicitly initialize pointers to null */
2407     init->next = 0, init->br = 0, init->custom = 0;
2408     init->final_resting_place = 0;
2409     /* lastseentyp[][] is reused for each level, so get rid of
2410        previous level's data */
2411     (void) memset((genericptr_t) lastseentyp, 0, sizeof lastseentyp);
2412
2413     init->lev.dnum = lev->dnum;
2414     init->lev.dlevel = lev->dlevel;
2415
2416     /* walk until we get to the place where we should insert init */
2417     for (mptr = mapseenchn, prev = 0; mptr; prev = mptr, mptr = mptr->next)
2418         if (mptr->lev.dnum > init->lev.dnum
2419             || (mptr->lev.dnum == init->lev.dnum
2420                 && mptr->lev.dlevel > init->lev.dlevel))
2421             break;
2422     if (!prev) {
2423         init->next = mapseenchn;
2424         mapseenchn = init;
2425     } else {
2426         mptr = prev->next;
2427         prev->next = init;
2428         init->next = mptr;
2429     }
2430 }
2431
2432 #define INTEREST(feat)                                                \
2433     ((feat).nfount || (feat).nsink || (feat).nthrone || (feat).naltar \
2434      || (feat).ngrave || (feat).ntree || (feat).nshop || (feat).ntemple)
2435   /* || (feat).water || (feat).ice || (feat).lava */
2436
2437 /* returns true if this level has something interesting to print out */
2438 STATIC_OVL boolean
2439 interest_mapseen(mptr)
2440 mapseen *mptr;
2441 {
2442     if (on_level(&u.uz, &mptr->lev))
2443         return TRUE;
2444     if (mptr->flags.unreachable || mptr->flags.forgot)
2445         return FALSE;
2446     /* level is of interest if it has an auto-generated annotation */
2447     if (mptr->flags.oracle || mptr->flags.bigroom || mptr->flags.roguelevel
2448         || mptr->flags.castle || mptr->flags.valley || mptr->flags.msanctum
2449         || mptr->flags.quest_summons || mptr->flags.questing)
2450         return TRUE;
2451     /* when in Sokoban, list all sokoban levels visited; when not in it,
2452        list any visited Sokoban level which remains unsolved (will usually
2453        only be furthest one reached, but it's possible to enter pits and
2454        climb out on the far side on the first Sokoban level; also, wizard
2455        mode overrides teleport restrictions) */
2456     if (In_sokoban(&mptr->lev)
2457         && (In_sokoban(&u.uz) || !mptr->flags.sokosolved))
2458         return TRUE;
2459     /* when in the endgame, list all endgame levels visited, whether they
2460        have annotations or not, so that #overview doesn't become extremely
2461        sparse once the rest of the dungeon has been flagged as unreachable */
2462     if (In_endgame(&u.uz))
2463         return (boolean) In_endgame(&mptr->lev);
2464     /* level is of interest if it has non-zero feature count or known bones
2465        or user annotation or known connection to another dungeon branch
2466        or is the furthest level reached in its branch */
2467     return (boolean) (INTEREST(mptr->feat)
2468                       || (mptr->final_resting_place
2469                           && (mptr->flags.knownbones || wizard))
2470                       || mptr->custom || mptr->br
2471                       || (mptr->lev.dlevel
2472                           == dungeons[mptr->lev.dnum].dunlev_ureached));
2473 }
2474
2475 /* recalculate mapseen for the current level */
2476 void
2477 recalc_mapseen()
2478 {
2479     mapseen *mptr;
2480     struct monst *mtmp;
2481     struct cemetery *bp, **bonesaddr;
2482     unsigned i, ridx;
2483     int x, y, ltyp, count, atmp;
2484
2485     /* Should not happen in general, but possible if in the process
2486      * of being booted from the quest.  The mapseen object gets
2487      * removed during the expulsion but prior to leaving the level
2488      * [Since quest expulsion no longer deletes quest mapseen data,
2489      * null return from find_mapseen() should now be impossible.]
2490      */
2491     if (!(mptr = find_mapseen(&u.uz)))
2492         return;
2493
2494     /* reset all features; mptr->feat.* = 0; */
2495     (void) memset((genericptr_t) &mptr->feat, 0, sizeof mptr->feat);
2496     /* reset most flags; some level-specific ones are left as-is */
2497     if (mptr->flags.unreachable) {
2498         mptr->flags.unreachable = 0; /* reached it; Eye of the Aethiopica? */
2499         if (In_quest(&u.uz)) {
2500             mapseen *mptrtmp = mapseenchn;
2501
2502             /* when quest was unreachable due to ejection and portal removal,
2503                getting back to it via arti-invoke should revive annotation
2504                data for all quest levels, not just the one we're on now */
2505             do {
2506                 if (mptrtmp->lev.dnum == mptr->lev.dnum)
2507                     mptrtmp->flags.unreachable = 0;
2508                 mptrtmp = mptrtmp->next;
2509             } while (mptrtmp);
2510         }
2511     }
2512     mptr->flags.knownbones = 0;
2513     mptr->flags.sokosolved = In_sokoban(&u.uz) && !Sokoban;
2514     /* mptr->flags.bigroom retains previous value when hero can't see */
2515     if (!Blind)
2516         mptr->flags.bigroom = Is_bigroom(&u.uz);
2517     else if (mptr->flags.forgot)
2518         mptr->flags.bigroom = 0;
2519     mptr->flags.roguelevel = Is_rogue_level(&u.uz);
2520     mptr->flags.oracle = 0; /* recalculated during room traversal below */
2521     mptr->flags.castletune = 0;
2522     /* flags.castle, flags.valley, flags.msanctum retain previous value */
2523     mptr->flags.forgot = 0;
2524     /* flags.quest_summons disabled once quest finished */
2525 /*JP
2526     mptr->flags.quest_summons = (at_dgn_entrance("The Quest")
2527 */
2528     mptr->flags.quest_summons = (at_dgn_entrance("\83N\83G\83X\83g")
2529                                  && u.uevent.qcalled
2530                                  && !(u.uevent.qcompleted
2531                                       || u.uevent.qexpelled
2532                                       || quest_status.leader_is_dead));
2533     mptr->flags.questing = (on_level(&u.uz, &qstart_level)
2534                             && quest_status.got_quest);
2535
2536     /* track rooms the hero is in */
2537     for (i = 0; i < SIZE(u.urooms); ++i) {
2538         if (!u.urooms[i])
2539             continue;
2540
2541         ridx = u.urooms[i] - ROOMOFFSET;
2542         mptr->msrooms[ridx].seen = 1;
2543         mptr->msrooms[ridx].untended =
2544             (rooms[ridx].rtype >= SHOPBASE)
2545                 ? (!(mtmp = shop_keeper(u.urooms[i])) || !inhishop(mtmp))
2546                 : (rooms[ridx].rtype == TEMPLE)
2547                       ? (!(mtmp = findpriest(u.urooms[i]))
2548                          || !inhistemple(mtmp))
2549                       : 0;
2550     }
2551
2552     /* recalculate room knowledge: for now, just shops and temples
2553      * this could be extended to an array of 0..SHOPBASE
2554      */
2555     for (i = 0; i < SIZE(mptr->msrooms); ++i) {
2556         if (mptr->msrooms[i].seen) {
2557             if (rooms[i].rtype >= SHOPBASE) {
2558                 if (mptr->msrooms[i].untended)
2559                     mptr->feat.shoptype = SHOPBASE - 1;
2560                 else if (!mptr->feat.nshop)
2561                     mptr->feat.shoptype = rooms[i].rtype;
2562                 else if (mptr->feat.shoptype != (unsigned) rooms[i].rtype)
2563                     mptr->feat.shoptype = 0;
2564                 count = mptr->feat.nshop + 1;
2565                 if (count <= 3)
2566                     mptr->feat.nshop = count;
2567             } else if (rooms[i].rtype == TEMPLE) {
2568                 /* altar and temple alignment handled below */
2569                 count = mptr->feat.ntemple + 1;
2570                 if (count <= 3)
2571                     mptr->feat.ntemple = count;
2572             } else if (rooms[i].orig_rtype == DELPHI) {
2573                 mptr->flags.oracle = 1;
2574             }
2575         }
2576     }
2577
2578     /* Update lastseentyp with typ if and only if it is in sight or the
2579      * hero can feel it on their current location (i.e. not levitating).
2580      * This *should* give the "last known typ" for each dungeon location.
2581      * (At the very least, it's a better assumption than determining what
2582      * the player knows from the glyph and the typ (which is isn't quite
2583      * enough information in some cases)).
2584      *
2585      * It was reluctantly added to struct rm to track.  Alternatively
2586      * we could track "features" and then update them all here, and keep
2587      * track of when new features are created or destroyed, but this
2588      * seemed the most elegant, despite adding more data to struct rm.
2589      * [3.6.0: we're using lastseentyp[][] rather than level.locations
2590      * to track the features seen.]
2591      *
2592      * Although no current windowing systems (can) do this, this would add
2593      * the ability to have non-dungeon glyphs float above the last known
2594      * dungeon glyph (i.e. items on fountains).
2595      */
2596     for (x = 1; x < COLNO; x++) {
2597         for (y = 0; y < ROWNO; y++) {
2598             if (cansee(x, y) || (x == u.ux && y == u.uy && !Levitation)) {
2599                 ltyp = levl[x][y].typ;
2600                 if (ltyp == DRAWBRIDGE_UP)
2601                     ltyp = db_under_typ(levl[x][y].drawbridgemask);
2602                 if ((mtmp = m_at(x, y)) != 0
2603                     && mtmp->m_ap_type == M_AP_FURNITURE && canseemon(mtmp))
2604                     ltyp = cmap_to_type(mtmp->mappearance);
2605                 lastseentyp[x][y] = ltyp;
2606             }
2607
2608             switch (lastseentyp[x][y]) {
2609 #if 0
2610             case ICE:
2611                 count = mptr->feat.ice + 1;
2612                 if (count <= 3)
2613                     mptr->feat.ice = count;
2614                 break;
2615             case POOL:
2616             case MOAT:
2617             case WATER:
2618                 count = mptr->feat.water + 1;
2619                 if (count <= 3)
2620                     mptr->feat.water = count;
2621                 break;
2622             case LAVAPOOL:
2623                 count = mptr->feat.lava + 1;
2624                 if (count <= 3)
2625                     mptr->feat.lava = count;
2626                 break;
2627 #endif
2628             case TREE:
2629                 count = mptr->feat.ntree + 1;
2630                 if (count <= 3)
2631                     mptr->feat.ntree = count;
2632                 break;
2633             case FOUNTAIN:
2634                 count = mptr->feat.nfount + 1;
2635                 if (count <= 3)
2636                     mptr->feat.nfount = count;
2637                 break;
2638             case THRONE:
2639                 count = mptr->feat.nthrone + 1;
2640                 if (count <= 3)
2641                     mptr->feat.nthrone = count;
2642                 break;
2643             case SINK:
2644                 count = mptr->feat.nsink + 1;
2645                 if (count <= 3)
2646                     mptr->feat.nsink = count;
2647                 break;
2648             case GRAVE:
2649                 count = mptr->feat.ngrave + 1;
2650                 if (count <= 3)
2651                     mptr->feat.ngrave = count;
2652                 break;
2653             case ALTAR:
2654                 atmp = (Is_astralevel(&u.uz)
2655                         && (levl[x][y].seenv & SVALL) != SVALL)
2656                          ? MSA_NONE
2657                          : Amask2msa(levl[x][y].altarmask);
2658                 if (!mptr->feat.naltar)
2659                     mptr->feat.msalign = atmp;
2660                 else if (mptr->feat.msalign != atmp)
2661                     mptr->feat.msalign = MSA_NONE;
2662                 count = mptr->feat.naltar + 1;
2663                 if (count <= 3)
2664                     mptr->feat.naltar = count;
2665                 break;
2666             /*  An automatic annotation is added to the Castle and
2667              *  to Fort Ludios once their structure's main entrance
2668              *  has been seen (in person or via magic mapping).
2669              *  For the Fort, that entrance is just a secret door
2670              *  which will be converted into a regular one when
2671              *  located (or destroyed).
2672              * DOOR: possibly a lowered drawbridge's open portcullis;
2673              * DBWALL: a raised drawbridge's "closed door";
2674              * DRAWBRIDGE_DOWN: the span provided by lowered bridge,
2675              *  with moat or other terrain hidden underneath;
2676              * DRAWBRIDGE_UP: moat in front of a raised drawbridge,
2677              *  not recognizable as a bridge location unless/until
2678              *  the adjacent DBWALL has been seen.
2679              */
2680             case DOOR:
2681                 if (Is_knox(&u.uz)) {
2682                     int ty, tx = x - 4;
2683
2684                     /* Throne is four columns left, either directly in
2685                      * line or one row higher or lower, and doesn't have
2686                      * to have been seen yet.
2687                      *   ......|}}}.
2688                      *   ..\...S}...
2689                      *   ..\...S}...
2690                      *   ......|}}}.
2691                      * For 3.6.0 and earlier, it was always in direct line:
2692                      * both throne and door on the lower of the two rows.
2693                      */
2694                     for (ty = y - 1; ty <= y + 1; ++ty)
2695                         if (isok(tx, ty) && IS_THRONE(levl[tx][ty].typ)) {
2696                             mptr->flags.ludios = 1;
2697                             break;
2698                         }
2699                     break;
2700                 }
2701                 if (is_drawbridge_wall(x, y) < 0)
2702                     break;
2703                 /*FALLTHRU*/
2704             case DBWALL:
2705             case DRAWBRIDGE_DOWN:
2706                 if (Is_stronghold(&u.uz))
2707                     mptr->flags.castle = 1, mptr->flags.castletune = 1;
2708                 break;
2709             default:
2710                 break;
2711             }
2712         }
2713     }
2714
2715     if (level.bonesinfo && !mptr->final_resting_place) {
2716         /* clone the bonesinfo so we aren't dependent upon this
2717            level being in memory */
2718         bonesaddr = &mptr->final_resting_place;
2719         bp = level.bonesinfo;
2720         do {
2721             *bonesaddr = (struct cemetery *) alloc(sizeof **bonesaddr);
2722             **bonesaddr = *bp;
2723             bp = bp->next;
2724             bonesaddr = &(*bonesaddr)->next;
2725         } while (bp);
2726         *bonesaddr = 0;
2727     }
2728     /* decide which past hero deaths have become known; there's no
2729        guarantee of either a grave or a ghost, so we go by whether the
2730        current hero has seen the map location where each old one died */
2731     for (bp = mptr->final_resting_place; bp; bp = bp->next)
2732         if (lastseentyp[bp->frpx][bp->frpy]) {
2733             bp->bonesknown = TRUE;
2734             mptr->flags.knownbones = 1;
2735         }
2736 }
2737
2738 /*ARGUSED*/
2739 /* valley and sanctum levels get automatic annotation once temple is entered
2740  */
2741 void
2742 mapseen_temple(priest)
2743 struct monst *priest UNUSED; /* currently unused; might be useful someday */
2744 {
2745     mapseen *mptr = find_mapseen(&u.uz);
2746
2747     if (Is_valley(&u.uz))
2748         mptr->flags.valley = 1;
2749     else if (Is_sanctum(&u.uz))
2750         mptr->flags.msanctum = 1;
2751 }
2752
2753 /* room entry message has just been delivered so learn room even if blind */
2754 void
2755 room_discovered(roomno)
2756 int roomno;
2757 {
2758     mapseen *mptr = find_mapseen(&u.uz);
2759
2760     mptr->msrooms[roomno].seen = 1;
2761 }
2762
2763 /* #overview command */
2764 int
2765 dooverview()
2766 {
2767     show_overview(0, 0);
2768     return 0;
2769 }
2770
2771 /* called for #overview or for end of game disclosure */
2772 void
2773 show_overview(why, reason)
2774 int why;    /* 0 => #overview command,
2775                1 or 2 => final disclosure (1: hero lived, 2: hero died) */
2776 int reason; /* how hero died; used when disclosing end-of-game level */
2777 {
2778     winid win;
2779     int lastdun = -1;
2780
2781     /* lazy initialization */
2782     (void) recalc_mapseen();
2783
2784     win = create_nhwindow(NHW_MENU);
2785     /* show the endgame levels before the rest of the dungeon,
2786        so that the Planes (dnum 5-ish) come out above main dungeon (dnum 0) */
2787     if (In_endgame(&u.uz))
2788         traverse_mapseenchn(TRUE, win, why, reason, &lastdun);
2789     /* if game is over or we're not in the endgame yet, show the dungeon */
2790     if (why > 0 || !In_endgame(&u.uz))
2791         traverse_mapseenchn(FALSE, win, why, reason, &lastdun);
2792     display_nhwindow(win, TRUE);
2793     destroy_nhwindow(win);
2794 }
2795
2796 /* display endgame levels or non-endgame levels, not both */
2797 STATIC_OVL void
2798 traverse_mapseenchn(viewendgame, win, why, reason, lastdun_p)
2799 boolean viewendgame;
2800 winid win;
2801 int why, reason, *lastdun_p;
2802 {
2803     mapseen *mptr;
2804     boolean showheader;
2805
2806     for (mptr = mapseenchn; mptr; mptr = mptr->next) {
2807         if (viewendgame ^ In_endgame(&mptr->lev))
2808             continue;
2809
2810         /* only print out info for a level or a dungeon if interest */
2811         if (why > 0 || interest_mapseen(mptr)) {
2812             showheader = (boolean) (mptr->lev.dnum != *lastdun_p);
2813             print_mapseen(win, mptr, why, reason, showheader);
2814             *lastdun_p = mptr->lev.dnum;
2815         }
2816     }
2817 }
2818
2819 STATIC_OVL const char *
2820 seen_string(x, obj)
2821 xchar x;
2822 const char *obj;
2823 {
2824     /* players are computer scientists: 0, 1, 2, n */
2825     switch (x) {
2826     case 0:
2827 /*JP:\82±\82±\82É\82Í\97\88\82È\82¢\82Í\82¸*/
2828         return "no";
2829     /* an() returns too much.  index is ok in this case */
2830     case 1:
2831 /*JP
2832         return index(vowels, *obj) ? "an" : "a";
2833 */
2834         return "";
2835     case 2:
2836 /*JP
2837         return "some";
2838 */
2839         return "\93ñ\82Â\82Ì";
2840     case 3:
2841 /*JP
2842         return "many";
2843 */
2844         return "\91½\82­\82Ì";
2845     }
2846
2847     return "(unknown)";
2848 }
2849
2850 /* better br_string */
2851 STATIC_OVL const char *
2852 br_string2(br)
2853 branch *br;
2854 {
2855     /* Special case: quest portal says closed if kicked from quest */
2856     boolean closed_portal = (br->end2.dnum == quest_dnum
2857                              && u.uevent.qexpelled);
2858
2859     switch (br->type) {
2860     case BR_PORTAL:
2861 /*JP
2862         return closed_portal ? "Sealed portal" : "Portal";
2863 */
2864         return closed_portal ? "\95\95\88ó\82³\82ê\82½\96\82\96@\82Ì\93ü\8cû" : "\96\82\96@\82Ì\93ü\8cû";
2865     case BR_NO_END1:
2866         return "Connection";
2867     case BR_NO_END2:
2868 /*JP
2869         return br->end1_up ? "One way stairs up" : "One way stairs down";
2870 */
2871         return br->end1_up ? "\8fã\82è\95Ð\93¹\8aK\92i" : "\89º\82è\95Ð\93¹\8aK\92i";
2872     case BR_STAIR:
2873 /*JP
2874         return br->end1_up ? "Stairs up" : "Stairs down";
2875 */
2876         return br->end1_up ? "\8fã\82è\8aK\92i" : "\89º\82è\8aK\92i";
2877     }
2878
2879     return "(unknown)";
2880 }
2881
2882 /* get the name of an endgame level; topten.c does something similar */
2883 STATIC_OVL const char *
2884 endgamelevelname(outbuf, indx)
2885 char *outbuf;
2886 int indx;
2887 {
2888     const char *planename = 0;
2889
2890     *outbuf = '\0';
2891     switch (indx) {
2892     case -5:
2893 /*JP
2894         Strcpy(outbuf, "Astral Plane");
2895 */
2896         Strcpy(outbuf, "\93V\8fã\8aE");
2897         break;
2898     case -4:
2899 /*JP
2900         planename = "Water";
2901 */
2902         planename = "\90\85";
2903         break;
2904     case -3:
2905 /*JP
2906         planename = "Fire";
2907 */
2908         planename = "\89Î";
2909         break;
2910     case -2:
2911 /*JP
2912         planename = "Air";
2913 */
2914         planename = "\95\97";
2915         break;
2916     case -1:
2917 /*JP
2918         planename = "Earth";
2919 */
2920         planename = "\93y";
2921         break;
2922     }
2923     if (planename)
2924 /*JP
2925         Sprintf(outbuf, "Plane of %s", planename);
2926 */
2927         Sprintf(outbuf, "%s\82Ì\90¸\97ì\8aE", planename);
2928     else if (!*outbuf)
2929         Sprintf(outbuf, "unknown plane #%d", indx);
2930     return outbuf;
2931 }
2932
2933 STATIC_OVL const char *
2934 shop_string(rtype)
2935 int rtype;
2936 {
2937 #if 0 /*JP*/
2938     const char *str = "shop"; /* catchall */
2939 #else
2940     const char *str = "\93X"; /* catchall */
2941 #endif
2942
2943     /* Yuck, redundancy...but shclass.name doesn't cut it as a noun */
2944     switch (rtype) {
2945     case SHOPBASE - 1:
2946 /*JP
2947         str = "untended shop";
2948 */
2949         str = "\95ú\8aü\82³\82ê\82½\93X";
2950         break; /* see recalc_mapseen */
2951     case SHOPBASE:
2952 /*JP
2953         str = "general store";
2954 */
2955         str = "\8eG\89Ý\93X";
2956         break;
2957     case ARMORSHOP:
2958 /*JP
2959         str = "armor shop";
2960 */
2961         str = "\96h\8bï\93X";
2962         break;
2963     case SCROLLSHOP:
2964 /*JP
2965         str = "scroll shop";
2966 */
2967         str = "\8aª\95¨\93X";
2968         break;
2969     case POTIONSHOP:
2970 /*JP
2971         str = "potion shop";
2972 */
2973         str = "\96ò\93X";
2974         break;
2975     case WEAPONSHOP:
2976 /*JP
2977         str = "weapon shop";
2978 */
2979         str = "\95\90\8aí\93X";
2980         break;
2981     case FOODSHOP:
2982 /*JP
2983         str = "delicatessen";
2984 */
2985         str = "\90H\97¿\95i\93X";
2986         break;
2987     case RINGSHOP:
2988 /*JP
2989         str = "jewelers";
2990 */
2991         str = "\95ó\90Î\93X";
2992         break;
2993     case WANDSHOP:
2994 /*JP
2995         str = "wand shop";
2996 */
2997         str = "\8fñ\93X";
2998         break;
2999     case BOOKSHOP:
3000 /*JP
3001         str = "bookstore";
3002 */
3003         str = "\8f\91\93X";
3004         break;
3005     case FODDERSHOP:
3006 /*JP
3007         str = "health food store";
3008 */
3009         str = "\8c\92\8dN\90H\95i\93X";
3010         break;
3011     case CANDLESHOP:
3012 /*JP
3013         str = "lighting shop";
3014 */
3015         str = "\8fÆ\96¾\93X";
3016         break;
3017     default:
3018         break;
3019     }
3020     return str;
3021 }
3022
3023 /* if player knows about the mastermind tune, append it to Castle annotation;
3024    if drawbridge has been destroyed, flags.castletune will be zero */
3025 STATIC_OVL char *
3026 tunesuffix(mptr, outbuf)
3027 mapseen *mptr;
3028 char *outbuf;
3029 {
3030     *outbuf = '\0';
3031     if (mptr->flags.castletune && u.uevent.uheard_tune) {
3032         char tmp[BUFSZ];
3033
3034         if (u.uevent.uheard_tune == 2)
3035             Sprintf(tmp, "notes \"%s\"", tune);
3036         else
3037             Strcpy(tmp, "5-note tune");
3038         Sprintf(outbuf, " (play %s to open or close drawbridge)", tmp);
3039     }
3040     return outbuf;
3041 }
3042
3043 /* some utility macros for print_mapseen */
3044 #define TAB "   " /* three spaces */
3045 #if 0
3046 #define BULLET "" /* empty; otherwise output becomes cluttered */
3047 #define PREFIX TAB TAB BULLET
3048 #else                   /*!0*/
3049 /* K&R: don't require support for concatenation of adjacent string literals */
3050 #define PREFIX "      " /* two TABs + empty BULLET: six spaces */
3051 #endif
3052 #define COMMA (i++ > 0 ? ", " : PREFIX)
3053 /* "iterate" once; safe to use as ``if (cond) ADDTOBUF(); else whatever;'' */
3054 #if 0 /*JP*/
3055 #define ADDNTOBUF(nam, var)                                                  \
3056     do {                                                                     \
3057         if (var)                                                             \
3058             Sprintf(eos(buf), "%s%s %s%s", COMMA, seen_string((var), (nam)), \
3059                     (nam), plur(var));                                       \
3060     } while (0)
3061 #else
3062 #define ADDNTOBUF(nam, var)                                                  \
3063     do {                                                                     \
3064         if (var)                                                             \
3065             Sprintf(eos(buf), "%s%s%s", COMMA, seen_string((var), (nam)),    \
3066                     (nam));                                                  \
3067     } while (0)
3068 #endif
3069 #define ADDTOBUF(nam, var)                           \
3070     do {                                             \
3071         if (var)                                     \
3072             Sprintf(eos(buf), "%s%s", COMMA, (nam)); \
3073     } while (0)
3074
3075 STATIC_OVL void
3076 print_mapseen(win, mptr, final, how, printdun)
3077 winid win;
3078 mapseen *mptr;
3079 int final; /* 0: not final; 1: game over, alive; 2: game over, dead */
3080 int how;   /* cause of death; only used if final==2 and mptr->lev==u.uz */
3081 boolean printdun;
3082 {
3083     char buf[BUFSZ], tmpbuf[BUFSZ];
3084     int i, depthstart, dnum;
3085     boolean died_here = (final == 2 && on_level(&u.uz, &mptr->lev));
3086
3087     /* Damnable special cases */
3088     /* The quest and knox should appear to be level 1 to match
3089      * other text.
3090      */
3091     dnum = mptr->lev.dnum;
3092     if (dnum == quest_dnum || dnum == knox_level.dnum)
3093         depthstart = 1;
3094     else
3095         depthstart = dungeons[dnum].depth_start;
3096
3097     if (printdun) {
3098         if (dungeons[dnum].dunlev_ureached == dungeons[dnum].entry_lev
3099             /* suppress the negative numbers in the endgame */
3100             || In_endgame(&mptr->lev))
3101             Sprintf(buf, "%s:", dungeons[dnum].dname);
3102         else if (builds_up(&mptr->lev))
3103 /*JP
3104             Sprintf(buf, "%s: levels %d up to %d",
3105 */
3106             Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
3107                     dungeons[dnum].dname,
3108                     depthstart + dungeons[dnum].entry_lev - 1,
3109                     depthstart + dungeons[dnum].dunlev_ureached - 1);
3110         else
3111 /*JP
3112             Sprintf(buf, "%s: levels %d to %d",
3113 */
3114             Sprintf(buf, "%s: %d\8aK\82©\82ç%d\8aK",
3115                     dungeons[dnum].dname, depthstart,
3116                     depthstart + dungeons[dnum].dunlev_ureached - 1);
3117         putstr(win, !final ? ATR_INVERSE : 0, buf);
3118     }
3119
3120     /* calculate level number */
3121     i = depthstart + mptr->lev.dlevel - 1;
3122     if (In_endgame(&mptr->lev))
3123         Sprintf(buf, "%s%s:", TAB, endgamelevelname(tmpbuf, i));
3124     else
3125 /*JP
3126         Sprintf(buf, "%sLevel %d:", TAB, i);
3127 */
3128         Sprintf(buf, "%s%d\8aK:", TAB, i);
3129
3130     /* wizmode prints out proto dungeon names for clarity */
3131     if (wizard) {
3132         s_level *slev;
3133
3134         if ((slev = Is_special(&mptr->lev)) != 0)
3135             Sprintf(eos(buf), " [%s]", slev->proto);
3136     }
3137     /* [perhaps print custom annotation on its own line when it's long] */
3138     if (mptr->custom)
3139         Sprintf(eos(buf), " \"%s\"", mptr->custom);
3140     if (on_level(&u.uz, &mptr->lev))
3141 #if 0 /*JP*/
3142         Sprintf(eos(buf), " <- You %s here.",
3143                 (!final || (final == 1 && how == ASCENDED)) ? "are"
3144                   : (final == 1 && how == ESCAPED) ? "left from"
3145                     : "were");
3146 #else
3147         Sprintf(eos(buf), " <- \82±\82±%s\81D",
3148                 (!final || (final == 1 && how == ASCENDED)) ? "\82É\82¢\82é"
3149                   : (final == 1 && how == ESCAPED) ? "\82©\82ç\94²\82¯\82½"
3150                     : "\82É\82¢\82½");
3151 #endif
3152     putstr(win, !final ? ATR_BOLD : 0, buf);
3153
3154     if (mptr->flags.forgot)
3155         return;
3156
3157     if (INTEREST(mptr->feat)) {
3158         buf[0] = 0;
3159
3160         i = 0; /* interest counter */
3161         /* List interests in an order vaguely corresponding to
3162          * how important they are.
3163          */
3164         if (mptr->feat.nshop > 0) {
3165             if (mptr->feat.nshop > 1)
3166 /*JP
3167                 ADDNTOBUF("shop", mptr->feat.nshop);
3168 */
3169                 ADDNTOBUF("\93X", mptr->feat.nshop);
3170             else
3171                 Sprintf(eos(buf), "%s%s", COMMA,
3172                         an(shop_string(mptr->feat.shoptype)));
3173         }
3174         if (mptr->feat.naltar > 0) {
3175             /* Temples + non-temple altars get munged into just "altars" */
3176             if (mptr->feat.ntemple != mptr->feat.naltar)
3177 /*JP
3178                 ADDNTOBUF("altar", mptr->feat.naltar);
3179 */
3180                 ADDNTOBUF("\8dÕ\92d", mptr->feat.naltar);
3181             else
3182 /*JP
3183                 ADDNTOBUF("temple", mptr->feat.ntemple);
3184 */
3185                 ADDNTOBUF("\8e\9b\89@", mptr->feat.ntemple);
3186
3187             /* only print out altar's god if they are all to your god */
3188             if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
3189 /*JP
3190                 Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
3191 */
3192                 Sprintf(eos(buf), "(%s)", align_gname(u.ualign.type));
3193         }
3194 /*JP
3195         ADDNTOBUF("throne", mptr->feat.nthrone);
3196 */
3197         ADDNTOBUF("\8bÊ\8dÀ", mptr->feat.nthrone);
3198 /*JP
3199         ADDNTOBUF("fountain", mptr->feat.nfount);
3200 */
3201         ADDNTOBUF("\90ò", mptr->feat.nfount);
3202 /*JP
3203         ADDNTOBUF("sink", mptr->feat.nsink);
3204 */
3205         ADDNTOBUF("\97¬\82µ\91ä", mptr->feat.nsink);
3206 /*JP
3207         ADDNTOBUF("grave", mptr->feat.ngrave);
3208 */
3209         ADDNTOBUF("\95æ", mptr->feat.ngrave);
3210 /*JP
3211         ADDNTOBUF("tree", mptr->feat.ntree);
3212 */
3213         ADDNTOBUF("\96Ø", mptr->feat.ntree);
3214 #if 0
3215         ADDTOBUF("water", mptr->feat.water);
3216         ADDTOBUF("lava", mptr->feat.lava);
3217         ADDTOBUF("ice", mptr->feat.ice);
3218 #endif
3219         /* capitalize afterwards */
3220         i = strlen(PREFIX);
3221         buf[i] = highc(buf[i]);
3222         /* capitalizing it makes it a sentence; terminate with '.' */
3223         Strcat(buf, ".");
3224         putstr(win, 0, buf);
3225     }
3226
3227     /* we assume that these are mutually exclusive */
3228     *buf = '\0';
3229     if (mptr->flags.oracle) {
3230 /*JP
3231         Sprintf(buf, "%sOracle of Delphi.", PREFIX);
3232 */
3233         Sprintf(buf, "%s\83f\83\8b\83t\83@\83C\82Ì\90_\93a\81D", PREFIX);
3234     } else if (In_sokoban(&mptr->lev)) {
3235 #if 0 /*JP*/
3236         Sprintf(buf, "%s%s.", PREFIX,
3237                 mptr->flags.sokosolved ? "Solved" : "Unsolved");
3238 #else
3239         Sprintf(buf, "%s%s.", PREFIX,
3240                 mptr->flags.sokosolved ? "\83N\83\8a\83A\8dÏ" : "\96¢\83N\83\8a\83A");
3241 #endif
3242     } else if (mptr->flags.bigroom) {
3243 /*JP
3244         Sprintf(buf, "%sA very big room.", PREFIX);
3245 */
3246         Sprintf(buf, "%s\82Æ\82Ä\82à\91å\82«\82¢\95\94\89®\81D", PREFIX);
3247     } else if (mptr->flags.roguelevel) {
3248 /*JP
3249         Sprintf(buf, "%sA primitive area.", PREFIX);
3250 */
3251         Sprintf(buf, "%s\92P\8f\83\82È\95\94\89®\81D", PREFIX);
3252     } else if (on_level(&mptr->lev, &qstart_level)) {
3253 #if 0 /*JP*/
3254         Sprintf(buf, "%sHome%s.", PREFIX,
3255                 mptr->flags.unreachable ? " (no way back...)" : "");
3256 #else
3257         Sprintf(buf, "%s\8cÌ\8b½%s\81D", PREFIX,
3258                 mptr->flags.unreachable ? "(\96ß\82ê\82È\82¢\81D\81D\81D)" : "");
3259 #endif
3260         if (u.uevent.qcompleted)
3261 /*JP
3262             Sprintf(buf, "%sCompleted quest for %s.", PREFIX, ldrname());
3263 */
3264             Sprintf(buf, "%s%s\82Ì\82½\82ß\82É\83N\83G\83X\83g\82ð\8a®\90\8b\82µ\82½\81D", PREFIX, ldrname());
3265         else if (mptr->flags.questing)
3266 /*JP
3267             Sprintf(buf, "%sGiven quest by %s.", PREFIX, ldrname());
3268 */
3269             Sprintf(buf, "%s%s\82©\82ç\83N\83G\83X\83g\82ð\97^\82¦\82ç\82ê\82½\81D", PREFIX, ldrname());
3270     } else if (mptr->flags.ludios) {
3271         /* presence of the ludios branch in #overview output indicates that
3272            the player has made it onto the level; presence of this annotation
3273            indicates that the fort's entrance has been seen (or mapped) */
3274 /*JP
3275         Sprintf(buf, "%sFort Ludios.", PREFIX);
3276 */
3277         Sprintf(buf, "%s\83\8d\81[\83f\83B\83I\83X\8dÔ\81D", PREFIX);
3278     } else if (mptr->flags.castle) {
3279 /*JP
3280         Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf));
3281 */
3282         Sprintf(buf, "%s\8fé%s\81D", PREFIX, tunesuffix(mptr, tmpbuf));
3283     } else if (mptr->flags.valley) {
3284 /*JP
3285         Sprintf(buf, "%sValley of the Dead.", PREFIX);
3286 */
3287         Sprintf(buf, "%s\8e\80\82Ì\92J\81D", PREFIX);
3288     } else if (mptr->flags.msanctum) {
3289 /*JP
3290         Sprintf(buf, "%sMoloch's Sanctum.", PREFIX);
3291 */
3292         Sprintf(buf, "%s\83\82\81[\83\8d\83b\83N\82Ì\90¹\88æ\81D", PREFIX);
3293     }
3294     if (*buf)
3295         putstr(win, 0, buf);
3296     /* quest entrance is not mutually-exclusive with bigroom or rogue level */
3297     if (mptr->flags.quest_summons) {
3298 /*JP
3299         Sprintf(buf, "%sSummoned by %s.", PREFIX, ldrname());
3300 */
3301         Sprintf(buf, "%s%s\82©\82ç\8cÄ\82Ñ\8fo\82³\82ê\82½\81D", PREFIX, ldrname());
3302         putstr(win, 0, buf);
3303     }
3304
3305     /* print out branches */
3306     if (mptr->br) {
3307 #if 0 /*JP*/
3308         Sprintf(buf, "%s%s to %s", PREFIX, br_string2(mptr->br),
3309                 dungeons[mptr->br->end2.dnum].dname);
3310 #else
3311         Sprintf(buf, "%s%s\82Ö\82Ì%s", PREFIX, dungeons[mptr->br->end2.dnum].dname,
3312                 br_string2(mptr->br));
3313 #endif
3314
3315         /* Since mapseen objects are printed out in increasing order
3316          * of dlevel, clarify which level this branch is going to
3317          * if the branch goes upwards.  Unless it's the end game.
3318          */
3319         if (mptr->br->end1_up && !In_endgame(&(mptr->br->end2)))
3320 /*JP
3321             Sprintf(eos(buf), ", level %d", depth(&(mptr->br->end2)));
3322 */
3323             Sprintf(eos(buf), ", %d\8aK", depth(&(mptr->br->end2)));
3324         Strcat(buf, ".");
3325         putstr(win, 0, buf);
3326     }
3327
3328     /* maybe print out bones details */
3329     if (mptr->final_resting_place || final) {
3330         struct cemetery *bp;
3331         int kncnt = !died_here ? 0 : 1;
3332
3333         for (bp = mptr->final_resting_place; bp; bp = bp->next)
3334             if (bp->bonesknown || wizard || final)
3335                 ++kncnt;
3336         if (kncnt) {
3337 /*JP
3338             Sprintf(buf, "%s%s", PREFIX, "Final resting place for");
3339 */
3340             Sprintf(buf, "%s%s", PREFIX, "\8dÅ\8aú\82Ì\92n:");
3341             putstr(win, 0, buf);
3342             if (died_here) {
3343                 /* disclosure occurs before bones creation, so listing dead
3344                    hero here doesn't give away whether bones are produced */
3345                 formatkiller(tmpbuf, sizeof tmpbuf, how, TRUE);
3346 #if 0 /*JP*/
3347                 /* rephrase a few death reasons to work with "you" */
3348                 (void) strsubst(tmpbuf, " himself", " yourself");
3349                 (void) strsubst(tmpbuf, " herself", " yourself");
3350                 (void) strsubst(tmpbuf, " his ", " your ");
3351                 (void) strsubst(tmpbuf, " her ", " your ");
3352 #endif
3353 #if 0 /*JP*/
3354                 Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf,
3355                         --kncnt ? ',' : '.');
3356 #else
3357                 Sprintf(buf, "%s%s     %s%c", PREFIX, TAB, tmpbuf,
3358                         --kncnt ? ',' : '.');
3359 #endif
3360                 putstr(win, 0, buf);
3361             }
3362             for (bp = mptr->final_resting_place; bp; bp = bp->next) {
3363                 if (bp->bonesknown || wizard || final) {
3364                     Sprintf(buf, "%s%s%s, %s%c", PREFIX, TAB, bp->who,
3365                             bp->how, --kncnt ? ',' : '.');
3366                     putstr(win, 0, buf);
3367                 }
3368             }
3369         }
3370     }
3371 }
3372
3373 /*dungeon.c*/