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 */