OSDN Git Service

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