1 /**
2 * \file mon-attack.c
3 * \brief Monster attacks
4 *
5 * Monster ranged attacks - choosing an attack spell or shot and making it.
6 * Monster melee attacks - monster critical blows, whether a monster
7 * attack hits, what happens when a monster attacks an adjacent player.
8 *
9 * Copyright (c) 1997 Ben Harrison, David Reeve Sward, Keldon Jones.
10 *
11 * This work is free software; you can redistribute it and/or modify it
12 * under the terms of either:
13 *
14 * a) the GNU General Public License as published by the Free Software
15 * Foundation, version 2, or
16 *
17 * b) the "Angband licence":
18 * This software may be copied and distributed for educational, research,
19 * and not for profit purposes provided that this copyright and statement
20 * are included in all such copies. Other copyrights may also apply.
21 */
22
23 #include "angband.h"
24 #include "cave.h"
25 #include "effects.h"
26 #include "init.h"
27 #include "mon-attack.h"
28 #include "mon-blows.h"
29 #include "mon-desc.h"
30 #include "mon-lore.h"
31 #include "mon-predicate.h"
32 #include "mon-spell.h"
33 #include "mon-timed.h"
34 #include "mon-util.h"
35 #include "obj-knowledge.h"
36 #include "player-attack.h"
37 #include "player-timed.h"
38 #include "player-util.h"
39 #include "project.h"
40
41 /**
42 * This file deals with monster attacks (including spells) as follows:
43 *
44 * Give monsters more intelligent attack/spell selection based on
45 * observations of previous attacks on the player, and/or by allowing
46 * the monster to "cheat" and know the player status.
47 *
48 * Maintain an idea of the player status, and use that information
49 * to occasionally eliminate "ineffective" spell attacks. We could
50 * also eliminate ineffective normal attacks, but there is no reason
51 * for the monster to do this, since he gains no benefit.
52 * Note that MINDLESS monsters are not allowed to use this code.
53 * And non-INTELLIGENT monsters only use it partially effectively.
54 *
55 * Actually learn what the player resists, and use that information
56 * to remove attacks or spells before using them.
57 */
58
59 /**
60 * Given the monster, *mon, and cave *c, set *dist to the distance to the
61 * monster's target and *grid to the target's location. Accounts for a player
62 * decoy, if present. Either dist or grid may be NULL if that value is not
63 * needed.
64 */
monster_get_target_dist_grid(struct monster * mon,struct chunk * c,int * dist,struct loc * grid)65 static void monster_get_target_dist_grid(struct monster *mon, struct chunk *c,
66 int *dist, struct loc *grid)
67 {
68 struct loc decoy = cave_find_decoy(c);
69
70 if (loc_is_zero(decoy)) {
71 if (dist) {
72 *dist = mon->cdis;
73 }
74 if (grid) {
75 *grid = player->grid;
76 }
77 } else {
78 if (dist) {
79 *dist = distance(mon->grid, decoy);
80 }
81 if (grid) {
82 *grid = decoy;
83 }
84 }
85 }
86
87 /**
88 * Check if a monster has a chance of casting a spell this turn
89 */
monster_can_cast(struct monster * mon,bool innate)90 static bool monster_can_cast(struct monster *mon, bool innate)
91 {
92 int chance = innate ? mon->race->freq_innate : mon->race->freq_spell;
93 int tdist;
94 struct loc tgrid;
95
96 monster_get_target_dist_grid(mon, cave, &tdist, &tgrid);
97
98 /* Cannot cast spells when nice */
99 if (mflag_has(mon->mflag, MFLAG_NICE)) return false;
100
101 /* Not allowed to cast spells */
102 if (!chance) return false;
103
104 /* Taunted monsters are likely just to attack */
105 if (player->timed[TMD_TAUNT]) {
106 chance /= 2;
107 }
108
109 /* Monsters at their preferred range are more likely to cast */
110 if (tdist == mon->best_range) {
111 chance *= 2;
112 }
113
114 /* Only do spells occasionally */
115 if (randint0(100) >= chance) return false;
116
117 /* Check range */
118 if (tdist > z_info->max_range) return false;
119
120 /* Check path */
121 if (!projectable(cave, mon->grid, tgrid, PROJECT_SHORT))
122 return false;
123
124 /* If the target isn't the player, only cast if the player can witness */
125 if ((tgrid.x != player->grid.x || tgrid.y != player->grid.y) &&
126 !square_isview(cave, mon->grid) &&
127 !square_isview(cave, tgrid)) {
128 struct loc *path = mem_alloc(z_info->max_range * sizeof(*path));
129 int npath, ipath;
130
131 npath = project_path(path, z_info->max_range, mon->grid, tgrid,
132 PROJECT_SHORT);
133 ipath = 0;
134 while (1) {
135 if (ipath >= npath) {
136 /* No point on path visible. Don't cast. */
137 mem_free(path);
138 return false;
139 }
140 if (square_isview(cave, path[ipath])) {
141 break;
142 }
143 ++ipath;
144 }
145 mem_free(path);
146 }
147
148 return true;
149 }
150
151 /**
152 * Remove the "bad" spells from a spell list
153 */
remove_bad_spells(struct monster * mon,bitflag f[RSF_SIZE])154 static void remove_bad_spells(struct monster *mon, bitflag f[RSF_SIZE])
155 {
156 bitflag f2[RSF_SIZE];
157 int tdist;
158
159 monster_get_target_dist_grid(mon, cave, &tdist, NULL);
160
161 /* Take working copy of spell flags */
162 rsf_copy(f2, f);
163
164 /* Don't heal if full */
165 if (mon->hp >= mon->maxhp) {
166 rsf_off(f2, RSF_HEAL);
167 }
168
169 /* Don't heal others if no injuries */
170 if (rsf_has(f2, RSF_HEAL_KIN) && !find_any_nearby_injured_kin(cave, mon)) {
171 rsf_off(f2, RSF_HEAL_KIN);
172 }
173
174 /* Don't haste if hasted with time remaining */
175 if (mon->m_timed[MON_TMD_FAST] > 10) {
176 rsf_off(f2, RSF_HASTE);
177 }
178
179 /* Don't teleport to if the player is already next to us */
180 if (tdist == 1) {
181 rsf_off(f2, RSF_TELE_TO);
182 rsf_off(f2, RSF_TELE_SELF_TO);
183 }
184
185 /* Don't use the lash effect if the player is too far away */
186 if (tdist > 2) {
187 rsf_off(f2, RSF_WHIP);
188 }
189 if (tdist > 3) {
190 rsf_off(f2, RSF_SPIT);
191 }
192
193 /* Update acquired knowledge */
194 if (OPT(player, birth_ai_learn)) {
195 size_t i;
196 bitflag ai_flags[OF_SIZE], ai_pflags[PF_SIZE];
197 struct element_info el[ELEM_MAX];
198 bool know_something = false;
199
200 /* Occasionally forget player status */
201 if (one_in_(20)) {
202 of_wipe(mon->known_pstate.flags);
203 pf_wipe(mon->known_pstate.pflags);
204 for (i = 0; i < ELEM_MAX; i++)
205 mon->known_pstate.el_info[i].res_level = 0;
206 }
207
208 /* Use the memorized info */
209 of_wipe(ai_flags);
210 pf_wipe(ai_pflags);
211 of_copy(ai_flags, mon->known_pstate.flags);
212 pf_copy(ai_pflags, mon->known_pstate.pflags);
213 if (!of_is_empty(ai_flags) || !pf_is_empty(ai_pflags)) {
214 know_something = true;
215 }
216
217 for (i = 0; i < ELEM_MAX; i++) {
218 el[i].res_level = mon->known_pstate.el_info[i].res_level;
219 if (el[i].res_level != 0) {
220 know_something = true;
221 }
222 }
223
224 /* Cancel out certain flags based on knowledge */
225 if (know_something) {
226 unset_spells(f2, ai_flags, ai_pflags, el, mon);
227 }
228 }
229
230 /* Use working copy of spell flags */
231 rsf_copy(f, f2);
232 }
233
234
235 /**
236 * Determine if there is a space near the selected spot in which
237 * a summoned creature can appear
238 */
summon_possible(struct loc grid)239 static bool summon_possible(struct loc grid)
240 {
241 int y, x;
242
243 /* No summons in arenas */
244 if (player->upkeep->arena_level) return false;
245
246 /* Start at the location, and check 2 grids in each dir */
247 for (y = grid.y - 2; y <= grid.y + 2; y++) {
248 for (x = grid.x - 2; x <= grid.x + 2; x++) {
249 struct loc near = loc(x, y);
250
251 /* Ignore illegal locations */
252 if (!square_in_bounds(cave, near)) continue;
253
254 /* Only check a circular area */
255 if (distance(grid, near) > 2) continue;
256
257 /* Hack: no summon on glyph of warding */
258 if (square_iswarded(cave, near)) continue;
259
260 /* If it's empty floor grid in line of sight, we're good */
261 if (square_isempty(cave, near) && los(cave, grid, near))
262 return (true);
263 }
264 }
265
266 return false;
267 }
268
269
270 /**
271 * Have a monster choose a spell to cast.
272 *
273 * Note that the monster's spell list has already had "useless" spells
274 * (bolts that won't hit the player, summons without room, etc.) removed.
275 * Perhaps that should be done by this function.
276 *
277 * Stupid monsters will just pick a spell randomly. Smart monsters
278 * will choose more "intelligently".
279 *
280 * This function could be an efficiency bottleneck.
281 */
choose_attack_spell(bitflag * f,bool innate,bool non_innate)282 int choose_attack_spell(bitflag *f, bool innate, bool non_innate)
283 {
284 int num = 0;
285 byte spells[RSF_MAX];
286
287 int i;
288
289 /* Paranoid initialization */
290 for (i = 0; i < RSF_MAX; i++) {
291 spells[i] = 0;
292 }
293
294 /* Extract spells, filtering as necessary */
295 for (i = FLAG_START, num = 0; i < RSF_MAX; i++) {
296 if (!innate && mon_spell_is_innate(i)) continue;
297 if (!non_innate && !mon_spell_is_innate(i)) continue;
298 if (rsf_has(f, i)) spells[num++] = i;
299 }
300
301 /* Pick at random */
302 return (spells[randint0(num)]);
303 }
304
305 /**
306 * Failure rate of a monster's spell, based on spell power and current status
307 */
monster_spell_failrate(struct monster * mon)308 static int monster_spell_failrate(struct monster *mon)
309 {
310 int power = MIN(mon->race->spell_power, 1);
311 int failrate = 0;
312
313 /* Stupid monsters will never fail (for jellies and such) */
314 if (!monster_is_stupid(mon)) {
315 /* Base failrate */
316 failrate = 25 - (power + 3) / 4;
317
318 /* Fear adds 20% */
319 if (mon->m_timed[MON_TMD_FEAR])
320 failrate += 20;
321
322 /* Confusion and diesnchantment add 50% */
323 if (mon->m_timed[MON_TMD_CONF] || mon->m_timed[MON_TMD_DISEN])
324 failrate += 50;
325 }
326
327 return failrate;
328 }
329
330 /**
331 * Creatures can cast spells, shoot missiles, and breathe.
332 *
333 * Returns "true" if a spell (or whatever) was (successfully) cast.
334 *
335 * Perhaps monsters should breathe at locations *near* the player,
336 * since this would allow them to inflict "partial" damage.
337 *
338 * It will not be possible to "correctly" handle the case in which a
339 * monster attempts to attack a location which is thought to contain
340 * the player, but which in fact is nowhere near the player, since this
341 * might induce all sorts of messages about the attack itself, and about
342 * the effects of the attack, which the player might or might not be in
343 * a position to observe. Thus, for simplicity, it is probably best to
344 * only allow "faulty" attacks by a monster if one of the important grids
345 * (probably the initial or final grid) is in fact in view of the player.
346 * It may be necessary to actually prevent spell attacks except when the
347 * monster actually has line of sight to the player. Note that a monster
348 * could be left in a bizarre situation after the player ducked behind a
349 * pillar and then teleported away, for example.
350 *
351 * Note that this function attempts to optimize the use of spells for the
352 * cases in which the monster has no spells, or has spells but cannot use
353 * them, or has spells but they will have no "useful" effect. Note that
354 * this function has been an efficiency bottleneck in the past.
355 *
356 * Note the special "MFLAG_NICE" flag, which prevents a monster from using
357 * any spell attacks until the player has had a single chance to move.
358 *
359 * Note the interaction between innate attacks and non-innate attacks (true
360 * spells). Because the check for spells is done first, actual innate attack
361 * frequencies are affected by the spell frequency.
362 */
make_ranged_attack(struct monster * mon)363 bool make_ranged_attack(struct monster *mon)
364 {
365 struct monster_lore *lore = get_lore(mon->race);
366 int thrown_spell, failrate;
367 bitflag f[RSF_SIZE];
368 char m_name[80];
369 bool seen = (player->timed[TMD_BLIND] == 0) && monster_is_visible(mon);
370 bool innate = false;
371
372 /* Check for cast this turn, non-innate and then innate */
373 if (!monster_can_cast(mon, false)) {
374 if (!monster_can_cast(mon, true)) {
375 return false;
376 } else {
377 /* We're casting an innate "spell" */
378 innate = true;
379 }
380 }
381
382 /* Extract the racial spell flags */
383 rsf_copy(f, mon->race->spell_flags);
384
385 /* Smart monsters can use "desperate" spells */
386 if (monster_is_smart(mon) && mon->hp < mon->maxhp / 10 && one_in_(2)) {
387 ignore_spells(f, RST_DAMAGE);
388 }
389
390 /* Non-stupid monsters do some filtering */
391 if (!monster_is_stupid(mon)) {
392 struct loc tgrid;
393
394 /* Remove the "ineffective" spells */
395 remove_bad_spells(mon, f);
396
397 /* Check for a clean bolt shot */
398 monster_get_target_dist_grid(mon, cave, NULL, &tgrid);
399 if (test_spells(f, RST_BOLT) &&
400 !projectable(cave, mon->grid, tgrid, PROJECT_STOP)) {
401 ignore_spells(f, RST_BOLT);
402 }
403
404 /* Check for a possible summon */
405 if (!summon_possible(mon->grid)) {
406 ignore_spells(f, RST_SUMMON);
407 }
408 }
409
410 /* No spells left */
411 if (rsf_is_empty(f)) return false;
412
413 /* Choose a spell to cast */
414 thrown_spell = choose_attack_spell(f, innate, !innate);
415
416 /* Abort if no spell was chosen */
417 if (!thrown_spell) return false;
418
419 /* There will be at least an attempt now, so get the monster's name */
420 monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);
421
422 /* If we see a hidden monster try to cast a spell, become aware of it */
423 if (monster_is_camouflaged(mon))
424 become_aware(mon);
425
426 /* Check for spell failure (innate attacks never fail) */
427 failrate = monster_spell_failrate(mon);
428 if (!mon_spell_is_innate(thrown_spell) && (randint0(100) < failrate)) {
429 msg("%s tries to cast a spell, but fails.", m_name);
430 return true;
431 }
432
433 /* Cast the spell. */
434 disturb(player);
435 do_mon_spell(thrown_spell, mon, seen);
436
437 /* Remember what the monster did */
438 if (seen) {
439 rsf_on(lore->spell_flags, thrown_spell);
440 if (mon_spell_is_innate(thrown_spell)) {
441 /* Innate spell */
442 if (lore->cast_innate < UCHAR_MAX)
443 lore->cast_innate++;
444 } else {
445 /* Bolt or Ball, or Special spell */
446 if (lore->cast_spell < UCHAR_MAX)
447 lore->cast_spell++;
448 }
449 }
450 if (player->is_dead && (lore->deaths < SHRT_MAX)) {
451 lore->deaths++;
452 }
453 lore_update(mon->race, lore);
454
455 /* A spell was cast */
456 return true;
457 }
458
459
460
461 /**
462 * Critical blow. All hits that do 95% of total possible damage,
463 * and which also do at least 20 damage, or, sometimes, N damage.
464 * This is used only to determine "cuts" and "stuns".
465 */
monster_critical(random_value dice,int rlev,int dam)466 static int monster_critical(random_value dice, int rlev, int dam)
467 {
468 int max = 0;
469 int total = randcalc(dice, rlev, MAXIMISE);
470
471 /* Must do at least 95% of perfect */
472 if (dam < total * 19 / 20) return (0);
473
474 /* Weak blows rarely work */
475 if ((dam < 20) && (randint0(100) >= dam)) return (0);
476
477 /* Perfect damage */
478 if (dam == total) max++;
479
480 /* Super-charge */
481 if (dam >= 20)
482 while (randint0(100) < 2) max++;
483
484 /* Critical damage */
485 if (dam > 45) return (6 + max);
486 if (dam > 33) return (5 + max);
487 if (dam > 25) return (4 + max);
488 if (dam > 18) return (3 + max);
489 if (dam > 11) return (2 + max);
490 return (1 + max);
491 }
492
493 /**
494 * Determine if a monster attack against the player succeeds.
495 */
check_hit(struct player * p,int power,int level,int accuracy)496 bool check_hit(struct player *p, int power, int level, int accuracy)
497 {
498 int chance, ac;
499
500 /* Calculate the "attack quality" */
501 chance = (power + (level * 3));
502
503 /* Total armor */
504 ac = p->state.ac + p->state.to_a;
505
506 /* If the monster checks vs ac, the player learns ac bonuses */
507 equip_learn_on_defend(p);
508
509 /* Apply accuracy */
510 chance *= accuracy;
511 chance /= 100;
512
513 /* Check if the player was hit */
514 return test_hit(chance, ac, true);
515 }
516
517 /**
518 * Determine if a monster attack against a monster succeeds.
519 */
check_hit_monster(struct monster * mon,int power,int level,int accuracy)520 bool check_hit_monster(struct monster *mon, int power, int level, int accuracy)
521 {
522 int chance, ac;
523
524 /* Calculate the "attack quality" */
525 chance = (power + (level * 3));
526
527 /* Total armor */
528 ac = mon->race->ac;
529
530 /* Apply accuracy */
531 chance *= accuracy;
532 chance /= 100;
533
534 /* Check if the monster was hit */
535 return test_hit(chance, ac, true);
536 }
537
538 /**
539 * Calculate how much damage remains after armor is taken into account
540 * (does for a physical attack what adjust_dam does for an elemental attack).
541 */
adjust_dam_armor(int damage,int ac)542 int adjust_dam_armor(int damage, int ac)
543 {
544 return damage - (damage * ((ac < 240) ? ac : 240) / 400);
545 }
546
547 /**
548 * Attack the player via physical attacks.
549 */
make_attack_normal(struct monster * mon,struct player * p)550 bool make_attack_normal(struct monster *mon, struct player *p)
551 {
552 struct monster_lore *lore = get_lore(mon->race);
553 int rlev = ((mon->race->level >= 1) ? mon->race->level : 1);
554 int ap_cnt;
555 char m_name[80];
556 char ddesc[80];
557 bool blinked = false;
558 int accuracy = 100 - (mon->m_timed[MON_TMD_STUN] ? STUN_HIT_REDUCTION : 0);
559
560 /* Not allowed to attack */
561 if (rf_has(mon->race->flags, RF_NEVER_BLOW)) return (false);
562
563 /* Get the monster name (or "it") */
564 monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);
565
566 /* Get the "died from" information (i.e. "a kobold") */
567 monster_desc(ddesc, sizeof(ddesc), mon, MDESC_SHOW | MDESC_IND_VIS);
568
569 /* Scan through all blows */
570 for (ap_cnt = 0; ap_cnt < z_info->mon_blows_max; ap_cnt++) {
571 struct loc pgrid = p->grid;
572 bool visible = monster_is_visible(mon) || (mon->race->light > 0);
573 bool obvious = false;
574
575 int damage = 0;
576 bool do_cut = false;
577 bool do_stun = false;
578 int sound_msg = MSG_GENERIC;
579
580 char *act = NULL;
581
582 /* Extract the attack infomation */
583 struct blow_effect *effect = mon->race->blow[ap_cnt].effect;
584 struct blow_method *method = mon->race->blow[ap_cnt].method;
585 random_value dice = mon->race->blow[ap_cnt].dice;
586
587 /* No more attacks */
588 if (!method) break;
589
590 /* Handle "leaving" */
591 if (p->is_dead || p->upkeep->generate_level) break;
592
593 /* Monster hits player */
594 assert(effect);
595 if (streq(effect->name, "NONE") ||
596 check_hit(p, effect->power, rlev, accuracy)) {
597 melee_effect_handler_f effect_handler;
598
599 /* Always disturbing */
600 disturb(p);
601
602 /* Hack -- Apply "protection from evil" */
603 if (p->timed[TMD_PROTEVIL] > 0) {
604 /* Learn about the evil flag */
605 if (monster_is_visible(mon))
606 rf_on(lore->flags, RF_EVIL);
607
608 if (monster_is_evil(mon) && p->lev >= rlev &&
609 randint0(100) + p->lev > 50) {
610 /* Message */
611 msg("%s is repelled.", m_name);
612
613 /* Hack -- Next attack */
614 continue;
615 }
616 }
617
618 /* Describe the attack method */
619 act = monster_blow_method_action(method, -1);
620 do_cut = method->cut;
621 do_stun = method->stun;
622 sound_msg = method->msgt;
623
624 /* Hack -- assume all attacks are obvious */
625 obvious = true;
626
627 /* Roll dice */
628 damage = randcalc(dice, rlev, RANDOMISE);
629
630 /* Reduce damage when stunned */
631 if (mon->m_timed[MON_TMD_STUN]) {
632 damage = (damage * (100 - STUN_DAM_REDUCTION)) / 100;
633 }
634
635 /* Message */
636 if (act) {
637 const char *fullstop = ".";
638 if (suffix(act, "'") || suffix(act, "!")) {
639 fullstop = "";
640 }
641
642 if (OPT(p, show_damage)) {
643 msgt(sound_msg, "%s %s (%d)%s", m_name, act, damage,
644 fullstop);
645 } else {
646 msgt(sound_msg, "%s %s%s", m_name, act, fullstop);
647 }
648 }
649
650 /* Perform the actual effect. */
651 effect_handler = melee_handler_for_blow_effect(effect->name);
652 if (effect_handler != NULL) {
653 melee_effect_handler_context_t context = {
654 p,
655 mon,
656 NULL,
657 rlev,
658 method,
659 p->state.ac + p->state.to_a,
660 ddesc,
661 obvious,
662 blinked,
663 damage,
664 };
665
666 effect_handler(&context);
667
668 /* Save any changes made in the handler for later use. */
669 obvious = context.obvious;
670 blinked = context.blinked;
671 damage = context.damage;
672 } else {
673 msg("ERROR: Effect handler not found for %s.", effect->name);
674 }
675
676 /* Don't cut or stun if player is dead */
677 if (p->is_dead) {
678 do_cut = false;
679 do_stun = false;
680 }
681
682 /* Hack -- only one of cut or stun */
683 if (do_cut && do_stun) {
684 /* Cancel cut */
685 if (randint0(100) < 50)
686 do_cut = false;
687
688 /* Cancel stun */
689 else
690 do_stun = false;
691 }
692
693 /* Handle cut */
694 if (do_cut) {
695 /* Critical hit (zero if non-critical) */
696 int amt, tmp = monster_critical(dice, rlev, damage);
697
698 /* Roll for damage */
699 switch (tmp) {
700 case 0: amt = 0; break;
701 case 1: amt = randint1(5); break;
702 case 2: amt = randint1(5) + 5; break;
703 case 3: amt = randint1(20) + 20; break;
704 case 4: amt = randint1(50) + 50; break;
705 case 5: amt = randint1(100) + 100; break;
706 case 6: amt = 300; break;
707 default: amt = 500; break;
708 }
709
710 /* Apply the cut */
711 if (amt) (void)player_inc_timed(p, TMD_CUT, amt, true, true);
712 }
713
714 /* Handle stun */
715 if (do_stun) {
716 /* Critical hit (zero if non-critical) */
717 int amt, tmp = monster_critical(dice, rlev, damage);
718
719 /* Roll for damage */
720 switch (tmp) {
721 case 0: amt = 0; break;
722 case 1: amt = randint1(5); break;
723 case 2: amt = randint1(10) + 10; break;
724 case 3: amt = randint1(20) + 20; break;
725 case 4: amt = randint1(30) + 30; break;
726 case 5: amt = randint1(40) + 40; break;
727 case 6: amt = 100; break;
728 default: amt = 200; break;
729 }
730
731 /* Apply the stun */
732 if (amt)
733 (void)player_inc_timed(p, TMD_STUN, amt, true, true);
734 }
735
736 string_free(act);
737 } else {
738 /* Visible monster missed player, so notify if appropriate. */
739 if (monster_is_visible(mon) && method->miss) {
740 /* Disturbing */
741 disturb(p);
742 msg("%s misses you.", m_name);
743 }
744 }
745
746 /* Analyze "visible" monsters only */
747 if (visible) {
748 /* Count "obvious" attacks (and ones that cause damage) */
749 if (obvious || damage || (lore->blows[ap_cnt].times_seen > 10)) {
750 /* Count attacks of this type */
751 if (lore->blows[ap_cnt].times_seen < UCHAR_MAX)
752 lore->blows[ap_cnt].times_seen++;
753 }
754 }
755
756 /* Skip the other blows if the player has moved */
757 if (!loc_eq(p->grid, pgrid)) break;
758 }
759
760 /* Blink away */
761 if (blinked) {
762 char dice[5];
763 msg("There is a puff of smoke!");
764 strnfmt(dice, sizeof(dice), "%d", z_info->max_sight * 2 + 5);
765 effect_simple(EF_TELEPORT, source_monster(mon->midx), dice, 0, 0, 0, 0, 0, NULL);
766 }
767
768 /* Always notice cause of death */
769 if (p->is_dead && (lore->deaths < SHRT_MAX))
770 lore->deaths++;
771
772 /* Learn lore */
773 lore_update(mon->race, lore);
774
775 /* Assume we attacked */
776 return (true);
777 }
778
779 /**
780 * Attack the player via physical attacks.
781 */
monster_attack_monster(struct monster * mon,struct monster * t_mon)782 bool monster_attack_monster(struct monster *mon, struct monster *t_mon)
783 {
784 struct monster_lore *lore = get_lore(mon->race);
785 int rlev = ((mon->race->level >= 1) ? mon->race->level : 1);
786 int ap_cnt;
787 char m_name[80];
788 char t_name[80];
789 bool blinked = false;
790 int accuracy = 100 - (mon->m_timed[MON_TMD_STUN] ? STUN_HIT_REDUCTION : 0);
791
792 /* Not allowed to attack */
793 if (rf_has(mon->race->flags, RF_NEVER_BLOW)) return (false);
794
795 /* Get the monster names (or "it") */
796 monster_desc(m_name, sizeof(m_name), mon, MDESC_STANDARD);
797 monster_desc(t_name, sizeof(t_name), t_mon, MDESC_TARG);
798
799 /* Scan through all blows */
800 for (ap_cnt = 0; ap_cnt < z_info->mon_blows_max; ap_cnt++) {
801 struct loc grid = t_mon->grid;
802 bool visible = monster_is_visible(mon) || (mon->race->light > 0);
803 bool obvious = false;
804
805 int damage = 0;
806 bool do_stun = false;
807 int sound_msg = MSG_GENERIC;
808
809 char *act = NULL;
810
811 /* Extract the attack infomation */
812 struct blow_effect *effect = mon->race->blow[ap_cnt].effect;
813 struct blow_method *method = mon->race->blow[ap_cnt].method;
814 random_value dice = mon->race->blow[ap_cnt].dice;
815
816 /* No more attacks */
817 if (!method) break;
818
819 /* Monster hits monster */
820 assert(effect);
821 if (streq(effect->name, "NONE") ||
822 check_hit_monster(t_mon, effect->power, rlev, accuracy)) {
823 melee_effect_handler_f effect_handler;
824
825 /* Describe the attack method */
826 act = monster_blow_method_action(method, t_mon->midx);
827 do_stun = method->stun;
828 sound_msg = method->msgt;
829
830 /* Hack -- assume all attacks are obvious */
831 obvious = true;
832
833 /* Roll dice */
834 damage = randcalc(dice, rlev, RANDOMISE);
835
836 /* Reduce damage when stunned */
837 if (mon->m_timed[MON_TMD_STUN]) {
838 damage = (damage * (100 - STUN_DAM_REDUCTION)) / 100;
839 }
840
841 /* Message */
842 if (act) {
843 const char *fullstop = ".";
844 if (suffix(act, "'") || suffix(act, "!")) {
845 fullstop = "";
846 }
847
848 msgt(sound_msg, "%s %s%s", m_name, act, fullstop);
849 }
850
851 /* Perform the actual effect. */
852 effect_handler = melee_handler_for_blow_effect(effect->name);
853 if (effect_handler != NULL) {
854 melee_effect_handler_context_t context = {
855 NULL,
856 mon,
857 t_mon,
858 rlev,
859 method,
860 t_mon->race->ac,
861 NULL,
862 obvious,
863 blinked,
864 damage,
865 };
866
867 effect_handler(&context);
868
869 /* Save any changes made in the handler for later use. */
870 obvious = context.obvious;
871 blinked = context.blinked;
872 damage = context.damage;
873 } else {
874 msg("ERROR: Effect handler not found for %s.", effect->name);
875 }
876
877 /* Handle stun */
878 if (do_stun && square_monster(cave, grid)) {
879 /* Critical hit (zero if non-critical) */
880 int amt, tmp = monster_critical(dice, rlev, damage);
881
882 /* Roll for damage */
883 switch (tmp) {
884 case 0: amt = 0; break;
885 case 1: amt = randint1(5); break;
886 case 2: amt = randint1(10) + 10; break;
887 case 3: amt = randint1(20) + 20; break;
888 case 4: amt = randint1(30) + 30; break;
889 case 5: amt = randint1(40) + 40; break;
890 case 6: amt = 100; break;
891 default: amt = 200; break;
892 }
893
894 /* Apply the stun */
895 if (amt)
896 (void)mon_inc_timed(t_mon, MON_TMD_STUN, amt, 0);
897 }
898
899 string_free(act);
900 } else {
901 /* Visible monster missed monster, so notify if appropriate. */
902 if (monster_is_visible(mon) && method->miss) {
903 msg("%s misses %s.", m_name, t_name);
904 }
905 }
906
907 /* Analyze "visible" monsters only */
908 if (visible) {
909 /* Count "obvious" attacks (and ones that cause damage) */
910 if (obvious || damage || (lore->blows[ap_cnt].times_seen > 10)) {
911 /* Count attacks of this type */
912 if (lore->blows[ap_cnt].times_seen < UCHAR_MAX)
913 lore->blows[ap_cnt].times_seen++;
914 }
915 }
916
917 /* Skip the other blows if the target has moved or died */
918 if (!square_monster(cave, grid)) break;
919 }
920
921 /* Blink away */
922 if (blinked) {
923 char dice[5];
924 msg("There is a puff of smoke!");
925 strnfmt(dice, sizeof(dice), "%d", z_info->max_sight * 2 + 5);
926 effect_simple(EF_TELEPORT, source_monster(mon->midx), dice, 0, 0, 0, 0, 0, NULL);
927 }
928
929 /* Learn lore */
930 lore_update(mon->race, lore);
931
932 /* Assume we attacked */
933 return (true);
934 }
935