OSDN Git Service

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