Angband 3.0.9b.
[angband.git] / src / melee1.c
blobdb9757370ea26770f6635cb5af3d2f53f6358f96
1 /* File: melee1.c */
3 /*
4 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6 * This software may be copied and distributed for educational, research,
7 * and not for profit purposes provided that this copyright and statement
8 * are included in all such copies. Other copyrights may also apply.
9 */
11 #include "angband.h"
16 * Critical blow. All hits that do 95% of total possible damage,
17 * and which also do at least 20 damage, or, sometimes, N damage.
18 * This is used only to determine "cuts" and "stuns".
20 static int monster_critical(int dice, int sides, int dam)
22 int max = 0;
23 int total = dice * sides;
25 /* Must do at least 95% of perfect */
26 if (dam < total * 19 / 20) return (0);
28 /* Weak blows rarely work */
29 if ((dam < 20) && (rand_int(100) >= dam)) return (0);
31 /* Perfect damage */
32 if (dam == total) max++;
34 /* Super-charge */
35 if (dam >= 20)
37 while (rand_int(100) < 2) max++;
40 /* Critical damage */
41 if (dam > 45) return (6 + max);
42 if (dam > 33) return (5 + max);
43 if (dam > 25) return (4 + max);
44 if (dam > 18) return (3 + max);
45 if (dam > 11) return (2 + max);
46 return (1 + max);
54 * Determine if a monster attack against the player succeeds.
56 static bool check_hit(int power, int level)
58 int chance, ac;
60 /* Calculate the "attack quality" */
61 chance = (power + (level * 3));
63 /* Total armor */
64 ac = p_ptr->ac + p_ptr->to_a;
66 /* Check if the player was hit */
67 return test_hit(chance, ac, TRUE);
71 #define MAX_DESC_INSULT 8
75 * Hack -- possible "insult" messages
77 static cptr desc_insult[MAX_DESC_INSULT] =
79 "insults you!",
80 "insults your mother!",
81 "gives you the finger!",
82 "humiliates you!",
83 "defiles you!",
84 "dances around you!",
85 "makes obscene gestures!",
86 "moons you!!!"
90 #define MAX_DESC_MOAN 8
94 * Hack -- possible "insult" messages
96 static cptr desc_moan[MAX_DESC_MOAN] =
98 "wants his mushrooms back.",
99 "tells you to get off his land.",
100 "looks for his dogs. ",
101 "says 'Did you kill my Fang?' ",
102 "asks 'Do you want to buy any mushrooms?' ",
103 "seems sad about something.",
104 "asks if you have seen his dogs.",
105 "mumbles something about mushrooms."
110 * Attack the player via physical attacks.
112 bool make_attack_normal(int m_idx)
114 monster_type *m_ptr = &mon_list[m_idx];
116 monster_race *r_ptr = &r_info[m_ptr->r_idx];
118 monster_lore *l_ptr = &l_list[m_ptr->r_idx];
120 int ap_cnt;
122 int i, k, tmp, ac, rlev;
123 int do_cut, do_stun;
125 s32b gold;
127 object_type *o_ptr;
129 char o_name[80];
131 char m_name[80];
133 char ddesc[80];
135 bool blinked;
137 int sound_msg;
140 /* Not allowed to attack */
141 if (r_ptr->flags1 & (RF1_NEVER_BLOW)) return (FALSE);
144 /* Total armor */
145 ac = p_ptr->ac + p_ptr->to_a;
147 /* Extract the effective monster level */
148 rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
151 /* Get the monster name (or "it") */
152 monster_desc(m_name, sizeof(m_name), m_ptr, 0);
154 /* Get the "died from" information (i.e. "a kobold") */
155 monster_desc(ddesc, sizeof(ddesc), m_ptr, 0x88);
158 /* Assume no blink */
159 blinked = FALSE;
161 /* Scan through all blows */
162 for (ap_cnt = 0; ap_cnt < MONSTER_BLOW_MAX; ap_cnt++)
164 bool visible = FALSE;
165 bool obvious = FALSE;
166 bool do_break = FALSE;
168 int power = 0;
169 int damage = 0;
171 cptr act = NULL;
173 /* Extract the attack infomation */
174 int effect = r_ptr->blow[ap_cnt].effect;
175 int method = r_ptr->blow[ap_cnt].method;
176 int d_dice = r_ptr->blow[ap_cnt].d_dice;
177 int d_side = r_ptr->blow[ap_cnt].d_side;
180 /* Hack -- no more attacks */
181 if (!method) break;
184 /* Handle "leaving" */
185 if (p_ptr->leaving) break;
188 /* Extract visibility (before blink) */
189 if (m_ptr->ml) visible = TRUE;
193 /* Extract the attack "power" */
194 switch (effect)
196 case RBE_HURT: power = 60; break;
197 case RBE_POISON: power = 5; break;
198 case RBE_UN_BONUS: power = 20; break;
199 case RBE_UN_POWER: power = 15; break;
200 case RBE_EAT_GOLD: power = 5; break;
201 case RBE_EAT_ITEM: power = 5; break;
202 case RBE_EAT_FOOD: power = 5; break;
203 case RBE_EAT_LITE: power = 5; break;
204 case RBE_ACID: power = 0; break;
205 case RBE_ELEC: power = 10; break;
206 case RBE_FIRE: power = 10; break;
207 case RBE_COLD: power = 10; break;
208 case RBE_BLIND: power = 2; break;
209 case RBE_CONFUSE: power = 10; break;
210 case RBE_TERRIFY: power = 10; break;
211 case RBE_PARALYZE: power = 2; break;
212 case RBE_LOSE_STR: power = 0; break;
213 case RBE_LOSE_DEX: power = 0; break;
214 case RBE_LOSE_CON: power = 0; break;
215 case RBE_LOSE_INT: power = 0; break;
216 case RBE_LOSE_WIS: power = 0; break;
217 case RBE_LOSE_CHR: power = 0; break;
218 case RBE_LOSE_ALL: power = 2; break;
219 case RBE_SHATTER: power = 60; break;
220 case RBE_EXP_10: power = 5; break;
221 case RBE_EXP_20: power = 5; break;
222 case RBE_EXP_40: power = 5; break;
223 case RBE_EXP_80: power = 5; break;
224 case RBE_HALLU: power = 10; break;
228 /* Monster hits player */
229 if (!effect || check_hit(power, rlev))
231 /* Always disturbing */
232 disturb(1, 0);
235 /* Hack -- Apply "protection from evil" */
236 if ((p_ptr->timed[TMD_PROTEVIL] > 0) &&
237 (r_ptr->flags3 & (RF3_EVIL)) &&
238 (p_ptr->lev >= rlev) &&
239 ((rand_int(100) + p_ptr->lev) > 50))
241 /* Remember the Evil-ness */
242 if (m_ptr->ml)
244 l_ptr->flags3 |= (RF3_EVIL);
247 /* Message */
248 msg_format("%^s is repelled.", m_name);
250 /* Hack -- Next attack */
251 continue;
255 /* Assume no cut or stun */
256 do_cut = do_stun = 0;
258 /* Assume no sound */
259 sound_msg = MSG_GENERIC;
261 /* Describe the attack method */
262 switch (method)
264 case RBM_HIT:
266 act = "hits you.";
267 do_cut = do_stun = 1;
268 sound_msg = MSG_MON_HIT;
269 break;
272 case RBM_TOUCH:
274 act = "touches you.";
275 sound_msg = MSG_MON_TOUCH;
276 break;
279 case RBM_PUNCH:
281 act = "punches you.";
282 do_stun = 1;
283 sound_msg = MSG_MON_PUNCH;
284 break;
287 case RBM_KICK:
289 act = "kicks you.";
290 do_stun = 1;
291 sound_msg = MSG_MON_KICK;
292 break;
295 case RBM_CLAW:
297 act = "claws you.";
298 do_cut = 1;
299 sound_msg = MSG_MON_CLAW;
300 break;
303 case RBM_BITE:
305 act = "bites you.";
306 do_cut = 1;
307 sound_msg = MSG_MON_BITE;
308 break;
311 case RBM_STING:
313 act = "stings you.";
314 sound_msg = MSG_MON_STING;
315 break;
318 case RBM_XXX1:
320 act = "XXX1's you.";
321 break;
324 case RBM_BUTT:
326 act = "butts you.";
327 do_stun = 1;
328 sound_msg = MSG_MON_BUTT;
329 break;
332 case RBM_CRUSH:
334 act = "crushes you.";
335 do_stun = 1;
336 sound_msg = MSG_MON_CRUSH;
337 break;
340 case RBM_ENGULF:
342 act = "engulfs you.";
343 sound_msg = MSG_MON_ENGULF;
344 break;
347 case RBM_XXX2:
349 act = "XXX2's you.";
350 break;
353 case RBM_CRAWL:
355 act = "crawls on you.";
356 sound_msg = MSG_MON_CRAWL;
357 break;
360 case RBM_DROOL:
362 act = "drools on you.";
363 sound_msg = MSG_MON_DROOL;
364 break;
367 case RBM_SPIT:
369 act = "spits on you.";
370 sound_msg = MSG_MON_SPIT;
371 break;
374 case RBM_XXX3:
376 act = "XXX3's on you.";
377 break;
380 case RBM_GAZE:
382 act = "gazes at you.";
383 sound_msg = MSG_MON_GAZE;
384 break;
387 case RBM_WAIL:
389 act = "wails at you.";
390 sound_msg = MSG_MON_WAIL;
391 break;
394 case RBM_SPORE:
396 act = "releases spores at you.";
397 sound_msg = MSG_MON_SPORE;
398 break;
401 case RBM_XXX4:
403 act = "projects XXX4's at you.";
404 break;
407 case RBM_BEG:
409 act = "begs you for money.";
410 sound_msg = MSG_MON_BEG;
411 break;
414 case RBM_INSULT:
416 act = desc_insult[rand_int(MAX_DESC_INSULT)];
417 sound_msg = MSG_MON_INSULT;
418 break;
421 case RBM_MOAN:
423 act = desc_moan[rand_int(MAX_DESC_MOAN)];
424 sound_msg = MSG_MON_MOAN;
425 break;
428 case RBM_XXX5:
430 act = "XXX5's you.";
431 break;
435 /* Message */
436 if (act) message_format(sound_msg, 0, "%^s %s", m_name, act);
439 /* Hack -- assume all attacks are obvious */
440 obvious = TRUE;
442 /* Roll out the damage */
443 damage = damroll(d_dice, d_side);
445 /* Apply appropriate damage */
446 switch (effect)
448 case 0:
450 /* Hack -- Assume obvious */
451 obvious = TRUE;
453 /* Hack -- No damage */
454 damage = 0;
456 break;
459 case RBE_HURT:
461 /* Obvious */
462 obvious = TRUE;
464 /* Hack -- Player armor reduces total damage */
465 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
467 /* Take damage */
468 take_hit(damage, ddesc);
470 break;
473 case RBE_POISON:
475 /* Take damage */
476 take_hit(damage, ddesc);
478 /* Take "poison" effect */
479 if (!(p_ptr->resist_pois || p_ptr->timed[TMD_OPP_POIS]))
481 if (inc_timed(TMD_POISONED, randint(rlev) + 5))
483 obvious = TRUE;
487 /* Learn about the player */
488 update_smart_learn(m_idx, DRS_RES_POIS);
490 break;
493 case RBE_UN_BONUS:
495 /* Take damage */
496 take_hit(damage, ddesc);
498 /* Allow complete resist */
499 if (!p_ptr->resist_disen)
501 /* Apply disenchantment */
502 if (apply_disenchant(0)) obvious = TRUE;
505 /* Learn about the player */
506 update_smart_learn(m_idx, DRS_RES_DISEN);
508 break;
511 case RBE_UN_POWER:
513 int drained = 0;
515 /* Take damage */
516 take_hit(damage, ddesc);
518 /* Find an item */
519 for (k = 0; k < 10; k++)
521 /* Pick an item */
522 i = rand_int(INVEN_PACK);
524 /* Obtain the item */
525 o_ptr = &inventory[i];
527 /* Skip non-objects */
528 if (!o_ptr->k_idx) continue;
530 /* Drain charged wands/staves */
531 if ((o_ptr->tval == TV_STAFF) ||
532 (o_ptr->tval == TV_WAND))
534 /* Charged? */
535 if (o_ptr->pval)
537 drained = o_ptr->pval;
539 /* Uncharge */
540 o_ptr->pval = 0;
544 if (drained)
546 int heal = rlev * drained;
548 msg_print("Energy drains from your pack!");
550 obvious = TRUE;
552 /* Don't heal more than max hp */
553 heal = MIN(heal, m_ptr->maxhp - m_ptr->hp);
555 /* Heal */
556 m_ptr->hp += heal;
558 /* Redraw (later) if needed */
559 if (p_ptr->health_who == m_idx)
560 p_ptr->redraw |= (PR_HEALTH);
562 /* Combine / Reorder the pack */
563 p_ptr->notice |= (PN_COMBINE | PN_REORDER);
565 /* Window stuff */
566 p_ptr->window |= (PW_INVEN);
568 /* Affect only a single inventory slot */
569 break;
573 break;
576 case RBE_EAT_GOLD:
578 /* Take damage */
579 take_hit(damage, ddesc);
581 /* Obvious */
582 obvious = TRUE;
584 /* Saving throw (unless paralyzed) based on dex and level */
585 if (!p_ptr->timed[TMD_PARALYZED] &&
586 (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
587 p_ptr->lev)))
589 /* Saving throw message */
590 msg_print("You quickly protect your money pouch!");
592 /* Occasional blink anyway */
593 if (rand_int(3)) blinked = TRUE;
596 /* Eat gold */
597 else
599 gold = (p_ptr->au / 10) + randint(25);
600 if (gold < 2) gold = 2;
601 if (gold > 5000) gold = (p_ptr->au / 20) + randint(3000);
602 if (gold > p_ptr->au) gold = p_ptr->au;
603 p_ptr->au -= gold;
604 if (gold <= 0)
606 msg_print("Nothing was stolen.");
608 else if (p_ptr->au)
610 msg_print("Your purse feels lighter.");
611 msg_format("%ld coins were stolen!", (long)gold);
613 else
615 msg_print("Your purse feels lighter.");
616 msg_print("All of your coins were stolen!");
619 /* Redraw gold */
620 p_ptr->redraw |= (PR_GOLD);
622 /* Window stuff */
623 p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1);
625 /* Blink away */
626 blinked = TRUE;
629 break;
632 case RBE_EAT_ITEM:
634 /* Take damage */
635 take_hit(damage, ddesc);
637 /* Saving throw (unless paralyzed) based on dex and level */
638 if (!p_ptr->timed[TMD_PARALYZED] &&
639 (rand_int(100) < (adj_dex_safe[p_ptr->stat_ind[A_DEX]] +
640 p_ptr->lev)))
642 /* Saving throw message */
643 msg_print("You grab hold of your backpack!");
645 /* Occasional "blink" anyway */
646 blinked = TRUE;
648 /* Obvious */
649 obvious = TRUE;
651 /* Done */
652 break;
655 /* Find an item */
656 for (k = 0; k < 10; k++)
658 object_type *i_ptr;
659 object_type object_type_body;
661 /* Pick an item */
662 i = rand_int(INVEN_PACK);
664 /* Obtain the item */
665 o_ptr = &inventory[i];
667 /* Skip non-objects */
668 if (!o_ptr->k_idx) continue;
670 /* Skip artifacts */
671 if (artifact_p(o_ptr)) continue;
673 /* Get a description */
674 object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 3);
676 /* Message */
677 msg_format("%sour %s (%c) was stolen!",
678 ((o_ptr->number > 1) ? "One of y" : "Y"),
679 o_name, index_to_label(i));
681 /* Get local object */
682 i_ptr = &object_type_body;
684 /* Obtain local object */
685 object_copy(i_ptr, o_ptr);
687 /* Modify number */
688 i_ptr->number = 1;
690 /* Hack -- If a rod, staff, or wand, allocate total
691 * maximum timeouts or charges between those
692 * stolen and those missed. -LM-
694 distribute_charges(o_ptr, i_ptr, 1);
696 /* Carry the object */
697 (void)monster_carry(m_idx, i_ptr);
699 /* Steal the items */
700 inven_item_increase(i, -1);
701 inven_item_optimize(i);
703 /* Obvious */
704 obvious = TRUE;
706 /* Blink away */
707 blinked = TRUE;
709 /* Done */
710 break;
713 break;
716 case RBE_EAT_FOOD:
718 /* Take damage */
719 take_hit(damage, ddesc);
721 /* Steal some food */
722 for (k = 0; k < 10; k++)
724 /* Pick an item from the pack */
725 i = rand_int(INVEN_PACK);
727 /* Get the item */
728 o_ptr = &inventory[i];
730 /* Skip non-objects */
731 if (!o_ptr->k_idx) continue;
733 /* Skip non-food objects */
734 if (o_ptr->tval != TV_FOOD) continue;
736 /* Get a description */
737 object_desc(o_name, sizeof(o_name), o_ptr, FALSE, 0);
739 /* Message */
740 msg_format("%sour %s (%c) was eaten!",
741 ((o_ptr->number > 1) ? "One of y" : "Y"),
742 o_name, index_to_label(i));
744 /* Steal the items */
745 inven_item_increase(i, -1);
746 inven_item_optimize(i);
748 /* Obvious */
749 obvious = TRUE;
751 /* Done */
752 break;
755 break;
758 case RBE_EAT_LITE:
760 u32b f1, f2, f3;
762 /* Take damage */
763 take_hit(damage, ddesc);
765 /* Get the lite, and its flags */
766 o_ptr = &inventory[INVEN_LITE];
767 object_flags(o_ptr, &f1, &f2, &f3);
769 /* Drain fuel where applicable */
770 if (!(f3 & TR3_NO_FUEL) && (o_ptr->timeout > 0))
772 /* Reduce fuel */
773 o_ptr->timeout -= (250 + randint(250));
774 if (o_ptr->timeout < 1) o_ptr->timeout = 1;
776 /* Notice */
777 if (!p_ptr->timed[TMD_BLIND])
779 msg_print("Your light dims.");
780 obvious = TRUE;
783 /* Window stuff */
784 p_ptr->window |= (PW_EQUIP);
787 break;
790 case RBE_ACID:
792 /* Obvious */
793 obvious = TRUE;
795 /* Message */
796 msg_print("You are covered in acid!");
798 /* Special damage */
799 acid_dam(damage, ddesc);
801 /* Learn about the player */
802 update_smart_learn(m_idx, DRS_RES_ACID);
804 break;
807 case RBE_ELEC:
809 /* Obvious */
810 obvious = TRUE;
812 /* Message */
813 msg_print("You are struck by electricity!");
815 /* Take damage (special) */
816 elec_dam(damage, ddesc);
818 /* Learn about the player */
819 update_smart_learn(m_idx, DRS_RES_ELEC);
821 break;
824 case RBE_FIRE:
826 /* Obvious */
827 obvious = TRUE;
829 /* Message */
830 msg_print("You are enveloped in flames!");
832 /* Take damage (special) */
833 fire_dam(damage, ddesc);
835 /* Learn about the player */
836 update_smart_learn(m_idx, DRS_RES_FIRE);
838 break;
841 case RBE_COLD:
843 /* Obvious */
844 obvious = TRUE;
846 /* Message */
847 msg_print("You are covered with frost!");
849 /* Take damage (special) */
850 cold_dam(damage, ddesc);
852 /* Learn about the player */
853 update_smart_learn(m_idx, DRS_RES_COLD);
855 break;
858 case RBE_BLIND:
860 /* Take damage */
861 take_hit(damage, ddesc);
863 /* Increase "blind" */
864 if (!p_ptr->resist_blind)
866 if (inc_timed(TMD_BLIND, 10 + randint(rlev)))
868 obvious = TRUE;
872 /* Learn about the player */
873 update_smart_learn(m_idx, DRS_RES_BLIND);
875 break;
878 case RBE_CONFUSE:
880 /* Take damage */
881 take_hit(damage, ddesc);
883 /* Increase "confused" */
884 if (!p_ptr->resist_confu)
886 if (inc_timed(TMD_CONFUSED, 3 + randint(rlev)))
888 obvious = TRUE;
892 /* Learn about the player */
893 update_smart_learn(m_idx, DRS_RES_CONFU);
895 break;
898 case RBE_TERRIFY:
900 /* Take damage */
901 take_hit(damage, ddesc);
903 /* Increase "afraid" */
904 if (p_ptr->resist_fear)
906 msg_print("You stand your ground!");
907 obvious = TRUE;
909 else if (rand_int(100) < p_ptr->skills[SKILL_SAV])
911 msg_print("You stand your ground!");
912 obvious = TRUE;
914 else
916 if (inc_timed(TMD_AFRAID, 3 + randint(rlev)))
918 obvious = TRUE;
922 /* Learn about the player */
923 update_smart_learn(m_idx, DRS_RES_FEAR);
925 break;
928 case RBE_PARALYZE:
930 /* Hack -- Prevent perma-paralysis via damage */
931 if (p_ptr->timed[TMD_PARALYZED] && (damage < 1)) damage = 1;
933 /* Take damage */
934 take_hit(damage, ddesc);
936 /* Increase "paralyzed" */
937 if (p_ptr->free_act)
939 msg_print("You are unaffected!");
940 obvious = TRUE;
942 else if (rand_int(100) < p_ptr->skills[SKILL_SAV])
944 msg_print("You resist the effects!");
945 obvious = TRUE;
947 else
949 if (inc_timed(TMD_PARALYZED, 3 + randint(rlev)))
951 obvious = TRUE;
955 /* Learn about the player */
956 update_smart_learn(m_idx, DRS_FREE);
958 break;
961 case RBE_LOSE_STR:
963 /* Take damage */
964 take_hit(damage, ddesc);
966 /* Damage (stat) */
967 if (do_dec_stat(A_STR)) obvious = TRUE;
969 break;
972 case RBE_LOSE_INT:
974 /* Take damage */
975 take_hit(damage, ddesc);
977 /* Damage (stat) */
978 if (do_dec_stat(A_INT)) obvious = TRUE;
980 break;
983 case RBE_LOSE_WIS:
985 /* Take damage */
986 take_hit(damage, ddesc);
988 /* Damage (stat) */
989 if (do_dec_stat(A_WIS)) obvious = TRUE;
991 break;
994 case RBE_LOSE_DEX:
996 /* Take damage */
997 take_hit(damage, ddesc);
999 /* Damage (stat) */
1000 if (do_dec_stat(A_DEX)) obvious = TRUE;
1002 break;
1005 case RBE_LOSE_CON:
1007 /* Take damage */
1008 take_hit(damage, ddesc);
1010 /* Damage (stat) */
1011 if (do_dec_stat(A_CON)) obvious = TRUE;
1013 break;
1016 case RBE_LOSE_CHR:
1018 /* Take damage */
1019 take_hit(damage, ddesc);
1021 /* Damage (stat) */
1022 if (do_dec_stat(A_CHR)) obvious = TRUE;
1024 break;
1027 case RBE_LOSE_ALL:
1029 /* Take damage */
1030 take_hit(damage, ddesc);
1032 /* Damage (stats) */
1033 if (do_dec_stat(A_STR)) obvious = TRUE;
1034 if (do_dec_stat(A_DEX)) obvious = TRUE;
1035 if (do_dec_stat(A_CON)) obvious = TRUE;
1036 if (do_dec_stat(A_INT)) obvious = TRUE;
1037 if (do_dec_stat(A_WIS)) obvious = TRUE;
1038 if (do_dec_stat(A_CHR)) obvious = TRUE;
1040 break;
1043 case RBE_SHATTER:
1045 /* Obvious */
1046 obvious = TRUE;
1048 /* Hack -- Reduce damage based on the player armor class */
1049 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
1051 /* Take damage */
1052 take_hit(damage, ddesc);
1054 /* Radius 8 earthquake centered at the monster */
1055 if (damage > 23)
1057 int px_old = p_ptr->px;
1058 int py_old = p_ptr->py;
1060 earthquake(m_ptr->fy, m_ptr->fx, 8);
1062 /* Stop the blows if the player is pushed away */
1063 if ((px_old != p_ptr->px) ||
1064 (py_old != p_ptr->py))
1065 do_break = TRUE;
1067 break;
1070 case RBE_EXP_10:
1072 /* Obvious */
1073 obvious = TRUE;
1075 /* Take damage */
1076 take_hit(damage, ddesc);
1078 if (p_ptr->hold_life && (rand_int(100) < 95))
1080 msg_print("You keep hold of your life force!");
1082 else
1084 s32b d = damroll(10, 6) + (p_ptr->exp/100) * MON_DRAIN_LIFE;
1085 if (p_ptr->hold_life)
1087 msg_print("You feel your life slipping away!");
1088 lose_exp(d/10);
1090 else
1092 msg_print("You feel your life draining away!");
1093 lose_exp(d);
1096 break;
1099 case RBE_EXP_20:
1101 /* Obvious */
1102 obvious = TRUE;
1104 /* Take damage */
1105 take_hit(damage, ddesc);
1107 if (p_ptr->hold_life && (rand_int(100) < 90))
1109 msg_print("You keep hold of your life force!");
1111 else
1113 s32b d = damroll(20, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE;
1115 if (p_ptr->hold_life)
1117 msg_print("You feel your life slipping away!");
1118 lose_exp(d / 10);
1120 else
1122 msg_print("You feel your life draining away!");
1123 lose_exp(d);
1126 break;
1129 case RBE_EXP_40:
1131 /* Obvious */
1132 obvious = TRUE;
1134 /* Take damage */
1135 take_hit(damage, ddesc);
1137 if (p_ptr->hold_life && (rand_int(100) < 75))
1139 msg_print("You keep hold of your life force!");
1141 else
1143 s32b d = damroll(40, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE;
1145 if (p_ptr->hold_life)
1147 msg_print("You feel your life slipping away!");
1148 lose_exp(d / 10);
1150 else
1152 msg_print("You feel your life draining away!");
1153 lose_exp(d);
1156 break;
1159 case RBE_EXP_80:
1161 /* Obvious */
1162 obvious = TRUE;
1164 /* Take damage */
1165 take_hit(damage, ddesc);
1167 if (p_ptr->hold_life && (rand_int(100) < 50))
1169 msg_print("You keep hold of your life force!");
1171 else
1173 s32b d = damroll(80, 6) + (p_ptr->exp / 100) * MON_DRAIN_LIFE;
1175 if (p_ptr->hold_life)
1177 msg_print("You feel your life slipping away!");
1178 lose_exp(d / 10);
1180 else
1182 msg_print("You feel your life draining away!");
1183 lose_exp(d);
1186 break;
1189 case RBE_HALLU:
1191 /* Take damage */
1192 take_hit(damage, ddesc);
1194 /* Increase "image" */
1195 if (!p_ptr->resist_chaos)
1197 if (inc_timed(TMD_IMAGE, 3 + randint(rlev / 2)))
1199 obvious = TRUE;
1203 /* Learn about the player */
1204 update_smart_learn(m_idx, DRS_RES_CHAOS);
1206 break;
1211 /* Hack -- only one of cut or stun */
1212 if (do_cut && do_stun)
1214 /* Cancel cut */
1215 if (rand_int(100) < 50)
1217 do_cut = 0;
1220 /* Cancel stun */
1221 else
1223 do_stun = 0;
1227 /* Handle cut */
1228 if (do_cut)
1230 int k;
1232 /* Critical hit (zero if non-critical) */
1233 tmp = monster_critical(d_dice, d_side, damage);
1235 /* Roll for damage */
1236 switch (tmp)
1238 case 0: k = 0; break;
1239 case 1: k = randint(5); break;
1240 case 2: k = randint(5) + 5; break;
1241 case 3: k = randint(20) + 20; break;
1242 case 4: k = randint(50) + 50; break;
1243 case 5: k = randint(100) + 100; break;
1244 case 6: k = 300; break;
1245 default: k = 500; break;
1248 /* Apply the cut */
1249 if (k) (void)inc_timed(TMD_CUT, k);
1252 /* Handle stun */
1253 if (do_stun)
1255 int k;
1257 /* Critical hit (zero if non-critical) */
1258 tmp = monster_critical(d_dice, d_side, damage);
1260 /* Roll for damage */
1261 switch (tmp)
1263 case 0: k = 0; break;
1264 case 1: k = randint(5); break;
1265 case 2: k = randint(10) + 10; break;
1266 case 3: k = randint(20) + 20; break;
1267 case 4: k = randint(30) + 30; break;
1268 case 5: k = randint(40) + 40; break;
1269 case 6: k = 100; break;
1270 default: k = 200; break;
1273 /* Apply the stun */
1274 if (k) (void)inc_timed(TMD_STUN, k);
1278 /* Monster missed player */
1279 else
1281 /* Analyze failed attacks */
1282 switch (method)
1284 case RBM_HIT:
1285 case RBM_TOUCH:
1286 case RBM_PUNCH:
1287 case RBM_KICK:
1288 case RBM_CLAW:
1289 case RBM_BITE:
1290 case RBM_STING:
1291 case RBM_XXX1:
1292 case RBM_BUTT:
1293 case RBM_CRUSH:
1294 case RBM_ENGULF:
1295 case RBM_XXX2:
1297 /* Visible monsters */
1298 if (m_ptr->ml)
1300 /* Disturbing */
1301 disturb(1, 0);
1303 /* Message */
1304 msg_format("%^s misses you.", m_name);
1307 break;
1312 /* Analyze "visible" monsters only */
1313 if (visible)
1315 /* Count "obvious" attacks (and ones that cause damage) */
1316 if (obvious || damage || (l_ptr->blows[ap_cnt] > 10))
1318 /* Count attacks of this type */
1319 if (l_ptr->blows[ap_cnt] < MAX_UCHAR)
1321 l_ptr->blows[ap_cnt]++;
1326 /* Skip the other blows if necessary */
1327 if (do_break) break;
1331 /* Blink away */
1332 if (blinked)
1334 msg_print("There is a puff of smoke!");
1335 teleport_away(m_idx, MAX_SIGHT * 2 + 5);
1339 /* Always notice cause of death */
1340 if (p_ptr->is_dead && (l_ptr->deaths < MAX_SHORT))
1342 l_ptr->deaths++;
1346 /* Assume we attacked */
1347 return (TRUE);