rm.h

Go to the documentation of this file.
00001 /*      SCCS Id: @(#)rm.h       3.4     1999/12/12      */
00002 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
00003 /* NetHack may be freely redistributed.  See license for details. */
00004 
00005 #ifndef RM_H
00006 #define RM_H
00007 
00008 /*
00009  * The dungeon presentation graphics code and data structures were rewritten
00010  * and generalized for NetHack's release 2 by Eric S. Raymond (eric@snark)
00011  * building on Don G. Kneller's MS-DOS implementation.  See drawing.c for
00012  * the code that permits the user to set the contents of the symbol structure.
00013  *
00014  * The door representation was changed by Ari Huttunen(ahuttune@niksula.hut.fi)
00015  */
00016 
00017 /*
00018  * TLCORNER     TDWALL          TRCORNER
00019  * +-           -+-             -+
00020  * |             |               |
00021  *
00022  * TRWALL       CROSSWALL       TLWALL          HWALL
00023  * |             |               |
00024  * +-           -+-             -+              ---
00025  * |             |               |
00026  *
00027  * BLCORNER     TUWALL          BRCORNER        VWALL
00028  * |             |               |              |
00029  * +-           -+-             -+              |
00030  */
00031 
00032 /* Level location types */
00033 #define STONE           0
00034 #define VWALL           1
00035 #define HWALL           2
00036 #define TLCORNER        3
00037 #define TRCORNER        4
00038 #define BLCORNER        5
00039 #define BRCORNER        6
00040 #define CROSSWALL       7       /* For pretty mazes and special levels */
00041 #define TUWALL          8
00042 #define TDWALL          9
00043 #define TLWALL          10
00044 #define TRWALL          11
00045 #define DBWALL          12
00046 #define TREE            13      /* KMH */
00047 #define SDOOR           14
00048 #define SCORR           15
00049 #define POOL            16
00050 #define MOAT            17      /* pool that doesn't boil, adjust messages */
00051 #define WATER           18
00052 #define DRAWBRIDGE_UP   19
00053 #define LAVAPOOL        20
00054 #define IRONBARS        21      /* KMH */
00055 #define DOOR            22
00056 #define CORR            23
00057 #define ROOM            24
00058 #define STAIRS          25
00059 #define LADDER          26
00060 #define FOUNTAIN        27
00061 #define THRONE          28
00062 #define SINK            29
00063 #define GRAVE           30
00064 #define ALTAR           31
00065 #define ICE             32
00066 #define DRAWBRIDGE_DOWN 33
00067 #define AIR             34
00068 #define CLOUD           35
00069 
00070 #define MAX_TYPE        36
00071 #define INVALID_TYPE    127
00072 
00073 /*
00074  * Avoid using the level types in inequalities:
00075  * these types are subject to change.
00076  * Instead, use one of the macros below.
00077  */
00078 #define IS_WALL(typ)    ((typ) && (typ) <= DBWALL)
00079 #define IS_STWALL(typ)  ((typ) <= DBWALL)       /* STONE <= (typ) <= DBWALL */
00080 #define IS_ROCK(typ)    ((typ) < POOL)          /* absolutely nonaccessible */
00081 #define IS_DOOR(typ)    ((typ) == DOOR)
00082 #define IS_TREE(typ)    ((typ) == TREE || \
00083                         (level.flags.arboreal && (typ) == STONE))
00084 #define ACCESSIBLE(typ) ((typ) >= DOOR)         /* good position */
00085 #define IS_ROOM(typ)    ((typ) >= ROOM)         /* ROOM, STAIRS, furniture.. */
00086 #define ZAP_POS(typ)    ((typ) >= POOL)
00087 #define SPACE_POS(typ)  ((typ) > DOOR)
00088 #define IS_POOL(typ)    ((typ) >= POOL && (typ) <= DRAWBRIDGE_UP)
00089 #define IS_THRONE(typ)  ((typ) == THRONE)
00090 #define IS_FOUNTAIN(typ) ((typ) == FOUNTAIN)
00091 #define IS_SINK(typ)    ((typ) == SINK)
00092 #define IS_GRAVE(typ)   ((typ) == GRAVE)
00093 #define IS_ALTAR(typ)   ((typ) == ALTAR)
00094 #define IS_DRAWBRIDGE(typ) ((typ) == DRAWBRIDGE_UP || (typ) == DRAWBRIDGE_DOWN)
00095 #define IS_FURNITURE(typ) ((typ) >= STAIRS && (typ) <= ALTAR)
00096 #define IS_AIR(typ)     ((typ) == AIR || (typ) == CLOUD)
00097 #define IS_SOFT(typ)    ((typ) == AIR || (typ) == CLOUD || IS_POOL(typ))
00098 
00099 /*
00100  * The screen symbols may be the default or defined at game startup time.
00101  * See drawing.c for defaults.
00102  * Note: {ibm|dec}_graphics[] arrays (also in drawing.c) must be kept in synch.
00103  */
00104 
00105 /* begin dungeon characters */
00106 
00107 #define S_stone         0
00108 #define S_vwall         1
00109 #define S_hwall         2
00110 #define S_tlcorn        3
00111 #define S_trcorn        4
00112 #define S_blcorn        5
00113 #define S_brcorn        6
00114 #define S_crwall        7
00115 #define S_tuwall        8
00116 #define S_tdwall        9
00117 #define S_tlwall        10
00118 #define S_trwall        11
00119 #define S_ndoor         12
00120 #define S_vodoor        13
00121 #define S_hodoor        14
00122 #define S_vcdoor        15      /* closed door, vertical wall */
00123 #define S_hcdoor        16      /* closed door, horizontal wall */
00124 #define S_bars          17      /* KMH -- iron bars */
00125 #define S_tree          18      /* KMH */
00126 #define S_room          19
00127 #define S_darkroom      20
00128 #define S_corr          21
00129 #define S_litcorr       22
00130 #define S_upstair       23
00131 #define S_dnstair       24
00132 #define S_upladder      25
00133 #define S_dnladder      26
00134 #define S_altar         27
00135 #define S_grave         28
00136 #define S_throne        29
00137 #define S_sink          30
00138 #define S_fountain      31
00139 #define S_pool          32
00140 #define S_ice           33
00141 #define S_lava          34
00142 #define S_vodbridge     35
00143 #define S_hodbridge     36
00144 #define S_vcdbridge     37      /* closed drawbridge, vertical wall */
00145 #define S_hcdbridge     38      /* closed drawbridge, horizontal wall */
00146 #define S_air           39
00147 #define S_cloud         40
00148 #define S_water         41
00149 
00150 /* end dungeon characters, begin traps */
00151 
00152 #define S_arrow_trap            42
00153 #define S_dart_trap             43
00154 #define S_falling_rock_trap     44
00155 #define S_squeaky_board         45
00156 #define S_bear_trap             46
00157 #define S_land_mine             47
00158 #define S_rolling_boulder_trap  48
00159 #define S_sleeping_gas_trap     49
00160 #define S_rust_trap             50
00161 #define S_fire_trap             51
00162 #define S_pit                   52
00163 #define S_spiked_pit            53
00164 #define S_hole                  54
00165 #define S_trap_door             55
00166 #define S_teleportation_trap    56
00167 #define S_level_teleporter      57
00168 #define S_magic_portal          58
00169 #define S_web                   59
00170 #define S_statue_trap           60
00171 #define S_magic_trap            61
00172 #define S_anti_magic_trap       62
00173 #define S_polymorph_trap        63
00174 
00175 /* end traps, begin special effects */
00176 
00177 #define S_vbeam         64      /* The 4 zap beam symbols.  Do NOT separate. */
00178 #define S_hbeam         65      /* To change order or add, see function     */
00179 #define S_lslant        66      /* zapdir_to_glyph() in display.c.          */
00180 #define S_rslant        67
00181 #define S_digbeam       68      /* dig beam symbol */
00182 #define S_flashbeam     69      /* camera flash symbol */
00183 #define S_boomleft      70      /* thrown boomerang, open left, e.g ')'    */
00184 #define S_boomright     71      /* thrown boomerand, open right, e.g. '('  */
00185 #define S_ss1           72      /* 4 magic shield glyphs */
00186 #define S_ss2           73
00187 #define S_ss3           74
00188 #define S_ss4           75
00189 
00190 /* The 8 swallow symbols.  Do NOT separate.  To change order or add, see */
00191 /* the function swallow_to_glyph() in display.c.                         */
00192 #define S_sw_tl         76      /* swallow top left [1]                 */
00193 #define S_sw_tc         77      /* swallow top center [2]       Order:  */
00194 #define S_sw_tr         78      /* swallow top right [3]                */
00195 #define S_sw_ml         79      /* swallow middle left [4]      1 2 3   */
00196 #define S_sw_mr         80      /* swallow middle right [6]     4 5 6   */
00197 #define S_sw_bl         81      /* swallow bottom left [7]      7 8 9   */
00198 #define S_sw_bc         82      /* swallow bottom center [8]            */
00199 #define S_sw_br         83      /* swallow bottom right [9]             */
00200 
00201 #define S_explode1      84      /* explosion top left                   */
00202 #define S_explode2      85      /* explosion top center                 */
00203 #define S_explode3      86      /* explosion top right           Ex.    */
00204 #define S_explode4      87      /* explosion middle left                */
00205 #define S_explode5      88      /* explosion middle center       /-\    */
00206 #define S_explode6      89      /* explosion middle right        |@|    */
00207 #define S_explode7      90      /* explosion bottom left         \-/    */
00208 #define S_explode8      91      /* explosion bottom center              */
00209 #define S_explode9      92      /* explosion bottom right               */
00210 
00211 /* end effects */
00212 
00213 #define MAXPCHARS       93      /* maximum number of mapped characters */
00214 #define MAXDCHARS       42      /* maximum of mapped dungeon characters */
00215 #define MAXTCHARS       22      /* maximum of mapped trap characters */
00216 #define MAXECHARS       29      /* maximum of mapped effects characters */
00217 #define MAXEXPCHARS     9       /* number of explosion characters */
00218 
00219 struct symdef {
00220     uchar sym;
00221     const char  *explanation;
00222 #ifdef TEXTCOLOR
00223     uchar color;
00224 #endif
00225 };
00226 
00227 extern struct symdef defsyms[MAXPCHARS];        /* defaults */
00228 extern uchar showsyms[MAXPCHARS];
00229 extern const struct symdef def_warnsyms[WARNCOUNT];
00230 
00231 /*
00232  * Graphics sets for display symbols
00233  */
00234 #define ASCII_GRAPHICS  0       /* regular characters: '-', '+', &c */
00235 #define IBM_GRAPHICS    1       /* PC graphic characters */
00236 #define DEC_GRAPHICS    2       /* VT100 line drawing characters */
00237 #define MAC_GRAPHICS    3       /* Macintosh drawing characters */
00238 #define CURS_GRAPHICS   4   /* Portable curses drawing characters */
00239 
00240 /*
00241  * The 5 possible states of doors
00242  */
00243 
00244 #define D_NODOOR        0
00245 #define D_BROKEN        1
00246 #define D_ISOPEN        2
00247 #define D_CLOSED        4
00248 #define D_LOCKED        8
00249 #define D_TRAPPED       16
00250 #define D_SECRET        32 /* only used by sp_lev.c, NOT in rm-struct */
00251 
00252 /*
00253  * Some altars are considered as shrines, so we need a flag.
00254  */
00255 #define AM_SHRINE       8
00256 
00257 /*
00258  * Thrones should only be looted once.
00259  */
00260 #define T_LOOTED        1
00261 
00262 /*
00263  * Trees have more than one kick result.
00264  */
00265 #define TREE_LOOTED     1
00266 #define TREE_SWARM      2
00267 
00268 /*
00269  * Fountains have limits, and special warnings.
00270  */
00271 #define F_LOOTED        1
00272 #define F_WARNED        2
00273 #define FOUNTAIN_IS_WARNED(x,y)         (levl[x][y].looted & F_WARNED)
00274 #define FOUNTAIN_IS_LOOTED(x,y)         (levl[x][y].looted & F_LOOTED)
00275 #define SET_FOUNTAIN_WARNED(x,y)        levl[x][y].looted |= F_WARNED;
00276 #define SET_FOUNTAIN_LOOTED(x,y)        levl[x][y].looted |= F_LOOTED;
00277 #define CLEAR_FOUNTAIN_WARNED(x,y)      levl[x][y].looted &= ~F_WARNED;
00278 #define CLEAR_FOUNTAIN_LOOTED(x,y)      levl[x][y].looted &= ~F_LOOTED;
00279 
00280 /*
00281  * Doors are even worse :-) The special warning has a side effect
00282  * of instantly trapping the door, and if it was defined as trapped,
00283  * the guards consider that you have already been warned!
00284  */
00285 #define D_WARNED        16
00286 
00287 /*
00288  * Sinks have 3 different types of loot that shouldn't be abused
00289  */
00290 #define S_LPUDDING      1
00291 #define S_LDWASHER      2
00292 #define S_LRING         4
00293 
00294 /*
00295  * The four directions for a DrawBridge.
00296  */
00297 #define DB_NORTH        0
00298 #define DB_SOUTH        1
00299 #define DB_EAST         2
00300 #define DB_WEST         3
00301 #define DB_DIR          3       /* mask for direction */
00302 
00303 /*
00304  * What's under a drawbridge.
00305  */
00306 #define DB_MOAT         0
00307 #define DB_LAVA         4
00308 #define DB_ICE          8
00309 #define DB_FLOOR        16
00310 #define DB_UNDER        28      /* mask for underneath */
00311 
00312 /*
00313  * Wall information.
00314  */
00315 #define WM_MASK         0x07    /* wall mode (bottom three bits) */
00316 #define W_NONDIGGABLE   0x08
00317 #define W_NONPASSWALL   0x10
00318 
00319 /*
00320  * Ladders (in Vlad's tower) may be up or down.
00321  */
00322 #define LA_UP           1
00323 #define LA_DOWN         2
00324 
00325 /*
00326  * Room areas may be iced pools
00327  */
00328 #define ICED_POOL       8
00329 #define ICED_MOAT       16
00330 
00331 /*
00332  * The structure describing a coordinate position.
00333  * Before adding fields, remember that this will significantly affect
00334  * the size of temporary files and save files.
00335  */
00336 struct rm {
00337         int glyph;              /* what the hero thinks is there */
00338         schar typ;              /* what is really there */
00339         Bitfield(styp, 6);      /* last seen/touched dungeon typ */
00340         uchar seenv;            /* seen vector */
00341         Bitfield(flags,5);      /* extra information for typ */
00342         Bitfield(horizontal,1); /* wall/door/etc is horiz. (more typ info) */
00343         Bitfield(lit,1);        /* speed hack for lit rooms */
00344         Bitfield(waslit,1);     /* remember if a location was lit */
00345         Bitfield(roomno,6);     /* room # for special rooms */
00346         Bitfield(edge,1);       /* marks boundaries for special rooms*/
00347 };
00348 
00349 
00350 #define SET_TYPLIT(x,y,ttyp,llit)                               \
00351 {                                                               \
00352     if ((ttyp) < MAX_TYPE) levl[(x)][(y)].typ = (ttyp);         \
00353     if ((ttyp) == LAVAPOOL) levl[(x)][(y)].lit = 1;             \
00354     else if ((schar)(llit) != -2) {                             \
00355         if ((schar)(llit) == -1) levl[(x)][(y)].lit = rn2(2);   \
00356         else levl[(x)][(y)].lit = (llit);                       \
00357     }                                                           \
00358 }
00359 
00360 /*
00361  * Add wall angle viewing by defining "modes" for each wall type.  Each
00362  * mode describes which parts of a wall are finished (seen as as wall)
00363  * and which are unfinished (seen as rock).
00364  *
00365  * We use the bottom 3 bits of the flags field for the mode.  This comes
00366  * in conflict with secret doors, but we avoid problems because until
00367  * a secret door becomes discovered, we know what sdoor's bottom three
00368  * bits are.
00369  *
00370  * The following should cover all of the cases.
00371  *
00372  *      type    mode                            Examples: R=rock, F=finished
00373  *      -----   ----                            ----------------------------
00374  *      WALL:   0 none                          hwall, mode 1
00375  *              1 left/top (1/2 rock)                   RRR
00376  *              2 right/bottom (1/2 rock)               ---
00377  *                                                      FFF
00378  *
00379  *      CORNER: 0 none                          trcorn, mode 2
00380  *              1 outer (3/4 rock)                      FFF
00381  *              2 inner (1/4 rock)                      F+-
00382  *                                                      F|R
00383  *
00384  *      TWALL:  0 none                          tlwall, mode 3
00385  *              1 long edge (1/2 rock)                  F|F
00386  *              2 bottom left (on a tdwall)             -+F
00387  *              3 bottom right (on a tdwall)            R|F
00388  *
00389  *      CRWALL: 0 none                          crwall, mode 5
00390  *              1 top left (1/4 rock)                   R|F
00391  *              2 top right (1/4 rock)                  -+-
00392  *              3 bottom left (1/4 rock)                F|R
00393  *              4 bottom right (1/4 rock)
00394  *              5 top left & bottom right (1/2 rock)
00395  *              6 bottom left & top right (1/2 rock)
00396  */
00397 
00398 #define WM_W_LEFT 1                     /* vertical or horizontal wall */
00399 #define WM_W_RIGHT 2
00400 #define WM_W_TOP WM_W_LEFT
00401 #define WM_W_BOTTOM WM_W_RIGHT
00402 
00403 #define WM_C_OUTER 1                    /* corner wall */
00404 #define WM_C_INNER 2
00405 
00406 #define WM_T_LONG 1                     /* T wall */
00407 #define WM_T_BL   2
00408 #define WM_T_BR   3
00409 
00410 #define WM_X_TL   1                     /* cross wall */
00411 #define WM_X_TR   2
00412 #define WM_X_BL   3
00413 #define WM_X_BR   4
00414 #define WM_X_TLBR 5
00415 #define WM_X_BLTR 6
00416 
00417 /*
00418  * Seen vector values.  The seen vector is an array of 8 bits, one for each
00419  * octant around a given center x:
00420  *
00421  *                      0 1 2
00422  *                      7 x 3
00423  *                      6 5 4
00424  *
00425  * In the case of walls, a single wall square can be viewed from 8 possible
00426  * directions.  If we know the type of wall and the directions from which
00427  * it has been seen, then we can determine what it looks like to the hero.
00428  */
00429 #define SV0 0x1
00430 #define SV1 0x2
00431 #define SV2 0x4
00432 #define SV3 0x8
00433 #define SV4 0x10
00434 #define SV5 0x20
00435 #define SV6 0x40
00436 #define SV7 0x80
00437 #define SVALL 0xFF
00438 
00439 
00440 
00441 #define doormask        flags
00442 #define altarmask       flags
00443 #define wall_info       flags
00444 #define ladder          flags
00445 #define drawbridgemask  flags
00446 #define looted          flags
00447 #define icedpool        flags
00448 
00449 #define blessedftn      horizontal  /* a fountain that grants attribs */
00450 #define disturbed       horizontal  /* a grave that has been disturbed */
00451 
00452 struct damage {
00453         struct damage *next;
00454         long when, cost;
00455         coord place;
00456         schar typ;
00457 };
00458 
00459 struct levelflags {
00460         uchar   nfountains;             /* number of fountains on level */
00461         uchar   nsinks;                 /* number of sinks on the level */
00462         /* Several flags that give hints about what's on the level */
00463         Bitfield(has_shop, 1);
00464         Bitfield(has_vault, 1);
00465         Bitfield(has_zoo, 1);
00466         Bitfield(has_court, 1);
00467         Bitfield(has_morgue, 1);
00468         Bitfield(has_garden, 1);
00469         Bitfield(has_beehive, 1);
00470         Bitfield(has_barracks, 1);
00471         Bitfield(has_temple, 1);
00472         Bitfield(has_lemurepit, 1);
00473 
00474         Bitfield(has_swamp, 1);
00475         Bitfield(noteleport,1);
00476         Bitfield(hardfloor,1);
00477         Bitfield(nommap,1);
00478         Bitfield(hero_memory,1);        /* hero has memory */
00479         Bitfield(shortsighted,1);       /* monsters are shortsighted */
00480         Bitfield(graveyard,1);          /* has_morgue, but remains set */
00481         Bitfield(is_maze_lev,1);
00482         Bitfield(stormy,1);             /* thunderous clouds */
00483 
00484         Bitfield(is_cavernous_lev,1);
00485         Bitfield(arboreal, 1);          /* Trees replace rock */
00486 };
00487 
00488 struct mon_gen_tuple {
00489     int freq;
00490     boolean is_sym;
00491     int monid;
00492     struct mon_gen_tuple *next;
00493 };
00494 
00495 struct mon_gen_override {
00496     int override_chance;
00497     int total_mon_freq;
00498     struct mon_gen_tuple *gen_chances;
00499 };
00500 
00501 #define LVLSND_HEARD    0       /* You_hear(msg); */
00502 #define LVLSND_PLINED   1       /* pline(msg); */
00503 #define LVLSND_VERBAL   2       /* verbalize(msg); */
00504 #define LVLSND_FELT     3       /* You_feel(msg); */
00505 
00506 struct lvl_sound_bite {
00507     int flags; /* LVLSND_foo */
00508     char *msg;
00509 };
00510 
00511 struct lvl_sounds {
00512     int freq;
00513     int n_sounds;
00514     struct lvl_sound_bite *sounds;
00515 };
00516 
00517 typedef struct
00518 {
00519     struct rm           locations[COLNO][ROWNO];
00520 #ifndef MICROPORT_BUG
00521     struct obj          *objects[COLNO][ROWNO];
00522     struct monst        *monsters[COLNO][ROWNO];
00523 #else
00524     struct obj          *objects[1][ROWNO];
00525     char                *yuk1[COLNO-1][ROWNO];
00526     struct monst        *monsters[1][ROWNO];
00527     char                *yuk2[COLNO-1][ROWNO];
00528 #endif
00529     struct obj          *objlist;
00530     struct obj          *buriedobjlist;
00531     struct monst        *monlist;
00532     struct damage       *damagelist;
00533     struct levelflags   flags;
00534     struct mon_gen_override *mon_gen;
00535     struct lvl_sounds   *sounds;
00536 }
00537 dlevel_t;
00538 
00539 extern dlevel_t level;  /* structure describing the current level */
00540 
00541 /*
00542  * Macros for compatibility with old code. Someday these will go away.
00543  */
00544 #define levl            level.locations
00545 #define fobj            level.objlist
00546 #define fmon            level.monlist
00547 
00548 /*
00549  * Covert a trap number into the defsym graphics array.
00550  * Convert a defsym number into a trap number.
00551  * Assumes that arrow trap will always be the first trap.
00552  */
00553 #define trap_to_defsym(t) (S_arrow_trap+(t)-1)
00554 #define defsym_to_trap(d) ((d)-S_arrow_trap+1)
00555 
00556 #define OBJ_AT(x,y)     (level.objects[x][y] != (struct obj *)0)
00557 /*
00558  * Macros for encapsulation of level.monsters references.
00559  */
00560 #define MON_AT(x,y)     (level.monsters[x][y] != (struct monst *)0 && \
00561                          !(level.monsters[x][y])->mburied)
00562 #define MON_BURIED_AT(x,y)      (level.monsters[x][y] != (struct monst *)0 && \
00563                                 (level.monsters[x][y])->mburied)
00564 #define place_worm_seg(m,x,y)   level.monsters[x][y] = m
00565 #define m_at(x,y)               (MON_AT(x,y) ? level.monsters[x][y] : \
00566                                                 (struct monst *)0)
00567 #define m_buried_at(x,y)        (MON_BURIED_AT(x,y) ? level.monsters[x][y] : \
00568                                                        (struct monst *)0)
00569 
00570 #endif /* RM_H */