1 /* NetHack 3.6 rm.h $NHDT-Date: 1573943499 2019/11/16 22:31:39 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.66 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Pasi Kallinen, 2017. */
4 /* NetHack may be freely redistributed. See license for details. */
10 * The dungeon presentation graphics code and data structures were rewritten
11 * and generalized for NetHack's release 2 by Eric S. Raymond (eric@snark)
12 * building on Don G. Kneller's MS-DOS implementation. See drawing.c for
13 * the code that permits the user to set the contents of the symbol structure.
15 * The door representation was changed by Ari
16 * Huttunen(ahuttune@niksula.hut.fi)
20 * TLCORNER TDWALL TRCORNER
24 * TRWALL CROSSWALL TLWALL HWALL
29 * BLCORNER TUWALL BRCORNER VWALL
34 /* Level location types. [Some debugging code in src/display.c
35 defines array type_names[] which contains an entry for each of
36 these, so needs to be kept in sync if any new types are added
37 or existing ones renumbered.] */
46 CROSSWALL = 7, /* For pretty mazes and special levels */
56 MOAT = 17, /* pool that doesn't boil, adjust messages */
60 IRONBARS = 21, /* KMH */
81 * Avoid using the level types in inequalities:
82 * these types are subject to change.
83 * Instead, use one of the macros below.
85 #define IS_WALL(typ) ((typ) && (typ) <= DBWALL)
86 #define IS_STWALL(typ) ((typ) <= DBWALL) /* STONE <= (typ) <= DBWALL */
87 #define IS_ROCK(typ) ((typ) < POOL) /* absolutely nonaccessible */
88 #define IS_DOOR(typ) ((typ) == DOOR)
89 #define IS_DOORJOIN(typ) (IS_ROCK(typ) || (typ) == IRONBARS)
90 #define IS_TREE(typ) \
91 ((typ) == TREE || (level.flags.arboreal && (typ) == STONE))
92 #define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */
93 #define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM, STAIRS, furniture.. */
94 #define ZAP_POS(typ) ((typ) >= POOL)
95 #define SPACE_POS(typ) ((typ) > DOOR)
96 #define IS_POOL(typ) ((typ) >= POOL && (typ) <= DRAWBRIDGE_UP)
97 #define IS_THRONE(typ) ((typ) == THRONE)
98 #define IS_FOUNTAIN(typ) ((typ) == FOUNTAIN)
99 #define IS_SINK(typ) ((typ) == SINK)
100 #define IS_GRAVE(typ) ((typ) == GRAVE)
101 #define IS_ALTAR(typ) ((typ) == ALTAR)
102 #define IS_DRAWBRIDGE(typ) \
103 ((typ) == DRAWBRIDGE_UP || (typ) == DRAWBRIDGE_DOWN)
104 #define IS_FURNITURE(typ) ((typ) >= STAIRS && (typ) <= ALTAR)
105 #define IS_AIR(typ) ((typ) == AIR || (typ) == CLOUD)
106 #define IS_SOFT(typ) ((typ) == AIR || (typ) == CLOUD || IS_POOL(typ))
109 * The screen symbols may be the default or defined at game startup time.
110 * See drawing.c for defaults.
111 * Note: {ibm|dec|curses}_graphics[] arrays (also in drawing.c) must be kept in
115 /* begin dungeon characters */
116 enum screen_symbols {
132 S_vcdoor = 15, /* closed door, vertical wall */
133 S_hcdoor = 16, /* closed door, horizontal wall */
134 S_bars = 17, /* KMH -- iron bars */
135 S_tree = 18, /* KMH */
154 S_vcdbridge = 37, /* closed drawbridge, vertical wall */
155 S_hcdbridge = 38, /* closed drawbridge, horizontal wall */
160 /* end dungeon characters, begin traps */
164 S_falling_rock_trap = 44,
165 S_squeaky_board = 45,
168 S_rolling_boulder_trap = 48,
169 S_sleeping_gas_trap = 49,
176 S_teleportation_trap = 56,
177 S_level_teleporter = 57,
182 S_anti_magic_trap = 62,
183 S_polymorph_trap = 63,
184 S_vibrating_square = 64, /* for display rather than any trap effect */
186 /* end traps, begin special effects */
188 S_vbeam = 65, /* The 4 zap beam symbols. Do NOT separate. */
189 S_hbeam = 66, /* To change order or add, see function */
190 S_lslant = 67, /* zapdir_to_glyph() in display.c. */
192 S_digbeam = 69, /* dig beam symbol */
193 S_flashbeam = 70, /* camera flash symbol */
194 S_boomleft = 71, /* thrown boomerang, open left, e.g ')' */
195 S_boomright = 72, /* thrown boomerang, open right, e.g. '(' */
196 S_ss1 = 73, /* 4 magic shield ("resistance sparkle") glyphs */
201 S_goodpos = 78, /* valid position for targeting via getpos() */
203 /* The 8 swallow symbols. Do NOT separate. To change order or add, */
204 /* see the function swallow_to_glyph() in display.c. */
205 S_sw_tl = 79, /* swallow top left [1] */
206 S_sw_tc = 80, /* swallow top center [2] Order: */
207 S_sw_tr = 81, /* swallow top right [3] */
208 S_sw_ml = 82, /* swallow middle left [4] 1 2 3 */
209 S_sw_mr = 83, /* swallow middle right [6] 4 5 6 */
210 S_sw_bl = 84, /* swallow bottom left [7] 7 8 9 */
211 S_sw_bc = 85, /* swallow bottom center [8] */
212 S_sw_br = 86, /* swallow bottom right [9] */
214 S_explode1 = 87, /* explosion top left */
215 S_explode2 = 88, /* explosion top center */
216 S_explode3 = 89, /* explosion top right Ex. */
217 S_explode4 = 90, /* explosion middle left */
218 S_explode5 = 91, /* explosion middle center /-\ */
219 S_explode6 = 92, /* explosion middle right |@| */
220 S_explode7 = 93, /* explosion bottom left \-/ */
221 S_explode8 = 94, /* explosion bottom center */
222 S_explode9 = 95, /* explosion bottom right */
226 MAXPCHARS = 96 /* maximum number of mapped characters */
229 #define MAXDCHARS (S_water - S_stone + 1) /* mapped dungeon characters */
230 #define MAXTCHARS (S_vibrating_square - S_arrow_trap + 1) /* trap chars */
231 #define MAXECHARS (S_explode9 - S_vbeam + 1) /* mapped effects characters */
232 #define MAXEXPCHARS 9 /* number of explosion characters */
234 #define DARKROOMSYM (Is_rogue_level(&u.uz) ? S_stone : S_darkroom)
236 #define is_cmap_trap(i) ((i) >= S_arrow_trap && (i) <= S_polymorph_trap)
237 #define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge)
238 #define is_cmap_door(i) ((i) >= S_vodoor && (i) <= S_hcdoor)
239 #define is_cmap_wall(i) ((i) >= S_stone && (i) <= S_trwall)
240 #define is_cmap_room(i) ((i) >= S_room && (i) <= S_darkroom)
241 #define is_cmap_corr(i) ((i) >= S_corr && (i) <= S_litcorr)
242 #define is_cmap_furniture(i) ((i) >= S_upstair && (i) <= S_fountain)
243 #define is_cmap_water(i) ((i) == S_pool || (i) == S_water)
244 #define is_cmap_lava(i) ((i) == S_lava)
249 const char *explanation;
257 #define SYM_CONTROL 1 /* start/finish markers */
258 #define SYM_PCHAR 2 /* index into showsyms */
259 #define SYM_OC 3 /* index into oc_syms */
260 #define SYM_MON 4 /* index into monsyms */
261 #define SYM_OTH 5 /* misc */
266 /* misc symbol definitions */
267 #define SYM_BOULDER 0
268 #define SYM_INVISIBLE 1
269 #define SYM_PET_OVERRIDE 2
270 #define SYM_HERO_OVERRIDE 3
273 /* linked list of symsets and their characteristics */
275 struct symsetentry *next; /* next in list */
276 char *name; /* ptr to symset name */
277 char *desc; /* ptr to description */
278 int idx; /* an index value */
279 int handling; /* known handlers value */
280 Bitfield(nocolor, 1); /* don't use color if set */
281 Bitfield(primary, 1); /* restricted for use as primary set */
282 Bitfield(rogue, 1); /* restricted for use as rogue lev set */
283 Bitfield(explicitly, 1); /* explicit symset set */
288 * Graphics sets for display symbols
290 #define DEFAULT_GRAPHICS 0 /* regular characters: '-', '+', &c */
291 #define PRIMARY 0 /* primary graphics set */
292 #define ROGUESET 1 /* rogue graphics set */
293 #define NUM_GRAPHICS 2
296 * special symbol set handling types ( for invoking callbacks, etc.)
297 * Must match the order of the known_handlers strings
304 #define H_MAC 4 /* obsolete; needed so that the listing of available
305 * symsets by 'O' can skip it for !MAC_GRAPHICS_ENV */
307 extern const struct symdef defsyms[MAXPCHARS]; /* defaults */
308 extern const struct symdef def_warnsyms[WARNCOUNT];
309 extern int currentgraphics; /* from drawing.c */
310 extern nhsym showsyms[];
311 extern nhsym primary_syms[];
312 extern nhsym rogue_syms[];
313 extern nhsym ov_primary_syms[];
314 extern nhsym ov_rogue_syms[];
316 extern struct symsetentry symset[NUM_GRAPHICS]; /* from drawing.c */
317 #define SYMHANDLING(ht) (symset[currentgraphics].handling == (ht))
320 * The 5 possible states of doors
329 #define D_SECRET 32 /* only used by sp_lev.c, NOT in rm-struct */
332 * Some altars are considered as shrines, so we need a flag.
337 * Thrones should only be looted once.
342 * Trees have more than one kick result.
344 #define TREE_LOOTED 1
348 * Fountains have limits, and special warnings.
352 #define FOUNTAIN_IS_WARNED(x, y) (levl[x][y].looted & F_WARNED)
353 #define FOUNTAIN_IS_LOOTED(x, y) (levl[x][y].looted & F_LOOTED)
354 #define SET_FOUNTAIN_WARNED(x, y) levl[x][y].looted |= F_WARNED;
355 #define SET_FOUNTAIN_LOOTED(x, y) levl[x][y].looted |= F_LOOTED;
356 #define CLEAR_FOUNTAIN_WARNED(x, y) levl[x][y].looted &= ~F_WARNED;
357 #define CLEAR_FOUNTAIN_LOOTED(x, y) levl[x][y].looted &= ~F_LOOTED;
360 * Doors are even worse :-) The special warning has a side effect
361 * of instantly trapping the door, and if it was defined as trapped,
362 * the guards consider that you have already been warned!
367 * Sinks have 3 different types of loot that shouldn't be abused
374 * The four directions for a DrawBridge.
380 #define DB_DIR 3 /* mask for direction */
383 * What's under a drawbridge.
389 #define DB_UNDER 28 /* mask for underneath */
392 * Wall information. Nondiggable also applies to iron bars.
394 #define WM_MASK 0x07 /* wall mode (bottom three bits) */
395 #define W_NONDIGGABLE 0x08
396 #define W_NONPASSWALL 0x10
399 * Ladders (in Vlad's tower) may be up or down.
405 * Room areas may be iced pools
411 * The structure describing a coordinate position.
412 * Before adding fields, remember that this will significantly affect
413 * the size of temporary files and save files.
415 * Also remember that the run-length encoding for some ports in save.c
416 * must be updated to consider the field.
419 int glyph; /* what the hero thinks is there */
420 schar typ; /* what is really there */
421 uchar seenv; /* seen vector */
422 Bitfield(flags, 5); /* extra information for typ */
423 Bitfield(horizontal, 1); /* wall/door/etc is horiz. (more typ info) */
424 Bitfield(lit, 1); /* speed hack for lit rooms */
425 Bitfield(waslit, 1); /* remember if a location was lit */
427 Bitfield(roomno, 6); /* room # for special rooms */
428 Bitfield(edge, 1); /* marks boundaries for special rooms*/
429 Bitfield(candig, 1); /* Exception to Can_dig_down; was a trapdoor */
432 #define SET_TYPLIT(x, y, ttyp, llit) \
434 if ((x) >= 0 && (y) >= 0 && (x) < COLNO && (y) < ROWNO) { \
435 if ((ttyp) < MAX_TYPE) \
436 levl[(x)][(y)].typ = (ttyp); \
437 if ((ttyp) == LAVAPOOL) \
438 levl[(x)][(y)].lit = 1; \
439 else if ((schar)(llit) != -2) { \
440 if ((schar)(llit) == -1) \
441 levl[(x)][(y)].lit = rn2(2); \
443 levl[(x)][(y)].lit = (llit); \
449 * Add wall angle viewing by defining "modes" for each wall type. Each
450 * mode describes which parts of a wall are finished (seen as as wall)
451 * and which are unfinished (seen as rock).
453 * We use the bottom 3 bits of the flags field for the mode. This comes
454 * in conflict with secret doors, but we avoid problems because until
455 * a secret door becomes discovered, we know what sdoor's bottom three
458 * The following should cover all of the cases.
460 * type mode Examples: R=rock, F=finished
461 * ----- ---- ----------------------------
462 * WALL: 0 none hwall, mode 1
463 * 1 left/top (1/2 rock) RRR
464 * 2 right/bottom (1/2 rock) ---
467 * CORNER: 0 none trcorn, mode 2
468 * 1 outer (3/4 rock) FFF
469 * 2 inner (1/4 rock) F+-
472 * TWALL: 0 none tlwall, mode 3
473 * 1 long edge (1/2 rock) F|F
474 * 2 bottom left (on a tdwall) -+F
475 * 3 bottom right (on a tdwall) R|F
477 * CRWALL: 0 none crwall, mode 5
478 * 1 top left (1/4 rock) R|F
479 * 2 top right (1/4 rock) -+-
480 * 3 bottom left (1/4 rock) F|R
481 * 4 bottom right (1/4 rock)
482 * 5 top left & bottom right (1/2 rock)
483 * 6 bottom left & top right (1/2 rock)
486 #define WM_W_LEFT 1 /* vertical or horizontal wall */
488 #define WM_W_TOP WM_W_LEFT
489 #define WM_W_BOTTOM WM_W_RIGHT
491 #define WM_C_OUTER 1 /* corner wall */
494 #define WM_T_LONG 1 /* T wall */
498 #define WM_X_TL 1 /* cross wall */
506 * Seen vector values. The seen vector is an array of 8 bits, one for each
507 * octant around a given center x:
513 * In the case of walls, a single wall square can be viewed from 8 possible
514 * directions. If we know the type of wall and the directions from which
515 * it has been seen, then we can determine what it looks like to the hero.
527 #define doormask flags
528 #define altarmask flags
529 #define wall_info flags
531 #define drawbridgemask flags
533 #define icedpool flags
535 #define blessedftn horizontal /* a fountain that grants attribs */
536 #define disturbed horizontal /* a grave that has been disturbed */
545 /* for bones levels: identify the dead character, who might have died on
546 an existing bones level; if so, most recent victim will be first in list */
548 struct cemetery *next; /* next struct is previous dead character... */
549 /* "plname" + "-ROLe" + "-RACe" + "-GENder" + "-ALIgnment" + \0 */
550 char who[PL_NSIZ + 4 * (1 + 3) + 1];
551 /* death reason, same as in score/log file */
552 char how[100 + 1]; /* [DTHSZ+1] */
553 /* date+time in string of digits rather than binary */
554 char when[4 + 2 + 2 + 2 + 2 + 2 + 1]; /* "YYYYMMDDhhmmss\0" */
555 /* final resting place spot */
561 uchar nfountains; /* number of fountains on level */
562 uchar nsinks; /* number of sinks on the level */
563 /* Several flags that give hints about what's on the level */
564 Bitfield(has_shop, 1);
565 Bitfield(has_vault, 1);
566 Bitfield(has_zoo, 1);
567 Bitfield(has_court, 1);
568 Bitfield(has_morgue, 1);
569 Bitfield(has_beehive, 1);
570 Bitfield(has_barracks, 1);
571 Bitfield(has_temple, 1);
573 Bitfield(has_swamp, 1);
574 Bitfield(noteleport, 1);
575 Bitfield(hardfloor, 1);
577 Bitfield(hero_memory, 1); /* hero has memory */
578 Bitfield(shortsighted, 1); /* monsters are shortsighted */
579 Bitfield(graveyard, 1); /* has_morgue, but remains set */
580 Bitfield(sokoban_rules, 1); /* fill pits and holes w/ boulders */
582 Bitfield(is_maze_lev, 1);
583 Bitfield(is_cavernous_lev, 1);
584 Bitfield(arboreal, 1); /* Trees replace rock */
585 Bitfield(wizard_bones, 1); /* set if level came from a bones file
586 which was created in wizard mode (or
587 normal mode descendant of such) */
588 Bitfield(corrmaze, 1); /* Whether corridors are used for the maze
593 struct rm locations[COLNO][ROWNO];
594 #ifndef MICROPORT_BUG
595 struct obj *objects[COLNO][ROWNO];
596 struct monst *monsters[COLNO][ROWNO];
598 struct obj *objects[1][ROWNO];
599 char *yuk1[COLNO - 1][ROWNO];
600 struct monst *monsters[1][ROWNO];
601 char *yuk2[COLNO - 1][ROWNO];
604 struct obj *buriedobjlist;
605 struct monst *monlist;
606 struct damage *damagelist;
607 struct cemetery *bonesinfo;
608 struct levelflags flags;
611 extern schar lastseentyp[COLNO][ROWNO]; /* last seen/touched dungeon typ */
613 extern dlevel_t level; /* structure describing the current level */
616 * Macros for compatibility with old code. Someday these will go away.
618 #define levl level.locations
619 #define fobj level.objlist
620 #define fmon level.monlist
623 * Covert a trap number into the defsym graphics array.
624 * Convert a defsym number into a trap number.
625 * Assumes that arrow trap will always be the first trap.
627 #define trap_to_defsym(t) (S_arrow_trap + (t) -1)
628 #define defsym_to_trap(d) ((d) -S_arrow_trap + 1)
630 #define OBJ_AT(x, y) (level.objects[x][y] != (struct obj *) 0)
632 * Macros for encapsulation of level.monsters references.
635 #define MON_AT(x, y) \
636 (level.monsters[x][y] != (struct monst *) 0 \
637 && !(level.monsters[x][y])->mburied)
638 #define MON_BURIED_AT(x, y) \
639 (level.monsters[x][y] != (struct monst *) 0 \
640 && (level.monsters[x][y])->mburied)
641 #else /* without 'mburied' */
642 #define MON_AT(x, y) (level.monsters[x][y] != (struct monst *) 0)
644 #ifdef EXTRA_SANITY_CHECKS
645 #define place_worm_seg(m, x, y) \
647 if (level.monsters[x][y] && level.monsters[x][y] != m) \
648 impossible("place_worm_seg over mon"); \
649 level.monsters[x][y] = m; \
651 #define remove_monster(x, y) \
653 if (!level.monsters[x][y]) \
654 impossible("no monster to remove"); \
655 level.monsters[x][y] = (struct monst *) 0; \
658 #define place_worm_seg(m, x, y) level.monsters[x][y] = m
659 #define remove_monster(x, y) level.monsters[x][y] = (struct monst *) 0
661 #define m_at(x, y) (MON_AT(x, y) ? level.monsters[x][y] : (struct monst *) 0)
662 #define m_buried_at(x, y) \
663 (MON_BURIED_AT(x, y) ? level.monsters[x][y] : (struct monst *) 0)
665 /* restricted movement, potential luck penalties */
666 #define Sokoban level.flags.sokoban_rules