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