root/trunk/src/attack.c

Revision 986, 22.4 kB (checked in by takkaria, 21 hours ago)

Do what I meant to do in r840/r841. (Make missile launchers as powerful as they were.)

  • Property svn:eol-style set to native
Line 
1 /*
2  * File: attack.c
3  * Purpose: Attacking (both throwing and melee) code
4  *
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 #include "angband.h"
19 #include "tvalsval.h"
20
21
22 /*
23  * Determines the odds of an object breaking when thrown at a monster
24  *
25  * Note that artifacts never break, see the "drop_near()" function.
26  */
27 int breakage_chance(const object_type *o_ptr)
28 {
29         /* Examine the item type */
30         switch (o_ptr->tval)
31         {
32                 /* Always break */
33                 case TV_FLASK:
34                 case TV_POTION:
35                 case TV_BOTTLE:
36                 case TV_FOOD:
37                 case TV_JUNK:
38                 {
39                         return (100);
40                 }
41
42                 /* Often break */
43                 case TV_LITE:
44                 case TV_SCROLL:
45                 case TV_SKELETON:
46                 {
47                         return (50);
48                 }
49
50                 /* Sometimes break */
51                 case TV_ARROW:
52                 {
53                         return (35);
54                 }
55
56                 /* Sometimes break */
57                 case TV_WAND:
58                 case TV_SHOT:
59                 case TV_BOLT:
60                 case TV_SPIKE:
61                 {
62                         return (25);
63                 }
64         }
65
66         /* Rarely break */
67         return (10);
68 }
69
70
71 /*
72  * Determine if the player "hits" a monster.
73  *
74  * Note -- Always miss 5%, always hit 5%, otherwise random.
75  */
76 bool test_hit(int chance, int ac, int vis)
77 {
78         int k;
79
80         /* Percentile dice */
81         k = randint0(100);
82
83         /* Hack -- Instant miss or hit */
84         if (k < 10) return (k < 5);
85
86         /* Penalize invisible targets */
87         if (!vis) chance = chance / 2;
88
89         /* Power competes against armor */
90         if ((chance > 0) && (randint0(chance) >= (ac * 3 / 4))) return (TRUE);
91
92         /* Assume miss */
93         return (FALSE);
94 }
95
96
97
98 /*
99  * Critical hits (from objects thrown by player)
100  * Factor in item weight, total plusses, and player level.
101  */
102 static int critical_shot(int weight, int plus, int dam)
103 {
104         int i, k;
105
106         /* Extract "shot" power */
107         i = (weight + ((p_ptr->to_h + plus) * 4) + (p_ptr->lev * 2));
108
109         /* Critical hit */
110         if (randint1(5000) <= i)
111         {
112                 k = weight + randint1(500);
113
114                 if (k < 500)
115                 {
116                         msg_print("It was a good hit!");
117                         dam = 2 * dam + 5;
118                 }
119                 else if (k < 1000)
120                 {
121                         msg_print("It was a great hit!");
122                         dam = 2 * dam + 10;
123                 }
124                 else
125                 {
126                         msg_print("It was a superb hit!");
127                         dam = 3 * dam + 15;
128                 }
129         }
130
131         return (dam);
132 }
133
134
135
136 /*
137  * Critical hits (by player)
138  *
139  * Factor in weapon weight, total plusses, player level.
140  */
141 static int critical_norm(int weight, int plus, int dam)
142 {
143         int i, k;
144
145         /* Extract "blow" power */
146         i = (weight + ((p_ptr->to_h + plus) * 5) + (p_ptr->lev * 3));
147
148         /* Chance */
149         if (randint1(5000) <= i)
150         {
151                 k = weight + randint1(650);
152
153                 if (k < 400)
154                 {
155                         sound(MSG_HIT_GOOD);
156                         msg_print("It was a good hit!");
157                         dam = 2 * dam + 5;
158                 }
159                 else if (k < 700)
160                 {
161                         sound(MSG_HIT_GREAT);
162                         msg_print("It was a great hit!");
163                         dam = 2 * dam + 10;
164                 }
165                 else if (k < 900)
166                 {
167                         sound(MSG_HIT_SUPERB);
168                         msg_print("It was a superb hit!");
169                         dam = 3 * dam + 15;
170                 }
171                 else if (k < 1300)
172                 {
173                         sound(MSG_HIT_HI_GREAT);
174                         msg_print("It was a *GREAT* hit!");
175                         dam = 3 * dam + 20;
176                 }
177                 else
178                 {
179                         sound(MSG_HIT_HI_SUPERB);
180                         msg_print("It was a *SUPERB* hit!");
181                         dam = ((7 * dam) / 2) + 25;
182                 }
183         }
184         else
185         {
186                 sound(MSG_HIT);
187         }
188
189         return (dam);
190 }
191
192
193
194 /*
195  * Extract the "multiplier" from a given object hitting a given monster.
196  *
197  * Most brands and slays are x3, except Slay Animal (x2), Slay Evil (x2),
198  * and Kill dragon (x5).
199  */
200 static int tot_dam_aux(const object_type *o_ptr, const monster_type *m_ptr)
201 {
202         int mult = 1;
203
204         monster_race *r_ptr = &r_info[m_ptr->r_idx];
205         monster_lore *l_ptr = &l_list[m_ptr->r_idx];
206
207         u32b f1, f2, f3;
208
209         /* Extract the flags */
210         object_flags(o_ptr, &f1, &f2, &f3);
211
212
213         /* Slay Animal */
214         if ((f1 & TR1_SLAY_ANIMAL) && (r_ptr->flags[2] & RF2_ANIMAL))
215         {
216                 if (m_ptr->ml)
217                         l_ptr->flags[2] |= (RF2_ANIMAL);
218
219                 if (mult < 2) mult = 2;
220         }
221
222         /* Slay Evil */
223         if ((f1 & TR1_SLAY_EVIL) && (r_ptr->flags[2] & RF2_EVIL))
224         {
225                 if (m_ptr->ml)
226                         l_ptr->flags[2] |= (RF2_EVIL);
227
228                 if (mult < 2) mult = 2;
229         }
230
231         /* Slay Undead */
232         if ((f1 & TR1_SLAY_UNDEAD) && (r_ptr->flags[2] & RF2_UNDEAD))
233         {
234                 if (m_ptr->ml)
235                         l_ptr->flags[2] |= (RF2_UNDEAD);
236
237                 if (mult < 3) mult = 3;
238         }
239
240         /* Slay Demon */
241         if ((f1 & TR1_SLAY_DEMON) && (r_ptr->flags[2] & RF2_DEMON))
242         {
243                 if (m_ptr->ml)
244                         l_ptr->flags[2] |= (RF2_DEMON);
245
246                 if (mult < 3) mult = 3;
247         }
248
249         /* Slay Orc */
250         if ((f1 & TR1_SLAY_ORC) && (r_ptr->flags[2] & RF2_ORC))
251         {
252                 if (m_ptr->ml)
253                         l_ptr->flags[2] |= (RF2_ORC);
254
255                 if (mult < 3) mult = 3;
256         }
257
258         /* Slay Troll */
259         if ((f1 & TR1_SLAY_TROLL) && (r_ptr->flags[2] & RF2_TROLL))
260         {
261                 if (m_ptr->ml)
262                         l_ptr->flags[2] |= (RF2_TROLL);
263
264                 if (mult < 3) mult = 3;
265         }
266
267         /* Slay Giant */
268         if ((f1 & TR1_SLAY_GIANT) && (r_ptr->flags[2] & RF2_GIANT))
269         {
270                 if (m_ptr->ml)
271                         l_ptr->flags[2] |= (RF2_GIANT);
272
273                 if (mult < 3) mult = 3;
274         }
275
276         /* Slay Dragon */
277         if ((f1 & TR1_SLAY_DRAGON) && (r_ptr->flags[2] & RF2_DRAGON))
278         {
279                 if (m_ptr->ml)
280                         l_ptr->flags[2] |= (RF2_DRAGON);
281
282                 if (mult < 3) mult = 3;
283         }
284
285         /* Execute Dragon */
286         if ((f1 & TR1_KILL_DRAGON) && (r_ptr->flags[2] & RF2_DRAGON))
287         {
288                 if (m_ptr->ml)
289                         l_ptr->flags[2] |= (RF2_DRAGON);
290
291                 if (mult < 5) mult = 5;
292         }
293
294         /* Execute demon */
295         if ((f1 & TR1_KILL_DEMON) && (r_ptr->flags[2] & RF2_DEMON))
296         {
297                 if (m_ptr->ml)
298                         l_ptr->flags[2] |= (RF2_DEMON);
299
300                 if (mult < 5) mult = 5;
301         }
302
303         /* Execute undead */
304         if ((f1 & TR1_KILL_UNDEAD) && (r_ptr->flags[2] & RF2_UNDEAD))
305         {
306                 if (m_ptr->ml)
307                         l_ptr->flags[2] |= (RF2_UNDEAD);
308
309                 if (mult < 5) mult = 5;
310         }
311
312         /* Brand (Acid) */
313         if (f1 & (TR1_BRAND_ACID))
314         {
315                 /* Notice immunity */
316                 if (r_ptr->flags[2] & (RF2_IM_ACID))
317                 {
318                         if (m_ptr->ml)
319                                 l_ptr->flags[2] |= (RF2_IM_ACID);
320                 }
321
322                 /* Otherwise, take the damage */
323                 else
324                 {
325                         if (mult < 3) mult = 3;
326                 }
327         }
328
329         /* Brand (Elec) */
330         if (f1 & (TR1_BRAND_ELEC))
331         {
332                 /* Notice immunity */
333                 if (r_ptr->flags[2] & (RF2_IM_ELEC))
334                 {
335                         if (m_ptr->ml)
336                                 l_ptr->flags[2] |= (RF2_IM_ELEC);
337                 }
338
339                 /* Otherwise, take the damage */
340                 else
341                 {
342                         if (mult < 3) mult = 3;
343                 }
344         }
345
346         /* Brand (Fire) */
347         if (f1 & (TR1_BRAND_FIRE))
348         {
349                 /* Notice immunity */
350                 if (r_ptr->flags[2] & (RF2_IM_FIRE))
351                 {
352                         if (m_ptr->ml)
353                                 l_ptr->flags[2] |= (RF2_IM_FIRE);
354                 }
355
356                 /* Otherwise, take the damage */
357                 else
358                 {
359                         if (mult < 3) mult = 3;
360                 }
361         }
362
363         /* Brand (Cold) */
364         if (f1 & (TR1_BRAND_COLD))
365         {
366                 /* Notice immunity */
367                 if (r_ptr->flags[2] & (RF2_IM_COLD))
368                 {
369                         if (m_ptr->ml)
370                                 l_ptr->flags[2] |= (RF2_IM_COLD);
371                 }
372
373                 /* Otherwise, take the damage */
374                 else
375                 {
376                         if (mult < 3) mult = 3;
377                 }
378         }
379
380         /* Brand (Poison) */
381         if (f1 & (TR1_BRAND_POIS))
382         {
383                 /* Notice immunity */
384                 if (r_ptr->flags[2] & (RF2_IM_POIS))
385                 {
386                         if (m_ptr->ml)
387                                 l_ptr->flags[2] |= (RF2_IM_POIS);
388                 }
389
390                 /* Otherwise, take the damage */
391                 else
392                 {
393                         if (mult < 3) mult = 3;
394                 }
395         }
396
397
398         /* Return the multiplier */
399         return (mult);
400 }
401
402
403
404 /*
405  * Attack the monster at the given location
406  *
407  * If no "weapon" is available, then "punch" the monster one time.
408  */
409 void py_attack(int y, int x)
410 {
411         int num = 0, k, bonus, chance;
412
413         monster_type *m_ptr;
414         monster_race *r_ptr;
415         monster_lore *l_ptr;
416
417         object_type *o_ptr;
418
419         char m_name[80];
420
421         bool fear = FALSE;
422
423         bool do_quake = FALSE;
424
425
426         /* Get the monster */
427         m_ptr = &mon_list[cave_m_idx[y][x]];
428         r_ptr = &r_info[m_ptr->r_idx];
429         l_ptr = &l_list[m_ptr->r_idx];
430
431
432         /* Disturb the player */
433         disturb(0, 0);
434
435
436         /* Disturb the monster */
437         m_ptr->csleep = 0;
438
439
440         /* Extract monster name (or "it") */
441         monster_desc(m_name, sizeof(m_name), m_ptr, 0);
442
443
444         /* Auto-Recall if possible and visible */
445         if (m_ptr->ml) monster_race_track(m_ptr->r_idx);
446
447         /* Track a new monster */
448         if (m_ptr->ml) health_track(cave_m_idx[y][x]);
449
450
451         /* Handle player fear */
452         if (p_ptr->afraid)
453         {
454                 /* Message */
455                 msg_format("You are too afraid to attack %s!", m_name);
456
457                 /* Done */
458                 return;
459         }
460
461
462         /* Get the weapon */
463         o_ptr = &inventory[INVEN_WIELD];
464
465         /* Calculate the "attack quality" */
466         bonus = p_ptr->to_h + o_ptr->to_h;
467         chance = (p_ptr->skills[SKILL_TO_HIT_MELEE] + (bonus * BTH_PLUS_ADJ));
468
469
470         /* Attack once for each legal blow */
471         while (num++ < p_ptr->num_blow)
472         {
473                 /* Test for hit */
474                 if (test_hit(chance, r_ptr->ac, m_ptr->ml))
475                 {
476                         /* Message */
477                         message_format(MSG_GENERIC, m_ptr->r_idx, "You hit %s.", m_name);
478
479                         /* Hack -- bare hands do one damage */
480                         k = 1;
481
482                         /* Handle normal weapon */
483                         if (o_ptr->k_idx)
484                         {
485                                 k = damroll(o_ptr->dd, o_ptr->ds);
486                                 k *= tot_dam_aux(o_ptr, m_ptr);
487                                 if (p_ptr->impact && (k > 50)) do_quake = TRUE;
488                                 k += o_ptr->to_d;
489                                 k = critical_norm(o_ptr->weight, o_ptr->to_h, k);
490                         }
491
492                         /* Apply the player damage bonuses */
493                         k += p_ptr->to_d;
494
495                         /* No negative damage */
496                         if (k < 0) k = 0;
497
498                         /* Complex message */
499                         if (p_ptr->wizard)
500                         {
501                                 msg_format("You do %d (out of %d) damage.", k, m_ptr->hp);
502                         }
503
504                         /* Damage, check for fear and death */
505                         if (mon_take_hit(cave_m_idx[y][x], k, &fear, NULL)) break;
506
507                         /* Confusion attack */
508                         if (p_ptr->confusing)
509                         {
510                                 /* Cancel glowing hands */
511                                 p_ptr->confusing = FALSE;
512
513                                 /* Message */
514                                 msg_print("Your hands stop glowing.");
515
516                                 /* Confuse the monster */
517                                 if (r_ptr->flags[2] & (RF2_NO_CONF))
518                                 {
519                                         if (m_ptr->ml)
520                                         {
521                                                 l_ptr->flags[2] |= (RF2_NO_CONF);
522                                         }
523
524                                         msg_format("%^s is unaffected.", m_name);
525                                 }
526                                 else if (randint0(100) < r_ptr->level)
527                                 {
528                                         msg_format("%^s is unaffected.", m_name);
529                                 }
530                                 else
531                                 {
532                                         msg_format("%^s appears confused.", m_name);
533                                         m_ptr->confused += 10 + randint0(p_ptr->lev) / 5;
534                                 }
535                         }
536                 }
537
538                 /* Player misses */
539                 else
540                 {
541                         /* Message */
542                         message_format(MSG_MISS, m_ptr->r_idx, "You miss %s.", m_name);
543                 }
544         }
545
546
547         /* Hack -- delay fear messages */
548         if (fear && m_ptr->ml)
549         {
550                 /* Message */
551                 message_format(MSG_FLEE, m_ptr->r_idx, "%^s flees in terror!", m_name);
552         }
553
554
555         /* Mega-Hack -- apply earthquake brand */
556         if (do_quake) earthquake(p_ptr->py, p_ptr->px, 10);
557 }
558
559
560
561
562
563 /*
564  * Fire an object from the pack or floor.
565  *
566  * You may only fire items that "match" your missile launcher.
567  *
568  * See "calc_bonuses()" for more calculations and such.
569  *
570  * Note that "firing" a missile is MUCH better than "throwing" it.
571  *
572  * Note: "unseen" monsters are very hard to hit.
573  *
574  * Objects are more likely to break if they "attempt" to hit a monster.
575  *
576  * Rangers (with Bows) and Anyone (with "Extra Shots") get extra shots.
577  * The "extra shot" code works by decreasing the amount of energy
578  * required to make each shot, spreading the shots out over time.
579  *
580  * Note that when firing missiles, the launcher multiplier is applied
581  * after all the bonuses are added in, making multipliers very useful.
582  *
583  * Note that Bows of "Extra Might" get extra range and an extra bonus
584  * for the damage multiplier.
585  */
586 void do_cmd_fire(void)
587 {
588         int dir, item;
589         int i, j, y, x;
590         s16b ty, tx;
591         int tdam, tdis, thits;
592         int bonus, chance;
593
594         object_type *o_ptr;
595         object_type *j_ptr;
596
597         object_type *i_ptr;
598         object_type object_type_body;
599
600         bool hit_body = FALSE;
601
602         byte missile_attr;
603         char missile_char;
604
605         char o_name[80];
606
607         int path_n;
608         u16b path_g[256];
609
610         cptr q, s;
611
612         int msec = op_ptr->delay_factor * op_ptr->delay_factor;
613
614
615         /* Get the "bow" (if any) */
616         j_ptr = &inventory[INVEN_BOW];
617
618         /* Require a usable launcher */
619         if (!j_ptr->tval || !p_ptr->ammo_tval)
620         {
621                 msg_print("You have nothing to fire with.");
622                 return;
623         }
624
625
626         /* Require proper missile */
627         item_tester_tval = p_ptr->ammo_tval;
628
629         /* Get an item */
630         q = "Fire which item? ";
631         s = "You have nothing to fire.";
632         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
633
634         /* Get the object */
635         if (item >= 0)
636         {
637                 o_ptr = &inventory[item];
638         }
639         else
640         {
641                 o_ptr = &o_list[0 - item];
642         }
643
644
645         /* Get a direction (or cancel) */
646         if (!get_aim_dir(&dir)) return;
647
648
649         /* Get local object */
650         i_ptr = &object_type_body;
651
652         /* Obtain a local object */
653         object_copy(i_ptr, o_ptr);
654
655         /* Single object */
656         i_ptr->number = 1;
657
658         /* Reduce and describe inventory */
659         if (item >= 0)
660         {
661                 inven_item_increase(item, -1);
662                 inven_item_describe(item);
663                 inven_item_optimize(item);
664         }
665
666         /* Reduce and describe floor item */
667         else
668         {
669                 floor_item_increase(0 - item, -1);
670                 floor_item_optimize(0 - item);
671         }
672
673
674         /* Sound */
675         sound(MSG_SHOOT);
676
677
678         /* Describe the object */
679         object_desc(o_name, sizeof(o_name), i_ptr, FALSE, ODESC_FULL);
680
681         /* Find the color and symbol for the object for throwing */
682         missile_attr = object_attr(i_ptr);
683         missile_char = object_char(i_ptr);
684
685
686         /* Use the proper number of shots */
687         thits = p_ptr->num_fire;
688
689         /* Actually "fire" the object */
690         bonus = (p_ptr->to_h + i_ptr->to_h + j_ptr->to_h);
691         chance = (p_ptr->skills[SKILL_TO_HIT_BOW] + (bonus * BTH_PLUS_ADJ));
692
693         /* Base range XXX XXX */
694         tdis = 6 + 2 * p_ptr->ammo_mult;
695
696
697         /* Take a (partial) turn */
698         p_ptr->energy_use = (100 / thits);
699
700
701         /* Start at the player */
702         y = p_ptr->py;
703         x = p_ptr->px;
704
705         /* Predict the "target" location */
706         ty = p_ptr->py + 99 * ddy[dir];
707         tx = p_ptr->px + 99 * ddx[dir];
708
709         /* Check for "target request" */
710         if ((dir == 5) && target_okay())
711         {
712                 target_get(&tx, &ty);
713         }
714
715         /* Calculate the path */
716         path_n = project_path(path_g, tdis, p_ptr->py, p_ptr->px, ty, tx, 0);
717
718
719         /* Hack -- Handle stuff */
720         handle_stuff();
721
722         /* Project along the path */
723         for (i = 0; i < path_n; ++i)
724         {
725                 int ny = GRID_Y(path_g[i]);
726                 int nx = GRID_X(path_g[i]);
727
728                 /* Hack -- Stop before hitting walls */
729                 if (!cave_floor_bold(ny, nx)) break;
730
731                 /* Advance */
732                 x = nx;
733                 y = ny;
734
735                 /* Only do visuals if the player can "see" the missile */
736                 if (player_can_see_bold(y, x))
737                 {
738                         /* Visual effects */
739                         print_rel(missile_char, missile_attr, y, x);
740                         move_cursor_relative(y, x);
741
742                         Term_fresh();
743                         if (p_ptr->redraw) redraw_stuff();
744
745                         Term_xtra(TERM_XTRA_DELAY, msec);
746                         lite_spot(y, x);
747
748                         Term_fresh();
749                         if (p_ptr->redraw) redraw_stuff();
750                 }
751
752                 /* Delay anyway for consistency */
753                 else
754                 {
755                         /* Pause anyway, for consistancy */
756                         Term_xtra(TERM_XTRA_DELAY, msec);
757                 }
758
759                 /* Handle monster */
760                 if (cave_m_idx[y][x] > 0)
761                 {
762                         monster_type *m_ptr = &mon_list[cave_m_idx[y][x]];
763                         monster_race *r_ptr = &r_info[m_ptr->r_idx];
764
765                         int chance2 = chance - distance(p_ptr->py, p_ptr->px, y, x);
766
767                         int visible = m_ptr->ml;
768
769                         int ammo_mult = tot_dam_aux(i_ptr, m_ptr);
770                         int shoot_mult = tot_dam_aux(j_ptr, m_ptr);
771
772                         /* Note the collision */
773                         hit_body = TRUE;
774
775                         /* Did we hit it (penalize distance travelled) */
776                         if (test_hit(chance2, r_ptr->ac, m_ptr->ml))
777                         {
778                                 bool fear = FALSE;
779
780                                 /* Assume a default death */
781                                 cptr note_dies = " dies.";
782
783                                 /* Some monsters get "destroyed" */
784                                 if ((r_ptr->flags[2] & (RF2_DEMON)) ||
785                                     (r_ptr->flags[2] & (RF2_UNDEAD)) ||
786                                     (r_ptr->flags[1] & (RF1_STUPID)) ||
787                                     (strchr("Evg", r_ptr->d_char)))
788                                 {
789                                         /* Special note at death */
790                                         note_dies = " is destroyed.";
791                                 }
792
793
794                                 /* Handle unseen monster */
795                                 if (!visible)
796                                 {
797                                         /* Invisible monster */
798                                         message_format(MSG_SHOOT_HIT, 0, "The %s finds a mark.", o_name);
799                                 }
800
801                                 /* Handle visible monster */
802                                 else
803                                 {
804                                         char m_name[80];
805
806                                         /* Get "the monster" or "it" */
807                                         monster_desc(m_name, sizeof(m_name), m_ptr, 0);
808
809                                         /* Message */
810                                         message_format(MSG_SHOOT_HIT, 0, "The %s hits %s.", o_name, m_name);
811
812                                         /* Hack -- Track this monster race */
813                                         if (m_ptr->ml) monster_race_track(m_ptr->r_idx);
814
815                                         /* Hack -- Track this monster */
816                                         if (m_ptr->ml) health_track(cave_m_idx[y][x]);
817                                 }
818
819                                 /* Apply damage: multiplier, slays, criticals, bonuses */
820                                 tdam = damroll(i_ptr->dd, i_ptr->ds);
821                                 tdam += i_ptr->to_d + j_ptr->to_d;
822                                 tdam *= p_ptr->ammo_mult;
823                                 tdam *= MAX(ammo_mult, shoot_mult);
824                                 tdam = critical_shot(i_ptr->weight, i_ptr->to_h, tdam);
825
826                                 /* No negative damage */
827                                 if (tdam < 0) tdam = 0;
828
829                                 /* Complex message */
830                                 if (p_ptr->wizard)
831                                 {
832                                         msg_format("You do %d (out of %d) damage.",
833                                                    tdam, m_ptr->hp);
834                                 }
835
836                                 /* Hit the monster, check for death */
837                                 if (mon_take_hit(cave_m_idx[y][x], tdam, &fear, note_dies))
838                                 {
839                                         /* Dead monster */
840                                 }
841
842                                 /* No death */
843                                 else
844                                 {
845                                         /* Message */
846                                         message_pain(cave_m_idx[y][x], tdam);
847
848                                         /* Take note */
849                                         if (fear && m_ptr->ml)
850                                         {
851                                                 char m_name[80];
852
853                                                 /* Get the monster name (or "it") */
854                                                 monster_desc(m_name, sizeof(m_name), m_ptr, 0);
855
856                                                 /* Message */
857                                                 message_format(MSG_FLEE, m_ptr->r_idx,
858                                                                "%^s flees in terror!", m_name);
859                                         }
860                                 }
861                         }
862
863                         /* Stop looking */
864                         break;
865                 }
866         }
867
868         /* Chance of breakage (during attacks) */
869         j = (hit_body ? breakage_chance(i_ptr) : 0);
870
871         /* Drop (or break) near that location */
872         drop_near(i_ptr, j, y, x);
873 }
874
875
876
877 /*
878  * Throw an object from the pack or floor.
879  *
880  * Note: "unseen" monsters are very hard to hit.
881  *
882  * Should throwing a weapon do full damage?  Should it allow the magic
883  * to hit bonus of the weapon to have an effect?  Should it ever cause
884  * the item to be destroyed?  Should it do any damage at all?
885  */
886 void do_cmd_throw(void)
887 {
888         int dir, item;
889         int i, j, y, x;
890         s16b ty, tx;
891         int chance, tdam, tdis;
892