1 /* SCCS Id: @(#)mondata.h 3.4 2003/01/08 */ 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 resists_drain(mon) (((mon)->mintrinsics & MR_DRAIN) != 0) 23 #define resists_death(mon) (((mon)->mintrinsics & MR_DEATH) != 0) 24 25 #define need_one(mon) (((mon)->mintrinsics & MR_PLUSONE) != 0) 26 #define need_two(mon) (((mon)->mintrinsics & MR_PLUSTWO) != 0) 27 #define need_three(mon) (((mon)->mintrinsics & MR_PLUSTHREE) != 0) 28 #define need_four(mon) (((mon)->mintrinsics & MR_PLUSFOUR) != 0) 29 #define hit_as_one(mon) (((mon)->mintrinsics & MR_HITASONE) != 0) 30 #define hit_as_two(mon) (((mon)->mintrinsics & MR_HITASTWO) != 0) 31 #define hit_as_three(mon) (((mon)->mintrinsics & MR_HITASTHREE) != 0) 32 #define hit_as_four(mon) (((mon)->mintrinsics & MR_HITASFOUR) != 0) 33 34 #define is_lminion(mon) (is_minion((mon)->data) && \ 35 (mon)->data->maligntyp >= A_COALIGNED && \ 36 ((mon)->data != &mons[PM_ANGEL] || \ 37 EPRI(mon)->shralign > 0)) 38 39 #define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L) 40 #define is_floater(ptr) ((ptr)->mlet == S_EYE) 41 #define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L) 42 #define is_swimmer(ptr) (((ptr)->mflags1 & M1_SWIM) != 0L) 43 #define breathless(ptr) (((ptr)->mflags1 & M1_BREATHLESS) != 0L) 44 #define amphibious(ptr) (((ptr)->mflags1 & (M1_AMPHIBIOUS | M1_BREATHLESS)) != 0L) 45 #define passes_walls(ptr) (((ptr)->mflags1 & M1_WALLWALK) != 0L) 46 #define amorphous(ptr) (((ptr)->mflags1 & M1_AMORPHOUS) != 0L) 47 #define noncorporeal(ptr) ((ptr)->mlet == S_GHOST) 48 #define tunnels(ptr) (((ptr)->mflags1 & M1_TUNNEL) != 0L) 49 #define needspick(ptr) (((ptr)->mflags1 & M1_NEEDPICK) != 0L) 50 #define hides_under(ptr) (((ptr)->mflags1 & M1_CONCEAL) != 0L) 51 #define is_hider(ptr) (((ptr)->mflags1 & M1_HIDE) != 0L) 52 #define haseyes(ptr) (((ptr)->mflags1 & M1_NOEYES) == 0L) 53 #define eyecount(ptr) (!haseyes(ptr) ? 0 : \ 54 ((ptr) == &mons[PM_CYCLOPS] || \ 55 (ptr) == &mons[PM_FLOATING_EYE]) ? 1 : 2) 56 #define nohands(ptr) (((ptr)->mflags1 & M1_NOHANDS) != 0L) 57 #define nolimbs(ptr) (((ptr)->mflags1 & M1_NOLIMBS) == M1_NOLIMBS) 58 #define notake(ptr) (((ptr)->mflags1 & M1_NOTAKE) != 0L) 59 #define has_head(ptr) (((ptr)->mflags1 & M1_NOHEAD) == 0L) 60 #define has_horns(ptr) (num_horns(ptr) > 0) 61 #define is_whirly(ptr) ((ptr)->mlet == S_VORTEX || \ 62 (ptr) == &mons[PM_AIR_ELEMENTAL]) 63 #define is_fire(ptr) ((ptr) == &mons[PM_FIRE_VORTEX] || \ 64 (ptr) == &mons[PM_FIRE_ELEMENTAL]) 65 #define flaming(ptr) ((ptr) == &mons[PM_FIRE_VORTEX] || \ 66 (ptr) == &mons[PM_FLAMING_SPHERE] || \ 67 (ptr) == &mons[PM_FIRE_ELEMENTAL] || \ 68 (ptr) == &mons[PM_SALAMANDER]) 69 #define is_silent(ptr) ((ptr)->msound == MS_SILENT) 70 #define unsolid(ptr) (((ptr)->mflags1 & M1_UNSOLID) != 0L) 71 #define mindless(ptr) (((ptr)->mflags1 & M1_MINDLESS) != 0L) 72 #define humanoid(ptr) (((ptr)->mflags1 & M1_HUMANOID) != 0L) 73 #define is_animal(ptr) (((ptr)->mflags1 & M1_ANIMAL) != 0L) 74 #define slithy(ptr) (((ptr)->mflags1 & M1_SLITHY) != 0L) 75 #define is_wooden(ptr) ((ptr) == &mons[PM_WOOD_GOLEM]) 76 #define thick_skinned(ptr) (((ptr)->mflags1 & M1_THICK_HIDE) != 0L) 77 #define lays_eggs(ptr) (((ptr)->mflags1 & M1_OVIPAROUS) != 0L) 78 #define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L) 79 #define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L) 80 #define can_teleport(ptr) (((ptr)->mflags1 & M1_TPORT) != 0L) 81 #define control_teleport(ptr) (((ptr)->mflags1 & M1_TPORT_CNTRL) != 0L) 82 #define telepathic(ptr) ((ptr) == &mons[PM_FLOATING_EYE] || \ 83 is_mind_flayer(ptr)) 84 #define is_armed(ptr) attacktype(ptr, AT_WEAP) 85 #define acidic(ptr) (((ptr)->mflags1 & M1_ACID) != 0L) 86 #define poisonous(ptr) (((ptr)->mflags1 & M1_POIS) != 0L) 87 #define carnivorous(ptr) (((ptr)->mflags1 & M1_CARNIVORE) != 0L) 88 #define herbivorous(ptr) (((ptr)->mflags1 & M1_HERBIVORE) != 0L) 89 #define metallivorous(ptr) (((ptr)->mflags1 & M1_METALLIVORE) != 0L) 90 #define polyok(ptr) (((ptr)->mflags2 & M2_NOPOLY) == 0L) 91 #define is_undead(ptr) (((ptr)->mflags2 & M2_UNDEAD) != 0L) 92 #define is_were(ptr) (((ptr)->mflags2 & M2_WERE) != 0L) 93 #define is_vampire(ptr) (((ptr)->mflags2 & M2_VAMPIRE) != 0L) 94 #define is_elf(ptr) (((ptr)->mflags2 & M2_ELF) != 0L) 95 #define is_dwarf(ptr) (((ptr)->mflags2 & M2_DWARF) != 0L) 96 #define is_gnome(ptr) (((ptr)->mflags2 & M2_GNOME) != 0L) 97 #define is_orc(ptr) (((ptr)->mflags2 & M2_ORC) != 0L) 98 #define is_human(ptr) (((ptr)->mflags2 & M2_HUMAN) != 0L) 99 #define is_hobbit(ptr) (((ptr)->mflags2 & M2_HOBBIT) != 0L) 100 #define your_race(ptr) (((ptr)->mflags2 & urace.selfmask) != 0L) 101 #define is_bat(ptr) ((ptr) == &mons[PM_BAT] || \ 102 (ptr) == &mons[PM_GIANT_BAT] || \ 103 (ptr) == &mons[PM_VAMPIRE_BAT]) 104 #define is_bird(ptr) ((ptr)->mlet == S_BAT && !is_bat(ptr)) 105 #define is_giant(ptr) (((ptr)->mflags2 & M2_GIANT) != 0L) 106 #define is_golem(ptr) ((ptr)->mlet == S_GOLEM) 107 #define is_domestic(ptr) (((ptr)->mflags2 & M2_DOMESTIC) != 0L) 108 #define is_demon(ptr) (((ptr)->mflags2 & M2_DEMON) != 0L) 109 #define is_mercenary(ptr) (((ptr)->mflags2 & M2_MERC) != 0L) 110 #define is_male(ptr) (((ptr)->mflags2 & M2_MALE) != 0L) 111 #define is_female(ptr) (((ptr)->mflags2 & M2_FEMALE) != 0L) 112 #define is_neuter(ptr) (((ptr)->mflags2 & M2_NEUTER) != 0L) 113 #define is_wanderer(ptr) (((ptr)->mflags2 & M2_WANDER) != 0L) 114 #define always_hostile(ptr) (((ptr)->mflags2 & M2_HOSTILE) != 0L) 115 #define always_peaceful(ptr) (((ptr)->mflags2 & M2_PEACEFUL) != 0L) 116 #define race_hostile(ptr) (((ptr)->mflags2 & urace.hatemask) != 0L) 117 #define race_peaceful(ptr) (((ptr)->mflags2 & urace.lovemask) != 0L) 118 #define extra_nasty(ptr) (((ptr)->mflags2 & M2_NASTY) != 0L) 119 #define strongmonst(ptr) (((ptr)->mflags2 & M2_STRONG) != 0L) 120 #define can_breathe(ptr) attacktype(ptr, AT_BREA) 121 #define cantwield(ptr) (nohands(ptr) || verysmall(ptr) || \ 122 (ptr)->mlet == S_ANT) 123 #define could_twoweap(ptr) ((ptr)->mattk[1].aatyp == AT_WEAP && \ 124 ((ptr) != youmonst.data || \ 125 P_MAX_SKILL(P_TWO_WEAPON_COMBAT) >= P_SKILLED || \ 126 P_MAX_SKILL(P_TWO_WEAPON_COMBAT) >= P_BASIC && \ 127 (Race_if(PM_DWARF) || Race_if(PM_HUMAN)))) 128 #define cantweararm(ptr) (breakarm(ptr) || sliparm(ptr)) 129 #define throws_rocks(ptr) (((ptr)->mflags2 & M2_ROCKTHROW) != 0L) 130 #define type_is_pname(ptr) (((ptr)->mflags2 & M2_PNAME) != 0L) 131 #define is_lord(ptr) (((ptr)->mflags2 & M2_LORD) != 0L) 132 #define is_prince(ptr) (((ptr)->mflags2 & M2_PRINCE) != 0L) 133 #define is_ndemon(ptr) (is_demon(ptr) && \ 134 (((ptr)->mflags2 & (M2_LORD|M2_PRINCE)) == 0L)) 135 #define is_dlord(ptr) (is_demon(ptr) && is_lord(ptr)) 136 #define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr)) 137 #define is_minion(ptr) ((ptr)->mflags2 & M2_MINION) 138 #define likes_gold(ptr) (((ptr)->mflags2 & M2_GREEDY) != 0L) 139 #define likes_gems(ptr) (((ptr)->mflags2 & M2_JEWELS) != 0L) 140 #define likes_objs(ptr) (((ptr)->mflags2 & M2_COLLECT) != 0L || \ 141 is_armed(ptr)) 142 #define likes_magic(ptr) (((ptr)->mflags2 & M2_MAGIC) != 0L) 143 #define webmaker(ptr) ((ptr) == &mons[PM_CAVE_SPIDER] || \ 144 (ptr) == &mons[PM_RECLUSE_SPIDER] || \ 145 (ptr) == &mons[PM_PHASE_SPIDER] || \ 146 (ptr) == &mons[PM_WERESPIDER] || \ 147 (ptr) == &mons[PM_BARKING_SPIDER] || \ 148 (ptr) == &mons[PM_GIANT_SPIDER]) 149 #define is_unicorn(ptr) ((ptr)->mlet == S_UNICORN && likes_gems(ptr)) /* KMH */ 150 #define is_longworm(ptr) (((ptr) == &mons[PM_BABY_LONG_WORM]) || \ 151 ((ptr) == &mons[PM_LONG_WORM]) || \ 152 ((ptr) == &mons[PM_LONG_WORM_TAIL])) 153 #define is_covetous(ptr) ((ptr)->mflags3 & M3_COVETOUS) 154 #define infravision(ptr) ((ptr->mflags3 & M3_INFRAVISION)) 155 #define infravisible(ptr) ((ptr->mflags3 & M3_INFRAVISIBLE)) 156 #define can_betray(ptr) ((ptr->mflags3 & M3_TRAITOR)) 157 #define cannot_be_tamed(ptr) ((ptr->mflags3 & M3_NOTAME)) 158 #define is_mplayer(ptr) (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \ 159 ((ptr) <= &mons[PM_WIZARD])) 160 #define is_rider(ptr) ((ptr) == &mons[PM_DEATH] || \ 161 (ptr) == &mons[PM_FAMINE] || \ 162 (ptr) == &mons[PM_PESTILENCE]) 163 #define is_placeholder(ptr) ((ptr) == &mons[PM_ORC] || \ 164 (ptr) == &mons[PM_GIANT] || \ 165 (ptr) == &mons[PM_ELF] || \ 166 (ptr) == &mons[PM_HUMAN]) 167 /* return TRUE if the monster tends to revive */ 168 #define is_reviver(ptr) (is_rider(ptr) || (ptr)->mlet == S_FUNGUS && \ 169 (ptr) != &mons[PM_LICHEN] || \ 170 (ptr)->mlet == S_TROLL) 171 172 /* this returns the light's range, or 0 if none; if we add more light emitting 173 monsters, we'll likely have to add a new light range field to mons[] */ 174 #define emits_light(ptr) (((ptr)->mlet == S_LIGHT || \ 175 (ptr) == &mons[PM_FIRE_VORTEX]) ? 3 : \ 176 ((ptr) == &mons[PM_FIRE_ELEMENTAL]) ? 2 : \ 177 ((ptr) == &mons[PM_FIRE_VAMPIRE])? 2 : \ 178 ((ptr) == &mons[PM_FLAMING_SPHERE]) ? 1 : \ 179 ((ptr) == &mons[PM_SHOCKING_SPHERE]) ? 1 : \ 180 ((ptr) == &mons[PM_WAX_GOLEM]) ? 1 : 0) 181 /* [note: the light ranges above were reduced to 1 for performance...] */ 182 /* WAC increased to 3 and 2?*/ 183 #define likes_lava(ptr) (ptr == &mons[PM_FIRE_ELEMENTAL] || \ 184 ptr == &mons[PM_SALAMANDER]) 185 #define pm_invisible(ptr) ((ptr) == &mons[PM_STALKER] || \ 186 (ptr) == &mons[PM_BLACK_LIGHT] || \ 187 (ptr) == &mons[PM_STAR_VAMPIRE]) 188 189 /* could probably add more */ 190 #define likes_fire(ptr) ((ptr) == &mons[PM_FIRE_VORTEX] || \ 191 (ptr) == &mons[PM_FLAMING_SPHERE] || \ 192 (ptr) == &mons[PM_FIRE_VAMPIRE] || \ 193 likes_lava(ptr)) 194 195 #define nonliving(ptr) (is_golem(ptr) || is_undead(ptr) || \ 196 (ptr)->mlet == S_VORTEX || \ 197 (ptr) == &mons[PM_MANES]) 198 199 #define touch_petrifies(ptr) (ptr == &mons[PM_COCKATRICE] || \ 200 ptr == &mons[PM_BASILISK] || \ 201 ptr == &mons[PM_CHICKATRICE] || \ 202 ptr == &mons[PM_ASPHYNX]) 203 204 #define is_mind_flayer(ptr) ((ptr) == &mons[PM_MIND_FLAYER] || \ 205 (ptr) == &mons[PM_MASTER_MIND_FLAYER]) 206 207 #define made_of_rock(ptr) ((passes_walls(ptr) && thick_skinned(ptr)) || \ 208 (ptr) == &mons[PM_STONE_GOLEM] || \ 209 (ptr) == &mons[PM_STATUE_GARGOYLE]) 210 #define hates_silver(ptr) (is_were(ptr) || is_vampire(ptr) || \ 211 is_demon(ptr) || (ptr) == &mons[PM_SHADE] || \ 212 ((ptr)->mlet==S_IMP && (ptr) != &mons[PM_TENGU])) 213 /* Used for conduct with corpses, tins, and digestion attacks */ 214 /* G_NOCORPSE monsters might still be swallowed as a purple worm */ 215 /* Maybe someday this could be in mflags... */ 216 #define vegan(ptr) ((ptr)->mlet == S_BLOB || \ 217 (ptr)->mlet == S_JELLY || \ 218 (ptr)->mlet == S_FUNGUS || \ 219 (ptr)->mlet == S_VORTEX || \ 220 (ptr)->mlet == S_LIGHT || \ 221 ((ptr)->mlet == S_ELEMENTAL && \ 222 (ptr) != &mons[PM_STALKER]) || \ 223 ((ptr)->mlet == S_GOLEM && \ 224 (ptr) != &mons[PM_FLESH_GOLEM] && \ 225 (ptr) != &mons[PM_FRANKENSTEIN_S_MONSTER] && \ 226 (ptr) != &mons[PM_LEATHER_GOLEM]) || \ 227 noncorporeal(ptr)) 228 #define vegetarian(ptr) (vegan(ptr) || \ 229 ((ptr)->mlet == S_PUDDING && \ 230 (ptr) != &mons[PM_BLACK_PUDDING])) 231 /* For vampires */ 232 #define has_blood(ptr) (!vegetarian(ptr) && \ 233 (ptr)->mlet != S_GOLEM && \ 234 ((ptr)->mlet != S_BAD_FOOD || \ 235 (ptr) == &mons[PM_KILLER_TRIPE_RATION]) && \ 236 (!is_undead(ptr) || is_vampire(ptr))) 237 238 #define befriend_with_obj(ptr, obj) ((obj)->oclass == FOOD_CLASS && ( \ 239 is_domestic(ptr) || \ 240 /* [Tom] Dorothy wants more pets... */ \ 241 (obj)->otyp == CHEESE && ((ptr) == &mons[PM_GIANT_RAT] || \ 242 (ptr) == &mons[PM_SEWER_RAT] || \ 243 (ptr) == &mons[PM_BLACK_RAT] || \ 244 (ptr) == &mons[PM_PACK_RAT]) || \ 245 (obj)->otyp == CARROT && ((ptr) == &mons[PM_RABBIT] || \ 246 (ptr) == &mons[PM_RABID_RABBIT]) || \ 247 (obj)->otyp == BANANA && (ptr)->mlet == S_YETI)) 248 249 #endif /* MONDATA_H */ 250