1 | /* SCCS Id: @(#)mondata.h 3.3 2000/07/14 */ 2 | /* Copyright (c) 1989 Mike Threepoint */ 3 | /* NetHack may be freely redistributed. See license for details. */ 4 | 5 | #ifndef MONDATA_H 6 | #define MONDATA_H 7 | 8 | #define verysmall(ptr) ((ptr)->msize < MZ_SMALL) 9 | #define bigmonst(ptr) ((ptr)->msize >= MZ_LARGE) 10 | 11 | #define pm_resistance(ptr,typ) (((ptr)->mresists & (typ)) != 0) 12 | 13 | #define resists_fire(mon) (((mon)->mintrinsics & MR_FIRE) != 0) 14 | #define resists_cold(mon) (((mon)->mintrinsics & MR_COLD) != 0) 15 | #define resists_sleep(mon) (((mon)->mintrinsics & MR_SLEEP) != 0) 16 | #define resists_disint(mon) (((mon)->mintrinsics & MR_DISINT) != 0) 17 | #define resists_elec(mon) (((mon)->mintrinsics & MR_ELEC) != 0) 18 | #define resists_poison(mon) (((mon)->mintrinsics & MR_POISON) != 0) 19 | #define resists_acid(mon) (((mon)->mintrinsics & MR_ACID) != 0) 20 | #define resists_ston(mon) (((mon)->mintrinsics & MR_STONE) != 0) 21 | 22 | #define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L) 23 | #define is_floater(ptr) ((ptr)->mlet == S_EYE) 24 | #define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L) 25 | #define is_swimmer(ptr) (((ptr)->mflags1 & M1_SWIM) != 0L) 26 | #define breathless(ptr) (((ptr)->mflags1 & M1_BREATHLESS) != 0L) 27 | #define amphibious(ptr) (((ptr)->mflags1 & (M1_AMPHIBIOUS | M1_BREATHLESS)) != 0L) 28 | #define passes_walls(ptr) (((ptr)->mflags1 & M1_WALLWALK) != 0L) 29 | #define amorphous(ptr) (((ptr)->mflags1 & M1_AMORPHOUS) != 0L) 30 | #define noncorporeal(ptr) ((ptr)->mlet == S_GHOST) 31 | #define tunnels(ptr) (((ptr)->mflags1 & M1_TUNNEL) != 0L) 32 | #define needspick(ptr) (((ptr)->mflags1 & M1_NEEDPICK) != 0L) 33 | #define hides_under(ptr) (((ptr)->mflags1 & M1_CONCEAL) != 0L) 34 | #define is_hider(ptr) (((ptr)->mflags1 & M1_HIDE) != 0L) 35 | #define haseyes(ptr) (((ptr)->mflags1 & M1_NOEYES) == 0L) 36 | #define nohands(ptr) (((ptr)->mflags1 & M1_NOHANDS) != 0L) 37 | #define nolimbs(ptr) (((ptr)->mflags1 & M1_NOLIMBS) == M1_NOLIMBS) 38 | #define notake(ptr) (((ptr)->mflags1 & M1_NOTAKE) != 0L) 39 | #define has_head(ptr) (((ptr)->mflags1 & M1_NOHEAD) == 0L) 40 | #define is_whirly(ptr) ((ptr)->mlet == S_VORTEX || \ 41 | (ptr) == &mons[PM_AIR_ELEMENTAL]) 42 | #define unsolid(ptr) (((ptr)->mflags1 & M1_UNSOLID) != 0L) 43 | #define mindless(ptr) (((ptr)->mflags1 & M1_MINDLESS) != 0L) 44 | #define humanoid(ptr) (((ptr)->mflags1 & M1_HUMANOID) != 0L) 45 | #define is_animal(ptr) (((ptr)->mflags1 & M1_ANIMAL) != 0L) 46 | #define slithy(ptr) (((ptr)->mflags1 & M1_SLITHY) != 0L) 47 | #define is_wooden(ptr) ((ptr) == &mons[PM_WOOD_GOLEM]) 48 | #define thick_skinned(ptr) (((ptr)->mflags1 & M1_THICK_HIDE) != 0L) 49 | #define lays_eggs(ptr) (((ptr)->mflags1 & M1_OVIPAROUS) != 0L) 50 | #define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L) 51 | #define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L) 52 | #define can_teleport(ptr) (((ptr)->mflags1 & M1_TPORT) != 0L) 53 | #define control_teleport(ptr) (((ptr)->mflags1 & M1_TPORT_CNTRL) != 0L) 54 | #define telepathic(ptr) ((ptr) == &mons[PM_FLOATING_EYE] || \ 55 | (ptr) == &mons[PM_MIND_FLAYER] || \ 56 | (ptr) == &mons[PM_MASTER_MIND_FLAYER]) 57 | #define is_armed(ptr) attacktype(ptr, AT_WEAP) 58 | #define acidic(ptr) (((ptr)->mflags1 & M1_ACID) != 0L) 59 | #define poisonous(ptr) (((ptr)->mflags1 & M1_POIS) != 0L) 60 | #define carnivorous(ptr) (((ptr)->mflags1 & M1_CARNIVORE) != 0L) 61 | #define herbivorous(ptr) (((ptr)->mflags1 & M1_HERBIVORE) != 0L) 62 | #define metallivorous(ptr) (((ptr)->mflags1 & M1_METALLIVORE) != 0L) 63 | #define polyok(ptr) (((ptr)->mflags2 & M2_NOPOLY) == 0L) 64 | #define is_undead(ptr) (((ptr)->mflags2 & M2_UNDEAD) != 0L) 65 | #define is_were(ptr) (((ptr)->mflags2 & M2_WERE) != 0L) 66 | #define is_elf(ptr) (((ptr)->mflags2 & M2_ELF) != 0L) 67 | #define is_dwarf(ptr) (((ptr)->mflags2 & M2_DWARF) != 0L) 68 | #define is_gnome(ptr) (((ptr)->mflags2 & M2_GNOME) != 0L) 69 | #define is_orc(ptr) (((ptr)->mflags2 & M2_ORC) != 0L) 70 | #define is_human(ptr) (((ptr)->mflags2 & M2_HUMAN) != 0L) 71 | #define your_race(ptr) (((ptr)->mflags2 & urace.selfmask) != 0L) 72 | #define is_bat(ptr) ((ptr) == &mons[PM_BAT] || \ 73 | (ptr) == &mons[PM_GIANT_BAT] || \ 74 | (ptr) == &mons[PM_VAMPIRE_BAT]) 75 | #define is_bird(ptr) ((ptr)->mlet == S_BAT && !is_bat(ptr)) 76 | #define is_giant(ptr) (((ptr)->mflags2 & M2_GIANT) != 0L) 77 | #define is_golem(ptr) ((ptr)->mlet == S_GOLEM) 78 | #define is_domestic(ptr) (((ptr)->mflags2 & M2_DOMESTIC) != 0L) 79 | #define is_demon(ptr) (((ptr)->mflags2 & M2_DEMON) != 0L) 80 | #define is_mercenary(ptr) (((ptr)->mflags2 & M2_MERC) != 0L) 81 | #define is_male(ptr) (((ptr)->mflags2 & M2_MALE) != 0L) 82 | #define is_female(ptr) (((ptr)->mflags2 & M2_FEMALE) != 0L) 83 | #define is_neuter(ptr) (((ptr)->mflags2 & M2_NEUTER) != 0L) 84 | #define is_wanderer(ptr) (((ptr)->mflags2 & M2_WANDER) != 0L) 85 | #define always_hostile(ptr) (((ptr)->mflags2 & M2_HOSTILE) != 0L) 86 | #define always_peaceful(ptr) (((ptr)->mflags2 & M2_PEACEFUL) != 0L) 87 | #define race_hostile(ptr) (((ptr)->mflags2 & urace.hatemask) != 0L) 88 | #define race_peaceful(ptr) (((ptr)->mflags2 & urace.lovemask) != 0L) 89 | #define extra_nasty(ptr) (((ptr)->mflags2 & M2_NASTY) != 0L) 90 | #define strongmonst(ptr) (((ptr)->mflags2 & M2_STRONG) != 0L) 91 | #define can_breathe(ptr) attacktype(ptr, AT_BREA) 92 | #define cantwield(ptr) (nohands(ptr) || verysmall(ptr)) 93 | #define cantweararm(ptr) (breakarm(ptr) || sliparm(ptr)) 94 | #define throws_rocks(ptr) (((ptr)->mflags2 & M2_ROCKTHROW) != 0L) 95 | #define type_is_pname(ptr) (((ptr)->mflags2 & M2_PNAME) != 0L) 96 | #define is_lord(ptr) (((ptr)->mflags2 & M2_LORD) != 0L) 97 | #define is_prince(ptr) (((ptr)->mflags2 & M2_PRINCE) != 0L) 98 | #define is_ndemon(ptr) (is_demon(ptr) && \ 99 | (((ptr)->mflags2 & (M2_LORD|M2_PRINCE)) == 0L)) 100 | #define is_dlord(ptr) (is_demon(ptr) && is_lord(ptr)) 101 | #define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr)) 102 | #define is_minion(ptr) ((ptr)->mflags2 & M2_MINION) 103 | #define is_lminion(ptr) (is_minion(ptr) && \ 104 | (ptr)->maligntyp >= A_COALIGNED) 105 | #define likes_gold(ptr) (((ptr)->mflags2 & M2_GREEDY) != 0L) 106 | #define likes_gems(ptr) (((ptr)->mflags2 & M2_JEWELS) != 0L) 107 | #define likes_objs(ptr) (((ptr)->mflags2 & M2_COLLECT) != 0L || \ 108 | is_armed(ptr)) 109 | #define likes_magic(ptr) (((ptr)->mflags2 & M2_MAGIC) != 0L) 110 | #define webmaker(ptr) ((ptr) == &mons[PM_CAVE_SPIDER] || \ 111 | (ptr) == &mons[PM_GIANT_SPIDER]) 112 | #define is_unicorn(ptr) ((ptr)->mlet == S_UNICORN && likes_gems(ptr)) 113 | #define is_longworm(ptr) (((ptr) == &mons[PM_BABY_LONG_WORM]) || \ 114 | ((ptr) == &mons[PM_LONG_WORM]) || \ 115 | ((ptr) == &mons[PM_LONG_WORM_TAIL])) 116 | #define is_covetous(ptr) ((ptr->mflags3 & M3_COVETOUS)) 117 | #define infravision(ptr) ((ptr->mflags3 & M3_INFRAVISION)) 118 | #define infravisible(ptr) ((ptr->mflags3 & M3_INFRAVISIBLE)) 119 | #define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \ 120 | ((ptr) <= &mons[PM_WIZARD])) 121 | #define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \ 122 | (ptr) == &mons[PM_FAMINE] || \ 123 | (ptr) == &mons[PM_PESTILENCE]) 124 | #define is_placeholder(ptr) ((ptr) == &mons[PM_ORC] || \ 125 | (ptr) == &mons[PM_GIANT] || \ 126 | (ptr) == &mons[PM_ELF] || \ 127 | (ptr) == &mons[PM_HUMAN]) 128 | /* this returns the light's range, or 0 if none; if we add more light emitting 129 | monsters, we'll likely have to add a new light range field to mons[] */ 130 | #define emits_light(ptr) (((ptr)->mlet == S_LIGHT || \ 131 | (ptr) == &mons[PM_FLAMING_SPHERE] || \ 132 | (ptr) == &mons[PM_SHOCKING_SPHERE] || \ 133 | (ptr) == &mons[PM_FIRE_VORTEX]) ? 1 : \ 134 | ((ptr) == &mons[PM_FIRE_ELEMENTAL]) ? 1 : 0) 135 | /* [note: the light ranges above were reduced to 1 for performance...] */ 136 | #define likes_lava(ptr) (ptr == &mons[PM_FIRE_ELEMENTAL] || \ 137 | ptr == &mons[PM_SALAMANDER]) 138 | #define pm_invisible(ptr) ((ptr) == &mons[PM_STALKER] || \ 139 | (ptr) == &mons[PM_BLACK_LIGHT]) 140 | 141 | /* could probably add more */ 142 | #define likes_fire(ptr) ((ptr) == &mons[PM_FIRE_VORTEX] || \ 143 | (ptr) == &mons[PM_FLAMING_SPHERE] || \ 144 | likes_lava(ptr)) 145 | 146 | #define touch_petrifies(ptr) ((ptr) == &mons[PM_COCKATRICE] || \ 147 | (ptr) == &mons[PM_CHICKATRICE]) 148 | 149 | #define is_mind_flayer(ptr) ((ptr) == &mons[PM_MIND_FLAYER] || \ 150 | (ptr) == &mons[PM_MASTER_MIND_FLAYER]) 151 | 152 | #define nonliving(ptr) (is_golem(ptr) || is_undead(ptr)) 153 | 154 | /* Used for conduct with corpses, tins, and digestion attacks */ 155 | /* G_NOCORPSE monsters might still be swallowed as a purple worm */ 156 | /* Maybe someday this could be in mflags... */ 157 | #define vegan(ptr) ((ptr)->mlet == S_BLOB || \ 158 | (ptr)->mlet == S_JELLY || \ 159 | (ptr)->mlet == S_FUNGUS || \ 160 | (ptr)->mlet == S_VORTEX || \ 161 | (ptr)->mlet == S_LIGHT || \ 162 | ((ptr)->mlet == S_ELEMENTAL && \ 163 | (ptr) != &mons[PM_STALKER]) || \ 164 | ((ptr)->mlet == S_GOLEM && \ 165 | (ptr) != &mons[PM_FLESH_GOLEM] && \ 166 | (ptr) != &mons[PM_LEATHER_GOLEM]) || \ 167 | noncorporeal(ptr)) 168 | #define vegetarian(ptr) (vegan(ptr) || \ 169 | ((ptr)->mlet == S_PUDDING && \ 170 | (ptr) != &mons[PM_BLACK_PUDDING])) 171 | 172 | #endif /* MONDATA_H */