1 /* File: melee1.c */
2
3 /* Purpose: Monster attacks */
4
5 /*
6 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7 *
8 * This software may be copied and distributed for educational, research, and
9 * not for profit purposes provided that this copyright and statement are
10 * included in all such copies.
11 */
12
13 #include "mangband.h"
14
15 /* Send "slash effect" to the client */
slash_fx(player_type * p_ptr,int agressor,int victim,u16b sound_msg)16 void slash_fx(player_type *p_ptr, int agressor, int victim, u16b sound_msg)
17 {
18 int x1, y1, x2, y2, dx, dy;
19 char dir;
20 const char dirrrs[3][3] = {
21 { 7, 8, 9 },
22 { 4, 5, 6 },
23 { 1, 2, 3 },
24 };
25 player_type *q_ptr, *q2_ptr;
26 monster_type *m_ptr, *m2_ptr;
27 if (victim >= 0)
28 {
29 m_ptr = &m_list[victim];
30 x1 = m_ptr->fx;
31 y1 = m_ptr->fy;
32 }
33 else
34 {
35 q_ptr = Players[0 - victim];
36 x1 = q_ptr->px;
37 y1 = q_ptr->py;
38 }
39 if (agressor >= 0)
40 {
41 m2_ptr = &m_list[agressor];
42 x2 = m2_ptr->fx;
43 y2 = m2_ptr->fy;
44 }
45 else
46 {
47 q2_ptr = Players[0 - agressor];
48 x2 = q2_ptr->px;
49 y2 = q2_ptr->py;
50 }
51 /* Determine direction */
52 dx = x1 - x2;
53 dy = y1 - y2;
54 if (dx < -1) dx = -1;
55 if (dx > 1) dx = 1;
56 if (dy < -1) dy = -1;
57 if (dy > 1) dy = 1;
58 dir = dirrrs[dy + 1][dx + 1];
59 /* Send it ! */
60 send_slash_fx(p_ptr, y2 - p_ptr->panel_row_min, x2 - p_ptr->panel_col_min, dir, sound_msg);
61 }
62
63 /*
64 * Critical blow. All hits that do 95% of total possible damage,
65 * and which also do at least 20 damage, or, sometimes, N damage.
66 * This is used only to determine "cuts" and "stuns".
67 */
monster_critical(int dice,int sides,int dam)68 static int monster_critical(int dice, int sides, int dam)
69 {
70 int max = 0;
71 int total = dice * sides;
72
73 /* Must do at least 95% of perfect */
74 if (dam < total * 19 / 20) return (0);
75
76 /* Weak blows rarely work */
77 if ((dam < 20) && (randint0(100) >= dam)) return (0);
78
79 /* Perfect damage */
80 if (dam == total) max++;
81
82 /* Super-charge */
83 if (dam >= 20)
84 {
85 while (randint0(100) < 2) max++;
86 }
87
88 /* Critical damage */
89 if (dam > 45) return (6 + max);
90 if (dam > 33) return (5 + max);
91 if (dam > 25) return (4 + max);
92 if (dam > 18) return (3 + max);
93 if (dam > 11) return (2 + max);
94 return (1 + max);
95 }
96
97
98
99
100
101 /*
102 * Determine if a monster attack against the player succeeds.
103 * Always miss 5% of the time, Always hit 5% of the time.
104 * Otherwise, match monster power against player armor.
105 */
check_hit(player_type * p_ptr,int power,int level)106 static int check_hit(player_type *p_ptr, int power, int level)
107 {
108 int i, k, ac;
109
110 /* Percentile dice */
111 k = randint0(100);
112
113 /* Hack -- Always miss or hit */
114 if (k < 10) return (k < 5);
115
116 /* Calculate the "attack quality" */
117 i = (power + (level * 3));
118
119 /* Total armor */
120 ac = p_ptr->ac + p_ptr->to_a;
121
122 /* Power and Level compete against Armor */
123 if ((i > 0) && (randint1(i) > ((ac * 3) / 4))) return (TRUE);
124
125 /* Assume miss */
126 return (FALSE);
127 }
128
129
130
131 /*
132 * Hack -- possible "insult" messages
133 */
134 static cptr desc_insult[] =
135 {
136 "insults you!",
137 "insults your mother!",
138 "gives you the finger!",
139 "humiliates you!",
140 "defiles you!",
141 "dances around you!",
142 "makes obscene gestures!",
143 "moons you!!!"
144 };
145
146
147
148 /*
149 * Hack -- possible "insult" messages
150 */
151 static cptr desc_moan[] =
152 {
153 "seems sad about something.",
154 "asks if you have seen his dogs.",
155 "tells you to get off his land.",
156 "mumbles something about mushrooms."
157 };
158
159
160 /*
161 * Attack a player via physical attacks.
162 */
make_attack_normal(player_type * p_ptr,int m_idx)163 bool make_attack_normal(player_type *p_ptr, int m_idx)
164 {
165 monster_type *m_ptr = &m_list[m_idx];
166
167 monster_race *r_ptr = &r_info[m_ptr->r_idx];
168
169 monster_lore *l_ptr = p_ptr->l_list + m_ptr->r_idx;
170
171 int ap_cnt;
172
173 int i, j, k, tmp, ac, rlev;
174 int do_cut, do_stun;
175
176 s32b gold;
177
178 object_type *o_ptr;
179
180 char o_name[80];
181
182 char m_name[80];
183
184 char ddesc[80];
185
186 int blinked;
187 int sound_msg;
188
189
190 /* Not allowed to attack */
191 if (r_ptr->flags1 & RF1_NEVER_BLOW) return (FALSE);
192
193 /* Total armor */
194 ac = p_ptr->ac + p_ptr->to_a;
195
196 /* Extract the effective monster level */
197 rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
198
199
200 /* Get the monster name (or "it") */
201 monster_desc(p_ptr, m_name, m_idx, 0);
202
203 /* Get the "died from" information (i.e. "a kobold") */
204 monster_desc(p_ptr, ddesc, m_idx, 0x88);
205
206
207 /* Assume no blink */
208 blinked = 0;
209
210 /* Scan through all four blows */
211 for (ap_cnt = 0; ap_cnt < 4; ap_cnt++)
212 {
213 bool visible = FALSE;
214 bool obvious = FALSE;
215
216 int power = 0;
217 int damage = 0;
218
219 cptr act = NULL;
220
221 /* Extract the attack infomation */
222 int effect = r_ptr->blow[ap_cnt].effect;
223 int method = r_ptr->blow[ap_cnt].method;
224 int d_dice = r_ptr->blow[ap_cnt].d_dice;
225 int d_side = r_ptr->blow[ap_cnt].d_side;
226
227
228 /* Hack -- no more attacks */
229 if (!method) break;
230
231 /* Stop if player is dead or gone */
232 if (!p_ptr->alive || p_ptr->death || p_ptr->new_level_flag) break;
233
234
235 /* Extract visibility (before blink) */
236 if (p_ptr->mon_vis[m_idx]) visible = TRUE;
237
238
239
240 /* Extract the attack "power" */
241 switch (effect)
242 {
243 case RBE_HURT: power = 60; break;
244 case RBE_POISON: power = 5; break;
245 case RBE_UN_BONUS: power = 20; break;
246 case RBE_UN_POWER: power = 15; break;
247 case RBE_EAT_GOLD: power = 5; break;
248 case RBE_EAT_ITEM: power = 5; break;
249 case RBE_EAT_FOOD: power = 5; break;
250 case RBE_EAT_LITE: power = 5; break;
251 case RBE_ACID: power = 0; break;
252 case RBE_ELEC: power = 10; break;
253 case RBE_FIRE: power = 10; break;
254 case RBE_COLD: power = 10; break;
255 case RBE_BLIND: power = 2; break;
256 case RBE_CONFUSE: power = 10; break;
257 case RBE_TERRIFY: power = 10; break;
258 case RBE_PARALYZE: power = 2; break;
259 case RBE_LOSE_STR: power = 0; break;
260 case RBE_LOSE_DEX: power = 0; break;
261 case RBE_LOSE_CON: power = 0; break;
262 case RBE_LOSE_INT: power = 0; break;
263 case RBE_LOSE_WIS: power = 0; break;
264 case RBE_LOSE_CHR: power = 0; break;
265 case RBE_LOSE_ALL: power = 2; break;
266 case RBE_SHATTER: power = 60; break;
267 case RBE_EXP_10: power = 5; break;
268 case RBE_EXP_20: power = 5; break;
269 case RBE_EXP_40: power = 5; break;
270 case RBE_EXP_80: power = 5; break;
271 case RBE_HALLU: power = 10; break;
272 }
273
274
275 /* Monster hits player */
276 if (!effect || check_hit(p_ptr, power, rlev))
277 {
278 /* Always disturbing */
279 disturb(p_ptr, 1, 0);
280
281
282 /* Hack -- Apply "protection from evil" */
283 if ((p_ptr->protevil > 0) &&
284 (r_ptr->flags3 & RF3_EVIL) &&
285 (p_ptr->lev >= rlev) &&
286 ((randint0(100) + p_ptr->lev) > 50))
287 {
288 /* Remember the Evil-ness */
289 if (p_ptr->mon_vis[m_idx]) l_ptr->flags3 |= RF3_EVIL;
290
291 /* Message */
292 msg_format(p_ptr, "%^s is repelled.", m_name);
293
294 /* Hack -- Next attack */
295 continue;
296 }
297
298
299 /* Assume no cut or stun */
300 do_cut = do_stun = 0;
301
302 /* Assume no sound */
303 sound_msg = MSG_GENERIC;
304
305 /* Describe the attack method */
306 switch (method)
307 {
308 case RBM_HIT:
309 {
310 act = "hits you.";
311 do_cut = do_stun = 1;
312 sound_msg = MSG_MON_HIT;
313 break;
314 }
315
316 case RBM_TOUCH:
317 {
318 act = "touches you.";
319 sound_msg = MSG_MON_TOUCH;
320 break;
321 }
322
323 case RBM_PUNCH:
324 {
325 act = "punches you.";
326 do_stun = 1;
327 sound_msg = MSG_MON_PUNCH;
328 break;
329 }
330
331 case RBM_KICK:
332 {
333 act = "kicks you.";
334 do_stun = 1;
335 sound_msg = MSG_MON_KICK;
336 break;
337 }
338
339 case RBM_CLAW:
340 {
341 act = "claws you.";
342 do_cut = 1;
343 sound_msg = MSG_MON_CLAW;
344 break;
345 }
346
347 case RBM_BITE:
348 {
349 act = "bites you.";
350 do_cut = 1;
351 sound_msg = MSG_MON_BITE;
352 break;
353 }
354
355 case RBM_STING:
356 {
357 act = "stings you.";
358 sound_msg = MSG_MON_STING;
359 break;
360 }
361
362 case RBM_XXX1:
363 {
364 act = "XXX1's you.";
365 break;
366 }
367
368 case RBM_BUTT:
369 {
370 act = "butts you.";
371 do_stun = 1;
372 sound_msg = MSG_MON_BUTT;
373 break;
374 }
375
376 case RBM_CRUSH:
377 {
378 act = "crushes you.";
379 do_stun = 1;
380 sound_msg = MSG_MON_CRUSH;
381 break;
382 }
383
384 case RBM_ENGULF:
385 {
386 act = "engulfs you.";
387 sound_msg = MSG_MON_ENGULF;
388 break;
389 }
390
391 case RBM_XXX2:
392 {
393 act = "XXX2's you.";
394 break;
395 }
396
397 case RBM_CRAWL:
398 {
399 act = "crawls on you.";
400 sound_msg = MSG_MON_CRAWL;
401 break;
402 }
403
404 case RBM_DROOL:
405 {
406 act = "drools on you.";
407 sound_msg = MSG_MON_DROOL;
408 break;
409 }
410
411 case RBM_SPIT:
412 {
413 act = "spits on you.";
414 sound_msg = MSG_MON_SPIT;
415 break;
416 }
417
418 case RBM_XXX3:
419 {
420 act = "XXX3's on you.";
421 break;
422 }
423
424 case RBM_GAZE:
425 {
426 act = "gazes at you.";
427 sound_msg = MSG_MON_GAZE;
428 break;
429 }
430
431 case RBM_WAIL:
432 {
433 act = "wails at you.";
434 sound_msg = MSG_MON_WAIL;
435 break;
436 }
437
438 case RBM_SPORE:
439 {
440 act = "releases spores at you.";
441 sound_msg = MSG_MON_SPORE;
442 break;
443 }
444
445 case RBM_XXX4:
446 {
447 act = "projects XXX4's at you.";
448 break;
449 }
450
451 case RBM_BEG:
452 {
453 act = "begs you for money.";
454 sound_msg = MSG_MON_BEG;
455 break;
456 }
457
458 case RBM_INSULT:
459 {
460 act = desc_insult[randint0(8)];
461 sound_msg = MSG_MON_INSULT;
462 break;
463 }
464
465 case RBM_MOAN:
466 {
467 act = desc_moan[randint0(4)];
468 sound_msg = MSG_MON_MOAN;
469 break;
470 }
471
472 case RBM_XXX5:
473 {
474 act = "XXX5's you.";
475 break;
476 }
477 }
478
479 /* Message */
480 if (act) msg_format(p_ptr, "%^s %s", m_name, act);
481 if (act) sound(p_ptr, sound_msg);
482 if (act) slash_fx(p_ptr, m_idx, 0 - p_ptr->Ind, sound_msg);
483
484 /* Hack -- assume all attacks are obvious */
485 obvious = TRUE;
486
487 /* Roll out the damage */
488 damage = damroll(d_dice, d_side);
489
490 /* Apply appropriate damage */
491 switch (effect)
492 {
493 case 0:
494 {
495 /* Hack -- Assume obvious */
496 obvious = TRUE;
497
498 /* Hack -- No damage */
499 damage = 0;
500
501 break;
502 }
503
504 case RBE_HURT:
505 {
506 /* Obvious */
507 obvious = TRUE;
508
509 /* Hack -- Player armor reduces total damage */
510 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
511
512 /* Take damage */
513 take_hit(p_ptr, damage, ddesc);
514
515 break;
516 }
517
518 case RBE_POISON:
519 {
520 /* Take some damage */
521 take_hit(p_ptr, damage, ddesc);
522
523 /* Take "poison" effect */
524 if (!(p_ptr->resist_pois || p_ptr->oppose_pois))
525 {
526 if (set_poisoned(p_ptr, p_ptr->poisoned + randint1(rlev) + 5))
527 {
528 obvious = TRUE;
529 }
530 }
531
532 /* Learn about the player */
533 update_smart_learn(m_idx, DRS_POIS);
534
535 break;
536 }
537
538 case RBE_UN_BONUS:
539 {
540 /* Take some damage */
541 take_hit(p_ptr, damage, ddesc);
542
543 /* Allow complete resist */
544 if (!p_ptr->resist_disen)
545 {
546 /* Apply disenchantment */
547 if (apply_disenchant(p_ptr, 0)) obvious = TRUE;
548 }
549
550 /* Learn about the player */
551 update_smart_learn(m_idx, DRS_DISEN);
552
553 break;
554 }
555
556 case RBE_UN_POWER:
557 {
558 /* Take some damage */
559 take_hit(p_ptr, damage, ddesc);
560
561 /* Find an item */
562 for (k = 0; k < 10; k++)
563 {
564 /* Pick an item */
565 i = randint0(INVEN_PACK);
566
567 /* Obtain the item */
568 o_ptr = &p_ptr->inventory[i];
569
570 /* Skip non-objects */
571 if (!o_ptr->k_idx) continue;
572
573 /* Drain charged wands/staffs */
574 if (((o_ptr->tval == TV_STAFF) ||
575 (o_ptr->tval == TV_WAND)) &&
576 (o_ptr->pval))
577 {
578 /* Message */
579 msg_print(p_ptr, "Energy drains from your pack!");
580
581 /* Obvious */
582 obvious = TRUE;
583
584 /* Heal */
585 j = rlev;
586 m_ptr->hp += j * o_ptr->pval;
587 if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
588
589 /* Redraw (later) if needed */
590 update_health(m_idx);
591
592 /* Uncharge */
593 o_ptr->pval = 0;
594
595 /* Combine / Reorder the pack */
596 p_ptr->notice |= (PN_COMBINE | PN_REORDER);
597
598 /* Redraw slot */
599 p_ptr->redraw_inven |= (1LL << i);
600
601 /* Done */
602 break;
603 }
604 }
605
606 break;
607 }
608
609 case RBE_EAT_GOLD:
610 {
611 /* Take some damage */
612 take_hit(p_ptr, damage, ddesc);
613
614 /* Obvious */
615 obvious = TRUE;
616
617 /* Saving throw (unless paralyzed) based on dex and level */
618 if (!p_ptr->paralyzed &&
619 (randint0(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
620 p_ptr->lev)))
621 {
622 /* Saving throw message */
623 msg_print(p_ptr, "You quickly protect your money pouch!");
624
625 /* Occasional blink anyway */
626 if (randint0(3)) blinked = 2;
627 }
628
629 /* Eat gold */
630 else
631 {
632 gold = (p_ptr->au / 10) + randint1(25);
633 if (gold < 2) gold = 2;
634 if (gold > 5000) gold = (p_ptr->au / 20) + randint1(3000);
635 if (gold > p_ptr->au) gold = p_ptr->au;
636 p_ptr->au -= gold;
637 if (gold <= 0)
638 {
639 msg_print(p_ptr, "Nothing was stolen.");
640 }
641 else if (p_ptr->au)
642 {
643 msg_print(p_ptr, "Your purse feels lighter.");
644 msg_format(p_ptr, "%ld coins were stolen!", (long)gold);
645 }
646 else
647 {
648 msg_print(p_ptr, "Your purse feels lighter.");
649 msg_print(p_ptr, "All of your coins were stolen!");
650 }
651
652 /* Redraw gold */
653 p_ptr->redraw |= (PR_GOLD);
654
655 /* Window stuff */
656 p_ptr->window |= (PW_PLAYER);
657
658 /* Blink away */
659 blinked = 2;
660 }
661
662 break;
663 }
664
665 case RBE_EAT_ITEM:
666 {
667 /* Take some damage */
668 take_hit(p_ptr, damage, ddesc);
669
670 /* Saving throw (unless paralyzed) based on dex and level */
671 if (!p_ptr->paralyzed &&
672 (randint0(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
673 p_ptr->lev)))
674 {
675 /* Saving throw message */
676 msg_print(p_ptr, "You grab hold of your backpack!");
677
678 /* Occasional "blink" anyway */
679 blinked = 2;
680
681 /* Obvious */
682 obvious = TRUE;
683
684 /* Done */
685 break;
686 }
687
688 /* Find an item */
689 for (k = 0; k < 10; k++)
690 {
691 /* Item copy */
692 object_type *i_ptr;
693 object_type object_type_body;
694
695 /* Pick an item */
696 i = randint0(INVEN_PACK);
697
698 /* Obtain the item */
699 o_ptr = &p_ptr->inventory[i];
700
701 /* Accept real items */
702 if (!o_ptr->k_idx) continue;
703
704 /* Don't steal artifacts -CFT */
705 if (true_artifact_p(o_ptr)) continue;
706
707 /* Get local object */
708 i_ptr = &object_type_body;
709
710 /* Obtain local object */
711 COPY(i_ptr, o_ptr, object_type);
712
713 /* Modify number */
714 i_ptr->number = 1;
715
716 /* Hack -- If a rod, staff, or wand, allocate total
717 * maximum timeouts or charges between those
718 * stolen and those missed. -LM-
719 */
720 distribute_charges(o_ptr, i_ptr, 1);
721
722 /* Get a description */
723 object_desc(p_ptr, o_name, sizeof(o_name), i_ptr, FALSE, 3);
724
725 /* Message */
726 msg_format(p_ptr, "%sour %s (%c) was stolen!",
727 ((o_ptr->number > 1) ? "One of y" : "Y"),
728 o_name, index_to_label(i));
729
730 if (monster_can_carry(m_idx))
731 {
732 /* Carry the object */
733 monster_carry(p_ptr, m_idx, i_ptr);
734 }
735
736 /* Steal the items */
737 inven_item_increase(p_ptr, i, -1);
738 inven_item_optimize(p_ptr, i);
739
740 /* Obvious */
741 obvious = TRUE;
742
743 /* Blink away */
744 blinked = 2;
745
746 /* Done */
747 break;
748 }
749
750 break;
751 }
752
753 case RBE_EAT_FOOD:
754 {
755 /* Take some damage */
756 take_hit(p_ptr, damage, ddesc);
757
758 /* Steal some food */
759 for (k = 0; k < 10; k++)
760 {
761 /* Pick an item from the pack */
762 i = randint0(INVEN_PACK);
763
764 /* Get the item */
765 o_ptr = &p_ptr->inventory[i];
766
767 /* Accept real items */
768 if (!o_ptr->k_idx) continue;
769
770 /* Only eat food */
771 if (o_ptr->tval != TV_FOOD) continue;
772
773 /* Get a description */
774 object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, FALSE, 0);
775
776 /* Message */
777 msg_format(p_ptr, "%sour %s (%c) was eaten!",
778 ((o_ptr->number > 1) ? "One of y" : "Y"),
779 o_name, index_to_label(i));
780
781 /* Steal the items */
782 inven_item_increase(p_ptr, i, -1);
783 inven_item_optimize(p_ptr, i);
784
785 /* Obvious */
786 obvious = TRUE;
787
788 /* Done */
789 break;
790 }
791
792 break;
793 }
794
795 case RBE_EAT_LITE:
796 {
797 /* Take some damage */
798 take_hit(p_ptr, damage, ddesc);
799
800 /* Access the lite */
801 o_ptr = &p_ptr->inventory[INVEN_LITE];
802
803 /* Drain fuel */
804 if ((o_ptr->pval > 0) && (o_ptr->sval < SV_LITE_DWARVEN))
805 {
806 /* Reduce fuel */
807 o_ptr->pval -= (250 + randint1(250));
808 if (o_ptr->pval < 1) o_ptr->pval = 1;
809
810 /* Notice */
811 if (!p_ptr->blind)
812 {
813 msg_print(p_ptr, "Your light dims.");
814 obvious = TRUE;
815 }
816
817 /* Redraw slot */
818 p_ptr->redraw_inven |= (1LL << INVEN_LITE);
819 }
820
821 break;
822 }
823
824 case RBE_ACID:
825 {
826 /* Obvious */
827 obvious = TRUE;
828
829 /* Message */
830 msg_print(p_ptr, "You are covered in acid!");
831
832 /* Special damage */
833 acid_dam(p_ptr, damage, ddesc);
834
835 /* Learn about the player */
836 update_smart_learn(m_idx, DRS_ACID);
837
838 break;
839 }
840
841 case RBE_ELEC:
842 {
843 /* Obvious */
844 obvious = TRUE;
845
846 /* Message */
847 msg_print(p_ptr, "You are struck by electricity!");
848
849 /* Special damage */
850 elec_dam(p_ptr, damage, ddesc);
851
852 /* Learn about the player */
853 update_smart_learn(m_idx, DRS_ELEC);
854
855 break;
856 }
857
858 case RBE_FIRE:
859 {
860 /* Obvious */
861 obvious = TRUE;
862
863 /* Message */
864 msg_print(p_ptr, "You are enveloped in flames!");
865
866 /* Special damage */
867 fire_dam(p_ptr, damage, ddesc);
868
869 /* Learn about the player */
870 update_smart_learn(m_idx, DRS_FIRE);
871
872 break;
873 }
874
875 case RBE_COLD:
876 {
877 /* Obvious */
878 obvious = TRUE;
879
880 /* Message */
881 msg_print(p_ptr, "You are covered with frost!");
882
883 /* Special damage */
884 cold_dam(p_ptr, damage, ddesc);
885
886 /* Learn about the player */
887 update_smart_learn(m_idx, DRS_COLD);
888
889 break;
890 }
891
892 case RBE_BLIND:
893 {
894 /* Take damage */
895 take_hit(p_ptr, damage, ddesc);
896
897 /* Increase "blind" */
898 if (!p_ptr->resist_blind)
899 {
900 if (set_blind(p_ptr, p_ptr->blind + 10 + randint1(rlev)))
901 {
902 obvious = TRUE;
903 }
904 }
905
906 /* Learn about the player */
907 update_smart_learn(m_idx, DRS_BLIND);
908
909 break;
910 }
911
912 case RBE_CONFUSE:
913 {
914 /* Take damage */
915 take_hit(p_ptr, damage, ddesc);
916
917 /* Increase "confused" */
918 if (!p_ptr->resist_conf)
919 {
920 if (set_confused(p_ptr, p_ptr->confused + 3 + randint1(rlev)))
921 {
922 obvious = TRUE;
923 }
924 }
925
926 /* Learn about the player */
927 update_smart_learn(m_idx, DRS_CONF);
928
929 break;
930 }
931
932 case RBE_TERRIFY:
933 {
934 /* Take damage */
935 take_hit(p_ptr, damage, ddesc);
936
937 /* Increase "afraid" */
938 if (p_ptr->resist_fear)
939 {
940 msg_print(p_ptr, "You stand your ground!");
941 obvious = TRUE;
942 }
943 else if (randint0(100) < p_ptr->skill_sav)
944 {
945 msg_print(p_ptr, "You stand your ground!");
946 obvious = TRUE;
947 }
948 else
949 {
950 if (set_afraid(p_ptr, p_ptr->afraid + 3 + randint1(rlev)))
951 {
952 obvious = TRUE;
953 }
954 }
955
956 /* Learn about the player */
957 update_smart_learn(m_idx, DRS_FEAR);
958
959 break;
960 }
961
962 case RBE_PARALYZE:
963 {
964 /* Take damage */
965 take_hit(p_ptr, damage, ddesc);
966
967 /* Increase "paralyzed" */
968 if (p_ptr->free_act)
969 {
970 msg_print(p_ptr, "You are unaffected!");
971 obvious = TRUE;
972 }
973 else if (randint0(100) < p_ptr->skill_sav)
974 {
975 msg_print(p_ptr, "You resist the effects!");
976 obvious = TRUE;
977 }
978 else
979 {
980 if (set_paralyzed(p_ptr, p_ptr->paralyzed + 3 + randint1(rlev)))
981 {
982 obvious = TRUE;
983
984 /* Hack - Make level 1 monsters who paralyze also blink */
985 if (r_ptr->level == 1) blinked = 1;
986 }
987 }
988
989 /* Learn about the player */
990 update_smart_learn(m_idx, DRS_FREE);
991
992 break;
993 }
994
995 case RBE_LOSE_STR:
996 {
997 /* Damage (physical) */
998 take_hit(p_ptr, damage, ddesc);
999
1000 /* Damage (stat) */
1001 if (do_dec_stat(p_ptr, A_STR)) obvious = TRUE;
1002
1003 break;
1004 }
1005
1006 case RBE_LOSE_INT:
1007 {
1008 /* Damage (physical) */
1009 take_hit(p_ptr, damage, ddesc);
1010
1011 /* Damage (stat) */
1012 if (do_dec_stat(p_ptr, A_INT)) obvious = TRUE;
1013
1014 break;
1015 }
1016
1017 case RBE_LOSE_WIS:
1018 {
1019 /* Damage (physical) */
1020 take_hit(p_ptr, damage, ddesc);
1021
1022 /* Damage (stat) */
1023 if (do_dec_stat(p_ptr, A_WIS)) obvious = TRUE;
1024
1025 break;
1026 }
1027
1028 case RBE_LOSE_DEX:
1029 {
1030 /* Damage (physical) */
1031 take_hit(p_ptr, damage, ddesc);
1032
1033 /* Damage (stat) */
1034 if (do_dec_stat(p_ptr, A_DEX)) obvious = TRUE;
1035
1036 break;
1037 }
1038
1039 case RBE_LOSE_CON:
1040 {
1041 /* Damage (physical) */
1042 take_hit(p_ptr, damage, ddesc);
1043
1044 /* Damage (stat) */
1045 if (do_dec_stat(p_ptr, A_CON)) obvious = TRUE;
1046
1047 break;
1048 }
1049
1050 case RBE_LOSE_CHR:
1051 {
1052 /* Damage (physical) */
1053 take_hit(p_ptr, damage, ddesc);
1054
1055 /* Damage (stat) */
1056 if (do_dec_stat(p_ptr, A_CHR)) obvious = TRUE;
1057
1058 break;
1059 }
1060
1061 case RBE_LOSE_ALL:
1062 {
1063 /* Damage (physical) */
1064 take_hit(p_ptr, damage, ddesc);
1065
1066 /* Damage (stats) */
1067 if (do_dec_stat(p_ptr, A_STR)) obvious = TRUE;
1068 if (do_dec_stat(p_ptr, A_DEX)) obvious = TRUE;
1069 if (do_dec_stat(p_ptr, A_CON)) obvious = TRUE;
1070 if (do_dec_stat(p_ptr, A_INT)) obvious = TRUE;
1071 if (do_dec_stat(p_ptr, A_WIS)) obvious = TRUE;
1072 if (do_dec_stat(p_ptr, A_CHR)) obvious = TRUE;
1073
1074 break;
1075 }
1076
1077 case RBE_SHATTER:
1078 {
1079 /* Obvious */
1080 obvious = TRUE;
1081
1082 /* Hack -- Reduce damage based on the player armor class */
1083 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
1084
1085 /* Take damage */
1086 take_hit(p_ptr, damage, ddesc);
1087
1088 /* Radius 8 earthquake centered at the monster */
1089 if (damage > 23) earthquake(p_ptr->dun_depth, m_ptr->fy, m_ptr->fx, 8);
1090
1091 break;
1092 }
1093
1094 case RBE_EXP_10:
1095 {
1096 /* Obvious */
1097 obvious = TRUE;
1098
1099 /* Take damage */
1100 take_hit(p_ptr, damage, ddesc);
1101
1102 if (p_ptr->hold_life && (randint0(100) < 95))
1103 {
1104 msg_print(p_ptr, "You keep hold of your life force!");
1105 }
1106 else
1107 {
1108 s32b d = damroll(10, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE;
1109 if (p_ptr->hold_life)
1110 {
1111 msg_print(p_ptr, "You feel your life slipping away!");
1112 lose_exp(p_ptr, d/10);
1113 }
1114 else
1115 {
1116 msg_print(p_ptr, "You feel your life draining away!");
1117 lose_exp(p_ptr, d);
1118 }
1119 }
1120 break;
1121 }
1122
1123 case RBE_EXP_20:
1124 {
1125 /* Obvious */
1126 obvious = TRUE;
1127
1128 /* Take damage */
1129 take_hit(p_ptr, damage, ddesc);
1130
1131 if (p_ptr->hold_life && (randint0(100) < 90))
1132 {
1133 msg_print(p_ptr, "You keep hold of your life force!");
1134 }
1135 else
1136 {
1137 s32b d = damroll(20, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE;
1138 if (p_ptr->hold_life)
1139 {
1140 msg_print(p_ptr, "You feel your life slipping away!");
1141 lose_exp(p_ptr, d/10);
1142 }
1143 else
1144 {
1145 msg_print(p_ptr, "You feel your life draining away!");
1146 lose_exp(p_ptr, d);
1147 }
1148 }
1149 break;
1150 }
1151
1152 case RBE_EXP_40:
1153 {
1154 /* Obvious */
1155 obvious = TRUE;
1156
1157 /* Take damage */
1158 take_hit(p_ptr, damage, ddesc);
1159
1160 if (p_ptr->hold_life && (randint0(100) < 75))
1161 {
1162 msg_print(p_ptr, "You keep hold of your life force!");
1163 }
1164 else
1165 {
1166 s32b d = damroll(40, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE;
1167 if (p_ptr->hold_life)
1168 {
1169 msg_print(p_ptr, "You feel your life slipping away!");
1170 lose_exp(p_ptr, d/10);
1171 }
1172 else
1173 {
1174 msg_print(p_ptr, "You feel your life draining away!");
1175 lose_exp(p_ptr, d);
1176 }
1177 }
1178 break;
1179 }
1180
1181 case RBE_EXP_80:
1182 {
1183 /* Obvious */
1184 obvious = TRUE;
1185
1186 /* Take damage */
1187 take_hit(p_ptr, damage, ddesc);
1188
1189 if (p_ptr->hold_life && (randint0(100) < 50))
1190 {
1191 msg_print(p_ptr, "You keep hold of your life force!");
1192 }
1193 else
1194 {
1195 s32b d = damroll(80, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE;
1196 if (p_ptr->hold_life)
1197 {
1198 msg_print(p_ptr, "You feel your life slipping away!");
1199 lose_exp(p_ptr, d/10);
1200 }
1201 else
1202 {
1203 msg_print(p_ptr, "You feel your life draining away!");
1204 lose_exp(p_ptr, d);
1205 }
1206 }
1207 break;
1208 }
1209
1210 case RBE_HALLU:
1211 {
1212 /* Take damage */
1213 take_hit(p_ptr, damage, ddesc);
1214
1215 /* Increase "image" */
1216 if (!p_ptr->resist_chaos)
1217 {
1218 if (set_image(p_ptr, p_ptr->image + 3 + randint1(rlev / 2)))
1219 {
1220 obvious = TRUE;
1221 }
1222 }
1223 }
1224 }
1225
1226
1227 /* Hack -- only one of cut or stun */
1228 if (do_cut && do_stun)
1229 {
1230 /* Cancel cut */
1231 if (randint0(100) < 50)
1232 {
1233 do_cut = 0;
1234 }
1235
1236 /* Cancel stun */
1237 else
1238 {
1239 do_stun = 0;
1240 }
1241 }
1242
1243 /* Handle cut */
1244 if (do_cut)
1245 {
1246 int k = 0;
1247
1248 /* Critical hit (zero if non-critical) */
1249 tmp = monster_critical(d_dice, d_side, damage);
1250
1251 /* Roll for damage */
1252 switch (tmp)
1253 {
1254 case 0: k = 0; break;
1255 case 1: k = randint1(5); break;
1256 case 2: k = randint1(5) + 5; break;
1257 case 3: k = randint1(20) + 20; break;
1258 case 4: k = randint1(50) + 50; break;
1259 case 5: k = randint1(100) + 100; break;
1260 case 6: k = 300; break;
1261 default: k = 500; break;
1262 }
1263
1264 /* Apply the cut */
1265 if (k) (void)set_cut(p_ptr, p_ptr->cut + k);
1266 }
1267
1268 /* Handle stun */
1269 if (do_stun)
1270 {
1271 int k = 0;
1272
1273 /* Critical hit (zero if non-critical) */
1274 tmp = monster_critical(d_dice, d_side, damage);
1275
1276 /* Roll for damage */
1277 switch (tmp)
1278 {
1279 case 0: k = 0; break;
1280 case 1: k = randint1(5); break;
1281 case 2: k = randint1(10) + 10; break;
1282 case 3: k = randint1(20) + 20; break;
1283 case 4: k = randint1(30) + 30; break;
1284 case 5: k = randint1(40) + 40; break;
1285 case 6: k = 100; break;
1286 default: k = 200; break;
1287 }
1288
1289 /* Apply the stun */
1290 if (k) (void)set_stun(p_ptr, p_ptr->stun + k);
1291 }
1292 }
1293
1294 /* Monster missed player */
1295 else
1296 {
1297 /* Analyze failed attacks */
1298 switch (method)
1299 {
1300 case RBM_HIT:
1301 case RBM_TOUCH:
1302 case RBM_PUNCH:
1303 case RBM_KICK:
1304 case RBM_CLAW:
1305 case RBM_BITE:
1306 case RBM_STING:
1307 case RBM_XXX1:
1308 case RBM_BUTT:
1309 case RBM_CRUSH:
1310 case RBM_ENGULF:
1311 case RBM_XXX2:
1312
1313 /* Visible monsters */
1314 if (p_ptr->mon_vis[m_idx])
1315 {
1316 /* Disturbing */
1317 disturb(p_ptr, 1, 0);
1318
1319 /* Message */
1320 msg_format(p_ptr, "%^s misses you.", m_name);
1321 sound(p_ptr, MSG_MISS);
1322 slash_fx(p_ptr, m_idx, 0 - p_ptr->Ind, MSG_MISS);
1323 }
1324
1325 break;
1326 }
1327 }
1328
1329
1330 /* Analyze "visible" monsters only */
1331 if (visible)
1332 {
1333 /* Count "obvious" attacks (and ones that cause damage) */
1334 if (obvious || damage || (l_ptr->blows[ap_cnt] > 10))
1335 {
1336 /* Count attacks of this type */
1337 if (l_ptr->blows[ap_cnt] < MAX_UCHAR)
1338 {
1339 l_ptr->blows[ap_cnt]++;
1340 }
1341 }
1342 }
1343 }
1344
1345
1346 /* Blink away */
1347 if (blinked == 2)
1348 {
1349 msg_print(p_ptr, "There is a puff of smoke!");
1350 teleport_away(m_idx, MAX_SIGHT * 2 + 5);
1351 }
1352 else if (blinked == 1)
1353 {
1354 msg_format(p_ptr, "%^s blinks away.", m_name);
1355 teleport_away(m_idx, 10);
1356 }
1357
1358
1359 /* Always notice cause of death */
1360 if (p_ptr->death && (l_ptr->deaths < MAX_SHORT)) l_ptr->deaths++;
1361
1362
1363 /* Assume we attacked */
1364 return (TRUE);
1365 }
1366