1 /**
2  * @file
3  * @brief Misc monster related functions.
4 **/
5 
6 #pragma once
7 
8 #include <functional>
9 #include <vector>
10 
11 #include "enum.h"
12 #include "gender-type.h"
13 #include "los-type.h"
14 #include "mon-enum.h"
15 #include "mon-inv-type.h"
16 #include "player.h"
17 
18 using std::vector;
19 
20 struct bolt;
21 struct mgen_data;
22 
23 struct mon_attack_def
24 {
25     attack_type     type;
26     attack_flavour  flavour;
27     int             damage;
28 };
29 
30 // Amount of mons->speed_increment used by different actions; defaults
31 // to 10.
32 #define DEFAULT_ENERGY {10, 10, 10, 10, 10, 10, 10, 100}
33 struct mon_energy_usage
34 {
35     uint8_t move;
36     uint8_t swim;
37     uint8_t attack;
38     uint8_t missile; // Arrows/crossbows/etc
39     uint8_t spell;
40     uint8_t special;
41     uint8_t item;    // Using an item (i.e., drinking a potion)
42 
43     // Percent of mons->speed used when picking up an item; defaults
44     // to 100%
45     uint8_t pickup_percent;
46 
47     static mon_energy_usage attack_cost(int cost, int sw = 10)
48     {
49         mon_energy_usage me = DEFAULT_ENERGY;
50         me.attack = cost;
51         me.swim = sw;
52         return me;
53     }
54 
missile_costmon_energy_usage55     static mon_energy_usage missile_cost(int cost)
56     {
57         mon_energy_usage me = DEFAULT_ENERGY;
58         me.missile = cost;
59         return me;
60     }
61 
swim_costmon_energy_usage62     static mon_energy_usage swim_cost (int cost)
63     {
64         mon_energy_usage me = DEFAULT_ENERGY;
65         me.swim = cost;
66         return me;
67     }
68 
69     static mon_energy_usage move_cost(int mv, int sw = 10)
70     {
71         mon_energy_usage me = DEFAULT_ENERGY;
72         me.move = mv;
73         me.swim = sw;
74         return me;
75     }
76 
77     mon_energy_usage operator | (const mon_energy_usage &o) const
78     {
79         mon_energy_usage me;
80         me.move = combine(move, o.move);
81         me.swim = combine(swim, o.swim);
82         me.attack = combine(attack, o.attack);
83         me.missile = combine(missile, o.missile);
84         me.spell = combine(spell, o.spell);
85         me.special = combine(special, o.special);
86         me.item = combine(item, o.item);
87         me.pickup_percent = combine(pickup_percent, o.pickup_percent, 100);
88         return me;
89     }
90 
91     bool operator == (const mon_energy_usage &rvalue) const
92     {
93         return move == rvalue.move
94                && swim == rvalue.swim
95                && attack == rvalue.attack
96                && missile == rvalue.missile
97                && spell == rvalue.spell
98                && special == rvalue.special
99                && item == rvalue.item
100                && pickup_percent == rvalue.pickup_percent;
101     }
102 private:
103     static uint8_t combine(uint8_t a, uint8_t b, uint8_t def = 10)
104     {
105         return b != def? b : a;
106     }
107 };
108 
109 /// in what ways do a monster's tiles vary?
110 enum mon_type_tile_variation
111 {
112     TVARY_NONE,   ///< fixed tile (or special case)
113     TVARY_MOD,    ///< monster instances have fixed but random tiles
114     TVARY_CYCLE,  ///< cycle through tileset with every redraw
115     TVARY_RANDOM, ///< choose a random tile in set with every redraw
116     TVARY_WATER,  ///< if in water, incr tile enum by 1 (merfolk &c)
117 };
118 
119 /// Tiles display information for a monster type.
120 struct mon_type_tile_info
121 {
122     tileidx_t base; ///< The base tile for the monster type.
123     mon_type_tile_variation variation; ///< How (and if) the tile should vary.
124 };
125 
126 struct monsterentry
127 {
128     short mc;            // monster number
129 
130     char basechar;
131     colour_t colour;
132     const char *name;
133 
134     monclass_flags_t bitfields;
135     resists_t resists;
136 
137     // Multiplier for calculated monster XP value; see exper_value() for use.
138     int8_t exp_mod;
139 
140     monster_type genus,         // "team" the monster plays for
141                  species;       // corpse type of the monster
142 
143     mon_holy_type holiness;
144 
145     short willpower;  // (positive sets value, negative is relative to hd)
146 
147     // max damage in a turn is total of these four?
148     mon_attack_def attack[MAX_NUM_ATTACKS];
149 
150     /// Similar to player level; used for misc purposes.
151     int HD;
152     /// Average hp; multiplied by 10 for precision.
153     int avg_hp_10x;
154 
155     int8_t AC; // armour class
156     int8_t ev; // evasion
157     int sec;   // actually mon_spellbook_type
158     bool leaves_corpse;
159     shout_type         shouts;
160     mon_intel_type     intel;
161     habitat_type     habitat;
162     int8_t           speed;        // How quickly speed_increment increases
163     mon_energy_usage energy_usage; // And how quickly it decreases
164     mon_itemuse_type gmon_use;
165     size_type size;
166     mon_body_shape shape;
167     mon_type_tile_info tile;
168     tileidx_t corpse_tile; // XXX: ideally this would be autogenerated...
169 };
170 
171 enum mon_threat_level_type
172 {
173     MTHRT_TRIVIAL,
174     MTHRT_EASY,
175     MTHRT_TOUGH,
176     MTHRT_NASTY,
177     MTHRT_UNDEF,
178 };
179 
180 void set_resist(resists_t &all, mon_resist_flags res, int lev);
181 
182 // In all cases this will be simplified to a bit field access, so let's let
183 // the compiler inline it.
get_resist(resists_t all,mon_resist_flags res)184 static inline int get_resist(resists_t all, mon_resist_flags res)
185 {
186     if (res > MR_LAST_MULTI)
187         return all & res ? 1 : 0;
188     int v = (all / res) & 7;
189     if (v > 4)
190         return v - 8;
191     return v;
192 }
193 
194 dungeon_feature_type habitat2grid(habitat_type ht);
195 
196 monsterentry *get_monster_data(monster_type mc) IMMUTABLE;
197 int get_mons_class_ac(monster_type mc) IMMUTABLE;
198 int get_mons_class_ev(monster_type mc) IMMUTABLE;
199 resists_t get_mons_class_resists(monster_type mc) IMMUTABLE;
200 resists_t get_mons_resists(const monster& mon);
201 int get_mons_resist(const monster& mon, mon_resist_flags res);
202 bool monster_resists_this_poison(const monster& mons, bool force = false);
203 
204 void init_monsters();
205 void init_monster_symbols();
206 
207 monster *monster_at(const coord_def &pos);
208 
209 // this is the old moname()
210 string mons_type_name(monster_type type, description_level_type desc);
211 
212 bool give_monster_proper_name(monster& mon, bool orcs_only = true);
213 
214 bool mons_flattens_trees(const monster& mon);
215 size_type mons_class_body_size(monster_type mc);
216 bool mons_class_res_polar_vortex(monster_type mc);
217 
218 mon_itemuse_type mons_class_itemuse(monster_type mc);
219 mon_itemuse_type mons_itemuse(const monster& mon);
220 
221 bool mons_can_be_blinded(monster_type mc);
222 bool mons_can_be_dazzled(monster_type mc);
223 
224 int get_shout_noise_level(const shout_type shout);
225 shout_type mons_shouts(monster_type mclass, bool demon_shout = false);
226 bool mons_can_shout(monster_type mclass);
227 
228 bool mons_is_ghost_demon(monster_type mc);
229 bool mons_is_unique(monster_type mc);
230 bool mons_is_or_was_unique(const monster& mon);
231 bool mons_is_pghost(monster_type mc);
232 bool mons_is_draconian_job(monster_type mc);
233 bool mons_is_demonspawn_job(monster_type mc);
234 bool mons_is_job(monster_type mc);
235 bool mons_is_hepliaklqana_ancestor(monster_type mc);
236 
237 int mutant_beast_tier(int xl);
238 
239 int mons_avg_hp(monster_type mc);
240 int mons_max_hp(monster_type mc, monster_type mbase_typeg = MONS_NO_MONSTER);
241 int exper_value(const monster& mon, bool real = true);
242 
243 int hit_points(int avg_hp, int scale = 10);
244 
245 int mons_class_hit_dice(monster_type mc);
246 int mons_class_willpower(monster_type type, monster_type base);
247 bool mons_class_sees_invis(monster_type type, monster_type base);
248 
249 bool mons_invuln_will(const monster& mon);
250 
251 mon_attack_def mons_attack_spec(const monster& mon, int attk_number, bool base_flavour = true);
252 string mon_attack_name(attack_type attack, bool with_object = true);
253 bool is_plain_attack_type(attack_type attack);
254 bool flavour_triggers_damageless(attack_flavour flavour);
255 int flavour_damage(attack_flavour flavour, int HD, bool random = true);
256 bool flavour_has_reach(attack_flavour flavour);
257 
258 bool mons_class_flag(monster_type mc, monclass_flags_t bits);
259 
260 mon_holy_type holiness_by_name(string name);
261 const char * holiness_name(mon_holy_type_flags which_holiness);
262 string holiness_description(mon_holy_type holiness);
263 mon_holy_type mons_class_holiness(monster_type mc);
264 
265 void discover_mimic(const coord_def& pos);
266 void discover_shifter(monster& shifter);
267 
268 bool mons_is_statue(monster_type mc);
269 bool mons_is_demon(monster_type mc);
270 bool mons_is_draconian(monster_type mc);
271 bool mons_is_base_draconian(monster_type mc);
272 bool mons_is_demonspawn(monster_type mc);
273 bool mons_is_conjured(monster_type mc);
274 bool mons_is_beast(monster_type mc);
275 bool mons_is_avatar(monster_type mc);
276 int mons_demon_tier(monster_type mc);
277 
278 bool mons_class_wields_two_weapons(monster_type mc);
279 bool mons_wields_two_weapons(const monster& m);
280 bool mons_self_destructs(const monster& m);
281 bool mons_blows_up(const monster& m);
282 bool mons_destroyed_on_impact(const monster& m);
283 
284 mon_intel_type mons_class_intel(monster_type mc);
285 mon_intel_type mons_intel(const monster& mon);
286 
287 // Use mons_habitat() and mons_primary_habitat() wherever possible,
288 // since the class variants do not handle zombies correctly.
289 habitat_type mons_habitat_type(monster_type t, monster_type base_t,
290                                bool real_amphibious = false);
291 habitat_type mons_habitat(const monster& mon, bool real_amphibious = false);
292 
293 habitat_type mons_class_primary_habitat(monster_type mc);
294 habitat_type mons_primary_habitat(const monster& mon);
295 habitat_type mons_class_secondary_habitat(monster_type mc);
296 habitat_type mons_secondary_habitat(const monster& mon);
297 
298 bool intelligent_ally(const monster& mon);
299 
300 bool mons_skeleton(monster_type mc);
301 bool mons_zombifiable(monster_type mc);
302 
303 int max_corpse_chunks(monster_type mc);
304 int mons_class_base_speed(monster_type mc);
305 mon_energy_usage mons_class_energy(monster_type mc);
306 mon_energy_usage mons_energy(const monster& mon);
307 int mons_class_zombie_base_speed(monster_type zombie_base_mc);
308 int mons_base_speed(const monster& mon, bool known = false);
309 
310 bool monster_class_flies(monster_type mc);
311 bool monster_inherently_flies(const monster &mons);
312 
313 bool mons_class_can_regenerate(monster_type mc);
314 bool mons_can_regenerate(const monster& mon);
315 bool mons_class_fast_regen(monster_type mc);
316 int mons_zombie_size(monster_type mc);
317 monster_type mons_zombie_base(const monster& mon);
318 bool mons_class_is_zombified(monster_type mc);
319 bool mons_class_is_animated_weapon(monster_type type);
320 bool mons_class_is_animated_object(monster_type type);
321 monster_type mons_base_type(const monster& mon);
322 bool mons_class_can_leave_corpse(monster_type mc);
323 bool mons_class_leaves_hide(monster_type mc);
324 bool mons_is_zombified(const monster& mons);
325 bool mons_class_can_be_zombified(monster_type mc);
326 bool mons_can_be_zombified(const monster& mon);
327 bool mons_class_can_use_stairs(monster_type mc);
328 bool mons_class_can_use_transporter(monster_type mc);
329 bool mons_can_use_stairs(const monster& mon,
330                          dungeon_feature_type stair = DNGN_UNSEEN);
331 bool mons_enslaved_body_and_soul(const monster& mon);
332 bool mons_enslaved_soul(const monster& mon);
333 void name_zombie(monster& mon, monster_type mc, const string &mon_name);
334 void name_zombie(monster& mon, const monster& orig);
335 
336 int mons_power(monster_type mc);
337 
338 char32_t mons_char(monster_type mc);
339 char mons_base_char(monster_type mc);
340 
341 int mons_class_colour(monster_type mc);
342 
343 monster_type royal_jelly_ejectable_monster();
344 monster_type random_draconian_monster_species();
345 monster_type random_draconian_job();
346 monster_type random_demonspawn_monster_species();
347 monster_type random_demonspawn_job();
348 
349 bool init_abomination(monster& mon, int hd);
350 void define_monster(monster& mons);
351 
352 void mons_pacify(monster& mon, mon_attitude_type att = ATT_GOOD_NEUTRAL,
353                  bool no_xp = false);
354 
355 bool mons_should_fire(bolt &beam, bool ignore_good_idea = false);
356 
357 bool mons_has_los_ability(monster_type mon_type);
358 bool mons_has_ranged_spell(const monster& mon, bool attack_only = false,
359                            bool ench_too = true);
360 bool mons_has_ranged_attack(const monster& mon);
361 bool mons_can_attack(const monster& mon);
362 bool mons_has_incapacitating_spell(const monster& mon, const actor& foe);
363 bool mons_has_incapacitating_ranged_attack(const monster& mon, const actor& foe);
364 
365 gender_type mons_class_gender(monster_type mc);
366 const char *mons_pronoun(monster_type mon_type, pronoun_type variant,
367                          bool visible = true);
368 
369 bool mons_aligned(const actor *m1, const actor *m2);
370 bool mons_atts_aligned(mon_attitude_type fr1, mon_attitude_type fr2);
371 
372 bool mons_att_wont_attack(mon_attitude_type fr);
373 mon_attitude_type mons_attitude(const monster& m);
374 
375 bool mons_is_native_in_branch(const monster& mons,
376                               const branch_type branch = you.where_are_you);
377 
378 // Whether the monster is temporarily confused (class_too = false)
379 // or confused at all (class_too = true; temporarily or by class).
380 bool mons_is_confused(const monster& m, bool class_too = false);
381 
382 bool mons_is_wandering(const monster& m);
383 bool mons_is_seeking(const monster& m);
384 bool mons_is_fleeing(const monster& m);
385 bool mons_is_retreating(const monster& m);
386 bool mons_is_cornered(const monster& m);
387 bool mons_is_batty(const monster& m);
388 bool mons_is_influenced_by_sanctuary(const monster& m);
389 bool mons_is_fleeing_sanctuary(const monster& m);
390 bool mons_just_slept(const monster& m);
391 bool mons_class_is_slime(monster_type mc);
392 bool mons_is_slime(const monster& mon);
393 bool mons_class_is_plant(monster_type mc);
394 bool mons_class_is_draconic(monster_type mc);
395 bool mons_is_plant(const monster& mon);
396 bool mons_eats_items(const monster& mon);
397 bool actor_is_susceptible_to_vampirism(const actor& act);
398 monster_type mons_genus(monster_type mc);
399 monster_type mons_species(monster_type mc);
400 monster_type draco_or_demonspawn_subspecies(const monster& mon);
401 monster_type draco_or_demonspawn_subspecies(monster_type type,
402                                             monster_type base);
403 monster_type mons_detected_base(monster_type mt);
404 bool mons_is_siren_beholder(monster_type mc);
405 bool mons_is_siren_beholder(const monster& mons);
406 
407 bool mons_is_removed(monster_type mc);
408 
409 bool mons_looks_stabbable(const monster& m);
410 bool mons_looks_distracted(const monster& m);
411 
412 void mons_start_fleeing_from_sanctuary(monster& mons);
413 void mons_stop_fleeing_from_sanctuary(monster& mons);
414 
415 bool mons_class_is_stationary(monster_type mc);
416 bool mons_class_is_firewood(monster_type mc);
417 bool mons_class_is_test(monster_type mc);
418 bool mons_is_firewood(const monster& mon);
419 bool mons_is_active_ballisto(const monster& mon);
420 bool mons_has_body(const monster& mon);
421 bool mons_has_flesh(const monster& mon);
422 bool mons_is_abyssal_only(monster_type mc);
423 bool mons_is_unbreathing(monster_type mc);
424 
425 bool herd_monster(const monster& mon);
426 
427 bool mons_class_requires_band(monster_type mc);
428 
429 int cheibriados_monster_player_speed_delta(const monster& mon);
430 bool cheibriados_thinks_mons_is_fast(const monster& mon);
431 bool mons_is_projectile(monster_type mc);
432 bool mons_is_projectile(const monster& mon);
433 bool mons_is_object(monster_type mc);
434 bool mons_has_blood(monster_type mc);
435 bool mons_is_sensed(monster_type mc);
436 bool mons_allows_beogh(const monster& mon);
437 bool mons_allows_beogh_now(const monster& mon);
438 
439 bool invalid_monster(const monster* mon);
440 bool invalid_monster_type(monster_type mt);
441 bool invalid_monster_index(int i);
442 
443 void mons_load_spells(monster& mon);
444 
445 void mons_remove_from_grid(const monster& mon);
446 
447 bool monster_shover(const monster& m);
448 
449 bool monster_senior(const monster& first, const monster& second,
450                     bool fleeing = false);
451 string ugly_thing_colour_name(colour_t colour);
452 colour_t ugly_thing_random_colour();
453 int str_to_ugly_thing_colour(const string &s);
454 colour_t random_monster_colour();
455 int ugly_thing_colour_offset(colour_t colour);
456 
457 /**
458  * @brief
459  *  Apply uniform colour when generating a band containing only ugly things.
460  *
461  * If the passed band does not contain only ugly things, @p mg is not modified.
462  *
463  * @param mg
464  *  The generation data to adjust.
465  * @param band_monsters
466  *  The array of monsters types comprising the band.
467  * @param num_monsters_in_band
468  *  The number of elements in @p band_monsters.
469  */
470 void ugly_thing_apply_uniform_band_colour(mgen_data &mg,
471     const monster_type *band_monsters, size_t num_monsters_in_band);
472 
473 string  draconian_colour_name(monster_type mon_type);
474 monster_type draconian_colour_by_name(const string &colour);
475 string  demonspawn_base_name(monster_type mon_type);
476 monster_type demonspawn_base_by_name(const string &colour);
477 mon_spell_slot drac_breath(monster_type drac_type);
478 
479 monster_type random_monster_at_grid(const coord_def& p, bool species = false);
480 
481 void         init_mon_name_cache();
482 monster_type get_monster_by_name(string name, bool substring = false);
483 
484 string do_mon_str_replacements(const string &msg, const monster& mons,
485                                int s_type = -1);
486 
487 mon_body_shape get_mon_shape(const monster& mon);
488 mon_body_shape get_mon_shape(const monster_type mc);
489 string get_mon_shape_str(const mon_body_shape shape);
490 bool mon_shape_is_humanoid(mon_body_shape shape);
491 
492 tileidx_t get_mon_base_tile(monster_type mc);
493 mon_type_tile_variation get_mon_tile_variation(monster_type mc);
494 tileidx_t get_mon_base_corpse_tile(monster_type mc);
495 
496 bool mons_class_can_pass(monster_type mc, const dungeon_feature_type grid);
497 bool mons_can_open_door(const monster& mon, const coord_def& pos);
498 bool mons_can_eat_door(const monster& mon, const coord_def& pos);
499 bool mons_can_destroy_door(const monster& mon, const coord_def& pos);
500 bool mons_can_traverse(const monster& mon, const coord_def& pos,
501                        bool only_in_sight = false,
502                        bool checktraps = true);
503 
504 mon_inv_type equip_slot_to_mslot(equipment_type eq);
505 mon_inv_type item_to_mslot(const item_def &item);
506 
507 bool player_or_mon_in_sanct(const monster& mons);
508 bool mons_is_immotile(const monster& mons);
509 
510 int get_dist_to_nearest_monster();
511 bool monster_nearby();
512 actor *actor_by_mid(mid_t m, bool require_valid = false);
513 monster *monster_by_mid(mid_t m, bool require_valid = false);
514 bool mons_is_recallable(const actor* caller, const monster& targ);
515 void init_anon();
516 actor *find_agent(mid_t m, kill_category kc);
517 const char* mons_class_name(monster_type mc);
518 mon_threat_level_type mons_threat_level(const monster &mon,
519                                         bool real = false);
520 int count_monsters(monster_type mtyp, bool friendly_only);
521 int count_allies();
522 
523 bool mons_foe_is_marked(const monster& mons);
524 vector<monster* > get_on_level_followers();
525 
526 bool mons_stores_tracking_data(const monster& mons);
527 
528 bool mons_is_player_shadow(const monster& mon);
529 bool mons_is_wrath_avatar(const monster &mon);
530 
531 bool mons_has_attacks(const monster& mon);
532 
533 void reset_all_monsters();
534 void debug_mondata();
535 void debug_monspells();
536 
537 bool choose_any_monster(const monster& mon);
538 monster *choose_random_nearby_monster(
539     int weight,
540     bool (*suitable)(const monster& mon) =
541         choose_any_monster,
542     bool prefer_named_or_priest = false);
543 
544 monster *choose_random_monster_on_level(
545     int weight,
546     bool (*suitable)(const monster& mon) =
547         choose_any_monster,
548     bool prefer_named_or_priest = false);
549 
550 void update_monster_symbol(monster_type mtype, cglyph_t md);
551 
552 int spell_freq_for_hd(int hd);
553 void normalize_spell_freq(monster_spells &spells, int total_freq);
554 
555 enum mon_dam_level_type
556 {
557     MDAM_OKAY,
558     MDAM_LIGHTLY_DAMAGED,
559     MDAM_MODERATELY_DAMAGED,
560     MDAM_HEAVILY_DAMAGED,
561     MDAM_SEVERELY_DAMAGED,
562     MDAM_ALMOST_DEAD,
563     MDAM_DEAD,
564 };
565 
566 void print_wounds(const monster& mons);
567 bool wounded_damaged(mon_holy_type holi);
568 
569 mon_dam_level_type mons_get_damage_level(const monster& mons);
570 
571 string get_damage_level_string(mon_holy_type holi, mon_dam_level_type mdam);
572 bool mons_class_is_threatening(monster_type mo);
573 bool mons_is_threatening(const monster& mon);
574 bool mons_class_gives_xp(monster_type mc, bool indirect = false);
575 bool mons_gives_xp(const monster& mon, const actor& agent);
576 bool mons_is_notable(const monster& mon);
577 
578 bool mons_class_is_fragile(monster_type mc);
579 bool mons_is_fragile(const monster& mons);
580 
581 int max_mons_charge(monster_type m);
582 
583 void init_mutant_beast(monster &mon, short HD, vector<int> beast_facets);
584 
585 void radiate_pain_bond(const monster& mon, int damage,
586                        const monster* original_target);
587 void throw_monster_bits(const monster& mon);
588 
589 void set_ancestor_spells(monster &ancestor, bool notify = false);
590 
591 typedef function<bool (monster& mon)> monster_func;
592 bool apply_monsters_around_square(monster_func mf, const coord_def& where,
593                                   int radius = 1);
594 bool apply_visible_monsters(monster_func mf,
595                             const coord_def& center = you.pos(),
596                             los_type los = LOS_NO_TRANS);
597 
598 int derived_undead_avg_hp(monster_type mtype, int hd, int scale = 10);
599