1 /**
2 * @file
3 * @brief Monsters class methods
4 **/
5
6 #include "AppHdr.h"
7
8 #include <algorithm>
9 #include <functional>
10 #include <queue>
11
12 #include "act-iter.h"
13 #include "areas.h"
14 #include "artefact.h"
15 #include "art-enum.h"
16 #include "attack.h"
17 #include "attitude-change.h"
18 #include "bloodspatter.h"
19 #include "branch.h"
20 #include "cloud.h"
21 #include "colour.h"
22 #include "coordit.h"
23 #include "corpse.h"
24 #include "database.h"
25 #include "delay.h"
26 #include "dgn-event.h"
27 #include "dgn-overview.h"
28 #include "directn.h"
29 #include "english.h"
30 #include "env.h"
31 #include "fight.h"
32 #include "fineff.h"
33 #include "fprop.h"
34 #include "ghost.h"
35 #include "god-abil.h"
36 #include "god-conduct.h"
37 #include "god-item.h"
38 #include "item-name.h"
39 #include "item-prop.h"
40 #include "item-status-flag-type.h"
41 #include "items.h"
42 #include "libutil.h"
43 #include "makeitem.h"
44 #include "message.h"
45 #include "misc.h"
46 #include "mon-abil.h"
47 #include "mon-act.h"
48 #include "mon-behv.h"
49 #include "mon-book.h"
50 #include "mon-cast.h"
51 #include "mon-clone.h"
52 #include "mon-death.h"
53 #include "mon-place.h"
54 #include "mon-poly.h"
55 #include "mon-tentacle.h"
56 #include "mon-transit.h"
57 #include "religion.h"
58 #include "spl-monench.h"
59 #include "spl-summoning.h"
60 #include "spl-util.h"
61 #include "state.h"
62 #include "stringutil.h"
63 #include "tag-version.h"
64 #include "teleport.h"
65 #include "terrain.h"
66 #ifdef USE_TILE
67 #include "tilepick.h"
68 #include "tileview.h"
69 #endif
70 #include "traps.h"
71 #include "view.h"
72 #include "xom.h"
73
monster()74 monster::monster()
75 : hit_points(0), max_hit_points(0),
76 speed(0), speed_increment(0), target(), firing_pos(),
77 patrol_point(), travel_target(MTRAV_NONE), inv(NON_ITEM), spells(),
78 attitude(ATT_HOSTILE), behaviour(BEH_WANDER), foe(MHITYOU),
79 enchantments(), flags(), xp_tracking(XP_NON_VAULT), experience(0),
80 base_monster(MONS_NO_MONSTER), number(0), colour(COLOUR_INHERIT),
81 foe_memory(0), god(GOD_NO_GOD), ghost(), seen_context(SC_NONE),
82 client_id(0), hit_dice(0)
83
84 {
85 type = MONS_NO_MONSTER;
86 travel_path.clear();
87 props.clear();
88 if (crawl_state.game_is_arena())
89 foe = MHITNOT;
90 shield_blocks = 0;
91
92 constricting = 0;
93
94 clear_constricted();
95 went_unseen_this_turn = false;
96 unseen_pos = coord_def(0, 0);
97 }
98
99 // Empty destructor to keep unique_ptr happy with incomplete ghost_demon type.
~monster()100 monster::~monster()
101 {
102 }
103
monster(const monster & mon)104 monster::monster(const monster& mon)
105 {
106 constricting = 0;
107 init_with(mon);
108 }
109
operator =(const monster & mon)110 monster &monster::operator = (const monster& mon)
111 {
112 if (this != &mon)
113 init_with(mon);
114 return *this;
115 }
116
reset()117 void monster::reset()
118 {
119 mname.clear();
120 enchantments.clear();
121 ench_cache.reset();
122 ench_countdown = 0;
123 inv.init(NON_ITEM);
124 spells.clear();
125
126 mid = 0;
127 flags = MF_NO_FLAGS;
128 experience = 0;
129 type = MONS_NO_MONSTER;
130 base_monster = MONS_NO_MONSTER;
131 hit_points = 0;
132 max_hit_points = 0;
133 hit_dice = 0;
134 speed_increment = 0;
135 attitude = ATT_HOSTILE;
136 behaviour = BEH_SLEEP;
137 foe = MHITNOT;
138 summoner = 0;
139 number = 0;
140 damage_friendly = 0;
141 damage_total = 0;
142 shield_blocks = 0;
143 foe_memory = 0;
144 god = GOD_NO_GOD;
145 went_unseen_this_turn = false;
146 unseen_pos = coord_def(0, 0);
147
148 mons_remove_from_grid(*this);
149 target.reset();
150 position.reset();
151 firing_pos.reset();
152 patrol_point.reset();
153 travel_target = MTRAV_NONE;
154 travel_path.clear();
155 ghost.reset(nullptr);
156 seen_context = SC_NONE;
157 props.clear();
158 clear_constricted();
159 // no actual in-game monster should be reset while still constricting
160 ASSERT(!constricting);
161
162 client_id = 0;
163
164 // Just for completeness.
165 speed = 0;
166 colour = COLOUR_INHERIT;
167 }
168
init_with(const monster & mon)169 void monster::init_with(const monster& mon)
170 {
171 reset();
172
173 mid = mon.mid;
174 mname = mon.mname;
175 type = mon.type;
176 base_monster = mon.base_monster;
177 hit_points = mon.hit_points;
178 max_hit_points = mon.max_hit_points;
179 hit_dice = mon.hit_dice;
180 speed = mon.speed;
181 speed_increment = mon.speed_increment;
182 position = mon.position;
183 target = mon.target;
184 firing_pos = mon.firing_pos;
185 patrol_point = mon.patrol_point;
186 travel_target = mon.travel_target;
187 travel_path = mon.travel_path;
188 inv = mon.inv;
189 spells = mon.spells;
190 attitude = mon.attitude;
191 behaviour = mon.behaviour;
192 foe = mon.foe;
193 enchantments = mon.enchantments;
194 ench_cache = mon.ench_cache;
195 flags = mon.flags;
196 experience = mon.experience;
197 number = mon.number;
198 colour = mon.colour;
199 summoner = mon.summoner;
200 foe_memory = mon.foe_memory;
201 god = mon.god;
202 props = mon.props;
203 damage_friendly = mon.damage_friendly;
204 damage_total = mon.damage_total;
205 xp_tracking = mon.xp_tracking;
206
207 if (mon.ghost)
208 ghost.reset(new ghost_demon(*mon.ghost));
209 else
210 ghost.reset(nullptr);
211 }
212
213 uint32_t monster::last_client_id = 0;
214
get_client_id() const215 uint32_t monster::get_client_id() const
216 {
217 return client_id;
218 }
219
reset_client_id()220 void monster::reset_client_id()
221 {
222 client_id = 0;
223 }
224
ensure_has_client_id()225 void monster::ensure_has_client_id()
226 {
227 if (client_id == 0)
228 client_id = ++last_client_id;
229 }
230
temp_attitude() const231 mon_attitude_type monster::temp_attitude() const
232 {
233 if (has_ench(ENCH_INSANE))
234 return ATT_NEUTRAL;
235
236 if (has_ench(ENCH_HEXED))
237 {
238 actor *agent = monster_by_mid(get_ench(ENCH_HEXED).source);
239 if (agent)
240 {
241 ASSERT(agent->is_monster());
242 return agent->as_monster()->attitude;
243 }
244 return ATT_HOSTILE; // ???
245 }
246 if (has_ench(ENCH_CHARM) || has_ench(ENCH_FRIENDLY_BRIBED))
247 return ATT_FRIENDLY;
248 else if (has_ench(ENCH_NEUTRAL_BRIBED))
249 return ATT_GOOD_NEUTRAL; // ???
250 else
251 return attitude;
252 }
253
swimming() const254 bool monster::swimming() const
255 {
256 const dungeon_feature_type grid = env.grid(pos());
257 return feat_is_watery(grid) && mons_primary_habitat(*this) == HT_WATER;
258 }
259
submerged() const260 bool monster::submerged() const
261 {
262 // FIXME, switch to 4.1's MF_SUBMERGED system which is much cleaner.
263 // Can't find any reference to MF_SUBMERGED anywhere. Don't know what
264 // this means. - abrahamwl
265 return has_ench(ENCH_SUBMERGED);
266 }
267
extra_balanced_at(const coord_def p) const268 bool monster::extra_balanced_at(const coord_def p) const
269 {
270 const dungeon_feature_type grid = env.grid(p);
271 return grid == DNGN_SHALLOW_WATER
272 && (mons_genus(type) == MONS_NAGA // tails, not feet
273 || mons_genus(type) == MONS_SALAMANDER
274 || body_size(PSIZE_BODY) >= SIZE_LARGE);
275 }
276
extra_balanced() const277 bool monster::extra_balanced() const
278 {
279 return extra_balanced_at(pos());
280 }
281
282 /**
283 * Monster floundering conditions.
284 *
285 * Floundering reduces movement speed and can cause the monster to fumble
286 * its attacks. It can be caused by water or by Leda's liquefaction.
287 *
288 * @param p Coordinates of position to check.
289 * @return Whether the monster would be floundering at p.
290 */
floundering_at(const coord_def p) const291 bool monster::floundering_at(const coord_def p) const
292 {
293 const dungeon_feature_type grid = env.grid(p);
294 return (liquefied(p)
295 || (feat_is_water(grid)
296 // Can't use monster_habitable_grid() because that'll return
297 // true for non-water monsters in shallow water.
298 && mons_primary_habitat(*this) != HT_WATER
299 // Use real_amphibious to detect giant non-water monsters in
300 // deep water, who flounder despite being treated as amphibious.
301 && mons_habitat(*this, true) != HT_AMPHIBIOUS
302 && !extra_balanced_at(p)))
303 && ground_level();
304 }
305
floundering() const306 bool monster::floundering() const
307 {
308 return floundering_at(pos());
309 }
310
can_pass_through_feat(dungeon_feature_type grid) const311 bool monster::can_pass_through_feat(dungeon_feature_type grid) const
312 {
313 return mons_class_can_pass(mons_base_type(*this), grid);
314 }
315
is_habitable_feat(dungeon_feature_type actual_grid) const316 bool monster::is_habitable_feat(dungeon_feature_type actual_grid) const
317 {
318 return monster_habitable_grid(this, actual_grid);
319 }
320
can_drown() const321 bool monster::can_drown() const
322 {
323 // Presumably a electric eel in lava or a lavafish in deep water could
324 // drown, but that should never happen, so this simple check should
325 // be enough.
326 switch (mons_primary_habitat(*this))
327 {
328 case HT_WATER:
329 case HT_LAVA:
330 case HT_AMPHIBIOUS:
331 return false;
332 default:
333 break;
334 }
335
336 return !is_unbreathing();
337 }
338
body_size(size_part_type,bool) const339 size_type monster::body_size(size_part_type /* psize */, bool /* base */) const
340 {
341 monster_info mi(this, MILEV_NAME);
342 return mi.body_size();
343 }
344
345 /**
346 * Returns brand information from an associated ghost_demon, if any.
347 * Used for player ghosts, illusions, and pan lords. Safe to call if `ghost`
348 * is not set; will just return SPWPN_NORMAL for this case.
349 */
ghost_brand() const350 brand_type monster::ghost_brand() const
351 {
352 if (!ghost || !(type == MONS_PANDEMONIUM_LORD || mons_is_pghost(type)))
353 return SPWPN_NORMAL;
354 return ghost->brand;
355 }
356
357 /**
358 * Is there a ghost_demon associated with this monster that has a brand set?
359 * Used for player ghosts, illusions, and pan lords. Safe to call if `ghost`
360 * is not set.
361 */
has_ghost_brand() const362 bool monster::has_ghost_brand() const
363 {
364 return ghost_brand() != SPWPN_NORMAL;
365 }
366
damage_brand(int which_attack)367 brand_type monster::damage_brand(int which_attack)
368 {
369 const item_def *mweap = weapon(which_attack);
370
371 if (!mweap)
372 return ghost_brand();
373
374 return !is_range_weapon(*mweap) ? static_cast<brand_type>(get_weapon_brand(*mweap))
375 : SPWPN_NORMAL;
376 }
377
damage_type(int which_attack)378 int monster::damage_type(int which_attack)
379 {
380 const item_def *mweap = weapon(which_attack);
381
382 if (!mweap)
383 {
384 const mon_attack_def atk = mons_attack_spec(*this, which_attack);
385 return (atk.type == AT_CLAW) ? DVORP_CLAWING :
386 (atk.type == AT_TENTACLE_SLAP) ? DVORP_TENTACLE
387 : DVORP_CRUSHING;
388 }
389
390 return get_vorpal_type(*mweap);
391 }
392
393 /**
394 * Return the delay caused by attacking with weapon and projectile.
395 *
396 * @param projectile The projectile to be fired/thrown, if any.
397 * @return The time taken by an attack with the monster's weapon
398 * and the given projectile, in aut.
399 */
attack_delay(const item_def * projectile,bool) const400 random_var monster::attack_delay(const item_def *projectile,
401 bool /*rescale*/) const
402 {
403 const item_def* weap = weapon();
404
405 const bool use_unarmed =
406 (projectile) ? is_launched(this, weap, *projectile) != launch_retval::LAUNCHED
407 : !weap;
408
409 if (use_unarmed || !weap)
410 return random_var(10);
411
412 random_var delay(10);
413 if (get_weapon_brand(*weap) == SPWPN_SPEED)
414 delay = div_rand_round(delay * 2, 3);
415 return delay;
416 }
417
has_claws(bool) const418 int monster::has_claws(bool /*allow_tran*/) const
419 {
420 for (int i = 0; i < MAX_NUM_ATTACKS; i++)
421 {
422 const mon_attack_def atk = mons_attack_spec(*this, i);
423 if (atk.type == AT_CLAW)
424 {
425 // Some better criteria would be better.
426 if (body_size() < SIZE_LARGE || atk.damage < 15)
427 return 1;
428 return 3;
429 }
430 }
431
432 return 0;
433 }
434
missiles() const435 item_def *monster::missiles() const
436 {
437 return inv[MSLOT_MISSILE] != NON_ITEM ? &env.item[inv[MSLOT_MISSILE]] : nullptr;
438 }
439
launcher() const440 item_def *monster::launcher() const
441 {
442 item_def *weap = mslot_item(MSLOT_WEAPON);
443 if (weap && is_range_weapon(*weap))
444 return weap;
445
446 weap = mslot_item(MSLOT_ALT_WEAPON);
447 return weap && is_range_weapon(*weap) ? weap : nullptr;
448 }
449
450 // Does not check whether the monster can dual-wield - that is the
451 // caller's responsibility.
_mons_offhand_weapon_index(const monster * m)452 static int _mons_offhand_weapon_index(const monster* m)
453 {
454 return m->inv[MSLOT_ALT_WEAPON];
455 }
456
weapon(int which_attack) const457 item_def *monster::weapon(int which_attack) const
458 {
459 const mon_attack_def attk = mons_attack_spec(*this, which_attack);
460 if (attk.type != AT_HIT && attk.type != AT_WEAP_ONLY)
461 return nullptr;
462
463 // Even/odd attacks use main/offhand weapon.
464 if (which_attack > 1)
465 which_attack &= 1;
466
467 // This randomly picks one of the wielded weapons for monsters that can use
468 // two weapons. Not ideal, but better than nothing. fight.cc does it right,
469 // for various values of right.
470 int weap = inv[MSLOT_WEAPON];
471
472 if (which_attack && mons_wields_two_weapons(*this))
473 {
474 const int offhand = _mons_offhand_weapon_index(this);
475 if (offhand != NON_ITEM
476 && (weap == NON_ITEM || which_attack == 1 || coinflip()))
477 {
478 weap = offhand;
479 }
480 }
481
482 return weap == NON_ITEM ? nullptr : &env.item[weap];
483 }
484
485 /**
486 * Find a monster's melee weapon, if any.
487 *
488 * Finds melee weapons carried in the primary or aux slot; if the monster has
489 * both (dual-wielding), choose one with a coinflip.
490 *
491 * @return A melee weapon that the monster is holding, or null.
492 */
melee_weapon() const493 item_def *monster::melee_weapon() const
494 {
495 item_def* first_weapon = mslot_item(MSLOT_WEAPON);
496 item_def* second_weapon = mslot_item(MSLOT_ALT_WEAPON);
497 const bool primary_is_melee = first_weapon
498 && is_melee_weapon(*first_weapon);
499 const bool secondary_is_melee = second_weapon
500 && is_melee_weapon(*second_weapon);
501 if (primary_is_melee && secondary_is_melee)
502 return random_choose(first_weapon, second_weapon);
503 if (primary_is_melee)
504 return first_weapon;
505 if (secondary_is_melee)
506 return second_weapon;
507 return nullptr;
508 }
509
510 /**
511 * If this is an animated object with some properties determined by an item,
512 * return that item.
513 */
get_defining_object() const514 item_def *monster::get_defining_object() const
515 {
516 // could ASSERT on the inventory checks, but wizmode placement doesn't
517 // really guarantee these items
518 if (mons_class_is_animated_weapon(type) && inv[MSLOT_WEAPON] != NON_ITEM)
519 return &env.item[inv[MSLOT_WEAPON]];
520 else if (type == MONS_ANIMATED_ARMOUR && inv[MSLOT_ARMOUR] != NON_ITEM)
521 return &env.item[inv[MSLOT_ARMOUR]];
522
523 return nullptr;
524 }
525
526 // Give hands required to wield weapon.
hands_reqd(const item_def & item,bool base) const527 hands_reqd_type monster::hands_reqd(const item_def &item, bool base) const
528 {
529 if (mons_genus(type) == MONS_FORMICID)
530 return HANDS_ONE;
531 return actor::hands_reqd(item, base);
532 }
533
can_wield(const item_def & item,bool ignore_curse,bool ignore_brand,bool ignore_shield,bool ignore_transform) const534 bool monster::can_wield(const item_def& item, bool ignore_curse,
535 bool ignore_brand, bool ignore_shield,
536 bool ignore_transform) const
537 {
538 // Monsters can only wield weapons or go unarmed (OBJ_UNASSIGNED
539 // means unarmed).
540 if (item.base_type != OBJ_WEAPONS && item.base_type != OBJ_UNASSIGNED)
541 return false;
542
543 // These *are* weapons, so they can't wield another weapon or
544 // unwield themselves.
545 if (mons_class_is_animated_object(type))
546 return false;
547
548 // MF_HARD_RESET means that all items the monster is carrying will
549 // disappear when it does, so it can't accept new items or give up
550 // the ones it has.
551 if (flags & MF_HARD_RESET)
552 return false;
553
554 // Summoned items can only be held by summoned monsters.
555 if ((item.flags & ISFLAG_SUMMONED) && !is_summoned())
556 return false;
557
558 item_def* weap1 = nullptr;
559 if (inv[MSLOT_WEAPON] != NON_ITEM)
560 weap1 = &env.item[inv[MSLOT_WEAPON]];
561
562 int avail_slots = 1;
563 item_def* weap2 = nullptr;
564 if (mons_wields_two_weapons(*this))
565 {
566 if (!weap1 || hands_reqd(*weap1) != HANDS_TWO)
567 avail_slots = 2;
568
569 const int offhand = _mons_offhand_weapon_index(this);
570 if (offhand != NON_ITEM)
571 weap2 = &env.item[offhand];
572 }
573
574 // If we're already wielding it, then of course we can wield it.
575 if (&item == weap1 || &item == weap2)
576 return true;
577
578 // Barehanded needs two hands.
579 const bool two_handed = item.base_type == OBJ_UNASSIGNED
580 || hands_reqd(item) == HANDS_TWO;
581
582 item_def* _shield = nullptr;
583 if (inv[MSLOT_SHIELD] != NON_ITEM)
584 {
585 ASSERT(!(weap1 && weap2));
586
587 if (two_handed && !ignore_shield)
588 return false;
589
590 _shield = &env.item[inv[MSLOT_SHIELD]];
591 }
592
593 if (!ignore_curse)
594 {
595 int num_cursed = 0;
596 if (weap1 && weap1->cursed())
597 num_cursed++;
598 if (weap2 && weap2->cursed())
599 num_cursed++;
600 if (_shield && _shield->cursed())
601 num_cursed++;
602
603 if (two_handed && num_cursed > 0 || num_cursed >= avail_slots)
604 return false;
605 }
606
607 return could_wield(item, ignore_brand, ignore_transform);
608 }
609
610 /**
611 * Checks whether the monster could ever wield the given item, regardless of
612 * what they're currently wielding or any other state.
613 *
614 * @param item The item to wield.
615 * @param ignore_brand Whether to disregard the item's brand.
616 * @return Whether the monster could potentially wield the
617 * item.
618 */
could_wield(const item_def & item,bool ignore_brand,bool,bool) const619 bool monster::could_wield(const item_def &item, bool ignore_brand,
620 bool /* ignore_transform */, bool /* quiet */) const
621 {
622 ASSERT(item.defined());
623
624 // These *are* weapons, so they can't wield another weapon.
625 if (mons_class_is_animated_object(type))
626 return false;
627
628 // Monsters can't use unrandarts with special effects.
629 if (is_special_unrandom_artefact(item) && !crawl_state.game_is_arena())
630 return false;
631
632 // Wimpy monsters (e.g. kobolds, goblins) can't use halberds, etc.
633 if (is_weapon(item) && !is_weapon_wieldable(item, body_size()))
634 return false;
635
636 if (!ignore_brand)
637 {
638 // Undead and demonic monsters and monsters that are
639 // gifts/worshippers of Yredelemnul won't use holy weapons.
640 if ((undead_or_demonic() || god == GOD_YREDELEMNUL)
641 && is_holy_item(item))
642 {
643 return false;
644 }
645
646 // Holy monsters that aren't gifts/worshippers of chaotic gods
647 // and monsters that are gifts/worshippers of good gods won't
648 // use potentially evil weapons.
649 if (((is_holy() && !is_chaotic_god(god))
650 || is_good_god(god))
651 && is_potentially_evil_item(item))
652 {
653 return false;
654 }
655
656 // Holy monsters and monsters that are gifts/worshippers of good
657 // gods won't use evil weapons.
658 if ((is_holy() || is_good_god(god)) && is_evil_item(item))
659 return false;
660
661 // Monsters that are gifts/worshippers of Zin won't use unclean
662 // weapons.
663 if (god == GOD_ZIN && is_unclean_item(item))
664 return false;
665
666 // Holy monsters that aren't gifts/worshippers of chaotic gods
667 // and monsters that are gifts/worshippers of good gods won't
668 // use chaotic weapons.
669 if (((is_holy() && !is_chaotic_god(god)) || is_good_god(god))
670 && is_chaotic_item(item))
671 {
672 return false;
673 }
674 }
675
676 return true;
677 }
678
can_throw_large_rocks() const679 bool monster::can_throw_large_rocks() const
680 {
681 monster_type species = mons_species(false); // zombies can't
682 return species == MONS_STONE_GIANT
683 || species == MONS_CYCLOPS
684 || species == MONS_OGRE;
685 }
686
can_speak()687 bool monster::can_speak()
688 {
689 if (has_ench(ENCH_MUTE))
690 return false;
691
692 // Priest and wizard monsters can always speak.
693 if (is_priest() || is_actual_spellcaster())
694 return true;
695
696 // Silent or non-sentient monsters can't use the original speech.
697 if (mons_intel(*this) < I_HUMAN || !mons_can_shout(type))
698 return false;
699
700 // Does it have the proper vocal equipment?
701 return mon_shape_is_humanoid(get_mon_shape(*this));
702 }
703
is_silenced() const704 bool monster::is_silenced() const
705 {
706 return silenced(pos())
707 || has_ench(ENCH_MUTE)
708 || (has_ench(ENCH_WATER_HOLD)
709 || has_ench(ENCH_WATERLOGGED))
710 && res_water_drowning() <= 0;
711 }
712
search_slots(function<bool (const mon_spell_slot &)> func) const713 bool monster::search_slots(function<bool (const mon_spell_slot &)> func) const
714 {
715 return any_of(begin(spells), end(spells), func);
716 }
717
search_spells(function<bool (spell_type)> func) const718 bool monster::search_spells(function<bool (spell_type)> func) const
719 {
720 return search_slots([&] (const mon_spell_slot &s)
721 { return func(s.spell); });
722 }
723
has_spell_of_type(spschool discipline) const724 bool monster::has_spell_of_type(spschool discipline) const
725 {
726 return search_spells(bind(spell_typematch, placeholders::_1, discipline));
727 }
728
bind_melee_flags()729 void monster::bind_melee_flags()
730 {
731 // Bind fighter / dual-wielder / archer flags from the base type.
732
733 // Alas, we don't know if the mon is zombified at the moment, if it
734 // is, the flags (other than dual-wielder) will be removed later.
735 if (mons_class_flag(type, M_FIGHTER))
736 flags |= MF_FIGHTER;
737 if (mons_class_flag(type, M_TWO_WEAPONS))
738 flags |= MF_TWO_WEAPONS;
739 if (mons_class_flag(type, M_ARCHER))
740 flags |= MF_ARCHER;
741 }
742
bind_spell_flags()743 void monster::bind_spell_flags()
744 {
745 if (!mons_is_ghost_demon(type) && mons_has_ranged_spell(*this))
746 flags |= MF_SEEN_RANGED;
747 }
748
_needs_ranged_attack(const monster * mon)749 static bool _needs_ranged_attack(const monster* mon)
750 {
751 // Prevent monsters that have conjurations from grabbing missiles.
752 if (mon->has_spell_of_type(spschool::conjuration))
753 return false;
754
755 // Same for summonings, but make an exception for friendlies.
756 if (!mon->friendly() && mon->has_spell_of_type(spschool::summoning))
757 return false;
758
759 // Blademasters don't want to throw stuff.
760 if (mon->type == MONS_DEEP_ELF_BLADEMASTER)
761 return false;
762
763 return true;
764 }
765
can_use_missile(const item_def & item) const766 bool monster::can_use_missile(const item_def &item) const
767 {
768 // Don't allow monsters to pick up missiles without the corresponding
769 // launcher. The opposite is okay, and sufficient wandering will
770 // hopefully take the monster to a stack of appropriate missiles.
771
772 if (!_needs_ranged_attack(this))
773 return false;
774
775 if (item.base_type == OBJ_WEAPONS
776 || item.base_type == OBJ_MISSILES && !has_launcher(item))
777 {
778 return is_throwable(this, item);
779 }
780
781 if (item.base_type != OBJ_MISSILES)
782 return false;
783
784 // Stones are allowed even without launcher.
785 if (item.sub_type == MI_STONE)
786 return true;
787
788 item_def *launch;
789 for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
790 {
791 launch = mslot_item(static_cast<mon_inv_type>(i));
792 if (launch && item.launched_by(*launch))
793 return true;
794 }
795
796 // No fitting launcher in inventory.
797 return false;
798 }
799
800 /**
801 * Does this monster have any interest in using the given wand? (Will they
802 * pick it up?)
803 *
804 * Based purely on monster HD & wand type for now. Higher-HD monsters are less
805 * inclined to bother with wands, especially the weaker ones.
806 *
807 * @param item The wand in question.
808 * @return Whether the monster will bother picking up the wand.
809 */
likes_wand(const item_def & item) const810 bool monster::likes_wand(const item_def &item) const
811 {
812 ASSERT(item.base_type == OBJ_WANDS);
813 // kind of a hack
814 // assumptions:
815 // bad wands are value 48, so won't be used past hd 4
816 // mediocre wands are value 24; won't be used past hd 8
817 // good wands are value 15; won't be used past hd 9
818 // best wands are value 9; won't be used past hd 10
819 // better implementations welcome
820 return wand_charge_value(item.sub_type) + get_hit_dice() * 6 <= 72;
821 }
822
equip_weapon_message(item_def & item)823 void monster::equip_weapon_message(item_def &item)
824 {
825 const string str = " wields " +
826 item.name(DESC_A, false, false, true, false,
827 ISFLAG_CURSED) + ".";
828 simple_monster_message(*this, str.c_str());
829
830 const int brand = get_weapon_brand(item);
831
832 bool message_given = true;
833 switch (brand)
834 {
835 case SPWPN_FLAMING:
836 mpr("It bursts into flame!");
837 break;
838 case SPWPN_FREEZING:
839 mpr(is_range_weapon(item) ? "It is covered in frost."
840 : "It glows with a cold blue light!");
841 break;
842 case SPWPN_HOLY_WRATH:
843 mpr("It softly glows with a divine radiance!");
844 break;
845 case SPWPN_ELECTROCUTION:
846 mprf(MSGCH_SOUND, "You hear the crackle of electricity.");
847 break;
848 case SPWPN_VENOM:
849 mpr("It begins to drip with poison!");
850 break;
851 case SPWPN_DRAINING:
852 mpr("You sense an unholy aura.");
853 break;
854 case SPWPN_DISTORTION:
855 mpr("Its appearance distorts for a moment.");
856 break;
857 case SPWPN_CHAOS:
858 mpr("It is briefly surrounded by a scintillating aura of "
859 "random colours.");
860 break;
861 case SPWPN_PENETRATION:
862 {
863 bool plural = true;
864 string hand = hand_name(true, &plural);
865 mprf("%s %s briefly %s through it before %s %s to get a "
866 "firm grip on it.",
867 pronoun(PRONOUN_POSSESSIVE).c_str(),
868 hand.c_str(),
869 // Not conj_verb: the monster isn't the subject.
870 conjugate_verb("pass", plural).c_str(),
871 pronoun(PRONOUN_SUBJECTIVE).c_str(),
872 conjugate_verb("manage", pronoun_plurality()).c_str());
873 }
874 break;
875 case SPWPN_REAPING:
876 mpr("It is briefly surrounded by shifting shadows.");
877 break;
878 case SPWPN_ACID:
879 mprf("It begins to drip corrosive slime!");
880 break;
881
882 default:
883 // A ranged weapon without special message is known to be unbranded.
884 if (brand != SPWPN_NORMAL || !is_range_weapon(item))
885 message_given = false;
886 }
887
888 if (message_given)
889 {
890 if (is_artefact(item) && !is_unrandom_artefact(item))
891 artefact_learn_prop(item, ARTP_BRAND);
892 else
893 set_ident_flags(item, ISFLAG_KNOW_TYPE);
894 }
895 }
896
897 /**
898 * What AC bonus does the monster get from the given item?
899 *
900 * @param calc_unid Whether to include properties unknown (to the player)
901 * in the calculated result.
902 * @return The AC provided by wearing the given item.
903 */
armour_bonus(const item_def & item,bool calc_unid) const904 int monster::armour_bonus(const item_def &item, bool calc_unid) const
905 {
906 ASSERT(!is_shield(item));
907
908 int armour_ac = property(item, PARM_AC);
909 // For consistency with players, we should multiply this by 1 + (skill/22),
910 // where skill may be HD.
911
912 if (!calc_unid && !item_ident(item, ISFLAG_KNOW_PLUSES))
913 return armour_ac;
914
915 const int armour_plus = item.plus;
916 ASSERT(abs(armour_plus) < 30); // sanity check
917 return armour_ac + armour_plus;
918 }
919
equip_armour_message(item_def & item)920 void monster::equip_armour_message(item_def &item)
921 {
922 const string str = " wears " +
923 item.name(DESC_A) + ".";
924 simple_monster_message(*this, str.c_str());
925 }
926
equip_jewellery_message(item_def & item)927 void monster::equip_jewellery_message(item_def &item)
928 {
929 ASSERT(item.base_type == OBJ_JEWELLERY);
930
931 const string str = " puts on " +
932 item.name(DESC_A) + ".";
933 simple_monster_message(*this, str.c_str());
934 }
935
equip_message(item_def & item)936 void monster::equip_message(item_def &item)
937 {
938 switch (item.base_type)
939 {
940 case OBJ_WEAPONS:
941 case OBJ_STAVES:
942 equip_weapon_message(item);
943 break;
944
945 case OBJ_ARMOUR:
946 equip_armour_message(item);
947 break;
948
949 case OBJ_JEWELLERY:
950 equip_jewellery_message(item);
951 break;
952
953 default:
954 break;
955 }
956 }
957
unequip_weapon(item_def & item,bool msg)958 void monster::unequip_weapon(item_def &item, bool msg)
959 {
960 if (msg)
961 {
962 const string str = " unwields " +
963 item.name(DESC_A, false, false, true, false,
964 ISFLAG_CURSED) + ".";
965 msg = simple_monster_message(*this, str.c_str());
966 }
967
968 const int brand = get_weapon_brand(item);
969 if (msg && brand != SPWPN_NORMAL)
970 {
971 bool message_given = true;
972 switch (brand)
973 {
974 case SPWPN_FLAMING:
975 mpr("It stops flaming.");
976 break;
977
978 case SPWPN_HOLY_WRATH:
979 mpr("It stops glowing.");
980 break;
981
982 case SPWPN_ELECTROCUTION:
983 mpr("It stops crackling.");
984 break;
985
986 case SPWPN_VENOM:
987 mpr("It stops dripping with poison.");
988 break;
989
990 case SPWPN_DISTORTION:
991 mpr("Its appearance distorts for a moment.");
992 break;
993
994 default:
995 message_given = false;
996 }
997 if (message_given)
998 {
999 if (is_artefact(item) && !is_unrandom_artefact(item))
1000 artefact_learn_prop(item, ARTP_BRAND);
1001 else
1002 set_ident_flags(item, ISFLAG_KNOW_TYPE);
1003 }
1004 }
1005
1006 monster *spectral_weapon = find_spectral_weapon(this);
1007 if (spectral_weapon)
1008 end_spectral_weapon(spectral_weapon, false);
1009 }
1010
unequip_armour(item_def & item,bool msg)1011 void monster::unequip_armour(item_def &item, bool msg)
1012 {
1013 if (msg)
1014 {
1015 const string str = " takes off " +
1016 item.name(DESC_A) + ".";
1017 simple_monster_message(*this, str.c_str());
1018 }
1019 }
1020
unequip_jewellery(item_def & item,bool msg)1021 void monster::unequip_jewellery(item_def &item, bool msg)
1022 {
1023 ASSERT(item.base_type == OBJ_JEWELLERY);
1024
1025 if (msg)
1026 {
1027 const string str = " takes off " +
1028 item.name(DESC_A) + ".";
1029 simple_monster_message(*this, str.c_str());
1030 }
1031 }
1032
1033 /**
1034 * Applies appropriate effects when unequipping an item.
1035 *
1036 * Note: this method does NOT modify this->inv to point to NON_ITEM!
1037 * @param item the item to be removed.
1038 * @param msg whether to give a message
1039 * @param force whether to remove the item even if cursed.
1040 * @return whether the item was unequipped successfully.
1041 */
unequip(item_def & item,bool msg,bool force)1042 bool monster::unequip(item_def &item, bool msg, bool force)
1043 {
1044 if (!force && item.cursed())
1045 return false;
1046
1047 switch (item.base_type)
1048 {
1049 case OBJ_WEAPONS:
1050 if (!force && mons_class_is_animated_object(type))
1051 return false;
1052 unequip_weapon(item, msg);
1053 break;
1054
1055 case OBJ_ARMOUR:
1056 if (!force && mons_class_is_animated_object(type))
1057 return false;
1058 unequip_armour(item, msg);
1059 break;
1060
1061 case OBJ_JEWELLERY:
1062 unequip_jewellery(item, msg);
1063 break;
1064
1065 default:
1066 break;
1067 }
1068
1069 return true;
1070 }
1071
lose_pickup_energy()1072 void monster::lose_pickup_energy()
1073 {
1074 if (const monsterentry* entry = find_monsterentry())
1075 {
1076 const int delta = speed * entry->energy_usage.pickup_percent / 100;
1077 if (speed_increment > 25 && delta < speed_increment)
1078 speed_increment -= delta;
1079 }
1080 }
1081
pickup_message(const item_def & item)1082 void monster::pickup_message(const item_def &item)
1083 {
1084 if (is_range_weapon(item)
1085 || is_throwable(this, item)
1086 || item.base_type == OBJ_MISSILES)
1087 {
1088 flags |= MF_SEEN_RANGED;
1089 }
1090
1091 mprf("%s picks up %s.",
1092 name(DESC_THE).c_str(),
1093 item.base_type == OBJ_GOLD ? "some gold"
1094 : item.name(DESC_A).c_str());
1095 }
1096
pickup(item_def & item,mon_inv_type slot,bool msg)1097 bool monster::pickup(item_def &item, mon_inv_type slot, bool msg)
1098 {
1099 ASSERT(item.defined());
1100
1101 const monster* other_mon = item.holding_monster();
1102
1103 if (other_mon != nullptr)
1104 {
1105 if (other_mon == this)
1106 {
1107 if (inv[slot] == item.index())
1108 {
1109 mprf(MSGCH_DIAGNOSTICS, "Monster %s already holding item %s.",
1110 name(DESC_PLAIN, true).c_str(),
1111 item.name(DESC_PLAIN, false, true).c_str());
1112 return false;
1113 }
1114 else
1115 {
1116 mprf(MSGCH_DIAGNOSTICS, "Item %s thinks it's already held by "
1117 "monster %s.",
1118 item.name(DESC_PLAIN, false, true).c_str(),
1119 name(DESC_PLAIN, true).c_str());
1120 }
1121 }
1122 else if (other_mon->type == MONS_NO_MONSTER)
1123 {
1124 mprf(MSGCH_DIAGNOSTICS, "Item %s, held by dead monster, being "
1125 "picked up by monster %s.",
1126 item.name(DESC_PLAIN, false, true).c_str(),
1127 name(DESC_PLAIN, true).c_str());
1128 }
1129 else
1130 {
1131 mprf(MSGCH_DIAGNOSTICS, "Item %s, held by monster %s, being "
1132 "picked up by monster %s.",
1133 item.name(DESC_PLAIN, false, true).c_str(),
1134 other_mon->name(DESC_PLAIN, true).c_str(),
1135 name(DESC_PLAIN, true).c_str());
1136 }
1137 }
1138
1139 // If a monster chooses a two-handed weapon as main weapon, it will
1140 // first have to drop any shield it might wear.
1141 // (Monsters will always favour damage over protection.)
1142 if ((slot == MSLOT_WEAPON || slot == MSLOT_ALT_WEAPON)
1143 && inv[MSLOT_SHIELD] != NON_ITEM
1144 && hands_reqd(item) == HANDS_TWO)
1145 {
1146 if (!drop_item(MSLOT_SHIELD, msg))
1147 return false;
1148 }
1149
1150 // Similarly, monsters won't pick up shields if they're
1151 // wielding (or alt-wielding) a two-handed weapon.
1152 if (slot == MSLOT_SHIELD)
1153 {
1154 const item_def* wpn = mslot_item(MSLOT_WEAPON);
1155 const item_def* alt = mslot_item(MSLOT_ALT_WEAPON);
1156 if (wpn && hands_reqd(*wpn) == HANDS_TWO)
1157 return false;
1158 if (alt && hands_reqd(*alt) == HANDS_TWO)
1159 return false;
1160 }
1161
1162 if (inv[slot] != NON_ITEM)
1163 {
1164 item_def &dest(env.item[inv[slot]]);
1165 if (items_stack(item, dest))
1166 {
1167 dungeon_events.fire_position_event(
1168 dgn_event(DET_ITEM_PICKUP, pos(), 0, item.index(),
1169 mindex()),
1170 pos());
1171
1172 if (msg)
1173 pickup_message(item);
1174 inc_mitm_item_quantity(inv[slot], item.quantity);
1175 destroy_item(item.index());
1176 if (msg)
1177 equip_message(item);
1178 lose_pickup_energy();
1179 return true;
1180 }
1181 return false;
1182 }
1183
1184 // don't try to pick up mimics
1185 if (item.flags & ISFLAG_MIMIC)
1186 return false;
1187
1188 dungeon_events.fire_position_event(
1189 dgn_event(DET_ITEM_PICKUP, pos(), 0, item.index(),
1190 mindex()),
1191 pos());
1192
1193 const int item_index = item.index();
1194 unlink_item(item_index);
1195
1196 inv[slot] = item_index;
1197
1198 item.set_holding_monster(*this);
1199
1200 if (msg)
1201 {
1202 pickup_message(item);
1203 equip_message(item);
1204 }
1205 lose_pickup_energy();
1206 return true;
1207 }
1208
drop_item(mon_inv_type eslot,bool msg)1209 bool monster::drop_item(mon_inv_type eslot, bool msg)
1210 {
1211 int item_index = inv[eslot];
1212 if (item_index == NON_ITEM)
1213 return true;
1214
1215 item_def& pitem = env.item[item_index];
1216
1217 // Unequip equipped items before dropping them; unequip() prevents
1218 // cursed items from being removed.
1219 bool was_unequipped = false;
1220 if (eslot == MSLOT_WEAPON
1221 || eslot == MSLOT_ARMOUR
1222 || eslot == MSLOT_JEWELLERY
1223 || eslot == MSLOT_ALT_WEAPON && mons_wields_two_weapons(*this))
1224 {
1225 if (!unequip(pitem, msg))
1226 return false;
1227 was_unequipped = true;
1228 }
1229
1230 if (pitem.flags & ISFLAG_SUMMONED)
1231 {
1232 if (msg)
1233 {
1234 mprf("%s %s as %s drops %s!",
1235 pitem.name(DESC_THE).c_str(),
1236 summoned_poof_msg(this, pitem).c_str(),
1237 name(DESC_THE).c_str(),
1238 pitem.quantity > 1 ? "them" : "it");
1239 }
1240
1241 item_was_destroyed(pitem);
1242 destroy_item(item_index);
1243 }
1244 else
1245 {
1246 if (msg)
1247 {
1248 mprf("%s drops %s.", name(DESC_THE).c_str(),
1249 pitem.name(DESC_A).c_str());
1250 }
1251 pitem.props[DROPPER_MID_KEY].get_int() = mid;
1252
1253 if (!move_item_to_grid(&item_index, pos(), swimming()))
1254 {
1255 // Re-equip item if we somehow failed to drop it.
1256 if (was_unequipped && msg)
1257 equip_message(pitem);
1258
1259 return false;
1260 }
1261 }
1262
1263 inv[eslot] = NON_ITEM;
1264 return true;
1265 }
1266
pickup_launcher(item_def & launch,bool msg,bool force)1267 bool monster::pickup_launcher(item_def &launch, bool msg, bool force)
1268 {
1269 // Don't allow monsters to pick up launchers that would also
1270 // refuse to pick up the matching ammo.
1271 if (!force && !_needs_ranged_attack(this))
1272 return false;
1273
1274 // Don't allow monsters to switch to another type of launcher
1275 // as that would require them to also drop their ammunition
1276 // and then try to find ammunition for their new launcher.
1277 // However, they may switch to another launcher if they're
1278 // out of ammo. (jpeg)
1279 const int mdam_rating = mons_weapon_damage_rating(launch);
1280 const missile_type mt = fires_ammo_type(launch);
1281 mon_inv_type eslot = NUM_MONSTER_SLOTS;
1282 for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
1283 {
1284 auto slot = static_cast<mon_inv_type>(i);
1285 if (const item_def *elaunch = mslot_item(slot))
1286 {
1287 if (!is_range_weapon(*elaunch))
1288 continue;
1289
1290 return (fires_ammo_type(*elaunch) == mt || !missiles())
1291 && (mons_weapon_damage_rating(*elaunch) < mdam_rating
1292 || mons_weapon_damage_rating(*elaunch) == mdam_rating
1293 && get_weapon_brand(*elaunch) == SPWPN_NORMAL
1294 && get_weapon_brand(launch) != SPWPN_NORMAL)
1295 && drop_item(slot, msg) && pickup(launch, slot, msg);
1296 }
1297 else
1298 eslot = slot;
1299 }
1300
1301 return eslot == NUM_MONSTER_SLOTS ? false : pickup(launch, eslot, msg);
1302 }
1303
_is_signature_weapon(const monster * mons,const item_def & weapon)1304 static bool _is_signature_weapon(const monster* mons, const item_def &weapon)
1305 {
1306 // Don't pick up items that would interfere with our special ability
1307 if (mons->type == MONS_RED_DEVIL)
1308 return item_attack_skill(weapon) == SK_POLEARMS;
1309
1310 // Some other uniques have a signature weapon, usually because they
1311 // always spawn with it, or because it is referenced in their speech
1312 // and/or descriptions.
1313 // Upgrading to a similar type is pretty much always allowed, unless
1314 // we are more interested in the brand, and the brand is *rare*.
1315 if (mons_is_unique(mons->type))
1316 {
1317 weapon_type wtype = (weapon.base_type == OBJ_WEAPONS) ?
1318 (weapon_type)weapon.sub_type : NUM_WEAPONS;
1319
1320 // We might allow Sigmund to pick up a better scythe if he finds
1321 // one...
1322 if (mons->type == MONS_SIGMUND)
1323 return wtype == WPN_SCYTHE;
1324
1325 // Crazy Yiuf's got MONUSE_STARTING_EQUIPMENT right now, but
1326 // in case that ever changes we don't want him to switch away
1327 // from his quarterstaff of chaos.
1328 if (mons->type == MONS_CRAZY_YIUF)
1329 {
1330 return wtype == WPN_QUARTERSTAFF
1331 && get_weapon_brand(weapon) == SPWPN_CHAOS;
1332 }
1333
1334 // Distortion/chaos is immensely flavourful, and we shouldn't
1335 // allow Psyche to switch away from it.
1336 if (mons->type == MONS_PSYCHE)
1337 {
1338 return get_weapon_brand(weapon) == SPWPN_CHAOS
1339 || get_weapon_brand(weapon) == SPWPN_DISTORTION;
1340 }
1341
1342 // Don't switch Azrael away from the customary scimitar of
1343 // flaming.
1344 if (mons->type == MONS_AZRAEL)
1345 {
1346 return wtype == WPN_SCIMITAR
1347 && get_weapon_brand(weapon) == SPWPN_FLAMING;
1348 }
1349
1350 if (mons->type == MONS_AGNES)
1351 return wtype == WPN_LAJATANG;
1352
1353 if (mons->type == MONS_EDMUND)
1354 return wtype == WPN_FLAIL || wtype == WPN_DIRE_FLAIL;
1355
1356 // Pikel's got MONUSE_STARTING_EQUIPMENT right now, but,
1357 // in case that ever changes, we don't want him to switch away
1358 // from a whip.
1359 if (mons->type == MONS_PIKEL)
1360 return get_vorpal_type(weapon) == DVORP_SLASHING;
1361
1362 if (mons->type == MONS_NIKOLA)
1363 return get_weapon_brand(weapon) == SPWPN_ELECTROCUTION;
1364
1365 if (mons->type == MONS_DUVESSA)
1366 {
1367 return item_attack_skill(weapon) == SK_SHORT_BLADES
1368 || item_attack_skill(weapon) == SK_LONG_BLADES;
1369 }
1370
1371 if (mons->type == MONS_IGNACIO)
1372 return wtype == WPN_EXECUTIONERS_AXE;
1373
1374 if (mons->type == MONS_MENNAS)
1375 return get_weapon_brand(weapon) == SPWPN_HOLY_WRATH;
1376
1377 if (mons->type == MONS_ARACHNE)
1378 {
1379 return weapon.is_type(OBJ_STAVES, STAFF_POISON)
1380 || is_unrandom_artefact(weapon, UNRAND_OLGREB);
1381 }
1382
1383 if (mons->type == MONS_FANNAR)
1384 return weapon.is_type(OBJ_STAVES, STAFF_COLD);
1385
1386 // Asterion's demon weapon was a gift from Makhleb.
1387 if (mons->type == MONS_ASTERION)
1388 {
1389 return wtype == WPN_DEMON_BLADE || wtype == WPN_DEMON_WHIP
1390 || wtype == WPN_DEMON_TRIDENT;
1391 }
1392
1393 // Donald kept dropping his shield. I hate that.
1394 if (mons->type == MONS_DONALD)
1395 return mons->hands_reqd(weapon) == HANDS_ONE;
1396
1397 // What kind of assassin would forget her dagger somewhere else?
1398 if (mons->type == MONS_SONJA)
1399 return item_attack_skill(weapon) == SK_SHORT_BLADES;
1400
1401 if (mons->type == MONS_IMPERIAL_MYRMIDON)
1402 return item_attack_skill(weapon) == SK_LONG_BLADES;
1403 }
1404
1405 if (mons->is_holy())
1406 return is_blessed(weapon) || get_weapon_brand(weapon) == SPWPN_HOLY_WRATH;
1407
1408 if (is_unrandom_artefact(weapon))
1409 {
1410 switch (weapon.unrand_idx)
1411 {
1412 case UNRAND_ASMODEUS:
1413 return mons->type == MONS_ASMODEUS;
1414
1415 case UNRAND_DISPATER:
1416 return mons->type == MONS_DISPATER;
1417
1418 case UNRAND_CEREBOV:
1419 return mons->type == MONS_CEREBOV;
1420
1421 case UNRAND_MORG:
1422 return mons->type == MONS_BORIS;
1423 }
1424 }
1425
1426 return false;
1427 }
1428
_ego_damage_bonus(item_def & item)1429 static int _ego_damage_bonus(item_def &item)
1430 {
1431 switch (get_weapon_brand(item))
1432 {
1433 case SPWPN_NORMAL: return 0;
1434 case SPWPN_VORPAL: // deliberate fall through
1435 case SPWPN_PROTECTION: return 1;
1436 default: return 2;
1437 }
1438 }
1439
pickup_melee_weapon(item_def & item,bool msg)1440 bool monster::pickup_melee_weapon(item_def &item, bool msg)
1441 {
1442 // Draconian monks are masters of unarmed combat.
1443 // Monstrous demonspawn prefer to RIP AND TEAR with their claws.
1444 // XXX: this could probably be a monster flag
1445 if (type == MONS_DRACONIAN_MONK
1446 || mons_is_demonspawn(type)
1447 && draco_or_demonspawn_subspecies(*this) == MONS_MONSTROUS_DEMONSPAWN)
1448 {
1449 return false;
1450 }
1451
1452 const bool dual_wielding = mons_wields_two_weapons(*this);
1453 if (dual_wielding)
1454 {
1455 // If we have either weapon slot free, pick up the weapon.
1456 if (inv[MSLOT_WEAPON] == NON_ITEM)
1457 return pickup(item, MSLOT_WEAPON, msg);
1458
1459 if (inv[MSLOT_ALT_WEAPON] == NON_ITEM)
1460 return pickup(item, MSLOT_ALT_WEAPON, msg);
1461 }
1462
1463 const int new_wpn_dam = mons_weapon_damage_rating(item)
1464 + _ego_damage_bonus(item);
1465 mon_inv_type eslot = NUM_MONSTER_SLOTS;
1466 item_def *weap;
1467
1468 // Monsters have two weapon slots, one of which can be a ranged, and
1469 // the other a melee weapon. (The exception being dual-wielders who can
1470 // wield two melee weapons). The weapon in MSLOT_WEAPON is the one
1471 // currently wielded (can be empty).
1472
1473 for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
1474 {
1475 auto slot = static_cast<mon_inv_type>(i);
1476 weap = mslot_item(slot);
1477
1478 if (!weap)
1479 {
1480 // If no weapon in this slot, mark this one.
1481 if (eslot == NUM_MONSTER_SLOTS)
1482 eslot = slot;
1483 }
1484 else
1485 {
1486 if (is_range_weapon(*weap))
1487 continue;
1488
1489 // Don't swap from a signature weapon to a non-signature one.
1490 if (!_is_signature_weapon(this, item)
1491 && _is_signature_weapon(this, *weap))
1492 {
1493 if (dual_wielding)
1494 continue;
1495 else
1496 return false;
1497 }
1498
1499 // If we get here, the weapon is a melee weapon.
1500 // If the new weapon is better than the current one and not cursed,
1501 // replace it. Otherwise, give up.
1502 const int old_wpn_dam = mons_weapon_damage_rating(*weap)
1503 + _ego_damage_bonus(*weap);
1504
1505 bool new_wpn_better = new_wpn_dam > old_wpn_dam;
1506 if (new_wpn_dam == old_wpn_dam)
1507 {
1508 // Use shopping value as a crude estimate of resistances etc.
1509 // XXX: This is not really logical as many properties don't
1510 // apply to monsters (e.g. flight, blink, berserk).
1511 // For simplicity, don't apply this check to secondary weapons
1512 // for dual wielding monsters.
1513 int oldval = item_value(*weap, true);
1514 int newval = item_value(item, true);
1515
1516 if (newval > oldval)
1517 new_wpn_better = true;
1518 }
1519
1520 if (new_wpn_better && !weap->cursed())
1521 {
1522 if (!dual_wielding
1523 || slot == MSLOT_WEAPON
1524 || old_wpn_dam
1525 < mons_weapon_damage_rating(*mslot_item(MSLOT_WEAPON))
1526 + _ego_damage_bonus(*mslot_item(MSLOT_WEAPON)))
1527 {
1528 eslot = slot;
1529 if (!dual_wielding)
1530 break;
1531 }
1532 }
1533 else if (!dual_wielding)
1534 {
1535 // Only dual wielders want two melee weapons.
1536 return false;
1537 }
1538 }
1539 }
1540
1541 // No slot found to place this item.
1542 if (eslot == NUM_MONSTER_SLOTS)
1543 return false;
1544
1545 // Current item cannot be dropped.
1546 if (inv[eslot] != NON_ITEM && !drop_item(eslot, msg))
1547 return false;
1548
1549 return pickup(item, eslot, msg);
1550 }
1551
wants_weapon(const item_def & weap) const1552 bool monster::wants_weapon(const item_def &weap) const
1553 {
1554 if (!could_wield(weap))
1555 return false;
1556
1557 // Blademasters and master archers like their starting weapon and
1558 // don't want another, thank you.
1559 if (type == MONS_DEEP_ELF_BLADEMASTER
1560 || type == MONS_DEEP_ELF_MASTER_ARCHER)
1561 {
1562 return false;
1563 }
1564
1565 // Monsters capable of dual-wielding will always prefer two weapons
1566 // to a single two-handed one, however strong.
1567 if (mons_wields_two_weapons(*this)
1568 && hands_reqd(weap) == HANDS_TWO)
1569 {
1570 return false;
1571 }
1572
1573 // Don't pick up a new weapon if we've been gifted one by the player.
1574 if (is_range_weapon(weap) && props.exists(BEOGH_RANGE_WPN_GIFT_KEY))
1575 return false;
1576 else if (props.exists(BEOGH_MELEE_WPN_GIFT_KEY))
1577 return false;
1578
1579 // Arcane spellcasters don't want -Cast.
1580 if (is_actual_spellcaster()
1581 && is_artefact(weap)
1582 && artefact_property(weap, ARTP_PREVENT_SPELLCASTING))
1583 {
1584 return false;
1585 }
1586
1587 // Nobody picks up giant clubs. Starting equipment is okay, of course.
1588 if (is_giant_club_type(weap.sub_type))
1589 return false;
1590
1591 return true;
1592 }
1593
wants_armour(const item_def & item) const1594 bool monster::wants_armour(const item_def &item) const
1595 {
1596 // Monsters that are capable of dual wielding won't pick up shields.
1597 // Neither will monsters that are already wielding a two-hander.
1598 if (is_shield(item)
1599 && (mons_wields_two_weapons(*this)
1600 || mslot_item(MSLOT_WEAPON)
1601 && hands_reqd(*mslot_item(MSLOT_WEAPON))
1602 == HANDS_TWO))
1603 {
1604 return false;
1605 }
1606
1607 // Don't pick up new armour if we've been gifted something by the player.
1608 if (is_shield(item) && props.exists(BEOGH_SH_GIFT_KEY))
1609 return false;
1610 else if (props.exists(BEOGH_ARM_GIFT_KEY))
1611 return false;
1612
1613 // Spellcasters won't pick up restricting armour, although they can
1614 // start with one. Applies to arcane spells only, of course.
1615 if (!pos().origin() && is_actual_spellcaster()
1616 && (property(item, PARM_EVASION) / 10 < -5
1617 || is_artefact(item)
1618 && artefact_property(item, ARTP_PREVENT_SPELLCASTING)))
1619 {
1620 return false;
1621 }
1622
1623 // Returns whether this armour is the monster's size.
1624 return check_armour_size(item, body_size());
1625 }
1626
wants_jewellery(const item_def & item) const1627 bool monster::wants_jewellery(const item_def &item) const
1628 {
1629 // Arcane spellcasters don't want -Cast.
1630 if (is_actual_spellcaster()
1631 && is_artefact(item)
1632 && artefact_property(item, ARTP_PREVENT_SPELLCASTING))
1633 {
1634 return false;
1635 }
1636
1637 // TODO: figure out what monsters actually want rings or amulets
1638 return true;
1639 }
1640
1641 // Monsters magically know the real properties of all items.
_get_monster_armour_value(const monster * mon,const item_def & item)1642 static int _get_monster_armour_value(const monster *mon,
1643 const item_def &item)
1644 {
1645 // Each resistance/property counts as much as 1 point of AC.
1646 // Steam has been excluded because of its general uselessness.
1647 int value = item.armour_rating()
1648 + get_armour_res_fire(item, true)
1649 + get_armour_res_cold(item, true)
1650 + get_armour_res_elec(item, true)
1651 + get_armour_res_corr(item);
1652
1653 // Give a simple bonus, no matter the size of the WL bonus.
1654 if (get_armour_willpower(item, true) > 0)
1655 value++;
1656
1657 // Poison becomes much less valuable if the monster is
1658 // intrinsically resistant.
1659 if (get_mons_resist(*mon, MR_RES_POISON) <= 0)
1660 value += get_armour_res_poison(item, true);
1661
1662 // Same for life protection.
1663 if (mon->holiness() & MH_NATURAL)
1664 value += get_armour_life_protection(item, true);
1665
1666 // See invisible also is only useful if not already intrinsic.
1667 if (!mons_class_flag(mon->type, M_SEE_INVIS))
1668 value += get_armour_see_invisible(item, true);
1669
1670 // Give a sizable bonus for shields of reflection.
1671 if (get_armour_ego_type(item) == SPARM_REFLECTION)
1672 value += 3;
1673
1674 // Another sizable bonus for rampaging.
1675 if (get_armour_rampaging(item, true))
1676 value += 5;
1677
1678 return value;
1679 }
1680
1681 /**
1682 * Attempt to have a monster pick up and wear the given armour item.
1683 * @param item The item in question.
1684 * @param msg Whether to print a message
1685 * @param force If true, force the monster to pick up and wear the item.
1686 * @return True if the monster picks up and wears the item, false otherwise.
1687 */
pickup_armour(item_def & item,bool msg,bool force)1688 bool monster::pickup_armour(item_def &item, bool msg, bool force)
1689 {
1690 ASSERT(item.base_type == OBJ_ARMOUR);
1691
1692 if (!force && !wants_armour(item))
1693 return false;
1694
1695 const monster_type genus = mons_genus(mons_species(true));
1696 const monster_type base_type = mons_is_zombified(*this) ? base_monster
1697 : type;
1698 equipment_type eq = EQ_NONE;
1699
1700 // HACK to allow nagas to wear bardings. (jpeg)
1701 switch (item.sub_type)
1702 {
1703 case ARM_BARDING:
1704 if (genus == MONS_NAGA || genus == MONS_SALAMANDER
1705 || genus == MONS_CENTAUR || genus == MONS_YAKTAUR)
1706 {
1707 eq = EQ_BODY_ARMOUR;
1708 }
1709 break;
1710 // And another hack or two...
1711 case ARM_HAT:
1712 if (base_type == MONS_GASTRONOK || genus == MONS_OCTOPODE)
1713 eq = EQ_BODY_ARMOUR;
1714 break;
1715 case ARM_CLOAK:
1716 if (base_type == MONS_MAURICE
1717 || base_type == MONS_NIKOLA
1718 || base_type == MONS_CRAZY_YIUF
1719 || genus == MONS_DRACONIAN)
1720 {
1721 eq = EQ_BODY_ARMOUR;
1722 }
1723 break;
1724 case ARM_GLOVES:
1725 if (base_type == MONS_NIKOLA)
1726 eq = EQ_SHIELD;
1727 break;
1728 case ARM_HELMET:
1729 if (base_type == MONS_ROBIN)
1730 eq = EQ_SHIELD;
1731 break;
1732 default:
1733 eq = get_armour_slot(item);
1734
1735 if (eq == EQ_BODY_ARMOUR && genus == MONS_DRACONIAN)
1736 return false;
1737
1738 if (eq != EQ_HELMET && base_type == MONS_GASTRONOK)
1739 return false;
1740
1741 if (eq != EQ_HELMET && eq != EQ_SHIELD
1742 && genus == MONS_OCTOPODE)
1743 {
1744 return false;
1745 }
1746 }
1747
1748 // Bardings are only wearable by the appropriate monster.
1749 if (eq == EQ_NONE)
1750 return false;
1751
1752 // XXX: Monsters can only equip body armour and shields (as of 0.4).
1753 if (!force && eq != EQ_BODY_ARMOUR && eq != EQ_SHIELD)
1754 return false;
1755
1756 const mon_inv_type mslot = equip_slot_to_mslot(eq);
1757 if (mslot == NUM_MONSTER_SLOTS)
1758 return false;
1759
1760 int value_new = _get_monster_armour_value(this, item);
1761
1762 // No armour yet -> get this one.
1763 if (!mslot_item(mslot) && value_new > 0)
1764 return pickup(item, mslot, msg);
1765
1766 // Simplistic armour evaluation (comparing AC and resistances).
1767 if (const item_def *existing_armour = slot_item(eq, false))
1768 {
1769 if (!force)
1770 {
1771 int value_old = _get_monster_armour_value(this,
1772 *existing_armour);
1773 if (value_old > value_new)
1774 return false;
1775
1776 if (value_old == value_new)
1777 {
1778 // If items are of the same value, use shopping
1779 // value as a further crude estimate.
1780 value_old = item_value(*existing_armour, true);
1781 value_new = item_value(item, true);
1782 }
1783 if (value_old >= value_new)
1784 return false;
1785 }
1786
1787 if (!drop_item(mslot, msg))
1788 return false;
1789 }
1790
1791 return pickup(item, mslot, msg);
1792 }
1793
_get_monster_jewellery_value(const monster * mon,const item_def & item)1794 static int _get_monster_jewellery_value(const monster *mon,
1795 const item_def &item)
1796 {
1797 ASSERT(item.base_type == OBJ_JEWELLERY);
1798
1799 // Each resistance/property counts as one point.
1800 int value = 0;
1801
1802 if (item.sub_type == RING_PROTECTION
1803 || item.sub_type == RING_EVASION
1804 || item.sub_type == RING_SLAYING)
1805 {
1806 value += item.plus;
1807 }
1808
1809 value += get_jewellery_res_fire(item, true);
1810 value += get_jewellery_res_cold(item, true);
1811 value += get_jewellery_res_elec(item, true);
1812
1813 // Give a simple bonus, no matter the size of the WL bonus.
1814 if (get_jewellery_willpower(item, true) > 0)
1815 value++;
1816
1817 // Poison becomes much less valuable if the monster is
1818 // intrinsically resistant.
1819 if (get_mons_resist(*mon, MR_RES_POISON) <= 0)
1820 value += get_jewellery_res_poison(item, true);
1821
1822 // Same for life protection.
1823 if (mon->holiness() & MH_NATURAL)
1824 value += get_jewellery_life_protection(item, true);
1825
1826 // See invisible also is only useful if not already intrinsic.
1827 if (!mons_class_flag(mon->type, M_SEE_INVIS))
1828 value += get_jewellery_see_invisible(item, true);
1829
1830 // If we're not naturally corrosion-resistant.
1831 if (item.sub_type == RING_RESIST_CORROSION && !mon->res_corr(false, false))
1832 value++;
1833
1834 return value;
1835 }
1836
pickup_jewellery(item_def & item,bool msg,bool force)1837 bool monster::pickup_jewellery(item_def &item, bool msg, bool force)
1838 {
1839 ASSERT(item.base_type == OBJ_JEWELLERY);
1840
1841 if (!force && !wants_jewellery(item))
1842 return false;
1843
1844 equipment_type eq = EQ_RINGS;
1845
1846 const mon_inv_type mslot = equip_slot_to_mslot(eq);
1847 if (mslot == NUM_MONSTER_SLOTS)
1848 return false;
1849
1850 int value_new = _get_monster_jewellery_value(this, item);
1851
1852 // No armour yet -> get this one.
1853 if (!mslot_item(mslot) && value_new > 0)
1854 return pickup(item, mslot, msg);
1855
1856 // Simplistic jewellery evaluation (comparing AC and resistances).
1857 if (const item_def *existing_jewellery = slot_item(eq, false))
1858 {
1859 if (!force)
1860 {
1861 int value_old = _get_monster_jewellery_value(this,
1862 *existing_jewellery);
1863 if (value_old > value_new)
1864 return false;
1865
1866 if (value_old == value_new)
1867 {
1868 // If items are of the same value, use shopping
1869 // value as a further crude estimate.
1870 value_old = item_value(*existing_jewellery, true);
1871 value_new = item_value(item, true);
1872 if (value_old >= value_new)
1873 return false;
1874 }
1875 }
1876
1877 if (!drop_item(mslot, msg))
1878 return false;
1879 }
1880
1881 return pickup(item, mslot, msg);
1882 }
1883
pickup_weapon(item_def & item,bool msg,bool force)1884 bool monster::pickup_weapon(item_def &item, bool msg, bool force)
1885 {
1886 if (!force && !wants_weapon(item))
1887 return false;
1888
1889 // Weapon pickup involves:
1890 // - If we have no weapons, always pick this up.
1891 // - If this is a melee weapon and we already have a melee weapon, pick
1892 // it up if it is superior to the one we're carrying (and drop the
1893 // one we have).
1894 // - If it is a ranged weapon, and we already have a ranged weapon,
1895 // pick it up if it is better than the one we have.
1896
1897 if (is_range_weapon(item))
1898 return pickup_launcher(item, msg, force);
1899
1900 if (pickup_melee_weapon(item, msg))
1901 return true;
1902
1903 return false;
1904 }
1905
1906 /**
1907 * Have a monster pick up a missile item.
1908 *
1909 * @param item The item to pick up.
1910 * @param msg Whether to print a message about the pickup.
1911 * @param force If true, the monster will always try to pick up the item.
1912 * @return True if the monster picked up the missile, false otherwise.
1913 */
pickup_missile(item_def & item,bool msg,bool force)1914 bool monster::pickup_missile(item_def &item, bool msg, bool force)
1915 {
1916 const item_def *miss = missiles();
1917
1918 if (!force)
1919 {
1920 if (item.sub_type == MI_THROWING_NET)
1921 {
1922 // Monster may not pick up trapping net.
1923 if (caught() && item_is_stationary_net(item))
1924 return false;
1925 }
1926 else // None of these exceptions hold for throwing nets.
1927 {
1928 // Spellcasters should not waste time with ammunition.
1929 // Neither summons nor debuffs are counted for this purpose.
1930 if (!force && mons_has_ranged_spell(*this, true, false))
1931 return false;
1932
1933 // Monsters in a fight will only pick up missiles if doing so
1934 // is worthwhile.
1935 if (!mons_is_wandering(*this)
1936 && foe != MHITYOU
1937 && (item.quantity < 5 || miss && miss->quantity >= 7))
1938 {
1939 return false;
1940 }
1941 }
1942 }
1943
1944 if (miss && items_stack(*miss, item))
1945 return pickup(item, MSLOT_MISSILE, msg);
1946
1947 if (!force && !can_use_missile(item))
1948 return false;
1949
1950 if (miss)
1951 {
1952 item_def *launch;
1953 for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
1954 {
1955 launch = mslot_item(static_cast<mon_inv_type>(i));
1956 if (launch)
1957 {
1958 const int item_brand = get_ammo_brand(item);
1959 // If this ammunition is better, drop the old ones.
1960 // Don't upgrade to ammunition whose brand cancels the
1961 // launcher brand or doesn't improve it further.
1962 // Don't drop huge stacks for tiny stacks.
1963 if (item.launched_by(*launch)
1964 && (!miss->launched_by(*launch)
1965 || item.sub_type == MI_SLING_BULLET
1966 && miss->sub_type == MI_STONE
1967 || get_ammo_brand(*miss) == SPMSL_NORMAL
1968 && item_brand != SPMSL_NORMAL)
1969 && item.quantity * 2 > miss->quantity)
1970 {
1971 if (!drop_item(MSLOT_MISSILE, msg))
1972 return false;
1973 break;
1974 }
1975 }
1976 }
1977
1978 // Allow upgrading throwing weapon brands (XXX: improve this!)
1979 if (item.sub_type == miss->sub_type
1980 && (item.sub_type == MI_BOOMERANG || item.sub_type == MI_JAVELIN)
1981 && get_ammo_brand(*miss) == SPMSL_NORMAL
1982 && get_ammo_brand(item) != SPMSL_NORMAL)
1983 {
1984 if (!drop_item(MSLOT_MISSILE, msg))
1985 return false;
1986 }
1987 }
1988
1989 return pickup(item, MSLOT_MISSILE, msg);
1990 }
1991
pickup_wand(item_def & item,bool msg,bool force)1992 bool monster::pickup_wand(item_def &item, bool msg, bool force)
1993 {
1994 if (!force)
1995 {
1996 // Don't pick up empty wands.
1997 if (item.plus == 0)
1998 return false;
1999
2000 // Only low-HD monsters bother with wands.
2001 if (!likes_wand(item))
2002 return false;
2003
2004 // Holy monsters and worshippers of good gods won't pick up evil
2005 // wands.
2006 if ((is_holy() || is_good_god(god)) && is_evil_item(item))
2007 return false;
2008 }
2009
2010 // If a monster already has a charged wand, don't bother.
2011 // Otherwise, replace with a charged one.
2012 if (item_def *wand = mslot_item(MSLOT_WAND))
2013 {
2014 if (wand->plus > 0 && !force)
2015 return false;
2016
2017 if (!drop_item(MSLOT_WAND, msg))
2018 return false;
2019 }
2020
2021 if (pickup(item, MSLOT_WAND, msg))
2022 return true;
2023 else
2024 return false;
2025 }
2026
pickup_scroll(item_def & item,bool msg)2027 bool monster::pickup_scroll(item_def &item, bool msg)
2028 {
2029 return pickup(item, MSLOT_SCROLL, msg);
2030 }
2031
pickup_potion(item_def & item,bool msg,bool force)2032 bool monster::pickup_potion(item_def &item, bool msg, bool force)
2033 {
2034 if (!can_drink() && !force)
2035 return false;
2036 return pickup(item, MSLOT_POTION, msg);
2037 }
2038
pickup_gold(item_def & item,bool msg)2039 bool monster::pickup_gold(item_def &item, bool msg)
2040 {
2041 return pickup(item, MSLOT_GOLD, msg);
2042 }
2043
pickup_misc(item_def & item,bool msg,bool force)2044 bool monster::pickup_misc(item_def &item, bool msg, bool force)
2045 {
2046 // Monsters can't use any miscellaneous items right now, so don't
2047 // let them pick them up unless explicitly given.
2048 if (!force)
2049 return false;
2050 return pickup(item, MSLOT_MISCELLANY, msg);
2051 }
2052
2053 // Eaten items are handled elsewhere, in _handle_pickup() in mon-act.cc.
pickup_item(item_def & item,bool msg,bool force)2054 bool monster::pickup_item(item_def &item, bool msg, bool force)
2055 {
2056 // Equipping stuff can be forced when initially equipping monsters.
2057 if (!force)
2058 {
2059 // If a monster isn't otherwise occupied (has a foe, is fleeing, etc.)
2060 // it is considered wandering.
2061 bool wandering = mons_is_wandering(*this);
2062 const int itype = item.base_type;
2063
2064 // Weak(ened) monsters won't stop to pick up things as long as they
2065 // feel unsafe.
2066 if (!wandering && (hit_points * 10 < max_hit_points || hit_points < 10)
2067 && mon_enemies_around(this))
2068 {
2069 return false;
2070 }
2071 if (!wandering && !wont_attack())
2072 {
2073 // These are not important enough for pickup when
2074 // seeking, fleeing etc.
2075 if (itype == OBJ_ARMOUR || itype == OBJ_CORPSES
2076 || itype == OBJ_JEWELLERY
2077 || itype == OBJ_MISCELLANY || itype == OBJ_GOLD)
2078 {
2079 return false;
2080 }
2081
2082 if (itype == OBJ_WEAPONS || itype == OBJ_MISSILES)
2083 {
2084 // Fleeing monsters only pick up emergency equipment.
2085 if (mons_is_fleeing(*this))
2086 return false;
2087
2088 // While occupied, hostile monsters won't pick up items
2089 // dropped or thrown by you. (You might have done that to
2090 // distract them.)
2091 if (testbits(item.flags, ISFLAG_DROPPED)
2092 || testbits(item.flags, ISFLAG_THROWN))
2093 {
2094 return false;
2095 }
2096 }
2097 }
2098 }
2099
2100 switch (item.base_type)
2101 {
2102 // Pickup some stuff only if WANDERING.
2103 case OBJ_ARMOUR:
2104 return pickup_armour(item, msg, force);
2105 case OBJ_GOLD:
2106 return pickup_gold(item, msg);
2107 case OBJ_JEWELLERY:
2108 return pickup_jewellery(item, msg, force);
2109 // Fleeing monsters won't pick up these.
2110 // Hostiles won't pick them up if they were ever dropped/thrown by you.
2111 case OBJ_STAVES:
2112 case OBJ_WEAPONS:
2113 return pickup_weapon(item, msg, force);
2114 case OBJ_MISSILES:
2115 return pickup_missile(item, msg, force);
2116 // Other types can always be picked up
2117 // (barring other checks depending on subtype, of course).
2118 case OBJ_WANDS:
2119 return pickup_wand(item, msg, force);
2120 case OBJ_SCROLLS:
2121 return pickup_scroll(item, msg);
2122 case OBJ_POTIONS:
2123 return pickup_potion(item, msg, force);
2124 case OBJ_BOOKS:
2125 case OBJ_MISCELLANY:
2126 return pickup_misc(item, msg, force);
2127 default:
2128 return false;
2129 }
2130 }
2131
swap_weapons(maybe_bool maybe_msg)2132 void monster::swap_weapons(maybe_bool maybe_msg)
2133 {
2134 const bool msg = tobool(maybe_msg, observable());
2135
2136 item_def *weap = mslot_item(MSLOT_WEAPON);
2137 item_def *alt = mslot_item(MSLOT_ALT_WEAPON);
2138
2139 if (weap && !unequip(*weap, msg))
2140 {
2141 // Item was cursed.
2142 return;
2143 }
2144
2145 swap(inv[MSLOT_WEAPON], inv[MSLOT_ALT_WEAPON]);
2146
2147 if (alt && msg)
2148 equip_message(*alt);
2149
2150 // Monsters can swap weapons really fast. :-)
2151 if ((weap || alt) && speed_increment >= 2)
2152 {
2153 if (const monsterentry *entry = find_monsterentry())
2154 speed_increment -= div_rand_round(entry->energy_usage.attack, 5);
2155 }
2156 }
2157
wield_melee_weapon(maybe_bool msg)2158 void monster::wield_melee_weapon(maybe_bool msg)
2159 {
2160 const item_def *weap = mslot_item(MSLOT_WEAPON);
2161 if (!weap || (!weap->cursed() && is_range_weapon(*weap)))
2162 {
2163 const item_def *alt = mslot_item(MSLOT_ALT_WEAPON);
2164
2165 // Switch to the alternate weapon if it's not a ranged weapon, too,
2166 // or switch away from our main weapon if it's a ranged weapon.
2167 if (alt && !is_range_weapon(*alt)
2168 || weap && !alt && type != MONS_STATUE)
2169 {
2170 swap_weapons(msg);
2171 }
2172 }
2173 }
2174
slot_item(equipment_type eq,bool) const2175 item_def *monster::slot_item(equipment_type eq, bool /*include_melded*/) const
2176 {
2177 return mslot_item(equip_slot_to_mslot(eq));
2178 }
2179
mslot_item(mon_inv_type mslot) const2180 item_def *monster::mslot_item(mon_inv_type mslot) const
2181 {
2182 const int mi = (mslot == NUM_MONSTER_SLOTS) ? NON_ITEM : inv[mslot];
2183 return mi == NON_ITEM ? nullptr : &env.item[mi];
2184 }
2185
shield() const2186 item_def *monster::shield() const
2187 {
2188 return mslot_item(MSLOT_SHIELD);
2189 }
2190
2191 /**
2192 * Does this monster have a proper name?
2193 *
2194 * @return Whether the monster has a proper name, e.g. "Rupert" or
2195 * "Bogric the orc warlord". Should not include 'renamed' vault
2196 * monsters, e.g. "decayed bog mummy" or "bag of meat".
2197 */
is_named() const2198 bool monster::is_named() const
2199 {
2200 return mons_is_unique(type)
2201 || (!mname.empty() && !testbits(flags, MF_NAME_ADJECTIVE |
2202 MF_NAME_REPLACE));
2203 }
2204
has_base_name() const2205 bool monster::has_base_name() const
2206 {
2207 // Any non-ghost, non-Pandemonium demon that has an explicitly set
2208 // name has a base name.
2209 return !mname.empty() && !ghost;
2210 }
2211
_invalid_monster_str(monster_type type)2212 static string _invalid_monster_str(monster_type type)
2213 {
2214 string str = "INVALID MONSTER ";
2215
2216 switch (type)
2217 {
2218 case NUM_MONSTERS:
2219 return str + "NUM_MONSTERS";
2220 case MONS_NO_MONSTER:
2221 return str + "MONS_NO_MONSTER";
2222 case MONS_PLAYER:
2223 return str + "MONS_PLAYER";
2224 case RANDOM_DRACONIAN:
2225 return str + "RANDOM_DRACONIAN";
2226 case RANDOM_BASE_DRACONIAN:
2227 return str + "RANDOM_BASE_DRACONIAN";
2228 case RANDOM_NONBASE_DRACONIAN:
2229 return str + "RANDOM_NONBASE_DRACONIAN";
2230 case WANDERING_MONSTER:
2231 return str + "WANDERING_MONSTER";
2232 default:
2233 break;
2234 }
2235
2236 str += make_stringf("#%d", (int) type);
2237
2238 if (type < 0)
2239 return str;
2240
2241 if (type > NUM_MONSTERS)
2242 {
2243 str += make_stringf(" (NUM_MONSTERS + %d)",
2244 int (NUM_MONSTERS - type));
2245 return str;
2246 }
2247
2248 int i;
2249 monster_type new_type;
2250 for (i = 0; true; i++)
2251 {
2252 new_type = (monster_type) (((int) type) - i);
2253
2254 if (invalid_monster_type(new_type))
2255 continue;
2256 break;
2257 }
2258 str += make_stringf(" (%s + %d)",
2259 mons_type_name(new_type, DESC_PLAIN).c_str(),
2260 i);
2261
2262 return str;
2263 }
2264
_mon_special_name(const monster & mon,description_level_type desc,bool force_seen)2265 static string _mon_special_name(const monster& mon, description_level_type desc,
2266 bool force_seen)
2267 {
2268 if (desc == DESC_NONE)
2269 return "";
2270
2271 const bool arena_submerged = crawl_state.game_is_arena() && !force_seen
2272 && mon.submerged();
2273
2274 if (mon.type == MONS_NO_MONSTER)
2275 return "DEAD MONSTER";
2276 else if (mon.mid == MID_YOU_FAULTLESS)
2277 return "INVALID YOU_FAULTLESS";
2278 else if (invalid_monster_type(mon.type) && mon.type != MONS_PROGRAM_BUG)
2279 return _invalid_monster_str(mon.type);
2280
2281 // Handle non-visible case first.
2282 if (!force_seen && !mon.observable() && !arena_submerged)
2283 {
2284 switch (desc)
2285 {
2286 case DESC_THE: case DESC_A: case DESC_PLAIN: case DESC_YOUR:
2287 return "something";
2288 case DESC_ITS:
2289 return "something's";
2290 default:
2291 return "it (buggy)";
2292 }
2293 }
2294
2295 if (desc == DESC_DBNAME)
2296 {
2297 monster_info mi(&mon, MILEV_NAME);
2298 return mi.db_name();
2299 }
2300
2301 return "";
2302 }
2303
name(description_level_type desc,bool force_vis,bool force_article) const2304 string monster::name(description_level_type desc, bool force_vis,
2305 bool force_article) const
2306 {
2307 string s = _mon_special_name(*this, desc, force_vis);
2308 if (!s.empty() || desc == DESC_NONE)
2309 return s;
2310
2311 monster_info mi(this, MILEV_NAME);
2312 // i.e. to produce "the Maras" instead of just "Maras"
2313 if (force_article)
2314 mi.mb.set(MB_NAME_UNQUALIFIED, false);
2315 return mi.proper_name(desc)
2316 #ifdef DEBUG_MONINDEX
2317 // This is incredibly spammy, too bad for regular debug builds, but
2318 // I keep re-adding this over and over during debugging.
2319 + (Options.quiet_debug_messages[DIAG_MONINDEX]
2320 ? string()
2321 : make_stringf("«%d:%d»", mindex(), mid))
2322 #endif
2323 ;
2324 }
2325
base_name(description_level_type desc,bool force_vis) const2326 string monster::base_name(description_level_type desc, bool force_vis) const
2327 {
2328 string s = _mon_special_name(*this, desc, force_vis);
2329 if (!s.empty() || desc == DESC_NONE)
2330 return s;
2331
2332 monster_info mi(this, MILEV_NAME);
2333 return mi.common_name(desc);
2334 }
2335
full_name(description_level_type desc) const2336 string monster::full_name(description_level_type desc) const
2337 {
2338 string s = _mon_special_name(*this, desc, true);
2339 if (!s.empty() || desc == DESC_NONE)
2340 return s;
2341
2342 monster_info mi(this, MILEV_NAME);
2343 return mi.full_name(desc);
2344 }
2345
pronoun(pronoun_type pro,bool force_visible) const2346 string monster::pronoun(pronoun_type pro, bool force_visible) const
2347 {
2348 const bool seen = force_visible || you.can_see(*this);
2349 if (seen && props.exists(MON_GENDER_KEY))
2350 {
2351 return decline_pronoun((gender_type)props[MON_GENDER_KEY].get_int(),
2352 pro);
2353 }
2354 return mons_pronoun(type, pro, seen);
2355 }
2356
pronoun_plurality(bool force_visible) const2357 bool monster::pronoun_plurality(bool force_visible) const
2358 {
2359 const bool seen = force_visible || you.can_see(*this);
2360 if (seen && props.exists(MON_GENDER_KEY))
2361 return props[MON_GENDER_KEY].get_int() == GENDER_NEUTRAL;
2362
2363 return seen && mons_class_gender(type) == GENDER_NEUTRAL;
2364 }
2365
conj_verb(const string & verb) const2366 string monster::conj_verb(const string &verb) const
2367 {
2368 return conjugate_verb(verb, false);
2369 }
2370
hand_name(bool plural,bool * can_plural) const2371 string monster::hand_name(bool plural, bool *can_plural) const
2372 {
2373 bool _can_plural;
2374 if (can_plural == nullptr)
2375 can_plural = &_can_plural;
2376 *can_plural = true;
2377
2378 string str;
2379 char ch = mons_base_char(mons_is_pghost(type)
2380 ? species::to_mons_species(ghost->species)
2381 : type);
2382
2383 const bool rand = (type == MONS_CHAOS_SPAWN);
2384
2385 switch (get_mon_shape(*this))
2386 {
2387 case MON_SHAPE_CENTAUR:
2388 case MON_SHAPE_NAGA:
2389 // Defaults to "hand"
2390 break;
2391 case MON_SHAPE_HUMANOID:
2392 case MON_SHAPE_HUMANOID_WINGED:
2393 case MON_SHAPE_HUMANOID_TAILED:
2394 case MON_SHAPE_HUMANOID_WINGED_TAILED:
2395 if (ch == 'T' || ch == 'n' || mons_is_demon(type))
2396 str = "claw";
2397 break;
2398
2399 case MON_SHAPE_QUADRUPED:
2400 case MON_SHAPE_QUADRUPED_TAILLESS:
2401 case MON_SHAPE_QUADRUPED_WINGED:
2402 case MON_SHAPE_ARACHNID:
2403 if (mons_genus(type) == MONS_SCORPION || rand && one_chance_in(4))
2404 str = "pincer";
2405 else
2406 {
2407 str = "front ";
2408 return str + foot_name(plural, can_plural);
2409 }
2410 break;
2411
2412 case MON_SHAPE_BLOB:
2413 case MON_SHAPE_SNAKE:
2414 case MON_SHAPE_FISH:
2415 return foot_name(plural, can_plural);
2416
2417 case MON_SHAPE_BAT:
2418 case MON_SHAPE_BIRD:
2419 str = "wing";
2420 break;
2421
2422 case MON_SHAPE_INSECT:
2423 case MON_SHAPE_INSECT_WINGED:
2424 case MON_SHAPE_CENTIPEDE:
2425 str = "antenna";
2426 break;
2427
2428 case MON_SHAPE_SNAIL:
2429 str = "eye-stalk";
2430 break;
2431
2432 case MON_SHAPE_PLANT:
2433 str = "leaf";
2434 break;
2435
2436 case MON_SHAPE_MISC:
2437 if (ch == 'x' || ch == 'X' || rand)
2438 {
2439 str = "tentacle";
2440 break;
2441 }
2442 // Deliberate fallthrough.
2443 case MON_SHAPE_FUNGUS:
2444 str = "body";
2445 *can_plural = false;
2446 break;
2447
2448 case MON_SHAPE_ORB:
2449 switch (type)
2450 {
2451 case MONS_BALLISTOMYCETE_SPORE:
2452 str = "rhizome";
2453 break;
2454
2455 case MONS_FLOATING_EYE:
2456 case MONS_SHINING_EYE:
2457 case MONS_EYE_OF_DEVASTATION:
2458 case MONS_GOLDEN_EYE:
2459 *can_plural = false;
2460 // Deliberate fallthrough.
2461 case MONS_GREAT_ORB_OF_EYES:
2462 str = "pupil";
2463 break;
2464
2465 case MONS_GLOWING_ORANGE_BRAIN:
2466 default:
2467 if (rand)
2468 str = "rhizome";
2469 else
2470 {
2471 str = "body";
2472 *can_plural = false;
2473 }
2474 break;
2475 }
2476 break;
2477
2478 case MON_SHAPE_BUGGY:
2479 str = "handbug";
2480 break;
2481 }
2482
2483 if (str.empty())
2484 {
2485 // Reduce the chance of a random-shaped monster having hands.
2486 if (rand && coinflip())
2487 return hand_name(plural, can_plural);
2488
2489 str = "hand";
2490 }
2491
2492 if (plural && *can_plural)
2493 str = pluralise(str);
2494
2495 return str;
2496 }
2497
foot_name(bool plural,bool * can_plural) const2498 string monster::foot_name(bool plural, bool *can_plural) const
2499 {
2500 bool _can_plural;
2501 if (can_plural == nullptr)
2502 can_plural = &_can_plural;
2503 *can_plural = true;
2504
2505 string str;
2506
2507 char ch = mons_base_char(mons_is_pghost(type)
2508 ? species::to_mons_species(ghost->species)
2509 : type);
2510
2511 const bool rand = (type == MONS_CHAOS_SPAWN);
2512
2513 switch (get_mon_shape(*this))
2514 {
2515 case MON_SHAPE_INSECT:
2516 case MON_SHAPE_INSECT_WINGED:
2517 case MON_SHAPE_ARACHNID:
2518 case MON_SHAPE_CENTIPEDE:
2519 str = "leg";
2520 break;
2521
2522 case MON_SHAPE_HUMANOID:
2523 case MON_SHAPE_HUMANOID_WINGED:
2524 case MON_SHAPE_HUMANOID_TAILED:
2525 case MON_SHAPE_HUMANOID_WINGED_TAILED:
2526 if (type == MONS_MINOTAUR)
2527 str = "hoof";
2528 else if (swimming() && mons_genus(type) == MONS_MERFOLK)
2529 {
2530 str = "tail";
2531 *can_plural = false;
2532 }
2533 break;
2534
2535 case MON_SHAPE_CENTAUR:
2536 str = "hoof";
2537 break;
2538
2539 case MON_SHAPE_QUADRUPED:
2540 case MON_SHAPE_QUADRUPED_TAILLESS:
2541 case MON_SHAPE_QUADRUPED_WINGED:
2542 if (rand)
2543 {
2544 const char* feet[] = {"paw", "talon", "hoof"};
2545 str = RANDOM_ELEMENT(feet);
2546 }
2547 else if (mons_genus(type) == MONS_HOG)
2548 str = "trotter";
2549 else if (ch == 'h')
2550 str = "paw";
2551 else if (ch == 'l' || ch == 'D')
2552 str = "talon";
2553 else if (type == MONS_YAK || type == MONS_DEATH_YAK)
2554 str = "hoof";
2555 else if (ch == 'H')
2556 {
2557 if (type == MONS_MANTICORE || type == MONS_SPHINX)
2558 str = "paw";
2559 else
2560 str = "talon";
2561 }
2562 break;
2563
2564 case MON_SHAPE_BIRD:
2565 str = "talon";
2566 break;
2567
2568 case MON_SHAPE_BAT:
2569 str = "claw";
2570 break;
2571
2572 case MON_SHAPE_SNAKE:
2573 case MON_SHAPE_FISH:
2574 str = "tail";
2575 *can_plural = false;
2576 break;
2577
2578 case MON_SHAPE_PLANT:
2579 str = "root";
2580 break;
2581
2582 case MON_SHAPE_FUNGUS:
2583 str = "stem";
2584 *can_plural = false;
2585 break;
2586
2587 case MON_SHAPE_BLOB:
2588 str = "pseudopod";
2589 break;
2590
2591 case MON_SHAPE_MISC:
2592 if (ch == 'x' || ch == 'X' || rand)
2593 {
2594 str = "tentacle";
2595 break;
2596 }
2597 // Deliberate fallthrough.
2598 case MON_SHAPE_SNAIL:
2599 case MON_SHAPE_NAGA:
2600 case MON_SHAPE_ORB:
2601 str = "underside";
2602 *can_plural = false;
2603 break;
2604
2605 case MON_SHAPE_BUGGY:
2606 str = "footbug";
2607 break;
2608 }
2609
2610 if (str.empty())
2611 {
2612 // Reduce the chance of a random-shaped monster having feet.
2613 if (rand && coinflip())
2614 return foot_name(plural, can_plural);
2615
2616 return plural ? "feet" : "foot";
2617 }
2618
2619 if (plural && *can_plural)
2620 str = pluralise(str);
2621
2622 return str;
2623 }
2624
arm_name(bool plural,bool * can_plural) const2625 string monster::arm_name(bool plural, bool *can_plural) const
2626 {
2627 mon_body_shape shape = get_mon_shape(*this);
2628
2629 if (!mon_shape_is_humanoid(shape))
2630 return hand_name(plural, can_plural);
2631
2632 if (can_plural != nullptr)
2633 *can_plural = true;
2634
2635 string adj;
2636 string str = "arm";
2637
2638 // TODO: shared code with species::skin_name for player species
2639 switch (mons_genus(type))
2640 {
2641 case MONS_DRACONIAN:
2642 case MONS_NAGA:
2643 adj = "scaled";
2644 break;
2645
2646 case MONS_TENGU:
2647 adj = "feathered";
2648 break;
2649
2650 case MONS_MUMMY:
2651 adj = "bandage-wrapped";
2652 break;
2653
2654 case MONS_OCTOPODE:
2655 str = "tentacle";
2656 break;
2657
2658 // TODO: this looks extremely non-general
2659 case MONS_LICH:
2660 case MONS_SKELETAL_WARRIOR:
2661 case MONS_ANCIENT_CHAMPION:
2662 case MONS_REVENANT:
2663 adj = "bony";
2664 break;
2665
2666 default:
2667 break;
2668 }
2669
2670 if (!adj.empty())
2671 str = adj + " " + str;
2672
2673 if (plural)
2674 str = pluralise(str);
2675
2676 return str;
2677 }
2678
mindex() const2679 int monster::mindex() const
2680 {
2681 return this - env.mons.buffer();
2682 }
2683
2684 /**
2685 * Sets the monster's "hit dice". Doesn't currently handle adjusting HP, etc.
2686 *
2687 * @param new_hit_dice The new value to set HD to.
2688 */
set_hit_dice(int new_hit_dice)2689 void monster::set_hit_dice(int new_hit_dice)
2690 {
2691 hit_dice = new_hit_dice;
2692
2693 // XXX: this is unbelievably hacky to preserve old behaviour
2694 if (type == MONS_OKLOB_PLANT && !spells.empty()
2695 && spells[0].spell == SPELL_SPIT_ACID)
2696 {
2697 spells[0].freq = 200 * hit_dice / 30;
2698 }
2699 }
2700
set_position(const coord_def & c)2701 void monster::set_position(const coord_def &c)
2702 {
2703 if (mons_is_projectile(*this))
2704 {
2705 // Assume some means of displacement, normal moves will overwrite this.
2706 props[IOOD_X].get_float() += c.x - pos().x;
2707 props[IOOD_Y].get_float() += c.y - pos().y;
2708 }
2709
2710 actor::set_position(c);
2711 }
2712
moveto(const coord_def & c,bool clear_net)2713 void monster::moveto(const coord_def& c, bool clear_net)
2714 {
2715 if (clear_net && c != pos() && in_bounds(pos()))
2716 mons_clear_trapping_net(this);
2717
2718 set_position(c);
2719
2720 // Do constriction invalidation after to the move, so that all LOS checking
2721 // is available.
2722 clear_invalid_constrictions(true);
2723 clear_far_engulf();
2724 }
2725
fumbles_attack()2726 bool monster::fumbles_attack()
2727 {
2728 if (floundering() && one_chance_in(4))
2729 {
2730 if (you.can_see(*this))
2731 {
2732 mprf("%s %s", name(DESC_THE).c_str(), liquefied(pos())
2733 ? "becomes momentarily stuck in the liquid earth."
2734 : env.grid(pos()) == DNGN_TOXIC_BOG
2735 ? "becomes momentarily stuck in the toxic bog."
2736 : "splashes around in the water.");
2737 }
2738 else if (player_can_hear(pos(), LOS_RADIUS))
2739 mprf(MSGCH_SOUND, "You hear a splashing noise.");
2740
2741 return true;
2742 }
2743
2744 if (submerged())
2745 return true;
2746
2747 return false;
2748 }
2749
attacking(actor *,bool)2750 void monster::attacking(actor * /* other */, bool /* ranged */)
2751 {
2752 }
2753
2754 // Sends a monster into a frenzy.
go_frenzy(actor * source)2755 bool monster::go_frenzy(actor *source)
2756 {
2757 if (!can_go_frenzy())
2758 return false;
2759
2760 if (has_ench(ENCH_SLOW))
2761 {
2762 del_ench(ENCH_SLOW, true); // Give no additional message.
2763 simple_monster_message(*this,
2764 make_stringf(" shakes off %s lethargy.",
2765 pronoun(PRONOUN_POSSESSIVE).c_str()).c_str());
2766 }
2767 del_ench(ENCH_HASTE, true);
2768 del_ench(ENCH_FATIGUE, true); // Give no additional message.
2769
2770 const int duration = 16 + random2avg(13, 2);
2771
2772 add_ench(mon_enchant(ENCH_INSANE, 0, source, duration * BASELINE_DELAY));
2773 if (holiness() & MH_NATURAL)
2774 {
2775 add_ench(mon_enchant(ENCH_HASTE, 0, source, duration * BASELINE_DELAY));
2776 add_ench(mon_enchant(ENCH_MIGHT, 0, source, duration * BASELINE_DELAY));
2777 }
2778 mons_att_changed(this);
2779
2780 if (simple_monster_message(*this, " flies into a frenzy!"))
2781 // Xom likes monsters going insane.
2782 xom_is_stimulated(friendly() ? 25 : 100);
2783
2784 return true;
2785 }
2786
go_berserk(bool intentional,bool)2787 bool monster::go_berserk(bool intentional, bool /* potion */)
2788 {
2789 if (!can_go_berserk())
2790 return false;
2791
2792 if (stasis())
2793 return false;
2794
2795 if (has_ench(ENCH_SLOW))
2796 {
2797 del_ench(ENCH_SLOW, true); // Give no additional message.
2798 simple_monster_message(*this,
2799 make_stringf(" shakes off %s lethargy.",
2800 pronoun(PRONOUN_POSSESSIVE).c_str()).c_str());
2801 }
2802 del_ench(ENCH_FATIGUE, true); // Give no additional message.
2803 del_ench(ENCH_FEAR, true); // Going berserk breaks fear.
2804 behaviour = BEH_SEEK;
2805
2806 // If we're intentionally berserking, use a melee weapon;
2807 // we won't be able to swap afterwards.
2808 if (intentional)
2809 wield_melee_weapon();
2810
2811 add_ench(ENCH_BERSERK);
2812 if (simple_monster_message(*this, " goes berserk!"))
2813 // Xom likes monsters going berserk.
2814 xom_is_stimulated(friendly() ? 25 : 100);
2815
2816 if (const item_def* w = weapon())
2817 {
2818 if (is_unrandom_artefact(*w, UNRAND_ZEALOT_SWORD))
2819 for (actor_near_iterator mi(pos(), LOS_NO_TRANS); mi; ++mi)
2820 if (mons_aligned(this, *mi))
2821 mi->go_berserk(false);
2822 }
2823
2824 return true;
2825 }
2826
expose_to_element(beam_type flavour,int strength,bool slow_cold_blood)2827 void monster::expose_to_element(beam_type flavour, int strength,
2828 bool slow_cold_blood)
2829 {
2830 switch (flavour)
2831 {
2832 case BEAM_COLD:
2833 if (slow_cold_blood && mons_class_flag(type, M_COLD_BLOOD)
2834 && res_cold() <= 0 && coinflip())
2835 {
2836 do_slow_monster(*this, this, (strength + random2(5)) * BASELINE_DELAY);
2837 }
2838 break;
2839 case BEAM_WATER:
2840 del_ench(ENCH_STICKY_FLAME);
2841 break;
2842 case BEAM_FIRE:
2843 case BEAM_LAVA:
2844 case BEAM_STICKY_FLAME:
2845 case BEAM_STEAM:
2846 if (has_ench(ENCH_ICEMAIL))
2847 del_ench(ENCH_ICEMAIL);
2848 break;
2849 default:
2850 break;
2851 }
2852 }
2853
banish(const actor * agent,const string &,const int,bool force)2854 void monster::banish(const actor *agent, const string &, const int, bool force)
2855 {
2856 coord_def old_pos = pos();
2857
2858 if (mons_is_projectile(type))
2859 return;
2860
2861 if (!force && player_in_branch(BRANCH_ABYSS)
2862 && x_chance_in_y(you.depth, brdepth[BRANCH_ABYSS]))
2863 {
2864 simple_monster_message(*this, " wobbles for a moment.");
2865 return;
2866 }
2867
2868 if (mons_is_tentacle_or_tentacle_segment(type))
2869 {
2870 monster* head = monster_by_mid(tentacle_connect);
2871 if (head)
2872 {
2873 head->banish(agent, "", 0, force);
2874 return;
2875 }
2876 }
2877
2878 simple_monster_message(*this, " is devoured by a tear in reality.",
2879 MSGCH_BANISHMENT);
2880 if (agent && mons_gives_xp(*this, *agent)
2881 && (agent->is_player() || agent->mid == MID_YOU_FAULTLESS))
2882 {
2883 // Count all remaining HP as damage done by you - no need to
2884 // pass flags this way.
2885 damage_friendly += hit_points * 2;
2886 // Note: we do not set MF_PACIFIED, the monster is usually not
2887 // distinguishable from others of the same kind in the Abyss.
2888 did_god_conduct(DID_BANISH, get_experience_level(),
2889 true /*possibly wrong*/, this);
2890 }
2891 monster_die(*this, KILL_BANISHED, NON_MONSTER);
2892
2893 if (!cell_is_solid(old_pos))
2894 place_cloud(CLOUD_TLOC_ENERGY, old_pos, 5 + random2(8), 0);
2895 for (adjacent_iterator ai(old_pos); ai; ++ai)
2896 if (!cell_is_solid(*ai) && !cloud_at(*ai) && coinflip())
2897 place_cloud(CLOUD_TLOC_ENERGY, *ai, 1 + random2(8), 0);
2898 }
2899
has_spells() const2900 bool monster::has_spells() const
2901 {
2902 return spells.size() > 0;
2903 }
2904
has_spell(spell_type spell) const2905 bool monster::has_spell(spell_type spell) const
2906 {
2907 return search_spells([=] (spell_type sp) { return sp == spell; } );
2908 }
2909
spell_slot_flags(spell_type spell) const2910 mon_spell_slot_flags monster::spell_slot_flags(spell_type spell) const
2911 {
2912 mon_spell_slot_flags slot_flags;
2913 for (const mon_spell_slot &slot : spells)
2914 if (slot.spell == spell)
2915 slot_flags |= slot.flags;
2916
2917 return slot_flags;
2918 }
2919
has_unclean_spell() const2920 bool monster::has_unclean_spell() const
2921 {
2922 return search_spells(is_unclean_spell);
2923 }
2924
has_chaotic_spell() const2925 bool monster::has_chaotic_spell() const
2926 {
2927 return search_spells(is_chaotic_spell);
2928 }
2929
has_attack_flavour(int flavour) const2930 bool monster::has_attack_flavour(int flavour) const
2931 {
2932 for (int i = 0; i < 4; ++i)
2933 {
2934 const int attk_flavour = mons_attack_spec(*this, i).flavour;
2935 if (attk_flavour == flavour)
2936 return true;
2937 }
2938
2939 return false;
2940 }
2941
has_damage_type(int dam_type)2942 bool monster::has_damage_type(int dam_type)
2943 {
2944 for (int i = 0; i < 4; ++i)
2945 {
2946 const int dmg_type = damage_type(i);
2947 if (dmg_type == dam_type)
2948 return true;
2949 }
2950
2951 return false;
2952 }
2953
constriction_damage(bool direct) const2954 int monster::constriction_damage(bool direct) const
2955 {
2956 if (direct)
2957 {
2958 for (int i = 0; i < 4; ++i)
2959 {
2960 const mon_attack_def attack = mons_attack_spec(*this, i);
2961 if (attack.type == AT_CONSTRICT)
2962 return attack.damage;
2963 }
2964 return -1;
2965 }
2966
2967 // The only monster spell that's a source of indirect constriction.
2968 return roll_dice(2, div_rand_round(40 +
2969 mons_spellpower(*this, SPELL_GRASPING_ROOTS), 20));
2970 }
2971
constriction_does_damage(bool direct) const2972 bool monster::constriction_does_damage(bool direct) const
2973 {
2974 return constriction_damage(direct) > 0;
2975 }
2976
2977 /** Return true if the monster temporarily confused. False for butterflies, or
2978 other permanently confused monsters.
2979 */
confused() const2980 bool monster::confused() const
2981 {
2982 return mons_is_confused(*this);
2983 }
2984
_you_responsible_for_ench(mon_enchant me)2985 static bool _you_responsible_for_ench(mon_enchant me)
2986 {
2987 return me.who == KC_YOU
2988 || me.who == KC_FRIENDLY && !crawl_state.game_is_arena();
2989 }
2990
confused_by_you() const2991 bool monster::confused_by_you() const
2992 {
2993 if (mons_class_flag(type, M_CONFUSED))
2994 return false;
2995
2996 const mon_enchant me = get_ench(ENCH_CONFUSION);
2997 const mon_enchant me2 = get_ench(ENCH_MAD);
2998
2999 return (me.ench == ENCH_CONFUSION && _you_responsible_for_ench(me))
3000 || (me2.ench == ENCH_MAD && _you_responsible_for_ench(me2));
3001 }
3002
paralysed() const3003 bool monster::paralysed() const
3004 {
3005 return has_ench(ENCH_PARALYSIS) || has_ench(ENCH_DUMB);
3006 }
3007
cannot_act() const3008 bool monster::cannot_act() const
3009 {
3010 return paralysed() || petrified();
3011 }
3012
cannot_move() const3013 bool monster::cannot_move() const
3014 {
3015 return cannot_act();
3016 }
3017
asleep() const3018 bool monster::asleep() const
3019 {
3020 return behaviour == BEH_SLEEP;
3021 }
3022
backlit(bool self_halo) const3023 bool monster::backlit(bool self_halo) const
3024 {
3025 if (has_ench(ENCH_CORONA) || has_ench(ENCH_STICKY_FLAME)
3026 || has_ench(ENCH_SILVER_CORONA))
3027 {
3028 return true;
3029 }
3030
3031 return !umbraed() && haloed() && (self_halo || halo_radius() == -1);
3032 }
3033
umbra() const3034 bool monster::umbra() const
3035 {
3036 return umbraed() && !haloed();
3037 }
3038
caught() const3039 bool monster::caught() const
3040 {
3041 return has_ench(ENCH_HELD);
3042 }
3043
petrified() const3044 bool monster::petrified() const
3045 {
3046 return has_ench(ENCH_PETRIFIED);
3047 }
3048
petrifying() const3049 bool monster::petrifying() const
3050 {
3051 return has_ench(ENCH_PETRIFYING);
3052 }
3053
liquefied_ground() const3054 bool monster::liquefied_ground() const
3055 {
3056 return liquefied(pos())
3057 && ground_level() && !is_insubstantial()
3058 && !mons_class_is_stationary(type);
3059 }
3060
3061 // in units of 1/25 hp/turn
natural_regen_rate() const3062 int monster::natural_regen_rate() const
3063 {
3064 // A HD divider ranging from 3 (at 1 HD) to 1 (at 8 HD).
3065 int divider = max(div_rand_round(15 - get_hit_dice(), 4), 1);
3066
3067 return max(div_rand_round(get_hit_dice(), divider), 1);
3068 }
3069
3070 // in units of 1/100 hp/turn
off_level_regen_rate() const3071 int monster::off_level_regen_rate() const
3072 {
3073 if (!mons_can_regenerate(*this))
3074 return 0;
3075
3076 if (mons_class_fast_regen(type) || type == MONS_PLAYER_GHOST)
3077 return 100;
3078 // Capped at 0.1 hp/turn.
3079 return max(natural_regen_rate() * 4, 10);
3080 }
3081
friendly() const3082 bool monster::friendly() const
3083 {
3084 return temp_attitude() == ATT_FRIENDLY;
3085 }
3086
neutral() const3087 bool monster::neutral() const
3088 {
3089 mon_attitude_type att = temp_attitude();
3090 return att == ATT_NEUTRAL || att == ATT_GOOD_NEUTRAL
3091 || att == ATT_STRICT_NEUTRAL;
3092 }
3093
good_neutral() const3094 bool monster::good_neutral() const
3095 {
3096 return temp_attitude() == ATT_GOOD_NEUTRAL;
3097 }
3098
strict_neutral() const3099 bool monster::strict_neutral() const
3100 {
3101 return temp_attitude() == ATT_STRICT_NEUTRAL;
3102 }
3103
wont_attack() const3104 bool monster::wont_attack() const
3105 {
3106 return friendly() || good_neutral() || strict_neutral();
3107 }
3108
pacified() const3109 bool monster::pacified() const
3110 {
3111 return attitude == ATT_NEUTRAL && testbits(flags, MF_PACIFIED);
3112 }
3113
can_feel_fear(bool) const3114 bool monster::can_feel_fear(bool /*include_unknown*/) const
3115 {
3116 return (holiness() & MH_NATURAL) && !berserk_or_insane();
3117 }
3118
3119 /**
3120 * Returns whether the monster currently has any kind of shield.
3121 */
shielded() const3122 bool monster::shielded() const
3123 {
3124 return shield() || wearing(EQ_AMULET, AMU_REFLECTION);
3125 }
3126
shield_bonus() const3127 int monster::shield_bonus() const
3128 {
3129 if (incapacitated())
3130 return -100;
3131
3132 int sh = 0;
3133 const item_def *shld = shield();
3134 if (shld && get_armour_slot(*shld) == EQ_SHIELD)
3135 {
3136
3137 int shld_c = property(*shld, PARM_AC) + shld->plus * 2;
3138 shld_c = shld_c * 2 + (body_size(PSIZE_TORSO) - SIZE_MEDIUM)
3139 * (shld->sub_type - ARM_TOWER_SHIELD);
3140 sh = random2avg(shld_c + get_hit_dice() * 4 / 3, 2) / 2;
3141 }
3142 // shielding from jewellery
3143 const item_def *amulet = mslot_item(MSLOT_JEWELLERY);
3144 if (amulet && amulet->sub_type == AMU_REFLECTION)
3145 sh += AMU_REFLECT_SH;
3146
3147 return sh ? sh : -100;
3148 }
3149
shield_block_penalty() const3150 int monster::shield_block_penalty() const
3151 {
3152 return 4 * shield_blocks * shield_blocks;
3153 }
3154
shield_block_succeeded()3155 void monster::shield_block_succeeded()
3156 {
3157 actor::shield_block_succeeded();
3158
3159 ++shield_blocks;
3160 }
3161
shield_bypass_ability(int) const3162 int monster::shield_bypass_ability(int) const
3163 {
3164 return mon_shield_bypass(get_hit_dice());
3165 }
3166
missile_repulsion() const3167 bool monster::missile_repulsion() const
3168 {
3169 return has_ench(ENCH_REPEL_MISSILES) || scan_artefacts(ARTP_RMSL);
3170 }
3171
3172 /**
3173 * How many weapons of the given brand does this monster currently wield?
3174 *
3175 * @param mon The monster in question.
3176 * @param brand The brand in question.
3177 * @param calc_unid Whether to include weapons whose brands are unknown (to
3178 * the player).
3179 * @return The number of the aforementioned weapons currently
3180 * wielded.
3181 */
_weapons_with_prop(const monster * mon,brand_type brand,bool calc_unid=true)3182 static int _weapons_with_prop(const monster *mon, brand_type brand,
3183 bool calc_unid = true)
3184 {
3185 int wielded = 0;
3186
3187 const mon_inv_type last_weap_slot = mons_wields_two_weapons(*mon) ?
3188 MSLOT_ALT_WEAPON :
3189 MSLOT_WEAPON;
3190 for (int i = MSLOT_WEAPON; i <= last_weap_slot; i++)
3191 {
3192 const item_def *weap = mon->mslot_item(static_cast<mon_inv_type>(i));
3193 if (!weap)
3194 continue;
3195
3196 if (!calc_unid && !item_ident(*weap, ISFLAG_KNOW_TYPE))
3197 continue;
3198
3199 const int weap_brand = get_weapon_brand(*weap);
3200 if (brand == weap_brand)
3201 wielded++;
3202 }
3203
3204 return wielded;
3205 }
3206
3207 /**
3208 * What AC bonus or penalty does a given zombie type apply to the base
3209 * monster type's?
3210 *
3211 * @param type The type of zombie. (Skeleton, simulac, etc)
3212 * @return The ac modifier to apply to the base monster's AC.
3213 */
_zombie_ac_modifier(monster_type type)3214 static int _zombie_ac_modifier(monster_type type)
3215 {
3216 ASSERT(mons_class_is_zombified(type));
3217
3218 switch (type)
3219 {
3220 case MONS_ZOMBIE:
3221 case MONS_SIMULACRUM:
3222 return -2;
3223 case MONS_SKELETON:
3224 return -6;
3225 case MONS_SPECTRAL_THING:
3226 return 2;
3227 default:
3228 die("invalid zombie type %d (%s)", type,
3229 mons_class_name(type));
3230 }
3231 }
3232
3233 /**
3234 * What's the base armour class of this monster?
3235 *
3236 * Usually based on type; ghost demons can override this, and draconians/
3237 * demonspawn are... complicated.
3238 *
3239 * @return The base armour class of this monster, before applying item &
3240 * status effects.
3241 */
base_armour_class() const3242 int monster::base_armour_class() const
3243 {
3244 ASSERT(!invalid_monster_type(type));
3245
3246 // ghost demon struct overrides the monster values.
3247 if (mons_is_ghost_demon(type))
3248 return ghost->ac;
3249
3250 // zombie, skeleton, etc ac mods
3251 if (mons_class_is_zombified(type))
3252 {
3253 // handle weird zombies for which type isn't enough to reconstruct ac
3254 // (e.g. zombies with jobs & demonghost zombies)
3255 const int base_ac = props.exists(ZOMBIE_BASE_AC_KEY) ?
3256 props[ZOMBIE_BASE_AC_KEY].get_int() :
3257 get_monster_data(base_monster)->AC;
3258
3259 return _zombie_ac_modifier(type) + base_ac;
3260 }
3261
3262 // abominations are weird.
3263 if (type == MONS_ABOMINATION_LARGE)
3264 return min(20, 7 + get_hit_dice() / 2);
3265 if (type == MONS_ABOMINATION_SMALL)
3266 return min(10, 3 + get_hit_dice() * 2 / 3);
3267
3268 // Hepliaklqana ancestors scale with xl.
3269 if (mons_is_hepliaklqana_ancestor(type))
3270 {
3271 if (type == MONS_ANCESTOR_KNIGHT)
3272 return get_experience_level() + 7;
3273 return get_experience_level() / 2;
3274 }
3275
3276 if (type == MONS_ANIMATED_ARMOUR)
3277 {
3278 // Armour spirits get double AC from their armour.
3279 const int armour_slot = inv[MSLOT_ARMOUR];
3280 if (armour_slot != NON_ITEM)
3281 {
3282 const int typ = env.item[armour_slot].sub_type;
3283 return armour_prop(typ, PARM_AC);
3284 }
3285 }
3286
3287 const int base_ac = get_monster_data(type)->AC;
3288
3289 // demonspawn & draconians combine base & class ac values.
3290 if (mons_is_job(type))
3291 {
3292 ASSERT(!invalid_monster_type(base_monster));
3293 return base_ac + get_monster_data(base_monster)->AC;
3294 }
3295
3296 // mutant beasts get extra AC for being musk oxen.
3297 if (has_facet(BF_OX))
3298 return base_ac + 5;
3299
3300 return base_ac;
3301 }
3302
3303 /**
3304 * What's the armour class of this monster?
3305 *
3306 * @param calc_unid Whether to include unknown items/properties in the
3307 * calculated results.
3308 * @return The armour class of this monster, including items,
3309 * statuses, etc.
3310 */
armour_class(bool calc_unid) const3311 int monster::armour_class(bool calc_unid) const
3312 {
3313 int ac = base_armour_class();
3314
3315 // check for protection-brand weapons
3316 ac += 5 * _weapons_with_prop(this, SPWPN_PROTECTION, calc_unid);
3317
3318 // armour from ac
3319 const item_def *armour = mslot_item(MSLOT_ARMOUR);
3320 if (armour)
3321 ac += armour_bonus(*armour, calc_unid);
3322
3323 // armour from jewellery
3324 const item_def *ring = mslot_item(MSLOT_JEWELLERY);
3325 if (ring && ring->sub_type == RING_PROTECTION
3326 && (calc_unid
3327 || item_ident(*ring, ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES)))
3328 {
3329 const int jewellery_plus = ring->plus;
3330 ASSERT(abs(jewellery_plus) < 30); // sanity check
3331 ac += jewellery_plus;
3332 }
3333
3334 // various enchantments
3335 if (has_ench(ENCH_ICEMAIL))
3336 ac += ICEMAIL_MAX;
3337 if (has_ench(ENCH_IDEALISED))
3338 ac += 4 + get_hit_dice() / 3;
3339
3340 // Penalty due to bad temp mutations.
3341 if (has_ench(ENCH_WRETCHED))
3342 ac -= 8;
3343
3344 // corrosion hurts.
3345 if (has_ench(ENCH_CORROSION))
3346 ac -= 8;
3347
3348 return max(ac, 0);
3349 }
3350
3351 /**
3352 * What EV bonus or penalty does a given zombie type apply to the base
3353 * monster type's?
3354 *
3355 * @param type The type of zombie. (Skeleton, simulac, etc)
3356 * @return The ev modifier to apply to the base monster's EV.
3357 */
_zombie_ev_modifier(monster_type type)3358 static int _zombie_ev_modifier(monster_type type)
3359 {
3360 ASSERT(mons_class_is_zombified(type));
3361
3362 switch (type)
3363 {
3364 case MONS_ZOMBIE:
3365 case MONS_SIMULACRUM:
3366 case MONS_SPECTRAL_THING:
3367 return -5;
3368 case MONS_SKELETON:
3369 return -7;
3370 default:
3371 die("invalid zombie type %d (%s)", type,
3372 mons_class_name(type));
3373 }
3374 }
3375
3376 /**
3377 * What's the base evasion of this monster?
3378 *
3379 * @return The base evasion of this monster, before applying items & statuses.
3380 **/
base_evasion() const3381 int monster::base_evasion() const
3382 {
3383 // ghost demon struct overrides the monster values.
3384 if (mons_is_ghost_demon(type))
3385 return ghost->ev;
3386
3387 // zombie, skeleton, etc ac mods
3388 if (mons_class_is_zombified(type))
3389 {
3390 // handle weird zombies for which type isn't enough to reconstruct ev
3391 // (e.g. zombies with jobs & demonghost zombies)
3392 const int base_ev = props.exists(ZOMBIE_BASE_EV_KEY) ?
3393 props[ZOMBIE_BASE_EV_KEY].get_int() :
3394 get_monster_data(base_monster)->ev;
3395
3396 return _zombie_ev_modifier(type) + base_ev;
3397 }
3398
3399 // abominations are weird.
3400 if (type == MONS_ABOMINATION_LARGE)
3401 return min(20, 2 * get_hit_dice() / 3);
3402 if (type == MONS_ABOMINATION_SMALL)
3403 return min(10, 4 + get_hit_dice());
3404
3405 const int base_ev = get_monster_data(type)->ev;
3406
3407 // demonspawn & draconians combine base & class ac values.
3408 if (mons_is_job(type))
3409 return base_ev + get_monster_data(base_monster)->ev;
3410
3411 return base_ev;
3412 }
3413
3414 /**
3415 * What's the current evasion of this monster?
3416 *
3417 * @param evit A bitfield of ev modifiers to ignore.
3418 * @return The evasion of this monster, after applying items & statuses.
3419 **/
evasion(ev_ignore_type evit,const actor *) const3420 int monster::evasion(ev_ignore_type evit, const actor* /*act*/) const
3421 {
3422 const bool calc_unid = !testbits(evit, ev_ignore::unided);
3423
3424 int ev = base_evasion();
3425
3426 // account for armour
3427 for (int slot = MSLOT_ARMOUR; slot <= MSLOT_SHIELD; slot++)
3428 {
3429 const item_def* armour = mslot_item(static_cast<mon_inv_type>(slot));
3430 if (armour)
3431 {
3432 ev += property(*armour, PARM_EVASION) / 10
3433 / (is_shield(*armour) ? 2 : 6);
3434 }
3435 }
3436
3437 // evasion from jewellery
3438 const item_def *ring = mslot_item(MSLOT_JEWELLERY);
3439 if (ring && ring->sub_type == RING_EVASION
3440 && (calc_unid
3441 || item_ident(*ring, ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES)))
3442 {
3443 const int jewellery_plus = ring->plus;
3444 ASSERT(abs(jewellery_plus) < 30); // sanity check
3445 ev += jewellery_plus;
3446 }
3447
3448 if (has_ench(ENCH_AGILE))
3449 ev += AGILITY_BONUS;
3450
3451 if (evit & ev_ignore::helpless)
3452 return max(ev, 0);
3453
3454 if (paralysed() || petrified() || petrifying() || asleep())
3455 return 0;
3456
3457 if (caught() || is_constricted())
3458 ev /= (body_size(PSIZE_BODY) + 2);
3459 else if (confused())
3460 ev /= 2;
3461
3462 return max(ev, 0);
3463 }
3464
heal(int amount)3465 bool monster::heal(int amount)
3466 {
3467 if (amount < 1)
3468 return false;
3469 else if (hit_points == max_hit_points)
3470 return false;
3471
3472 hit_points += amount;
3473
3474 bool success = true;
3475
3476 if (hit_points > max_hit_points)
3477 hit_points = max_hit_points;
3478
3479 if (hit_points == max_hit_points)
3480 {
3481 // Clear the damage blame if it goes away completely.
3482 damage_friendly = 0;
3483 damage_total = 0;
3484 props.erase("reaping_damage");
3485 }
3486
3487 return success;
3488 }
3489
blame_damage(const actor * attacker,int amount)3490 void monster::blame_damage(const actor* attacker, int amount)
3491 {
3492 ASSERT(amount >= 0);
3493 damage_total = min<int>(MAX_DAMAGE_COUNTER, damage_total + amount);
3494 if (attacker)
3495 {
3496 damage_friendly = min<int>(MAX_DAMAGE_COUNTER * 2,
3497 damage_friendly + amount * exp_rate(attacker->mindex()));
3498 }
3499 }
3500
suicide(int hp_target)3501 void monster::suicide(int hp_target)
3502 {
3503 ASSERT(hp_target <= 0);
3504 const int dam = hit_points - hp_target;
3505 if (dam > 0)
3506 blame_damage(nullptr, dam);
3507 hit_points = hp_target;
3508 }
3509
holiness(bool) const3510 mon_holy_type monster::holiness(bool /*temp*/) const
3511 {
3512 // zombie kraken tentacles
3513 if (testbits(flags, MF_FAKE_UNDEAD))
3514 return MH_UNDEAD;
3515
3516 mon_holy_type holi = mons_class_holiness(type);
3517
3518 // Assume that all unknown gods are not holy.
3519 if (is_priest() && is_good_god(god))
3520 holi |= MH_HOLY;
3521
3522 // Assume that all unknown gods are evil.
3523 if (is_priest() && (is_evil_god(god) || is_unknown_god(god)))
3524 holi |= MH_EVIL;
3525
3526 if (has_attack_flavour(AF_DRAIN)
3527 || has_attack_flavour(AF_VAMPIRIC))
3528 {
3529 holi |= MH_EVIL;
3530 }
3531
3532 if (testbits(flags, MF_SPECTRALISED))
3533 holi |= MH_EVIL;
3534
3535 return holi;
3536 }
3537
undead_or_demonic(bool) const3538 bool monster::undead_or_demonic(bool /*temp*/) const
3539 {
3540 const mon_holy_type holi = holiness();
3541
3542 return bool(holi & (MH_UNDEAD | MH_DEMONIC));
3543 }
3544
is_holy() const3545 bool monster::is_holy() const
3546 {
3547 return bool(holiness() & MH_HOLY);
3548 }
3549
is_nonliving(bool) const3550 bool monster::is_nonliving(bool /*temp*/) const
3551 {
3552 return bool(holiness() & MH_NONLIVING);
3553 }
3554
3555 /** Is the monster considered unclean by Zin?
3556 *
3557 * If not 0, then Zin won't let you have it as an ally, and gives
3558 * piety for killing it.
3559 * @param check_god whether the monster having a chaotic god matters.
3560 * @returns 0 if not hated, a number greater than 0 otherwise.
3561 */
how_unclean(bool check_god) const3562 int monster::how_unclean(bool check_god) const
3563 {
3564 int uncleanliness = 0;
3565
3566 if (has_attack_flavour(AF_DRAIN))
3567 uncleanliness++;
3568 if (has_attack_flavour(AF_STEAL))
3569 uncleanliness++;
3570 if (has_attack_flavour(AF_VAMPIRIC))
3571 uncleanliness++;
3572
3573 // Zin considers insanity unclean. And slugs that speak.
3574 if (type == MONS_CRAZY_YIUF
3575 || type == MONS_PSYCHE
3576 || type == MONS_LOUISE
3577 || type == MONS_GASTRONOK)
3578 {
3579 uncleanliness++;
3580 }
3581
3582 // A floating mass of disease is nearly the definition of unclean.
3583 if (type == MONS_ANCIENT_ZYME)
3584 uncleanliness++;
3585
3586 // Assume that all unknown gods are not chaotic.
3587 //
3588 // Being a worshipper of a chaotic god doesn't yet make you
3589 // physically/essentially chaotic (so you don't get hurt by silver),
3590 // but Zin does mind.
3591 if (is_priest() && is_chaotic_god(god) && check_god)
3592 uncleanliness++;
3593
3594 if (has_unclean_spell())
3595 uncleanliness++;
3596
3597 if (has_chaotic_spell() && is_actual_spellcaster())
3598 uncleanliness++;
3599
3600 // Corporeal undead are a perversion of natural form.
3601 if (holiness() & MH_UNDEAD && !is_insubstantial())
3602 uncleanliness++;
3603
3604 return uncleanliness;
3605 }
3606
3607 /** How chaotic do you know this monster to be?
3608 *
3609 * @param check_spells_god whether to look at its spells and/or
3610 * religion; silver damage does not.
3611 * @returns 0 if not chaotic, a larger number if so.
3612 */
known_chaos(bool check_spells_god) const3613 int monster::known_chaos(bool check_spells_god) const
3614 {
3615 int chaotic = 0;
3616
3617 if (type == MONS_UGLY_THING
3618 || type == MONS_VERY_UGLY_THING
3619 || type == MONS_ABOMINATION_SMALL
3620 || type == MONS_ABOMINATION_LARGE
3621 || type == MONS_WRETCHED_STAR
3622 || type == MONS_KILLER_KLOWN // For their random attacks.
3623 || type == MONS_TIAMAT // For her colour-changing.
3624 || type == MONS_BAI_SUZHEN
3625 || type == MONS_BAI_SUZHEN_DRAGON // For her transformation.
3626 || mons_is_demonspawn(type)) // Like player demonspawn.
3627 {
3628 chaotic++;
3629 }
3630
3631 if (is_shapeshifter() && (flags & MF_KNOWN_SHIFTER))
3632 chaotic++;
3633
3634 // Knowing chaotic spells is not enough to make you "essentially"
3635 // chaotic (i.e., silver doesn't hurt you), but it does make you
3636 // chaotic enough for Zin's chaos recitation. Having chaotic
3637 // abilities (not actual spells) does mean you're truly changed
3638 // by chaos.
3639 if (has_chaotic_spell() && (!is_actual_spellcaster()
3640 || check_spells_god))
3641 {
3642 chaotic++;
3643 }
3644
3645 if (has_attack_flavour(AF_MUTATE)
3646 || has_attack_flavour(AF_CHAOTIC))
3647 {
3648 chaotic++;
3649 }
3650
3651 if (is_chaotic_god(god))
3652 chaotic++;
3653
3654 if (is_chaotic_god(god) && is_priest())
3655 chaotic++;
3656
3657 return chaotic;
3658 }
3659
3660 /** How chaotic is this monster really?
3661 *
3662 * @param check_spells_god whether to look at its spells and/or
3663 * religion; silver damage does not.
3664 * @returns 0 if not chaotic, a larger number if so.
3665 */
how_chaotic(bool check_spells_god) const3666 int monster::how_chaotic(bool check_spells_god) const
3667 {
3668 // Don't count known shapeshifters twice.
3669 if (is_shapeshifter() && (flags & MF_KNOWN_SHIFTER))
3670 return known_chaos(check_spells_god);
3671 else
3672 return is_shapeshifter() + known_chaos(check_spells_god);
3673 }
3674
is_unbreathing() const3675 bool monster::is_unbreathing() const
3676 {
3677 return mons_is_unbreathing(type);
3678 }
3679
is_insubstantial() const3680 bool monster::is_insubstantial() const
3681 {
3682 return mons_class_flag(type, M_INSUBSTANTIAL);
3683 }
3684
3685 /// Is this monster completely immune to Damnation-flavoured damage?
res_damnation() const3686 bool monster::res_damnation() const
3687 {
3688 return get_mons_resist(*this, MR_RES_DAMNATION);
3689 }
3690
res_fire() const3691 int monster::res_fire() const
3692 {
3693 int u = get_mons_resist(*this, MR_RES_FIRE);
3694
3695 if (mons_itemuse(*this) >= MONUSE_STARTING_EQUIPMENT)
3696 {
3697 u += scan_artefacts(ARTP_FIRE);
3698
3699 const int armour = inv[MSLOT_ARMOUR];
3700 const int shld = inv[MSLOT_SHIELD];
3701 const int jewellery = inv[MSLOT_JEWELLERY];
3702
3703 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR)
3704 u += get_armour_res_fire(env.item[armour], false);
3705
3706 if (shld != NON_ITEM && env.item[shld].base_type == OBJ_ARMOUR)
3707 u += get_armour_res_fire(env.item[shld], false);
3708
3709 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY)
3710 u += get_jewellery_res_fire(env.item[jewellery], false);
3711
3712 const item_def *w = primary_weapon();
3713 if (w && w->is_type(OBJ_STAVES, STAFF_FIRE))
3714 u++;
3715 }
3716
3717 if (has_ench(ENCH_FIRE_VULN))
3718 u--;
3719
3720 if (has_ench(ENCH_RESISTANCE))
3721 u++;
3722
3723 if (u < -3)
3724 u = -3;
3725 else if (u > 3)
3726 u = 3;
3727
3728 return u;
3729 }
3730
res_steam() const3731 int monster::res_steam() const
3732 {
3733 int res = get_mons_resist(*this, MR_RES_STEAM);
3734 if (wearing(EQ_BODY_ARMOUR, ARM_STEAM_DRAGON_ARMOUR))
3735 res += 3;
3736
3737 res += (res_fire() + 1) / 2;
3738
3739 if (res > 3)
3740 res = 3;
3741
3742 return res;
3743 }
3744
res_cold() const3745 int monster::res_cold() const
3746 {
3747 int u = get_mons_resist(*this, MR_RES_COLD);
3748
3749 if (mons_itemuse(*this) >= MONUSE_STARTING_EQUIPMENT)
3750 {
3751 u += scan_artefacts(ARTP_COLD);
3752
3753 const int armour = inv[MSLOT_ARMOUR];
3754 const int shld = inv[MSLOT_SHIELD];
3755 const int jewellery = inv[MSLOT_JEWELLERY];
3756
3757 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR)
3758 u += get_armour_res_cold(env.item[armour], false);
3759
3760 if (shld != NON_ITEM && env.item[shld].base_type == OBJ_ARMOUR)
3761 u += get_armour_res_cold(env.item[shld], false);
3762
3763 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY)
3764 u += get_jewellery_res_cold(env.item[jewellery], false);
3765
3766 const item_def *w = primary_weapon();
3767 if (w && w->is_type(OBJ_STAVES, STAFF_COLD))
3768 u++;
3769 }
3770
3771 if (has_ench(ENCH_RESISTANCE))
3772 u++;
3773
3774 if (u < -3)
3775 u = -3;
3776 else if (u > 3)
3777 u = 3;
3778
3779 return u;
3780 }
3781
res_elec() const3782 int monster::res_elec() const
3783 {
3784 // This is a variable, not a player_xx() function, so can be above 1.
3785 int u = 0;
3786
3787 u += get_mons_resist(*this, MR_RES_ELEC);
3788
3789 // Don't bother checking equipment if the monster can't use it.
3790 if (mons_itemuse(*this) >= MONUSE_STARTING_EQUIPMENT)
3791 {
3792 u += scan_artefacts(ARTP_ELECTRICITY);
3793
3794 // No ego armour, but storm dragon.
3795 // Also no non-artefact rings at present,
3796 // but it doesn't hurt to be thorough.
3797 const int armour = inv[MSLOT_ARMOUR];
3798 const int jewellery = inv[MSLOT_JEWELLERY];
3799
3800 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR)
3801 u += get_armour_res_elec(env.item[armour], false);
3802
3803 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY)
3804 u += get_jewellery_res_elec(env.item[jewellery], false);
3805
3806 const item_def *w = primary_weapon();
3807 if (w && w->is_type(OBJ_STAVES, STAFF_AIR))
3808 u++;
3809 }
3810
3811 if (has_ench(ENCH_RESISTANCE))
3812 u++;
3813
3814 // Monsters can legitimately get multiple levels of electricity resistance.
3815
3816 return u;
3817 }
3818
res_water_drowning() const3819 int monster::res_water_drowning() const
3820 {
3821 int rw = 0;
3822
3823 if (is_unbreathing())
3824 rw++;
3825
3826 habitat_type hab = mons_habitat(*this, true);
3827 if (hab == HT_WATER || hab == HT_AMPHIBIOUS)
3828 rw++;
3829
3830 if (get_mons_resist(*this, MR_VUL_WATER))
3831 rw--;
3832
3833 return sgn(rw);
3834 }
3835
res_poison(bool temp) const3836 int monster::res_poison(bool temp) const
3837 {
3838 int u = get_mons_resist(*this, MR_RES_POISON);
3839
3840 if (const item_def* w = primary_weapon())
3841 {
3842 if (is_unrandom_artefact(*w, UNRAND_OLGREB))
3843 return 3;
3844 }
3845
3846 if (temp && has_ench(ENCH_POISON_VULN))
3847 u--;
3848
3849 if (u > 0)
3850 return u;
3851
3852 if (mons_itemuse(*this) >= MONUSE_STARTING_EQUIPMENT)
3853 {
3854 u += scan_artefacts(ARTP_POISON);
3855
3856 const int armour = inv[MSLOT_ARMOUR];
3857 const int shld = inv[MSLOT_SHIELD];
3858 const int jewellery = inv[MSLOT_JEWELLERY];
3859
3860 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR)
3861 u += get_armour_res_poison(env.item[armour], false);
3862
3863 if (shld != NON_ITEM && env.item[shld].base_type == OBJ_ARMOUR)
3864 u += get_armour_res_poison(env.item[shld], false);
3865
3866 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY)
3867 u += get_jewellery_res_poison(env.item[jewellery], false);
3868
3869 const item_def *w = primary_weapon();
3870 if (w && w->is_type(OBJ_STAVES, STAFF_POISON))
3871 u++;
3872 }
3873
3874 if (has_ench(ENCH_RESISTANCE))
3875 u++;
3876
3877 // Monsters can have multiple innate levels of poison resistance, but
3878 // like players, equipment doesn't stack.
3879 if (u > 0)
3880 return 1;
3881 return u;
3882 }
3883
res_sticky_flame() const3884 bool monster::res_sticky_flame() const
3885 {
3886 return is_insubstantial() || get_mons_resist(*this, MR_RES_STICKY_FLAME) > 0;
3887 }
3888
res_miasma(bool) const3889 bool monster::res_miasma(bool /*temp*/) const
3890 {
3891 if ((holiness() & (MH_HOLY | MH_DEMONIC | MH_UNDEAD | MH_NONLIVING))
3892 || get_mons_resist(*this, MR_RES_MIASMA))
3893 {
3894 return true;
3895 }
3896
3897 const item_def *armour = mslot_item(MSLOT_ARMOUR);
3898 if (armour && is_unrandom_artefact(*armour, UNRAND_EMBRACE))
3899 return true;
3900
3901 return false;
3902 }
3903
res_holy_energy() const3904 int monster::res_holy_energy() const
3905 {
3906 if (type == MONS_PROFANE_SERVITOR)
3907 return 3;
3908
3909 if (undead_or_demonic())
3910 return -1;
3911
3912 if (is_holy()
3913 || is_good_god(god)
3914 || is_good_god(you.religion) && is_follower(*this))
3915 {
3916 return 3;
3917 }
3918
3919 return 0;
3920 }
3921
res_negative_energy(bool intrinsic_only) const3922 int monster::res_negative_energy(bool intrinsic_only) const
3923 {
3924 // If you change this, also change get_mons_resists.
3925 if (!(holiness() & MH_NATURAL))
3926 return 3;
3927
3928 int u = get_mons_resist(*this, MR_RES_NEG);
3929
3930 if (mons_itemuse(*this) >= MONUSE_STARTING_EQUIPMENT && !intrinsic_only)
3931 {
3932 u += scan_artefacts(ARTP_NEGATIVE_ENERGY);
3933
3934 const int armour = inv[MSLOT_ARMOUR];
3935 const int shld = inv[MSLOT_SHIELD];
3936 const int jewellery = inv[MSLOT_JEWELLERY];
3937
3938 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR)
3939 u += get_armour_life_protection(env.item[armour], false);
3940
3941 if (shld != NON_ITEM && env.item[shld].base_type == OBJ_ARMOUR)
3942 u += get_armour_life_protection(env.item[shld], false);
3943
3944 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY)
3945 u += get_jewellery_life_protection(env.item[jewellery], false);
3946
3947 const item_def *w = primary_weapon();
3948 if (w && w->is_type(OBJ_STAVES, STAFF_DEATH))
3949 u++;
3950 }
3951
3952 if (u > 3)
3953 u = 3;
3954
3955 return u;
3956 }
3957
res_torment() const3958 bool monster::res_torment() const
3959 {
3960 return get_mons_resist(*this, MR_RES_TORMENT) > 0;
3961 }
3962
res_polar_vortex() const3963 bool monster::res_polar_vortex() const
3964 {
3965 return has_ench(ENCH_POLAR_VORTEX)
3966 || get_mons_resist(*this, MR_RES_VORTEX) > 0;
3967 }
3968
res_petrify(bool) const3969 bool monster::res_petrify(bool /*temp*/) const
3970 {
3971 return is_insubstantial() || get_mons_resist(*this, MR_RES_PETRIFY) > 0;
3972 }
3973
res_constrict() const3974 int monster::res_constrict() const
3975 {
3976 // 3 is immunity, 1 or 2 reduces damage
3977 if (is_insubstantial())
3978 return 3;
3979 if (mons_genus(type) == MONS_JELLY)
3980 return 3;
3981 if (is_spiny())
3982 return 3;
3983
3984 return 0;
3985 }
3986
res_corr(bool calc_unid,bool temp) const3987 bool monster::res_corr(bool calc_unid, bool temp) const
3988 {
3989 if (get_mons_resist(*this, MR_RES_ACID) > 0)
3990 return true;
3991
3992 return actor::res_corr(calc_unid, temp);
3993 }
3994
res_acid(bool calc_unid) const3995 int monster::res_acid(bool calc_unid) const
3996 {
3997 int u = max(get_mons_resist(*this, MR_RES_ACID), (int)actor::res_corr(calc_unid));
3998
3999 if (has_ench(ENCH_RESISTANCE))
4000 u++;
4001
4002 return u;
4003 }
4004
4005 /**
4006 * What WL (resistance to hexes, etc) does this monster have?
4007 *
4008 * @param calc_unid Whether to include items & effects the player may not
4009 * know about.
4010 * @return The monster's willpower value.
4011 */
willpower(bool calc_unid) const4012 int monster::willpower(bool calc_unid) const
4013 {
4014 if (mons_invuln_will(*this))
4015 return WILL_INVULN;
4016
4017 const item_def *arm = mslot_item(MSLOT_ARMOUR);
4018 if (arm && is_unrandom_artefact(*arm, UNRAND_FOLLY))
4019 return 0;
4020
4021 const int type_wl = (get_monster_data(type))->willpower;
4022 // Negative values get multiplied with monster hit dice.
4023 int u = type_wl < 0 ?
4024 get_hit_dice() * -type_wl * 4 / 3 :
4025 mons_class_willpower(type, base_monster);
4026
4027 // Hepliaklqana ancestors scale with xl.
4028 if (mons_is_hepliaklqana_ancestor(type))
4029 u = get_experience_level() * get_experience_level() / 2; // 0-160ish
4030
4031 // Draining/malmutation reduce monster base WL proportionately.
4032 const int HD = get_hit_dice();
4033 if (HD < get_experience_level())
4034 u = u * HD / get_experience_level();
4035
4036 // Resistance from artefact properties.
4037 u += WL_PIP * scan_artefacts(ARTP_WILLPOWER);
4038
4039 // Ego equipment resistance.
4040 const int armour = inv[MSLOT_ARMOUR];
4041 const int shld = inv[MSLOT_SHIELD];
4042 const int jewellery = inv[MSLOT_JEWELLERY];
4043
4044 // XXX: should also include artefacts mr props
4045 // (remove ", false" and add appropriate flag checks for calc_unid)
4046
4047 if (armour != NON_ITEM && env.item[armour].base_type == OBJ_ARMOUR
4048 && (calc_unid || (env.item[armour].flags & ISFLAG_KNOW_TYPE)))
4049 {
4050 u += get_armour_willpower(env.item[armour], false);
4051 }
4052
4053 if (shld != NON_ITEM && env.item[shld].base_type == OBJ_ARMOUR
4054 && (calc_unid || (env.item[shld].flags & ISFLAG_KNOW_TYPE)))
4055 {
4056 u += get_armour_willpower(env.item[shld], false);
4057 }
4058
4059 if (jewellery != NON_ITEM && env.item[jewellery].base_type == OBJ_JEWELLERY
4060 && calc_unid) // XXX: can you ever see monster jewellery?
4061 {
4062 u += get_jewellery_willpower(env.item[jewellery], false);
4063 }
4064
4065 if (has_ench(ENCH_STRONG_WILLED)) //trog's hand
4066 u += 80;
4067
4068 if (has_ench(ENCH_LOWERED_WL))
4069 u /= 2;
4070
4071 if (u < 0)
4072 u = 0;
4073
4074 return u;
4075 }
4076
no_tele(bool calc_unid,bool,bool) const4077 bool monster::no_tele(bool calc_unid, bool /*permit_id*/, bool /*blinking*/) const
4078 {
4079 // Plants can't survive without roots, so it's either this or auto-kill.
4080 // Statues have pedestals so moving them is weird.
4081 if (mons_class_is_stationary(type))
4082 return true;
4083
4084 if (mons_is_projectile(type))
4085 return true;
4086
4087 // Might be better to teleport the whole kraken instead...
4088 if (mons_is_tentacle_or_tentacle_segment(type))
4089 return true;
4090
4091 if (stasis())
4092 return true;
4093
4094 // TODO: permit_id
4095 if (has_notele_item(calc_unid))
4096 return true;
4097
4098 if (has_ench(ENCH_DIMENSION_ANCHOR))
4099 return true;
4100
4101 return false;
4102 }
4103
antimagic_susceptible() const4104 bool monster::antimagic_susceptible() const
4105 {
4106 return search_slots([] (const mon_spell_slot& slot)
4107 { return bool(slot.flags & MON_SPELL_ANTIMAGIC_MASK); });
4108 }
4109
airborne() const4110 bool monster::airborne() const
4111 {
4112 // For dancing weapons, this function can get called before their
4113 // ghost_demon is created, so check for a nullptr ghost. -cao
4114 return monster_inherently_flies(*this)
4115 || scan_artefacts(ARTP_FLY) > 0
4116 || mslot_item(MSLOT_ARMOUR)
4117 && mslot_item(MSLOT_ARMOUR)->base_type == OBJ_ARMOUR
4118 && mslot_item(MSLOT_ARMOUR)->brand == SPARM_FLYING
4119 || mslot_item(MSLOT_JEWELLERY)
4120 && mslot_item(MSLOT_JEWELLERY)->is_type(OBJ_JEWELLERY, RING_FLIGHT)
4121 || has_ench(ENCH_FLIGHT);
4122 }
4123
is_banished() const4124 bool monster::is_banished() const
4125 {
4126 return !alive() && flags & MF_BANISHED;
4127 }
4128
mons_species(bool zombie_base) const4129 monster_type monster::mons_species(bool zombie_base) const
4130 {
4131 if (zombie_base && mons_class_is_zombified(type))
4132 return ::mons_species(base_monster);
4133 return ::mons_species(type);
4134 }
4135
poison(actor * agent,int amount,bool force)4136 bool monster::poison(actor *agent, int amount, bool force)
4137 {
4138 if (amount <= 0)
4139 return false;
4140
4141 // Scale poison down for monsters.
4142 amount = 1 + amount / 7;
4143
4144 return poison_monster(this, agent, amount, force);
4145 }
4146
skill(skill_type sk,int scale,bool,bool) const4147 int monster::skill(skill_type sk, int scale, bool /*real*/, bool /*temp*/) const
4148 {
4149 // Let spectral weapons have necromancy skill for pain brand.
4150 if (mons_intel(*this) < I_HUMAN && !mons_is_avatar(type))
4151 return 0;
4152
4153 const int hd = scale * get_hit_dice();
4154 int ret;
4155 switch (sk)
4156 {
4157 case SK_EVOCATIONS:
4158 return hd;
4159
4160 case SK_NECROMANCY:
4161 return (has_spell_of_type(spschool::necromancy)) ? hd : hd/2;
4162
4163 case SK_POISON_MAGIC:
4164 case SK_FIRE_MAGIC:
4165 case SK_ICE_MAGIC:
4166 case SK_EARTH_MAGIC:
4167 case SK_AIR_MAGIC:
4168 case SK_SUMMONINGS:
4169 return is_actual_spellcaster() ? hd : hd / 3;
4170
4171 // Weapon skills for spectral weapon
4172 case SK_SHORT_BLADES:
4173 case SK_LONG_BLADES:
4174 case SK_AXES:
4175 case SK_MACES_FLAILS:
4176 case SK_POLEARMS:
4177 case SK_STAVES:
4178 ret = hd;
4179 if (weapon()
4180 && sk == item_attack_skill(*weapon())
4181 && _is_signature_weapon(this, *weapon()))
4182 {
4183 // generally slightly skilled if it's a signature weapon
4184 ret = ret * 5 / 4;
4185 }
4186 return ret;
4187
4188 default:
4189 return 0;
4190 }
4191 }
4192
4193 /**
4194 * Move a monster to an approximate location.
4195 *
4196 * @param p the position to end up near.
4197 * @return whether it tried to move the monster at all.
4198 */
shift(coord_def p)4199 bool monster::shift(coord_def p)
4200 {
4201 coord_def result;
4202
4203 int count = 0;
4204
4205 if (p.origin())
4206 p = pos();
4207
4208 for (adjacent_iterator ai(p); ai; ++ai)
4209 {
4210 // Don't drop on anything but vanilla floor right now.
4211 if (env.grid(*ai) != DNGN_FLOOR)
4212 continue;
4213
4214 if (actor_at(*ai))
4215 continue;
4216
4217 if (one_chance_in(++count))
4218 result = *ai;
4219 }
4220
4221 if (count > 0)
4222 move_to_pos(result);
4223
4224 return count > 0;
4225 }
blink()4226 void monster::blink()
4227 {
4228 monster_blink(this);
4229 }
4230
teleport(bool now,bool)4231 void monster::teleport(bool now, bool)
4232 {
4233 monster_teleport(this, now, false);
4234 }
4235
alive() const4236 bool monster::alive() const
4237 {
4238 return hit_points > 0 && type != MONS_NO_MONSTER;
4239 }
4240
deity() const4241 god_type monster::deity() const
4242 {
4243 return god;
4244 }
4245
drain(const actor * agent,bool quiet,int)4246 bool monster::drain(const actor *agent, bool quiet, int /*pow*/)
4247 {
4248 if (res_negative_energy() >= 3)
4249 return false;
4250
4251 if (!quiet && you.can_see(*this))
4252 mprf("%s is drained!", name(DESC_THE).c_str());
4253
4254 // If quiet, don't clean up the monster in order to credit properly.
4255 hurt(agent, 2 + random2(3), BEAM_NEG, KILLED_BY_DRAINING, "", "", !quiet);
4256
4257 if (alive())
4258 {
4259 int dur = 200 + random2(100);
4260 dur = min(dur, 300 - get_ench(ENCH_DRAINED).duration - random2(50));
4261
4262 if (res_negative_energy())
4263 dur /= (res_negative_energy() * 2);
4264
4265 const mon_enchant drain_ench = mon_enchant(ENCH_DRAINED, 1, agent,
4266 dur);
4267 add_ench(drain_ench);
4268 }
4269
4270 return true;
4271 }
4272
corrode_equipment(const char * corrosion_source,int degree)4273 bool monster::corrode_equipment(const char* corrosion_source, int degree)
4274 {
4275 // Don't corrode spectral weapons or temporary items.
4276 if (mons_is_avatar(type) || type == MONS_PLAYER_SHADOW)
4277 return false;
4278
4279 // rCorr protects against 50% of corrosion.
4280 // As long as degree is at least 1, we'll apply the status once, because
4281 // it doesn't look to me like applying it more times does anything.
4282 // If I'm wrong, we should fix that.
4283 if (res_corr())
4284 {
4285 degree = binomial(degree, 50);
4286 if (!degree)
4287 {
4288 dprf("rCorr protects.");
4289 return false;
4290 }
4291 }
4292
4293 if (you.see_cell(pos()))
4294 {
4295 if (!has_ench(ENCH_CORROSION))
4296 mprf("%s corrodes %s!", corrosion_source, name(DESC_THE).c_str());
4297 else
4298 mprf("%s seems to be corroded for longer.", name(DESC_THE).c_str());
4299 }
4300
4301 add_ench(mon_enchant(ENCH_CORROSION, 0));
4302 return true;
4303 }
4304
4305 /**
4306 * Attempts to apply corrosion to a monster.
4307 */
splash_with_acid(const actor * evildoer,int,bool,const char *)4308 void monster::splash_with_acid(const actor* evildoer, int /*acid_strength*/,
4309 bool /*allow_corrosion*/, const char* /*hurt_msg*/)
4310 {
4311 // Splashing with acid shouldn't do anything to immune targets
4312 if (res_acid() == 3)
4313 return;
4314
4315 const int dam = roll_dice(2, 4);
4316 const int post_res_dam = resist_adjust_damage(this, BEAM_ACID, dam);
4317
4318 if (this->observable())
4319 {
4320 mprf("%s is splashed with acid%s", this->name(DESC_THE).c_str(),
4321 attack_strength_punctuation(post_res_dam).c_str());
4322 }
4323
4324 if (!one_chance_in(3))
4325 corrode_equipment();
4326
4327 if (post_res_dam > 0)
4328 hurt(evildoer, post_res_dam, BEAM_ACID, KILLED_BY_ACID);
4329 }
4330
hurt(const actor * agent,int amount,beam_type flavour,kill_method_type kill_type,string,string,bool cleanup_dead,bool attacker_effects)4331 int monster::hurt(const actor *agent, int amount, beam_type flavour,
4332 kill_method_type kill_type, string /*source*/,
4333 string /*aux*/, bool cleanup_dead, bool attacker_effects)
4334 {
4335 if (mons_is_projectile(type)
4336 || mid == MID_ANON_FRIEND
4337 || type == MONS_PLAYER_SHADOW)
4338 {
4339 return 0;
4340 }
4341
4342 if (alive())
4343 {
4344 if (amount != INSTANT_DEATH
4345 && mons_species(true) == MONS_DEEP_DWARF)
4346 {
4347 // Deep Dwarves get to shave _any_ hp loss. Player version:
4348 int shave = 1 + random2(2 + random2(1 + get_hit_dice() / 3));
4349 dprf("(mon) HP shaved: %d.", shave);
4350 amount -= shave;
4351 if (amount <= 0)
4352 return 0;
4353 }
4354
4355 if (amount != INSTANT_DEATH)
4356 {
4357 if (petrified())
4358 amount /= 2;
4359 else if (petrifying())
4360 amount = amount * 2 / 3;
4361 }
4362
4363 if (amount != INSTANT_DEATH && has_ench(ENCH_INJURY_BOND))
4364 {
4365 actor* guardian = get_ench(ENCH_INJURY_BOND).agent();
4366 if (guardian && guardian->alive() && mons_aligned(guardian, this))
4367 {
4368 int split = amount / 2;
4369 if (split > 0)
4370 {
4371 deferred_damage_fineff::schedule(agent, guardian,
4372 split, false);
4373 amount -= split;
4374 }
4375 }
4376 }
4377
4378 if (amount == INSTANT_DEATH)
4379 amount = hit_points;
4380 else if (get_hit_dice() <= 0)
4381 amount = hit_points;
4382 else if (amount <= 0 && hit_points <= max_hit_points)
4383 return 0;
4384
4385 // Apply damage multipliers for scarf of harm
4386 if (amount != INSTANT_DEATH)
4387 {
4388 // +30% damage when the opponent has harm
4389 if (agent && agent->extra_harm())
4390 amount = amount * 13 / 10;
4391 // +20% damage when self has harm
4392 else if (extra_harm())
4393 amount = amount * 6 / 5;
4394 }
4395
4396 // Apply damage multipliers for quad damage
4397 if (attacker_effects && agent && agent->is_player()
4398 && you.duration[DUR_QUAD_DAMAGE]
4399 && flavour != BEAM_TORMENT_DAMAGE)
4400 {
4401 amount *= 4;
4402 if (amount > hit_points + 50)
4403 flags |= MF_EXPLODE_KILL;
4404 }
4405
4406 amount = min(amount, hit_points);
4407 hit_points -= amount;
4408
4409 if (hit_points > max_hit_points)
4410 {
4411 amount += hit_points - max_hit_points;
4412 hit_points = max_hit_points;
4413 }
4414
4415 if (flavour == BEAM_DEVASTATION || flavour == BEAM_MINDBURST)
4416 {
4417 if (can_bleed())
4418 blood_spray(pos(), type, amount / 5);
4419
4420 if (!alive())
4421 flags |= MF_EXPLODE_KILL;
4422 }
4423
4424 // Hurt conducts -- pain bond is exempted for balance/gameplay reasons.
4425 // Damage over time effects are excluded for similar reasons.
4426 if (agent && agent->is_player() && mons_gives_xp(*this, *agent)
4427 && flavour != BEAM_SHARED_PAIN
4428 && flavour != BEAM_STICKY_FLAME
4429 && kill_type != KILLED_BY_POISON
4430 && kill_type != KILLED_BY_CLOUD)
4431 {
4432 did_hurt_conduct(DID_HURT_FOE, *this, amount);
4433 }
4434
4435 // Handle pain bond behaviour here. Is technically passive damage.
4436 // radiate_pain_bond may do additional damage by recursively looping
4437 // back to the original trigger.
4438 if (has_ench(ENCH_PAIN_BOND) && flavour != BEAM_SHARED_PAIN)
4439 {
4440 int hp_before_pain_bond = hit_points;
4441 radiate_pain_bond(*this, amount, this);
4442 amount += max(hp_before_pain_bond - hit_points, 0);
4443 }
4444
4445 // Allow the victim to exhibit passive damage behaviour (e.g.
4446 // the Royal Jelly or Uskayaw's Pain Bond).
4447 react_to_damage(agent, amount, flavour);
4448
4449 // Don't mirror Yredelemnul's effects (in particular don't mirror
4450 // mirrored damage).
4451 if (has_ench(ENCH_MIRROR_DAMAGE)
4452 && crawl_state.which_god_acting() != GOD_YREDELEMNUL)
4453 {
4454 // ensure that YOU_FAULTLESS is converted to `you`. this may still
4455 // fail e.g. when the damage is from a vault-created cloud
4456 if (auto valid_agent = ensure_valid_actor(agent))
4457 mirror_damage_fineff::schedule(valid_agent, this, amount * 2 / 3);
4458 }
4459
4460 // Trigger corrupting presence
4461 if (agent && agent->is_player() && alive()
4462 && you.get_mutation_level(MUT_CORRUPTING_PRESENCE))
4463 {
4464 if (one_chance_in(12))
4465 this->corrode_equipment("Your corrupting presence");
4466 if (you.get_mutation_level(MUT_CORRUPTING_PRESENCE) > 1
4467 && one_chance_in(12))
4468 {
4469 this->malmutate("Your corrupting presence");
4470 }
4471 }
4472
4473 blame_damage(agent, amount);
4474
4475 if (mons_is_fragile(*this) && !has_ench(ENCH_SLOWLY_DYING))
4476 {
4477 // Die in 3-5 turns.
4478 this->add_ench(mon_enchant(ENCH_SLOWLY_DYING, 1, nullptr,
4479 30 + random2(20)));
4480 if (you.can_see(*this))
4481 {
4482 if (type == MONS_WITHERED_PLANT)
4483 mprf("%s begins to crumble.", this->name(DESC_THE).c_str());
4484 else
4485 mprf("%s begins to die.", this->name(DESC_THE).c_str());
4486 }
4487 }
4488 }
4489
4490 if (cleanup_dead && (hit_points <= 0 || get_hit_dice() <= 0)
4491 && type != MONS_NO_MONSTER)
4492 {
4493 if (agent == nullptr)
4494 monster_die(*this, KILL_MISC, NON_MONSTER);
4495 else if (agent->is_player())
4496 monster_die(*this, KILL_YOU, NON_MONSTER);
4497 else
4498 monster_die(*this, KILL_MON, agent->mindex());
4499 }
4500
4501 return amount;
4502 }
4503
confuse(actor * atk,int strength)4504 void monster::confuse(actor *atk, int strength)
4505 {
4506 if (!clarity())
4507 enchant_actor_with_flavour(this, atk, BEAM_CONFUSION, strength);
4508 }
4509
paralyse(const actor * atk,int strength,string)4510 void monster::paralyse(const actor *atk, int strength, string /*cause*/)
4511 {
4512 enchant_actor_with_flavour(this, atk, BEAM_PARALYSIS, strength);
4513 }
4514
petrify(const actor * atk,bool)4515 void monster::petrify(const actor *atk, bool /*force*/)
4516 {
4517 enchant_actor_with_flavour(this, atk, BEAM_PETRIFY);
4518 }
4519
fully_petrify(bool quiet)4520 bool monster::fully_petrify(bool quiet)
4521 {
4522 bool msg = !quiet && simple_monster_message(*this, mons_is_immotile(*this) ?
4523 " turns to stone!" : " stops moving altogether!");
4524
4525 add_ench(ENCH_PETRIFIED);
4526 return msg;
4527 }
4528
slow_down(actor * atk,int strength)4529 void monster::slow_down(actor *atk, int strength)
4530 {
4531 enchant_actor_with_flavour(this, atk, BEAM_SLOW, strength);
4532 }
4533
set_ghost(const ghost_demon & g)4534 void monster::set_ghost(const ghost_demon &g)
4535 {
4536 ghost.reset(new ghost_demon(g));
4537
4538 if (!ghost->name.empty())
4539 mname = ghost->name;
4540 }
4541
set_new_monster_id()4542 void monster::set_new_monster_id()
4543 {
4544 mid = ++you.last_mid;
4545 // Sorry, if you made 4294901759 monsters over the course of your
4546 // game you deserve a crash, particularly when the game doesn't
4547 // even last that many turns.
4548 ASSERT(mid < MID_FIRST_NON_MONSTER);
4549 env.mid_cache[mid] = mindex();
4550 }
4551
ghost_init(bool need_pos)4552 void monster::ghost_init(bool need_pos)
4553 {
4554 ghost_demon_init();
4555
4556 god = ghost->religion;
4557 attitude = ATT_HOSTILE;
4558 behaviour = BEH_WANDER;
4559 flags = MF_NO_FLAGS;
4560 foe = MHITNOT;
4561 foe_memory = 0;
4562 number = MONS_NO_MONSTER;
4563
4564 // Ghosts can't worship good gods, but keep the god in the ghost
4565 // structure so the ghost can comment on it.
4566 if (is_good_god(god))
4567 god = GOD_NO_GOD;
4568
4569 inv.init(NON_ITEM);
4570 enchantments.clear();
4571 ench_cache.reset();
4572 ench_countdown = 0;
4573
4574 // Summoned player ghosts are already given a position; calling this
4575 // in those instances will cause a segfault. Instead, check to see
4576 // if we have a home first. {due}
4577 if (need_pos && !in_bounds(pos()))
4578 find_place_to_live();
4579
4580 bind_melee_flags();
4581 bind_spell_flags(); // does this even do anything on ghosts?
4582 }
4583
uglything_init(bool only_mutate)4584 void monster::uglything_init(bool only_mutate)
4585 {
4586 // If we're mutating an ugly thing, leave its experience level, hit
4587 // dice and maximum and current hit points as they are.
4588 if (!only_mutate)
4589 {
4590 hit_dice = ghost->xl;
4591 max_hit_points = ghost->max_hp;
4592 hit_points = max_hit_points;
4593 }
4594
4595 speed = ghost->speed;
4596 speed_increment = 70;
4597 colour = ghost->colour;
4598 }
4599
ghost_demon_init()4600 void monster::ghost_demon_init()
4601 {
4602 hit_dice = ghost->xl;
4603 max_hit_points = min<short int>(ghost->max_hp, MAX_MONSTER_HP);
4604 hit_points = max_hit_points;
4605 speed = ghost->speed;
4606 speed_increment = 70;
4607 if (ghost->colour != COLOUR_UNDEF)
4608 colour = ghost->colour;
4609 if (ghost->cloud_ring_ench != ENCH_NONE)
4610 add_ench(ghost->cloud_ring_ench);
4611
4612 load_ghost_spells();
4613 }
4614
uglything_mutate(colour_t force_colour)4615 void monster::uglything_mutate(colour_t force_colour)
4616 {
4617 ghost->init_ugly_thing(type == MONS_VERY_UGLY_THING, true, force_colour);
4618 uglything_init(true);
4619 }
4620
4621 // Randomise potential damage.
_estimated_trap_damage(trap_type trap)4622 static int _estimated_trap_damage(trap_type trap)
4623 {
4624 switch (trap)
4625 {
4626 case TRAP_BLADE: return 10 + random2(30);
4627 case TRAP_ARROW: return random2(7);
4628 case TRAP_SPEAR: return random2(10);
4629 case TRAP_BOLT: return random2(13);
4630 default: return 0;
4631 }
4632 }
4633
4634 /**
4635 * Check whether a given trap (described by trap position) can be
4636 * regarded as safe. Takes into account monster intelligence and
4637 * allegiance.
4638 *
4639 * @param where The square to be checked for dangerous traps.
4640 * @param just_check Used for intelligent monsters trying to avoid traps.
4641 * @return Whether the monster will willingly enter the square.
4642 */
is_trap_safe(const coord_def & where,bool just_check) const4643 bool monster::is_trap_safe(const coord_def& where, bool just_check) const
4644 {
4645 const mon_intel_type intel = mons_intel(*this);
4646
4647 const trap_def *ptrap = trap_at(where);
4648 if (!ptrap)
4649 return true;
4650 const trap_def& trap = *ptrap;
4651
4652 // Known shafts are safe.
4653 if (trap.type == TRAP_SHAFT)
4654 return true;
4655
4656 #if TAG_MAJOR_VERSION == 34
4657 if (trap.type == TRAP_SHADOW_DORMANT || trap.type == TRAP_SHADOW)
4658 return true;
4659 #endif
4660
4661 // No friendly or good neutral monsters will ever enter a trap that harms
4662 // the player when triggered.
4663 if (wont_attack() && trap.is_bad_for_player())
4664 return false;
4665
4666 // Dumb monsters don't care at all.
4667 if (intel == I_BRAINLESS)
4668 return true;
4669
4670 // Ditto, berserkers & frenzied creatures.
4671 if (berserk_or_insane())
4672 return true;
4673
4674 // Friendlies will try not to be parted from you.
4675 if (intelligent_ally(*this) && (trap.type == TRAP_TELEPORT
4676 || trap.type == TRAP_TELEPORT_PERMANENT)
4677 && can_see(you))
4678 {
4679 return false;
4680 }
4681
4682 // Hostile monsters are not afraid of non-mechanical traps.
4683 // But, in the arena Zot traps affect all monsters.
4684 if (!trap.is_mechanical())
4685 return !crawl_state.game_is_arena() || trap.type != TRAP_ZOT;
4686
4687 // Net traps always target the player, let's use them!
4688 if (trap.type == TRAP_NET)
4689 return true;
4690
4691 // If just checking a mechanical trap is dangerous
4692 if (just_check)
4693 return false;
4694
4695 // Mechanical trap calculations
4696 // Test for corridor-like environment.
4697 const int x = where.x - pos().x;
4698 const int y = where.y - pos().y;
4699
4700 // The question is whether the monster (m) can easily reach its
4701 // presumable destination (x) without stepping on the trap. Traps
4702 // in corridors do not allow this. See e.g
4703 // #x# ##
4704 // #^# or m^x
4705 // m ##
4706 //
4707 // The same problem occurs if paths are blocked by monsters,
4708 // hostile terrain or other traps rather than walls.
4709 // What we do is check whether the squares with the relative
4710 // positions (-1,0)/(+1,0) or (0,-1)/(0,+1) form a "corridor"
4711 // (relative to the _trap_ position rather than the monster one).
4712 // If they don't, the trap square is marked as "unsafe" (because
4713 // there's a good alternative move for the monster to take),
4714 // otherwise the decision will be made according to later tests
4715 // (monster hp, trap type, ...)
4716 // If a monster still gets stuck in a corridor it will usually be
4717 // because it has less than half its maximum hp.
4718
4719 if ((mon_can_move_to_pos(this, coord_def(x-1, y), true)
4720 || mon_can_move_to_pos(this, coord_def(x+1,y), true))
4721 && (mon_can_move_to_pos(this, coord_def(x,y-1), true)
4722 || mon_can_move_to_pos(this, coord_def(x,y+1), true)))
4723 {
4724 return false;
4725 }
4726
4727 // Healthy monsters don't mind a little pain.
4728 if (hit_points >= max_hit_points / 2
4729 && (intel < I_HUMAN
4730 || hit_points > _estimated_trap_damage(trap.type)))
4731 {
4732 return true;
4733 }
4734
4735 // we don't think we have enough hp (per above), so avoid mech traps
4736 return false;
4737 }
4738
is_cloud_safe(const coord_def & place) const4739 bool monster::is_cloud_safe(const coord_def &place) const
4740 {
4741 return !mons_avoids_cloud(this, place);
4742 }
4743
check_set_valid_home(const coord_def & place,coord_def & chosen,int & nvalid) const4744 bool monster::check_set_valid_home(const coord_def &place,
4745 coord_def &chosen,
4746 int &nvalid) const
4747 {
4748 if (!in_bounds(place))
4749 return false;
4750
4751 if (actor_at(place))
4752 return false;
4753
4754 if (!monster_habitable_grid(this, env.grid(place)))
4755 return false;
4756
4757 if (!is_trap_safe(place, true))
4758 return false;
4759
4760 if (one_chance_in(++nvalid))
4761 chosen = place;
4762
4763 return true;
4764 }
4765
4766
is_location_safe(const coord_def & place)4767 bool monster::is_location_safe(const coord_def &place)
4768 {
4769 if (!monster_habitable_grid(this, env.grid(place)))
4770 return false;
4771
4772 if (!is_trap_safe(place, true))
4773 return false;
4774
4775 if (!is_cloud_safe(place))
4776 return false;
4777
4778 return true;
4779 }
4780
has_originating_map() const4781 bool monster::has_originating_map() const
4782 {
4783 return props.exists(MAP_KEY);
4784 }
4785
originating_map() const4786 string monster::originating_map() const
4787 {
4788 if (!has_originating_map())
4789 return "";
4790 return props[MAP_KEY].get_string();
4791 }
4792
set_originating_map(const string & map_name)4793 void monster::set_originating_map(const string &map_name)
4794 {
4795 if (!map_name.empty())
4796 props[MAP_KEY].get_string() = map_name;
4797 }
4798
4799 #define MAX_PLACE_NEAR_DIST 8
4800
find_home_near_place(const coord_def & c)4801 bool monster::find_home_near_place(const coord_def &c)
4802 {
4803 int last_dist = -1;
4804 coord_def place(-1, -1);
4805 int nvalid = 0;
4806 SquareArray<int, MAX_PLACE_NEAR_DIST> dist(-1);
4807 queue<coord_def> q;
4808
4809 q.push(c);
4810 dist(coord_def()) = 0;
4811 while (!q.empty())
4812 {
4813 coord_def p = q.front();
4814 q.pop();
4815 if (dist(p - c) >= last_dist && nvalid)
4816 {
4817 bool moved_to_pos = move_to_pos(place);
4818 ASSERT(moved_to_pos);
4819 // can't apply location effects here, since the monster might not
4820 // be on the level yet, which interacts poorly with e.g. shafts
4821 return true;
4822 }
4823 else if (dist(p - c) >= MAX_PLACE_NEAR_DIST)
4824 break;
4825
4826 for (adjacent_iterator ai(p); ai; ++ai)
4827 {
4828 if (dist(*ai - c) > -1)
4829 continue;
4830 dist(*ai - c) = last_dist = dist(p - c) + 1;
4831
4832 if (!monster_habitable_grid(this, env.grid(*ai)))
4833 continue;
4834
4835 q.push(*ai);
4836 check_set_valid_home(*ai, place, nvalid);
4837 }
4838 }
4839
4840 return false;
4841 }
4842
find_home_near_player()4843 bool monster::find_home_near_player()
4844 {
4845 return find_home_near_place(you.pos());
4846 }
4847
find_home_anywhere()4848 bool monster::find_home_anywhere()
4849 {
4850 coord_def place(-1, -1);
4851 int nvalid = 0;
4852 for (int tries = 0; tries < 600; ++tries)
4853 if (check_set_valid_home(random_in_bounds(), place, nvalid))
4854 {
4855 bool moved_to_pos = move_to_pos(place);
4856 ASSERT(moved_to_pos);
4857 // can't apply location effects here, since the monster might not
4858 // be on the level yet, which interacts poorly with e.g. shafts
4859 return true;
4860 }
4861 return false;
4862 }
4863
find_place_to_live(bool near_player)4864 bool monster::find_place_to_live(bool near_player)
4865 {
4866 return near_player && find_home_near_player()
4867 || find_home_anywhere();
4868 }
4869
destroy_inventory()4870 void monster::destroy_inventory()
4871 {
4872 for (mon_inv_iterator ii(*this); ii; ++ii)
4873 destroy_item(ii->index());
4874 }
4875
is_travelling() const4876 bool monster::is_travelling() const
4877 {
4878 return !travel_path.empty();
4879 }
4880
is_patrolling() const4881 bool monster::is_patrolling() const
4882 {
4883 return !patrol_point.origin();
4884 }
4885
needs_abyss_transit() const4886 bool monster::needs_abyss_transit() const
4887 {
4888 return (mons_is_unique(type)
4889 || (flags & MF_BANISHED)
4890 || get_experience_level() > 8 + random2(25)
4891 && mons_can_use_stairs(*this))
4892 && !is_summoned()
4893 && !mons_is_conjured(type);
4894 }
4895
set_transit(const level_id & dest)4896 void monster::set_transit(const level_id &dest)
4897 {
4898 add_monster_to_transit(dest, *this);
4899 if (you.can_see(*this))
4900 remove_unique_annotation(this);
4901 }
4902
load_ghost_spells()4903 void monster::load_ghost_spells()
4904 {
4905 if (!ghost)
4906 {
4907 spells.clear();
4908 return;
4909 }
4910
4911 spells = ghost->spells;
4912
4913 #ifdef DEBUG_DIAGNOSTICS
4914 dprf(DIAG_MONPLACE, "Ghost spells:");
4915 for (unsigned int i = 0; i < spells.size(); i++)
4916 {
4917 dprf(DIAG_MONPLACE, "Spell #%d: %d (%s)",
4918 i, spells[i].spell, spell_title(spells[i].spell));
4919 }
4920 #endif
4921 }
4922
has_hydra_multi_attack() const4923 bool monster::has_hydra_multi_attack() const
4924 {
4925 return mons_genus(mons_base_type(*this)) == MONS_HYDRA
4926 || mons_species(true) == MONS_SERPENT_OF_HELL;
4927 }
4928
heads() const4929 int monster::heads() const
4930 {
4931 if (has_hydra_multi_attack())
4932 return num_heads;
4933 else if (mons_shouts(mons_species(true)) == S_SHOUT2)
4934 return 2;
4935 // There are lots of things with more or fewer heads, but the return value
4936 // here doesn't actually matter for non-hydra-type monsters.
4937 else
4938 return 1;
4939 }
4940
has_multitargeting() const4941 bool monster::has_multitargeting() const
4942 {
4943 return has_hydra_multi_attack() && !mons_is_zombified(*this);
4944 }
4945
is_priest() const4946 bool monster::is_priest() const
4947 {
4948 return search_slots([] (const mon_spell_slot& slot)
4949 { return bool(slot.flags & MON_SPELL_PRIEST); });
4950 }
4951
is_fighter() const4952 bool monster::is_fighter() const
4953 {
4954 return bool(flags & MF_FIGHTER);
4955 }
4956
is_archer() const4957 bool monster::is_archer() const
4958 {
4959 return bool(flags & MF_ARCHER);
4960 }
4961
is_actual_spellcaster() const4962 bool monster::is_actual_spellcaster() const
4963 {
4964 return search_slots([] (const mon_spell_slot& slot)
4965 { return bool(slot.flags & MON_SPELL_WIZARD); } );
4966 }
4967
is_shapeshifter() const4968 bool monster::is_shapeshifter() const
4969 {
4970 return has_ench(ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER);
4971 }
4972
scale_hp(int num,int den)4973 void monster::scale_hp(int num, int den)
4974 {
4975 // Without the +1, we lose maxhp on every berserk (the only use) if the
4976 // maxhp is odd. This version does preserve the value correctly, but only
4977 // if it is first inflated then deflated.
4978 hit_points = (hit_points * num + 1) / den;
4979 max_hit_points = (max_hit_points * num + 1) / den;
4980
4981 if (hit_points < 1)
4982 hit_points = 1;
4983 if (max_hit_points < 1)
4984 max_hit_points = 1;
4985 if (hit_points > max_hit_points)
4986 hit_points = max_hit_points;
4987 }
4988
kill_alignment() const4989 kill_category monster::kill_alignment() const
4990 {
4991 if (mid == MID_YOU_FAULTLESS)
4992 return KC_YOU;
4993 return friendly() ? KC_FRIENDLY : KC_OTHER;
4994 }
4995
sicken(int amount)4996 bool monster::sicken(int amount)
4997 {
4998 if (res_miasma() || (amount /= 2) < 1)
4999 return false;
5000
5001 if (!has_ench(ENCH_SICK) && you.can_see(*this))
5002 {
5003 // Yes, could be confused with poisoning.
5004 mprf("%s looks sick.", name(DESC_THE).c_str());
5005 }
5006
5007 add_ench(mon_enchant(ENCH_SICK, 0, 0, amount * BASELINE_DELAY));
5008
5009 return true;
5010 }
5011
5012 // Recalculate movement speed.
calc_speed()5013 void monster::calc_speed()
5014 {
5015 speed = mons_base_speed(*this);
5016
5017 if (has_ench(ENCH_BERSERK))
5018 speed = berserk_mul(speed);
5019 else if (has_ench(ENCH_HASTE))
5020 speed = haste_mul(speed);
5021 if (has_ench(ENCH_SLOW))
5022 speed = haste_div(speed);
5023 }
5024
5025 // Check speed and speed_increment sanity.
check_speed()5026 void monster::check_speed()
5027 {
5028 // FIXME: If speed is borked, recalculate. Need to figure out how
5029 // speed is getting borked.
5030 if (speed < 0 || speed > 130)
5031 {
5032 dprf("Bad speed: %s, spd: %d, spi: %d, hd: %d, ench: %s",
5033 name(DESC_PLAIN).c_str(),
5034 speed, speed_increment, get_hit_dice(),
5035 describe_enchantments().c_str());
5036
5037 calc_speed();
5038
5039 dprf("Fixed speed for %s to %d", name(DESC_PLAIN).c_str(), speed);
5040 }
5041
5042 if (speed_increment < 0)
5043 speed_increment = 0;
5044
5045 if (speed_increment > 200)
5046 {
5047 dprf("Clamping speed increment on %s: %d",
5048 name(DESC_PLAIN).c_str(), speed_increment);
5049
5050 speed_increment = 140;
5051 }
5052 }
5053
get_foe() const5054 actor *monster::get_foe() const
5055 {
5056 if (foe == MHITNOT)
5057 return nullptr;
5058 else if (foe == MHITYOU)
5059 return friendly() ? nullptr : &you;
5060
5061 // Must be a monster!
5062 monster* my_foe = &env.mons[foe];
5063 return my_foe->alive()? my_foe : nullptr;
5064 }
5065
foe_distance() const5066 int monster::foe_distance() const
5067 {
5068 const actor *afoe = get_foe();
5069 return afoe ? pos().distance_from(afoe->pos())
5070 : INFINITE_DISTANCE;
5071 }
5072
5073 /**
5074 * Can the monster suffer ENCH_FRENZY?
5075 *
5076 * @param check_sleep Consider sleeping monsters as immune.
5077 */
can_go_frenzy(bool check_sleep) const5078 bool monster::can_go_frenzy(bool check_sleep) const
5079 {
5080 if (mons_is_tentacle_or_tentacle_segment(type))
5081 return false;
5082
5083 // Brainless natural monsters can still be berserked/frenzied.
5084 // This could maybe all be replaced by mons_is_object()?
5085 if (mons_intel(*this) == I_BRAINLESS && !(holiness() & MH_NATURAL))
5086 return false;
5087
5088 if (paralysed() || petrified() || petrifying() || check_sleep && asleep())
5089 return false;
5090
5091 if (berserk_or_insane() || has_ench(ENCH_FATIGUE))
5092 return false;
5093
5094 // If we have no melee attack, going berserk is pointless.
5095 if (!mons_has_attacks(*this))
5096 return false;
5097
5098 // These allies have a special loyalty
5099 if (god_protects(this)
5100 || testbits(flags, MF_DEMONIC_GUARDIAN))
5101 {
5102 return false;
5103 }
5104
5105 return true;
5106 }
5107
can_go_berserk() const5108 bool monster::can_go_berserk() const
5109 {
5110 return bool(holiness() & MH_NATURAL) && can_go_frenzy();
5111 }
5112
berserk() const5113 bool monster::berserk() const
5114 {
5115 return has_ench(ENCH_BERSERK);
5116 }
5117
5118 // XXX: this function could use a better name
berserk_or_insane() const5119 bool monster::berserk_or_insane() const
5120 {
5121 return berserk() || has_ench(ENCH_INSANE);
5122 }
5123
needs_berserk(bool check_spells,bool ignore_distance) const5124 bool monster::needs_berserk(bool check_spells, bool ignore_distance) const
5125 {
5126 if (!can_go_berserk())
5127 return false;
5128
5129 if (has_ench(ENCH_HASTE) || has_ench(ENCH_TP))
5130 return false;
5131
5132 if (!ignore_distance && foe_distance() > 3)
5133 return false;
5134
5135 if (check_spells)
5136 {
5137 for (const mon_spell_slot &slot : spells)
5138 {
5139 // Don't count natural abilities for this purpose.
5140 if (slot.flags & MON_SPELL_NATURAL)
5141 continue;
5142
5143 const int spell = slot.spell;
5144 if (spell != SPELL_BERSERKER_RAGE)
5145 return false;
5146 }
5147 }
5148
5149 return true;
5150 }
5151
5152 /**
5153 * Can this monster see invisible creatures?
5154 *
5155 * @param calc_unid Should effects the player doesn't know about be
5156 * considered?
5157 * @return Whether the monster can see invisible things.
5158 */
can_see_invisible(bool calc_unid) const5159 bool monster::can_see_invisible(bool calc_unid) const
5160 {
5161 if (mons_is_ghost_demon(type))
5162 return ghost->see_invis;
5163 else if (mons_class_sees_invis(type, base_monster))
5164 return true;
5165 else if (has_facet(BF_WEIRD))
5166 return true;
5167
5168 if (!calc_unid)
5169 return false;
5170
5171 if (scan_artefacts(ARTP_SEE_INVISIBLE) > 0)
5172 return true;
5173 else if (wearing(EQ_RINGS, RING_SEE_INVISIBLE))
5174 return true;
5175 else if (wearing_ego(EQ_ALL_ARMOUR, SPARM_SEE_INVISIBLE))
5176 return true;
5177
5178 return false;
5179 }
5180
invisible() const5181 bool monster::invisible() const
5182 {
5183 return has_ench(ENCH_INVIS) && !backlit();
5184 }
5185
visible_to(const actor * looker) const5186 bool monster::visible_to(const actor *looker) const
5187 {
5188 const bool blind = looker->is_monster()
5189 && looker->as_monster()->has_ench(ENCH_BLIND);
5190 const bool physically_vis = !blind && (!invisible()
5191 || looker->can_see_invisible());
5192 const bool seen_by_att = looker->is_player() && (friendly() || pacified());
5193
5194 const bool vis = seen_by_att || physically_vis;
5195 return vis && (this == looker || !submerged());
5196 }
5197
near_foe() const5198 bool monster::near_foe() const
5199 {
5200 const actor *afoe = get_foe();
5201 return afoe && see_cell_no_trans(afoe->pos())
5202 && summon_can_attack(this, afoe);
5203 }
5204
5205 /**
5206 * Can the monster be mutated?
5207 *
5208 * Nonliving (e.g. statue) monsters & the undead are safe, as are a very few
5209 * other weird types of monsters.
5210 *
5211 * @return Whether the monster can be mutated in any way.
5212 */
can_mutate() const5213 bool monster::can_mutate() const
5214 {
5215 if (mons_is_tentacle_or_tentacle_segment(type))
5216 return false;
5217
5218 // too weird
5219 if (type == MONS_CHAOS_SPAWN)
5220 return false;
5221
5222 // Abominations re-randomize their tile when mutated. They do not gain the
5223 // malmutate status or experience any other non-cosmetic effect.
5224 if (type == MONS_ABOMINATION_SMALL || type == MONS_ABOMINATION_LARGE)
5225 return true;
5226
5227 const mon_holy_type holi = holiness();
5228
5229 return !(holi & (MH_UNDEAD | MH_NONLIVING));
5230 }
5231
can_safely_mutate(bool) const5232 bool monster::can_safely_mutate(bool /*temp*/) const
5233 {
5234 return can_mutate();
5235 }
5236
can_polymorph() const5237 bool monster::can_polymorph() const
5238 {
5239 // can't mutate but can be poly'd
5240 if (type == MONS_CHAOS_SPAWN)
5241 return true;
5242
5243 // Abominations re-randomize their tile when mutated, so can_mutate returns
5244 // true for them. Like all undead, they can't be polymorphed.
5245 if (type == MONS_ABOMINATION_SMALL || type == MONS_ABOMINATION_LARGE)
5246 return false;
5247
5248 return can_mutate();
5249 }
5250
can_bleed(bool) const5251 bool monster::can_bleed(bool /*temp*/) const
5252 {
5253 return mons_has_blood(type);
5254 }
5255
is_stationary() const5256 bool monster::is_stationary() const
5257 {
5258 return mons_class_is_stationary(type);
5259 }
5260
can_burrow() const5261 bool monster::can_burrow() const
5262 {
5263 return mons_class_flag(type, M_BURROWS);
5264 }
5265
5266 /**
5267 * Malmutate the monster.
5268 *
5269 * Gives a temporary 'wretched' effect, generally. Some monsters have special
5270 * interactions.
5271 *
5272 * @return Whether the monster was mutated in any way.
5273 */
malmutate(const string &)5274 bool monster::malmutate(const string &/*reason*/)
5275 {
5276 if (!can_mutate())
5277 return false;
5278
5279 // Abominations re-randomize their tile when mutated. They do not gain the
5280 // malmutate status or experience any other non-cosmetic effect.
5281 if (type == MONS_ABOMINATION_SMALL || type == MONS_ABOMINATION_LARGE)
5282 {
5283 #ifdef USE_TILE
5284 props[TILE_NUM_KEY].get_short() = ui_random(256);
5285 #endif
5286 return true;
5287 }
5288
5289 // Ugly things merely change colour.
5290 if (type == MONS_UGLY_THING || type == MONS_VERY_UGLY_THING)
5291 {
5292 ugly_thing_mutate(*this);
5293 return true;
5294 }
5295
5296 simple_monster_message(*this, " twists and deforms.");
5297 add_ench(mon_enchant(ENCH_WRETCHED, 1));
5298 return true;
5299 }
5300
5301 /**
5302 * Corrupt the monster's body.
5303 *
5304 * Analogous to effects that give the player temp mutations, like wretched star
5305 * pulses & demonspawn corruptors. Currently identical to malmutate. (Writing
5306 * this function anyway, since they probably shouldn't be identical.)
5307 *
5308 * XXX: adjust duration to differentiate? (make malmut's duration longer, or
5309 * corrupt's shorter?)
5310 */
corrupt()5311 void monster::corrupt()
5312 {
5313 malmutate("");
5314 }
5315
polymorph(int,bool)5316 bool monster::polymorph(int /* pow */, bool /*allow_immobile*/)
5317 {
5318 return polymorph();
5319 }
5320
polymorph(poly_power_type power)5321 bool monster::polymorph(poly_power_type power)
5322 {
5323 if (!can_polymorph())
5324 return false;
5325
5326 // Polymorphing a (very) ugly thing will mutate it into a different
5327 // (very) ugly thing.
5328 if (type == MONS_UGLY_THING || type == MONS_VERY_UGLY_THING)
5329 {
5330 ugly_thing_mutate(*this);
5331 return true;
5332 }
5333
5334 // Polymorphing a shapeshifter will make it revert to its original
5335 // form.
5336 if (has_ench(ENCH_GLOWING_SHAPESHIFTER))
5337 return monster_polymorph(this, MONS_GLOWING_SHAPESHIFTER, power);
5338 if (has_ench(ENCH_SHAPESHIFTER))
5339 return monster_polymorph(this, MONS_SHAPESHIFTER, power);
5340
5341 // Polymorphing a slime creature will usually split it first
5342 // and polymorph each part separately.
5343 if (type == MONS_SLIME_CREATURE)
5344 {
5345 slime_creature_polymorph(*this, power);
5346 return true;
5347 }
5348
5349 return monster_polymorph(this, RANDOM_POLYMORPH_MONSTER, power);
5350 }
5351
_mons_is_icy(int mc)5352 static bool _mons_is_icy(int mc)
5353 {
5354 return mc == MONS_ICE_BEAST
5355 || mc == MONS_SIMULACRUM
5356 || mc == MONS_ICE_STATUE
5357 || mc == MONS_BLOCK_OF_ICE;
5358 }
5359
is_icy() const5360 bool monster::is_icy() const
5361 {
5362 return _mons_is_icy(type);
5363 }
5364
_mons_is_fiery(int mc)5365 static bool _mons_is_fiery(int mc)
5366 {
5367 return mc == MONS_FIRE_VORTEX
5368 || mc == MONS_FIRE_ELEMENTAL
5369 || mc == MONS_EFREET
5370 || mc == MONS_AZRAEL
5371 || mc == MONS_LAVA_SNAKE
5372 || mc == MONS_SALAMANDER
5373 || mc == MONS_SALAMANDER_MYSTIC
5374 || mc == MONS_MOLTEN_GARGOYLE
5375 || mc == MONS_ORB_OF_FIRE;
5376 }
5377
is_fiery() const5378 bool monster::is_fiery() const
5379 {
5380 return _mons_is_fiery(type);
5381 }
5382
_mons_is_skeletal(int mc)5383 static bool _mons_is_skeletal(int mc)
5384 {
5385 return mc == MONS_SKELETON
5386 || mc == MONS_BONE_DRAGON
5387 || mc == MONS_SKELETAL_WARRIOR
5388 || mc == MONS_ANCIENT_CHAMPION
5389 || mc == MONS_REVENANT
5390 || mc == MONS_FLYING_SKULL
5391 || mc == MONS_CURSE_SKULL
5392 || mc == MONS_MURRAY;
5393 }
5394
is_skeletal() const5395 bool monster::is_skeletal() const
5396 {
5397 return _mons_is_skeletal(type);
5398 }
5399
5400 /**
5401 * Does this monster have spines?
5402 *
5403 * (If so, it may do damage when attacked in melee, and has rConstrict (!?)
5404 *
5405 * @return Whether this monster has spines.
5406 */
is_spiny() const5407 bool monster::is_spiny() const
5408 {
5409 return mons_class_flag(mons_is_job(type) ? base_monster : type,
5410 M_SPINY);
5411 }
5412
has_action_energy() const5413 bool monster::has_action_energy() const
5414 {
5415 return speed_increment >= 80;
5416 }
5417
check_redraw(const coord_def & old,bool clear_tiles) const5418 void monster::check_redraw(const coord_def &old, bool clear_tiles) const
5419 {
5420 if (!crawl_state.io_inited)
5421 return;
5422
5423 const bool see_new = you.see_cell(pos());
5424 const bool see_old = you.see_cell(old);
5425 if ((see_new || see_old) && !view_update())
5426 {
5427 if (see_new)
5428 view_update_at(pos());
5429
5430 // Don't leave a trail if we can see the monster move in.
5431 if (see_old || (pos() - old).rdist() <= 1)
5432 {
5433 view_update_at(old);
5434 #ifdef USE_TILE
5435 if (clear_tiles && !see_old)
5436 tile_reset_fg(old);
5437 #else
5438 UNUSED(clear_tiles);
5439 #endif
5440 }
5441 update_screen();
5442 }
5443 }
5444
apply_location_effects(const coord_def & oldpos,killer_type killer,int killernum)5445 void monster::apply_location_effects(const coord_def &oldpos,
5446 killer_type killer,
5447 int killernum)
5448 {
5449 if (oldpos != pos())
5450 dungeon_events.fire_position_event(DET_MONSTER_MOVED, pos());
5451
5452 if (alive()
5453 && (mons_habitat(*this) == HT_WATER || mons_habitat(*this) == HT_LAVA)
5454 && !monster_habitable_grid(this, env.grid(pos()))
5455 && !has_ench(ENCH_AQUATIC_LAND))
5456 {
5457 add_ench(ENCH_AQUATIC_LAND);
5458 }
5459
5460 if (alive() && has_ench(ENCH_AQUATIC_LAND))
5461 {
5462 if (!monster_habitable_grid(this, env.grid(pos())))
5463 simple_monster_message(*this, " flops around on dry land!");
5464 else if (!monster_habitable_grid(this, env.grid(oldpos)))
5465 {
5466 if (you.can_see(*this))
5467 {
5468 mprf("%s dives back into the %s!", name(DESC_THE).c_str(),
5469 feat_type_name(env.grid(pos())));
5470 }
5471 del_ench(ENCH_AQUATIC_LAND);
5472 }
5473 // This may have been called via dungeon_terrain_changed instead
5474 // of by the monster moving move, in that case env.grid(oldpos) will
5475 // be the current position that became watery.
5476 else
5477 del_ench(ENCH_AQUATIC_LAND);
5478 }
5479
5480 // Monsters stepping on traps:
5481 trap_def* ptrap = trap_at(pos());
5482 if (ptrap)
5483 ptrap->trigger(*this);
5484
5485 if (alive())
5486 mons_check_pool(this, pos(), killer, killernum);
5487
5488 if (alive()
5489 && has_ench(ENCH_SUBMERGED)
5490 && !monster_can_submerge(this, env.grid(pos())))
5491 {
5492 del_ench(ENCH_SUBMERGED);
5493 }
5494
5495 terrain_property_t &prop = env.pgrid(pos());
5496
5497 if (prop & FPROP_BLOODY)
5498 {
5499 monster_type genus = mons_genus(type);
5500
5501 if (genus == MONS_JELLY || genus == MONS_ELEPHANT_SLUG)
5502 {
5503 prop &= ~FPROP_BLOODY;
5504 if (you.see_cell(pos()) && !visible_to(&you))
5505 {
5506 string desc =
5507 feature_description_at(pos(), false, DESC_THE);
5508 mprf("The bloodstain on %s disappears!", desc.c_str());
5509 }
5510 }
5511 }
5512 }
5513
self_destruct()5514 void monster::self_destruct()
5515 {
5516 suicide();
5517 monster_die(*as_monster(), KILL_MON, mindex());
5518 }
5519
5520 /** A higher-level moving method than moveto().
5521 *
5522 * @param newpos where to move this monster
5523 * @param clear_net whether to clear any trapping nets
5524 * @param force whether to move it even if you're standing there
5525 * @returns whether the move took place.
5526 */
move_to_pos(const coord_def & newpos,bool clear_net,bool force)5527 bool monster::move_to_pos(const coord_def &newpos, bool clear_net, bool force)
5528 {
5529 const actor* a = actor_at(newpos);
5530 if (a && !(a->is_player() && (fedhas_passthrough(this) || force)))
5531 return false;
5532
5533 const int index = mindex();
5534
5535 // Clear old cell pointer.
5536 if (in_bounds(pos()) && env.mgrid(pos()) == index)
5537 env.mgrid(pos()) = NON_MONSTER;
5538
5539 // Set monster x,y to new value.
5540 moveto(newpos, clear_net);
5541
5542 // Set new monster grid pointer to this monster.
5543 env.mgrid(newpos) = index;
5544
5545 return true;
5546 }
5547
5548 /** Swap positions with another monster.
5549 *
5550 * move_to_pos can't be used in this case, since it can't move something
5551 * to a spot that's occupied. This will abort if either monster can't survive
5552 * in the new place.
5553 *
5554 * We also cannot use moveto, since that calls clear_invalid_constrictions,
5555 * which may cause a more(), causing a render. While monsters are being
5556 * swapped, their positions and the env.mgrid mismatch, so rendering would crash.
5557 *
5558 * @param other the monster to swap with
5559 * @returns whether they ended up moving.
5560 */
swap_with(monster * other)5561 bool monster::swap_with(monster* other)
5562 {
5563 const coord_def old_pos = pos();
5564 const coord_def new_pos = other->pos();
5565
5566 if (!can_pass_through(new_pos)
5567 || !other->can_pass_through(old_pos))
5568 {
5569 return false;
5570 }
5571
5572 if (!monster_habitable_grid(this, env.grid(new_pos))
5573 || !monster_habitable_grid(other, env.grid(old_pos)))
5574 {
5575 return false;
5576 }
5577
5578 mons_clear_trapping_net(this);
5579 mons_clear_trapping_net(other);
5580
5581 // Swap monster positions. Cannot render inside here, since env.mgrid and monster
5582 // positions would mismatch.
5583 env.mgrid(old_pos) = other->mindex();
5584 env.mgrid(new_pos) = mindex();
5585 set_position(new_pos);
5586 other->set_position(old_pos);
5587
5588 // Okay to render again now
5589 clear_invalid_constrictions(true);
5590 other->clear_invalid_constrictions(true);
5591
5592 return true;
5593 }
5594
5595 // Returns true if the trap should be revealed to the player.
do_shaft()5596 bool monster::do_shaft()
5597 {
5598 if (!is_valid_shaft_level())
5599 return false;
5600
5601 // Tentacles are immune to shafting
5602 if (mons_is_tentacle_or_tentacle_segment(type))
5603 return false;
5604
5605 // Handle instances of do_shaft() being invoked magically when
5606 // the monster isn't standing over a shaft.
5607 if (get_trap_type(pos()) != TRAP_SHAFT
5608 && !feat_is_shaftable(env.grid(pos())))
5609 {
5610 return false;
5611 }
5612
5613 level_id lev = shaft_dest();
5614
5615 if (lev == level_id::current())
5616 return false;
5617
5618 // If a pacified monster is leaving the level via a shaft trap, and
5619 // has reached its goal, vaporize it instead of moving it.
5620 // ditto, non-monsters like battlespheres and prisms.
5621 if (!pacified() && !mons_is_conjured(type))
5622 set_transit(lev);
5623
5624 string msg = make_stringf(" %s a shaft!",
5625 !ground_level() ? "is sucked into"
5626 : "falls through");
5627
5628 const bool reveal = simple_monster_message(*this, msg.c_str());
5629
5630 place_cloud(CLOUD_DUST, pos(), 1 + random2(3), this);
5631
5632 // Monster is no longer on this level.
5633 destroy_inventory();
5634 monster_cleanup(this);
5635
5636 return reveal;
5637 }
5638
put_to_sleep(actor *,int,bool hibernate)5639 void monster::put_to_sleep(actor */*attacker*/, int /*strength*/, bool hibernate)
5640 {
5641 const bool valid_target = hibernate ? can_hibernate() : can_sleep();
5642 if (!valid_target)
5643 return;
5644
5645 stop_directly_constricting_all(false);
5646 behaviour = BEH_SLEEP;
5647 flags |= MF_JUST_SLEPT;
5648 if (hibernate)
5649 add_ench(ENCH_SLEEP_WARY);
5650 }
5651
weaken(actor * attacker,int pow)5652 void monster::weaken(actor *attacker, int pow)
5653 {
5654 if (!has_ench(ENCH_WEAK))
5655 simple_monster_message(*this, " looks weaker.");
5656
5657 add_ench(mon_enchant(ENCH_WEAK, 1, attacker,
5658 (pow + random2(pow + 3)) * BASELINE_DELAY));
5659 }
5660
check_awaken(int)5661 void monster::check_awaken(int)
5662 {
5663 // XXX
5664 }
5665
beam_resists(bolt & beam,int hurted,bool doEffects,string)5666 int monster::beam_resists(bolt &beam, int hurted, bool doEffects, string /*source*/)
5667 {
5668 return mons_adjust_flavoured(this, beam, hurted, doEffects);
5669 }
5670
find_monsterentry() const5671 const monsterentry *monster::find_monsterentry() const
5672 {
5673 return (type == MONS_NO_MONSTER || type == MONS_PROGRAM_BUG) ? nullptr
5674 : get_monster_data(type);
5675 }
5676
action_energy(energy_use_type et) const5677 int monster::action_energy(energy_use_type et) const
5678 {
5679 if (!find_monsterentry())
5680 return 10;
5681
5682 const mon_energy_usage &mu = mons_energy(*this);
5683 int move_cost = 0;
5684 switch (et)
5685 {
5686 case EUT_MOVE: move_cost = mu.move; break;
5687 // Amphibious monster speed boni are now dealt with using SWIM_ENERGY,
5688 // rather than here.
5689 case EUT_SWIM: move_cost = mu.swim; break;
5690 case EUT_MISSILE: return mu.missile;
5691 case EUT_ITEM: return mu.item;
5692 case EUT_SPECIAL: return mu.special;
5693 case EUT_SPELL: return mu.spell;
5694 case EUT_ATTACK: return mu.attack;
5695 case EUT_PICKUP: return mu.pickup_percent;
5696 }
5697
5698 if (has_ench(ENCH_SWIFT))
5699 move_cost -= 3;
5700
5701 if (has_ench(ENCH_ROLLING))
5702 move_cost -= 5;
5703
5704 if (wearing_ego(EQ_ALL_ARMOUR, SPARM_PONDEROUSNESS))
5705 move_cost += 1;
5706
5707 // Shadows move more quickly when blended with the darkness.
5708 // Change _monster_stat_description in describe.cc if you change this.
5709 if (type == MONS_SHADOW && invisible())
5710 move_cost -= 3;
5711
5712 // Floundering monsters get the same penalty as the player, except that
5713 // players get the penalty on entering water, while monsters get the
5714 // penalty when leaving it.
5715 if (floundering() || has_ench(ENCH_LIQUEFYING))
5716 move_cost += 6;
5717
5718 // Never reduce the cost to zero
5719 return max(move_cost, 1);
5720 }
5721
lose_energy(energy_use_type et,int div,int mult)5722 void monster::lose_energy(energy_use_type et, int div, int mult)
5723 {
5724 int energy_loss = div_round_up(mult * action_energy(et), div);
5725 if (has_ench(ENCH_PETRIFYING))
5726 {
5727 energy_loss *= 3;
5728 energy_loss /= 2;
5729 }
5730
5731 if ((et == EUT_MOVE || et == EUT_SWIM) && has_ench(ENCH_FROZEN))
5732 energy_loss += 4;
5733
5734 // Randomize movement cost slightly, to make it less predictable,
5735 // and make pillar-dancing not entirely safe.
5736 // No randomization for allies following you to avoid traffic jam
5737 if ((et == EUT_MOVE || et == EUT_SWIM) && (!friendly() || foe != MHITYOU))
5738 energy_loss += random2(3) - 1;
5739
5740 speed_increment -= energy_loss;
5741 }
5742
gain_energy(energy_use_type et,int div,int mult)5743 void monster::gain_energy(energy_use_type et, int div, int mult)
5744 {
5745 int energy_gain = div_round_up(mult * action_energy(et), div);
5746 if (has_ench(ENCH_PETRIFYING))
5747 {
5748 energy_gain *= 2;
5749 energy_gain /= 3;
5750 }
5751
5752 speed_increment += energy_gain;
5753 }
5754
5755 /**
5756 * Can this monster ever drink any potions at all?
5757 *
5758 * @return Whether the monster can drink potions (not a statue, mummy, etc)
5759 */
can_drink() const5760 bool monster::can_drink() const
5761 {
5762 if (mons_class_is_stationary(type))
5763 return false;
5764
5765 if (mons_itemuse(*this) < MONUSE_STARTING_EQUIPMENT)
5766 return false;
5767
5768 // These monsters cannot drink.
5769 if (is_skeletal() || is_insubstantial()
5770 || mons_species() == MONS_LICH || mons_genus(type) == MONS_MUMMY
5771 || mons_species() == MONS_WIGHT || type == MONS_GASTRONOK)
5772 {
5773 return false;
5774 }
5775
5776 return true;
5777 }
5778
can_drink_potion(potion_type ptype) const5779 bool monster::can_drink_potion(potion_type ptype) const
5780 {
5781 if (!can_drink())
5782 return false;
5783
5784 switch (ptype)
5785 {
5786 case POT_CURING:
5787 case POT_HEAL_WOUNDS:
5788 return !(holiness() & (MH_NONLIVING | MH_PLANT));
5789 case POT_BERSERK_RAGE:
5790 return can_go_berserk();
5791 case POT_HASTE:
5792 case POT_MIGHT:
5793 case POT_INVISIBILITY:
5794 case POT_RESISTANCE:
5795 // If there are any item using monsters that are permanently
5796 // invisible, this might have to be restricted.
5797 return true;
5798 default:
5799 break;
5800 CASE_REMOVED_POTIONS(ptype)
5801 }
5802
5803 return false;
5804 }
5805
should_drink_potion(potion_type ptype) const5806 bool monster::should_drink_potion(potion_type ptype) const
5807 {
5808 switch (ptype)
5809 {
5810 case POT_CURING:
5811 return hit_points <= max_hit_points / 2
5812 || has_ench(ENCH_POISON)
5813 || has_ench(ENCH_CONFUSION);
5814 case POT_HEAL_WOUNDS:
5815 return hit_points <= max_hit_points / 2;
5816 case POT_BERSERK_RAGE:
5817 // this implies !berserk()
5818 return !has_ench(ENCH_MIGHT) && !has_ench(ENCH_HASTE)
5819 && needs_berserk();
5820 case POT_HASTE:
5821 return !has_ench(ENCH_HASTE);
5822 case POT_MIGHT:
5823 return !has_ench(ENCH_MIGHT) && foe_distance() <= 2;
5824 case POT_RESISTANCE:
5825 return !has_ench(ENCH_RESISTANCE);
5826 case POT_INVISIBILITY:
5827 // We're being nice: friendlies won't go invisible if the player
5828 // won't be able to see them.
5829 return !has_ench(ENCH_INVIS)
5830 && (you.can_see_invisible(false) || !friendly());
5831 default:
5832 break;
5833 CASE_REMOVED_POTIONS(ptype)
5834 }
5835
5836 return false;
5837 }
5838
5839 // Return true if the potion should be identified.
drink_potion_effect(potion_type pot_eff,bool card)5840 bool monster::drink_potion_effect(potion_type pot_eff, bool card)
5841 {
5842 if (!card)
5843 simple_monster_message(*this, " drinks a potion.");
5844
5845 switch (pot_eff)
5846 {
5847 case POT_CURING:
5848 {
5849 if (heal(5 + random2(7)))
5850 simple_monster_message(*this, " is healed!");
5851
5852 static const enchant_type cured_enchants[] =
5853 {
5854 ENCH_POISON, ENCH_CONFUSION
5855 };
5856
5857 for (enchant_type cured : cured_enchants)
5858 del_ench(cured);
5859 }
5860 break;
5861
5862 case POT_HEAL_WOUNDS:
5863 if (heal(10 + random2avg(28, 3)))
5864 simple_monster_message(*this, " is healed!");
5865 break;
5866
5867 case POT_BERSERK_RAGE:
5868 enchant_actor_with_flavour(this, this, BEAM_BERSERK);
5869 break;
5870
5871 case POT_HASTE:
5872 enchant_actor_with_flavour(this, this, BEAM_HASTE);
5873 break;
5874
5875 case POT_MIGHT:
5876 enchant_actor_with_flavour(this, this, BEAM_MIGHT);
5877 break;
5878
5879 case POT_INVISIBILITY:
5880 enchant_actor_with_flavour(this, this, BEAM_INVISIBILITY);
5881 break;
5882
5883 case POT_RESISTANCE:
5884 enchant_actor_with_flavour(this, this, BEAM_RESISTANCE);
5885 break;
5886
5887 default:
5888 return false;
5889 CASE_REMOVED_POTIONS(pot_eff)
5890 }
5891
5892 return !card;
5893 }
5894
can_evoke_jewellery(jewellery_type) const5895 bool monster::can_evoke_jewellery(jewellery_type /*jtype*/) const
5896 {
5897 return false;
5898 }
5899
should_evoke_jewellery(jewellery_type) const5900 bool monster::should_evoke_jewellery(jewellery_type /*jtype*/) const
5901 {
5902 return false;
5903 }
5904
5905 // Return true if the jewellery should be identified.
evoke_jewellery_effect(jewellery_type)5906 bool monster::evoke_jewellery_effect(jewellery_type /*jtype*/)
5907 {
5908 return false;
5909 }
5910
react_to_damage(const actor * oppressor,int damage,beam_type flavour)5911 void monster::react_to_damage(const actor *oppressor, int damage,
5912 beam_type flavour)
5913 {
5914 // Don't discharge on small amounts of damage (this helps avoid
5915 // continuously shocking when poisoned or sticky flamed)
5916 // XXX: this might not be necessary anymore?
5917 if (type == MONS_SHOCK_SERPENT && damage > 4 && oppressor && oppressor != this)
5918 {
5919 const int pow = div_rand_round(min(damage, hit_points + damage), 9);
5920 if (pow)
5921 {
5922 // we intentionally allow harming the oppressor in this case,
5923 // so need to cast off its constness
5924 shock_serpent_discharge_fineff::schedule(this,
5925 const_cast<actor&>(*oppressor),
5926 pos(), pow);
5927 }
5928 }
5929
5930 // The (real) royal jelly objects to taking damage and will SULK. :-)
5931 if (type == MONS_ROYAL_JELLY && !is_summoned())
5932 trj_spawn_fineff::schedule(oppressor, this, pos(), damage);
5933
5934 // Damage sharing from the spectral weapon to its owner
5935 // The damage shared should not be directly lethal, though like the
5936 // pain spell, it can leave the player at a very dangerous 1hp.
5937 // XXX: This makes a lot of messages, especially when the spectral weapon
5938 // is hit by a monster with multiple attacks and is frozen, burned, etc.
5939 if (type == MONS_SPECTRAL_WEAPON && oppressor)
5940 {
5941 // The owner should not be able to damage itself
5942 // XXX: the mid check here is intended to treat the player's shadow
5943 // mimic as the player itself, i.e. the weapon won't share damage
5944 // the shadow mimic inflicts on it (this causes a crash).
5945 actor *owner = actor_by_mid(summoner);
5946 if (owner && owner != oppressor && oppressor->mid != summoner)
5947 {
5948 int shared_damage = damage / 2;
5949 if (shared_damage > 0)
5950 {
5951 if (owner->is_player())
5952 mpr("Your spectral weapon shares its damage with you!");
5953 else if (owner->alive() && you.can_see(*owner))
5954 {
5955 string buf = " shares ";
5956 buf += owner->pronoun(PRONOUN_POSSESSIVE);
5957 buf += " spectral weapon's damage!";
5958 simple_monster_message(*owner->as_monster(), buf.c_str());
5959 }
5960
5961 // Share damage using a fineff, so that it's non-fatal
5962 // regardless of processing order in an AoE attack.
5963 deferred_damage_fineff::schedule(oppressor, owner,
5964 shared_damage, false, false);
5965 }
5966 }
5967 }
5968 else if (mons_is_tentacle_or_tentacle_segment(type)
5969 && !mons_is_solo_tentacle(type)
5970 && flavour != BEAM_TORMENT_DAMAGE
5971 && monster_by_mid(tentacle_connect)
5972 && monster_by_mid(tentacle_connect)->is_parent_monster_of(this))
5973 {
5974 deferred_damage_fineff::schedule(oppressor,
5975 monster_by_mid(tentacle_connect),
5976 damage, false);
5977 }
5978
5979 if (!alive())
5980 return;
5981
5982 if (!mons_is_tentacle_or_tentacle_segment(type)
5983 && has_ench(ENCH_INNER_FLAME) && oppressor && damage)
5984 {
5985 mon_enchant i_f = get_ench(ENCH_INNER_FLAME);
5986 if (you.see_cell(pos()))
5987 mprf("Flame seeps out of %s.", name(DESC_THE).c_str());
5988 check_place_cloud(CLOUD_FIRE, pos(), 3, actor_by_mid(i_f.source));
5989 }
5990
5991
5992 if (mons_species() == MONS_BUSH
5993 && res_fire() < 0 && flavour == BEAM_FIRE
5994 && damage > 8 && x_chance_in_y(damage, 20))
5995 {
5996 place_cloud(CLOUD_FIRE, pos(), 20 + random2(15), oppressor, 5);
5997 }
5998 else if (type == MONS_SPRIGGAN_RIDER)
5999 {
6000 if (hit_points + damage > max_hit_points / 2)
6001 damage = max_hit_points / 2 - hit_points;
6002 if (damage > 0 && x_chance_in_y(damage, damage + hit_points)
6003 && flavour != BEAM_TORMENT_DAMAGE)
6004 {
6005 bool fly_died = coinflip();
6006 int old_hp = hit_points;
6007 auto old_flags = flags;
6008 mon_enchant_list old_ench = enchantments;
6009 FixedBitVector<NUM_ENCHANTMENTS> old_ench_cache = ench_cache;
6010 int8_t old_ench_countdown = ench_countdown;
6011 string old_name = mname;
6012
6013 if (!fly_died)
6014 monster_drop_things(this, mons_aligned(oppressor, &you));
6015
6016 type = fly_died ? MONS_SPRIGGAN : MONS_HORNET;
6017 define_monster(*this);
6018 hit_points = min(old_hp, hit_points);
6019 flags = old_flags;
6020 enchantments = old_ench;
6021 ench_cache = old_ench_cache;
6022 ench_countdown = old_ench_countdown;
6023 // Keep the rider's name, if it had one (Mercenary card).
6024 if (!old_name.empty())
6025 mname = old_name;
6026
6027 mounted_kill(this, fly_died ? MONS_HORNET : MONS_SPRIGGAN,
6028 !oppressor ? KILL_MISC
6029 : (oppressor->is_player())
6030 ? KILL_YOU : KILL_MON,
6031 (oppressor && oppressor->is_monster())
6032 ? oppressor->mindex() : NON_MONSTER);
6033
6034 // Now clear the name, if the rider just died.
6035 if (!fly_died)
6036 mname.clear();
6037
6038 if (fly_died && !is_habitable(pos()))
6039 {
6040 hit_points = 0;
6041 if (observable())
6042 {
6043 mprf("As %s mount dies, %s plunges down into %s!",
6044 pronoun(PRONOUN_POSSESSIVE).c_str(),
6045 name(DESC_THE).c_str(),
6046 env.grid(pos()) == DNGN_LAVA ?
6047 "lava and is incinerated" :
6048 "deep water and drowns");
6049 }
6050 }
6051 else if (fly_died && observable())
6052 {
6053 mprf("%s falls from %s now dead mount.",
6054 name(DESC_THE).c_str(),
6055 pronoun(PRONOUN_POSSESSIVE).c_str());
6056 }
6057 }
6058 }
6059 else if (type == MONS_STARCURSED_MASS)
6060 starcursed_merge_fineff::schedule(this);
6061 else if (type == MONS_RAKSHASA && !has_ench(ENCH_PHANTOM_MIRROR)
6062 && hit_points < max_hit_points / 2
6063 && hit_points - damage > 0)
6064 {
6065 if (!props.exists("emergency_clone"))
6066 {
6067 rakshasa_clone_fineff::schedule(this, pos());
6068 props["emergency_clone"].get_bool() = true;
6069 }
6070 }
6071
6072 else if (type == MONS_BAI_SUZHEN && hit_points < max_hit_points / 2
6073 && hit_points - damage > 0)
6074 {
6075 int old_hp = hit_points;
6076 auto old_flags = flags;
6077 mon_enchant_list old_ench = enchantments;
6078 FixedBitVector<NUM_ENCHANTMENTS> old_ench_cache = ench_cache;
6079 int8_t old_ench_countdown = ench_countdown;
6080 string old_name = mname;
6081
6082 monster_drop_things(this, mons_aligned(oppressor, &you));
6083
6084 type = MONS_BAI_SUZHEN_DRAGON;
6085 define_monster(*this);
6086 hit_points = min(old_hp, hit_points);
6087 flags = old_flags;
6088 enchantments = old_ench;
6089 ench_cache = old_ench_cache;
6090 ench_countdown = old_ench_countdown;
6091
6092 if (observable())
6093 {
6094 mprf(MSGCH_WARN,
6095 "%s roars in fury and transforms into a fierce dragon!",
6096 name(DESC_THE).c_str());
6097 }
6098 if (caught())
6099 check_net_will_hold_monster(this);
6100 if (this->is_constricted())
6101 this->stop_being_constricted();
6102
6103 add_ench(ENCH_RING_OF_THUNDER);
6104 }
6105 }
6106
reach_range() const6107 reach_type monster::reach_range() const
6108 {
6109 const mon_attack_def attk(mons_attack_spec(*this, 0));
6110 if (flavour_has_reach(attk.flavour) && attk.damage)
6111 return REACH_TWO;
6112
6113 const item_def *wpn = primary_weapon();
6114 if (wpn)
6115 return weapon_reach(*wpn);
6116 return REACH_NONE;
6117 }
6118
steal_item_from_player()6119 void monster::steal_item_from_player()
6120 {
6121 if (confused())
6122 {
6123 string msg = getSpeakString("Maurice confused nonstealing");
6124 if (!msg.empty() && msg != "__NONE")
6125 {
6126 msg = replace_all(msg, "@The_monster@", name(DESC_THE));
6127 mprf(MSGCH_TALK, "%s", msg.c_str());
6128 }
6129 return;
6130 }
6131 // Theft isn't very peaceful. More importantly, you would risk losing the
6132 // item forever when the monster flees the level.
6133 if (pacified())
6134 return;
6135
6136 mon_inv_type mslot = NUM_MONSTER_SLOTS;
6137 int steal_what = -1;
6138 int total_value = 0;
6139 for (int m = 0; m < ENDOFPACK; ++m)
6140 {
6141 if (!you.inv[m].defined())
6142 continue;
6143
6144 // Cannot unequip player.
6145 // TODO: Allow stealing of the wielded weapon?
6146 // Needs to be unwielded properly and should never lead to
6147 // fatal stat loss.
6148 // 1KB: I'd say no, weapon is being held, it's different from pulling
6149 // a wand from your pocket.
6150 if (item_is_equipped(you.inv[m]))
6151 continue;
6152
6153 // Maurice isn't skilled enough to steal stuff you're in the middle of
6154 // using.
6155 for (const /*shared_ptr<Delay>*/auto& delay : you.delay_queue)
6156 if (delay->is_being_used(you.inv[m]))
6157 continue;
6158
6159 mon_inv_type monslot = item_to_mslot(you.inv[m]);
6160 if (monslot == NUM_MONSTER_SLOTS)
6161 continue;
6162
6163 // Only try to steal stuff we can still store somewhere.
6164 if (inv[monslot] != NON_ITEM)
6165 {
6166 if (monslot == MSLOT_WEAPON
6167 && inv[MSLOT_ALT_WEAPON] == NON_ITEM)
6168 {
6169 monslot = MSLOT_ALT_WEAPON;
6170 }
6171 else
6172 continue;
6173 }
6174
6175 // Candidate for stealing.
6176 const int value = item_value(you.inv[m], true);
6177 total_value += value;
6178
6179 if (x_chance_in_y(value, total_value))
6180 {
6181 steal_what = m;
6182 mslot = monslot;
6183 }
6184 }
6185
6186 if (steal_what == -1 || you.gold > 0 && one_chance_in(10))
6187 {
6188 // Found no item worth stealing, try gold.
6189 if (you.gold == 0)
6190 {
6191 if (silenced(pos()))
6192 return;
6193
6194 string complaint = getSpeakString("Maurice nonstealing");
6195 if (!complaint.empty())
6196 {
6197 complaint = replace_all(complaint, "@The_monster@",
6198 name(DESC_THE));
6199 mprf(MSGCH_TALK, "%s", complaint.c_str());
6200 }
6201
6202 bolt beem;
6203 beem.source = pos();
6204 beem.target = pos();
6205 beem.source_id = mid;
6206
6207 // Try to teleport away.
6208 if (no_tele())
6209 return;
6210
6211 if (has_ench(ENCH_TP))
6212 {
6213 mons_cast_noise(this, beem, SPELL_BLINK, MON_SPELL_WIZARD);
6214 // this can kill us, delay the call
6215 blink_fineff::schedule(this);
6216 }
6217 else
6218 mons_cast(this, beem, SPELL_TELEPORT_SELF, MON_SPELL_WIZARD);
6219
6220 return;
6221 }
6222
6223 const int stolen_amount = min(20 + random2(800), you.gold);
6224 if (inv[MSLOT_GOLD] != NON_ITEM)
6225 {
6226 // If Maurice already's got some gold, simply increase the amount.
6227 env.item[inv[MSLOT_GOLD]].quantity += stolen_amount;
6228 // Don't re-tithe stolen gold under Zin.
6229 env.item[inv[MSLOT_GOLD]].tithe_state = (you_worship(GOD_ZIN))
6230 ? TS_NO_TITHE : TS_NO_PIETY;
6231 }
6232 else
6233 {
6234 // Else create a new item for this pile of gold.
6235 const int idx = items(false, OBJ_GOLD, OBJ_RANDOM, 0);
6236 if (idx == NON_ITEM)
6237 return;
6238
6239 item_def &new_item = env.item[idx];
6240 new_item.base_type = OBJ_GOLD;
6241 new_item.sub_type = 0;
6242 // Don't re-tithe stolen gold under Zin.
6243 new_item.tithe_state = (you_worship(GOD_ZIN)) ? TS_NO_TITHE
6244 : TS_NO_PIETY;
6245 new_item.plus2 = 0;
6246 new_item.special = 0;
6247 new_item.flags = 0;
6248 new_item.link = NON_ITEM;
6249 new_item.quantity = stolen_amount;
6250 new_item.pos.reset();
6251 item_colour(new_item);
6252
6253 unlink_item(idx);
6254
6255 inv[MSLOT_GOLD] = idx;
6256 new_item.set_holding_monster(*this);
6257 }
6258 mprf("%s steals %d gold piece%s!",
6259 name(DESC_THE).c_str(),
6260 stolen_amount,
6261 stolen_amount != 1 ? "s" : "");
6262
6263 you.attribute[ATTR_GOLD_FOUND] -= stolen_amount;
6264
6265 you.del_gold(stolen_amount);
6266 mprf("You now have %d gold piece%s.",
6267 you.gold, you.gold != 1 ? "s" : "");
6268
6269 return;
6270 }
6271
6272 ASSERT(steal_what != -1);
6273 ASSERT(mslot != NUM_MONSTER_SLOTS);
6274 ASSERT(inv[mslot] == NON_ITEM);
6275
6276 item_def* tmp = take_item(steal_what, mslot, true);
6277 if (!tmp)
6278 return;
6279 item_def& new_item = *tmp;
6280
6281 // You'll want to autopickup it after killing Maurice.
6282 new_item.flags |= ISFLAG_THROWN;
6283 }
6284
6285 /**
6286 * "Give" a monster an item from the player's inventory.
6287 *
6288 * @param steal_what The slot in your inventory of the item.
6289 * @param mslot Which mon_inv_type to put the item in
6290 *
6291 * @returns new_item the new item, now in the monster's inventory.
6292 */
take_item(int steal_what,mon_inv_type mslot,bool is_stolen)6293 item_def* monster::take_item(int steal_what, mon_inv_type mslot,
6294 bool is_stolen)
6295 {
6296 // Create new item.
6297 int index = get_mitm_slot(10);
6298 if (index == NON_ITEM)
6299 return nullptr;
6300
6301 item_def &new_item = env.item[index];
6302
6303 // Copy item.
6304 new_item = you.inv[steal_what];
6305
6306 // If the item was stolen, randomize quantity
6307 if (is_stolen)
6308 {
6309 const int stolen_amount = 1 + random2(new_item.quantity);
6310 if (stolen_amount < new_item.quantity)
6311 {
6312 mprf("%s steals %d of %s!",
6313 name(DESC_THE).c_str(),
6314 stolen_amount,
6315 new_item.name(DESC_YOUR).c_str());
6316 }
6317 else
6318 {
6319 mprf("%s steals %s!",
6320 name(DESC_THE).c_str(),
6321 new_item.name(DESC_YOUR).c_str());
6322 }
6323 new_item.quantity = stolen_amount;
6324 }
6325
6326 // Drop the item already in the slot (including the shield
6327 // if it's a two-hander).
6328 // TODO: fail conditions here have an awkward ordering with the steal msgs
6329 if ((mslot == MSLOT_WEAPON || mslot == MSLOT_ALT_WEAPON)
6330 && inv[MSLOT_SHIELD] != NON_ITEM
6331 && hands_reqd(new_item) == HANDS_TWO
6332 && !drop_item(MSLOT_SHIELD, observable()))
6333 {
6334 return nullptr;
6335 }
6336 if (inv[mslot] != NON_ITEM && !drop_item(mslot, observable()))
6337 return nullptr;
6338
6339 // Set the item as unlinked.
6340 new_item.pos.reset();
6341 new_item.link = NON_ITEM;
6342 unlink_item(index);
6343 inv[mslot] = index;
6344 new_item.set_holding_monster(*this);
6345
6346 if (mslot != MSLOT_ALT_WEAPON || mons_wields_two_weapons(*this))
6347 equip_message(new_item);
6348
6349 // Item is gone from player's inventory.
6350 dec_inv_item_quantity(steal_what, new_item.quantity);
6351
6352 return &new_item;
6353 }
6354
6355 /** Disarm this monster, and preferably pull the weapon into your tile.
6356 *
6357 * @returns a pointer to the weapon disarmed, or nullptr if unsuccessful.
6358 */
disarm()6359 item_def* monster::disarm()
6360 {
6361 item_def *mons_wpn = mslot_item(MSLOT_WEAPON);
6362
6363 // is it ok to move the weapon into your tile (w/o destroying it?)
6364 const bool your_tile_ok = !feat_eliminates_items(env.grid(you.pos()));
6365
6366 // It's ok to drop the weapon into deep water if it comes out right away,
6367 // but if the monster is on lava we just have to abort.
6368 const bool mon_tile_ok = !feat_destroys_items(env.grid(pos()))
6369 && (your_tile_ok
6370 || !feat_eliminates_items(env.grid(pos())));
6371
6372 if (!mons_wpn
6373 || mons_wpn->cursed()
6374 || mons_class_is_animated_object(type)
6375 || !adjacent(you.pos(), pos())
6376 || !you.can_see(*this)
6377 || !mon_tile_ok
6378 || mons_wpn->flags & ISFLAG_SUMMONED)
6379 {
6380 return nullptr;
6381 }
6382
6383 drop_item(MSLOT_WEAPON, false);
6384
6385 // XXX: assumes nothing's re-ordering items - e.g. gozag gold
6386 if (your_tile_ok)
6387 move_top_item(pos(), you.pos());
6388
6389 if (type == MONS_CEREBOV)
6390 you.props[CEREBOV_DISARMED_KEY] = true;
6391
6392 return mons_wpn;
6393 }
6394
6395 /**
6396 * Checks if the monster can pass through webs freely.
6397 *
6398 * Currently: spiders (including Arachne), moths, demonic crawlers,
6399 * ghosts & other incorporeal monsters, and jelly monsters.
6400 *
6401 * @return Whether the monster is immune to webs.
6402 */
is_web_immune() const6403 bool monster::is_web_immune() const
6404 {
6405 return mons_genus(type) == MONS_SPIDER
6406 || type == MONS_ARACHNE
6407 || mons_genus(type) == MONS_MOTH
6408 || mons_genus(type) == MONS_DEMONIC_CRAWLER
6409 || is_insubstantial()
6410 || mons_genus(type) == MONS_JELLY;
6411 }
6412
6413 // Followers of Yredelemnul and Dithmenos don't have their accuracy
6414 // reduced by umbra.
nightvision() const6415 bool monster::nightvision() const
6416 {
6417 return god == GOD_YREDELEMNUL
6418 || god == GOD_DITHMENOS;
6419 }
6420
attempt_escape(int attempts)6421 bool monster::attempt_escape(int attempts)
6422 {
6423 int attfactor;
6424 int randfact;
6425
6426 if (!is_constricted())
6427 return true;
6428
6429 escape_attempts += attempts;
6430 attfactor = 3 * escape_attempts;
6431
6432 if (constricted_by == MID_PLAYER)
6433 {
6434 if (has_ench(ENCH_VILE_CLUTCH))
6435 {
6436 randfact = roll_dice(1, 10 + div_rand_round(
6437 calc_spell_power(SPELL_BORGNJORS_VILE_CLUTCH, true), 5));
6438 }
6439 else
6440 randfact = roll_dice(1, 3 + you.experience_level);
6441 }
6442 else
6443 {
6444 const monster* themonst = monster_by_mid(constricted_by);
6445 ASSERT(themonst);
6446
6447 // Monsters use the same escape formula for all forms of constriction.
6448 randfact = 5 + roll_dice(1, 5)
6449 + roll_dice(1, themonst->get_hit_dice());
6450 }
6451
6452 if (attfactor > randfact)
6453 {
6454 stop_being_constricted(true);
6455 return true;
6456 }
6457 else
6458 return false;
6459 }
6460
6461 /**
6462 * Does the monster have a free tentacle to constrict something?
6463 * Currently only used by octopode monsters.
6464 * @return True if it can constrict an additional monster, false otherwise.
6465 */
has_usable_tentacle() const6466 bool monster::has_usable_tentacle() const
6467 {
6468 if (mons_genus(type) != MONS_OCTOPODE)
6469 return false;
6470
6471 // ignoring monster octopodes with weapons, for now
6472 return num_constricting() < 8;
6473 }
6474
6475 // Move the monster to the nearest valid space.
shove(const char * feat_name)6476 bool monster::shove(const char* feat_name)
6477 {
6478 for (distance_iterator di(pos()); di; ++di)
6479 if (monster_space_valid(this, *di, false))
6480 {
6481 move_to_pos(*di);
6482 simple_monster_message(*this,
6483 make_stringf(" is pushed out of the %s.", feat_name).c_str());
6484 dprf("Moved to (%d, %d).", pos().x, pos().y);
6485
6486 return true;
6487 }
6488
6489 return false;
6490 }
6491
id_if_worn(mon_inv_type mslot,object_class_type base_type,int sub_type) const6492 void monster::id_if_worn(mon_inv_type mslot, object_class_type base_type,
6493 int sub_type) const
6494 {
6495 item_def *item = mslot_item(mslot);
6496
6497 if (item && item->is_type(base_type, sub_type))
6498 set_ident_type(*item, true);
6499 }
6500
stasis() const6501 bool monster::stasis() const
6502 {
6503 return mons_genus(type) == MONS_FORMICID
6504 || type == MONS_PLAYER_GHOST && ghost->species == SP_FORMICID;
6505 }
6506
cloud_immune(bool calc_unid,bool items) const6507 bool monster::cloud_immune(bool calc_unid, bool items) const
6508 {
6509 // Cloud Mage is also checked for in (so stay in sync with)
6510 // monster_info::monster_info(monster_type, monster_type).
6511 return type == MONS_CLOUD_MAGE || actor::cloud_immune(calc_unid, items);
6512 }
6513
is_illusion() const6514 bool monster::is_illusion() const
6515 {
6516 return type == MONS_PLAYER_ILLUSION
6517 || has_ench(ENCH_PHANTOM_MIRROR)
6518 || props.exists(CLONE_SLAVE_KEY);
6519 }
6520
is_divine_companion() const6521 bool monster::is_divine_companion() const
6522 {
6523 return attitude == ATT_FRIENDLY
6524 && !is_summoned()
6525 && (mons_is_god_gift(*this, GOD_BEOGH)
6526 || mons_is_god_gift(*this, GOD_YREDELEMNUL)
6527 || mons_is_god_gift(*this, GOD_HEPLIAKLQANA))
6528 && mons_can_use_stairs(*this);
6529 }
6530
is_dragonkind() const6531 bool monster::is_dragonkind() const
6532 {
6533 if (actor::is_dragonkind())
6534 return true;
6535
6536 if (mons_is_zombified(*this) && mons_class_is_draconic(base_monster))
6537 return true;
6538
6539 if (mons_is_ghost_demon(type) && species::is_draconian(ghost->species))
6540 return true;
6541
6542 return false;
6543 }
6544
dragon_level() const6545 int monster::dragon_level() const
6546 {
6547 if (is_summoned() || testbits(flags, MF_NO_REWARD))
6548 return 0;
6549 return actor::dragon_level();
6550 }
6551
6552 /// Is this monster's Blink ability themed as a 'jump'?
is_jumpy() const6553 bool monster::is_jumpy() const
6554 {
6555 return type == MONS_JUMPING_SPIDER || type == MONS_BOULDER_BEETLE;
6556 }
6557
6558 // HD for spellcasting purposes.
6559 // Currently only used for Aura of Brilliance and Hep ancestors.
spell_hd(spell_type spell) const6560 int monster::spell_hd(spell_type spell) const
6561 {
6562 UNUSED(spell);
6563 int hd = get_hit_dice();
6564 if (mons_is_hepliaklqana_ancestor(type))
6565 hd = max(1, hd * 2 / 3);
6566 if (has_ench(ENCH_IDEALISED))
6567 hd *= 2;
6568 if (has_ench(ENCH_EMPOWERED_SPELLS))
6569 hd += 5;
6570 return hd;
6571 }
6572
6573 /**
6574 * Remove this monsters summon's. Any monsters summoned by this monster will be
6575 * abjured and any spectral weapon or battlesphere avatars they have will be
6576 * ended.
6577 *
6578 * @param check_attitude If true, only remove summons/avatars whose attitude
6579 * differs from the the monster.
6580 */
remove_summons(bool check_attitude)6581 void monster::remove_summons(bool check_attitude)
6582 {
6583 monster* avatar = find_spectral_weapon(this);
6584 if (avatar && (!check_attitude || attitude != avatar->attitude))
6585 end_spectral_weapon(avatar, false, false);
6586
6587 avatar = find_battlesphere(this);
6588 if (avatar && (!check_attitude || attitude != avatar->attitude))
6589 end_battlesphere(avatar, false);
6590
6591 for (monster_iterator mi; mi; ++mi)
6592 {
6593 int sumtype = 0;
6594
6595 if ((!check_attitude || attitude != mi->attitude)
6596 && mi->summoner == mid
6597 && (mi->is_summoned(nullptr, &sumtype)
6598 || sumtype == MON_SUMM_CLONE))
6599 {
6600 mi->del_ench(ENCH_ABJ);
6601 }
6602 }
6603 }
6604
6605 /**
6606 * Does this monster have the given mutant beast facet?
6607 *
6608 * @param facet The beast_facet in question; e.g. BF_BAT.
6609 * @return Whether the given facet is one this monster has.
6610 */
has_facet(int facet) const6611 bool monster::has_facet(int facet) const
6612 {
6613 if (!props.exists(MUTANT_BEAST_FACETS))
6614 return false;
6615
6616 for (auto facet_val : props[MUTANT_BEAST_FACETS].get_vector())
6617 if (facet_val.get_int() == facet)
6618 return true;
6619 return false;
6620 }
6621
6622 /// If the player attacks this monster, will it become hostile?
angered_by_attacks() const6623 bool monster::angered_by_attacks() const
6624 {
6625 return !has_ench(ENCH_INSANE)
6626 && !mons_is_avatar(type)
6627 && type != MONS_SPELLFORGED_SERVITOR
6628 && !mons_is_conjured(type)
6629 && !testbits(flags, MF_DEMONIC_GUARDIAN)
6630 // allied fed plants, hep ancestor:
6631 && !god_protects(this);
6632 }
6633