1 #pragma once
2 
3 #include <cstdint>
4 
5 #include "enum.h"
6 
7 #define BIT(x) ((uint64_t)1<<(x))
8 
9 /// Properties of the monster class (other than resists/vulnerabilities).
10 enum monclass_flag_type : uint64_t
11 {
12     M_NO_FLAGS = 0,
13 
14     /// monster eats doors
15     M_EAT_DOORS         = BIT(0),
16 
17     /// monster crashes through doors rather than opening
18     M_CRASH_DOORS       = BIT(1),
19 
20     /// monster flies all the time
21     M_FLIES             = BIT(2),
22 
23     /// monster is skilled fighter
24     M_FIGHTER           = BIT(3),
25 
26     /// do not give (unique) a wand
27     M_NO_WAND           = BIT(4),
28 
29     /// do not give a high tier wand
30     M_NO_HT_WAND        = BIT(5),
31 
32     /// is created invis
33     M_INVIS             = BIT(6),
34 
35     /// can see invis
36     M_SEE_INVIS         = BIT(7),
37 
38     /// can't be blinded
39     M_UNBLINDABLE       = BIT(8),
40 
41     /// uses talking code
42     M_SPEAKS            = BIT(9),
43 
44     /// monster is perma-confused,
45     M_CONFUSED          = BIT(10),
46 
47     /// monster is batty
48     M_BATTY             = BIT(11),
49 
50     /// monster can split
51     M_SPLITS            = BIT(12),
52 
53     /// monster dies a few turns after being hit
54     M_FRAGILE           = BIT(13),
55 
56     /// monster is stationary
57     M_STATIONARY        = BIT(14),
58 
59                         //BIT(15), // was M_BLOOD_SCENT
60 
61     /// susceptible to cold; drainable by vampires, splashes blood when hit
62     M_COLD_BLOOD        = BIT(16),
63 
64     /// drainable by vampires, splashes blood when hit
65     M_WARM_BLOOD        = BIT(17),
66 
67     /// uses the 'ghost demon' struct to track stats varying per individual monster
68     M_GHOST_DEMON       = BIT(18),
69 
70     /// monster digs through rock
71     M_BURROWS           = BIT(19),
72 
73     /// monster can submerge
74     M_SUBMERGES         = BIT(20),
75 
76     /// monster is a unique
77     M_UNIQUE            = BIT(21),
78 
79     /// Passive acid splash when hit.
80     M_ACID_SPLASH       = BIT(22),
81 
82     /// gets various archery boosts
83     M_ARCHER            = BIT(23),
84 
85     /// is insubstantial
86     M_INSUBSTANTIAL     = BIT(24),
87 
88     /// wields two weapons at once
89     M_TWO_WEAPONS       = BIT(25),
90 
91     /// has extra-fast regeneration
92     M_FAST_REGEN        = BIT(26),
93 
94     /// cannot regenerate
95     M_NO_REGEN          = BIT(27),
96 
97     /// uses male pronouns
98     M_MALE              = BIT(28),
99 
100     /// uses female pronouns
101     M_FEMALE            = BIT(29),
102 
103     /// boneless corpses
104     M_NO_SKELETON       = BIT(30),
105 
106     /// worth 0 xp
107     M_NO_EXP_GAIN       = BIT(31),
108 
109     /// can do damage when attacked in melee
110     M_SPINY             = BIT(32),
111 
112                         //BIT(33),
113 
114     /// not a valid polymorph target (but can be polymorphed)
115     M_NO_POLY_TO        = BIT(34),
116 
117     /// An ancestor granted by Hepliaklqana
118     M_ANCESTOR          = BIT(35),
119 
120                         //BIT(36), // was M_ALWAYS_CORPSE
121 
122     /// prefer ranged attacks over melee
123     M_PREFER_RANGED     = BIT(37),
124 
125                         //BIT(38), // was M_ARTIFICIAL
126 
127     /// can survive without breathing; immune to asphyxiation and Mephitic Cloud
128     M_UNBREATHING       = BIT(39),
129 
130     /// not fully coded; causes a warning
131     M_UNFINISHED        = BIT(40),
132 
133     M_HERD              = BIT(41),
134 
135     // has a double-sized tile
136     M_TALL_TILE         = BIT(42),
137 
138                         //BIT(43), // was M_WEB_SENSE
139 
140     /// tries to maintain LOS/2 range from its target
141     M_MAINTAIN_RANGE    = BIT(44),
142 
143     /// flesh is not usable for making zombies
144     M_NO_ZOMBIE         = BIT(45),
145 
146     /// cannot be placed by any means, even in the arena, etc.
147     M_CANT_SPAWN        = BIT(46),
148 
149     /// derived undead can't be randomly generated
150     M_NO_GEN_DERIVED    = BIT(47),
151 
152     /// only generate when bands are permitted
153     M_REQUIRE_BAND      = BIT(48),
154 
155                         //BIT(49), // was M_HYBRID
156 
157                         //BIT(50),
158 
159     /// monster is a projectile (just OOD right now)
160     M_PROJECTILE        = BIT(51),
161 
162     /// monster is an "avatar" (no independent attacks, only support)
163     M_AVATAR            = BIT(52),
164 
165                         //BIT(53),
166 
167     /// monster is a proxy for a charm/conjuration spell (ball lightning, etc.)
168     M_CONJURED          = BIT(54),
169 
170     /// monster will never harm the player
171     M_NO_THREAT         = BIT(55),
172 
173     /// monster always receives a wand
174     M_ALWAYS_WAND       = BIT(56),
175 
176     /// uses they/them pronouns
177     M_GENDER_NEUTRAL    = BIT(57),
178 
179     /// is surrounded by a ring of clouds. Only one can be active at a time!
180     M_THUNDER_RING      = BIT(58),
181     M_FIRE_RING         = BIT(59),
182 };
183 DEF_BITFIELD(monclass_flags_t, monclass_flag_type);
184 
185 /// Properties of specific monsters.
186 enum monster_flag_type : uint64_t
187 {
188     MF_NO_FLAGS           = 0,
189     /// no benefit from killing
190     MF_NO_REWARD          = BIT(0),
191     /// monster skips next available action
192     MF_JUST_SUMMONED      = BIT(1),
193     /// is following player through stairs
194     MF_TAKING_STAIRS      = BIT(2),
195 
196     //                      BIT(3),
197 
198     /// Player has already seen monster
199     MF_SEEN               = BIT(4),
200     /// A known shapeshifter.
201     MF_KNOWN_SHIFTER      = BIT(5),
202     /// Monster that has been banished.
203     MF_BANISHED           = BIT(6),
204 
205     /// Summoned, should not drop gear on reset
206     MF_HARD_RESET         = BIT(7),
207     /// mirror to CREATED_FRIENDLY for neutrals
208     MF_WAS_NEUTRAL        = BIT(8),
209     /// Saw player and attitude changed (or not); currently used for holy
210     /// beings (good god worshippers -> neutral) orcs (Beogh worshippers
211     /// -> friendly), and slimes (Jiyva worshippers -> neutral)
212     MF_ATT_CHANGE_ATTEMPT = BIT(9),
213     /// Was in view during previous turn.
214     MF_WAS_IN_VIEW        = BIT(10),
215 
216     /// Created as a member of a band
217     MF_BAND_MEMBER        = BIT(11),
218     /// Monter has been pacified
219     MF_PACIFIED           = BIT(12),
220     /// Consider this monster to have MH_UNDEAD holiness, regardless
221     /// of its actual type
222     MF_FAKE_UNDEAD        = BIT(13),
223     /// An undead monster soul enslaved by
224     /// Yredelemnul's power
225     MF_ENSLAVED_SOUL      = BIT(14),
226 
227     /// mname is a suffix.
228     MF_NAME_SUFFIX        = BIT(15),
229     /// mname is an adjective (prefix).
230     MF_NAME_ADJECTIVE     = BIT(16),
231     /// mname entirely replaces normal monster name.
232     MF_NAME_REPLACE       = MF_NAME_SUFFIX|MF_NAME_ADJECTIVE,
233     /// Is a god gift.
234     MF_GOD_GIFT           = BIT(17),
235     /// Is running away from player sanctuary
236     MF_FLEEING_FROM_SANCTUARY = BIT(18),
237     /// Is being killed with disintegration
238     MF_EXPLODE_KILL       = BIT(19),
239 
240     // These are based on the flags in monster class, but can be set for
241     // monsters that are not normally fighters (in vaults).
242 
243     /// Monster is skilled fighter.
244     MF_FIGHTER            = BIT(20),
245     /// Monster wields two weapons.
246     MF_TWO_WEAPONS        = BIT(21),
247     /// Monster gets various archery boosts.
248     MF_ARCHER             = BIT(22),
249 
250                           //BIT(23),
251                           //BIT(24),
252                           //BIT(25),
253 
254     /// This monster cannot regenerate.
255     MF_NO_REGEN           = BIT(26),
256 
257     /// mname should be treated with normal grammar, ie, prevent
258     /// "You hit red rat" and other such constructs.
259     MF_NAME_DESCRIPTOR    = BIT(27),
260     /// give this monster the definite "the" article, instead of the
261     /// indefinite "a" article.
262     MF_NAME_DEFINITE      = BIT(28),
263     /// living monster revived by a lost soul
264     MF_SPECTRALISED       = BIT(29),
265     /// is a demonic_guardian
266     MF_DEMONIC_GUARDIAN   = BIT(30),
267     /// mname should be used for corpses as well
268     MF_NAME_SPECIES       = BIT(31),
269     /// mname replaces "zombie" etc.; use only for already zombified monsters
270     MF_NAME_ZOMBIE        = BIT(32),
271     /// Player has been warned about this monster being nearby.
272     MF_SENSED             = BIT(33),
273     /// mname should not be used for corpses
274     MF_NAME_NOCORPSE      = BIT(34),
275     /// known to have a ranged attack
276     MF_SEEN_RANGED        = BIT(35),
277 
278     /// this monster has been polymorphed.
279     MF_POLYMORPHED        = BIT(36),
280     /// just got hibernated/slept
281     MF_JUST_SLEPT         = BIT(37),
282     /// possibly got piety with TSO
283     MF_TSO_SEEN           = BIT(38),
284 };
285 DEF_BITFIELD(monster_flags_t, monster_flag_type);
286 
287 constexpr monster_flags_t MF_NAME_MASK = MF_NAME_REPLACE;
288 constexpr monster_flags_t MF_MELEE_MASK = MF_FIGHTER | MF_TWO_WEAPONS
289                                         | MF_ARCHER;
290