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